# include <windows.h>
# include <ctype.h>
# include <direct.h>
-# include <io.h>
#endif /* G_OS_WIN32 */
#ifdef HAVE_CODESET
g_error ("Could not register atexit() function: %s", error);
}
+/* Based on execvp() from GNU Libc.
+ * Some of this code is cut-and-pasted into gspawn.c
+ */
+
+static gchar*
+my_strchrnul (const gchar *str, gchar c)
+{
+ gchar *p = (gchar*)str;
+ while (*p && (*p != c))
+ ++p;
+
+ return p;
+}
+
+/**
+ * g_find_program_in_path:
+ * @program: a program name
+ *
+ * Locates the first executable named @program in the user's path, in the
+ * same way that execvp() would locate it. Returns an allocated string
+ * with the absolute path name, or NULL if the program is not found in
+ * the path. If @program is already an absolute path, returns a copy of
+ * @program if @program exists and is executable, and NULL otherwise.
+ *
+ * Return value: absolute path, or NULL
+ **/
+gchar*
+g_find_program_in_path (const gchar *program)
+{
+ gchar *path, *p, *name, *freeme;
+ size_t len;
+ size_t pathlen;
+
+ g_return_val_if_fail (program != NULL, NULL);
+
+ if (*program == '/')
+ {
+ if (g_file_test (program, G_FILE_TEST_IS_EXECUTABLE))
+ return g_strdup (program);
+ else
+ return NULL;
+ }
+
+ path = g_getenv ("PATH");
+ if (path == NULL)
+ {
+ /* There is no `PATH' in the environment. The default
+ * search path in GNU libc is the current directory followed by
+ * the path `confstr' returns for `_CS_PATH'.
+ */
+
+ /* In GLib we put . last, for security, and don't use the
+ * unportable confstr(); UNIX98 does not actually specify
+ * what to search if PATH is unset. POSIX may, dunno.
+ */
+
+ path = "/bin:/usr/bin:.";
+ }
+
+ len = strlen (program) + 1;
+ pathlen = strlen (path);
+ freeme = name = g_malloc (pathlen + len + 1);
+
+ /* Copy the file name at the top, including '\0' */
+ memcpy (name + pathlen + 1, program, len);
+ name = name + pathlen;
+ /* And add the slash before the filename */
+ *name = '/';
+
+ p = path;
+ do
+ {
+ char *startp;
+
+ path = p;
+ p = my_strchrnul (path, ':');
+
+ if (p == path)
+ /* Two adjacent colons, or a colon at the beginning or the end
+ * of `PATH' means to search the current directory.
+ */
+ startp = name + 1;
+ else
+ startp = memcpy (name - (p - path), path, p - path);
+
+ if (g_file_test (startp, G_FILE_TEST_IS_EXECUTABLE))
+ {
+ gchar *ret;
+ ret = g_strdup (startp);
+ g_free (freeme);
+ return ret;
+ }
+ }
+ while (*p++ != '\0');
+
+ g_free (freeme);
+
+ return NULL;
+}
+
gint
g_snprintf (gchar *str,
gulong n,
g_basename (const gchar *file_name)
{
register gchar *base;
-#ifdef G_ENABLE_DEBUG
+#if defined(G_ENABLE_DEBUG) && !defined(G_OS_WIN32)
static gboolean first_call = TRUE;
if (first_call)
{
- g_warning("g_basename is deprecated. Use g_path_get_basename instead.");
- g_warning("Watch out! You have to g_free the string returned by "
- "g_path_get_basename.");
+ g_message ("g_basename is deprecated. Use g_path_get_basename instead. "
+ "Beware that the string returned by g_path_get_basename() has "
+ " to be g_free()ed.");
first_call = FALSE;
}
#endif /* G_ENABLE_DEBUG */
{
g_return_val_if_fail (file_name != NULL, NULL);
+#ifdef G_OS_WIN32
+ /* Skip \\server\share */
+ if (file_name[0] == G_DIR_SEPARATOR &&
+ file_name[1] == G_DIR_SEPARATOR &&
+ file_name[2])
+ {
+ gchar *p, *q;
+
+ if ((p = strchr (file_name + 2, G_DIR_SEPARATOR)) > file_name + 2 &&
+ p[1])
+ {
+ file_name = p + 1;
+
+ while (file_name[0] && file_name[0] != G_DIR_SEPARATOR)
+ file_name++;
+
+ /* Possibly skip a backslash after the share name */
+ if (file_name[0] == G_DIR_SEPARATOR)
+ file_name++;
+
+ return file_name;
+ }
+ }
+#endif
+
+ /* Skip initial slashes */
if (file_name[0] == G_DIR_SEPARATOR)
- return file_name + 1;
+ {
+ while (file_name[0] == G_DIR_SEPARATOR)
+ file_name++;
+ return file_name;
+ }
#ifdef G_OS_WIN32
+ /* Skip X:\ */
if (isalpha (file_name[0]) && file_name[1] == ':' && file_name[2] == G_DIR_SEPARATOR)
return file_name + 3;
#endif
gchar*
g_dirname (const gchar *file_name)
{
-#ifdef G_ENABLE_DEBUG
+#if defined(G_ENABLE_DEBUG) && !defined(G_OS_WIN32)
static gboolean first_call = TRUE;
if (first_call)
{
- g_warning("g_dirname is deprecated. Use g_path_get_dirname instead.");
+ g_message ("g_dirname() is deprecated. Use g_path_get_dirname() instead.");
first_call = FALSE;
}
#endif /* G_ENABLE_DEBUG */
{
gchar *buffer = NULL;
gchar *dir = NULL;
- static gulong max_len = (G_PATH_LENGTH == -1) ? 2048 : G_PATH_LENGTH;
+ static gulong max_len = 0;
+
+ if (max_len == 0)
+ max_len = (G_PATH_LENGTH == -1) ? 2048 : G_PATH_LENGTH;
/* 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)
+#if (defined (sun) && !defined (__SVR4)) || !defined(HAVE_GETCWD)
buffer = g_new (gchar, max_len + 1);
*buffer = 0;
dir = getwd (buffer);
-#else /* !sun */
+#else /* !sun || !HAVE_GETCWD */
while (max_len < G_MAXULONG / 2)
{
buffer = g_new (gchar, max_len + 1);
g_free (buffer);
max_len *= 2;
}
-#endif /* !sun */
+#endif /* !sun || !HAVE_GETCWD */
if (!dir || !*buffer)
{
g_home_dir = g_strdup (g_getenv ("HOME"));
#ifdef G_OS_WIN32
- if (!g_home_dir)
+ /* In case HOME is Unix-style (it happens), convert it to
+ * Windows style.
+ */
+ if (g_home_dir)
+ {
+ gchar *p;
+ while ((p = strchr (g_home_dir, '/')) != NULL)
+ *p = '\\';
+ }
+ else
{
/* The official way to specify a home directory on NT is
- * the HOMEDRIVE and HOMEPATH environment variables.
- *
- * This is inside #ifdef G_OS_WIN32 because with the cygwin dll,
- * HOME should be a POSIX style pathname.
+ * the HOMEDRIVE and HOMEPATH environment variables. At least
+ * it was at some time.
*/
-
if (getenv ("HOMEDRIVE") != NULL && getenv ("HOMEPATH") != NULL)
{
gchar *homedrive, *homepath;
struct passwd *pw = NULL;
gpointer buffer = NULL;
-# ifdef HAVE_GETPWUID_R
+# if defined (HAVE_POSIX_GETPWUID_R) || defined (HAVE_NONPOSIX_GETPWUID_R)
struct passwd pwd;
# ifdef _SC_GETPW_R_SIZE_MAX
/* This reurns the maximum length */
buffer = g_malloc (bufsize);
errno = 0;
-# ifdef HAVE_GETPWUID_R_POSIX
+# ifdef HAVE_POSIX_GETPWUID_R
error = getpwuid_r (getuid (), &pwd, buffer, bufsize, &pw);
error = error < 0 ? errno : error;
-# else /* !HAVE_GETPWUID_R_POSIX */
+# else /* HAVE_NONPOSIX_GETPWUID_R */
# ifdef _AIX
error = getpwuid_r (getuid (), &pwd, buffer, bufsize);
pw = error == 0 ? &pwd : NULL;
pw = getpwuid_r (getuid (), &pwd, buffer, bufsize);
error = pw ? 0 : errno;
# endif /* !_AIX */
-# endif /* !HAVE_GETPWUID_R_POSIX */
+# endif /* HAVE_NONPOSIX_GETPWUID_R */
if (!pw)
{
}
}
while (!pw);
-# endif /* !HAVE_GETPWUID_R */
+# endif /* HAVE_POSIX_GETPWUID_R || HAVE_NONPOSIX_GETPWUID_R */
if (!pw)
{
return GPOINTER_TO_UINT (v);
}
-gint
+gboolean
g_direct_equal (gconstpointer v1,
gconstpointer v2)
{
return v1 == v2;
}
-gint
+gboolean
g_int_equal (gconstpointer v1,
gconstpointer v2)
{
*/
return g_strdup ("ISO-8859-1");
#else
- /* On Win32 we always use UTF-8. At least in GDK. SO should we
- * therefore return that?
- */
- return g_strdup ("UTF-8");
+ return g_strdup_printf ("CP%d", GetACP ());
#endif
#endif
}
+
+#ifdef ENABLE_NLS
+
+#include <libintl.h>
+
+
+#ifdef G_OS_WIN32
+
+#define GLIB_LOCALE_DIR \
+ g_win32_get_package_installation_subdirectory \
+ (GETTEXT_PACKAGE, g_strdup_printf ("glib-%d.%d.dll", \
+ GLIB_MAJOR_VERSION, \
+ GLIB_MINOR_VERSION), \
+ "locale")
+
+#endif /* G_OS_WIN32 */
+
+gchar *
+_glib_gettext (const gchar *str)
+{
+ gboolean _glib_gettext_initialized = FALSE;
+
+ if (!_glib_gettext_initialized)
+ {
+ bindtextdomain(GETTEXT_PACKAGE, GLIB_LOCALE_DIR);
+ _glib_gettext_initialized = TRUE;
+ }
+
+ return dgettext (GETTEXT_PACKAGE, str);
+}
+
+#endif /* ENABLE_NLS */
+
+