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