#include <errno.h>
[platform/upstream/glib.git] / gutils.c
1 /* GLIB - Library of useful routines for C programming
2  * Copyright (C) 1995-1998  Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19 #include <unistd.h>
20 #include <stdarg.h>
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <errno.h>
25 #include <pwd.h>
26 #include <sys/types.h>
27 #include <sys/param.h>
28
29 /* implement Glib's inline functions
30  */
31 #define G_INLINE_FUNC extern
32 #define G_CAN_INLINE 1
33 #include "glib.h"
34
35 const guint glib_major_version = GLIB_MAJOR_VERSION;
36 const guint glib_minor_version = GLIB_MINOR_VERSION;
37 const guint glib_micro_version = GLIB_MICRO_VERSION;
38 const guint glib_interface_age = GLIB_INTERFACE_AGE;
39 const guint glib_binary_age = GLIB_BINARY_AGE;
40
41
42 void
43 g_atexit (GVoidFunc func)
44 {
45   gint result;
46   gchar *error = NULL;
47
48   /* keep this in sync with glib.h */
49
50 #ifdef  G_NATIVE_ATEXIT
51   result = ATEXIT (func);
52   if (result)
53     error = g_strerror (errno);
54 #elif defined (HAVE_ATEXIT)
55 #  ifdef NeXT /* @#%@! NeXTStep */
56   result = !atexit ((void (*)(void)) func);
57   if (result)
58     error = g_strerror (errno);
59 #  else
60   result = atexit ((void (*)(void)) func);
61   if (result)
62     error = g_strerror (errno);
63 #  endif /* NeXT */
64 #elif defined (HAVE_ON_EXIT)
65   result = on_exit ((void (*)(int, void *)) func, NULL);
66   if (result)
67     error = g_strerror (errno);
68 #else
69   result = 0;
70   error = "no implementation";
71 #endif /* G_NATIVE_ATEXIT */
72
73   if (error)
74     g_error ("Could not register atexit() function: %s", error);
75 }
76
77 gint
78 g_snprintf (gchar       *str,
79             gulong       n,
80             gchar const *fmt,
81             ...)
82 {
83 #ifdef  HAVE_VSNPRINTF
84   va_list args;
85   gint retval;
86   
87   va_start (args, fmt);
88   retval = vsnprintf (str, n, fmt, args);
89   va_end (args);
90   
91   return retval;
92 #else   /* !HAVE_VSNPRINTF */
93   gchar *printed;
94   va_list args;
95   
96   va_start (args, fmt);
97   printed = g_strdup_vprintf (fmt, args);
98   va_end (args);
99   
100   strncpy (str, printed, n);
101   str[n-1] = '\0';
102
103   g_free (printed);
104   
105   return strlen (str);
106 #endif  /* !HAVE_VSNPRINTF */
107 }
108
109 gint
110 g_vsnprintf (gchar       *str,
111              gulong       n,
112              gchar const *fmt,
113              va_list      args)
114 {
115 #ifdef  HAVE_VSNPRINTF
116   gint retval;
117   
118   retval = vsnprintf (str, n, fmt, args);
119   
120   return retval;
121 #else   /* !HAVE_VSNPRINTF */
122   gchar *printed;
123   
124   printed = g_strdup_vprintf (fmt, args);
125   strncpy (str, printed, n);
126   str[n-1] = '\0';
127
128   g_free (printed);
129   
130   return strlen (str);
131 #endif /* !HAVE_VSNPRINTF */
132 }
133
134 guint        
135 g_parse_debug_string  (const gchar *string, 
136                        GDebugKey   *keys, 
137                        guint        nkeys)
138 {
139   guint i;
140   guint result = 0;
141   
142   g_return_val_if_fail (string != NULL, 0);
143   
144   if (!g_strcasecmp (string, "all"))
145     {
146       for (i=0; i<nkeys; i++)
147         result |= keys[i].value;
148     }
149   else
150     {
151       gchar *str = g_strdup (string);
152       gchar *p = str;
153       gchar *q;
154       gboolean done = FALSE;
155       
156       while (*p && !done)
157         {
158           q = strchr (p, ':');
159           if (!q)
160             {
161               q = p + strlen(p);
162               done = TRUE;
163             }
164           
165           *q = 0;
166           
167           for (i=0; i<nkeys; i++)
168             if (!g_strcasecmp(keys[i].key, p))
169               result |= keys[i].value;
170           
171           p = q+1;
172         }
173       
174       g_free (str);
175     }
176   
177   return result;
178 }
179
180 gchar*
181 g_basename (const gchar    *file_name)
182 {
183   register gchar *base;
184   
185   g_return_val_if_fail (file_name != NULL, NULL);
186   
187   base = strrchr (file_name, '/');
188   if (base)
189     return base + 1;
190   
191   return (gchar*) file_name;
192 }
193
194 gchar*
195 g_dirname (const gchar     *file_name)
196 {
197   register gchar *base;
198   register guint len;
199   
200   g_return_val_if_fail (file_name != NULL, NULL);
201   
202   base = strrchr (file_name, '/');
203   if (!base)
204     return g_strdup (".");
205   while (base > file_name && *base == '/')
206     base--;
207   len = (guint) 1 + base - file_name;
208   
209   base = g_new (gchar, len + 1);
210   g_memmove (base, file_name, len);
211   base[len] = 0;
212   
213   return base;
214 }
215
216 #ifdef  MAXPATHLEN
217 #define G_PATH_LENGTH   (MAXPATHLEN + 1)
218 #elif   defined (PATH_MAX)
219 #define G_PATH_LENGTH   (PATH_MAX + 1)
220 #else   /* !MAXPATHLEN */
221 #define G_PATH_LENGTH   (2048 + 1)
222 #endif  /* !MAXPATHLEN && !PATH_MAX */
223
224 gchar*
225 g_get_current_dir (void)
226 {
227   gchar *buffer;
228   gchar *dir;
229
230   buffer = g_new (gchar, G_PATH_LENGTH);
231   *buffer = 0;
232   
233   /* We don't use getcwd(3) on SUNOS, because, it does a popen("pwd")
234    * and, if that wasn't bad enough, hangs in doing so.
235    */
236 #if     defined (sun) && !defined (__SVR4)
237   dir = getwd (buffer);
238 #else   /* !sun */
239   dir = getcwd (buffer, G_PATH_LENGTH - 1);
240 #endif  /* !sun */
241   
242   if (!dir || !*buffer)
243     {
244       /* hm, should we g_error() out here?
245        * this can happen if e.g. "./" has mode \0000
246        */
247       buffer[0] = '/';
248       buffer[1] = 0;
249     }
250
251   dir = g_strdup (buffer);
252   g_free (buffer);
253   
254   return dir;
255 }
256
257 static  gchar   *g_tmp_dir = NULL;
258 static  gchar   *g_user_name = NULL;
259 static  gchar   *g_real_name = NULL;
260 static  gchar   *g_home_dir = NULL;
261
262 static void
263 g_get_any_init (void)
264 {
265   if (!g_tmp_dir)
266     {
267       struct passwd *pw;
268       
269       g_tmp_dir = g_strdup (getenv ("TMPDIR"));
270       if (!g_tmp_dir)
271         g_tmp_dir = g_strdup (getenv ("TMP"));
272       if (!g_tmp_dir)
273         g_tmp_dir = g_strdup (getenv ("TEMP"));
274       if (!g_tmp_dir)
275         g_tmp_dir = g_strdup ("/tmp");
276       
277       g_home_dir = g_strdup (getenv ("HOME"));
278       
279       setpwent ();
280       pw = getpwuid (getuid ());
281       endpwent ();
282       
283       if (pw)
284         {
285           g_user_name = g_strdup (pw->pw_name);
286           g_real_name = g_strdup (pw->pw_gecos);
287           if (!g_home_dir)
288             g_home_dir = g_strdup (pw->pw_dir);
289         }
290     }
291 }
292
293 gchar*
294 g_get_user_name (void)
295 {
296   if (!g_tmp_dir)
297     g_get_any_init ();
298   
299   return g_user_name;
300 }
301
302 gchar*
303 g_get_real_name (void)
304 {
305   if (!g_tmp_dir)
306     g_get_any_init ();
307   
308   return g_real_name;
309 }
310
311 gchar*
312 g_get_home_dir (void)
313 {
314   if (!g_tmp_dir)
315     g_get_any_init ();
316   
317   return g_home_dir;
318 }
319
320 gchar*
321 g_get_tmp_dir (void)
322 {
323   if (!g_tmp_dir)
324     g_get_any_init ();
325   
326   return g_tmp_dir;
327 }
328
329 static gchar *g_prgname = NULL;
330
331 gchar*
332 g_get_prgname (void)
333 {
334   return g_prgname;
335 }
336
337 void
338 g_set_prgname (const gchar *prgname)
339 {
340   gchar *c = g_prgname;
341   
342   g_prgname = g_strdup (prgname);
343   g_free (c);
344 }
345
346 guint
347 g_direct_hash(gconstpointer v)
348 {
349   return GPOINTER_TO_UINT (v);
350 }
351
352 gint
353 g_direct_equal(gconstpointer v, gconstpointer v2)
354 {
355   return GPOINTER_TO_UINT (v) == GPOINTER_TO_UINT (v2);
356 }
357
358 gint
359 g_int_equal (gconstpointer v, gconstpointer v2)
360 {
361   return *((const gint*) v) == *((const gint*) v2);
362 }
363
364 guint
365 g_int_hash (gconstpointer v)
366 {
367   return *(const gint*) v;
368 }