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 "/"
a "\"
).
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
, TMP
, TEMP
…
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ě.