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