check for all three inline keywords individually.
[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 <pwd.h>
25 #include <sys/types.h>
26 #include <sys/param.h>
27
28 /* implement Glib's inline functions
29  */
30 #define G_INLINE_FUNC extern
31 #define G_CAN_INLINE 1
32 #include "glib.h"
33
34 const guint glib_major_version = GLIB_MAJOR_VERSION;
35 const guint glib_minor_version = GLIB_MINOR_VERSION;
36 const guint glib_micro_version = GLIB_MICRO_VERSION;
37 const guint glib_interface_age = GLIB_INTERFACE_AGE;
38 const guint glib_binary_age = GLIB_BINARY_AGE;
39
40
41 gint
42 g_snprintf (gchar       *str,
43             gulong       n,
44             gchar const *fmt,
45             ...)
46 {
47 #ifdef  HAVE_VSNPRINTF
48   va_list args;
49   gint retval;
50   
51   va_start (args, fmt);
52   retval = vsnprintf (str, n, fmt, args);
53   va_end (args);
54   
55   return retval;
56 #else   /* !HAVE_VSNPRINTF */
57   gchar *printed;
58   va_list args;
59   
60   va_start (args, fmt);
61   printed = g_strdup_vprintf (fmt, args);
62   va_end (args);
63   
64   strncpy (str, printed, n);
65   str[n-1] = '\0';
66
67   g_free (printed);
68   
69   return strlen (str);
70 #endif  /* !HAVE_VSNPRINTF */
71 }
72
73 gint
74 g_vsnprintf (gchar       *str,
75              gulong       n,
76              gchar const *fmt,
77              va_list      args)
78 {
79 #ifdef  HAVE_VSNPRINTF
80   gint retval;
81   
82   retval = vsnprintf (str, n, fmt, args);
83   
84   return retval;
85 #else   /* !HAVE_VSNPRINTF */
86   gchar *printed;
87   
88   printed = g_strdup_vprintf (fmt, args);
89   strncpy (str, printed, n);
90   str[n-1] = '\0';
91
92   g_free (printed);
93   
94   return strlen (str);
95 #endif /* !HAVE_VSNPRINTF */
96 }
97
98 guint        
99 g_parse_debug_string  (const gchar *string, 
100                        GDebugKey   *keys, 
101                        guint        nkeys)
102 {
103   guint i;
104   guint result = 0;
105   
106   g_return_val_if_fail (string != NULL, 0);
107   
108   if (!g_strcasecmp (string, "all"))
109     {
110       for (i=0; i<nkeys; i++)
111         result |= keys[i].value;
112     }
113   else
114     {
115       gchar *str = g_strdup (string);
116       gchar *p = str;
117       gchar *q;
118       gboolean done = FALSE;
119       
120       while (*p && !done)
121         {
122           q = strchr (p, ':');
123           if (!q)
124             {
125               q = p + strlen(p);
126               done = TRUE;
127             }
128           
129           *q = 0;
130           
131           for (i=0; i<nkeys; i++)
132             if (!g_strcasecmp(keys[i].key, p))
133               result |= keys[i].value;
134           
135           p = q+1;
136         }
137       
138       g_free (str);
139     }
140   
141   return result;
142 }
143
144 gchar*
145 g_basename (const gchar    *file_name)
146 {
147   register gchar *base;
148   
149   g_return_val_if_fail (file_name != NULL, NULL);
150   
151   base = strrchr (file_name, '/');
152   if (base)
153     return base + 1;
154   
155   return (gchar*) file_name;
156 }
157
158 gchar*
159 g_dirname (const gchar     *file_name)
160 {
161   register gchar *base;
162   register guint len;
163   
164   g_return_val_if_fail (file_name != NULL, NULL);
165   
166   base = strrchr (file_name, '/');
167   if (!base)
168     return g_strdup (".");
169   while (base > file_name && *base == '/')
170     base--;
171   len = (guint) 1 + base - file_name;
172   
173   base = g_new (gchar, len + 1);
174   g_memmove (base, file_name, len);
175   base[len] = 0;
176   
177   return base;
178 }
179
180 #ifdef  MAXPATHLEN
181 #define G_PATH_LENGTH   (MAXPATHLEN + 1)
182 #elif   defined (PATH_MAX)
183 #define G_PATH_LENGTH   (PATH_MAX + 1)
184 #else   /* !MAXPATHLEN */
185 #define G_PATH_LENGTH   (2048 + 1)
186 #endif  /* !MAXPATHLEN && !PATH_MAX */
187
188 gchar*
189 g_get_current_dir (void)
190 {
191   gchar *buffer;
192   gchar *dir;
193
194   buffer = g_new (gchar, G_PATH_LENGTH);
195   *buffer = 0;
196   
197   /* We don't use getcwd(3) on SUNOS, because, it does a popen("pwd")
198    * and, if that wasn't bad enough, hangs in doing so.
199    */
200 #if     defined (sun) && !defined (__SVR4)
201   dir = getwd (buffer);
202 #else   /* !sun */
203   dir = getcwd (buffer, G_PATH_LENGTH - 1);
204 #endif  /* !sun */
205   
206   if (!dir || !*buffer)
207     {
208       /* hm, should we g_error() out here?
209        * this can happen if e.g. "./" has mode \0000
210        */
211       buffer[0] = '/';
212       buffer[1] = 0;
213     }
214
215   dir = g_strdup (buffer);
216   g_free (buffer);
217   
218   return dir;
219 }
220
221 static  gchar   *g_tmp_dir = NULL;
222 static  gchar   *g_user_name = NULL;
223 static  gchar   *g_real_name = NULL;
224 static  gchar   *g_home_dir = NULL;
225
226 static void
227 g_get_any_init (void)
228 {
229   if (!g_tmp_dir)
230     {
231       struct passwd *pw;
232       
233       g_tmp_dir = g_strdup (getenv ("TMPDIR"));
234       if (!g_tmp_dir)
235         g_tmp_dir = g_strdup (getenv ("TMP"));
236       if (!g_tmp_dir)
237         g_tmp_dir = g_strdup (getenv ("TEMP"));
238       if (!g_tmp_dir)
239         g_tmp_dir = g_strdup ("/tmp");
240       
241       g_home_dir = g_strdup (getenv ("HOME"));
242       
243       setpwent ();
244       pw = getpwuid (getuid ());
245       endpwent ();
246       
247       if (pw)
248         {
249           g_user_name = g_strdup (pw->pw_name);
250           g_real_name = g_strdup (pw->pw_gecos);
251           if (!g_home_dir)
252             g_home_dir = g_strdup (pw->pw_dir);
253         }
254     }
255 }
256
257 gchar*
258 g_get_user_name (void)
259 {
260   if (!g_tmp_dir)
261     g_get_any_init ();
262   
263   return g_user_name;
264 }
265
266 gchar*
267 g_get_real_name (void)
268 {
269   if (!g_tmp_dir)
270     g_get_any_init ();
271   
272   return g_real_name;
273 }
274
275 gchar*
276 g_get_home_dir (void)
277 {
278   if (!g_tmp_dir)
279     g_get_any_init ();
280   
281   return g_home_dir;
282 }
283
284 gchar*
285 g_get_tmp_dir (void)
286 {
287   if (!g_tmp_dir)
288     g_get_any_init ();
289   
290   return g_tmp_dir;
291 }
292
293 static gchar *g_prgname = NULL;
294
295 gchar*
296 g_get_prgname (void)
297 {
298   return g_prgname;
299 }
300
301 void
302 g_set_prgname (const gchar *prgname)
303 {
304   gchar *c = g_prgname;
305   
306   g_prgname = g_strdup (prgname);
307   g_free (c);
308 }
309
310 guint
311 g_direct_hash(gconstpointer v)
312 {
313   return GPOINTER_TO_UINT (v);
314 }
315
316 gint
317 g_direct_equal(gconstpointer v, gconstpointer v2)
318 {
319   return GPOINTER_TO_UINT (v) == GPOINTER_TO_UINT (v2);
320 }
321
322 gint
323 g_int_equal (gconstpointer v, gconstpointer v2)
324 {
325   return *((const gint*) v) == *((const gint*) v2);
326 }
327
328 guint
329 g_int_hash (gconstpointer v)
330 {
331   return *(const gint*) v;
332 }