glib.h 28.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/* 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
15 16 17
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
18
 */
19 20 21 22
#ifndef __G_LIB_H__
#define __G_LIB_H__

#include <glibconfig.h>
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

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

Tim Janik's avatar
Tim Janik committed
94 95
#undef	NULL
#define NULL ((void*) 0)
96

Tim Janik's avatar
Tim Janik committed
97 98
#undef	FALSE
#define FALSE	0
99

Tim Janik's avatar
Tim Janik committed
100 101
#undef	TRUE
#define TRUE	1
102

Tim Janik's avatar
Tim Janik committed
103
#undef	MAX
104 105
#define MAX(a, b)  (((a) > (b)) ? (a) : (b))

Tim Janik's avatar
Tim Janik committed
106
#undef	MIN
107 108
#define MIN(a, b)  (((a) < (b)) ? (a) : (b))

Tim Janik's avatar
Tim Janik committed
109
#undef	ABS
110
#define ABS(a)	   (((a) < 0) ? -(a) : (a))
111

Tim Janik's avatar
Tim Janik committed
112
#undef	CLAMP
113
#define CLAMP(x, low, high)  (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
Tim Janik's avatar
Tim Janik committed
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161

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

/* Wrap the __PRETTY_FUNCTION__ and __FUNCTION__ variables with macros,
 * so we can refer to them as strings unconditionally.
 */
#ifdef  __GNUC__
#define G_GNUC_FUNCTION         (__FUNCTION__)
#define G_GNUC_PRETTY_FUNCTION  (__PRETTY_FUNCTION__)
#else   /* !__GNUC__ */
#define G_GNUC_FUNCTION         ("")
#define G_GNUC_PRETTY_FUNCTION  ("")
#endif  /* !__GNUC__ */

162 163

#ifndef ATEXIT
164 165 166 167 168
#  ifdef HAVE_ATEXIT
#    define ATEXIT(proc)   (atexit (proc))
#  elif defined (HAVE_ON_EXIT)
#    define ATEXIT(proc)   (on_exit ((void (*)(int, void *))(proc), NULL))
#  endif    
169 170 171 172 173 174 175 176 177 178
#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__

179 180
#define g_new(type,count)	 ALLOC(type,count)
#define g_new0(type,count)	 CALLOC(type,count)
181 182 183

#else /* __DMALLOC_H__ */

184
#define g_new(type, count)	  \
185
    ((type *) g_malloc ((unsigned) sizeof (type) * (count)))
186
#define g_new0(type, count)	  \
187 188 189 190 191 192 193
    ((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
194 195 196 197 198
#define g_string(x) #x




199
/* Provide macros for error handling. The "assert" macros will
Tim Janik's avatar
GLib:  
Tim Janik committed
200
 *  exit on failure. The "return" macros will exit the current
201 202 203 204
 *  function. Two different definitions are given for the macros
 *  in order to support gcc's __PRETTY_FUNCTION__ capability.
 */

205 206 207 208 209 210 211
#ifdef G_DISABLE_ASSERT

#define g_assert(expr)
#define g_assert_not_reached()

#else /* !G_DISABLE_ASSERT */

212 213
#ifdef __GNUC__

Tim Janik's avatar
GLib:  
Tim Janik committed
214
#define g_assert(expr)			G_STMT_START{\
215
     if (!(expr))				     \
216
       g_error ("file %s: line %d (%s): \"%s\"",     \
217 218 219
		__FILE__,			     \
		__LINE__,			     \
		__PRETTY_FUNCTION__,		     \
Tim Janik's avatar
GLib:  
Tim Janik committed
220
		#expr);			}G_STMT_END
221

Tim Janik's avatar
GLib:  
Tim Janik committed
222
#define g_assert_not_reached()		G_STMT_START{		      \
223
     g_error ("file %s: line %d (%s): \"should not be reached\"",     \
224 225
	      __FILE__,						      \
	      __LINE__,						      \
Tim Janik's avatar
GLib:  
Tim Janik committed
226
	      __PRETTY_FUNCTION__);	}G_STMT_END
227

228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254
#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
255
#define g_return_if_fail(expr)		G_STMT_START{	       \
256 257 258 259 260 261 262 263
     if (!(expr))					       \
       {						       \
	 g_warning ("file %s: line %d (%s): \"%s\"",	       \
		    __FILE__,				       \
		    __LINE__,				       \
		    __PRETTY_FUNCTION__,		       \
		    #expr);				       \
	 return;					       \
Tim Janik's avatar
GLib:  
Tim Janik committed
264
       };				}G_STMT_END
265

Tim Janik's avatar
GLib:  
Tim Janik committed
266
#define g_return_val_if_fail(expr,val)	G_STMT_START{	       \
267 268 269 270 271 272 273 274
     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
275
       };				}G_STMT_END
276

277
#else /* !__GNUC__ */
278

Tim Janik's avatar
GLib:  
Tim Janik committed
279
#define g_return_if_fail(expr)		G_STMT_START{	 \
280 281 282 283 284 285 286
     if (!(expr))					 \
       {						 \
	 g_warning ("file %s: line %d: \"%s\"",		 \
		    __FILE__,				 \
		    __LINE__,				 \
		    #expr);				 \
	 return;					 \
Tim Janik's avatar
GLib:  
Tim Janik committed
287
       };				}G_STMT_END
288

Tim Janik's avatar
GLib:  
Tim Janik committed
289
#define g_return_val_if_fail(expr, val)	G_STMT_START{	 \
290 291 292 293 294 295 296
     if (!(expr))					 \
       {						 \
	 g_warning ("file %s: line %d: \"%s\"",		 \
		    __FILE__,				 \
		    __LINE__,				 \
		    #expr);				 \
	 return val;					 \
Tim Janik's avatar
GLib:  
Tim Janik committed
297
       };				}G_STMT_END
298

299
#endif /* !__GNUC__ */
300

301
#endif /* G_DISABLE_CHECKS */
302

303 304


305 306
#ifdef __cplusplus
extern "C" {
307
#pragma }
308 309 310 311 312 313 314 315 316 317 318 319 320
#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;
321
typedef char   gboolean;
322

323 324 325 326
typedef unsigned char	guchar;
typedef unsigned short	gushort;
typedef unsigned long	gulong;
typedef unsigned int	guint;
327

328 329
typedef float	gfloat;
typedef double	gdouble;
330 331 332 333 334 335 336 337 338 339 340 341 342 343 344

/* 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)
345 346
typedef signed char	gint8;
typedef unsigned char	guint8;
347 348 349 350
#endif /* SIZEOF_CHAR */


#if (SIZEOF_SHORT == 2)
351 352
typedef signed short	gint16;
typedef unsigned short	guint16;
353 354 355 356
#endif /* SIZEOF_SHORT */


#if (SIZEOF_INT == 4)
357 358
typedef signed int	gint32;
typedef unsigned int	guint32;
359
#elif (SIZEOF_LONG == 4)
360 361
typedef signed long	gint32;
typedef unsigned long	guint32;
362 363 364
#endif /* SIZEOF_INT */


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 397 398 399 400 401 402 403
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);
404 405
typedef void		(*GDestroyNotify)	(gpointer  data);

406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427

struct _GList
{
  gpointer data;
  GList *next;
  GList *prev;
};

struct _GSList
{
  gpointer data;
  GSList *next;
};

struct _GString
{
  gchar *str;
  gint len;
};

struct _GArray
{
428
  gchar *data;
429 430 431
  guint len;
};

432 433 434 435 436 437
struct _GDebugKey
{
  gchar *key;
  guint  value;
};

438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454
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
 */
455 456 457 458
GList* g_list_alloc	  (void);
void   g_list_free	  (GList     *list);
void   g_list_free_1	  (GList     *list);
GList* g_list_append	  (GList     *list,
459
			   gpointer   data);
460
GList* g_list_prepend	  (GList     *list,
461
			   gpointer   data);
462
GList* g_list_insert	  (GList     *list,
463
			   gpointer   data,
464
			   gint	      position);
465 466 467 468
GList* g_list_insert_sorted
			  (GList     *list,
			   gpointer   data,
			   GCompareFunc func);			    
469
GList* g_list_concat	  (GList     *list1, 
470
			   GList     *list2);
471
GList* g_list_remove	  (GList     *list,
472 473 474
			   gpointer   data);
GList* g_list_remove_link (GList     *list,
			   GList     *link);
475 476
GList* g_list_reverse	  (GList     *list);
GList* g_list_nth	  (GList     *list,
477
			   guint      n);
478 479
GList* g_list_find	  (GList     *list,
			   gpointer   data);
480 481
gint   g_list_position    (GList     *list,
			   GList     *link);
482
gint   g_list_index	  (GList     *list,
483
			   gpointer   data);
484 485
GList* g_list_last	  (GList     *list);
GList* g_list_first	  (GList     *list);
486
guint  g_list_length	  (GList     *list);
487
void   g_list_foreach	  (GList     *list,
488 489 490
			   GFunc      func,
			   gpointer   user_data);

491 492
#define g_list_previous(list) ((list) ? (((GList *)list)->prev) : NULL)
#define g_list_next(list) ((list) ? (((GList *)list)->next) : NULL)
493 494 495

/* Singly linked lists
 */
496 497 498 499
GSList* g_slist_alloc	    (void);
void	g_slist_free	    (GSList   *list);
void	g_slist_free_1	    (GSList   *list);
GSList* g_slist_append	    (GSList   *list,
500
			     gpointer  data);
501
GSList* g_slist_prepend	    (GSList   *list,
502
			     gpointer  data);
503
GSList* g_slist_insert	    (GSList   *list,
504 505
			     gpointer  data,
			     gint      position);
506 507 508 509
GSList* g_slist_insert_sorted
			    (GSList   *list,
			     gpointer  data,
			     GCompareFunc func);			    
510
GSList* g_slist_concat	    (GSList   *list1, 
511
			     GSList   *list2);
512
GSList* g_slist_remove	    (GSList   *list,
513 514 515
			     gpointer  data);
GSList* g_slist_remove_link (GSList   *list,
			     GSList   *link);
516 517
GSList* g_slist_reverse	    (GSList   *list);
GSList* g_slist_nth	    (GSList   *list,
518
			     guint     n);
519
GSList* g_slist_find	    (GSList   *list,
520
			     gpointer  data);
521 522 523 524
gint    g_slist_position    (GSList   *list,
			     GSList   *link);
gint	g_slist_index	    (GSList   *list,
			     gpointer  data);
525
GSList* g_slist_last	    (GSList   *list);
526
guint	g_slist_length	    (GSList   *list);
527
void	g_slist_foreach	    (GSList   *list,
528 529 530
			     GFunc     func,
			     gpointer  user_data);

531
#define g_slist_next(list) ((list) ? (((GSList *)list)->next) : NULL)
532 533 534 535

/* List Allocators
 */
GListAllocator* g_list_allocator_new  (void);
536
void		g_list_allocator_free (GListAllocator* allocator);
537 538 539 540 541 542
GListAllocator* g_slist_set_allocator (GListAllocator* allocator);
GListAllocator* g_list_set_allocator  (GListAllocator* allocator);


/* Hash tables
 */
543 544 545 546 547 548 549 550 551
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,
552
				  const gpointer  key);
553 554 555 556 557
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);
558

559

560 561
/* Caches
 */
562
GCache*	 g_cache_new	       (GCacheNewFunc	   value_new_func,
563
				GCacheDestroyFunc  value_destroy_func,
564
				GCacheDupFunc	   key_dup_func,
565
				GCacheDestroyFunc  key_destroy_func,
566 567 568 569 570 571 572 573 574 575 576 577 578 579
				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);
580 581 582 583


/* Trees
 */
584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601
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);
602 603 604 605 606 607 608


/* Memory
 */

#ifdef USE_DMALLOC

609 610
#define g_malloc(size)	     (gpointer) MALLOC(size)
#define g_malloc0(size)	     (gpointer) CALLOC(char,size)
611
#define g_realloc(mem,size)  (gpointer) REALLOC(mem,char,size)
612
#define g_free(mem)	     FREE(mem)
613 614 615

#else /* USE_DMALLOC */

616 617
gpointer g_malloc      (gulong	  size);
gpointer g_malloc0     (gulong	  size);
618
gpointer g_realloc     (gpointer  mem,
619 620
			gulong	  size);
void	 g_free	       (gpointer  mem);
621 622 623

#endif /* USE_DMALLOC */

624 625
void	 g_mem_profile (void);
void	 g_mem_check   (gpointer  mem);
626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646


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

647
#define G_ALLOC_ONLY	  1
648 649
#define G_ALLOC_AND_FREE  2

650 651 652 653 654
GMemChunk* g_mem_chunk_new     (gchar	  *name,
				gint	   atom_size,
				gulong	   area_size,
				gint	   type);
void	   g_mem_chunk_destroy (GMemChunk *mem_chunk);
655
gpointer   g_mem_chunk_alloc   (GMemChunk *mem_chunk);
656
void	   g_mem_chunk_free    (GMemChunk *mem_chunk,
657
				gpointer   mem);
658 659 660 661
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);
662 663 664 665 666 667 668 669 670 671 672 673 674 675

/* 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
 */
676 677 678 679 680 681 682
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);
683 684 685 686


/* Output
 */
687 688 689 690
void g_error   (const gchar *format, ...) G_GNUC_PRINTF (1, 2);
void g_warning (const gchar *format, ...) G_GNUC_PRINTF (1, 2);
void g_message (const gchar *format, ...) G_GNUC_PRINTF (1, 2);
void g_print   (const gchar *format, ...) G_GNUC_PRINTF (1, 2);
691 692 693

/* Utility functions
 */
694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715
#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);
716 717 718 719 720 721 722 723 724 725 726 727

/* 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
 */
728
GErrorFunc   g_set_error_handler   (GErrorFunc	 func);
729 730 731 732
GWarningFunc g_set_warning_handler (GWarningFunc func);
GPrintFunc   g_set_message_handler (GPrintFunc func);
GPrintFunc   g_set_print_handler   (GPrintFunc func);

733 734 735 736 737
void g_debug	      (const gchar *progname);
void g_attach_process (const gchar *progname,
		       gint         query);
void g_stack_trace    (const gchar *progname,
		       gint         query);
738 739 740 741


/* String Chunks
 */
742 743 744
GStringChunk* g_string_chunk_new	   (gint size);
void	      g_string_chunk_free	   (GStringChunk *chunk);
gchar*	      g_string_chunk_insert	   (GStringChunk *chunk,
745
					    const gchar	 *string);
746
gchar*	      g_string_chunk_insert_const  (GStringChunk *chunk,
747
					    const gchar	 *string);
748 749 750

/* Strings
 */
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
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);
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
/* 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);
811 812 813

/* Hash Functions
 */
Owen Taylor's avatar
Owen Taylor committed
814 815 816
gint  g_str_equal (const gpointer v,
		   const gpointer v2);
guint g_str_hash  (const gpointer v);
817 818 819 820 821 822

/* 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);
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
/* Associated Data
 */
void	  g_dataset_destroy		(const gpointer	 dataset_location);
guint	  g_dataset_try_key		(const gchar    *key);
guint	  g_dataset_force_id		(const gchar    *key);
gpointer  g_dataset_id_get_data		(const gpointer	 dataset_location,
					 guint		 key_id);
void	  g_dataset_id_set_data_full	(const gpointer	 dataset_location,
					 guint		 key_id,
					 gpointer        data,
					 GDestroyNotify	 destroy_func);
void	  g_dataset_id_set_destroy	(const gpointer	 dataset_location,
					 guint		 key_id,
					 GDestroyNotify	 destroy_func);

#define	  g_dataset_id_set_data(l,k,d)	G_STMT_START{g_dataset_id_set_data_full((l),(k),(d),NULL);}G_STMT_END
#define	  g_dataset_id_remove_data(l,k)	G_STMT_START{g_dataset_id_set_data((l),(k),NULL);}G_STMT_END
#define	  g_dataset_get_data(l,k)	(g_dataset_id_get_data((l),g_dataset_try_key(k)))
#define	  g_dataset_set_data_full(l,k,d,f) G_STMT_START{g_dataset_id_set_data_full((l),g_dataset_force_id(k),(d),(f));}G_STMT_END
#define	  g_dataset_set_destroy(l,k,f)  G_STMT_START{g_dataset_id_set_destroy((l),g_dataset_force_id(k),(f));}G_STMT_END
#define	  g_dataset_set_data(l,k,d)	G_STMT_START{g_dataset_set_data_full((l),(k),(d),NULL);}G_STMT_END
#define	  g_dataset_remove_data(l,k)	G_STMT_START{g_dataset_set_data((l),(k),NULL);}G_STMT_END


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 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 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
/* 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?
   */
938
  guint		case_sensitive : 1;
939 940 941 942
  
  /* Boolean values to be adjusted "on the fly"
   * to configure scanning behaviour.
   */
943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961
  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;
962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988
};

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;
Tim Janik's avatar
Tim Janik committed
989 990

  GScannerMsgFunc	msg_handler;
991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013
};

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);
1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027
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);
1028 1029 1030



1031 1032 1033 1034 1035 1036
#ifdef __cplusplus
}
#endif /* __cplusplus */


#endif /* __G_LIB_H__ */