Navit SVN

/work/compile/navit/src/navit/support/glib/gutils.h

00001 /* GLIB - Library of useful routines for C programming
00002  * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Lesser General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Lesser General Public
00015  * License along with this library; if not, write to the
00016  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00017  * Boston, MA 02111-1307, USA.
00018  */
00019 
00020 /*
00021  * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
00022  * file for a list of people on the GLib Team.  See the ChangeLog
00023  * files for a list of changes.  These files are distributed with
00024  * GLib at ftp://ftp.gtk.org/pub/gtk/.
00025  */
00026 
00027 #if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
00028 #error "Only <glib.h> can be included directly."
00029 #endif
00030 
00031 #ifndef __G_UTILS_H__
00032 #define __G_UTILS_H__
00033 
00034 #include <glib/gtypes.h>
00035 #include <stdarg.h>
00036 
00037 G_BEGIN_DECLS
00038 
00039 #ifdef G_OS_WIN32
00040 
00041 /* On Win32, the canonical directory separator is the backslash, and
00042  * the search path separator is the semicolon. Note that also the
00043  * (forward) slash works as directory separator.
00044  */
00045 #define G_DIR_SEPARATOR '\\'
00046 #define G_DIR_SEPARATOR_S "\\"
00047 #define G_IS_DIR_SEPARATOR(c) ((c) == G_DIR_SEPARATOR || (c) == '/')
00048 #define G_SEARCHPATH_SEPARATOR ';'
00049 #define G_SEARCHPATH_SEPARATOR_S ";"
00050 
00051 #else  /* !G_OS_WIN32 */
00052 
00053 /* Unix */
00054 
00055 #define G_DIR_SEPARATOR '/'
00056 #define G_DIR_SEPARATOR_S "/"
00057 #define G_IS_DIR_SEPARATOR(c) ((c) == G_DIR_SEPARATOR)
00058 #define G_SEARCHPATH_SEPARATOR ':'
00059 #define G_SEARCHPATH_SEPARATOR_S ":"
00060 
00061 #endif /* !G_OS_WIN32 */
00062 
00063 /* Define G_VA_COPY() to do the right thing for copying va_list variables.
00064  * glibconfig.h may have already defined G_VA_COPY as va_copy or __va_copy.
00065  */
00066 #if !defined (G_VA_COPY)
00067 #  if defined (__GNUC__) && defined (__PPC__) && (defined (_CALL_SYSV) || defined (_WIN32))
00068 #    define G_VA_COPY(ap1, ap2)   (*(ap1) = *(ap2))
00069 #  elif defined (G_VA_COPY_AS_ARRAY)
00070 #    define G_VA_COPY(ap1, ap2)   g_memmove ((ap1), (ap2), sizeof (va_list))
00071 #  else /* va_list is a pointer */
00072 #    define G_VA_COPY(ap1, ap2)   ((ap1) = (ap2))
00073 #  endif /* va_list is a pointer */
00074 #endif /* !G_VA_COPY */
00075 
00076 /* inlining hassle. for compilers that don't allow the `inline' keyword,
00077  * mostly because of strict ANSI C compliance or dumbness, we try to fall
00078  * back to either `__inline__' or `__inline'.
00079  * G_CAN_INLINE is defined in glibconfig.h if the compiler seems to be 
00080  * actually *capable* to do function inlining, in which case inline 
00081  * function bodies do make sense. we also define G_INLINE_FUNC to properly 
00082  * export the function prototypes if no inlining can be performed.
00083  * inline function bodies have to be special cased with G_CAN_INLINE and a
00084  * .c file specific macro to allow one compiled instance with extern linkage
00085  * of the functions by defining G_IMPLEMENT_INLINES and the .c file macro.
00086  */
00087 #if defined (G_HAVE_INLINE) && defined (__GNUC__) && defined (__STRICT_ANSI__)
00088 #  undef inline
00089 #  define inline __inline__
00090 #elif !defined (G_HAVE_INLINE)
00091 #  undef inline
00092 #  if defined (G_HAVE___INLINE__)
00093 #    define inline __inline__
00094 #  elif defined (G_HAVE___INLINE)
00095 #    define inline __inline
00096 #  else /* !inline && !__inline__ && !__inline */
00097 #    define inline  /* don't inline, then */
00098 #  endif
00099 #endif
00100 #ifdef G_IMPLEMENT_INLINES
00101 #  define G_INLINE_FUNC
00102 #  undef  G_CAN_INLINE
00103 #elif defined (__GNUC__) 
00104 #  define G_INLINE_FUNC static __inline __attribute__ ((unused))
00105 #elif defined (G_CAN_INLINE) 
00106 #  define G_INLINE_FUNC static inline
00107 #else /* can't inline */
00108 #  define G_INLINE_FUNC
00109 #endif /* !G_INLINE_FUNC */
00110 
00111 /* Retrive static string info
00112  */
00113 #ifdef G_OS_WIN32
00114 #define g_get_user_name g_get_user_name_utf8
00115 #define g_get_real_name g_get_real_name_utf8
00116 #define g_get_home_dir g_get_home_dir_utf8
00117 #define g_get_tmp_dir g_get_tmp_dir_utf8
00118 #endif
00119 
00120 G_CONST_RETURN gchar* g_get_user_name        (void);
00121 G_CONST_RETURN gchar* g_get_real_name        (void);
00122 G_CONST_RETURN gchar* g_get_home_dir         (void);
00123 G_CONST_RETURN gchar* g_get_tmp_dir          (void);
00124 G_CONST_RETURN gchar* g_get_host_name        (void);
00125 gchar*                g_get_prgname          (void);
00126 void                  g_set_prgname          (const gchar *prgname);
00127 G_CONST_RETURN gchar* g_get_application_name (void);
00128 void                  g_set_application_name (const gchar *application_name);
00129 
00130 void    g_reload_user_special_dirs_cache     (void);
00131 G_CONST_RETURN gchar*    g_get_user_data_dir      (void);
00132 G_CONST_RETURN gchar*    g_get_user_config_dir    (void);
00133 G_CONST_RETURN gchar*    g_get_user_cache_dir     (void);
00134 G_CONST_RETURN gchar* G_CONST_RETURN * g_get_system_data_dirs   (void);
00135 
00136 #ifdef G_OS_WIN32
00137 /* This functions is not part of the public GLib API */
00138 G_CONST_RETURN gchar* G_CONST_RETURN * g_win32_get_system_data_dirs_for_module (void (*address_of_function)(void));
00139 #endif
00140 
00141 #if defined (G_OS_WIN32) && defined (G_CAN_INLINE) && !defined (__cplusplus)
00142 /* This function is not part of the public GLib API either. Just call
00143  * g_get_system_data_dirs() in your code, never mind that that is
00144  * actually a macro and you will in fact call this inline function.
00145  */
00146 static inline G_CONST_RETURN gchar * G_CONST_RETURN *
00147 _g_win32_get_system_data_dirs (void)
00148 {
00149   return g_win32_get_system_data_dirs_for_module ((void (*)(void)) &_g_win32_get_system_data_dirs);
00150 }
00151 #define g_get_system_data_dirs _g_win32_get_system_data_dirs
00152 #endif
00153 
00154 G_CONST_RETURN gchar* G_CONST_RETURN * g_get_system_config_dirs (void);
00155 
00156 G_CONST_RETURN gchar* G_CONST_RETURN * g_get_language_names (void);
00157 
00180 typedef enum {
00181   G_USER_DIRECTORY_DESKTOP,
00182   G_USER_DIRECTORY_DOCUMENTS,
00183   G_USER_DIRECTORY_DOWNLOAD,
00184   G_USER_DIRECTORY_MUSIC,
00185   G_USER_DIRECTORY_PICTURES,
00186   G_USER_DIRECTORY_PUBLIC_SHARE,
00187   G_USER_DIRECTORY_TEMPLATES,
00188   G_USER_DIRECTORY_VIDEOS,
00189 
00190   G_USER_N_DIRECTORIES
00191 } GUserDirectory;
00192 
00193 G_CONST_RETURN gchar* g_get_user_special_dir (GUserDirectory directory);
00194 
00195 typedef struct _GDebugKey       GDebugKey;
00196 struct _GDebugKey
00197 {
00198   const gchar *key;
00199   guint        value;
00200 };
00201 
00202 /* Miscellaneous utility functions
00203  */
00204 guint                 g_parse_debug_string (const gchar     *string,
00205                                             const GDebugKey *keys,
00206                                             guint            nkeys);
00207 
00208 gint                  g_snprintf           (gchar       *string,
00209                                             gulong       n,
00210                                             gchar const *format,
00211                                             ...) G_GNUC_PRINTF (3, 4);
00212 gint                  g_vsnprintf          (gchar       *string,
00213                                             gulong       n,
00214                                             gchar const *format,
00215                                             va_list      args);
00216 
00217 /* Check if a file name is an absolute path */
00218 gboolean              g_path_is_absolute   (const gchar *file_name);
00219 
00220 /* In case of absolute paths, skip the root part */
00221 G_CONST_RETURN gchar* g_path_skip_root     (const gchar *file_name);
00222 
00223 #ifndef G_DISABLE_DEPRECATED
00224 
00225 /* These two functions are deprecated and will be removed in the next
00226  * major release of GLib. Use g_path_get_dirname/g_path_get_basename
00227  * instead. Whatch out! The string returned by g_path_get_basename
00228  * must be g_freed, while the string returned by g_basename must not.*/
00229 G_CONST_RETURN gchar* g_basename           (const gchar *file_name);
00230 #define g_dirname g_path_get_dirname
00231 
00232 #endif /* G_DISABLE_DEPRECATED */
00233 
00234 #ifdef G_OS_WIN32
00235 #define g_get_current_dir g_get_current_dir_utf8
00236 #endif
00237 
00238 /* The returned strings are newly allocated with g_malloc() */
00239 gchar*                g_get_current_dir    (void);
00240 gchar*                g_path_get_basename  (const gchar *file_name) G_GNUC_MALLOC;
00241 gchar*                g_path_get_dirname   (const gchar *file_name) G_GNUC_MALLOC;
00242 
00243 /* Set the pointer at the specified location to NULL */
00244 void                  g_nullify_pointer    (gpointer    *nullify_location);
00245 
00246 /* return the environment string for the variable. The returned memory
00247  * must not be freed. */
00248 #ifdef G_OS_WIN32
00249 #define g_getenv g_getenv_utf8
00250 #define g_setenv g_setenv_utf8
00251 #define g_unsetenv g_unsetenv_utf8
00252 #define g_find_program_in_path g_find_program_in_path_utf8
00253 #endif
00254 
00255 G_CONST_RETURN gchar* g_getenv             (const gchar *variable);
00256 gboolean              g_setenv             (const gchar *variable,
00257                                             const gchar *value,
00258                                             gboolean     overwrite);
00259 void                  g_unsetenv           (const gchar *variable);
00260 gchar**               g_listenv            (void);
00261 
00262 /* private */
00263 const gchar*         _g_getenv_nomalloc    (const gchar *variable,
00264                                             gchar        buffer[1024]);
00265 
00266 /* we try to provide a useful equivalent for ATEXIT if it is
00267  * not defined, but use is actually abandoned. people should
00268  * use g_atexit() instead.
00269  */
00270 typedef void            (*GVoidFunc)            (void);
00271 #ifndef ATEXIT
00272 # define ATEXIT(proc)   g_ATEXIT(proc)
00273 #else
00274 # define G_NATIVE_ATEXIT
00275 #endif /* ATEXIT */
00276 /* we use a GLib function as a replacement for ATEXIT, so
00277  * the programmer is not required to check the return value
00278  * (if there is any in the implementation) and doesn't encounter
00279  * missing include files.
00280  */
00281 void    g_atexit                (GVoidFunc    func);
00282 
00283 #ifdef G_OS_WIN32
00284 /* It's a bad idea to wrap atexit() on Windows. If the GLib DLL calls
00285  * atexit(), the function will be called when the GLib DLL is detached
00286  * from the program, which is not what the caller wants. The caller
00287  * wants the function to be called when it *itself* exits (or is
00288  * detached, in case the caller, too, is a DLL).
00289  */
00290 #if (defined(__MINGW_H) && !defined(_STDLIB_H_)) || (defined(_MSC_VER) && !defined(_INC_STDLIB))
00291 int atexit (void (*)(void));
00292 #endif
00293 #define g_atexit(func) atexit(func)
00294 #endif
00295 
00296 /* Look for an executable in PATH, following execvp() rules */
00297 gchar*  g_find_program_in_path  (const gchar *program);
00298 
00299 /* Bit tests
00300  */
00301 G_INLINE_FUNC gint      g_bit_nth_lsf (gulong  mask,
00302                                        gint    nth_bit) G_GNUC_CONST;
00303 G_INLINE_FUNC gint      g_bit_nth_msf (gulong  mask,
00304                                        gint    nth_bit) G_GNUC_CONST;
00305 G_INLINE_FUNC guint     g_bit_storage (gulong  number) G_GNUC_CONST;
00306 
00307 /* Trash Stacks
00308  * elements need to be >= sizeof (gpointer)
00309  */
00310 typedef struct _GTrashStack     GTrashStack;
00311 struct _GTrashStack
00312 {
00313   GTrashStack *next;
00314 };
00315 
00316 G_INLINE_FUNC void      g_trash_stack_push      (GTrashStack **stack_p,
00317                                                  gpointer      data_p);
00318 G_INLINE_FUNC gpointer  g_trash_stack_pop       (GTrashStack **stack_p);
00319 G_INLINE_FUNC gpointer  g_trash_stack_peek      (GTrashStack **stack_p);
00320 G_INLINE_FUNC guint     g_trash_stack_height    (GTrashStack **stack_p);
00321 
00322 /* inline function implementations
00323  */
00324 #if defined (G_CAN_INLINE) || defined (__G_UTILS_C__)
00325 G_INLINE_FUNC gint
00326 g_bit_nth_lsf (gulong mask,
00327                gint   nth_bit)
00328 {
00329   if (G_UNLIKELY (nth_bit < -1))
00330     nth_bit = -1;
00331   while (nth_bit < ((GLIB_SIZEOF_LONG * 8) - 1))
00332     {
00333       nth_bit++;
00334       if (mask & (1UL << nth_bit))
00335         return nth_bit;
00336     }
00337   return -1;
00338 }
00339 G_INLINE_FUNC gint
00340 g_bit_nth_msf (gulong mask,
00341                gint   nth_bit)
00342 {
00343   if (nth_bit < 0 || G_UNLIKELY (nth_bit > GLIB_SIZEOF_LONG * 8))
00344     nth_bit = GLIB_SIZEOF_LONG * 8;
00345   while (nth_bit > 0)
00346     {
00347       nth_bit--;
00348       if (mask & (1UL << nth_bit))
00349         return nth_bit;
00350     }
00351   return -1;
00352 }
00353 G_INLINE_FUNC guint
00354 g_bit_storage (gulong number)
00355 {
00356 #if defined(__GNUC__) && (__GNUC__ >= 4) && defined(__OPTIMIZE__) && !defined(__ARM_ARCH_4T__)
00357   return G_LIKELY (number) ?
00358            ((GLIB_SIZEOF_LONG * 8 - 1) ^ __builtin_clzl(number)) + 1 : 1;
00359 #else
00360   register guint n_bits = 0;
00361   
00362   do
00363     {
00364       n_bits++;
00365       number >>= 1;
00366     }
00367   while (number);
00368   return n_bits;
00369 #endif
00370 }
00371 G_INLINE_FUNC void
00372 g_trash_stack_push (GTrashStack **stack_p,
00373                     gpointer      data_p)
00374 {
00375   GTrashStack *data = (GTrashStack *) data_p;
00376 
00377   data->next = *stack_p;
00378   *stack_p = data;
00379 }
00380 G_INLINE_FUNC gpointer
00381 g_trash_stack_pop (GTrashStack **stack_p)
00382 {
00383   GTrashStack *data;
00384 
00385   data = *stack_p;
00386   if (data)
00387     {
00388       *stack_p = data->next;
00389       /* NULLify private pointer here, most platforms store NULL as
00390        * subsequent 0 bytes
00391        */
00392       data->next = NULL;
00393     }
00394 
00395   return data;
00396 }
00397 G_INLINE_FUNC gpointer
00398 g_trash_stack_peek (GTrashStack **stack_p)
00399 {
00400   GTrashStack *data;
00401 
00402   data = *stack_p;
00403 
00404   return data;
00405 }
00406 G_INLINE_FUNC guint
00407 g_trash_stack_height (GTrashStack **stack_p)
00408 {
00409   GTrashStack *data;
00410   guint i = 0;
00411 
00412   for (data = *stack_p; data; data = data->next)
00413     i++;
00414 
00415   return i;
00416 }
00417 #endif  /* G_CAN_INLINE || __G_UTILS_C__ */
00418 
00419 /* Glib version.
00420  * we prefix variable declarations so they can
00421  * properly get exported in windows dlls.
00422  */
00423 GLIB_VAR const guint glib_major_version;
00424 GLIB_VAR const guint glib_minor_version;
00425 GLIB_VAR const guint glib_micro_version;
00426 GLIB_VAR const guint glib_interface_age;
00427 GLIB_VAR const guint glib_binary_age;
00428 
00429 const gchar * glib_check_version (guint required_major,
00430                                   guint required_minor,
00431                                   guint required_micro);
00432 
00433 #define GLIB_CHECK_VERSION(major,minor,micro)    \
00434     (GLIB_MAJOR_VERSION > (major) || \
00435      (GLIB_MAJOR_VERSION == (major) && GLIB_MINOR_VERSION > (minor)) || \
00436      (GLIB_MAJOR_VERSION == (major) && GLIB_MINOR_VERSION == (minor) && \
00437       GLIB_MICRO_VERSION >= (micro)))
00438 
00439 G_END_DECLS
00440 
00441 #ifndef G_DISABLE_DEPRECATED
00442 
00443 /*
00444  * This macro is deprecated. This DllMain() is too complex. It is
00445  * recommended to write an explicit minimal DLlMain() that just saves
00446  * the handle to the DLL and then use that handle instead, for
00447  * instance passing it to
00448  * g_win32_get_package_installation_directory_of_module().
00449  *
00450  * On Windows, this macro defines a DllMain function that stores the
00451  * actual DLL name that the code being compiled will be included in.
00452  * STATIC should be empty or 'static'. DLL_NAME is the name of the
00453  * (pointer to the) char array where the DLL name will be stored. If
00454  * this is used, you must also include <windows.h>. If you need a more complex
00455  * DLL entry point function, you cannot use this.
00456  *
00457  * On non-Windows platforms, expands to nothing.
00458  */
00459 
00460 #ifndef G_PLATFORM_WIN32
00461 # define G_WIN32_DLLMAIN_FOR_DLL_NAME(static, dll_name)
00462 #else
00463 # define G_WIN32_DLLMAIN_FOR_DLL_NAME(static, dll_name)                 \
00464 static char *dll_name;                                                  \
00465                                                                         \
00466 BOOL WINAPI                                                             \
00467 DllMain (HINSTANCE hinstDLL,                                            \
00468          DWORD     fdwReason,                                           \
00469          LPVOID    lpvReserved)                                         \
00470 {                                                                       \
00471   wchar_t wcbfr[1000];                                                  \
00472   char *tem;                                                            \
00473   switch (fdwReason)                                                    \
00474     {                                                                   \
00475     case DLL_PROCESS_ATTACH:                                            \
00476       GetModuleFileNameW ((HMODULE) hinstDLL, wcbfr, G_N_ELEMENTS (wcbfr)); \
00477       tem = g_utf16_to_utf8 (wcbfr, -1, NULL, NULL, NULL);              \
00478       dll_name = g_path_get_basename (tem);                             \
00479       g_free (tem);                                                     \
00480       break;                                                            \
00481     }                                                                   \
00482                                                                         \
00483   return TRUE;                                                          \
00484 }
00485 
00486 #endif  /* !G_DISABLE_DEPRECATED */
00487 
00488 #endif /* G_PLATFORM_WIN32 */
00489 
00490 #endif /* __G_UTILS_H__ */