glib.h 24.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
17
 */
18 19 20 21
#ifndef __G_LIB_H__
#define __G_LIB_H__

#include <glibconfig.h>
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116

#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 <float.h>

#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 <values.h>

#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 <limits.h>

#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 <values.h>
#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
117
#define ABS(a)	   (((a) < 0) ? -(a) : (a))
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
#endif /* ABS */

#ifndef CLAMP
#define CLAMP(x, low, high)  (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
#endif /* CLAMP */

#ifndef ATEXIT
#define ATEXIT(proc)   (atexit (proc))
#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__

136 137
#define g_new(type,count)	 ALLOC(type,count)
#define g_new0(type,count)	 CALLOC(type,count)
138 139 140

#else /* __DMALLOC_H__ */

141
#define g_new(type, count)	  \
142
    ((type *) g_malloc ((unsigned) sizeof (type) * (count)))
143
#define g_new0(type, count)	  \
144 145 146 147 148 149 150
    ((type *) g_malloc0 ((unsigned) sizeof (type) * (count)))
#endif /* __DMALLOC_H__ */

#define g_chunk_new(type, chunk)  \
    ((type *) g_mem_chunk_alloc (chunk))


Tim Janik's avatar
GLib:  
Tim Janik committed
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
#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


179
/* Provide macros for error handling. The "assert" macros will
Tim Janik's avatar
GLib:  
Tim Janik committed
180
 *  exit on failure. The "return" macros will exit the current
181 182 183 184 185 186
 *  function. Two different definitions are given for the macros
 *  in order to support gcc's __PRETTY_FUNCTION__ capability.
 */

#ifdef __GNUC__

Tim Janik's avatar
GLib:  
Tim Janik committed
187
#define g_assert(expr)			G_STMT_START{\
188
     if (!(expr))				     \
189
       g_error ("file %s: line %d (%s): \"%s\"",     \
190 191 192
		__FILE__,			     \
		__LINE__,			     \
		__PRETTY_FUNCTION__,		     \
Tim Janik's avatar
GLib:  
Tim Janik committed
193
		#expr);			}G_STMT_END
194

Tim Janik's avatar
GLib:  
Tim Janik committed
195
#define g_assert_not_reached()		G_STMT_START{		      \
196
     g_error ("file %s: line %d (%s): \"should not be reached\"",     \
197 198
	      __FILE__,						      \
	      __LINE__,						      \
Tim Janik's avatar
GLib:  
Tim Janik committed
199
	      __PRETTY_FUNCTION__);	}G_STMT_END
200

Tim Janik's avatar
GLib:  
Tim Janik committed
201
#define g_return_if_fail(expr)		G_STMT_START{	       \
202 203 204 205 206 207 208 209
     if (!(expr))					       \
       {						       \
	 g_warning ("file %s: line %d (%s): \"%s\"",	       \
		    __FILE__,				       \
		    __LINE__,				       \
		    __PRETTY_FUNCTION__,		       \
		    #expr);				       \
	 return;					       \
Tim Janik's avatar
GLib:  
Tim Janik committed
210
       };				}G_STMT_END
211

Tim Janik's avatar
GLib:  
Tim Janik committed
212
#define g_return_val_if_fail(expr,val)	G_STMT_START{	       \
213 214 215 216 217 218 219 220
     if (!(expr))					       \
       {						       \
	 g_warning ("file %s: line %d (%s): \"%s\"",	       \
		    __FILE__,				       \
		    __LINE__,				       \
		    __PRETTY_FUNCTION__,		       \
		    #expr);				       \
	 return val;					       \
Tim Janik's avatar
GLib:  
Tim Janik committed
221
       };				}G_STMT_END
222 223 224

#else /* __GNUC__ */

Tim Janik's avatar
GLib:  
Tim Janik committed
225
#define g_assert(expr)			G_STMT_START{\
226 227 228 229
     if (!(expr))				     \
       g_error ("file %s: line %d: \"%s\"",	     \
		__FILE__,			     \
		__LINE__,			     \
Tim Janik's avatar
GLib:  
Tim Janik committed
230
		#expr);			}G_STMT_END
231

Tim Janik's avatar
GLib:  
Tim Janik committed
232
#define g_assert_not_reached()		G_STMT_START{		      \
233 234
     g_error ("file %s: line %d: \"should not be reached\"",	      \
	      __FILE__,						      \
Tim Janik's avatar
GLib:  
Tim Janik committed
235
	      __LINE__);		}G_STMT_END
236

Tim Janik's avatar
GLib:  
Tim Janik committed
237
#define g_return_if_fail(expr)		G_STMT_START{	 \
238 239 240 241 242 243 244
     if (!(expr))					 \
       {						 \
	 g_warning ("file %s: line %d: \"%s\"",		 \
		    __FILE__,				 \
		    __LINE__,				 \
		    #expr);				 \
	 return;					 \
Tim Janik's avatar
GLib:  
Tim Janik committed
245
       };				}G_STMT_END
246

Tim Janik's avatar
GLib:  
Tim Janik committed
247
#define g_return_val_if_fail(expr, val)	G_STMT_START{	 \
248 249 250 251 252 253 254
     if (!(expr))					 \
       {						 \
	 g_warning ("file %s: line %d: \"%s\"",		 \
		    __FILE__,				 \
		    __LINE__,				 \
		    #expr);				 \
	 return val;					 \
Tim Janik's avatar
GLib:  
Tim Janik committed
255
       };				}G_STMT_END
256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276

#endif /* __GNUC__ */


#ifdef __cplusplus
extern "C" {
#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;

277 278 279 280
typedef unsigned char	guchar;
typedef unsigned short	gushort;
typedef unsigned long	gulong;
typedef unsigned int	guint;
281

282 283
typedef float	gfloat;
typedef double	gdouble;
284 285 286 287 288 289 290 291 292 293 294 295 296 297 298

/* 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)
299 300
typedef signed char	gint8;
typedef unsigned char	guint8;
301 302 303 304
#endif /* SIZEOF_CHAR */


#if (SIZEOF_SHORT == 2)
305 306
typedef signed short	gint16;
typedef unsigned short	guint16;
307 308 309 310
#endif /* SIZEOF_SHORT */


#if (SIZEOF_INT == 4)
311 312
typedef signed int	gint32;
typedef unsigned int	guint32;
313
#elif (SIZEOF_LONG == 4)
314 315
typedef signed long	gint32;
typedef unsigned long	guint32;
316 317 318
#endif /* SIZEOF_INT */


319 320
typedef struct _GList	       GList;
typedef struct _GSList	       GSList;
321
typedef struct _GHashTable     GHashTable;
322 323 324
typedef struct _GCache	       GCache;
typedef struct _GTree	       GTree;
typedef struct _GTimer	       GTimer;
325 326 327
typedef struct _GMemChunk      GMemChunk;
typedef struct _GListAllocator GListAllocator;
typedef struct _GStringChunk   GStringChunk;
328 329
typedef struct _GString	       GString;
typedef struct _GArray	       GArray;
330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389

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);


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 _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
 */
390 391 392 393
GList* g_list_alloc	  (void);
void   g_list_free	  (GList     *list);
void   g_list_free_1	  (GList     *list);
GList* g_list_append	  (GList     *list,
394
			   gpointer   data);
395
GList* g_list_prepend	  (GList     *list,
396
			   gpointer   data);
397
GList* g_list_insert	  (GList     *list,
398
			   gpointer   data,
399
			   gint	      position);
400 401 402 403
GList* g_list_insert_sorted
			  (GList     *list,
			   gpointer   data,
			   GCompareFunc func);			    
404
GList* g_list_concat	  (GList     *list1, 
405
			   GList     *list2);
406
GList* g_list_remove	  (GList     *list,
407 408 409
			   gpointer   data);
GList* g_list_remove_link (GList     *list,
			   GList     *link);
410 411 412 413
GList* g_list_reverse	  (GList     *list);
GList* g_list_nth	  (GList     *list,
			   gint	      n);
GList* g_list_find	  (GList     *list,
414
			   gpointer   data);
415 416 417 418
GList* g_list_last	  (GList     *list);
GList* g_list_first	  (GList     *list);
gint   g_list_length	  (GList     *list);
void   g_list_foreach	  (GList     *list,
419 420 421
			   GFunc      func,
			   gpointer   user_data);

422 423
#define g_list_previous(list) (((GList *)list)->prev)
#define g_list_next(list) (((GList *)list)->next)
424 425 426

/* Singly linked lists
 */
427 428 429 430
GSList* g_slist_alloc	    (void);
void	g_slist_free	    (GSList   *list);
void	g_slist_free_1	    (GSList   *list);
GSList* g_slist_append	    (GSList   *list,
431
			     gpointer  data);
432
GSList* g_slist_prepend	    (GSList   *list,
433
			     gpointer  data);
434
GSList* g_slist_insert	    (GSList   *list,
435 436
			     gpointer  data,
			     gint      position);
437 438 439 440
GSList* g_slist_insert_sorted
			    (GSList   *list,
			     gpointer  data,
			     GCompareFunc func);			    
441
GSList* g_slist_concat	    (GSList   *list1, 
442
			     GSList   *list2);
443
GSList* g_slist_remove	    (GSList   *list,
444 445 446
			     gpointer  data);
GSList* g_slist_remove_link (GSList   *list,
			     GSList   *link);
447 448
GSList* g_slist_reverse	    (GSList   *list);
GSList* g_slist_nth	    (GSList   *list,
449
			     gint      n);
450
GSList* g_slist_find	    (GSList   *list,
451
			     gpointer  data);
452 453 454
GSList* g_slist_last	    (GSList   *list);
gint	g_slist_length	    (GSList   *list);
void	g_slist_foreach	    (GSList   *list,
455 456 457
			     GFunc     func,
			     gpointer  user_data);

458
#define g_slist_next(list) (((GSList *)list)->next)
459 460 461 462

/* List Allocators
 */
GListAllocator* g_list_allocator_new  (void);
463
void		g_list_allocator_free (GListAllocator* allocator);
464 465 466 467 468 469
GListAllocator* g_slist_set_allocator (GListAllocator* allocator);
GListAllocator* g_list_set_allocator  (GListAllocator* allocator);


/* Hash tables
 */
470 471 472 473 474 475 476 477 478
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,
479
				  const gpointer  key);
480 481 482 483 484
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);
485 486 487 488


/* Caches
 */
489
GCache*	 g_cache_new	       (GCacheNewFunc	   value_new_func,
490
				GCacheDestroyFunc  value_destroy_func,
491
				GCacheDupFunc	   key_dup_func,
492
				GCacheDestroyFunc  key_destroy_func,
493 494 495 496 497 498 499 500 501 502 503 504 505 506
				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);
507 508 509 510


/* Trees
 */
511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528
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);
529 530 531 532 533 534 535


/* Memory
 */

#ifdef USE_DMALLOC

536 537
#define g_malloc(size)	     (gpointer) MALLOC(size)
#define g_malloc0(size)	     (gpointer) CALLOC(char,size)
538
#define g_realloc(mem,size)  (gpointer) REALLOC(mem,char,size)
539
#define g_free(mem)	     FREE(mem)
540 541 542

#else /* USE_DMALLOC */

543 544
gpointer g_malloc      (gulong	  size);
gpointer g_malloc0     (gulong	  size);
545
gpointer g_realloc     (gpointer  mem,
546 547
			gulong	  size);
void	 g_free	       (gpointer  mem);
548 549 550

#endif /* USE_DMALLOC */

551 552
void	 g_mem_profile (void);
void	 g_mem_check   (gpointer  mem);
553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573


/* "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.
 */

574
#define G_ALLOC_ONLY	  1
575 576
#define G_ALLOC_AND_FREE  2

577 578 579 580 581
GMemChunk* g_mem_chunk_new     (gchar	  *name,
				gint	   atom_size,
				gulong	   area_size,
				gint	   type);
void	   g_mem_chunk_destroy (GMemChunk *mem_chunk);
582
gpointer   g_mem_chunk_alloc   (GMemChunk *mem_chunk);
583
void	   g_mem_chunk_free    (GMemChunk *mem_chunk,
584
				gpointer   mem);
585 586 587 588
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);
589 590 591 592 593 594 595 596 597 598 599 600 601 602

/* 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
 */
603 604 605 606 607 608 609
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);
610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627


/* Output
 */
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
void g_error   (gchar *format, ...) __attribute__ ((format (printf, 1, 2)));
void g_warning (gchar *format, ...) __attribute__ ((format (printf, 1, 2)));
void g_message (gchar *format, ...) __attribute__ ((format (printf, 1, 2)));
void g_print   (gchar *format, ...) __attribute__ ((format (printf, 1, 2)));
#else
void g_error   (gchar *format, ...);
void g_warning (gchar *format, ...);
void g_message (gchar *format, ...);
void g_print   (gchar *format, ...);
#endif

/* Utility functions
 */
628 629 630 631 632
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);
633 634 635 636 637 638 639 640 641 642 643 644

/* 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
 */
645
GErrorFunc   g_set_error_handler   (GErrorFunc	 func);
646 647 648 649
GWarningFunc g_set_warning_handler (GWarningFunc func);
GPrintFunc   g_set_message_handler (GPrintFunc func);
GPrintFunc   g_set_print_handler   (GPrintFunc func);

650
void g_debug	      (char *progname);
651 652 653 654 655 656
void g_attach_process (char *progname, int query);
void g_stack_trace    (char *progname, int query);


/* String Chunks
 */
657 658 659 660 661 662
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);
663 664 665

/* Strings
 */
666 667
GString* g_string_new	    (gchar   *init);
void	 g_string_free	    (GString *string,
668 669 670 671 672 673 674 675 676 677 678 679 680
			     gint     free_segment);
GString* g_string_assign    (GString *lval,
			     gchar   *rval);
GString* g_string_truncate  (GString *string,
			     gint     len);
GString* g_string_append    (GString *string,
			     gchar   *val);
GString* g_string_append_c  (GString *string,
			     gchar    c);
GString* g_string_prepend   (GString *string,
			     gchar   *val);
GString* g_string_prepend_c (GString *string,
			     gchar    c);
681
void	 g_string_sprintf   (GString *string,
682 683
			     gchar   *fmt,
			     ...);
684
void	 g_string_sprintfa  (GString *string,
685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702
			     gchar   *fmt,
			     ...);

/* 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]

703 704 705 706
GArray* g_array_new	  (gint	     zero_terminated);
void	g_array_free	  (GArray   *array,
			   gint	     free_segment);
GArray* g_rarray_append	  (GArray   *array,
707
			   gpointer  data,
708
			   gint	     size);
709 710
GArray* g_rarray_prepend  (GArray   *array,
			   gpointer  data,
711
			   gint	     size);
712
GArray* g_rarray_truncate (GArray   *array,
713 714
			   gint	     length,
			   gint	     size);
715 716 717 718 719 720 721 722

/* Hash Functions
 */
gint  g_string_equal (gpointer v,
		      gpointer v2);
guint g_string_hash  (gpointer v);


723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817

/* GScanner: Flexible lexical scanner for general purpose.
 * Copyright (C) 1997 Tim Janik
 */

/* 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"

typedef union	_GValue		GValue;
typedef struct	_GScannerConfig GScannerConfig;
typedef struct	_GScanner	GScanner;

/* 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?
   */
818
  guint		case_sensitive : 1;
819 820 821 822
  
  /* Boolean values to be adjusted "on the fly"
   * to configure scanning behaviour.
   */
823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841
  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;
842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894
};

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 */
  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);



895 896 897 898 899 900
#ifdef __cplusplus
}
#endif /* __cplusplus */


#endif /* __G_LIB_H__ */