mirror of
				https://gitlab.gnome.org/GNOME/glib.git
				synced 2025-11-04 01:58:54 +01:00 
			
		
		
		
	W32: swap special g_get_prgname() for platform_get_argv0()
Commit398008daadded a W32-only code (from commit7e0e251a) to g_get_prgname() that makes this function never return NULL. This is inconsistent with the other platforms. Revert the change, and add an implementation for platform_get_argv0(), which is used by GOption when g_get_prgname() == NULL. The W32 platform_get_argv0() code is different from the one that was in g_get_prgname(), because it should be getting argv0, not the name of the executable that is being run (although most of the time they are one and the same). Adjust thest option-argv0 test to expect it to pass on W32.
This commit is contained in:
		@@ -194,6 +194,10 @@
 | 
			
		||||
#include "gprintf.h"
 | 
			
		||||
#include "glibintl.h"
 | 
			
		||||
 | 
			
		||||
#if defined G_OS_WIN32
 | 
			
		||||
#include <windows.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define TRANSLATE(group, str) (((group)->translate_func ? (* (group)->translate_func) ((str), (group)->translate_data) : (str)))
 | 
			
		||||
 | 
			
		||||
#define NO_ARG(entry) ((entry)->arg == G_OPTION_ARG_NONE ||       \
 | 
			
		||||
@@ -1860,6 +1864,51 @@ platform_get_argv0 (void)
 | 
			
		||||
  base_arg0 = g_path_get_basename (*cmdline);
 | 
			
		||||
  g_free (cmdline);
 | 
			
		||||
  return base_arg0;
 | 
			
		||||
#elif defined G_OS_WIN32
 | 
			
		||||
  const wchar_t *cmdline;
 | 
			
		||||
  wchar_t **wargv;
 | 
			
		||||
  int wargc;
 | 
			
		||||
  gchar *utf8_buf = NULL;
 | 
			
		||||
  char *base_arg0 = NULL;
 | 
			
		||||
 | 
			
		||||
  /* Pretend it's const, since we're not allowed to free it */
 | 
			
		||||
  cmdline = (const wchar_t *) GetCommandLineW ();
 | 
			
		||||
  if (G_UNLIKELY (cmdline == NULL))
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  /* Skip leading whitespace. CommandLineToArgvW() is documented
 | 
			
		||||
   * to behave weirdly with that. The character codes below
 | 
			
		||||
   * correspond to the *only* unicode characters that are
 | 
			
		||||
   * considered to be spaces by CommandLineToArgvW(). The rest
 | 
			
		||||
   * (such as 0xa0 - NO-BREAK SPACE) are treated as
 | 
			
		||||
   * normal characters.
 | 
			
		||||
   */
 | 
			
		||||
  while (cmdline[0] == 0x09 ||
 | 
			
		||||
         cmdline[0] == 0x0a ||
 | 
			
		||||
         cmdline[0] == 0x0c ||
 | 
			
		||||
         cmdline[0] == 0x0d ||
 | 
			
		||||
         cmdline[0] == 0x20)
 | 
			
		||||
    cmdline++;
 | 
			
		||||
 | 
			
		||||
  wargv = CommandLineToArgvW (cmdline, &wargc);
 | 
			
		||||
  if (G_UNLIKELY (wargv == NULL))
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  if (wargc > 0)
 | 
			
		||||
    utf8_buf = g_utf16_to_utf8 (wargv[0], -1, NULL, NULL, NULL);
 | 
			
		||||
 | 
			
		||||
  LocalFree (wargv);
 | 
			
		||||
 | 
			
		||||
  if (G_UNLIKELY (utf8_buf == NULL))
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  /* We could just return cmdline, but I think it's better
 | 
			
		||||
   * to hold on to a smaller malloc block; the arguments
 | 
			
		||||
   * could be large.
 | 
			
		||||
   */
 | 
			
		||||
  base_arg0 = g_path_get_basename (utf8_buf);
 | 
			
		||||
  g_free (utf8_buf);
 | 
			
		||||
  return base_arg0;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  return NULL;
 | 
			
		||||
 
 | 
			
		||||
@@ -1047,29 +1047,6 @@ g_get_prgname (void)
 | 
			
		||||
  gchar* retval;
 | 
			
		||||
 | 
			
		||||
  G_LOCK (g_prgname);
 | 
			
		||||
#ifdef G_OS_WIN32
 | 
			
		||||
  if (g_prgname == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      static gboolean beenhere = FALSE;
 | 
			
		||||
 | 
			
		||||
      if (!beenhere)
 | 
			
		||||
	{
 | 
			
		||||
	  gchar *utf8_buf = NULL;
 | 
			
		||||
	  wchar_t buf[MAX_PATH+1];
 | 
			
		||||
 | 
			
		||||
	  beenhere = TRUE;
 | 
			
		||||
	  if (GetModuleFileNameW (GetModuleHandle (NULL),
 | 
			
		||||
				  buf, G_N_ELEMENTS (buf)) > 0)
 | 
			
		||||
	    utf8_buf = g_utf16_to_utf8 (buf, -1, NULL, NULL, NULL);
 | 
			
		||||
 | 
			
		||||
	  if (utf8_buf)
 | 
			
		||||
	    {
 | 
			
		||||
	      g_prgname = g_path_get_basename (utf8_buf);
 | 
			
		||||
	      g_free (utf8_buf);
 | 
			
		||||
	    }
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
  retval = g_prgname;
 | 
			
		||||
  G_UNLOCK (g_prgname);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -51,7 +51,8 @@ test_platform_argv0 (void)
 | 
			
		||||
  /* This test must pass on platforms where platform_get_argv0()
 | 
			
		||||
   * is implemented. At the moment that means Linux/Cygwin,
 | 
			
		||||
   * (which uses /proc/self/cmdline) or OpenBSD (which uses
 | 
			
		||||
   * sysctl and KERN_PROC_ARGS). On other platforms the test
 | 
			
		||||
   * sysctl and KERN_PROC_ARGS) or Windows (which uses
 | 
			
		||||
   * GetCommandlineW ()). On other platforms the test
 | 
			
		||||
   * is not expected to pass, but we'd still want to know
 | 
			
		||||
   * how it does (the test code itself doesn't use any platform-specific
 | 
			
		||||
   * functionality, the difference is internal to glib, so it's quite
 | 
			
		||||
@@ -60,7 +61,10 @@ test_platform_argv0 (void)
 | 
			
		||||
   * to prevent them from crashing hard on failed assertions,
 | 
			
		||||
   * and make them call g_test_skip() instead.
 | 
			
		||||
   */
 | 
			
		||||
#if !defined HAVE_PROC_SELF_CMDLINE && !defined __OpenBSD__ && !defined __linux
 | 
			
		||||
#if !defined HAVE_PROC_SELF_CMDLINE && \
 | 
			
		||||
    !defined __OpenBSD__ && \
 | 
			
		||||
    !defined __linux && \
 | 
			
		||||
    !defined G_OS_WIN32
 | 
			
		||||
  fatal_errors = FALSE;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user