Properly store changes for arrays. (#308528, Roger Leigh)
[platform/upstream/glib.git] / glib / gutils.c
1 /* GLIB - Library of useful routines for C programming
2  * Copyright (C) 1995-1998  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 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, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 /*
21  * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
22  * file for a list of people on the GLib Team.  See the ChangeLog
23  * files for a list of changes.  These files are distributed with
24  * GLib at ftp://ftp.gtk.org/pub/gtk/. 
25  */
26
27 /* 
28  * MT safe for the unix part, FIXME: make the win32 part MT safe as well.
29  */
30
31 #include "config.h"
32
33 #ifdef HAVE_UNISTD_H
34 #include <unistd.h>
35 #endif
36 #include <stdarg.h>
37 #include <stdlib.h>
38 #include <stdio.h>
39 #include <locale.h>
40 #include <string.h>
41 #include <errno.h>
42 #ifdef HAVE_PWD_H
43 #include <pwd.h>
44 #endif
45 #include <sys/types.h>
46 #ifdef HAVE_SYS_PARAM_H
47 #include <sys/param.h>
48 #endif
49
50 /* implement gutils's inline functions
51  */
52 #define G_IMPLEMENT_INLINES 1
53 #define __G_UTILS_C__
54 #include "glib.h"
55 #include "gprintfint.h"
56 #include "gthreadinit.h"
57 #include "galias.h"
58
59 #ifdef  MAXPATHLEN
60 #define G_PATH_LENGTH   MAXPATHLEN
61 #elif   defined (PATH_MAX)
62 #define G_PATH_LENGTH   PATH_MAX
63 #elif   defined (_PC_PATH_MAX)
64 #define G_PATH_LENGTH   sysconf(_PC_PATH_MAX)
65 #else   
66 #define G_PATH_LENGTH   2048
67 #endif
68
69 #ifdef G_PLATFORM_WIN32
70 #  define STRICT                /* Strict typing, please */
71 #  include <windows.h>
72 #  undef STRICT
73 #  ifndef GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
74 #    define GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT 2
75 #    define GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS 4
76 #  endif
77 #  include <lmcons.h>           /* For UNLEN */
78 #endif /* G_PLATFORM_WIN32 */
79
80 #ifdef G_OS_WIN32
81 #  include <direct.h>
82 #  include <shlobj.h>
83    /* older SDK (e.g. msvc 5.0) does not have these*/
84 #  ifndef CSIDL_INTERNET_CACHE
85 #    define CSIDL_INTERNET_CACHE 32
86 #  endif
87 #  ifndef CSIDL_COMMON_APPDATA
88 #    define CSIDL_COMMON_APPDATA 35
89 #  endif
90 #  ifndef CSIDL_COMMON_DOCUMENTS
91 #    define CSIDL_COMMON_DOCUMENTS 46
92 #  endif
93 #  ifndef CSIDL_PROFILE
94 #    define CSIDL_PROFILE 40
95 #  endif
96 #  include <process.h>
97 #endif
98
99 #ifdef HAVE_CODESET
100 #include <langinfo.h>
101 #endif
102
103 #ifdef HAVE_BIND_TEXTDOMAIN_CODESET
104 #include <libintl.h>
105 #endif
106
107 const guint glib_major_version = GLIB_MAJOR_VERSION;
108 const guint glib_minor_version = GLIB_MINOR_VERSION;
109 const guint glib_micro_version = GLIB_MICRO_VERSION;
110 const guint glib_interface_age = GLIB_INTERFACE_AGE;
111 const guint glib_binary_age = GLIB_BINARY_AGE;
112
113 #ifdef G_PLATFORM_WIN32
114
115 G_WIN32_DLLMAIN_FOR_DLL_NAME (static, dll_name)
116
117 #endif
118
119 /**
120  * glib_check_version:
121  * @required_major: the required major version.
122  * @required_minor: the required major version.
123  * @required_micro: the required major version.
124  *
125  * Checks that the GLib library in use is compatible with the
126  * given version. Generally you would pass in the constants
127  * #GLIB_MAJOR_VERSION, #GLIB_MINOR_VERSION, #GLIB_MICRO_VERSION
128  * as the three arguments to this function; that produces
129  * a check that the library in use is compatible with
130  * the version of GLib the application or module was compiled
131  * against.
132  *
133  * Compatibility is defined by two things: first the version
134  * of the running library is newer than the version
135  * @required_major.required_minor.@required_micro. Second
136  * the running library must be binary compatible with the
137  * version @required_major.required_minor.@required_micro
138  * (same major version.)
139  *
140  * Return value: %NULL if the GLib library is compatible with the
141  *   given version, or a string describing the version mismatch.
142  *   The returned string is owned by GLib and must not be modified
143  *   or freed.
144  *
145  * Since: 2.6
146  **/
147 const gchar *
148 glib_check_version (guint required_major,
149                     guint required_minor,
150                     guint required_micro)
151 {
152   gint glib_effective_micro = 100 * GLIB_MINOR_VERSION + GLIB_MICRO_VERSION;
153   gint required_effective_micro = 100 * required_minor + required_micro;
154
155   if (required_major > GLIB_MAJOR_VERSION)
156     return "GLib version too old (major mismatch)";
157   if (required_major < GLIB_MAJOR_VERSION)
158     return "GLib version too new (major mismatch)";
159   if (required_effective_micro < glib_effective_micro - GLIB_BINARY_AGE)
160     return "GLib version too new (micro mismatch)";
161   if (required_effective_micro > glib_effective_micro)
162     return "GLib version too old (micro mismatch)";
163   return NULL;
164 }
165
166 #if !defined (HAVE_MEMMOVE) && !defined (HAVE_WORKING_BCOPY)
167 /**
168  * g_memmove: 
169  * @dest: the destination address to copy the bytes to.
170  * @src: the source address to copy the bytes from.
171  * @len: the number of bytes to copy.
172  *
173  * Copies a block of memory @len bytes long, from @src to @dest.
174  * The source and destination areas may overlap.
175  *
176  * In order to use this function, you must include 
177  * <filename>string.h</filename> yourself, because this macro will 
178  * typically simply resolve to memmove() and GLib does not include 
179  * <filename>string.h</filename> for you.
180  */
181 void 
182 g_memmove (gpointer      dest, 
183            gconstpointer src, 
184            gulong        len)
185 {
186   gchar* destptr = dest;
187   const gchar* srcptr = src;
188   if (src + len < dest || dest + len < src)
189     {
190       bcopy (src, dest, len);
191       return;
192     }
193   else if (dest <= src)
194     {
195       while (len--)
196         *(destptr++) = *(srcptr++);
197     }
198   else
199     {
200       destptr += len;
201       srcptr += len;
202       while (len--)
203         *(--destptr) = *(--srcptr);
204     }
205 }
206 #endif /* !HAVE_MEMMOVE && !HAVE_WORKING_BCOPY */
207
208 /**
209  * g_atexit:
210  * @func: the function to call on normal program termination.
211  * 
212  * Specifies a function to be called at normal program termination.
213  */
214 void
215 g_atexit (GVoidFunc func)
216 {
217   gint result;
218   const gchar *error = NULL;
219
220   /* keep this in sync with glib.h */
221
222 #ifdef  G_NATIVE_ATEXIT
223   result = ATEXIT (func);
224   if (result)
225     error = g_strerror (errno);
226 #elif defined (HAVE_ATEXIT)
227 #  ifdef NeXT /* @#%@! NeXTStep */
228   result = !atexit ((void (*)(void)) func);
229   if (result)
230     error = g_strerror (errno);
231 #  else
232   result = atexit ((void (*)(void)) func);
233   if (result)
234     error = g_strerror (errno);
235 #  endif /* NeXT */
236 #elif defined (HAVE_ON_EXIT)
237   result = on_exit ((void (*)(int, void *)) func, NULL);
238   if (result)
239     error = g_strerror (errno);
240 #else
241   result = 0;
242   error = "no implementation";
243 #endif /* G_NATIVE_ATEXIT */
244
245   if (error)
246     g_error ("Could not register atexit() function: %s", error);
247 }
248
249 /* Based on execvp() from GNU Libc.
250  * Some of this code is cut-and-pasted into gspawn.c
251  */
252
253 static gchar*
254 my_strchrnul (const gchar *str, 
255               gchar        c)
256 {
257   gchar *p = (gchar*)str;
258   while (*p && (*p != c))
259     ++p;
260
261   return p;
262 }
263
264 #ifdef G_OS_WIN32
265
266 static gchar *inner_find_program_in_path (const gchar *program);
267
268 gchar*
269 g_find_program_in_path (const gchar *program)
270 {
271   const gchar *last_dot = strrchr (program, '.');
272
273   if (last_dot == NULL ||
274       strchr (last_dot, '\\') != NULL ||
275       strchr (last_dot, '/') != NULL)
276     {
277       const gint program_length = strlen (program);
278       gchar *pathext = g_build_path (";",
279                                      ".exe;.cmd;.bat;.com",
280                                      g_getenv ("PATHEXT"),
281                                      NULL);
282       gchar *p;
283       gchar *decorated_program;
284       gchar *retval;
285
286       p = pathext;
287       do
288         {
289           gchar *q = my_strchrnul (p, ';');
290
291           decorated_program = g_malloc (program_length + (q-p) + 1);
292           memcpy (decorated_program, program, program_length);
293           memcpy (decorated_program+program_length, p, q-p);
294           decorated_program [program_length + (q-p)] = '\0';
295           
296           retval = inner_find_program_in_path (decorated_program);
297           g_free (decorated_program);
298
299           if (retval != NULL)
300             {
301               g_free (pathext);
302               return retval;
303             }
304           p = q;
305         } while (*p++ != '\0');
306       g_free (pathext);
307       return NULL;
308     }
309   else
310     return inner_find_program_in_path (program);
311 }
312
313 #endif
314
315 /**
316  * g_find_program_in_path:
317  * @program: a program name in the GLib file name encoding
318  * 
319  * Locates the first executable named @program in the user's path, in the
320  * same way that execvp() would locate it. Returns an allocated string
321  * with the absolute path name, or %NULL if the program is not found in
322  * the path. If @program is already an absolute path, returns a copy of
323  * @program if @program exists and is executable, and %NULL otherwise.
324  *  
325  * On Windows, if @program does not have a file type suffix, tries
326  * with the suffixes .exe, .cmd, .bat and .com, and the suffixes in
327  * the <envar>PATHEXT</envar> environment variable. 
328  * 
329  * On Windows, it looks for the file in the same way as CreateProcess() 
330  * would. This means first in the directory where the executing
331  * program was loaded from, then in the current directory, then in the
332  * Windows 32-bit system directory, then in the Windows directory, and
333  * finally in the directories in the <envar>PATH</envar> environment 
334  * variable. If the program is found, the return value contains the 
335  * full name including the type suffix.
336  *
337  * Return value: absolute path, or %NULL
338  **/
339 #ifdef G_OS_WIN32
340 static gchar *
341 inner_find_program_in_path (const gchar *program)
342 #else
343 gchar*
344 g_find_program_in_path (const gchar *program)
345 #endif
346 {
347   const gchar *path, *p;
348   gchar *name, *freeme;
349 #ifdef G_OS_WIN32
350   const gchar *path_copy;
351   gchar *filename = NULL, *appdir = NULL;
352   gchar *sysdir = NULL, *windir = NULL;
353 #endif
354   size_t len;
355   size_t pathlen;
356
357   g_return_val_if_fail (program != NULL, NULL);
358
359   /* If it is an absolute path, or a relative path including subdirectories,
360    * don't look in PATH.
361    */
362   if (g_path_is_absolute (program)
363       || strchr (program, G_DIR_SEPARATOR) != NULL
364 #ifdef G_OS_WIN32
365       || strchr (program, '/') != NULL
366 #endif
367       )
368     {
369       if (g_file_test (program, G_FILE_TEST_IS_EXECUTABLE) &&
370           !g_file_test (program, G_FILE_TEST_IS_DIR))
371         return g_strdup (program);
372       else
373         return NULL;
374     }
375   
376   path = g_getenv ("PATH");
377 #ifdef G_OS_UNIX
378   if (path == NULL)
379     {
380       /* There is no `PATH' in the environment.  The default
381        * search path in GNU libc is the current directory followed by
382        * the path `confstr' returns for `_CS_PATH'.
383        */
384       
385       /* In GLib we put . last, for security, and don't use the
386        * unportable confstr(); UNIX98 does not actually specify
387        * what to search if PATH is unset. POSIX may, dunno.
388        */
389       
390       path = "/bin:/usr/bin:.";
391     }
392 #else
393   if (G_WIN32_HAVE_WIDECHAR_API ())
394     {
395       int n;
396       wchar_t wfilename[MAXPATHLEN], wsysdir[MAXPATHLEN],
397         wwindir[MAXPATHLEN];
398       
399       n = GetModuleFileNameW (NULL, wfilename, MAXPATHLEN);
400       if (n > 0 && n < MAXPATHLEN)
401         filename = g_utf16_to_utf8 (wfilename, -1, NULL, NULL, NULL);
402       
403       n = GetSystemDirectoryW (wsysdir, MAXPATHLEN);
404       if (n > 0 && n < MAXPATHLEN)
405         sysdir = g_utf16_to_utf8 (wsysdir, -1, NULL, NULL, NULL);
406       
407       n = GetWindowsDirectoryW (wwindir, MAXPATHLEN);
408       if (n > 0 && n < MAXPATHLEN)
409         windir = g_utf16_to_utf8 (wwindir, -1, NULL, NULL, NULL);
410     }
411   else
412     {
413       int n;
414       gchar cpfilename[MAXPATHLEN], cpsysdir[MAXPATHLEN],
415         cpwindir[MAXPATHLEN];
416       
417       n = GetModuleFileNameA (NULL, cpfilename, MAXPATHLEN);
418       if (n > 0 && n < MAXPATHLEN)
419         filename = g_locale_to_utf8 (cpfilename, -1, NULL, NULL, NULL);
420       
421       n = GetSystemDirectoryA (cpsysdir, MAXPATHLEN);
422       if (n > 0 && n < MAXPATHLEN)
423         sysdir = g_locale_to_utf8 (cpsysdir, -1, NULL, NULL, NULL);
424       
425       n = GetWindowsDirectoryA (cpwindir, MAXPATHLEN);
426       if (n > 0 && n < MAXPATHLEN)
427         windir = g_locale_to_utf8 (cpwindir, -1, NULL, NULL, NULL);
428     }
429   
430   if (filename)
431     {
432       appdir = g_path_get_dirname (filename);
433       g_free (filename);
434     }
435   
436   path = g_strdup (path);
437
438   if (windir)
439     {
440       const gchar *tem = path;
441       path = g_strconcat (windir, ";", path, NULL);
442       g_free ((gchar *) tem);
443       g_free (windir);
444     }
445   
446   if (sysdir)
447     {
448       const gchar *tem = path;
449       path = g_strconcat (sysdir, ";", path, NULL);
450       g_free ((gchar *) tem);
451       g_free (sysdir);
452     }
453   
454   {
455     const gchar *tem = path;
456     path = g_strconcat (".;", path, NULL);
457     g_free ((gchar *) tem);
458   }
459   
460   if (appdir)
461     {
462       const gchar *tem = path;
463       path = g_strconcat (appdir, ";", path, NULL);
464       g_free ((gchar *) tem);
465       g_free (appdir);
466     }
467
468   path_copy = path;
469 #endif
470   
471   len = strlen (program) + 1;
472   pathlen = strlen (path);
473   freeme = name = g_malloc (pathlen + len + 1);
474   
475   /* Copy the file name at the top, including '\0'  */
476   memcpy (name + pathlen + 1, program, len);
477   name = name + pathlen;
478   /* And add the slash before the filename  */
479   *name = G_DIR_SEPARATOR;
480   
481   p = path;
482   do
483     {
484       char *startp;
485
486       path = p;
487       p = my_strchrnul (path, G_SEARCHPATH_SEPARATOR);
488
489       if (p == path)
490         /* Two adjacent colons, or a colon at the beginning or the end
491          * of `PATH' means to search the current directory.
492          */
493         startp = name + 1;
494       else
495         startp = memcpy (name - (p - path), path, p - path);
496
497       if (g_file_test (startp, G_FILE_TEST_IS_EXECUTABLE) &&
498           !g_file_test (startp, G_FILE_TEST_IS_DIR))
499         {
500           gchar *ret;
501           ret = g_strdup (startp);
502           g_free (freeme);
503 #ifdef G_OS_WIN32
504           g_free ((gchar *) path_copy);
505 #endif
506           return ret;
507         }
508     }
509   while (*p++ != '\0');
510   
511   g_free (freeme);
512 #ifdef G_OS_WIN32
513   g_free ((gchar *) path_copy);
514 #endif
515
516   return NULL;
517 }
518
519 /**
520  * g_parse_debug_string:
521  * @string: a list of debug options separated by ':' or "all" 
522  *     to set all flags.
523  * @keys: pointer to an array of #GDebugKey which associate 
524  *     strings with bit flags.
525  * @nkeys: the number of #GDebugKey<!-- -->s in the array.
526  *
527  * Parses a string containing debugging options separated 
528  * by ':' into a %guint containing bit flags. This is used 
529  * within GDK and GTK+ to parse the debug options passed on the
530  * command line or through environment variables.
531  *
532  * Returns: the combined set of bit flags.
533  */
534 guint        
535 g_parse_debug_string  (const gchar     *string, 
536                        const GDebugKey *keys, 
537                        guint            nkeys)
538 {
539   guint i;
540   guint result = 0;
541   
542   g_return_val_if_fail (string != NULL, 0);
543   
544   if (!g_ascii_strcasecmp (string, "all"))
545     {
546       for (i=0; i<nkeys; i++)
547         result |= keys[i].value;
548     }
549   else
550     {
551       const gchar *p = string;
552       const gchar *q;
553       gboolean done = FALSE;
554       
555       while (*p && !done)
556         {
557           q = strchr (p, ':');
558           if (!q)
559             {
560               q = p + strlen(p);
561               done = TRUE;
562             }
563           
564           for (i=0; i<nkeys; i++)
565             if (g_ascii_strncasecmp (keys[i].key, p, q - p) == 0 &&
566                 keys[i].key[q - p] == '\0')
567               result |= keys[i].value;
568           
569           p = q + 1;
570         }
571     }
572   
573   return result;
574 }
575
576 /**
577  * g_basename:
578  * @file_name: the name of the file.
579  * 
580  * Gets the name of the file without any leading directory components.  
581  * It returns a pointer into the given file name string.
582  * 
583  * Return value: the name of the file without any leading directory components.
584  *
585  * Deprecated: Use g_path_get_basename() instead, but notice that
586  * g_path_get_basename() allocates new memory for the returned string, unlike
587  * this function which returns a pointer into the argument.
588  **/
589 G_CONST_RETURN gchar*
590 g_basename (const gchar    *file_name)
591 {
592   register gchar *base;
593   
594   g_return_val_if_fail (file_name != NULL, NULL);
595   
596   base = strrchr (file_name, G_DIR_SEPARATOR);
597
598 #ifdef G_OS_WIN32
599   {
600     gchar *q = strrchr (file_name, '/');
601     if (base == NULL || (q != NULL && q > base))
602         base = q;
603   }
604 #endif
605
606   if (base)
607     return base + 1;
608
609 #ifdef G_OS_WIN32
610   if (g_ascii_isalpha (file_name[0]) && file_name[1] == ':')
611     return (gchar*) file_name + 2;
612 #endif /* G_OS_WIN32 */
613   
614   return (gchar*) file_name;
615 }
616
617 /**
618  * g_path_get_basename:
619  * @file_name: the name of the file.
620  *
621  * Gets the last component of the filename. If @file_name ends with a 
622  * directory separator it gets the component before the last slash. If 
623  * @file_name consists only of directory separators (and on Windows, 
624  * possibly a drive letter), a single separator is returned. If
625  * @file_name is empty, it gets ".".
626  *
627  * Return value: a newly allocated string containing the last component of 
628  *   the filename.
629  */
630 gchar*
631 g_path_get_basename (const gchar   *file_name)
632 {
633   register gssize base;             
634   register gssize last_nonslash;    
635   gsize len;    
636   gchar *retval;
637  
638   g_return_val_if_fail (file_name != NULL, NULL);
639
640   if (file_name[0] == '\0')
641     /* empty string */
642     return g_strdup (".");
643   
644   last_nonslash = strlen (file_name) - 1;
645
646   while (last_nonslash >= 0 && G_IS_DIR_SEPARATOR (file_name [last_nonslash]))
647     last_nonslash--;
648
649   if (last_nonslash == -1)
650     /* string only containing slashes */
651     return g_strdup (G_DIR_SEPARATOR_S);
652
653 #ifdef G_OS_WIN32
654   if (last_nonslash == 1 && g_ascii_isalpha (file_name[0]) && file_name[1] == ':')
655     /* string only containing slashes and a drive */
656     return g_strdup (G_DIR_SEPARATOR_S);
657 #endif /* G_OS_WIN32 */
658
659   base = last_nonslash;
660
661   while (base >=0 && !G_IS_DIR_SEPARATOR (file_name [base]))
662     base--;
663
664 #ifdef G_OS_WIN32
665   if (base == -1 && g_ascii_isalpha (file_name[0]) && file_name[1] == ':')
666     base = 1;
667 #endif /* G_OS_WIN32 */
668
669   len = last_nonslash - base;
670   retval = g_malloc (len + 1);
671   memcpy (retval, file_name + base + 1, len);
672   retval [len] = '\0';
673   return retval;
674 }
675
676 /**
677  * g_path_is_absolute:
678  * @file_name: a file name.
679  *
680  * Returns %TRUE if the given @file_name is an absolute file name,
681  * i.e. it contains a full path from the root directory such as "/usr/local"
682  * on UNIX or "C:\windows" on Windows systems.
683  *
684  * Returns: %TRUE if @file_name is an absolute path. 
685  */
686 gboolean
687 g_path_is_absolute (const gchar *file_name)
688 {
689   g_return_val_if_fail (file_name != NULL, FALSE);
690   
691   if (G_IS_DIR_SEPARATOR (file_name[0]))
692     return TRUE;
693
694 #ifdef G_OS_WIN32
695   /* Recognize drive letter on native Windows */
696   if (g_ascii_isalpha (file_name[0]) && 
697       file_name[1] == ':' && G_IS_DIR_SEPARATOR (file_name[2]))
698     return TRUE;
699 #endif /* G_OS_WIN32 */
700
701   return FALSE;
702 }
703
704 /**
705  * g_path_skip_root:
706  * @file_name: a file name.
707  *
708  * Returns a pointer into @file_name after the root component, i.e. after
709  * the "/" in UNIX or "C:\" under Windows. If @file_name is not an absolute
710  * path it returns %NULL.
711  *
712  * Returns: a pointer into @file_name after the root component.
713  */
714 G_CONST_RETURN gchar*
715 g_path_skip_root (const gchar *file_name)
716 {
717   g_return_val_if_fail (file_name != NULL, NULL);
718   
719 #ifdef G_PLATFORM_WIN32
720   /* Skip \\server\share or //server/share */
721   if (G_IS_DIR_SEPARATOR (file_name[0]) &&
722       G_IS_DIR_SEPARATOR (file_name[1]) &&
723       file_name[2] &&
724       !G_IS_DIR_SEPARATOR (file_name[2]))
725     {
726       gchar *p;
727
728       p = strchr (file_name + 2, G_DIR_SEPARATOR);
729 #ifdef G_OS_WIN32
730       {
731         gchar *q = strchr (file_name + 2, '/');
732         if (p == NULL || (q != NULL && q < p))
733           p = q;
734       }
735 #endif
736       if (p &&
737           p > file_name + 2 &&
738           p[1])
739         {
740           file_name = p + 1;
741
742           while (file_name[0] && !G_IS_DIR_SEPARATOR (file_name[0]))
743             file_name++;
744
745           /* Possibly skip a backslash after the share name */
746           if (G_IS_DIR_SEPARATOR (file_name[0]))
747             file_name++;
748
749           return (gchar *)file_name;
750         }
751     }
752 #endif
753   
754   /* Skip initial slashes */
755   if (G_IS_DIR_SEPARATOR (file_name[0]))
756     {
757       while (G_IS_DIR_SEPARATOR (file_name[0]))
758         file_name++;
759       return (gchar *)file_name;
760     }
761
762 #ifdef G_OS_WIN32
763   /* Skip X:\ */
764   if (g_ascii_isalpha (file_name[0]) && file_name[1] == ':' && G_IS_DIR_SEPARATOR (file_name[2]))
765     return (gchar *)file_name + 3;
766 #endif
767
768   return NULL;
769 }
770
771 /**
772  * g_path_get_dirname:
773  * @file_name: the name of the file.
774  *
775  * Gets the directory components of a file name.  If the file name has no
776  * directory components "." is returned.  The returned string should be
777  * freed when no longer needed.
778  * 
779  * Returns: the directory components of the file.
780  */
781 gchar*
782 g_path_get_dirname (const gchar    *file_name)
783 {
784   register gchar *base;
785   register gsize len;    
786   
787   g_return_val_if_fail (file_name != NULL, NULL);
788   
789   base = strrchr (file_name, G_DIR_SEPARATOR);
790 #ifdef G_OS_WIN32
791   {
792     gchar *q = strrchr (file_name, '/');
793     if (base == NULL || (q != NULL && q > base))
794         base = q;
795   }
796 #endif
797   if (!base)
798     {
799 #ifdef G_OS_WIN32
800       if (g_ascii_isalpha (file_name[0]) && file_name[1] == ':')
801         {
802           gchar drive_colon_dot[4];
803
804           drive_colon_dot[0] = file_name[0];
805           drive_colon_dot[1] = ':';
806           drive_colon_dot[2] = '.';
807           drive_colon_dot[3] = '\0';
808
809           return g_strdup (drive_colon_dot);
810         }
811 #endif
812     return g_strdup (".");
813     }
814
815   while (base > file_name && G_IS_DIR_SEPARATOR (*base))
816     base--;
817
818 #ifdef G_OS_WIN32
819   /* base points to the char before the last slash.
820    *
821    * In case file_name is the root of a drive (X:\) or a child of the
822    * root of a drive (X:\foo), include the slash.
823    *
824    * In case file_name is the root share of an UNC path
825    * (\\server\share), add a slash, returning \\server\share\ .
826    *
827    * In case file_name is a direct child of a share in an UNC path
828    * (\\server\share\foo), include the slash after the share name,
829    * returning \\server\share\ .
830    */
831   if (base == file_name + 1 && g_ascii_isalpha (file_name[0]) && file_name[1] == ':')
832     base++;
833   else if (G_IS_DIR_SEPARATOR (file_name[0]) &&
834            G_IS_DIR_SEPARATOR (file_name[1]) &&
835            file_name[2] &&
836            !G_IS_DIR_SEPARATOR (file_name[2]) &&
837            base >= file_name + 2)
838     {
839       const gchar *p = file_name + 2;
840       while (*p && !G_IS_DIR_SEPARATOR (*p))
841         p++;
842       if (p == base + 1)
843         {
844           len = (guint) strlen (file_name) + 1;
845           base = g_new (gchar, len + 1);
846           strcpy (base, file_name);
847           base[len-1] = G_DIR_SEPARATOR;
848           base[len] = 0;
849           return base;
850         }
851       if (G_IS_DIR_SEPARATOR (*p))
852         {
853           p++;
854           while (*p && !G_IS_DIR_SEPARATOR (*p))
855             p++;
856           if (p == base + 1)
857             base++;
858         }
859     }
860 #endif
861
862   len = (guint) 1 + base - file_name;
863   
864   base = g_new (gchar, len + 1);
865   g_memmove (base, file_name, len);
866   base[len] = 0;
867   
868   return base;
869 }
870
871 /**
872  * g_get_current_dir:
873  *
874  * Gets the current directory.
875  * The returned string should be freed when no longer needed. The encoding 
876  * of the returned string is system defined. On Windows, it is always UTF-8.
877  * 
878  * Returns: the current directory.
879  */
880 gchar*
881 g_get_current_dir (void)
882 {
883 #ifdef G_OS_WIN32
884
885   gchar *dir = NULL;
886
887   if (G_WIN32_HAVE_WIDECHAR_API ())
888     {
889       wchar_t dummy[2], *wdir;
890       int len;
891
892       len = GetCurrentDirectoryW (2, dummy);
893       wdir = g_new (wchar_t, len);
894
895       if (GetCurrentDirectoryW (len, wdir) == len - 1)
896         dir = g_utf16_to_utf8 (wdir, -1, NULL, NULL, NULL);
897
898       g_free (wdir);
899     }
900   else
901     {
902       gchar dummy[2], *cpdir;
903       int len;
904
905       len = GetCurrentDirectoryA (2, dummy);
906       cpdir = g_new (gchar, len);
907
908       if (GetCurrentDirectoryA (len, cpdir) == len - 1)
909         dir = g_locale_to_utf8 (cpdir, -1, NULL, NULL, NULL);
910
911       g_free (cpdir);
912     }
913
914   if (dir == NULL)
915     dir = g_strdup ("\\");
916
917   return dir;
918
919 #else
920
921   gchar *buffer = NULL;
922   gchar *dir = NULL;
923   static gulong max_len = 0;
924
925   if (max_len == 0) 
926     max_len = (G_PATH_LENGTH == -1) ? 2048 : G_PATH_LENGTH;
927   
928   /* We don't use getcwd(3) on SUNOS, because, it does a popen("pwd")
929    * and, if that wasn't bad enough, hangs in doing so.
930    */
931 #if     (defined (sun) && !defined (__SVR4)) || !defined(HAVE_GETCWD)
932   buffer = g_new (gchar, max_len + 1);
933   *buffer = 0;
934   dir = getwd (buffer);
935 #else   /* !sun || !HAVE_GETCWD */
936   while (max_len < G_MAXULONG / 2)
937     {
938       buffer = g_new (gchar, max_len + 1);
939       *buffer = 0;
940       dir = getcwd (buffer, max_len);
941
942       if (dir || errno != ERANGE)
943         break;
944
945       g_free (buffer);
946       max_len *= 2;
947     }
948 #endif  /* !sun || !HAVE_GETCWD */
949   
950   if (!dir || !*buffer)
951     {
952       /* hm, should we g_error() out here?
953        * this can happen if e.g. "./" has mode \0000
954        */
955       buffer[0] = G_DIR_SEPARATOR;
956       buffer[1] = 0;
957     }
958
959   dir = g_strdup (buffer);
960   g_free (buffer);
961   
962   return dir;
963 #endif /* !Win32 */
964 }
965
966 /**
967  * g_getenv:
968  * @variable: the environment variable to get, in the GLib file name encoding.
969  * 
970  * Returns the value of an environment variable. The name and value
971  * are in the GLib file name encoding. On UNIX, this means the actual
972  * bytes which might or might not be in some consistent character set
973  * and encoding. On Windows, it is in UTF-8. On Windows, in case the
974  * environment variable's value contains references to other
975  * environment variables, they are expanded.
976  * 
977  * Return value: the value of the environment variable, or %NULL if
978  * the environment variable is not found. The returned string may be
979  * overwritten by the next call to g_getenv(), g_setenv() or
980  * g_unsetenv().
981  **/
982 G_CONST_RETURN gchar*
983 g_getenv (const gchar *variable)
984 {
985 #ifndef G_OS_WIN32
986
987   g_return_val_if_fail (variable != NULL, NULL);
988
989   return getenv (variable);
990
991 #else /* G_OS_WIN32 */
992
993   GQuark quark;
994   gchar *value;
995
996   g_return_val_if_fail (variable != NULL, NULL);
997   g_return_val_if_fail (g_utf8_validate (variable, -1, NULL), NULL);
998
999   /* On Windows NT, it is relatively typical that environment
1000    * variables contain references to other environment variables. If
1001    * so, use ExpandEnvironmentStrings(). (In an ideal world, such
1002    * environment variables would be stored in the Registry as
1003    * REG_EXPAND_SZ type values, and would then get automatically
1004    * expanded before a program sees them. But there is broken software
1005    * that stores environment variables as REG_SZ values even if they
1006    * contain references to other environment variables.)
1007    */
1008
1009   if (G_WIN32_HAVE_WIDECHAR_API ())
1010     {
1011       wchar_t dummy[2], *wname, *wvalue;
1012       int len;
1013       
1014       wname = g_utf8_to_utf16 (variable, -1, NULL, NULL, NULL);
1015
1016       len = GetEnvironmentVariableW (wname, dummy, 2);
1017
1018       if (len == 0)
1019         {
1020           g_free (wname);
1021           return NULL;
1022         }
1023       else if (len == 1)
1024         len = 2;
1025
1026       wvalue = g_new (wchar_t, len);
1027
1028       if (GetEnvironmentVariableW (wname, wvalue, len) != len - 1)
1029         {
1030           g_free (wname);
1031           g_free (wvalue);
1032           return NULL;
1033         }
1034
1035       if (wcschr (wvalue, L'%') != NULL)
1036         {
1037           wchar_t *tem = wvalue;
1038
1039           len = ExpandEnvironmentStringsW (wvalue, dummy, 2);
1040
1041           if (len > 0)
1042             {
1043               wvalue = g_new (wchar_t, len);
1044
1045               if (ExpandEnvironmentStringsW (tem, wvalue, len) != len)
1046                 {
1047                   g_free (wvalue);
1048                   wvalue = tem;
1049                 }
1050               else
1051                 g_free (tem);
1052             }
1053         }
1054
1055       value = g_utf16_to_utf8 (wvalue, -1, NULL, NULL, NULL);
1056
1057       g_free (wname);
1058       g_free (wvalue);
1059     }
1060   else
1061     {
1062       gchar dummy[3], *cpname, *cpvalue;
1063       int len;
1064       
1065       cpname = g_locale_from_utf8 (variable, -1, NULL, NULL, NULL);
1066
1067       g_return_val_if_fail (cpname != NULL, NULL);
1068
1069       len = GetEnvironmentVariableA (cpname, dummy, 2);
1070
1071       if (len == 0)
1072         {
1073           g_free (cpname);
1074           return NULL;
1075         }
1076       else if (len == 1)
1077         len = 2;
1078
1079       cpvalue = g_new (gchar, len);
1080
1081       if (GetEnvironmentVariableA (cpname, cpvalue, len) != len - 1)
1082         {
1083           g_free (cpname);
1084           g_free (cpvalue);
1085           return NULL;
1086         }
1087
1088       if (strchr (cpvalue, '%') != NULL)
1089         {
1090           gchar *tem = cpvalue;
1091
1092           len = ExpandEnvironmentStringsA (cpvalue, dummy, 3);
1093
1094           if (len > 0)
1095             {
1096               cpvalue = g_new (gchar, len);
1097
1098               if (ExpandEnvironmentStringsA (tem, cpvalue, len) != len)
1099                 {
1100                   g_free (cpvalue);
1101                   cpvalue = tem;
1102                 }
1103               else
1104                 g_free (tem);
1105             }
1106         }
1107
1108       value = g_locale_to_utf8 (cpvalue, -1, NULL, NULL, NULL);
1109
1110       g_free (cpname);
1111       g_free (cpvalue);
1112     }
1113
1114   quark = g_quark_from_string (value);
1115   g_free (value);
1116   
1117   return g_quark_to_string (quark);
1118
1119 #endif /* G_OS_WIN32 */
1120 }
1121
1122 /**
1123  * g_setenv:
1124  * @variable: the environment variable to set, must not contain '='.
1125  * @value: the value for to set the variable to.
1126  * @overwrite: whether to change the variable if it already exists.
1127  *
1128  * Sets an environment variable. Both the variable's name and value
1129  * should be in the GLib file name encoding. On UNIX, this means that
1130  * they can be any sequence of bytes. On Windows, they should be in
1131  * UTF-8.
1132  *
1133  * Note that on some systems, when variables are overwritten, the memory 
1134  * used for the previous variables and its value isn't reclaimed.
1135  *
1136  * Returns: %FALSE if the environment variable couldn't be set.
1137  *
1138  * Since: 2.4
1139  */
1140 gboolean
1141 g_setenv (const gchar *variable, 
1142           const gchar *value, 
1143           gboolean     overwrite)
1144 {
1145 #ifndef G_OS_WIN32
1146
1147   gint result;
1148 #ifndef HAVE_SETENV
1149   gchar *string;
1150 #endif
1151
1152   g_return_val_if_fail (variable != NULL, FALSE);
1153   g_return_val_if_fail (strchr (variable, '=') == NULL, FALSE);
1154
1155 #ifdef HAVE_SETENV
1156   result = setenv (variable, value, overwrite);
1157 #else
1158   if (!overwrite && getenv (variable) != NULL)
1159     return TRUE;
1160   
1161   /* This results in a leak when you overwrite existing
1162    * settings. It would be fairly easy to fix this by keeping
1163    * our own parallel array or hash table.
1164    */
1165   string = g_strconcat (variable, "=", value, NULL);
1166   result = putenv (string);
1167 #endif
1168   return result == 0;
1169
1170 #else /* G_OS_WIN32 */
1171
1172   gboolean retval;
1173
1174   g_return_val_if_fail (variable != NULL, FALSE);
1175   g_return_val_if_fail (strchr (variable, '=') == NULL, FALSE);
1176   g_return_val_if_fail (g_utf8_validate (variable, -1, NULL), FALSE);
1177   g_return_val_if_fail (g_utf8_validate (value, -1, NULL), FALSE);
1178
1179   if (!overwrite && g_getenv (variable) != NULL)
1180     return TRUE;
1181
1182   /* We want to (if possible) set both the environment variable copy
1183    * kept by the C runtime and the one kept by the system.
1184    *
1185    * We can't use only the C runtime's putenv or _wputenv() as that
1186    * won't work for arbitrary Unicode strings in a "non-Unicode" app
1187    * (with main() and not wmain()). In a "main()" app the C runtime
1188    * initializes the C runtime's environment table by converting the
1189    * real (wide char) environment variables to system codepage, thus
1190    * breaking those that aren't representable in the system codepage.
1191    *
1192    * As the C runtime's putenv() will also set the system copy, we do
1193    * the putenv() first, then call SetEnvironmentValueW ourselves.
1194    */
1195
1196   if (G_WIN32_HAVE_WIDECHAR_API ())
1197     {
1198       wchar_t *wname = g_utf8_to_utf16 (variable, -1, NULL, NULL, NULL);
1199       wchar_t *wvalue = g_utf8_to_utf16 (value, -1, NULL, NULL, NULL);
1200       gchar *tem = g_strconcat (variable, "=", value, NULL);
1201       wchar_t *wassignment = g_utf8_to_utf16 (tem, -1, NULL, NULL, NULL);
1202       
1203       g_free (tem);
1204       _wputenv (wassignment);
1205       g_free (wassignment);
1206
1207       retval = (SetEnvironmentVariableW (wname, wvalue) != 0);
1208
1209       g_free (wname);
1210       g_free (wvalue);
1211     }
1212   else
1213     {
1214       /* In the non-Unicode case (Win9x), just putenv() is good
1215        * enough.
1216        */
1217       gchar *tem = g_strconcat (variable, "=", value, NULL);
1218       gchar *cpassignment = g_locale_from_utf8 (tem, -1, NULL, NULL, NULL);
1219
1220       g_free (tem);
1221       
1222       retval = (putenv (cpassignment) == 0);
1223
1224       g_free (cpassignment);
1225     }
1226
1227   return retval;
1228
1229 #endif /* G_OS_WIN32 */
1230 }
1231
1232 #ifndef G_OS_WIN32
1233
1234 /* According to the Single Unix Specification, environ is not in 
1235  * any system header, although unistd.h often declares it.
1236  */
1237 extern char **environ;
1238
1239 #endif
1240            
1241 /**
1242  * g_unsetenv:
1243  * @variable: the environment variable to remove, must not contain '='.
1244  * 
1245  * Removes an environment variable from the environment.
1246  *
1247  * Note that on some systems, when variables are overwritten, the memory 
1248  * used for the previous variables and its value isn't reclaimed.
1249  * Furthermore, this function can't be guaranteed to operate in a 
1250  * threadsafe way.
1251  *
1252  * Since: 2.4 
1253  **/
1254 void
1255 g_unsetenv (const gchar *variable)
1256 {
1257 #ifndef G_OS_WIN32
1258
1259 #ifdef HAVE_UNSETENV
1260   g_return_if_fail (variable != NULL);
1261   g_return_if_fail (strchr (variable, '=') == NULL);
1262
1263   unsetenv (variable);
1264 #else /* !HAVE_UNSETENV */
1265   int len;
1266   gchar **e, **f;
1267
1268   g_return_if_fail (variable != NULL);
1269   g_return_if_fail (strchr (variable, '=') == NULL);
1270
1271   len = strlen (variable);
1272   
1273   /* Mess directly with the environ array.
1274    * This seems to be the only portable way to do this.
1275    *
1276    * Note that we remove *all* environment entries for
1277    * the variable name, not just the first.
1278    */
1279   e = f = environ;
1280   while (*e != NULL) 
1281     {
1282       if (strncmp (*e, variable, len) != 0 || (*e)[len] != '=') 
1283         {
1284           *f = *e;
1285           f++;
1286         }
1287       e++;
1288     }
1289   *f = NULL;
1290 #endif /* !HAVE_UNSETENV */
1291
1292 #else  /* G_OS_WIN32 */
1293
1294   g_return_if_fail (variable != NULL);
1295   g_return_if_fail (strchr (variable, '=') == NULL);
1296   g_return_if_fail (g_utf8_validate (variable, -1, NULL));
1297
1298   if (G_WIN32_HAVE_WIDECHAR_API ())
1299     {
1300       wchar_t *wname = g_utf8_to_utf16 (variable, -1, NULL, NULL, NULL);
1301       gchar *tem = g_strconcat (variable, "=", NULL);
1302       wchar_t *wassignment = g_utf8_to_utf16 (tem, -1, NULL, NULL, NULL);
1303       
1304       g_free (tem);
1305       _wputenv (wassignment);
1306       g_free (wassignment);
1307
1308       SetEnvironmentVariableW (wname, NULL);
1309
1310       g_free (wname);
1311     }
1312   else
1313     {
1314       /* In the non-Unicode case (Win9x), just putenv() is good
1315        * enough.
1316        */
1317       gchar *tem = g_strconcat (variable, "=", NULL);
1318       gchar *cpassignment = g_locale_from_utf8 (tem, -1, NULL, NULL, NULL);
1319
1320       g_free (tem);
1321       
1322       putenv (cpassignment);
1323
1324       g_free (cpassignment);
1325     }
1326
1327 #endif /* G_OS_WIN32 */
1328 }
1329
1330 /**
1331  * g_listenv:
1332  *
1333  * Gets the names of all variables set in the environment.
1334  * 
1335  * Returns: a %NULL-terminated list of strings which must be freed
1336  * with g_strfreev().
1337  *
1338  * Since: 2.8
1339  */
1340 gchar **
1341 g_listenv (void)
1342 {
1343   gchar **result, *eq;
1344   gint len, i;
1345
1346   len = g_strv_length (environ);
1347   result = g_new0 (gchar *, len + 1);
1348   
1349   for (i = 0; i < len; i++)
1350     {
1351       eq = strchr (environ[i], '=');
1352       result[i] = g_strndup (environ[i], eq - environ[i]);
1353     }
1354
1355   result[len] = NULL;
1356
1357   return result;
1358 }
1359
1360 G_LOCK_DEFINE_STATIC (g_utils_global);
1361
1362 static  gchar   *g_tmp_dir = NULL;
1363 static  gchar   *g_user_name = NULL;
1364 static  gchar   *g_real_name = NULL;
1365 static  gchar   *g_home_dir = NULL;
1366 static  gchar   *g_host_name = NULL;
1367
1368 #ifdef G_OS_WIN32
1369 /* System codepage versions of the above, kept at file level so that they,
1370  * too, are produced only once.
1371  */
1372 static  gchar   *g_tmp_dir_cp = NULL;
1373 static  gchar   *g_user_name_cp = NULL;
1374 static  gchar   *g_real_name_cp = NULL;
1375 static  gchar   *g_home_dir_cp = NULL;
1376 #endif
1377
1378 static  gchar   *g_user_data_dir = NULL;
1379 static  gchar  **g_system_data_dirs = NULL;
1380 static  gchar   *g_user_cache_dir = NULL;
1381 static  gchar   *g_user_config_dir = NULL;
1382 static  gchar  **g_system_config_dirs = NULL;
1383
1384 #ifdef G_OS_WIN32
1385
1386 static gchar *
1387 get_special_folder (int csidl)
1388 {
1389   union {
1390     char c[MAX_PATH+1];
1391     wchar_t wc[MAX_PATH+1];
1392   } path;
1393   HRESULT hr;
1394   LPITEMIDLIST pidl = NULL;
1395   BOOL b;
1396   gchar *retval = NULL;
1397
1398   hr = SHGetSpecialFolderLocation (NULL, csidl, &pidl);
1399   if (hr == S_OK)
1400     {
1401       if (G_WIN32_HAVE_WIDECHAR_API ())
1402         {
1403           b = SHGetPathFromIDListW (pidl, path.wc);
1404           if (b)
1405             retval = g_utf16_to_utf8 (path.wc, -1, NULL, NULL, NULL);
1406         }
1407       else
1408         {
1409           b = SHGetPathFromIDListA (pidl, path.c);
1410           if (b)
1411             retval = g_locale_to_utf8 (path.c, -1, NULL, NULL, NULL);
1412         }
1413       CoTaskMemFree (pidl);
1414     }
1415   return retval;
1416 }
1417
1418 static char *
1419 get_windows_directory_root (void)
1420 {
1421   char windowsdir[MAX_PATH];
1422
1423   if (GetWindowsDirectory (windowsdir, sizeof (windowsdir)))
1424     {
1425       /* Usually X:\Windows, but in terminal server environments
1426        * might be an UNC path, AFAIK.
1427        */
1428       char *p = (char *) g_path_skip_root (windowsdir);
1429       if (G_IS_DIR_SEPARATOR (p[-1]) && p[-2] != ':')
1430         p--;
1431       *p = '\0';
1432       return g_strdup (windowsdir);
1433     }
1434   else
1435     return g_strdup ("C:\\");
1436 }
1437
1438 #endif
1439
1440 /* HOLDS: g_utils_global_lock */
1441 static void
1442 g_get_any_init (void)
1443 {
1444   if (!g_tmp_dir)
1445     {
1446       gchar hostname[100];
1447
1448       g_tmp_dir = g_strdup (g_getenv ("TMPDIR"));
1449       if (!g_tmp_dir)
1450         g_tmp_dir = g_strdup (g_getenv ("TMP"));
1451       if (!g_tmp_dir)
1452         g_tmp_dir = g_strdup (g_getenv ("TEMP"));
1453       
1454 #ifdef G_OS_WIN32
1455       if (!g_tmp_dir)
1456         g_tmp_dir = get_windows_directory_root ();
1457 #else
1458 #ifdef P_tmpdir
1459       if (!g_tmp_dir)
1460         {
1461           gsize k;    
1462           g_tmp_dir = g_strdup (P_tmpdir);
1463           k = strlen (g_tmp_dir);
1464           if (k > 1 && G_IS_DIR_SEPARATOR (g_tmp_dir[k - 1]))
1465             g_tmp_dir[k - 1] = '\0';
1466         }
1467 #endif
1468       
1469       if (!g_tmp_dir)
1470         {
1471           g_tmp_dir = g_strdup ("/tmp");
1472         }
1473 #endif  /* !G_OS_WIN32 */
1474       
1475 #ifdef G_OS_WIN32
1476       /* We check $HOME first for Win32, though it is a last resort for Unix
1477        * where we prefer the results of getpwuid().
1478        */
1479       g_home_dir = g_strdup (g_getenv ("HOME"));
1480
1481       /* Only believe HOME if it is an absolute path and exists */
1482       if (g_home_dir)
1483         {
1484           if (!(g_path_is_absolute (g_home_dir) &&
1485                 g_file_test (g_home_dir, G_FILE_TEST_IS_DIR)))
1486             {
1487               g_free (g_home_dir);
1488               g_home_dir = NULL;
1489             }
1490         }
1491       
1492       /* In case HOME is Unix-style (it happens), convert it to
1493        * Windows style.
1494        */
1495       if (g_home_dir)
1496         {
1497           gchar *p;
1498           while ((p = strchr (g_home_dir, '/')) != NULL)
1499             *p = '\\';
1500         }
1501
1502       if (!g_home_dir)
1503         {
1504           /* USERPROFILE is probably the closest equivalent to $HOME? */
1505           if (g_getenv ("USERPROFILE") != NULL)
1506             g_home_dir = g_strdup (g_getenv ("USERPROFILE"));
1507         }
1508
1509       if (!g_home_dir)
1510         g_home_dir = get_special_folder (CSIDL_PROFILE);
1511       
1512       if (!g_home_dir)
1513         g_home_dir = get_windows_directory_root ();
1514 #endif /* G_OS_WIN32 */
1515       
1516 #ifdef HAVE_PWD_H
1517       {
1518         struct passwd *pw = NULL;
1519         gpointer buffer = NULL;
1520         gint error;
1521         
1522 #  if defined (HAVE_POSIX_GETPWUID_R) || defined (HAVE_NONPOSIX_GETPWUID_R)
1523         struct passwd pwd;
1524 #    ifdef _SC_GETPW_R_SIZE_MAX  
1525         /* This reurns the maximum length */
1526         glong bufsize = sysconf (_SC_GETPW_R_SIZE_MAX);
1527         
1528         if (bufsize < 0)
1529           bufsize = 64;
1530 #    else /* _SC_GETPW_R_SIZE_MAX */
1531         glong bufsize = 64;
1532 #    endif /* _SC_GETPW_R_SIZE_MAX */
1533         
1534         do
1535           {
1536             g_free (buffer);
1537             /* we allocate 6 extra bytes to work around a bug in 
1538              * Mac OS < 10.3. See #156446
1539              */
1540             buffer = g_malloc (bufsize + 6);
1541             errno = 0;
1542             
1543 #    ifdef HAVE_POSIX_GETPWUID_R
1544             error = getpwuid_r (getuid (), &pwd, buffer, bufsize, &pw);
1545             error = error < 0 ? errno : error;
1546 #    else /* HAVE_NONPOSIX_GETPWUID_R */
1547        /* HPUX 11 falls into the HAVE_POSIX_GETPWUID_R case */
1548 #      if defined(_AIX) || defined(__hpux)
1549             error = getpwuid_r (getuid (), &pwd, buffer, bufsize);
1550             pw = error == 0 ? &pwd : NULL;
1551 #      else /* !_AIX */
1552             pw = getpwuid_r (getuid (), &pwd, buffer, bufsize);
1553             error = pw ? 0 : errno;
1554 #      endif /* !_AIX */            
1555 #    endif /* HAVE_NONPOSIX_GETPWUID_R */
1556             
1557             if (!pw)
1558               {
1559                 /* we bail out prematurely if the user id can't be found
1560                  * (should be pretty rare case actually), or if the buffer
1561                  * should be sufficiently big and lookups are still not
1562                  * successfull.
1563                  */
1564                 if (error == 0 || error == ENOENT)
1565                   {
1566                     g_warning ("getpwuid_r(): failed due to unknown user id (%lu)",
1567                                (gulong) getuid ());
1568                     break;
1569                   }
1570                 if (bufsize > 32 * 1024)
1571                   {
1572                     g_warning ("getpwuid_r(): failed due to: %s.",
1573                                g_strerror (error));
1574                     break;
1575                   }
1576                 
1577                 bufsize *= 2;
1578               }
1579           }
1580         while (!pw);
1581 #  endif /* HAVE_POSIX_GETPWUID_R || HAVE_NONPOSIX_GETPWUID_R */
1582         
1583         if (!pw)
1584           {
1585             setpwent ();
1586             pw = getpwuid (getuid ());
1587             endpwent ();
1588           }
1589         if (pw)
1590           {
1591             g_user_name = g_strdup (pw->pw_name);
1592
1593             if (pw->pw_gecos && *pw->pw_gecos != '\0') 
1594               {
1595                 gchar **gecos_fields;
1596                 gchar **name_parts;
1597
1598                 /* split the gecos field and substitute '&' */
1599                 gecos_fields = g_strsplit (pw->pw_gecos, ",", 0);
1600                 name_parts = g_strsplit (gecos_fields[0], "&", 0);
1601                 pw->pw_name[0] = g_ascii_toupper (pw->pw_name[0]);
1602                 g_real_name = g_strjoinv (pw->pw_name, name_parts);
1603                 g_strfreev (gecos_fields);
1604                 g_strfreev (name_parts);
1605               }
1606
1607             if (!g_home_dir)
1608               g_home_dir = g_strdup (pw->pw_dir);
1609           }
1610         g_free (buffer);
1611       }
1612       
1613 #else /* !HAVE_PWD_H */
1614       
1615 #ifdef G_OS_WIN32
1616       if (G_WIN32_HAVE_WIDECHAR_API ())
1617         {
1618           guint len = UNLEN+1;
1619           wchar_t buffer[UNLEN+1];
1620           
1621           if (GetUserNameW (buffer, (LPDWORD) &len))
1622             {
1623               g_user_name = g_utf16_to_utf8 (buffer, -1, NULL, NULL, NULL);
1624               g_real_name = g_strdup (g_user_name);
1625             }
1626         }
1627       else
1628         {
1629           guint len = UNLEN+1;
1630           char buffer[UNLEN+1];
1631           
1632           if (GetUserNameA (buffer, (LPDWORD) &len))
1633             {
1634               g_user_name = g_locale_to_utf8 (buffer, -1, NULL, NULL, NULL);
1635               g_real_name = g_strdup (g_user_name);
1636             }
1637         }
1638 #endif /* G_OS_WIN32 */
1639
1640 #endif /* !HAVE_PWD_H */
1641
1642 #ifndef G_OS_WIN32
1643       if (!g_home_dir)
1644         g_home_dir = g_strdup (g_getenv ("HOME"));
1645 #endif
1646
1647 #ifdef __EMX__
1648       /* change '\\' in %HOME% to '/' */
1649       g_strdelimit (g_home_dir, "\\",'/');
1650 #endif
1651       if (!g_user_name)
1652         g_user_name = g_strdup ("somebody");
1653       if (!g_real_name)
1654         g_real_name = g_strdup ("Unknown");
1655
1656 #ifndef G_OS_WIN32
1657       if (gethostname (hostname, sizeof (hostname)) == -1)
1658         g_host_name = g_strdup ("unknown");
1659       else
1660         g_host_name = g_strdup (hostname);
1661 #else
1662       {
1663         DWORD size = sizeof (hostname);
1664         
1665         if (!GetComputerName (hostname, &size))
1666           g_host_name = g_strdup ("unknown");
1667         else
1668           g_host_name = g_strdup (hostname);
1669       }
1670 #endif
1671
1672 #ifdef G_OS_WIN32
1673       g_tmp_dir_cp = g_locale_from_utf8 (g_tmp_dir, -1, NULL, NULL, NULL);
1674       g_user_name_cp = g_locale_from_utf8 (g_user_name, -1, NULL, NULL, NULL);
1675       g_real_name_cp = g_locale_from_utf8 (g_real_name, -1, NULL, NULL, NULL);
1676
1677       if (!g_tmp_dir_cp)
1678         g_tmp_dir_cp = g_strdup ("\\");
1679       if (!g_user_name_cp)
1680         g_user_name_cp = g_strdup ("somebody");
1681       if (!g_real_name_cp)
1682         g_real_name_cp = g_strdup ("Unknown");
1683
1684       /* home_dir might be NULL, unlike tmp_dir, user_name and
1685        * real_name.
1686        */
1687       if (g_home_dir)
1688         g_home_dir_cp = g_locale_from_utf8 (g_home_dir, -1, NULL, NULL, NULL);
1689       else
1690         g_home_dir_cp = NULL;
1691 #endif /* G_OS_WIN32 */
1692     }
1693 }
1694
1695 /**
1696  * g_get_user_name:
1697  *
1698  * Gets the user name of the current user. The encoding of the returned
1699  * string is system-defined. On UNIX, it might be the preferred file name
1700  * encoding, or something else, and there is no guarantee that it is even
1701  * consistent on a machine. On Windows, it is always UTF-8.
1702  *
1703  * Returns: the user name of the current user.
1704  */
1705 G_CONST_RETURN gchar*
1706 g_get_user_name (void)
1707 {
1708   G_LOCK (g_utils_global);
1709   if (!g_tmp_dir)
1710     g_get_any_init ();
1711   G_UNLOCK (g_utils_global);
1712   
1713   return g_user_name;
1714 }
1715
1716 /**
1717  * g_get_real_name:
1718  *
1719  * Gets the real name of the user. This usually comes from the user's entry 
1720  * in the <filename>passwd</filename> file. The encoding of the returned 
1721  * string is system-defined. (On Windows, it is, however, always UTF-8.) 
1722  * If the real user name cannot be determined, the string "Unknown" is 
1723  * returned.
1724  *
1725  * Returns: the user's real name.
1726  */
1727 G_CONST_RETURN gchar*
1728 g_get_real_name (void)
1729 {
1730   G_LOCK (g_utils_global);
1731   if (!g_tmp_dir)
1732     g_get_any_init ();
1733   G_UNLOCK (g_utils_global);
1734  
1735   return g_real_name;
1736 }
1737
1738 /**
1739  * g_get_home_dir:
1740  *
1741  * Gets the current user's home directory. 
1742  *
1743  * Note that in contrast to traditional UNIX tools, this function 
1744  * prefers <filename>passwd</filename> entries over the <envar>HOME</envar> 
1745  * environment variable.
1746  *
1747  * Returns: the current user's home directory.
1748  */
1749 G_CONST_RETURN gchar*
1750 g_get_home_dir (void)
1751 {
1752   G_LOCK (g_utils_global);
1753   if (!g_tmp_dir)
1754     g_get_any_init ();
1755   G_UNLOCK (g_utils_global);
1756   
1757   return g_home_dir;
1758 }
1759
1760 /**
1761  * g_get_tmp_dir:
1762  *
1763  * Gets the directory to use for temporary files. This is found from 
1764  * inspecting the environment variables <envar>TMPDIR</envar>, 
1765  * <envar>TMP</envar>, and <envar>TEMP</envar> in that order. If none 
1766  * of those are defined "/tmp" is returned on UNIX and "C:\" on Windows. 
1767  * The encoding of the returned string is system-defined. On Windows, 
1768  * it is always UTF-8. The return value is never %NULL.
1769  *
1770  * Returns: the directory to use for temporary files.
1771  */
1772 G_CONST_RETURN gchar*
1773 g_get_tmp_dir (void)
1774 {
1775   G_LOCK (g_utils_global);
1776   if (!g_tmp_dir)
1777     g_get_any_init ();
1778   G_UNLOCK (g_utils_global);
1779   
1780   return g_tmp_dir;
1781 }
1782
1783 /**
1784  * g_get_host_name:
1785  *
1786  * Return a name for the machine. 
1787  *
1788  * The returned name is not necessarily a fully-qualified domain name,
1789  * or even present in DNS or some other name service at all. It need
1790  * not even be unique on your local network or site, but usually it
1791  * is. Callers should not rely on the return value having any specific
1792  * properties like uniqueness for security purposes. Even if the name
1793  * of the machine is changed while an application is running, the
1794  * return value from this function does not change. The returned
1795  * string is owned by GLib and should not be modified or freed. If no
1796  * name can be determined, a default fixed string "unknown" is
1797  * returned.
1798  *
1799  * Since: 2.8
1800  */
1801 const gchar *
1802 g_get_host_name (void)
1803 {
1804   G_LOCK (g_utils_global);
1805   if (!g_tmp_dir)
1806     g_get_any_init ();
1807   G_UNLOCK (g_utils_global);
1808
1809   return g_host_name;
1810 }
1811
1812 G_LOCK_DEFINE_STATIC (g_prgname);
1813 static gchar *g_prgname = NULL;
1814
1815 /**
1816  * g_get_prgname:
1817  *
1818  * Gets the name of the program. This name should <emphasis>not</emphasis> 
1819  * be localized, contrast with g_get_application_name().
1820  * (If you are using GDK or GTK+ the program name is set in gdk_init(), 
1821  * which is called by gtk_init(). The program name is found by taking 
1822  * the last component of <literal>argv[0]</literal>.)
1823  *
1824  * Returns: the name of the program. The returned string belongs 
1825  * to GLib and must not be modified or freed.
1826  */
1827 gchar*
1828 g_get_prgname (void)
1829 {
1830   gchar* retval;
1831
1832   G_LOCK (g_prgname);
1833 #ifdef G_OS_WIN32
1834   if (g_prgname == NULL)
1835     {
1836       static gboolean beenhere = FALSE;
1837
1838       if (!beenhere)
1839         {
1840           gchar *utf8_buf = NULL;
1841
1842           beenhere = TRUE;
1843           if (G_WIN32_HAVE_WIDECHAR_API ())
1844             {
1845               wchar_t buf[MAX_PATH+1];
1846               if (GetModuleFileNameW (GetModuleHandle (NULL),
1847                                       buf, G_N_ELEMENTS (buf)) > 0)
1848                 utf8_buf = g_utf16_to_utf8 (buf, -1, NULL, NULL, NULL);
1849             }
1850           else
1851             {
1852               gchar buf[MAX_PATH+1];
1853               if (GetModuleFileNameA (GetModuleHandle (NULL),
1854                                       buf, G_N_ELEMENTS (buf)) > 0)
1855                 utf8_buf = g_locale_to_utf8 (buf, -1, NULL, NULL, NULL);
1856             }
1857           if (utf8_buf)
1858             {
1859               g_prgname = g_path_get_basename (utf8_buf);
1860               g_free (utf8_buf);
1861             }
1862         }
1863     }
1864 #endif
1865   retval = g_prgname;
1866   G_UNLOCK (g_prgname);
1867
1868   return retval;
1869 }
1870
1871 /**
1872  * g_set_prgname:
1873  * @prgname: the name of the program.
1874  *
1875  * Sets the name of the program. This name should <emphasis>not</emphasis> 
1876  * be localized, contrast with g_set_application_name(). Note that for 
1877  * thread-safety reasons this function can only be called once.
1878  */
1879 void
1880 g_set_prgname (const gchar *prgname)
1881 {
1882   G_LOCK (g_prgname);
1883   g_free (g_prgname);
1884   g_prgname = g_strdup (prgname);
1885   G_UNLOCK (g_prgname);
1886 }
1887
1888 G_LOCK_DEFINE_STATIC (g_application_name);
1889 static gchar *g_application_name = NULL;
1890
1891 /**
1892  * g_get_application_name:
1893  * 
1894  * Gets a human-readable name for the application, as set by
1895  * g_set_application_name(). This name should be localized if
1896  * possible, and is intended for display to the user.  Contrast with
1897  * g_get_prgname(), which gets a non-localized name. If
1898  * g_set_application_name() has not been called, returns the result of
1899  * g_get_prgname() (which may be %NULL if g_set_prgname() has also not
1900  * been called).
1901  * 
1902  * Return value: human-readable application name. may return %NULL
1903  *
1904  * Since: 2.2
1905  **/
1906 G_CONST_RETURN gchar*
1907 g_get_application_name (void)
1908 {
1909   gchar* retval;
1910
1911   G_LOCK (g_application_name);
1912   retval = g_application_name;
1913   G_UNLOCK (g_application_name);
1914
1915   if (retval == NULL)
1916     return g_get_prgname ();
1917   
1918   return retval;
1919 }
1920
1921 /**
1922  * g_set_application_name:
1923  * @application_name: localized name of the application
1924  *
1925  * Sets a human-readable name for the application. This name should be
1926  * localized if possible, and is intended for display to the user.
1927  * Contrast with g_set_prgname(), which sets a non-localized name.
1928  * g_set_prgname() will be called automatically by gtk_init(),
1929  * but g_set_application_name() will not.
1930  *
1931  * Note that for thread safety reasons, this function can only
1932  * be called once.
1933  *
1934  * The application name will be used in contexts such as error messages,
1935  * or when displaying an application's name in the task list.
1936  * 
1937  **/
1938 void
1939 g_set_application_name (const gchar *application_name)
1940 {
1941   gboolean already_set = FALSE;
1942         
1943   G_LOCK (g_application_name);
1944   if (g_application_name)
1945     already_set = TRUE;
1946   else
1947     g_application_name = g_strdup (application_name);
1948   G_UNLOCK (g_application_name);
1949
1950   if (already_set)
1951     g_warning ("g_set_application() name called multiple times");
1952 }
1953
1954 /**
1955  * g_get_user_data_dir:
1956  * 
1957  * Returns a base directory in which to access application data such
1958  * as icons that is customized for a particular user.  
1959  *
1960  * On UNIX platforms this is determined using the mechanisms described in
1961  * the <ulink url="http://www.freedesktop.org/Standards/basedir-spec">
1962  * XDG Base Directory Specification</ulink>
1963  * 
1964  * Return value: a string owned by GLib that must not be modified 
1965  *               or freed.
1966  * Since: 2.6
1967  **/
1968 G_CONST_RETURN gchar*
1969 g_get_user_data_dir (void)
1970 {
1971   gchar *data_dir;  
1972
1973   G_LOCK (g_utils_global);
1974
1975   if (!g_user_data_dir)
1976     {
1977 #ifdef G_OS_WIN32
1978       data_dir = get_special_folder (CSIDL_PERSONAL);
1979 #else
1980       data_dir = (gchar *) g_getenv ("XDG_DATA_HOME");
1981
1982       if (data_dir && data_dir[0])
1983         data_dir = g_strdup (data_dir);
1984 #endif
1985       if (!data_dir || !data_dir[0])
1986         {
1987           if (!g_tmp_dir)
1988             g_get_any_init ();
1989
1990           if (g_home_dir)
1991             data_dir = g_build_filename (g_home_dir, ".local", 
1992                                          "share", NULL);
1993           else
1994             data_dir = g_build_filename (g_tmp_dir, g_user_name, ".local",
1995                                          "share", NULL);
1996         }
1997
1998       g_user_data_dir = data_dir;
1999     }
2000   else
2001     data_dir = g_user_data_dir;
2002
2003   G_UNLOCK (g_utils_global);
2004
2005   return data_dir;
2006 }
2007
2008 /**
2009  * g_get_user_config_dir:
2010  * 
2011  * Returns a base directory in which to store user-specific application 
2012  * configuration information such as user preferences and settings. 
2013  *
2014  * On UNIX platforms this is determined using the mechanisms described in
2015  * the <ulink url="http://www.freedesktop.org/Standards/basedir-spec">
2016  * XDG Base Directory Specification</ulink>
2017  * 
2018  * Return value: a string owned by GLib that must not be modified 
2019  *               or freed.
2020  * Since: 2.6
2021  **/
2022 G_CONST_RETURN gchar*
2023 g_get_user_config_dir (void)
2024 {
2025   gchar *config_dir;  
2026
2027   G_LOCK (g_utils_global);
2028
2029   if (!g_user_config_dir)
2030     {
2031 #ifdef G_OS_WIN32
2032       config_dir = get_special_folder (CSIDL_APPDATA);
2033 #else
2034       config_dir = (gchar *) g_getenv ("XDG_CONFIG_HOME");
2035
2036       if (config_dir && config_dir[0])
2037         config_dir = g_strdup (config_dir);
2038 #endif
2039       if (!config_dir || !config_dir[0])
2040         {
2041           if (!g_tmp_dir)
2042             g_get_any_init ();
2043           
2044           if (g_home_dir)
2045             config_dir = g_build_filename (g_home_dir, ".config", NULL);
2046           else
2047             config_dir = g_build_filename (g_tmp_dir, g_user_name, ".config", NULL);
2048         }
2049       g_user_config_dir = config_dir;
2050     }
2051   else
2052     config_dir = g_user_config_dir;
2053
2054   G_UNLOCK (g_utils_global);
2055
2056   return config_dir;
2057 }
2058
2059 /**
2060  * g_get_user_cache_dir:
2061  * 
2062  * Returns a base directory in which to store non-essential, cached
2063  * data specific to particular user.
2064  *
2065  * On UNIX platforms this is determined using the mechanisms described in
2066  * the <ulink url="http://www.freedesktop.org/Standards/basedir-spec">
2067  * XDG Base Directory Specification</ulink>
2068  * 
2069  * Return value: a string owned by GLib that must not be modified 
2070  *               or freed.
2071  * Since: 2.6
2072  **/
2073 G_CONST_RETURN gchar*
2074 g_get_user_cache_dir (void)
2075 {
2076   gchar *cache_dir;  
2077
2078   G_LOCK (g_utils_global);
2079
2080   if (!g_user_cache_dir)
2081     {
2082 #ifdef G_OS_WIN32
2083       cache_dir = get_special_folder (CSIDL_INTERNET_CACHE); /* XXX correct? */
2084 #else
2085       cache_dir = (gchar *) g_getenv ("XDG_CACHE_HOME");
2086
2087       if (cache_dir && cache_dir[0])
2088           cache_dir = g_strdup (cache_dir);
2089 #endif
2090       if (!cache_dir || !cache_dir[0])
2091         {
2092           if (!g_tmp_dir)
2093             g_get_any_init ();
2094
2095           if (g_home_dir)
2096             cache_dir = g_build_filename (g_home_dir, ".cache", NULL);
2097           else
2098             cache_dir = g_build_filename (g_tmp_dir, g_user_name, ".cache", NULL);
2099         }
2100       g_user_cache_dir = cache_dir;
2101     }
2102   else
2103     cache_dir = g_user_cache_dir;
2104
2105   G_UNLOCK (g_utils_global);
2106
2107   return cache_dir;
2108 }
2109
2110 #ifdef G_OS_WIN32
2111
2112 #undef g_get_system_data_dirs
2113
2114 static HMODULE
2115 get_module_for_address (gconstpointer address)
2116 {
2117   /* Holds the g_utils_global lock */
2118
2119   static gboolean beenhere = FALSE;
2120   typedef BOOL (WINAPI *t_GetModuleHandleExA) (DWORD, LPCTSTR, HMODULE *);
2121   static t_GetModuleHandleExA p_GetModuleHandleExA = NULL;
2122   HMODULE hmodule;
2123
2124   if (!address)
2125     return NULL;
2126
2127   if (!beenhere)
2128     {
2129       p_GetModuleHandleExA =
2130         (t_GetModuleHandleExA) GetProcAddress (LoadLibrary ("kernel32.dll"),
2131                                                "GetModuleHandleExA");
2132       beenhere = TRUE;
2133     }
2134
2135   if (p_GetModuleHandleExA == NULL ||
2136       !(*p_GetModuleHandleExA) (GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT |
2137                                 GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
2138                                 address, &hmodule))
2139     {
2140       MEMORY_BASIC_INFORMATION mbi;
2141       VirtualQuery (address, &mbi, sizeof (mbi));
2142       hmodule = (HMODULE) mbi.AllocationBase;
2143     }
2144
2145   return hmodule;
2146 }
2147
2148 static gchar *
2149 get_module_share_dir (gconstpointer address)
2150 {
2151   HMODULE hmodule;
2152   gchar *filename = NULL;
2153   gchar *p, *retval;
2154
2155   hmodule = get_module_for_address (address);
2156   if (hmodule == NULL)
2157     return NULL;
2158
2159   if (G_WIN32_IS_NT_BASED ())
2160     {
2161       wchar_t wfilename[MAX_PATH];
2162       if (GetModuleFileNameW (hmodule, wfilename, G_N_ELEMENTS (wfilename)))
2163         filename = g_utf16_to_utf8 (wfilename, -1, NULL, NULL, NULL);
2164     }
2165   else
2166     {
2167       char cpfilename[MAX_PATH];
2168       if (GetModuleFileNameA (hmodule, cpfilename, G_N_ELEMENTS (cpfilename)))
2169         filename = g_locale_to_utf8 (cpfilename, -1, NULL, NULL, NULL);
2170     }
2171
2172   if (filename == NULL)
2173     return NULL;
2174
2175   if ((p = strrchr (filename, G_DIR_SEPARATOR)) != NULL)
2176     *p = '\0';
2177
2178   p = strrchr (filename, G_DIR_SEPARATOR);
2179   if (p && (g_ascii_strcasecmp (p + 1, "bin") == 0))
2180     *p = '\0';
2181
2182   retval = g_build_filename (filename, "share", NULL);
2183   g_free (filename);
2184
2185   return retval;
2186 }
2187
2188 G_CONST_RETURN gchar * G_CONST_RETURN *
2189 g_win32_get_system_data_dirs_for_module (gconstpointer address)
2190 {
2191   GArray *data_dirs;
2192   HMODULE hmodule;
2193   static GHashTable *per_module_data_dirs = NULL;
2194   gchar **retval;
2195   gchar *p;
2196       
2197   if (address)
2198     {
2199       G_LOCK (g_utils_global);
2200       hmodule = get_module_for_address (address);
2201       if (hmodule != NULL)
2202         {
2203           if (per_module_data_dirs == NULL)
2204             per_module_data_dirs = g_hash_table_new (NULL, NULL);
2205           else
2206             {
2207               retval = g_hash_table_lookup (per_module_data_dirs, hmodule);
2208               
2209               if (retval != NULL)
2210                 {
2211                   G_UNLOCK (g_utils_global);
2212                   return (G_CONST_RETURN gchar * G_CONST_RETURN *) retval;
2213                 }
2214             }
2215         }
2216     }
2217
2218   data_dirs = g_array_new (TRUE, TRUE, sizeof (char *));
2219
2220   /* Documents and Settings\All Users\Application Data */
2221   p = get_special_folder (CSIDL_COMMON_APPDATA);
2222   if (p)
2223     g_array_append_val (data_dirs, p);
2224   
2225   /* Documents and Settings\All Users\Documents */
2226   p = get_special_folder (CSIDL_COMMON_DOCUMENTS);
2227   if (p)
2228     g_array_append_val (data_dirs, p);
2229         
2230   /* Using the above subfolders of Documents and Settings perhaps
2231    * makes sense from a Windows perspective.
2232    *
2233    * But looking at the actual use cases of this function in GTK+
2234    * and GNOME software, what we really want is the "share"
2235    * subdirectory of the installation directory for the package
2236    * our caller is a part of.
2237    *
2238    * The address parameter, if non-NULL, points to a function in the
2239    * calling module. Use that to determine that module's installation
2240    * folder, and use its "share" subfolder.
2241    *
2242    * Additionally, also use the "share" subfolder of the installation
2243    * locations of GLib and the .exe file being run.
2244    *
2245    * To guard against none of the above being what is really wanted,
2246    * callers of this function should have Win32-specific code to look
2247    * up their installation folder themselves, and handle a subfolder
2248    * "share" of it in the same way as the folders returned from this
2249    * function.
2250    */
2251
2252   p = get_module_share_dir (address);
2253   if (p)
2254     g_array_append_val (data_dirs, p);
2255     
2256   p = g_win32_get_package_installation_subdirectory (NULL, dll_name, "share");
2257   if (p)
2258     g_array_append_val (data_dirs, p);
2259   
2260   p = g_win32_get_package_installation_subdirectory (NULL, NULL, "share");
2261   if (p)
2262     g_array_append_val (data_dirs, p);
2263
2264   retval = (gchar **) g_array_free (data_dirs, FALSE);
2265
2266   if (address)
2267     {
2268       if (hmodule != NULL)
2269         g_hash_table_insert (per_module_data_dirs, hmodule, retval);
2270       G_UNLOCK (g_utils_global);
2271     }
2272
2273   return (G_CONST_RETURN gchar * G_CONST_RETURN *) retval;
2274 }
2275
2276 #endif
2277
2278 /**
2279  * g_get_system_data_dirs:
2280  * 
2281  * Returns an ordered list of base directories in which to access 
2282  * system-wide application data.
2283  *
2284  * On UNIX platforms this is determined using the mechanisms described in
2285  * the <ulink url="http://www.freedesktop.org/Standards/basedir-spec">
2286  * XDG Base Directory Specification</ulink>
2287  * 
2288  * On Windows the first elements in the list are the Application Data
2289  * and Documents folders for All Users. (These can be determined only
2290  * on Windows 2000 or later and are not present in the list on other
2291  * Windows versions.) See documentation for CSIDL_COMMON_APPDATA and
2292  * CSIDL_COMMON_DOCUMENTS.
2293  *
2294  * Then follows the "share" subfolder in the installation folder for
2295  * the package containing the DLL that calls this function, if it can
2296  * be determined.
2297  * 
2298  * Finally the list contains the "share" subfolder in the installation
2299  * folder for GLib, and in the installation folder for the package the
2300  * application's .exe file belongs to.
2301  *
2302  * The installation folders above are determined by looking up the
2303  * folder where the module (DLL or EXE) in question is located. If the
2304  * folder's name is "bin", its parent is used, otherwise the folder
2305  * itself.
2306  *
2307  * Note that on Windows the returned list can vary depending on where
2308  * this function is called.
2309  *
2310  * Return value: a %NULL-terminated array of strings owned by GLib that must 
2311  *               not be modified or freed.
2312  * Since: 2.6
2313  **/
2314 G_CONST_RETURN gchar * G_CONST_RETURN * 
2315 g_get_system_data_dirs (void)
2316 {
2317   gchar **data_dir_vector;
2318
2319   G_LOCK (g_utils_global);
2320
2321   if (!g_system_data_dirs)
2322     {
2323 #ifdef G_OS_WIN32
2324       data_dir_vector = (gchar **) g_win32_get_system_data_dirs_for_module (NULL);
2325 #else
2326       gchar *data_dirs = (gchar *) g_getenv ("XDG_DATA_DIRS");
2327
2328       if (!data_dirs || !data_dirs[0])
2329           data_dirs = "/usr/local/share/:/usr/share/";
2330
2331       data_dir_vector = g_strsplit (data_dirs, G_SEARCHPATH_SEPARATOR_S, 0);
2332 #endif
2333
2334       g_system_data_dirs = data_dir_vector;
2335     }
2336   else
2337     data_dir_vector = g_system_data_dirs;
2338
2339   G_UNLOCK (g_utils_global);
2340
2341   return (G_CONST_RETURN gchar * G_CONST_RETURN *) data_dir_vector;
2342 }
2343
2344 /**
2345  * g_get_system_config_dirs:
2346  * 
2347  * Returns an ordered list of base directories in which to access 
2348  * system-wide configuration information.
2349  *
2350  * On UNIX platforms this is determined using the mechanisms described in
2351  * the <ulink url="http://www.freedesktop.org/Standards/basedir-spec">
2352  * XDG Base Directory Specification</ulink>
2353  * 
2354  * Return value: a %NULL-terminated array of strings owned by GLib that must 
2355  *               not be modified or freed.
2356  * Since: 2.6
2357  **/
2358 G_CONST_RETURN gchar * G_CONST_RETURN *
2359 g_get_system_config_dirs (void)
2360 {
2361   gchar *conf_dirs, **conf_dir_vector;
2362
2363   G_LOCK (g_utils_global);
2364
2365   if (!g_system_config_dirs)
2366     {
2367 #ifdef G_OS_WIN32
2368       conf_dirs = get_special_folder (CSIDL_COMMON_APPDATA);
2369       if (conf_dirs)
2370         {
2371           conf_dir_vector = g_strsplit (conf_dirs, G_SEARCHPATH_SEPARATOR_S, 0);
2372           g_free (conf_dirs);
2373         }
2374       else
2375         {
2376           /* Return empty list */
2377           conf_dir_vector = g_strsplit ("", G_SEARCHPATH_SEPARATOR_S, 0);
2378         }
2379 #else
2380       conf_dirs = (gchar *) g_getenv ("XDG_CONFIG_DIRS");
2381
2382       if (!conf_dirs || !conf_dirs[0])
2383           conf_dirs = "/etc/xdg";
2384
2385       conf_dir_vector = g_strsplit (conf_dirs, G_SEARCHPATH_SEPARATOR_S, 0);
2386 #endif
2387
2388       g_system_config_dirs = conf_dir_vector;
2389     }
2390   else
2391     conf_dir_vector = g_system_config_dirs;
2392   G_UNLOCK (g_utils_global);
2393
2394   return (G_CONST_RETURN gchar * G_CONST_RETURN *) conf_dir_vector;
2395 }
2396
2397 #ifndef G_OS_WIN32
2398
2399 static GHashTable *alias_table = NULL;
2400
2401 /* read an alias file for the locales */
2402 static void
2403 read_aliases (gchar *file)
2404 {
2405   FILE *fp;
2406   char buf[256];
2407   
2408   if (!alias_table)
2409     alias_table = g_hash_table_new (g_str_hash, g_str_equal);
2410   fp = fopen (file,"r");
2411   if (!fp)
2412     return;
2413   while (fgets (buf, 256, fp))
2414     {
2415       char *p, *q;
2416
2417       g_strstrip (buf);
2418
2419       /* Line is a comment */
2420       if ((buf[0] == '#') || (buf[0] == '\0'))
2421         continue;
2422
2423       /* Reads first column */
2424       for (p = buf, q = NULL; *p; p++) {
2425         if ((*p == '\t') || (*p == ' ') || (*p == ':')) {
2426           *p = '\0';
2427           q = p+1;
2428           while ((*q == '\t') || (*q == ' ')) {
2429             q++;
2430           }
2431           break;
2432         }
2433       }
2434       /* The line only had one column */
2435       if (!q || *q == '\0')
2436         continue;
2437       
2438       /* Read second column */
2439       for (p = q; *p; p++) {
2440         if ((*p == '\t') || (*p == ' ')) {
2441           *p = '\0';
2442           break;
2443         }
2444       }
2445
2446       /* Add to alias table if necessary */
2447       if (!g_hash_table_lookup (alias_table, buf)) {
2448         g_hash_table_insert (alias_table, g_strdup (buf), g_strdup (q));
2449       }
2450     }
2451   fclose (fp);
2452 }
2453
2454 #endif
2455
2456 static char *
2457 unalias_lang (char *lang)
2458 {
2459 #ifndef G_OS_WIN32
2460   char *p;
2461   int i;
2462
2463   if (!alias_table)
2464     read_aliases ("/usr/share/locale/locale.alias");
2465
2466   i = 0;
2467   while ((p = g_hash_table_lookup (alias_table, lang)) && (strcmp (p, lang) != 0))
2468     {
2469       lang = p;
2470       if (i++ == 30)
2471         {
2472           static gboolean said_before = FALSE;
2473           if (!said_before)
2474             g_warning ("Too many alias levels for a locale, "
2475                        "may indicate a loop");
2476           said_before = TRUE;
2477           return lang;
2478         }
2479     }
2480 #endif
2481   return lang;
2482 }
2483
2484 /* Mask for components of locale spec. The ordering here is from
2485  * least significant to most significant
2486  */
2487 enum
2488 {
2489   COMPONENT_CODESET =   1 << 0,
2490   COMPONENT_TERRITORY = 1 << 1,
2491   COMPONENT_MODIFIER =  1 << 2
2492 };
2493
2494 /* Break an X/Open style locale specification into components
2495  */
2496 static guint
2497 explode_locale (const gchar *locale,
2498                 gchar      **language, 
2499                 gchar      **territory, 
2500                 gchar      **codeset, 
2501                 gchar      **modifier)
2502 {
2503   const gchar *uscore_pos;
2504   const gchar *at_pos;
2505   const gchar *dot_pos;
2506
2507   guint mask = 0;
2508
2509   uscore_pos = strchr (locale, '_');
2510   dot_pos = strchr (uscore_pos ? uscore_pos : locale, '.');
2511   at_pos = strchr (dot_pos ? dot_pos : (uscore_pos ? uscore_pos : locale), '@');
2512
2513   if (at_pos)
2514     {
2515       mask |= COMPONENT_MODIFIER;
2516       *modifier = g_strdup (at_pos);
2517     }
2518   else
2519     at_pos = locale + strlen (locale);
2520
2521   if (dot_pos)
2522     {
2523       mask |= COMPONENT_CODESET;
2524       *codeset = g_strndup (dot_pos, at_pos - dot_pos);
2525     }
2526   else
2527     dot_pos = at_pos;
2528
2529   if (uscore_pos)
2530     {
2531       mask |= COMPONENT_TERRITORY;
2532       *territory = g_strndup (uscore_pos, dot_pos - uscore_pos);
2533     }
2534   else
2535     uscore_pos = dot_pos;
2536
2537   *language = g_strndup (locale, uscore_pos - locale);
2538
2539   return mask;
2540 }
2541
2542 /*
2543  * Compute all interesting variants for a given locale name -
2544  * by stripping off different components of the value.
2545  *
2546  * For simplicity, we assume that the locale is in
2547  * X/Open format: language[_territory][.codeset][@modifier]
2548  *
2549  * TODO: Extend this to handle the CEN format (see the GNUlibc docs)
2550  *       as well. We could just copy the code from glibc wholesale
2551  *       but it is big, ugly, and complicated, so I'm reluctant
2552  *       to do so when this should handle 99% of the time...
2553  */
2554 GSList *
2555 _g_compute_locale_variants (const gchar *locale)
2556 {
2557   GSList *retval = NULL;
2558
2559   gchar *language;
2560   gchar *territory;
2561   gchar *codeset;
2562   gchar *modifier;
2563
2564   guint mask;
2565   guint i;
2566
2567   g_return_val_if_fail (locale != NULL, NULL);
2568
2569   mask = explode_locale (locale, &language, &territory, &codeset, &modifier);
2570
2571   /* Iterate through all possible combinations, from least attractive
2572    * to most attractive.
2573    */
2574   for (i = 0; i <= mask; i++)
2575     if ((i & ~mask) == 0)
2576       {
2577         gchar *val = g_strconcat (language,
2578                                   (i & COMPONENT_TERRITORY) ? territory : "",
2579                                   (i & COMPONENT_CODESET) ? codeset : "",
2580                                   (i & COMPONENT_MODIFIER) ? modifier : "",
2581                                   NULL);
2582         retval = g_slist_prepend (retval, val);
2583       }
2584
2585   g_free (language);
2586   if (mask & COMPONENT_CODESET)
2587     g_free (codeset);
2588   if (mask & COMPONENT_TERRITORY)
2589     g_free (territory);
2590   if (mask & COMPONENT_MODIFIER)
2591     g_free (modifier);
2592
2593   return retval;
2594 }
2595
2596 /* The following is (partly) taken from the gettext package.
2597    Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.  */
2598
2599 static const gchar *
2600 guess_category_value (const gchar *category_name)
2601 {
2602   const gchar *retval;
2603
2604   /* The highest priority value is the `LANGUAGE' environment
2605      variable.  This is a GNU extension.  */
2606   retval = g_getenv ("LANGUAGE");
2607   if ((retval != NULL) && (retval[0] != '\0'))
2608     return retval;
2609
2610   /* `LANGUAGE' is not set.  So we have to proceed with the POSIX
2611      methods of looking to `LC_ALL', `LC_xxx', and `LANG'.  On some
2612      systems this can be done by the `setlocale' function itself.  */
2613
2614   /* Setting of LC_ALL overwrites all other.  */
2615   retval = g_getenv ("LC_ALL");  
2616   if ((retval != NULL) && (retval[0] != '\0'))
2617     return retval;
2618
2619   /* Next comes the name of the desired category.  */
2620   retval = g_getenv (category_name);
2621   if ((retval != NULL) && (retval[0] != '\0'))
2622     return retval;
2623
2624   /* Last possibility is the LANG environment variable.  */
2625   retval = g_getenv ("LANG");
2626   if ((retval != NULL) && (retval[0] != '\0'))
2627     return retval;
2628
2629 #ifdef G_PLATFORM_WIN32
2630   /* g_win32_getlocale() first checks for LC_ALL, LC_MESSAGES and
2631    * LANG, which we already did above. Oh well. The main point of
2632    * calling g_win32_getlocale() is to get the thread's locale as used
2633    * by Windows and the Microsoft C runtime (in the "English_United
2634    * States" format) translated into the Unixish format.
2635    */
2636   retval = g_win32_getlocale ();
2637   if ((retval != NULL) && (retval[0] != '\0'))
2638     return retval;
2639 #endif  
2640
2641   return NULL;
2642 }
2643
2644 typedef struct _GLanguageNamesCache GLanguageNamesCache;
2645
2646 struct _GLanguageNamesCache {
2647   gchar *languages;
2648   gchar **language_names;
2649 };
2650
2651 static void
2652 language_names_cache_free (gpointer data)
2653 {
2654   GLanguageNamesCache *cache = data;
2655   g_free (cache->languages);
2656   g_strfreev (cache->language_names);
2657   g_free (cache);
2658 }
2659
2660 /**
2661  * g_get_language_names:
2662  * 
2663  * Computes a list of applicable locale names, which can be used to 
2664  * e.g. construct locale-dependent filenames or search paths. The returned 
2665  * list is sorted from most desirable to least desirable and always contains 
2666  * the default locale "C".
2667  *
2668  * For example, if LANGUAGE=de:en_US, then the returned list is
2669  * "de", "en_US", "en", "C".
2670  *
2671  * This function consults the environment variables <envar>LANGUAGE</envar>, 
2672  * <envar>LC_ALL</envar>, <envar>LC_MESSAGES</envar> and <envar>LANG</envar> 
2673  * to find the list of locales specified by the user.
2674  * 
2675  * Return value: a %NULL-terminated array of strings owned by GLib 
2676  *    that must not be modified or freed.
2677  *
2678  * Since: 2.6
2679  **/
2680 G_CONST_RETURN gchar * G_CONST_RETURN * 
2681 g_get_language_names (void)
2682 {
2683   static GStaticPrivate cache_private = G_STATIC_PRIVATE_INIT;
2684   GLanguageNamesCache *cache = g_static_private_get (&cache_private);
2685   const gchar *value;
2686
2687   if (!cache)
2688     {
2689       cache = g_new0 (GLanguageNamesCache, 1);
2690       g_static_private_set (&cache_private, cache, language_names_cache_free);
2691     }
2692
2693   value = guess_category_value ("LC_MESSAGES");
2694   if (!value)
2695     value = "C";
2696
2697   if (!(cache->languages && strcmp (cache->languages, value) == 0))
2698     {
2699       gchar **languages;
2700       gchar **alist, **a;
2701       GSList *list, *l;
2702       gint i;
2703
2704       g_free (cache->languages);
2705       g_strfreev (cache->language_names);
2706       cache->languages = g_strdup (value);
2707
2708       alist = g_strsplit (value, ":", 0);
2709       list = NULL;
2710       for (a = alist; *a; a++)
2711         {
2712           gchar *b = unalias_lang (*a);
2713           list = g_slist_concat (list, _g_compute_locale_variants (b));
2714         }
2715       g_strfreev (alist);
2716       list = g_slist_append (list, g_strdup ("C"));
2717
2718       cache->language_names = languages = g_new (gchar *, g_slist_length (list) + 1);
2719       for (l = list, i = 0; l; l = l->next, i++)
2720         languages[i] = l->data;
2721       languages[i] = NULL;
2722
2723       g_slist_free (list);
2724     }
2725
2726   return (G_CONST_RETURN gchar * G_CONST_RETURN *) cache->language_names;
2727 }
2728
2729 /**
2730  * g_direct_hash:
2731  * @v: a #gpointer key
2732  *
2733  * Converts a gpointer to a hash value.
2734  * It can be passed to g_hash_table_new() as the @hash_func parameter, 
2735  * when using pointers as keys in a #GHashTable.
2736  *
2737  * Returns: a hash value corresponding to the key.
2738  */
2739 guint
2740 g_direct_hash (gconstpointer v)
2741 {
2742   return GPOINTER_TO_UINT (v);
2743 }
2744
2745 /**
2746  * g_direct_equal:
2747  * @v1: a key.
2748  * @v2: a key to compare with @v1.
2749  *
2750  * Compares two #gpointer arguments and returns %TRUE if they are equal.
2751  * It can be passed to g_hash_table_new() as the @key_equal_func
2752  * parameter, when using pointers as keys in a #GHashTable.
2753  * 
2754  * Returns: %TRUE if the two keys match.
2755  */
2756 gboolean
2757 g_direct_equal (gconstpointer v1,
2758                 gconstpointer v2)
2759 {
2760   return v1 == v2;
2761 }
2762
2763 /**
2764  * g_int_equal:
2765  * @v1: a pointer to a #gint key.
2766  * @v2: a pointer to a #gint key to compare with @v1.
2767  *
2768  * Compares the two #gint values being pointed to and returns 
2769  * %TRUE if they are equal.
2770  * It can be passed to g_hash_table_new() as the @key_equal_func
2771  * parameter, when using pointers to integers as keys in a #GHashTable.
2772  * 
2773  * Returns: %TRUE if the two keys match.
2774  */
2775 gboolean
2776 g_int_equal (gconstpointer v1,
2777              gconstpointer v2)
2778 {
2779   return *((const gint*) v1) == *((const gint*) v2);
2780 }
2781
2782 /**
2783  * g_int_hash:
2784  * @v: a pointer to a #gint key
2785  *
2786  * Converts a pointer to a #gint to a hash value.
2787  * It can be passed to g_hash_table_new() as the @hash_func parameter, 
2788  * when using pointers to integers values as keys in a #GHashTable.
2789  *
2790  * Returns: a hash value corresponding to the key.
2791  */
2792 guint
2793 g_int_hash (gconstpointer v)
2794 {
2795   return *(const gint*) v;
2796 }
2797
2798 /**
2799  * g_nullify_pointer:
2800  * @nullify_location: the memory address of the pointer.
2801  * 
2802  * Set the pointer at the specified location to %NULL.
2803  **/
2804 void
2805 g_nullify_pointer (gpointer *nullify_location)
2806 {
2807   g_return_if_fail (nullify_location != NULL);
2808
2809   *nullify_location = NULL;
2810 }
2811
2812 /**
2813  * g_get_codeset:
2814  * 
2815  * Get the codeset for the current locale.
2816  * 
2817  * Return value: a newly allocated string containing the name
2818  * of the codeset. This string must be freed with g_free().
2819  **/
2820 gchar *
2821 g_get_codeset (void)
2822 {
2823   const gchar *charset;
2824
2825   g_get_charset (&charset);
2826
2827   return g_strdup (charset);
2828 }
2829
2830 /* This is called from g_thread_init(). It's used to
2831  * initialize some static data in a threadsafe way.
2832  */
2833 void
2834 _g_utils_thread_init (void)
2835 {
2836   g_get_language_names ();
2837 }
2838
2839 #ifdef ENABLE_NLS
2840
2841 #include <libintl.h>
2842
2843 #ifdef G_OS_WIN32
2844
2845 /**
2846  * _glib_get_locale_dir:
2847  *
2848  * Return the path to the lib\locale subfolder of the GLib
2849  * installation folder. The path is in the system codepage. We have to
2850  * use system codepage as bindtextdomain() doesn't have a UTF-8
2851  * interface.
2852  */
2853 static const gchar *
2854 _glib_get_locale_dir (void)
2855 {
2856   gchar *dir, *cp_dir;
2857   gchar *retval = NULL;
2858
2859   dir = g_win32_get_package_installation_directory (GETTEXT_PACKAGE, dll_name);
2860   cp_dir = g_win32_locale_filename_from_utf8 (dir);
2861   g_free (dir);
2862
2863   if (cp_dir)
2864     {
2865       /* Don't use g_build_filename() on pathnames in the system
2866        * codepage. In CJK locales cp_dir might end with a double-byte
2867        * character whose trailing byte is a backslash.
2868        */
2869       retval = g_strconcat (cp_dir, "\\lib\\locale", NULL);
2870       g_free (cp_dir);
2871     }
2872
2873   if (retval)
2874     return retval;
2875   else
2876     return g_strdup ("");
2877 }
2878
2879 #undef GLIB_LOCALE_DIR
2880 #define GLIB_LOCALE_DIR _glib_get_locale_dir ()
2881
2882 #endif /* G_OS_WIN32 */
2883
2884 G_CONST_RETURN gchar *
2885 _glib_gettext (const gchar *str)
2886 {
2887   static gboolean _glib_gettext_initialized = FALSE;
2888
2889   if (!_glib_gettext_initialized)
2890     {
2891       bindtextdomain(GETTEXT_PACKAGE, GLIB_LOCALE_DIR);
2892 #    ifdef HAVE_BIND_TEXTDOMAIN_CODESET
2893       bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
2894 #    endif
2895       _glib_gettext_initialized = TRUE;
2896     }
2897   
2898   return dgettext (GETTEXT_PACKAGE, str);
2899 }
2900
2901 #endif /* ENABLE_NLS */
2902
2903 #ifdef G_OS_WIN32
2904
2905 /* Binary compatibility versions. Not for newly compiled code. */
2906
2907 #undef g_find_program_in_path
2908
2909 gchar*
2910 g_find_program_in_path (const gchar *program)
2911 {
2912   gchar *utf8_program = g_locale_to_utf8 (program, -1, NULL, NULL, NULL);
2913   gchar *utf8_retval = g_find_program_in_path_utf8 (utf8_program);
2914   gchar *retval;
2915
2916   g_free (utf8_program);
2917   if (utf8_retval == NULL)
2918     return NULL;
2919   retval = g_locale_from_utf8 (utf8_retval, -1, NULL, NULL, NULL);
2920   g_free (utf8_retval);
2921
2922   return retval;
2923 }
2924
2925 #undef g_get_current_dir
2926
2927 gchar*
2928 g_get_current_dir (void)
2929 {
2930   gchar *utf8_dir = g_get_current_dir_utf8 ();
2931   gchar *dir = g_locale_from_utf8 (utf8_dir, -1, NULL, NULL, NULL);
2932   g_free (utf8_dir);
2933   return dir;
2934 }
2935
2936 #undef g_getenv
2937
2938 G_CONST_RETURN gchar*
2939 g_getenv (const gchar *variable)
2940 {
2941   gchar *utf8_variable = g_locale_to_utf8 (variable, -1, NULL, NULL, NULL);
2942   const gchar *utf8_value = g_getenv_utf8 (utf8_variable);
2943   gchar *value;
2944   GQuark quark;
2945
2946   g_free (utf8_variable);
2947   if (!utf8_value)
2948     return NULL;
2949   value = g_locale_from_utf8 (utf8_value, -1, NULL, NULL, NULL);
2950   quark = g_quark_from_string (value);
2951   g_free (value);
2952
2953   return g_quark_to_string (quark);
2954 }
2955
2956 #undef g_setenv
2957
2958 gboolean
2959 g_setenv (const gchar *variable, 
2960           const gchar *value, 
2961           gboolean     overwrite)
2962 {
2963   gchar *utf8_variable = g_locale_to_utf8 (variable, -1, NULL, NULL, NULL);
2964   gchar *utf8_value = g_locale_to_utf8 (value, -1, NULL, NULL, NULL);
2965   gboolean retval = g_setenv_utf8 (utf8_variable, utf8_value, overwrite);
2966
2967   g_free (utf8_variable);
2968   g_free (utf8_value);
2969
2970   return retval;
2971 }
2972
2973 #undef g_unsetenv
2974
2975 void
2976 g_unsetenv (const gchar *variable)
2977 {
2978   gchar *utf8_variable = g_locale_to_utf8 (variable, -1, NULL, NULL, NULL);
2979
2980   g_unsetenv_utf8 (utf8_variable);
2981
2982   g_free (utf8_variable);
2983 }
2984
2985 #undef g_get_user_name
2986
2987 G_CONST_RETURN gchar*
2988 g_get_user_name (void)
2989 {
2990   G_LOCK (g_utils_global);
2991   if (!g_tmp_dir)
2992     g_get_any_init ();
2993   G_UNLOCK (g_utils_global);
2994   
2995   return g_user_name_cp;
2996 }
2997
2998 #undef g_get_real_name
2999
3000 G_CONST_RETURN gchar*
3001 g_get_real_name (void)
3002 {
3003   G_LOCK (g_utils_global);
3004   if (!g_tmp_dir)
3005     g_get_any_init ();
3006   G_UNLOCK (g_utils_global);
3007  
3008   return g_real_name_cp;
3009 }
3010
3011 #undef g_get_home_dir
3012
3013 G_CONST_RETURN gchar*
3014 g_get_home_dir (void)
3015 {
3016   G_LOCK (g_utils_global);
3017   if (!g_tmp_dir)
3018     g_get_any_init ();
3019   G_UNLOCK (g_utils_global);
3020
3021   return g_home_dir_cp;
3022 }
3023
3024 #undef g_get_tmp_dir
3025
3026 G_CONST_RETURN gchar*
3027 g_get_tmp_dir (void)
3028 {
3029   G_LOCK (g_utils_global);
3030   if (!g_tmp_dir)
3031     g_get_any_init ();
3032   G_UNLOCK (g_utils_global);
3033
3034   return g_tmp_dir_cp;
3035 }
3036
3037 #endif
3038
3039 #define __G_UTILS_C__
3040 #include "galiasdef.c"