home *** CD-ROM | disk | FTP | other *** search
- /* GLIB - Library of useful routines for C programming
- * Copyright (C) 1995-1998 Peter Mattis, Spencer Kimball and Josh MacDonald
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
- /*
- * MT safe for the unix part, FIXME: make the win32 part MT safe as well.
- */
-
- #ifdef HAVE_CONFIG_H
- #include <config.h>
- #endif
-
- #include "glibconfig.h"
-
- #ifdef HAVE_UNISTD_H
- #include <unistd.h>
- #endif
- #include <stdarg.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <errno.h>
- #ifdef HAVE_PWD_H
- #include <pwd.h>
- #endif
- #include <sys/types.h>
- #ifdef HAVE_SYS_PARAM_H
- #include <sys/param.h>
- #endif
-
- #ifdef NATIVE_WIN32
- # define STRICT /* Strict typing, please */
- # include <windows.h>
- # include <direct.h>
- # include <errno.h>
- # include <ctype.h>
- # ifdef _MSC_VER
- # include <io.h>
- # endif /* _MSC_VER */
- #endif /* NATIVE_WIN32 */
-
- /* implement Glib's inline functions
- */
- #define G_INLINE_FUNC extern
- #define G_CAN_INLINE 1
- #include "glib.h"
-
- #ifdef MAXPATHLEN
- #define G_PATH_LENGTH (MAXPATHLEN + 1)
- #elif defined (PATH_MAX)
- #define G_PATH_LENGTH (PATH_MAX + 1)
- #else /* !MAXPATHLEN */
- #define G_PATH_LENGTH (2048 + 1)
- #endif /* !MAXPATHLEN && !PATH_MAX */
-
- const guint glib_major_version = GLIB_MAJOR_VERSION;
- const guint glib_minor_version = GLIB_MINOR_VERSION;
- const guint glib_micro_version = GLIB_MICRO_VERSION;
- const guint glib_interface_age = GLIB_INTERFACE_AGE;
- const guint glib_binary_age = GLIB_BINARY_AGE;
-
- #if defined (NATIVE_WIN32) && defined (__LCC__)
- int __stdcall
- LibMain (void *hinstDll,
- unsigned long dwReason,
- void *reserved)
- {
- return 1;
- }
- #endif /* NATIVE_WIN32 && __LCC__ */
-
- void
- g_atexit (GVoidFunc func)
- {
- gint result;
- gchar *error = NULL;
-
- /* keep this in sync with glib.h */
-
- #ifdef G_NATIVE_ATEXIT
- result = ATEXIT (func);
- if (result)
- error = g_strerror (errno);
- #elif defined (HAVE_ATEXIT)
- # ifdef NeXT /* @#%@! NeXTStep */
- result = !atexit ((void (*)(void)) func);
- if (result)
- error = g_strerror (errno);
- # else
- result = atexit ((void (*)(void)) func);
- if (result)
- error = g_strerror (errno);
- # endif /* NeXT */
- #elif defined (HAVE_ON_EXIT)
- result = on_exit ((void (*)(int, void *)) func, NULL);
- if (result)
- error = g_strerror (errno);
- #else
- result = 0;
- error = "no implementation";
- #endif /* G_NATIVE_ATEXIT */
-
- if (error)
- g_error ("Could not register atexit() function: %s", error);
- }
-
- gint
- g_snprintf (gchar *str,
- gulong n,
- gchar const *fmt,
- ...)
- {
- #ifdef HAVE_VSNPRINTF
- va_list args;
- gint retval;
-
- va_start (args, fmt);
- retval = vsnprintf (str, n, fmt, args);
- va_end (args);
-
- return retval;
- #else /* !HAVE_VSNPRINTF */
- gchar *printed;
- va_list args;
-
- va_start (args, fmt);
- printed = g_strdup_vprintf (fmt, args);
- va_end (args);
-
- strncpy (str, printed, n);
- str[n-1] = '\0';
-
- g_free (printed);
-
- return strlen (str);
- #endif /* !HAVE_VSNPRINTF */
- }
-
- gint
- g_vsnprintf (gchar *str,
- gulong n,
- gchar const *fmt,
- va_list args)
- {
- #ifdef HAVE_VSNPRINTF
- gint retval;
-
- retval = vsnprintf (str, n, fmt, args);
-
- return retval;
- #else /* !HAVE_VSNPRINTF */
- gchar *printed;
-
- printed = g_strdup_vprintf (fmt, args);
- strncpy (str, printed, n);
- str[n-1] = '\0';
-
- g_free (printed);
-
- return strlen (str);
- #endif /* !HAVE_VSNPRINTF */
- }
-
- guint
- g_parse_debug_string (const gchar *string,
- GDebugKey *keys,
- guint nkeys)
- {
- guint i;
- guint result = 0;
-
- g_return_val_if_fail (string != NULL, 0);
-
- if (!g_strcasecmp (string, "all"))
- {
- for (i=0; i<nkeys; i++)
- result |= keys[i].value;
- }
- else
- {
- gchar *str = g_strdup (string);
- gchar *p = str;
- gchar *q;
- gboolean done = FALSE;
-
- while (*p && !done)
- {
- q = strchr (p, ':');
- if (!q)
- {
- q = p + strlen(p);
- done = TRUE;
- }
-
- *q = 0;
-
- for (i=0; i<nkeys; i++)
- if (!g_strcasecmp(keys[i].key, p))
- result |= keys[i].value;
-
- p = q+1;
- }
-
- g_free (str);
- }
-
- return result;
- }
-
- gchar*
- g_basename (const gchar *file_name)
- {
- register gchar *base;
-
- g_return_val_if_fail (file_name != NULL, NULL);
-
- base = strrchr (file_name, G_DIR_SEPARATOR);
- if (base)
- return base + 1;
-
- #ifdef NATIVE_WIN32
- if (isalpha (file_name[0]) && file_name[1] == ':')
- return (gchar*) file_name + 2;
- #endif /* NATIVE_WIN32 */
-
- return (gchar*) file_name;
- }
-
- gboolean
- g_path_is_absolute (const gchar *file_name)
- {
- g_return_val_if_fail (file_name != NULL, FALSE);
-
- if (file_name[0] == G_DIR_SEPARATOR)
- return TRUE;
-
- #ifdef NATIVE_WIN32
- if (isalpha (file_name[0]) && file_name[1] == ':' && file_name[2] == G_DIR_SEPARATOR)
- return TRUE;
- #endif
-
- return FALSE;
- }
-
- gchar*
- g_path_skip_root (gchar *file_name)
- {
- g_return_val_if_fail (file_name != NULL, NULL);
-
- if (file_name[0] == G_DIR_SEPARATOR)
- return file_name + 1;
-
- #ifdef NATIVE_WIN32
- if (isalpha (file_name[0]) && file_name[1] == ':' && file_name[2] == G_DIR_SEPARATOR)
- return file_name + 3;
- #endif
-
- return NULL;
- }
-
- gchar*
- g_dirname (const gchar *file_name)
- {
- register gchar *base;
- register guint len;
-
- g_return_val_if_fail (file_name != NULL, NULL);
-
- base = strrchr (file_name, G_DIR_SEPARATOR);
- if (!base)
- return g_strdup (".");
- while (base > file_name && *base == G_DIR_SEPARATOR)
- base--;
- len = (guint) 1 + base - file_name;
-
- base = g_new (gchar, len + 1);
- g_memmove (base, file_name, len);
- base[len] = 0;
-
- return base;
- }
-
- gchar*
- g_get_current_dir (void)
- {
- gchar *buffer;
- gchar *dir;
-
- buffer = g_new (gchar, G_PATH_LENGTH);
- *buffer = 0;
-
- /* We don't use getcwd(3) on SUNOS, because, it does a popen("pwd")
- * and, if that wasn't bad enough, hangs in doing so.
- */
- #if defined (sun) && !defined (__SVR4)
- dir = getwd (buffer);
- #else /* !sun */
- dir = getcwd (buffer, G_PATH_LENGTH - 1);
- #endif /* !sun */
-
- if (!dir || !*buffer)
- {
- /* hm, should we g_error() out here?
- * this can happen if e.g. "./" has mode \0000
- */
- buffer[0] = G_DIR_SEPARATOR;
- buffer[1] = 0;
- }
-
- dir = g_strdup (buffer);
- g_free (buffer);
-
- return dir;
- }
-
- gchar*
- g_getenv (const gchar *variable)
- {
- #ifndef NATIVE_WIN32
- g_return_val_if_fail (variable != NULL, NULL);
-
- return getenv (variable);
- #else
- gchar *v;
- guint k;
- static gchar *p = NULL;
- static gint l;
- gchar dummy[2];
-
- g_return_val_if_fail (variable != NULL, NULL);
-
- v = getenv (variable);
- if (!v)
- return NULL;
-
- /* On Windows NT, it is relatively typical that environment variables
- * contain references to other environment variables. Handle that by
- * calling ExpandEnvironmentStrings.
- */
-
- /* First check how much space we need */
- k = ExpandEnvironmentStrings (v, dummy, 2);
- /* Then allocate that much, and actualy do the expansion */
- if (p == NULL)
- {
- p = g_malloc (k);
- l = k;
- }
- else if (k > l)
- {
- p = g_realloc (p, k);
- l = k;
- }
- ExpandEnvironmentStrings (v, p, k);
- return p;
- #endif
- }
-
- #ifndef OS2EMX
-
- G_LOCK_DECLARE_STATIC (g_utils_global);
-
- static gchar *g_tmp_dir = NULL;
- static gchar *g_user_name = NULL;
- static gchar *g_real_name = NULL;
- static gchar *g_home_dir = NULL;
-
- /* HOLDS: g_utils_global_lock */
- static void
- g_get_any_init (void)
- {
- if (!g_tmp_dir)
- {
- #ifdef HAVE_PWD_H
- struct passwd *pw;
- #endif
-
- g_tmp_dir = g_strdup (g_getenv ("TMPDIR"));
- if (!g_tmp_dir)
- g_tmp_dir = g_strdup (g_getenv ("TMP"));
- if (!g_tmp_dir)
- g_tmp_dir = g_strdup (g_getenv ("TEMP"));
-
- #ifdef P_tmpdir
- if (!g_tmp_dir)
- {
- int k;
- g_tmp_dir = g_strdup (P_tmpdir);
- k = strlen (g_tmp_dir);
- if (g_tmp_dir[k-1] == G_DIR_SEPARATOR)
- g_tmp_dir[k-1] = '\0';
- }
- #endif
- if (!g_tmp_dir)
- {
- #ifndef NATIVE_WIN32
- g_tmp_dir = g_strdup ("/tmp");
- #else /* NATIVE_WIN32 */
- g_tmp_dir = g_strdup ("C:\\");
- #endif /* NATIVE_WIN32 */
- }
-
- g_home_dir = g_strdup (g_getenv ("HOME"));
-
- #ifdef HAVE_PWD_H
- setpwent ();
- pw = getpwuid (getuid ());
- endpwent ();
-
- if (pw)
- {
- g_user_name = g_strdup (pw->pw_name);
- g_real_name = g_strdup (pw->pw_gecos);
- if (!g_home_dir)
- g_home_dir = g_strdup (pw->pw_dir);
- }
- #else /* !HAVE_PWD_H */
- # ifdef NATIVE_WIN32
- {
- guint len = 17;
-
- g_user_name = g_new (gchar, len);
-
- if (!GetUserName (g_user_name, &len))
- {
- g_free (g_user_name);
- g_user_name = g_strdup ("somebody");
- g_real_name = g_strdup ("Unknown");
- }
- else
- g_real_name = g_strdup (g_user_name);
- }
- # else /* !NATIVE_WIN32 */
- g_user_name = g_strdup ("somebody");
- g_real_name = g_strdup ("Unknown");
- g_home_dir = NULL;
- # endif /* !NATIVE_WIN32 */
- #endif /* !HAVE_PWD_H */
- }
- }
-
- gchar*
- g_get_user_name (void)
- {
- G_LOCK (g_utils_global);
- if (!g_tmp_dir)
- g_get_any_init ();
- G_UNLOCK (g_utils_global);
-
- return g_user_name;
- }
-
- gchar*
- g_get_real_name (void)
- {
- G_LOCK (g_utils_global);
- if (!g_tmp_dir)
- g_get_any_init ();
- G_UNLOCK (g_utils_global);
-
- return g_real_name;
- }
-
- /* Return the home directory of the user. If there is a HOME
- * environment variable, its value is returned, otherwise use some
- * system-dependent way of finding it out. If no home directory can be
- * deduced, return NULL.
- */
-
- gchar*
- g_get_home_dir (void)
- {
- G_LOCK (g_utils_global);
- if (!g_tmp_dir)
- g_get_any_init ();
- G_UNLOCK (g_utils_global);
-
- return g_home_dir;
- }
-
- /* Return a directory to be used to store temporary files. This is the
- * value of the TMPDIR, TMP or TEMP environment variables (they are
- * checked in that order). If none of those exist, use P_tmpdir from
- * stdio.h. If that isn't defined, return "/tmp" on POSIXly systems,
- * and C:\ on Windows.
- */
-
- gchar*
- g_get_tmp_dir (void)
- {
- G_LOCK (g_utils_global);
- if (!g_tmp_dir)
- g_get_any_init ();
- G_UNLOCK (g_utils_global);
-
- return g_tmp_dir;
- }
-
- static gchar *g_prgname = NULL;
-
- gchar*
- g_get_prgname (void)
- {
- gchar* retval;
-
- G_LOCK (g_utils_global);
- retval = g_prgname;
- G_UNLOCK (g_utils_global);
-
- return retval;
- }
-
- void
- g_set_prgname (const gchar *prgname)
- {
- gchar *c;
-
- G_LOCK (g_utils_global);
- c = g_prgname;
- g_prgname = g_strdup (prgname);
- g_free (c);
- G_UNLOCK (g_utils_global);
- }
-
- guint
- g_direct_hash (gconstpointer v)
- {
- return GPOINTER_TO_UINT (v);
- }
-
- gint
- g_direct_equal (gconstpointer v1,
- gconstpointer v2)
- {
- return GPOINTER_TO_UINT (v1) == GPOINTER_TO_UINT (v2);
- }
-
- gint
- g_int_equal (gconstpointer v1,
- gconstpointer v2)
- {
- return *((const gint*) v1) == *((const gint*) v2);
- }
-
- guint
- g_int_hash (gconstpointer v)
- {
- return *(const gint*) v;
- }
-
- #if 0 /* Old IO Channels */
-
- GIOChannel*
- g_iochannel_new (gint fd)
- {
- GIOChannel *channel = g_new (GIOChannel, 1);
-
- channel->fd = fd;
-
- #ifdef NATIVE_WIN32
- channel->peer = 0;
- channel->peer_fd = 0;
- channel->offset = 0;
- channel->need_wakeups = 0;
- #endif /* NATIVE_WIN32 */
-
- return channel;
- }
-
- void
- g_iochannel_free (GIOChannel *channel)
- {
- g_return_if_fail (channel != NULL);
-
- g_free (channel);
- }
-
- void
- g_iochannel_close_and_free (GIOChannel *channel)
- {
- g_return_if_fail (channel != NULL);
-
- close (channel->fd);
-
- g_iochannel_free (channel);
- }
-
- #undef g_iochannel_wakeup_peer
-
- void
- g_iochannel_wakeup_peer (GIOChannel *channel)
- {
- #ifdef NATIVE_WIN32
- static guint message = 0;
- #endif
-
- g_return_if_fail (channel != NULL);
-
- #ifdef NATIVE_WIN32
- if (message == 0)
- message = RegisterWindowMessage ("gdk-pipe-readable");
-
- # if 0
- g_print ("g_iochannel_wakeup_peer: calling PostThreadMessage (%#x, %d, %d, %d)\n",
- channel->peer, message, channel->peer_fd, channel->offset);
- # endif
- PostThreadMessage (channel->peer, message,
- channel->peer_fd, channel->offset);
- #endif /* NATIVE_WIN32 */
- }
-
- #endif /* Old IO Channels */
-
- #ifdef NATIVE_WIN32
- #ifdef _MSC_VER
-
- int
- gwin_ftruncate (gint fd,
- guint size)
- {
- HANDLE hfile;
- guint curpos;
-
- g_return_val_if_fail (fd >= 0, -1);
-
- hfile = (HANDLE) _get_osfhandle (fd);
- curpos = SetFilePointer (hfile, 0, NULL, FILE_CURRENT);
- if (curpos == 0xFFFFFFFF
- || SetFilePointer (hfile, size, NULL, FILE_BEGIN) == 0xFFFFFFFF
- || !SetEndOfFile (hfile))
- {
- gint error = GetLastError ();
-
- switch (error)
- {
- case ERROR_INVALID_HANDLE:
- errno = EBADF;
- break;
- default:
- errno = EIO;
- break;
- }
-
- return -1;
- }
-
- return 0;
- }
-
- DIR*
- gwin_opendir (const char *dirname)
- {
- DIR *result;
- gchar *mask;
- guint k;
-
- g_return_val_if_fail (dirname != NULL, NULL);
-
- result = g_new0 (DIR, 1);
- result->find_file_data = g_new0 (WIN32_FIND_DATA, 1);
- result->dir_name = g_strdup (dirname);
-
- k = strlen (result->dir_name);
- if (k && result->dir_name[k - 1] == '\\')
- {
- result->dir_name[k - 1] = '\0';
- k--;
- }
- mask = g_strdup_printf ("%s\\*", result->dir_name);
-
- result->find_file_handle = (guint) FindFirstFile (mask,
- (LPWIN32_FIND_DATA) result->find_file_data);
- g_free (mask);
-
- if (result->find_file_handle == (guint) INVALID_HANDLE_VALUE)
- {
- int error = GetLastError ();
-
- g_free (result->dir_name);
- g_free (result->find_file_data);
- g_free (result);
- switch (error)
- {
- default:
- errno = EIO;
- return NULL;
- }
- }
- result->just_opened = TRUE;
-
- return result;
- }
-
- struct dirent*
- gwin_readdir (DIR *dir)
- {
- static struct dirent result;
-
- g_return_val_if_fail (dir != NULL, NULL);
-
- if (dir->just_opened)
- dir->just_opened = FALSE;
- else
- {
- if (!FindNextFile ((HANDLE) dir->find_file_handle,
- (LPWIN32_FIND_DATA) dir->find_file_data))
- {
- int error = GetLastError ();
-
- switch (error)
- {
- case ERROR_NO_MORE_FILES:
- return NULL;
- default:
- errno = EIO;
- return NULL;
- }
- }
- }
- strcpy (result.d_name, g_basename (((LPWIN32_FIND_DATA) dir->find_file_data)->cFileName));
-
- return &result;
- }
-
- void
- gwin_rewinddir (DIR *dir)
- {
- gchar *mask;
-
- g_return_if_fail (dir != NULL);
-
- if (!FindClose ((HANDLE) dir->find_file_handle))
- g_warning ("gwin_rewinddir(): FindClose() failed\n");
-
- mask = g_strdup_printf ("%s\\*", dir->dir_name);
- dir->find_file_handle = (guint) FindFirstFile (mask,
- (LPWIN32_FIND_DATA) dir->find_file_data);
- g_free (mask);
-
- if (dir->find_file_handle == (guint) INVALID_HANDLE_VALUE)
- {
- int error = GetLastError ();
-
- switch (error)
- {
- default:
- errno = EIO;
- return;
- }
- }
- dir->just_opened = TRUE;
- }
-
- gint
- gwin_closedir (DIR *dir)
- {
- g_return_val_if_fail (dir != NULL, -1);
-
- if (!FindClose ((HANDLE) dir->find_file_handle))
- {
- int error = GetLastError ();
-
- switch (error)
- {
- default:
- errno = EIO; return -1;
- }
- }
-
- g_free (dir->dir_name);
- g_free (dir->find_file_data);
- g_free (dir);
-
- return 0;
- }
-
- #endif /* _MSC_VER */
-
- #endif /* NATIVE_WIN32 */
-
- #endif /* OS2EMX */