/* GLIB - Library of useful routines for C programming * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifndef __G_LIB_H__ #define __G_LIB_H__ #include #ifdef USE_DMALLOC #include "dmalloc.h" #endif /* glib provides definitions for the extrema of many * of the standard types. These are: * G_MINFLOAT * G_MAXFLOAT * G_MINDOUBLE * G_MAXDOUBLE * G_MINSHORT * G_MAXSHORT * G_MININT * G_MAXINT * G_MINLONG * G_MAXLONG */ #ifdef HAVE_FLOAT_H #include #define G_MINFLOAT FLT_MIN #define G_MAXFLOAT FLT_MAX #define G_MINDOUBLE DBL_MIN #define G_MAXDOUBLE DBL_MAX #elif HAVE_VALUES_H #include #define G_MINFLOAT MINFLOAT #define G_MAXFLOAT MAXFLOAT #define G_MINDOUBLE MINDOUBLE #define G_MAXDOUBLE MAXDOUBLE #endif /* HAVE_VALUES_H */ #ifdef HAVE_LIMITS_H #include #define G_MINSHORT SHRT_MIN #define G_MAXSHORT SHRT_MAX #define G_MININT INT_MIN #define G_MAXINT INT_MAX #define G_MINLONG LONG_MIN #define G_MAXLONG LONG_MAX #elif HAVE_VALUES_H #ifdef HAVE_FLOAT_H #include #endif /* HAVE_FLOAT_H */ #define G_MINSHORT MINSHORT #define G_MAXSHORT MAXSHORT #define G_MININT MININT #define G_MAXINT MAXINT #define G_MINLONG MINLONG #define G_MAXLONG MAXLONG #endif /* HAVE_VALUES_H */ /* Provide definitions for some commonly used macros. * These are only provided if they haven't already * been defined. It is assumed that if they are already * defined then the current definition is correct. */ #ifndef FALSE #define FALSE 0 #endif /* FALSE */ #ifndef TRUE #define TRUE 1 #endif /* TRUE */ #ifndef NULL #define NULL ((void*) 0) #endif /* NULL */ #ifndef MAX #define MAX(a, b) (((a) > (b)) ? (a) : (b)) #endif /* MAX */ #ifndef MIN #define MIN(a, b) (((a) < (b)) ? (a) : (b)) #endif /* MIN */ #ifndef ABS #define ABS(a) (((a) < 0) ? -(a) : (a)) #endif /* ABS */ #ifndef CLAMP #define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x))) #endif /* CLAMP */ #ifndef ATEXIT # ifdef HAVE_ATEXIT # define ATEXIT(proc) (atexit (proc)) # elif defined (HAVE_ON_EXIT) # define ATEXIT(proc) (on_exit ((void (*)(int, void *))(proc), NULL)) # endif #endif /* ATEXIT */ /* Provide macros for easily allocating memory. The macros * will cast the allocated memory to the specified type * in order to avoid compiler warnings. (Makes the code neater). */ #ifdef __DMALLOC_H__ #define g_new(type,count) ALLOC(type,count) #define g_new0(type,count) CALLOC(type,count) #else /* __DMALLOC_H__ */ #define g_new(type, count) \ ((type *) g_malloc ((unsigned) sizeof (type) * (count))) #define g_new0(type, count) \ ((type *) g_malloc0 ((unsigned) sizeof (type) * (count))) #endif /* __DMALLOC_H__ */ #define g_chunk_new(type, chunk) \ ((type *) g_mem_chunk_alloc (chunk)) #define g_string(x) #x /* Provide simple macro statement wrappers (adapted from Pearl): * G_STMT_START { statements; } G_STMT_END; * can be used as a single statement, as in * if (x) G_STMT_START { ... } G_STMT_END; else ... * * For gcc we will wrap the statements within `({' and `})' braces. * For SunOS they will be wrapped within `if (1)' and `else (void)0', * and otherwise within `do' and `while (0)'. */ #if !(defined (G_STMT_START) && defined (G_STMT_END)) # if defined (__GNUC__) && !defined (__STRICT_ANSI__) && !defined (__cplusplus) # define G_STMT_START (void)( # define G_STMT_END ) # else # if (defined (sun) || defined (__sun__)) # define G_STMT_START if (1) # define G_STMT_END else (void)0 # else # define G_STMT_START do # define G_STMT_END while (0) # endif # endif #endif /* Provide macros for error handling. The "assert" macros will * exit on failure. The "return" macros will exit the current * function. Two different definitions are given for the macros * in order to support gcc's __PRETTY_FUNCTION__ capability. */ #ifdef G_DISABLE_ASSERT #define g_assert(expr) #define g_assert_not_reached() #else /* !G_DISABLE_ASSERT */ #ifdef __GNUC__ #define g_assert(expr) G_STMT_START{\ if (!(expr)) \ g_error ("file %s: line %d (%s): \"%s\"", \ __FILE__, \ __LINE__, \ __PRETTY_FUNCTION__, \ #expr); }G_STMT_END #define g_assert_not_reached() G_STMT_START{ \ g_error ("file %s: line %d (%s): \"should not be reached\"", \ __FILE__, \ __LINE__, \ __PRETTY_FUNCTION__); }G_STMT_END #else /* !__GNUC__ */ #define g_assert(expr) G_STMT_START{\ if (!(expr)) \ g_error ("file %s: line %d: \"%s\"", \ __FILE__, \ __LINE__, \ #expr); }G_STMT_END #define g_assert_not_reached() G_STMT_START{ \ g_error ("file %s: line %d: \"should not be reached\"", \ __FILE__, \ __LINE__); }G_STMT_END #endif /* __GNUC__ */ #endif /* G_DISABLE_ASSERT */ #ifdef G_DISABLE_CHECKS #define g_return_if_fail(expr) #define g_return_val_if_fail(expr,val) #else /* !G_DISABLE_CHECKS */ #ifdef __GNUC__ #define g_return_if_fail(expr) G_STMT_START{ \ if (!(expr)) \ { \ g_warning ("file %s: line %d (%s): \"%s\"", \ __FILE__, \ __LINE__, \ __PRETTY_FUNCTION__, \ #expr); \ return; \ }; }G_STMT_END #define g_return_val_if_fail(expr,val) G_STMT_START{ \ if (!(expr)) \ { \ g_warning ("file %s: line %d (%s): \"%s\"", \ __FILE__, \ __LINE__, \ __PRETTY_FUNCTION__, \ #expr); \ return val; \ }; }G_STMT_END #else /* !__GNUC__ */ #define g_return_if_fail(expr) G_STMT_START{ \ if (!(expr)) \ { \ g_warning ("file %s: line %d: \"%s\"", \ __FILE__, \ __LINE__, \ #expr); \ return; \ }; }G_STMT_END #define g_return_val_if_fail(expr, val) G_STMT_START{ \ if (!(expr)) \ { \ g_warning ("file %s: line %d: \"%s\"", \ __FILE__, \ __LINE__, \ #expr); \ return val; \ }; }G_STMT_END #endif /* !__GNUC__ */ #endif /* G_DISABLE_CHECKS */ /* Provide macros to feature the GCC printf format function attribute. */ #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4) #define G_GNUC_PRINTF( format_idx, arg_idx ) \ __attribute__((format (printf, format_idx, arg_idx))) #define G_GNUC_SCANF( format_idx, arg_idx ) \ __attribute__((format (scanf, format_idx, arg_idx))) #else /* !__GNUC__ */ #define G_GNUC_PRINTF( format_idx, arg_idx ) #define G_GNUC_SCANF( format_idx, arg_idx ) #endif /* !__GNUC__ */ #ifdef __cplusplus extern "C" { #pragma } #endif /* __cplusplus */ /* Provide type definitions for commonly used types. * These are useful because a "gint8" can be adjusted * to be 1 byte (8 bits) on all platforms. Similarly and * more importantly, "gint32" can be adjusted to be * 4 bytes (32 bits) on all platforms. */ typedef char gchar; typedef short gshort; typedef long glong; typedef int gint; typedef char gboolean; typedef unsigned char guchar; typedef unsigned short gushort; typedef unsigned long gulong; typedef unsigned int guint; typedef float gfloat; typedef double gdouble; /* HAVE_LONG_DOUBLE doesn't work correctly on all platforms. * Since gldouble isn't used anywhere, just disable it for now */ #if 0 #ifdef HAVE_LONG_DOUBLE typedef long double gldouble; #else /* HAVE_LONG_DOUBLE */ typedef double gldouble; #endif /* HAVE_LONG_DOUBLE */ #endif /* 0 */ typedef void* gpointer; #if (SIZEOF_CHAR == 1) typedef signed char gint8; typedef unsigned char guint8; #endif /* SIZEOF_CHAR */ #if (SIZEOF_SHORT == 2) typedef signed short gint16; typedef unsigned short guint16; #endif /* SIZEOF_SHORT */ #if (SIZEOF_INT == 4) typedef signed int gint32; typedef unsigned int guint32; #elif (SIZEOF_LONG == 4) typedef signed long gint32; typedef unsigned long guint32; #endif /* SIZEOF_INT */ typedef struct _GList GList; typedef struct _GSList GSList; typedef struct _GHashTable GHashTable; typedef struct _GCache GCache; typedef struct _GTree GTree; typedef struct _GTimer GTimer; typedef struct _GMemChunk GMemChunk; typedef struct _GListAllocator GListAllocator; typedef struct _GStringChunk GStringChunk; typedef struct _GString GString; typedef struct _GArray GArray; typedef struct _GDebugKey GDebugKey; typedef struct _GScannerConfig GScannerConfig; typedef struct _GScanner GScanner; typedef union _GValue GValue; typedef void (*GFunc) (gpointer data, gpointer user_data); typedef void (*GHFunc) (gpointer key, gpointer value, gpointer user_data); typedef guint (*GHashFunc) (gpointer key); typedef gint (*GCompareFunc) (gpointer a, gpointer b); typedef gpointer (*GCacheNewFunc) (gpointer key); typedef gpointer (*GCacheDupFunc) (gpointer value); typedef void (*GCacheDestroyFunc) (gpointer value); typedef gint (*GTraverseFunc) (gpointer key, gpointer value, gpointer data); typedef gint (*GSearchFunc) (gpointer key, gpointer data); typedef void (*GErrorFunc) (gchar *str); typedef void (*GWarningFunc) (gchar *str); typedef void (*GPrintFunc) (gchar *str); typedef void (*GScannerMsgFunc) (GScanner *scanner, gchar *message, gint error); struct _GList { gpointer data; GList *next; GList *prev; }; struct _GSList { gpointer data; GSList *next; }; struct _GString { gchar *str; gint len; }; struct _GArray { gchar *data; guint len; }; struct _GDebugKey { gchar *key; guint value; }; struct _GHashTable { gint dummy; }; struct _GCache { gint dummy; }; struct _GTree { gint dummy; }; struct _GTimer { gint dummy; }; struct _GMemChunk { gint dummy; }; struct _GListAllocator { gint dummy; }; struct _GStringChunk { gint dummy; }; typedef enum { G_IN_ORDER, G_PRE_ORDER, G_POST_ORDER } GTraverseType; /* Doubly linked lists */ GList* g_list_alloc (void); void g_list_free (GList *list); void g_list_free_1 (GList *list); GList* g_list_append (GList *list, gpointer data); GList* g_list_prepend (GList *list, gpointer data); GList* g_list_insert (GList *list, gpointer data, gint position); GList* g_list_insert_sorted (GList *list, gpointer data, GCompareFunc func); GList* g_list_concat (GList *list1, GList *list2); GList* g_list_remove (GList *list, gpointer data); GList* g_list_remove_link (GList *list, GList *link); GList* g_list_reverse (GList *list); GList* g_list_nth (GList *list, guint n); GList* g_list_find (GList *list, gpointer data); gint g_list_position (GList *list, GList *link); gint g_list_index (GList *list, gpointer data); GList* g_list_last (GList *list); GList* g_list_first (GList *list); guint g_list_length (GList *list); void g_list_foreach (GList *list, GFunc func, gpointer user_data); #define g_list_previous(list) ((list) ? (((GList *)list)->prev) : NULL) #define g_list_next(list) ((list) ? (((GList *)list)->next) : NULL) /* Singly linked lists */ GSList* g_slist_alloc (void); void g_slist_free (GSList *list); void g_slist_free_1 (GSList *list); GSList* g_slist_append (GSList *list, gpointer data); GSList* g_slist_prepend (GSList *list, gpointer data); GSList* g_slist_insert (GSList *list, gpointer data, gint position); GSList* g_slist_insert_sorted (GSList *list, gpointer data, GCompareFunc func); GSList* g_slist_concat (GSList *list1, GSList *list2); GSList* g_slist_remove (GSList *list, gpointer data); GSList* g_slist_remove_link (GSList *list, GSList *link); GSList* g_slist_reverse (GSList *list); GSList* g_slist_nth (GSList *list, guint n); GSList* g_slist_find (GSList *list, gpointer data); gint g_slist_position (GSList *list, GSList *link); gint g_slist_index (GSList *list, gpointer data); GSList* g_slist_last (GSList *list); guint g_slist_length (GSList *list); void g_slist_foreach (GSList *list, GFunc func, gpointer user_data); #define g_slist_next(list) ((list) ? (((GSList *)list)->next) : NULL) /* List Allocators */ GListAllocator* g_list_allocator_new (void); void g_list_allocator_free (GListAllocator* allocator); GListAllocator* g_slist_set_allocator (GListAllocator* allocator); GListAllocator* g_list_set_allocator (GListAllocator* allocator); /* Hash tables */ GHashTable* g_hash_table_new (GHashFunc hash_func, GCompareFunc key_compare_func); void g_hash_table_destroy (GHashTable *hash_table); void g_hash_table_insert (GHashTable *hash_table, gpointer key, gpointer value); void g_hash_table_remove (GHashTable *hash_table, gpointer key); gpointer g_hash_table_lookup (GHashTable *hash_table, const gpointer key); void g_hash_table_freeze (GHashTable *hash_table); void g_hash_table_thaw (GHashTable *hash_table); void g_hash_table_foreach (GHashTable *hash_table, GHFunc func, gpointer user_data); /* Caches */ GCache* g_cache_new (GCacheNewFunc value_new_func, GCacheDestroyFunc value_destroy_func, GCacheDupFunc key_dup_func, GCacheDestroyFunc key_destroy_func, GHashFunc hash_key_func, GHashFunc hash_value_func, GCompareFunc key_compare_func); void g_cache_destroy (GCache *cache); gpointer g_cache_insert (GCache *cache, gpointer key); void g_cache_remove (GCache *cache, gpointer value); void g_cache_key_foreach (GCache *cache, GHFunc func, gpointer user_data); void g_cache_value_foreach (GCache *cache, GHFunc func, gpointer user_data); /* Trees */ GTree* g_tree_new (GCompareFunc key_compare_func); void g_tree_destroy (GTree *tree); void g_tree_insert (GTree *tree, gpointer key, gpointer value); void g_tree_remove (GTree *tree, gpointer key); gpointer g_tree_lookup (GTree *tree, gpointer key); void g_tree_traverse (GTree *tree, GTraverseFunc traverse_func, GTraverseType traverse_type, gpointer data); gpointer g_tree_search (GTree *tree, GSearchFunc search_func, gpointer data); gint g_tree_height (GTree *tree); gint g_tree_nnodes (GTree *tree); /* Memory */ #ifdef USE_DMALLOC #define g_malloc(size) (gpointer) MALLOC(size) #define g_malloc0(size) (gpointer) CALLOC(char,size) #define g_realloc(mem,size) (gpointer) REALLOC(mem,char,size) #define g_free(mem) FREE(mem) #else /* USE_DMALLOC */ gpointer g_malloc (gulong size); gpointer g_malloc0 (gulong size); gpointer g_realloc (gpointer mem, gulong size); void g_free (gpointer mem); #endif /* USE_DMALLOC */ void g_mem_profile (void); void g_mem_check (gpointer mem); /* "g_mem_chunk_new" creates a new memory chunk. * Memory chunks are used to allocate pieces of memory which are * always the same size. Lists are a good example of such a data type. * The memory chunk allocates and frees blocks of memory as needed. * Just be sure to call "g_mem_chunk_free" and not "g_free" on data * allocated in a mem chunk. ("g_free" will most likely cause a seg * fault...somewhere). * * Oh yeah, GMemChunk is an opaque data type. (You don't really * want to know what's going on inside do you?) */ /* ALLOC_ONLY MemChunk's can only allocate memory. The free operation * is interpreted as a no op. ALLOC_ONLY MemChunk's save 4 bytes per * atom. (They are also useful for lists which use MemChunk to allocate * memory but are also part of the MemChunk implementation). * ALLOC_AND_FREE MemChunk's can allocate and free memory. */ #define G_ALLOC_ONLY 1 #define G_ALLOC_AND_FREE 2 GMemChunk* g_mem_chunk_new (gchar *name, gint atom_size, gulong area_size, gint type); void g_mem_chunk_destroy (GMemChunk *mem_chunk); gpointer g_mem_chunk_alloc (GMemChunk *mem_chunk); void g_mem_chunk_free (GMemChunk *mem_chunk, gpointer mem); void g_mem_chunk_clean (GMemChunk *mem_chunk); void g_mem_chunk_reset (GMemChunk *mem_chunk); void g_mem_chunk_print (GMemChunk *mem_chunk); void g_mem_chunk_info (void); /* Ah yes...we have a "g_blow_chunks" function. * "g_blow_chunks" simply compresses all the chunks. This operation * consists of freeing every memory area that should be freed (but * which we haven't gotten around to doing yet). And, no, * "g_blow_chunks" doesn't follow the naming scheme, but it is a * much better name than "g_mem_chunk_clean_all" or something * similar. */ void g_blow_chunks (void); /* Timer */ GTimer* g_timer_new (void); void g_timer_destroy (GTimer *timer); void g_timer_start (GTimer *timer); void g_timer_stop (GTimer *timer); void g_timer_reset (GTimer *timer); gdouble g_timer_elapsed (GTimer *timer, gulong *microseconds); /* Output */ void g_error (gchar *format, ...) G_GNUC_PRINTF (1, 2); void g_warning (gchar *format, ...) G_GNUC_PRINTF (1, 2); void g_message (gchar *format, ...) G_GNUC_PRINTF (1, 2); void g_print (gchar *format, ...) G_GNUC_PRINTF (1, 2); /* Utility functions */ #define G_STR_DELIMITERS "_-|> <." void g_strdelimit (gchar *string, const gchar *delimiters, gchar new_delimiter); gchar* g_strdup (const gchar *str); gchar* g_strconcat (const gchar *string1, ...); /* NULL terminated */ gdouble g_strtod (const gchar *nptr, gchar **endptr); gchar* g_strerror (gint errnum); gchar* g_strsignal (gint signum); gint g_strcasecmp (const gchar *s1, const gchar *s2); void g_strdown (gchar *string); void g_strup (gchar *string); guint g_parse_debug_string (const gchar *string, GDebugKey *keys, guint nkeys); gint g_snprintf (gchar *string, gulong n, gchar const *format, ...) G_GNUC_PRINTF (3, 4); /* We make the assumption that if memmove isn't available, then * bcopy will do the job. This isn't safe everywhere. (bcopy can't * necessarily handle overlapping copies) */ #ifdef HAVE_MEMMOVE #define g_memmove memmove #else #define g_memmove(a,b,c) bcopy(b,a,c) #endif /* Errors */ GErrorFunc g_set_error_handler (GErrorFunc func); GWarningFunc g_set_warning_handler (GWarningFunc func); GPrintFunc g_set_message_handler (GPrintFunc func); GPrintFunc g_set_print_handler (GPrintFunc func); void g_debug (const gchar *progname); void g_attach_process (const gchar *progname, gint query); void g_stack_trace (const gchar *progname, gint query); /* String Chunks */ GStringChunk* g_string_chunk_new (gint size); void g_string_chunk_free (GStringChunk *chunk); gchar* g_string_chunk_insert (GStringChunk *chunk, gchar* string); gchar* g_string_chunk_insert_const (GStringChunk *chunk, gchar* string); /* Strings */ GString* g_string_new (const gchar *init); void g_string_free (GString *string, gint free_segment); GString* g_string_assign (GString *lval, const gchar *rval); GString* g_string_truncate (GString *string, gint len); GString* g_string_append (GString *string, const gchar *val); GString* g_string_append_c (GString *string, gchar c); GString* g_string_prepend (GString *string, const gchar *val); GString* g_string_prepend_c (GString *string, gchar c); GString* g_string_insert (GString *string, gint pos, const gchar *val); GString* g_string_insert_c (GString *string, gint pos, gchar c); GString* g_string_erase (GString *string, gint pos, gint len); GString* g_string_down (GString *string); GString* g_string_up (GString *string); void g_string_sprintf (GString *string, const gchar *format, ...) G_GNUC_PRINTF (2, 3); void g_string_sprintfa (GString *string, const gchar *format, ...) G_GNUC_PRINTF (2, 3); /* Resizable arrays */ #define g_array_append_val(array,type,val) \ g_rarray_append (array, (gpointer) &val, sizeof (type)) #define g_array_append_vals(array,type,vals,nvals) \ g_rarray_append (array, (gpointer) vals, sizeof (type) * nvals) #define g_array_prepend_val(array,type,val) \ g_rarray_prepend (array, (gpointer) &val, sizeof (type)) #define g_array_prepend_vals(array,type,vals,nvals) \ g_rarray_prepend (array, (gpointer) vals, sizeof (type) * nvals) #define g_array_truncate(array,type,length) \ g_rarray_truncate (array, length, sizeof (type)) #define g_array_index(array,type,index) \ ((type*) array->data)[index] GArray* g_array_new (gint zero_terminated); void g_array_free (GArray *array, gint free_segment); GArray* g_rarray_append (GArray *array, gpointer data, gint size); GArray* g_rarray_prepend (GArray *array, gpointer data, gint size); GArray* g_rarray_truncate (GArray *array, gint length, gint size); /* Hash Functions */ gint g_str_equal (const gpointer v, const gpointer v2); guint g_str_hash (const gpointer v); /* This "hash" function will just return the key's adress as an * unsigned integer. Useful for hashing on plain adresses or * simple integer values. */ guint g_direct_hash (gpointer key); /* GScanner: Flexible lexical scanner for general purpose. */ /* Character sets */ #define G_CSET_A_2_Z "ABCDEFGHIJKLMNOPQRSTUVWXYZ" #define G_CSET_a_2_z "abcdefghijklmnopqrstuvwxyz" #define G_CSET_LATINC "\300\301\302\303\304\305\306"\ "\307\310\311\312\313\314\315\316\317\320"\ "\321\322\323\324\325\326"\ "\330\331\332\333\334\335\336" #define G_CSET_LATINS "\337\340\341\342\343\344\345\346"\ "\347\350\351\352\353\354\355\356\357\360"\ "\361\362\363\364\365\366"\ "\370\371\372\373\374\375\376\377" /* Error types */ typedef enum { G_ERR_UNKNOWN, G_ERR_UNEXP_EOF, G_ERR_UNEXP_EOF_IN_STRING, G_ERR_UNEXP_EOF_IN_COMMENT, G_ERR_NON_DIGIT_IN_CONST, G_ERR_DIGIT_RADIX, G_ERR_FLOAT_RADIX, G_ERR_FLOAT_MALFORMED } GErrorType; /* Token types */ typedef enum { G_TOKEN_EOF = 0, G_TOKEN_LEFT_PAREN = '(', G_TOKEN_RIGHT_PAREN = ')', G_TOKEN_LEFT_CURLY = '{', G_TOKEN_RIGHT_CURLY = '}', G_TOKEN_LEFT_BRACE = '[', G_TOKEN_RIGHT_BRACE = ']', G_TOKEN_EQUAL_SIGN = '=', G_TOKEN_COMMA = ',', G_TOKEN_NONE = 256, G_TOKEN_ERROR, G_TOKEN_CHAR, G_TOKEN_BINARY, G_TOKEN_OCTAL, G_TOKEN_INT, G_TOKEN_HEX, G_TOKEN_FLOAT, G_TOKEN_STRING, G_TOKEN_SYMBOL, G_TOKEN_IDENTIFIER, G_TOKEN_IDENTIFIER_NULL, G_TOKEN_COMMENT_SINGLE, G_TOKEN_COMMENT_MULTI, G_TOKEN_LAST } GTokenType; union _GValue { gpointer v_symbol; gchar *v_identifier; gulong v_binary; gulong v_octal; gulong v_int; gdouble v_float; gulong v_hex; gchar *v_string; gchar *v_comment; guchar v_char; guint v_error; }; struct _GScannerConfig { /* Character sets */ gchar *cset_skip_characters; /* default: " \t\n" */ gchar *cset_identifier_first; gchar *cset_identifier_nth; gchar *cpair_comment_single; /* default: "#\n" */ /* Should symbol lookup work case sensitive? */ guint case_sensitive : 1; /* Boolean values to be adjusted "on the fly" * to configure scanning behaviour. */ guint skip_comment_multi : 1; /* C like comment */ guint skip_comment_single : 1; /* single line comment */ guint scan_comment_multi : 1; /* scan multi line comments? */ guint scan_identifier : 1; guint scan_identifier_1char : 1; guint scan_identifier_NULL : 1; guint scan_symbols : 1; guint scan_binary : 1; guint scan_octal : 1; guint scan_float : 1; guint scan_hex : 1; /* `0x0ff0' */ guint scan_hex_dollar : 1; /* `$0ff0' */ guint scan_string_sq : 1; /* string: 'anything' */ guint scan_string_dq : 1; /* string: "\\-escapes!\n" */ guint numbers_2_int : 1; /* bin, octal, hex => int */ guint int_2_float : 1; /* int => G_TOKEN_FLOAT? */ guint identifier_2_string : 1; guint char_2_token : 1; /* return G_TOKEN_CHAR? */ guint symbol_2_token : 1; }; struct _GScanner { /* unused portions */ gpointer user_data; const gchar *input_name; guint parse_errors; guint max_parse_errors; /* maintained/used by the g_scanner_*() functions */ GScannerMsgFunc msg_handler; GScannerConfig *config; GTokenType token; GValue value; guint line; guint position; /* to be considered private */ GTokenType next_token; GValue next_value; guint next_line; guint next_position; GHashTable *symbol_table; const gchar *text; guint text_len; gint input_fd; gint peeked_char; }; GScanner* g_scanner_new (GScannerConfig *config_templ); void g_scanner_destroy (GScanner *scanner); void g_scanner_input_file (GScanner *scanner, gint input_fd); void g_scanner_input_text (GScanner *scanner, const gchar *text, guint text_len); GTokenType g_scanner_get_next_token (GScanner *scanner); GTokenType g_scanner_peek_next_token (GScanner *scanner); GTokenType g_scanner_cur_token (GScanner *scanner); GValue g_scanner_cur_value (GScanner *scanner); guint g_scanner_cur_line (GScanner *scanner); guint g_scanner_cur_position (GScanner *scanner); gboolean g_scanner_eof (GScanner *scanner); void g_scanner_add_symbol (GScanner *scanner, const gchar *symbol, gpointer value); gpointer g_scanner_lookup_symbol (GScanner *scanner, const gchar *symbol); void g_scanner_remove_symbol (GScanner *scanner, const gchar *symbol); void g_scanner_unexp_token (GScanner *scanner, GTokenType expected_token, const gchar *identifier_spec, const gchar *symbol_spec, const gchar *symbol_name, const gchar *message, gint is_error); void g_scanner_error (GScanner *scanner, const gchar *format, ...) G_GNUC_PRINTF (2,3); void g_scanner_warn (GScanner *scanner, const gchar *format, ...) G_GNUC_PRINTF (2,3); gint g_scanner_stat_mode (const gchar *filename); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* __G_LIB_H__ */