| 1 | /* GLIB - Library of useful routines for C programming | 
| 2 |  * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald | 
| 3 |  * | 
| 4 |  * This library is free software; you can redistribute it and/or | 
| 5 |  * modify it under the terms of the GNU Lesser General Public | 
| 6 |  * License as published by the Free Software Foundation; either | 
| 7 |  * version 2.1 of the License, or (at your option) any later version. | 
| 8 |  * | 
| 9 |  * This library is distributed in the hope that it will be useful, | 
| 10 |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
| 11 |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
| 12 |  * Lesser General Public License for more details. | 
| 13 |  * | 
| 14 |  * You should have received a copy of the GNU Lesser General Public | 
| 15 |  * License along with this library; if not, see <http://www.gnu.org/licenses/>. | 
| 16 |  */ | 
| 17 |  | 
| 18 | /* | 
| 19 |  * Modified by the GLib Team and others 1997-2000.  See the AUTHORS | 
| 20 |  * file for a list of people on the GLib Team.  See the ChangeLog | 
| 21 |  * files for a list of changes.  These files are distributed with | 
| 22 |  * GLib at ftp://ftp.gtk.org/pub/gtk/. | 
| 23 |  */ | 
| 24 |  | 
| 25 | #ifndef __G_UTILS_H__ | 
| 26 | #define __G_UTILS_H__ | 
| 27 |  | 
| 28 | #if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) | 
| 29 | #error "Only <glib.h> can be included directly." | 
| 30 | #endif | 
| 31 |  | 
| 32 | #include <glib/gtypes.h> | 
| 33 | #include <stdarg.h> | 
| 34 |  | 
| 35 | G_BEGIN_DECLS | 
| 36 |  | 
| 37 | /* Define G_VA_COPY() to do the right thing for copying va_list variables. | 
| 38 |  * glibconfig.h may have already defined G_VA_COPY as va_copy or __va_copy. | 
| 39 |  */ | 
| 40 | #if !defined (G_VA_COPY) | 
| 41 | #  if defined (__GNUC__) && defined (__PPC__) && (defined (_CALL_SYSV) || defined (_WIN32)) | 
| 42 | #    define G_VA_COPY(ap1, ap2)	  (*(ap1) = *(ap2)) | 
| 43 | #  elif defined (G_VA_COPY_AS_ARRAY) | 
| 44 | #    define G_VA_COPY(ap1, ap2)	  memmove ((ap1), (ap2), sizeof (va_list)) | 
| 45 | #  else /* va_list is a pointer */ | 
| 46 | #    define G_VA_COPY(ap1, ap2)	  ((ap1) = (ap2)) | 
| 47 | #  endif /* va_list is a pointer */ | 
| 48 | #endif /* !G_VA_COPY */ | 
| 49 |  | 
| 50 | GLIB_AVAILABLE_IN_ALL | 
| 51 | const gchar *         g_get_user_name        (void); | 
| 52 | GLIB_AVAILABLE_IN_ALL | 
| 53 | const gchar *         g_get_real_name        (void); | 
| 54 | GLIB_AVAILABLE_IN_ALL | 
| 55 | const gchar *         g_get_home_dir         (void); | 
| 56 | GLIB_AVAILABLE_IN_ALL | 
| 57 | const gchar *         g_get_tmp_dir          (void); | 
| 58 | GLIB_AVAILABLE_IN_ALL | 
| 59 | const gchar *         g_get_host_name	     (void); | 
| 60 | GLIB_AVAILABLE_IN_ALL | 
| 61 | const gchar *         g_get_prgname          (void); | 
| 62 | GLIB_AVAILABLE_IN_ALL | 
| 63 | void                  g_set_prgname          (const gchar *prgname); | 
| 64 | GLIB_AVAILABLE_IN_ALL | 
| 65 | const gchar *         g_get_application_name (void); | 
| 66 | GLIB_AVAILABLE_IN_ALL | 
| 67 | void                  g_set_application_name (const gchar *application_name); | 
| 68 | GLIB_AVAILABLE_IN_2_64 | 
| 69 | gchar *               g_get_os_info          (const gchar *key_name); | 
| 70 |  | 
| 71 | /** | 
| 72 |  * G_OS_INFO_KEY_NAME: | 
| 73 |  * | 
| 74 |  * A key to get the name of the operating system excluding version information suitable for presentation to the user, e.g. "YoYoOS" | 
| 75 |  * | 
| 76 |  * Since: 2.64 | 
| 77 |  */ | 
| 78 | #define G_OS_INFO_KEY_NAME \ | 
| 79 |     GLIB_AVAILABLE_MACRO_IN_2_64 \ | 
| 80 |     "NAME" | 
| 81 |  | 
| 82 | /** | 
| 83 |  * G_OS_INFO_KEY_PRETTY_NAME: | 
| 84 |  * | 
| 85 |  * A key to get the name of the operating system in a format suitable for presentation to the user, e.g. "YoYoOS Foo" | 
| 86 |  * | 
| 87 |  * Since: 2.64 | 
| 88 |  */ | 
| 89 | #define G_OS_INFO_KEY_PRETTY_NAME \ | 
| 90 |     GLIB_AVAILABLE_MACRO_IN_2_64 \ | 
| 91 |     "PRETTY_NAME" | 
| 92 |  | 
| 93 | /** | 
| 94 |  * G_OS_INFO_KEY_VERSION: | 
| 95 |  * | 
| 96 |  * A key to get the operating system version suitable for presentation to the user, e.g. "42 (Foo)" | 
| 97 |  * | 
| 98 |  * Since: 2.64 | 
| 99 |  */ | 
| 100 | #define G_OS_INFO_KEY_VERSION \ | 
| 101 |     GLIB_AVAILABLE_MACRO_IN_2_64 \ | 
| 102 |     "VERSION" | 
| 103 |  | 
| 104 | /** | 
| 105 |  * G_OS_INFO_KEY_VERSION_CODENAME: | 
| 106 |  * | 
| 107 |  * A key to get a codename identifying the operating system release suitable for processing by scripts or usage in generated filenames, e.g. "foo" | 
| 108 |  * | 
| 109 |  * Since: 2.64 | 
| 110 |  */ | 
| 111 | #define G_OS_INFO_KEY_VERSION_CODENAME \ | 
| 112 |     GLIB_AVAILABLE_MACRO_IN_2_64 \ | 
| 113 |     "VERSION_CODENAME" | 
| 114 |  | 
| 115 | /** | 
| 116 |  * G_OS_INFO_KEY_VERSION_ID: | 
| 117 |  * | 
| 118 |  * A key to get the version of the operating system suitable for processing by scripts or usage in generated filenames, e.g. "42" | 
| 119 |  * | 
| 120 |  * Since: 2.64 | 
| 121 |  */ | 
| 122 | #define G_OS_INFO_KEY_VERSION_ID \ | 
| 123 |     GLIB_AVAILABLE_MACRO_IN_2_64 \ | 
| 124 |     "VERSION_ID" | 
| 125 |  | 
| 126 | /** | 
| 127 |  * G_OS_INFO_KEY_ID: | 
| 128 |  * | 
| 129 |  * A key to get an ID identifying the operating system suitable for processing by scripts or usage in generated filenames, e.g. "yoyoos" | 
| 130 |  * | 
| 131 |  * Since: 2.64 | 
| 132 |  */ | 
| 133 | #define G_OS_INFO_KEY_ID \ | 
| 134 |     GLIB_AVAILABLE_MACRO_IN_2_64 \ | 
| 135 |     "ID" | 
| 136 |  | 
| 137 | /** | 
| 138 |  * G_OS_INFO_KEY_HOME_URL: | 
| 139 |  * | 
| 140 |  * A key to get the homepage for the operating system, e.g. "https://www.yoyo-os.com/" | 
| 141 |  * | 
| 142 |  * Since: 2.64 | 
| 143 |  */ | 
| 144 | #define G_OS_INFO_KEY_HOME_URL \ | 
| 145 |     GLIB_AVAILABLE_MACRO_IN_2_64 \ | 
| 146 |     "HOME_URL" | 
| 147 |  | 
| 148 | /** | 
| 149 |  * G_OS_INFO_KEY_DOCUMENTATION_URL: | 
| 150 |  * | 
| 151 |  * A key to get the documentation page for the operating system, e.g. "https://docs.yoyo-os.com/" | 
| 152 |  * | 
| 153 |  * Since: 2.64 | 
| 154 |  */ | 
| 155 | #define G_OS_INFO_KEY_DOCUMENTATION_URL \ | 
| 156 |     GLIB_AVAILABLE_MACRO_IN_2_64 \ | 
| 157 |     "DOCUMENTATION_URL" | 
| 158 |  | 
| 159 | /** | 
| 160 |  * G_OS_INFO_KEY_SUPPORT_URL: | 
| 161 |  * | 
| 162 |  * A key to get the support page for the operating system, e.g. "https://support.yoyo-os.com/" | 
| 163 |  * | 
| 164 |  * Since: 2.64 | 
| 165 |  */ | 
| 166 | #define G_OS_INFO_KEY_SUPPORT_URL \ | 
| 167 |     GLIB_AVAILABLE_MACRO_IN_2_64 \ | 
| 168 |     "SUPPORT_URL" | 
| 169 |  | 
| 170 | /** | 
| 171 |  * G_OS_INFO_KEY_BUG_REPORT_URL: | 
| 172 |  * | 
| 173 |  * A key to get the bug reporting page for the operating system, e.g. "https://bugs.yoyo-os.com/" | 
| 174 |  * | 
| 175 |  * Since: 2.64 | 
| 176 |  */ | 
| 177 | #define G_OS_INFO_KEY_BUG_REPORT_URL \ | 
| 178 |     GLIB_AVAILABLE_MACRO_IN_2_64 \ | 
| 179 |     "BUG_REPORT_URL" | 
| 180 |  | 
| 181 | /** | 
| 182 |  * G_OS_INFO_KEY_PRIVACY_POLICY_URL: | 
| 183 |  * | 
| 184 |  * A key to get the privacy policy for the operating system, e.g. "https://privacy.yoyo-os.com/" | 
| 185 |  * | 
| 186 |  * Since: 2.64 | 
| 187 |  */ | 
| 188 | #define G_OS_INFO_KEY_PRIVACY_POLICY_URL \ | 
| 189 |     GLIB_AVAILABLE_MACRO_IN_2_64 \ | 
| 190 |     "PRIVACY_POLICY_URL" | 
| 191 |  | 
| 192 | GLIB_AVAILABLE_IN_ALL | 
| 193 | void      g_reload_user_special_dirs_cache     (void); | 
| 194 | GLIB_AVAILABLE_IN_ALL | 
| 195 | const gchar *         g_get_user_data_dir      (void); | 
| 196 | GLIB_AVAILABLE_IN_ALL | 
| 197 | const gchar *         g_get_user_config_dir    (void); | 
| 198 | GLIB_AVAILABLE_IN_ALL | 
| 199 | const gchar *         g_get_user_cache_dir     (void); | 
| 200 | GLIB_AVAILABLE_IN_2_72 | 
| 201 | const gchar *         g_get_user_state_dir     (void); | 
| 202 | GLIB_AVAILABLE_IN_ALL | 
| 203 | const gchar * const * g_get_system_data_dirs   (void); | 
| 204 |  | 
| 205 | #ifdef G_OS_WIN32 | 
| 206 | /* This function is not part of the public GLib API */ | 
| 207 | GLIB_AVAILABLE_IN_ALL | 
| 208 | const gchar * const * g_win32_get_system_data_dirs_for_module (void (*address_of_function)(void)); | 
| 209 | #endif | 
| 210 |  | 
| 211 | #if defined (G_OS_WIN32) && defined (G_CAN_INLINE) | 
| 212 | /* This function is not part of the public GLib API either. Just call | 
| 213 |  * g_get_system_data_dirs() in your code, never mind that that is | 
| 214 |  * actually a macro and you will in fact call this inline function. | 
| 215 |  */ | 
| 216 | static inline const gchar * const * | 
| 217 | _g_win32_get_system_data_dirs (void) | 
| 218 | { | 
| 219 |   return g_win32_get_system_data_dirs_for_module ((void (*)(void)) &_g_win32_get_system_data_dirs); | 
| 220 | } | 
| 221 | #define g_get_system_data_dirs _g_win32_get_system_data_dirs | 
| 222 | #endif | 
| 223 |  | 
| 224 | GLIB_AVAILABLE_IN_ALL | 
| 225 | const gchar * const * g_get_system_config_dirs (void); | 
| 226 |  | 
| 227 | GLIB_AVAILABLE_IN_ALL | 
| 228 | const gchar * g_get_user_runtime_dir (void); | 
| 229 |  | 
| 230 | /** | 
| 231 |  * GUserDirectory: | 
| 232 |  * @G_USER_DIRECTORY_DESKTOP: the user's Desktop directory | 
| 233 |  * @G_USER_DIRECTORY_DOCUMENTS: the user's Documents directory | 
| 234 |  * @G_USER_DIRECTORY_DOWNLOAD: the user's Downloads directory | 
| 235 |  * @G_USER_DIRECTORY_MUSIC: the user's Music directory | 
| 236 |  * @G_USER_DIRECTORY_PICTURES: the user's Pictures directory | 
| 237 |  * @G_USER_DIRECTORY_PUBLIC_SHARE: the user's shared directory | 
| 238 |  * @G_USER_DIRECTORY_TEMPLATES: the user's Templates directory | 
| 239 |  * @G_USER_DIRECTORY_VIDEOS: the user's Movies directory | 
| 240 |  * @G_USER_N_DIRECTORIES: the number of enum values | 
| 241 |  * | 
| 242 |  * These are logical ids for special directories which are defined | 
| 243 |  * depending on the platform used. You should use g_get_user_special_dir() | 
| 244 |  * to retrieve the full path associated to the logical id. | 
| 245 |  * | 
| 246 |  * The #GUserDirectory enumeration can be extended at later date. Not | 
| 247 |  * every platform has a directory for every logical id in this | 
| 248 |  * enumeration. | 
| 249 |  * | 
| 250 |  * Since: 2.14 | 
| 251 |  */ | 
| 252 | typedef enum { | 
| 253 |   G_USER_DIRECTORY_DESKTOP, | 
| 254 |   G_USER_DIRECTORY_DOCUMENTS, | 
| 255 |   G_USER_DIRECTORY_DOWNLOAD, | 
| 256 |   G_USER_DIRECTORY_MUSIC, | 
| 257 |   G_USER_DIRECTORY_PICTURES, | 
| 258 |   G_USER_DIRECTORY_PUBLIC_SHARE, | 
| 259 |   G_USER_DIRECTORY_TEMPLATES, | 
| 260 |   G_USER_DIRECTORY_VIDEOS, | 
| 261 |  | 
| 262 |   G_USER_N_DIRECTORIES | 
| 263 | } GUserDirectory; | 
| 264 |  | 
| 265 | GLIB_AVAILABLE_IN_ALL | 
| 266 | const gchar * g_get_user_special_dir (GUserDirectory directory); | 
| 267 |  | 
| 268 | /** | 
| 269 |  * GDebugKey: | 
| 270 |  * @key: the string | 
| 271 |  * @value: the flag | 
| 272 |  * | 
| 273 |  * Associates a string with a bit flag. | 
| 274 |  * Used in g_parse_debug_string(). | 
| 275 |  */ | 
| 276 | typedef struct _GDebugKey GDebugKey; | 
| 277 | struct _GDebugKey | 
| 278 | { | 
| 279 |   const gchar *key; | 
| 280 |   guint	       value; | 
| 281 | }; | 
| 282 |  | 
| 283 | /* Miscellaneous utility functions | 
| 284 |  */ | 
| 285 | GLIB_AVAILABLE_IN_ALL | 
| 286 | guint                 g_parse_debug_string (const gchar     *string, | 
| 287 | 					    const GDebugKey *keys, | 
| 288 | 					    guint            nkeys); | 
| 289 |  | 
| 290 | GLIB_AVAILABLE_IN_ALL | 
| 291 | gint                  g_snprintf           (gchar       *string, | 
| 292 | 					    gulong       n, | 
| 293 | 					    gchar const *format, | 
| 294 | 					    ...) G_GNUC_PRINTF (3, 4); | 
| 295 | GLIB_AVAILABLE_IN_ALL | 
| 296 | gint                  g_vsnprintf          (gchar       *string, | 
| 297 | 					    gulong       n, | 
| 298 | 					    gchar const *format, | 
| 299 | 					    va_list      args) | 
| 300 | 					    G_GNUC_PRINTF(3, 0); | 
| 301 |  | 
| 302 | GLIB_AVAILABLE_IN_ALL | 
| 303 | void                  g_nullify_pointer    (gpointer    *nullify_location); | 
| 304 |  | 
| 305 | typedef enum | 
| 306 | { | 
| 307 |   G_FORMAT_SIZE_DEFAULT     = 0, | 
| 308 |   G_FORMAT_SIZE_LONG_FORMAT = 1 << 0, | 
| 309 |   G_FORMAT_SIZE_IEC_UNITS   = 1 << 1, | 
| 310 |   G_FORMAT_SIZE_BITS        = 1 << 2 | 
| 311 | } GFormatSizeFlags; | 
| 312 |  | 
| 313 | GLIB_AVAILABLE_IN_2_30 | 
| 314 | gchar *g_format_size_full   (guint64          size, | 
| 315 |                              GFormatSizeFlags flags); | 
| 316 | GLIB_AVAILABLE_IN_2_30 | 
| 317 | gchar *g_format_size        (guint64          size); | 
| 318 |  | 
| 319 | GLIB_DEPRECATED_IN_2_30_FOR(g_format_size) | 
| 320 | gchar *g_format_size_for_display (goffset size); | 
| 321 |  | 
| 322 | #define g_ATEXIT(proc)	(atexit (proc)) GLIB_DEPRECATED_MACRO_IN_2_32 | 
| 323 | #define g_memmove(dest,src,len) \ | 
| 324 |   G_STMT_START { memmove ((dest), (src), (len)); } G_STMT_END  GLIB_DEPRECATED_MACRO_IN_2_40_FOR(memmove) | 
| 325 |  | 
| 326 | /** | 
| 327 |  * GVoidFunc: | 
| 328 |  * | 
| 329 |  * Declares a type of function which takes no arguments | 
| 330 |  * and has no return value. It is used to specify the type | 
| 331 |  * function passed to g_atexit(). | 
| 332 |  */ | 
| 333 | typedef void (*GVoidFunc) (void) GLIB_DEPRECATED_TYPE_IN_2_32; | 
| 334 | #define ATEXIT(proc) g_ATEXIT(proc) GLIB_DEPRECATED_MACRO_IN_2_32 | 
| 335 |  | 
| 336 | G_GNUC_BEGIN_IGNORE_DEPRECATIONS | 
| 337 | GLIB_DEPRECATED | 
| 338 | void	g_atexit		(GVoidFunc    func); | 
| 339 | G_GNUC_END_IGNORE_DEPRECATIONS | 
| 340 |  | 
| 341 | #ifdef G_OS_WIN32 | 
| 342 | /* It's a bad idea to wrap atexit() on Windows. If the GLib DLL calls | 
| 343 |  * atexit(), the function will be called when the GLib DLL is detached | 
| 344 |  * from the program, which is not what the caller wants. The caller | 
| 345 |  * wants the function to be called when it *itself* exits (or is | 
| 346 |  * detached, in case the caller, too, is a DLL). | 
| 347 |  */ | 
| 348 | #if (defined(__MINGW_H) && !defined(_STDLIB_H_)) || (defined(_MSC_VER) && !defined(_INC_STDLIB)) | 
| 349 | int atexit (void (*)(void)); | 
| 350 | #endif | 
| 351 | #define g_atexit(func) atexit(func) GLIB_DEPRECATED_MACRO_IN_2_32 | 
| 352 | #endif | 
| 353 |  | 
| 354 |  | 
| 355 | /* Look for an executable in PATH, following execvp() rules */ | 
| 356 | GLIB_AVAILABLE_IN_ALL | 
| 357 | gchar*  g_find_program_in_path  (const gchar *program); | 
| 358 |  | 
| 359 | /* Bit tests | 
| 360 |  * | 
| 361 |  * These are defined in a convoluted way because we want the compiler to | 
| 362 |  * be able to inline the code for performance reasons, but for | 
| 363 |  * historical reasons, we must continue to provide non-inline versions | 
| 364 |  * on our ABI. | 
| 365 |  * | 
| 366 |  * We define these as functions in gutils.c which are just implemented | 
| 367 |  * as calls to the _impl() versions in order to preserve the ABI. | 
| 368 |  */ | 
| 369 |  | 
| 370 | #define g_bit_nth_lsf(mask, nth_bit) g_bit_nth_lsf_impl(mask, nth_bit) | 
| 371 | #define g_bit_nth_msf(mask, nth_bit) g_bit_nth_msf_impl(mask, nth_bit) | 
| 372 | #define g_bit_storage(number)        g_bit_storage_impl(number) | 
| 373 |  | 
| 374 | GLIB_AVAILABLE_IN_ALL | 
| 375 | gint    (g_bit_nth_lsf)         (gulong mask, | 
| 376 |                                  gint   nth_bit); | 
| 377 | GLIB_AVAILABLE_IN_ALL | 
| 378 | gint    (g_bit_nth_msf)         (gulong mask, | 
| 379 |                                  gint   nth_bit); | 
| 380 | GLIB_AVAILABLE_IN_ALL | 
| 381 | guint   (g_bit_storage)         (gulong number); | 
| 382 |  | 
| 383 | static inline gint | 
| 384 | g_bit_nth_lsf_impl (gulong mask, | 
| 385 |                     gint   nth_bit) | 
| 386 | { | 
| 387 |   if (G_UNLIKELY (nth_bit < -1)) | 
| 388 |     nth_bit = -1; | 
| 389 |   while (nth_bit < ((GLIB_SIZEOF_LONG * 8) - 1)) | 
| 390 |     { | 
| 391 |       nth_bit++; | 
| 392 |       if (mask & (1UL << nth_bit)) | 
| 393 |         return nth_bit; | 
| 394 |     } | 
| 395 |   return -1; | 
| 396 | } | 
| 397 |  | 
| 398 | static inline gint | 
| 399 | g_bit_nth_msf_impl (gulong mask, | 
| 400 |                     gint   nth_bit) | 
| 401 | { | 
| 402 |   if (nth_bit < 0 || G_UNLIKELY (nth_bit > GLIB_SIZEOF_LONG * 8)) | 
| 403 |     nth_bit = GLIB_SIZEOF_LONG * 8; | 
| 404 |   while (nth_bit > 0) | 
| 405 |     { | 
| 406 |       nth_bit--; | 
| 407 |       if (mask & (1UL << nth_bit)) | 
| 408 |         return nth_bit; | 
| 409 |     } | 
| 410 |   return -1; | 
| 411 | } | 
| 412 |  | 
| 413 | static inline guint | 
| 414 | g_bit_storage_impl (gulong number) | 
| 415 | { | 
| 416 | #if defined(__GNUC__) && (__GNUC__ >= 4) && defined(__OPTIMIZE__) | 
| 417 |   return G_LIKELY (number) ? | 
| 418 |            ((GLIB_SIZEOF_LONG * 8U - 1) ^ (guint) __builtin_clzl(number)) + 1 : 1; | 
| 419 | #else | 
| 420 |   guint n_bits = 0; | 
| 421 |  | 
| 422 |   do | 
| 423 |     { | 
| 424 |       n_bits++; | 
| 425 |       number >>= 1; | 
| 426 |     } | 
| 427 |   while (number); | 
| 428 |   return n_bits; | 
| 429 | #endif | 
| 430 | } | 
| 431 |  | 
| 432 | /* Crashes the program. */ | 
| 433 | #if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_50 | 
| 434 | #ifndef G_OS_WIN32 | 
| 435 | #  include <stdlib.h> | 
| 436 | #  define g_abort() abort () | 
| 437 | #else | 
| 438 | GLIB_AVAILABLE_IN_2_50 | 
| 439 | G_NORETURN void g_abort (void) G_ANALYZER_NORETURN; | 
| 440 | #endif | 
| 441 | #endif | 
| 442 |  | 
| 443 | /* | 
| 444 |  * This macro is deprecated. This DllMain() is too complex. It is | 
| 445 |  * recommended to write an explicit minimal DLlMain() that just saves | 
| 446 |  * the handle to the DLL and then use that handle instead, for | 
| 447 |  * instance passing it to | 
| 448 |  * g_win32_get_package_installation_directory_of_module(). | 
| 449 |  * | 
| 450 |  * On Windows, this macro defines a DllMain function that stores the | 
| 451 |  * actual DLL name that the code being compiled will be included in. | 
| 452 |  * STATIC should be empty or 'static'. DLL_NAME is the name of the | 
| 453 |  * (pointer to the) char array where the DLL name will be stored. If | 
| 454 |  * this is used, you must also include <windows.h>. If you need a more complex | 
| 455 |  * DLL entry point function, you cannot use this. | 
| 456 |  * | 
| 457 |  * On non-Windows platforms, expands to nothing. | 
| 458 |  */ | 
| 459 |  | 
| 460 | #ifndef G_PLATFORM_WIN32 | 
| 461 | # define G_WIN32_DLLMAIN_FOR_DLL_NAME(static, dll_name) GLIB_DEPRECATED_MACRO_IN_2_26 | 
| 462 | #else | 
| 463 | # define G_WIN32_DLLMAIN_FOR_DLL_NAME(static, dll_name)			\ | 
| 464 | static char *dll_name;							\ | 
| 465 | 									\ | 
| 466 | BOOL WINAPI								\ | 
| 467 | DllMain (HINSTANCE hinstDLL,						\ | 
| 468 | 	 DWORD     fdwReason,						\ | 
| 469 | 	 LPVOID    lpvReserved)						\ | 
| 470 | {									\ | 
| 471 |   wchar_t wcbfr[1000];							\ | 
| 472 |   char *tem;								\ | 
| 473 |   switch (fdwReason)							\ | 
| 474 |     {									\ | 
| 475 |     case DLL_PROCESS_ATTACH:						\ | 
| 476 |       GetModuleFileNameW ((HMODULE) hinstDLL, wcbfr, G_N_ELEMENTS (wcbfr)); \ | 
| 477 |       tem = g_utf16_to_utf8 (wcbfr, -1, NULL, NULL, NULL);		\ | 
| 478 |       dll_name = g_path_get_basename (tem);				\ | 
| 479 |       g_free (tem);							\ | 
| 480 |       break;								\ | 
| 481 |     }									\ | 
| 482 | 									\ | 
| 483 |   return TRUE;								\ | 
| 484 | } GLIB_DEPRECATED_MACRO_IN_2_26 | 
| 485 | #endif /* G_PLATFORM_WIN32 */ | 
| 486 |  | 
| 487 | G_END_DECLS | 
| 488 |  | 
| 489 | #endif /* __G_UTILS_H__ */ | 
| 490 |  |