* we define G_CAN_INLINE, if the compiler seems to be actually
* *capable* to do function inlining, in which case inline function bodys
* do make sense. we also define G_INLINE_FUNC to properly export the
- * function prototypes if no inlinig can be performed.
+ * function prototypes if no inlining can be performed.
* we special case most of the stuff, so inline functions can have a normal
* implementation by defining G_INLINE_FUNC to extern and G_CAN_INLINE to 1.
*/
((type *) g_realloc (mem, (unsigned) sizeof (type) * (count)))
#endif /* __DMALLOC_H__ */
+/* alloca-based counterparts of the above routines */
+#if G_HAVE_ALLOCA
+# define g_alloca alloca
+# define g_new_a(type, count) \
+ ((type *) alloca ((unsigned) sizeof (type) * (count)))
+# define g_new0_a(type, count) \
+ ((type *) memset (alloca ((unsigned) sizeof (type) * (count)), 0, \
+ ((unsigned) sizeof (type) * (count))))
+#endif /* G_HAVE_ALLOCA */
+
#define g_mem_chunk_create(type, pre_alloc, alloc_type) ( \
g_mem_chunk_new (#type " mem chunks (" #pre_alloc ")", \
sizeof (type), \
/* Portable endian checks and conversions
+ *
+ * glibconfig.h defines G_BYTE_ORDER which expands to one of
+ * the below macros.
*/
-
#define G_LITTLE_ENDIAN 1234
#define G_BIG_ENDIAN 4321
#define G_PDP_ENDIAN 3412 /* unused, need specific PDP check */
+
/* Basic bit swapping functions
*/
#define GUINT16_SWAP_LE_BE_CONSTANT(val) ((guint16) ( \
/* Intel specific stuff for speed
*/
#if defined (__i386__) && defined (__GNUC__) && __GNUC__ >= 2
-
# define GUINT16_SWAP_LE_BE_X86(val) \
(__extension__ \
({ register guint16 __v; \
: "=r" (__v) \
: "0" ((guint16) (val))); \
__v; }))
-
# define GUINT16_SWAP_LE_BE(val) (GUINT16_SWAP_LE_BE_X86 (val))
-
# if !defined(__i486__) && !defined(__i586__) \
&& !defined(__pentium__) && !defined(__i686__) && !defined(__pentiumpro__)
# define GUINT32_SWAP_LE_BE_X86(val) \
: "=r" (__v) \
: "0" ((guint32) (val))); \
__v; }))
-
# else /* 486 and higher has bswap */
# define GUINT32_SWAP_LE_BE_X86(val) \
(__extension__ \
: "0" ((guint32) (val))); \
__v; }))
# endif /* processor specific 32-bit stuff */
-
# define GUINT32_SWAP_LE_BE(val) (GUINT32_SWAP_LE_BE_X86 (val))
-
#else /* !__i386__ */
# define GUINT16_SWAP_LE_BE(val) (GUINT16_SWAP_LE_BE_CONSTANT (val))
# define GUINT32_SWAP_LE_BE(val) (GUINT32_SWAP_LE_BE_CONSTANT (val))
(guint64) G_GINT64_CONSTANT(0x00ff000000000000U)) >> 40) | \
(((guint64) (val) & \
(guint64) G_GINT64_CONSTANT(0xff00000000000000U)) >> 56)))
-
# if defined (__i386__) && defined (__GNUC__) && __GNUC__ >= 2
# define GUINT64_SWAP_LE_BE_X86(val) \
(__extension__ \
__r.__l[1] = GUINT32_SWAP_LE_BE (__w.__l[0]); \
} \
__r.__ll; }))
-
# define GUINT64_SWAP_LE_BE(val) (GUINT64_SWAP_LE_BE_X86 (val))
-
# else /* !__i386__ */
# define GUINT64_SWAP_LE_BE(val) (GUINT64_SWAP_LE_BE_CONSTANT(val))
# endif
(((guint32) (val) & (guint32) 0x00ff00ffU) << 8) | \
(((guint32) (val) & (guint32) 0xff00ff00U) >> 8)))
-/* The TO_?E stuff is defined in glibconfig.h. The transformation is symmetric,
- so the FROM just maps to the TO.
+/* The G*_TO_?E() macros are defined in glibconfig.h.
+ * The transformation is symmetric, so the FROM just maps to the TO.
*/
#define GINT16_FROM_LE(val) (GINT16_TO_LE (val))
#define GUINT16_FROM_LE(val) (GUINT16_TO_LE (val))
#define GUINT32_FROM_BE(val) (GUINT32_TO_BE (val))
#ifdef G_HAVE_GINT64
-#define GINT64_FROM_LE(val) (GINT32_TO_LE (val))
-#define GUINT64_FROM_LE(val) (GUINT32_TO_LE (val))
-#define GINT64_FROM_BE(val) (GINT32_TO_BE (val))
-#define GUINT64_FROM_BE(val) (GUINT32_TO_BE (val))
+#define GINT64_FROM_LE(val) (GINT64_TO_LE (val))
+#define GUINT64_FROM_LE(val) (GUINT64_TO_LE (val))
+#define GINT64_FROM_BE(val) (GINT64_TO_BE (val))
+#define GUINT64_FROM_BE(val) (GUINT64_TO_BE (val))
#endif
#define GLONG_FROM_LE(val) (GLONG_TO_LE (val))
#define GINT_FROM_BE(val) (GINT_TO_BE (val))
#define GUINT_FROM_BE(val) (GUINT_TO_BE (val))
+
/* Portable versions of host-network order stuff
*/
#define g_ntohl(val) (GUINT32_FROM_BE (val))
GUTILS_C_VAR const guint glib_interface_age;
GUTILS_C_VAR const guint glib_binary_age;
+
/* Forward declarations of glib types.
*/
-
typedef struct _GAllocator GAllocator;
typedef struct _GArray GArray;
typedef struct _GByteArray GByteArray;
typedef union _GTokenValue GTokenValue;
typedef struct _GIOChannel GIOChannel;
-
typedef enum
{
G_TRAVERSE_LEAFS = 1 << 0,
gboolean need_valids,
gpointer func,
gpointer data);
+/* return the first valid hook, and increment its reference count */
GHook* g_hook_first_valid (GHookList *hook_list,
gboolean may_be_in_call);
-GHook* g_hook_next_valid (GHook *hook,
+/* return the next valid hook with incremented reference count, and
+ * decrement the reference count of the original hook
+ */
+GHook* g_hook_next_valid (GHookList *hook_list,
+ GHook *hook,
gboolean may_be_in_call);
/* GHookCompareFunc implementation to insert hooks sorted by their id */
gpointer g_memdup (gconstpointer mem,
guint byte_size);
+/* Macros for dynamic strings via fast stack allocation
+ * All macros take a special first argument: the target gchar* string
+ */
+#if G_HAVE_ALLOCA
+# define g_strdup_a(newstr,str) G_STMT_START { \
+ gchar *__new; \
+ const gchar *__old = (str); \
+ if (__old) \
+ { \
+ size_t __len = strlen (__old) + 1; \
+ __new = alloca (__len); \
+ memcpy (__new, __old, __len); \
+ } \
+ else \
+ __new = NULL; \
+ (newstr) = __new; \
+ } G_STMT_END
+# define g_strndup_a(newstr,str,n) G_STMT_START { \
+ gchar *__new; \
+ const gchar *__old = (str); \
+ if (__old) \
+ { \
+ guint __n = (n); \
+ size_t __len = strlen (__old); \
+ if (__len > (__n)) \
+ __len = (__n); \
+ __new = alloca (__len + 1); \
+ memcpy (__new, __old, __len); \
+ __new[__len] = 0; \
+ } \
+ else \
+ __new = NULL; \
+ (newstr) = __new; \
+ } G_STMT_END
+# define g_strconcat3_a(newstr,str1,str2,str3) G_STMT_START { \
+ const gchar *__str1 = (str1); \
+ const gchar *__str2 = (str2); \
+ const gchar *__str3 = (str3); \
+ gchar *__new; \
+ if (__str1) { \
+ size_t __len1 = strlen (__str1); \
+ if (__str2) { \
+ size_t __len2 = strlen (__str2); \
+ if (__str3) { \
+ size_t __len3 = strlen (__str3); \
+ __new = alloca (__len1 + __len2 + __len3 + 1); \
+ __new[__len1 + __len2 + __len3] = 0; \
+ memcpy (__new + __len1 + __len2, __str3, __len3); \
+ } else { \
+ __new = alloca (__len1 + __len2 + 1); \
+ __new[__len1 + __len2] = 0; \
+ } \
+ memcpy (__new + __len1, __str2, __len2); \
+ } else { \
+ __new = alloca (__len1 + 1); \
+ __new[__len1] = 0; \
+ } \
+ memcpy (__new, __str1, __len1); \
+ } else \
+ __new = NULL; \
+ (newstr) = __new; \
+ } G_STMT_END
+#endif /* G_HAVE_ALLOCA */
+
+
/* NULL terminated string arrays.
* g_strsplit() splits up string into max_tokens tokens at delim and
* returns a newly allocated string array.
#define g_array_append_val(a,v) g_array_append_vals(a,&v,1)
#define g_array_prepend_val(a,v) g_array_prepend_vals(a,&v,1)
-#define g_array_insert_val(a,i,v) g_array_prepend_vals(a,i,&v,1)
+#define g_array_insert_val(a,i,v) g_array_insert_vals(a,i,&v,1)
#define g_array_index(a,t,i) (((t*)a->data)[i])
GArray* g_array_new (gboolean zero_terminated,
void g_scanner_scope_foreach_symbol (GScanner *scanner,
guint scope_id,
GHFunc func,
- gpointer func_data);
+ gpointer user_data);
gpointer g_scanner_lookup_symbol (GScanner *scanner,
const gchar *symbol);
void g_scanner_freeze_symbol_table (GScanner *scanner);
} G_STMT_END
-/* Completion */
+/* GCompletion
+ */
struct _GCompletion
{
void g_completion_free (GCompletion* cmp);
-/* GRelation: Indexed Relations. Imagine a really simple table in a
+/* GDate
+ *
+ * Date calculations (not time for now, to be resolved). These are a
+ * mutant combination of Steffen Beyer's DateCalc routines
+ * (http://www.perl.com/CPAN/authors/id/STBEY/) and Jon Trowbridge's
+ * date routines (written for in-house software). Written by Havoc
+ * Pennington <hp@pobox.com>
+ */
+
+typedef guint16 GDateYear;
+typedef guint8 GDateDay; /* day of the month */
+typedef struct _GDate GDate;
+/* make struct tm known without having to include time.h */
+struct tm;
+
+/* enum used to specify order of appearance in parsed date strings */
+typedef enum
+{
+ G_DATE_DAY = 0,
+ G_DATE_MONTH = 1,
+ G_DATE_YEAR = 2
+} GDateDMY;
+
+/* actual week and month values */
+typedef enum
+{
+ G_DATE_BAD_WEEKDAY = 0,
+ G_DATE_MONDAY = 1,
+ G_DATE_TUESDAY = 2,
+ G_DATE_WEDNESDAY = 3,
+ G_DATE_THURSDAY = 4,
+ G_DATE_FRIDAY = 5,
+ G_DATE_SATURDAY = 6,
+ G_DATE_SUNDAY = 7
+} GDateWeekday;
+typedef enum
+{
+ G_DATE_BAD_MONTH = 0,
+ G_DATE_JANUARY = 1,
+ G_DATE_FEBRUARY = 2,
+ G_DATE_MARCH = 3,
+ G_DATE_APRIL = 4,
+ G_DATE_MAY = 5,
+ G_DATE_JUNE = 6,
+ G_DATE_JULY = 7,
+ G_DATE_AUGUST = 8,
+ G_DATE_SEPTEMBER = 9,
+ G_DATE_OCTOBER = 10,
+ G_DATE_NOVEMBER = 11,
+ G_DATE_DECEMBER = 12
+} GDateMonth;
+
+#define G_DATE_BAD_JULIAN 0U
+#define G_DATE_BAD_DAY 0U
+#define G_DATE_BAD_YEAR 0U
+
+/* Note: directly manipulating structs is generally a bad idea, but
+ * in this case it's an *incredibly* bad idea, because all or part
+ * of this struct can be invalid at any given time. Use the functions,
+ * or you will get hosed, I promise.
+ */
+struct _GDate
+{
+ guint julian_days : 32; /* julian days representation - we use a
+ * bitfield hoping that 64 bit platforms
+ * will pack this whole struct in one big
+ * int
+ */
+
+ guint julian : 1; /* julian is valid */
+ guint dmy : 1; /* dmy is valid */
+
+ /* DMY representation */
+ guint day : 6;
+ guint month : 4;
+ guint year : 16;
+};
+
+/* g_date_new() returns an invalid date, you then have to _set() stuff
+ * to get a usable object. You can also allocate a GDate statically,
+ * then call g_date_clear() to initialize.
+ */
+GDate* g_date_new (void);
+GDate* g_date_new_dmy (GDateDay day,
+ GDateMonth month,
+ GDateYear year);
+GDate* g_date_new_julian (guint32 julian_day);
+void g_date_free (GDate *date);
+
+/* check g_date_valid() after doing an operation that might fail, like
+ * _parse. Almost all g_date operations are undefined on invalid
+ * dates (the exceptions are the mutators, since you need those to
+ * return to validity).
+ */
+gboolean g_date_valid (GDate *date);
+gboolean g_date_valid_day (GDateDay day);
+gboolean g_date_valid_month (GDateMonth month);
+gboolean g_date_valid_year (GDateYear year);
+gboolean g_date_valid_weekday (GDateWeekday weekday);
+gboolean g_date_valid_julian (guint32 julian_date);
+gboolean g_date_valid_dmy (GDateDay day,
+ GDateMonth month,
+ GDateYear year);
+
+GDateWeekday g_date_weekday (GDate *date);
+GDateMonth g_date_month (GDate *date);
+GDateYear g_date_year (GDate *date);
+GDateDay g_date_day (GDate *date);
+guint32 g_date_julian (GDate *date);
+guint g_date_day_of_year (GDate *date);
+
+/* First monday/sunday is the start of week 1; if we haven't reached
+ * that day, return 0. These are not ISO weeks of the year; that
+ * routine needs to be added.
+ * these functions return the number of weeks, starting on the
+ * corrsponding day
+ */
+guint g_date_monday_week_of_year (GDate *date);
+guint g_date_sunday_week_of_year (GDate *date);
+
+/* If you create a static date struct you need to clear it to get it
+ * in a sane state before use. You can clear a whole array at
+ * once with the ndates argument.
+ */
+void g_date_clear (GDate *date,
+ guint n_dates);
+
+/* The parse routine is meant for dates typed in by a user, so it
+ * permits many formats but tries to catch common typos. If your data
+ * needs to be strictly validated, it is not an appropriate function.
+ */
+void g_date_set_parse (GDate *date,
+ const gchar *str);
+void g_date_set_time (GDate *date,
+ GTime time);
+void g_date_set_month (GDate *date,
+ GDateMonth month);
+void g_date_set_day (GDate *date,
+ GDateDay day);
+void g_date_set_year (GDate *date,
+ GDateYear year);
+void g_date_set_dmy (GDate *date,
+ GDateDay day,
+ GDateMonth month,
+ GDateYear y);
+void g_date_set_julian (GDate *date,
+ guint32 julian_date);
+gboolean g_date_is_first_of_month (GDate *date);
+gboolean g_date_is_last_of_month (GDate *date);
+
+/* To go forward by some number of weeks just go forward weeks*7 days */
+void g_date_add_days (GDate *date,
+ guint n_days);
+void g_date_subtract_days (GDate *date,
+ guint n_days);
+
+/* If you add/sub months while day > 28, the day might change */
+void g_date_add_months (GDate *date,
+ guint n_months);
+void g_date_subtract_months (GDate *date,
+ guint n_months);
+
+/* If it's feb 29, changing years can move you to the 28th */
+void g_date_add_years (GDate *date,
+ guint n_years);
+void g_date_subtract_years (GDate *date,
+ guint n_years);
+gboolean g_date_is_leap_year (GDateYear year);
+guint8 g_date_days_in_month (GDateMonth month,
+ GDateYear year);
+guint8 g_date_monday_weeks_in_year (GDateYear year);
+guint8 g_date_sunday_weeks_in_year (GDateYear year);
+
+/* qsort-friendly (with a cast...) */
+gint g_date_compare (GDate *lhs,
+ GDate *rhs);
+void g_date_to_struct_tm (GDate *date,
+ struct tm *tm);
+
+/* Just like strftime() except you can only use date-related formats.
+ * Using a time format is undefined.
+ */
+gsize g_date_strftime (gchar *s,
+ gsize slen,
+ const gchar *format,
+ GDate *date);
+
+
+/* GRelation
+ *
+ * Indexed Relations. Imagine a really simple table in a
* database. Relations are not ordered. This data type is meant for
* maintaining a N-way mapping.
*
guint g_spaced_primes_closest (guint num);
+/* GIOChannel
+ */
+
+typedef struct _GIOFuncs GIOFuncs;
+typedef enum
+{
+ G_IO_ERROR_NONE,
+ G_IO_ERROR_AGAIN,
+ G_IO_ERROR_INVAL,
+ G_IO_ERROR_UNKNOWN
+} GIOError;
+typedef enum
+{
+ G_SEEK_CUR,
+ G_SEEK_SET,
+ G_SEEK_END
+} GSeekType;
+typedef enum
+{
+ G_IO_IN GLIB_SYSDEF_POLLIN,
+ G_IO_OUT GLIB_SYSDEF_POLLOUT,
+ G_IO_PRI GLIB_SYSDEF_POLLPRI,
+ G_IO_ERR GLIB_SYSDEF_POLLERR,
+ G_IO_HUP GLIB_SYSDEF_POLLHUP,
+ G_IO_NVAL GLIB_SYSDEF_POLLNVAL
+} GIOCondition;
+
+struct _GIOChannel
+{
+ guint channel_flags;
+ guint ref_count;
+ GIOFuncs *funcs;
+};
+
+typedef gboolean (*GIOFunc) (GIOChannel *source,
+ GIOCondition condition,
+ gpointer data);
+struct _GIOFuncs
+{
+ GIOError (*io_read) (GIOChannel *channel,
+ gchar *buf,
+ guint count,
+ guint *bytes_read);
+ GIOError (*io_write) (GIOChannel *channel,
+ gchar *buf,
+ guint count,
+ guint *bytes_written);
+ GIOError (*io_seek) (GIOChannel *channel,
+ gint offset,
+ GSeekType type);
+ void (*io_close) (GIOChannel *channel);
+ guint (*io_add_watch) (GIOChannel *channel,
+ gint priority,
+ GIOCondition condition,
+ GIOFunc func,
+ gpointer user_data,
+ GDestroyNotify notify);
+ void (*io_free) (GIOChannel *channel);
+};
+
+void g_io_channel_init (GIOChannel *channel);
+void g_io_channel_ref (GIOChannel *channel);
+void g_io_channel_unref (GIOChannel *channel);
+GIOError g_io_channel_read (GIOChannel *channel,
+ gchar *buf,
+ guint count,
+ guint *bytes_read);
+GIOError g_io_channel_write (GIOChannel *channel,
+ gchar *buf,
+ guint count,
+ guint *bytes_written);
+GIOError g_io_channel_seek (GIOChannel *channel,
+ gint offset,
+ GSeekType type);
+void g_io_channel_close (GIOChannel *channel);
+guint g_io_add_watch_full (GIOChannel *channel,
+ gint priority,
+ GIOCondition condition,
+ GIOFunc func,
+ gpointer user_data,
+ GDestroyNotify notify);
+guint g_io_add_watch (GIOChannel *channel,
+ GIOCondition condition,
+ GIOFunc func,
+ gpointer user_data);
+
+
+/* Main loop
+ */
+typedef struct _GTimeVal GTimeVal;
+typedef struct _GSourceFuncs GSourceFuncs;
+typedef struct _GMainLoop GMainLoop; /* Opaque */
+
+struct _GTimeVal
+{
+ glong tv_sec;
+ glong tv_usec;
+};
+struct _GSourceFuncs
+{
+ gboolean (*prepare) (gpointer source_data,
+ GTimeVal *current_time,
+ gint *timeout);
+ gboolean (*check) (gpointer source_data,
+ GTimeVal *current_time);
+ gboolean (*dispatch) (gpointer source_data,
+ GTimeVal *current_time,
+ gpointer user_data);
+ GDestroyNotify destroy;
+};
+
+/* Standard priorities */
+
+#define G_PRIORITY_HIGH -100
+#define G_PRIORITY_DEFAULT 0
+#define G_PRIORITY_HIGH_IDLE 100
+#define G_PRIORITY_DEFAULT_IDLE 200
+#define G_PRIORITY_LOW 300
+
+typedef gboolean (*GSourceFunc) (gpointer data);
+
+/* Hooks for adding to the main loop */
+guint g_source_add (gint priority,
+ gboolean can_recurse,
+ GSourceFuncs *funcs,
+ gpointer source_data,
+ gpointer user_data,
+ GDestroyNotify notify);
+void g_source_remove (guint tag);
+void g_source_remove_by_user_data (gpointer user_data);
+void g_source_remove_by_source_data (gpointer source_data);
+
+void g_get_current_time (GTimeVal *result);
+
+/* Running the main loop */
+GMainLoop* g_main_new (gboolean is_running);
+void g_main_run (GMainLoop *loop);
+void g_main_quit (GMainLoop *loop);
+void g_main_destroy (GMainLoop *loop);
+gboolean g_main_is_running (GMainLoop *loop);
+
+/* Run a single iteration of the mainloop. If block is FALSE,
+ * will never block
+ */
+gboolean g_main_iteration (gboolean may_block);
+
+/* See if any events are pending */
+gboolean g_main_pending (void);
+
+/* Idles and timeouts */
+guint g_timeout_add_full (gint priority,
+ guint interval,
+ GSourceFunc function,
+ gpointer data,
+ GDestroyNotify notify);
+guint g_timeout_add (guint interval,
+ GSourceFunc function,
+ gpointer data);
+guint g_idle_add (GSourceFunc function,
+ gpointer data);
+guint g_idle_add_full (gint priority,
+ GSourceFunc function,
+ gpointer data,
+ GDestroyNotify destroy);
+
+/* GPollFD
+ *
+ * Unix-specific IO and main loop calls
+ */
+
+typedef struct _GPollFD GPollFD;
+typedef gint (*GPollFunc) (GPollFD *ufds,
+ guint nfsd,
+ gint timeout);
+struct _GPollFD
+{
+ gint fd;
+ gushort events;
+ gushort revents;
+};
+
+void g_main_add_poll (GPollFD *fd,
+ gint priority);
+void g_main_remove_poll (GPollFD *fd);
+void g_main_set_poll_func (GPollFunc func);
+
+GIOChannel* g_io_channel_unix_new (int fd);
+gint g_io_channel_unix_get_fd (GIOChannel *channel);
+
+
+/* old IO Channels */
+#if 0
/* IO Channels.
* These are used for plug-in communication in the GIMP, for instance.
* On Unix, it's simply an encapsulated file descriptor (a pipe).
*/
#endif
};
-
GIOChannel *g_iochannel_new (gint fd);
void g_iochannel_free (GIOChannel *channel);
void g_iochannel_close_and_free (GIOChannel *channel);
#ifndef NATIVE_WIN32
# define g_iochannel_wakeup_peer(channel) G_STMT_START { } G_STMT_END
#endif
+#endif /* old IO Channels */
/* Windows emulation stubs for common unix functions
*/
#ifdef NATIVE_WIN32
-
-#define MAXPATHLEN 1024
-
-#ifdef _MSC_VER
+# define MAXPATHLEN 1024
+# ifdef _MSC_VER
typedef int pid_t;
/* These POSIXish functions are available in the Microsoft C library
* For some functions, we provide emulators in glib, which are prefixed
* with gwin_.
*/
-#define getcwd _getcwd
-#define getpid _getpid
-#define access _access
-#define open _open
-#define read _read
-#define write _write
-#define lseek _lseek
-#define close _close
-#define pipe(phandles) _pipe (phandles, 4096, _O_BINARY)
-#define popen _popen
-#define pclose _pclose
-#define fdopen _fdopen
-#define ftruncate(fd, size) gwin_ftruncate (fd, size)
-#define opendir gwin_opendir
-#define readdir gwin_readdir
-#define rewinddir gwin_rewinddir
-#define closedir gwin_closedir
-
-#define NAME_MAX 255
-
+# define getcwd _getcwd
+# define getpid _getpid
+# define access _access
+# define open _open
+# define read _read
+# define write _write
+# define lseek _lseek
+# define close _close
+# define pipe(phandles) _pipe (phandles, 4096, _O_BINARY)
+# define popen _popen
+# define pclose _pclose
+# define fdopen _fdopen
+# define ftruncate(fd, size) gwin_ftruncate (fd, size)
+# define opendir gwin_opendir
+# define readdir gwin_readdir
+# define rewinddir gwin_rewinddir
+# define closedir gwin_closedir
+# define NAME_MAX 255
struct DIR
{
gchar *dir_name;
-
gboolean just_opened;
guint find_file_handle;
gpointer find_file_data;
{
gchar d_name[NAME_MAX + 1];
};
-
/* emulation functions */
extern int gwin_ftruncate (gint f,
guint size);
struct dirent* gwin_readdir (DIR *dir);
void gwin_rewinddir (DIR *dir);
gint gwin_closedir (DIR *dir);
+# endif /* _MSC_VER */
+#endif /* NATIVE_WIN32 */
-#endif /* _MSC_VER */
-#endif /* NATIVE_WIN32 */
+/* GLib Thread support
+ */
+typedef struct _GMutex GMutex;
+typedef struct _GCond GCond;
+typedef struct _GPrivate GPrivate;
+typedef struct _GStaticPrivate GStaticPrivate;
+typedef struct _GThreadFunctions GThreadFunctions;
+struct _GThreadFunctions
+{
+ GMutex* (*mutex_new) (void);
+ void (*mutex_lock) (GMutex *mutex);
+ gboolean (*mutex_trylock) (GMutex *mutex);
+ void (*mutex_unlock) (GMutex *mutex);
+ void (*mutex_free) (GMutex *mutex);
+ GCond* (*cond_new) (void);
+ void (*cond_signal) (GCond *cond);
+ void (*cond_broadcast) (GCond *cond);
+ void (*cond_wait) (GCond *cond,
+ GMutex *mutex);
+ gboolean (*cond_timed_wait) (GCond *cond,
+ GMutex *mutex,
+ GTimeVal *end_time);
+ void (*cond_free) (GCond *cond);
+ GPrivate* (*private_new) (GDestroyNotify destructor);
+ gpointer (*private_get) (GPrivate *private_key);
+ void (*private_set) (GPrivate *private_key,
+ gpointer data);
+};
+GUTILS_C_VAR GThreadFunctions g_thread_functions_for_glib_use;
+GUTILS_C_VAR gboolean g_thread_use_default_impl;
+GUTILS_C_VAR gboolean g_threads_got_initialized;
+
+/* initializes the mutex/cond/private implementation for glib, might
+ * only be called once, and must not be called directly or indirectly
+ * from another glib-function, e.g. as a callback.
+ */
+void g_thread_init (GThreadFunctions *vtable);
+
+/* internal function for fallback static mutex implementation */
+GMutex* g_static_mutex_get_mutex_impl (GMutex **mutex);
+
+/* shorthands for conditional and unconditional function calls */
+#define G_THREAD_UF(name, arglist) \
+ (*g_thread_functions_for_glib_use . name) arglist
+#define G_THREAD_CF(name, fail, arg) \
+ (g_thread_supported () ? G_THREAD_UF (name, arg) : (fail))
+/* keep in mind, all those mutexes and static mutexes are not
+ * recursive in general, don't rely on that
+ */
+#define g_thread_supported() (g_threads_got_initialized)
+#define g_mutex_new() G_THREAD_UF (mutex_new, ())
+#define g_mutex_lock(mutex) G_THREAD_CF (mutex_lock, (void)0, (mutex))
+#define g_mutex_trylock(mutex) G_THREAD_CF (mutex_trylock, TRUE, (mutex))
+#define g_mutex_unlock(mutex) G_THREAD_CF (mutex_unlock, (void)0, (mutex))
+#define g_mutex_free(mutex) G_THREAD_CF (mutex_free, (void)0, (mutex))
+#define g_cond_new() G_THREAD_UF (cond_new, ())
+#define g_cond_signal(cond) G_THREAD_CF (cond_signal, (void)0, (cond))
+#define g_cond_broadcast(cond) G_THREAD_CF (cond_broadcast, (void)0, (cond))
+#define g_cond_wait(cond, mutex) G_THREAD_CF (cond_wait, (void)0, (cond, \
+ mutex))
+#define g_cond_free(cond) G_THREAD_CF (cond_free, (void)0, (cond))
+#define g_cond_timed_wait(cond, mutex, abs_time) G_THREAD_CF (cond_timed_wait, \
+ TRUE, \
+ (cond, mutex, \
+ abs_time))
+#define g_private_new(destructor) G_THREAD_UF (private_new, (destructor))
+#define g_private_get(private_key) G_THREAD_CF (private_get, \
+ ((gpointer)private_key), \
+ (private_key))
+#define g_private_set(private_key, value) G_THREAD_CF (private_set, \
+ (void) (private_key = \
+ (GPrivate*) (value)), \
+ (private_key, value))
+/* GStaticMutexes can be statically initialized with the value
+ * G_STATIC_MUTEX_INIT, and then they can directly be used, that is
+ * much easier, than having to explicitly allocate the mutex before
+ * use
+ */
+#define g_static_mutex_lock(mutex) \
+ g_mutex_lock (g_static_mutex_get_mutex (mutex))
+#define g_static_mutex_trylock(mutex) \
+ g_mutex_trylock (g_static_mutex_get_mutex (mutex))
+#define g_static_mutex_unlock(mutex) \
+ g_mutex_unlock (g_static_mutex_get_mutex (mutex))
+struct _GStaticPrivate
+{
+ guint index;
+};
+#define G_STATIC_PRIVATE_INIT { 0 }
+gpointer g_static_private_get (GStaticPrivate *private_key);
+void g_static_private_set (GStaticPrivate *private_key,
+ gpointer data,
+ GDestroyNotify notify);
+
+/* these are some convenience macros that expand to nothing if GLib was
+ * configured with --deisable-threads. for using StaticMutexes, you
+ * declare them with G_LOCK_DECLARE_STATIC (name) or G_LOCK_DECLARE (name)
+ * if you need to export the mutex. name is a unique identifier for the
+ * protected varibale or code portion. locking, testing and unlocking of
+ * such mutexes can be done with G_LOCK(), G_UNLOCK() and G_TRYLOCK()
+ * respectively.
+ */
+extern void glib_dummy_decl (void);
+#define G_LOCK_NAME(name) (g__ ## name ## _lock)
+#ifdef G_THREADS_ENABLED
+# define G_LOCK_DECLARE_STATIC(name) static G_LOCK_DECLARE (name)
+# define G_LOCK_DECLARE(name) \
+ GStaticMutex G_LOCK_NAME (name) = G_STATIC_MUTEX_INIT
+
+# ifdef G_DEBUG_LOCKS
+# define G_LOCK(name) G_STMT_START{ \
+ g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, \
+ "file %s: line %d (%s): locking: %s ", \
+ __FILE__, __LINE__, G_GNUC_PRETTY_FUNCTION, \
+ #name); \
+ g_static_mutex_lock (G_LOCK_NAME (name)); \
+ }G_STMT_END
+# define G_UNLOCK(name) G_STMT_START{ \
+ g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, \
+ "file %s: line %d (%s): unlocking: %s ", \
+ __FILE__, __LINE__, G_GNUC_PRETTY_FUNCTION, \
+ #name); \
+ g_static_mutex_unlock (G_LOCK_NAME (name)); \
+ }G_STMT_END
+# define G_TRYLOCK(name) G_STMT_START{ \
+ g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, \
+ "file %s: line %d (%s): try locking: %s ", \
+ __FILE__, __LINE__, G_GNUC_PRETTY_FUNCTION, \
+ #name); \
+ }G_STMT_END, g_static_mutex_trylock (G_LOCK_NAME (name))
+# else /* !G_DEBUG_LOCKS */
+# define G_LOCK(name) g_static_mutex_lock (G_LOCK_NAME (name))
+# define G_UNLOCK(name) g_static_mutex_unlock (G_LOCK_NAME (name))
+# define G_TRYLOCK(name) g_static_mutex_trylock (G_LOCK_NAME (name))
+# endif /* !G_DEBUG_LOCKS */
+#else /* !G_THREADS_ENABLED */
+# define G_LOCK_DECLARE_STATIC(name) extern void glib_dummy_decl (void)
+# define G_LOCK_DECLARE(name) extern void glib_dummy_decl (void)
+# define G_LOCK(name)
+# define G_UNLOCK(name)
+# define G_TRYLOCK(name) (FALSE)
+#endif /* !G_THREADS_ENABLED */
#ifdef __cplusplus
}