glib.h 26.1 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
#endif /* ABS */

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

#ifndef ATEXIT
125 126 127 128 129
#  ifdef HAVE_ATEXIT
#    define ATEXIT(proc)   (atexit (proc))
#  elif defined (HAVE_ON_EXIT)
#    define ATEXIT(proc)   (on_exit ((void (*)(int, void *))(proc), NULL))
#  endif    
130 131 132 133 134 135 136 137 138 139
#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__

140 141
#define g_new(type,count)	 ALLOC(type,count)
#define g_new0(type,count)	 CALLOC(type,count)
142 143 144

#else /* __DMALLOC_H__ */

145
#define g_new(type, count)	  \
146
    ((type *) g_malloc ((unsigned) sizeof (type) * (count)))
147
#define g_new0(type, count)	  \
148 149 150 151 152 153 154
    ((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
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
#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


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

189 190 191 192 193 194 195
#ifdef G_DISABLE_ASSERT

#define g_assert(expr)
#define g_assert_not_reached()

#else /* !G_DISABLE_ASSERT */

196 197
#ifdef __GNUC__

Tim Janik's avatar
GLib:  
Tim Janik committed
198
#define g_assert(expr)			G_STMT_START{\
199
     if (!(expr))				     \
200
       g_error ("file %s: line %d (%s): \"%s\"",     \
201 202 203
		__FILE__,			     \
		__LINE__,			     \
		__PRETTY_FUNCTION__,		     \
Tim Janik's avatar
GLib:  
Tim Janik committed
204
		#expr);			}G_STMT_END
205

Tim Janik's avatar
GLib:  
Tim Janik committed
206
#define g_assert_not_reached()		G_STMT_START{		      \
207
     g_error ("file %s: line %d (%s): \"should not be reached\"",     \
208 209
	      __FILE__,						      \
	      __LINE__,						      \
Tim Janik's avatar
GLib:  
Tim Janik committed
210
	      __PRETTY_FUNCTION__);	}G_STMT_END
211

212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
#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__

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

Tim Janik's avatar
GLib:  
Tim Janik committed
250
#define g_return_val_if_fail(expr,val)	G_STMT_START{	       \
251 252 253 254 255 256 257 258
     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
259
       };				}G_STMT_END
260

261
#else /* !__GNUC__ */
262

Tim Janik's avatar
GLib:  
Tim Janik committed
263
#define g_return_if_fail(expr)		G_STMT_START{	 \
264 265 266 267 268 269 270
     if (!(expr))					 \
       {						 \
	 g_warning ("file %s: line %d: \"%s\"",		 \
		    __FILE__,				 \
		    __LINE__,				 \
		    #expr);				 \
	 return;					 \
Tim Janik's avatar
GLib:  
Tim Janik committed
271
       };				}G_STMT_END
272

Tim Janik's avatar
GLib:  
Tim Janik committed
273
#define g_return_val_if_fail(expr, val)	G_STMT_START{	 \
274 275 276 277 278 279 280
     if (!(expr))					 \
       {						 \
	 g_warning ("file %s: line %d: \"%s\"",		 \
		    __FILE__,				 \
		    __LINE__,				 \
		    #expr);				 \
	 return val;					 \
Tim Janik's avatar
GLib:  
Tim Janik committed
281
       };				}G_STMT_END
282

283
#endif /* !__GNUC__ */
284

285
#endif /* G_DISABLE_CHECKS */
286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301

#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;
302
typedef char   gboolean;
303

304 305 306 307
typedef unsigned char	guchar;
typedef unsigned short	gushort;
typedef unsigned long	gulong;
typedef unsigned int	guint;
308

309 310
typedef float	gfloat;
typedef double	gdouble;
311 312 313 314 315 316 317 318 319 320 321 322 323 324 325

/* 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)
326 327
typedef signed char	gint8;
typedef unsigned char	guint8;
328 329 330 331
#endif /* SIZEOF_CHAR */


#if (SIZEOF_SHORT == 2)
332 333
typedef signed short	gint16;
typedef unsigned short	guint16;
334 335 336 337
#endif /* SIZEOF_SHORT */


#if (SIZEOF_INT == 4)
338 339
typedef signed int	gint32;
typedef unsigned int	guint32;
340
#elif (SIZEOF_LONG == 4)
341 342
typedef signed long	gint32;
typedef unsigned long	guint32;
343 344 345
#endif /* SIZEOF_INT */


346 347
typedef struct _GList	       GList;
typedef struct _GSList	       GSList;
348
typedef struct _GHashTable     GHashTable;
349 350 351
typedef struct _GCache	       GCache;
typedef struct _GTree	       GTree;
typedef struct _GTimer	       GTimer;
352 353 354
typedef struct _GMemChunk      GMemChunk;
typedef struct _GListAllocator GListAllocator;
typedef struct _GStringChunk   GStringChunk;
355 356
typedef struct _GString	       GString;
typedef struct _GArray	       GArray;
357
typedef struct _GDebugKey      GDebugKey;
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 390 391 392 393 394 395 396

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
{
397
  gchar *data;
398 399 400
  guint len;
};

401 402 403 404 405 406
struct _GDebugKey
{
  gchar *key;
  guint  value;
};

407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423
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
 */
424 425 426 427
GList* g_list_alloc	  (void);
void   g_list_free	  (GList     *list);
void   g_list_free_1	  (GList     *list);
GList* g_list_append	  (GList     *list,
428
			   gpointer   data);
429
GList* g_list_prepend	  (GList     *list,
430
			   gpointer   data);
431
GList* g_list_insert	  (GList     *list,
432
			   gpointer   data,
433
			   gint	      position);
434 435 436 437
GList* g_list_insert_sorted
			  (GList     *list,
			   gpointer   data,
			   GCompareFunc func);			    
438
GList* g_list_concat	  (GList     *list1, 
439
			   GList     *list2);
440
GList* g_list_remove	  (GList     *list,
441 442 443
			   gpointer   data);
GList* g_list_remove_link (GList     *list,
			   GList     *link);
444 445
GList* g_list_reverse	  (GList     *list);
GList* g_list_nth	  (GList     *list,
446
			   guint      n);
447
GList* g_list_find	  (GList     *list,
448
			   gpointer   data);
449 450
GList* g_list_last	  (GList     *list);
GList* g_list_first	  (GList     *list);
451
guint  g_list_length	  (GList     *list);
452
void   g_list_foreach	  (GList     *list,
453 454 455
			   GFunc      func,
			   gpointer   user_data);

456 457
#define g_list_previous(list) ((list) ? (((GList *)list)->prev) : NULL)
#define g_list_next(list) ((list) ? (((GList *)list)->next) : NULL)
458 459 460

/* Singly linked lists
 */
461 462 463 464
GSList* g_slist_alloc	    (void);
void	g_slist_free	    (GSList   *list);
void	g_slist_free_1	    (GSList   *list);
GSList* g_slist_append	    (GSList   *list,
465
			     gpointer  data);
466
GSList* g_slist_prepend	    (GSList   *list,
467
			     gpointer  data);
468
GSList* g_slist_insert	    (GSList   *list,
469 470
			     gpointer  data,
			     gint      position);
471 472 473 474
GSList* g_slist_insert_sorted
			    (GSList   *list,
			     gpointer  data,
			     GCompareFunc func);			    
475
GSList* g_slist_concat	    (GSList   *list1, 
476
			     GSList   *list2);
477
GSList* g_slist_remove	    (GSList   *list,
478 479 480
			     gpointer  data);
GSList* g_slist_remove_link (GSList   *list,
			     GSList   *link);
481 482
GSList* g_slist_reverse	    (GSList   *list);
GSList* g_slist_nth	    (GSList   *list,
483
			     guint     n);
484
GSList* g_slist_find	    (GSList   *list,
485
			     gpointer  data);
486
GSList* g_slist_last	    (GSList   *list);
487
guint	g_slist_length	    (GSList   *list);
488
void	g_slist_foreach	    (GSList   *list,
489 490 491
			     GFunc     func,
			     gpointer  user_data);

492
#define g_slist_next(list) ((list) ? (((GSList *)list)->next) : NULL)
493 494 495 496

/* List Allocators
 */
GListAllocator* g_list_allocator_new  (void);
497
void		g_list_allocator_free (GListAllocator* allocator);
498 499 500 501 502 503
GListAllocator* g_slist_set_allocator (GListAllocator* allocator);
GListAllocator* g_list_set_allocator  (GListAllocator* allocator);


/* Hash tables
 */
504 505 506 507 508 509 510 511 512
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,
513
				  const gpointer  key);
514 515 516 517 518
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);
519

520

521 522
/* Caches
 */
523
GCache*	 g_cache_new	       (GCacheNewFunc	   value_new_func,
524
				GCacheDestroyFunc  value_destroy_func,
525
				GCacheDupFunc	   key_dup_func,
526
				GCacheDestroyFunc  key_destroy_func,
527 528 529 530 531 532 533 534 535 536 537 538 539 540
				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);
541 542 543 544


/* Trees
 */
545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562
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);
563 564 565 566 567 568 569


/* Memory
 */

#ifdef USE_DMALLOC

570 571
#define g_malloc(size)	     (gpointer) MALLOC(size)
#define g_malloc0(size)	     (gpointer) CALLOC(char,size)
572
#define g_realloc(mem,size)  (gpointer) REALLOC(mem,char,size)
573
#define g_free(mem)	     FREE(mem)
574 575 576

#else /* USE_DMALLOC */

577 578
gpointer g_malloc      (gulong	  size);
gpointer g_malloc0     (gulong	  size);
579
gpointer g_realloc     (gpointer  mem,
580 581
			gulong	  size);
void	 g_free	       (gpointer  mem);
582 583 584

#endif /* USE_DMALLOC */

585 586
void	 g_mem_profile (void);
void	 g_mem_check   (gpointer  mem);
587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607


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

608
#define G_ALLOC_ONLY	  1
609 610
#define G_ALLOC_AND_FREE  2

611 612 613 614 615
GMemChunk* g_mem_chunk_new     (gchar	  *name,
				gint	   atom_size,
				gulong	   area_size,
				gint	   type);
void	   g_mem_chunk_destroy (GMemChunk *mem_chunk);
616
gpointer   g_mem_chunk_alloc   (GMemChunk *mem_chunk);
617
void	   g_mem_chunk_free    (GMemChunk *mem_chunk,
618
				gpointer   mem);
619 620 621 622
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);
623 624 625 626 627 628 629 630 631 632 633 634 635 636

/* 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
 */
637 638 639 640 641 642 643
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);
644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661


/* 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
 */
662 663 664 665 666
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);
667
gint    g_strcasecmp (const gchar *s1, const gchar *s2);
668 669 670
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
gint    g_snprintf   (gchar *str, gulong n, gchar const *fmt, ...) __attribute__ ((format (printf, 3, 4)));
#else
671
gint    g_snprintf   (gchar *str, gulong n, gchar const *fmt, ...);
672
#endif
673 674 675 676 677 678 679 680 681 682 683 684

/* 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
 */
685
GErrorFunc   g_set_error_handler   (GErrorFunc	 func);
686 687 688 689
GWarningFunc g_set_warning_handler (GWarningFunc func);
GPrintFunc   g_set_message_handler (GPrintFunc func);
GPrintFunc   g_set_print_handler   (GPrintFunc func);

690 691 692 693
guint        g_parse_debug_string  (const gchar *string, 
				    GDebugKey   *keys, 
				    guint        nkeys);

694
void g_debug	      (char *progname);
695 696 697 698 699 700
void g_attach_process (char *progname, int query);
void g_stack_trace    (char *progname, int query);


/* String Chunks
 */
701 702 703 704 705 706
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);
707 708 709

/* Strings
 */
710 711
GString* g_string_new	    (gchar   *init);
void	 g_string_free	    (GString *string,
712 713 714 715 716 717 718 719 720 721 722 723 724
			     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);
725 726 727 728 729 730 731 732 733
GString* g_string_insert    (GString *fstring, 
			     gint pos, 
			     gchar *val);
GString* g_string_insert_c  (GString *fstring, 
			     gint pos, 
			     gchar c);
GString* g_string_erase    (GString *fstring, 
			     gint pos, 
			     gint len);
734 735 736 737 738 739 740 741 742
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
void	 g_string_sprintf   (GString *string,
			     gchar   *fmt,
			     ...) __attribute__ ((format (printf, 2, 3)));

void	 g_string_sprintfa  (GString *string,
			     gchar   *fmt,
			     ...) __attribute__ ((format (printf, 2, 3)));
#else
743
void	 g_string_sprintf   (GString *string,
744 745
			     gchar   *fmt,
			     ...);
746

747
void	 g_string_sprintfa  (GString *string,
748 749
			     gchar   *fmt,
			     ...);
750
#endif
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
/* 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);
779 780 781

/* Hash Functions
 */
Owen Taylor's avatar
Owen Taylor committed
782 783 784
gint  g_str_equal (const gpointer v,
		   const gpointer v2);
guint g_str_hash  (const gpointer v);
785 786 787 788 789 790

/* 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);
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 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 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

/* 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?
   */
887
  guint		case_sensitive : 1;
888 889 890 891
  
  /* Boolean values to be adjusted "on the fly"
   * to configure scanning behaviour.
   */
892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910
  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;
911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963
};

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



964 965 966 967 968 969
#ifdef __cplusplus
}
#endif /* __cplusplus */


#endif /* __G_LIB_H__ */