Hlavní navigace

GLib: Užitečnosti všeho druhu

Michal Burda

V dnešním pokračovaní si ukážeme sadu funkcí těžko zařaditelnou do nějaké konkrétní skupiny. Zkrátka a dobře, jsou to různé rutiny, které se občas hodí. Knihovna GLib garantuje, že jsou přenositelné i na jiné platformy, a to je jistě příjemné.

Zjištění verze knihovny GLib

Verze knihovny GLib je zaznamenaná ve trojici maker:

#define GLIB_MAJOR_VERSION
#define GLIB_MINOR_VERSION
#define GLIB_MICRO_VERSION

Každé makro znamená jednu složku čísla verze knihovny:

GLib version  1. 2. 8
              |  |  |
          |  |  V
          |  V  GLIB_MICRO_VERSION
          V  GLIB_MINOR_VERSION
          GLIB_MAJOR_VERSION

Ve svých programech je můžete využít třeba k výpisu informace o verzi, pod kterou byla aplikace zkompilována.

Chcete-li naopak zkontrolovat, je-li program sestavován pod vámi požadovanou verzí knihovny, můžete s úspěchem využít následující makro:

#define GLIB_CHECK_VERSION(major,minor,micro)

Makro vrátí TRUE, je-li aktuální verze knihovny stejná nebo lepší než zadaná verze major. minor. micro.

Oddělovače

Nepříjemnost s různými oddělovači adresářů na různých platformách řeší následující konstantní makra:

#define G_DIR_SEPARATOR
#define G_DIR_SEPARATOR_S

G_DIR_SEPARATOR je na Unixech roven '/' a ve Windows '\'. V makru G_DIR_SEPARATOR_S je definováno totéž, ale jako řetězec (tedy "/""\").

Podobně se věci mají i u těchto maker:

#define G_SEARCHPATH_SEPARATOR
#define G_SEARCHPATH_SEPARATOR_S

G_SEARCHPATH_SEPARATOR uchovává oddělovač cest v proměnné prostředí PATH. V Unixu je to dvojtečka ( ':') a ve Windows středník ( ';'). Potřebujete-li oddělovač cest zapsaný jako řetězec, sáhněte po  G_SEARCHPATH_SEPARATOR_S.

Boolovské hodnoty

V dřívějších dílech jsem běžně v příkladech používal boolovské konstanty TRUE a FALSE (což není standardní výbava jazyka C), aniž bych se předtím zmínil o tom, že jsou definovány v knihovně GLib. Za to se všem omlouvám a jen pro pořádek uvádím jejich definici:

#define FALSE (0)
#define TRUE  (!FALSE)

Stejně tak makro

#define NULL ((void*) 0)

…označující prázdný ( NULL ový) pointer.

Větší, menší

#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define MAX(a, b) (((a) > (b)) ? (a) : (b))

…jednoduchá makra, jejichž výsledkem je menší (větší) číslo z a  a b.

Výpočet absolutní hodnoty je realizován makrem:

#define ABS(a) (((a) < 0) ? -(a) : (a))

Pro zarovnání hodnoty do číselného intervalu slouží makro:

#define CLAMP(x, low, high) \
    (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))

Jeho výsledkem je zadané číslo x, pokud se nachází v rozmezí hodnot low a high. Je-li x menší, vrátí se low, je-li větší, předá se high.

Například výsledkem všech tří následujících volání bude číslo  10:

CLAMP(5, 10, 15)
CLAMP(10, 5, 20)
CLAMP(25, 5, 10)

Struktury na úrovni bajtů

#define G_STRUCT_OFFSET(struct_type, member)

…vrátí offset v bajtech položky member struktury struct_type. Argument struct_type je tedy název datového typu struktury (např. GString) a member název položky, jejíž adresový offset chceme získat (např.  len).

#define G_STRUCT_MEMBER(member_type, struct_p, struct_offset)

…zpřístupní v konkrétní instanci struktury, na níž ukazuje pointer struct_p, položku s offsetem struct_offset a výsledek přetypuje na typ  member_type.

#define G_STRUCT_MEMBER_P(struct_p, struct_offset)

…vrátí beztypový Pointer na položku s offsetem struct_offset struktury struct_p.

Příklad:

#include <glib.h>

typedef struct {
  char *nazev;
  float max_rychlost;
  float spotreba;
} Automobil;


int main(void) {
  Automobil auto1 = { "Skoda", 130, 7.2 };
  Automobil auto2 = { "Audi", 220, 10.4 };
  
  gulong o_nazev = G_STRUCT_OFFSET(Automobil, nazev);
  gulong o_spotreba = G_STRUCT_OFFSET(Automobil, spotreba);

  printf("%s ma spotrebu %0.1f litru\n",
      G_STRUCT_MEMBER(char*, &auto1, o_nazev),
      G_STRUCT_MEMBER(float, &auto1, o_spotreba));

  printf("%s ma spotrebu %0.1f litru\n",
      G_STRUCT_MEMBER(char*, &auto2, o_nazev),
      G_STRUCT_MEMBER(float, &auto2, o_spotreba));

  return 0;
}

Tato ukázka vypíše na terminál:

Skoda ma spotrebu 7.2 litru
Audi ma spotrebu 10.4 litru

Cesty a jména

gchar* g_get_prgname(void);

…vrátí jméno programového souboru. Pokud používáte knihovnu GDK nebo GTK, je jméno programu inicializováno automaticky ve funkci gdk_init(), která je volána z funkce gtk_init(). Název se zjistí z poslední složky řetězce argv[0]. Jestliže ale výše zmiňované knihovny nepoužíváte a přesto máte pro funkci g_get_prgname() uplatnění, musíte název programu inicializovat sami:

void g_set_prgname(const gchar *prgname);

Na původu řetězce prgname nezáleží, protože rutina si pro název programu alokuje nový řetězec.

Pro získání hodnoty proměnné prostředí poskytuje GLib přenositelnou­ funkci

gchar* g_getenv(const gchar *variable);

Argument variable je název proměnné prostředí a navrácený řetězec je její hodnota, nebo NULL, pokud taková proměnná není definována. Pozn.: ve Windows je vrácený řetězec platný jen do dalšího volání  g_getenv().

Funkce

gchar* g_get_user_name(void);

…vrátí jméno (login) aktuálního uživatele. Pokud na dané platformě není možné jméno zjistit, funkce vrátí řetězec  "somebody".

Podobně tak funkce

gchar* g_get_real_name(void);

…vracející skutečné jméno uživatele (viz. /etc/passwd). Pokud nelze zjistit, vrátí se  "Unknown".

Domácí adresář uživatele, adresář pro dočasné soubory (tmp, temp) a aktuální adresář zjistíte pomocí funkcí:

gchar* g_get_home_dir(void);
gchar* g_get_tmp_dir(void);
gchar* g_get_current_dir(void);

Funkce hledají zmíněné informace v proměnných prostředí HOME (ve Windows NT i HOMEDRIVE  a HOMEPATH), TMPDIR, TMPTEMP

Další práce s cestami k souborům

gchar* g_basename(const gchar *file_name);

…vrátí jméno souboru bez předcházející adresářové složky. Vrácený řetězcový pointer ukazuje přímo doprostřed argumentu file_name.

gchar* g_dirname(const gchar *file_name);

…vrátí adresářovou složku jména souboru file_name. Pokud file_name neobsahuje cestu i s adresáři, použije se jako návratová hodnota řetězec ".". Vrácená hodnota by měla být po použití dealokována.

gboolean g_path_is_absolute(const gchar *file_name);

…vrátí TRUE, jestliže je jméno souboru file_name absolutní, tj. rozhodne, jestli obsahuje plnou cestu z kořenového adresáře. (Např. „ /usr/local“ v Unixech nebo „ C:\WINDOWS\SYSTEM“ ve Windows.)

gchar* g_path_skip_root(gchar *file_name);

…vrátí pointer na jméno souboru file_name těsně za označením kořenového adresáře, tj. za lomítkem ( /) v Unixech a za C:\ ve Windows. Jestliže file_name není absolutní jméno souboru, funkce předá  NULL.

Pokračování příště.

Našli jste v článku chybu?
Vitalia.cz: 9 největších mýtů o mase

9 největších mýtů o mase

Podnikatel.cz: Přehledná titulka, průvodci, responzivita

Přehledná titulka, průvodci, responzivita

Lupa.cz: Teletext je „internetem hipsterů“

Teletext je „internetem hipsterů“

DigiZone.cz: „Black Friday 2016“: závěrečné zhodnocení

„Black Friday 2016“: závěrečné zhodnocení

Vitalia.cz: Láska na vozíku: Přitažliví jsme pro tzv. pečovatelky

Láska na vozíku: Přitažliví jsme pro tzv. pečovatelky

Vitalia.cz: Proč vás každý zubař posílá na dentální hygienu

Proč vás každý zubař posílá na dentální hygienu

Lupa.cz: Propustili je z Avastu, už po nich sahá ESET

Propustili je z Avastu, už po nich sahá ESET

Vitalia.cz: Spor o mortadelu: podle Lidlu falšovaná nebyla

Spor o mortadelu: podle Lidlu falšovaná nebyla

Podnikatel.cz: Chaos u EET pokračuje. Jsou tu další návrhy

Chaos u EET pokračuje. Jsou tu další návrhy

Měšec.cz: mBank cenzuruje, zrušila mFórum

mBank cenzuruje, zrušila mFórum

Vitalia.cz: Znáte „černý detox“? Ani to nezkoušejte

Znáte „černý detox“? Ani to nezkoušejte

Lupa.cz: Insolvenční řízení kvůli cookies? Vítejte v ČR

Insolvenční řízení kvůli cookies? Vítejte v ČR

Vitalia.cz: Taky věříte na pravidlo 5 sekund?

Taky věříte na pravidlo 5 sekund?

Vitalia.cz: Co pomáhá dítěti při zácpě?

Co pomáhá dítěti při zácpě?

Lupa.cz: Proč firmy málo chrání data? Chovají se logicky

Proč firmy málo chrání data? Chovají se logicky

Vitalia.cz: Když přijdete o oko, přijdete na rok o řidičák

Když přijdete o oko, přijdete na rok o řidičák

Vitalia.cz: Paštiky plné masa ho zatím neuživí

Paštiky plné masa ho zatím neuživí

Podnikatel.cz: Zavře krám u #EET Malá pokladna a Teeta?

Zavře krám u #EET Malá pokladna a Teeta?

Lupa.cz: Co se dá měřit přes Internet věcí

Co se dá měřit přes Internet věcí

120na80.cz: Pánové, pečujte o svoje přirození a prostatu

Pánové, pečujte o svoje přirození a prostatu