From 075f8622776ff04e726e9eb5cef19eb86a92bde1 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 10 Sep 2002 08:27:38 +0000 Subject: [PATCH] * w32reg.c (read_w32_registry_string): Handle REG_EXPAND_SZ. Suggested by Ryan Malayter. * strgutil.c (ascii_strcasecmp): Replaced by code from gnulib. (ascii_strncasecmp): New. --- util/ChangeLog | 11 +++++++++ util/simple-gettext.c | 13 ++++++++-- util/strgutil.c | 55 +++++++++++++++++++++++++++++++++++++------ util/w32reg.c | 43 ++++++++++++++++++++++++++++++--- 4 files changed, 110 insertions(+), 12 deletions(-) diff --git a/util/ChangeLog b/util/ChangeLog index 4e0915ccc..add000357 100644 --- a/util/ChangeLog +++ b/util/ChangeLog @@ -1,5 +1,16 @@ +2002-09-09 Werner Koch + + * w32reg.c (read_w32_registry_string): Handle REG_EXPAND_SZ. + Suggested by Ryan Malayter. + + * strgutil.c (ascii_strcasecmp): Replaced by code from gnulib. + (ascii_strncasecmp): New. + 2002-09-02 Werner Koch + * simple-gettext.c (set_gettext_file): Make sure that we only use + backslashes. + * strgutil.c (set_native_charset): Allow NULL as argument to use nl_langinfo for selection. Mapped latin-15 to latin-1. diff --git a/util/simple-gettext.c b/util/simple-gettext.c index db229437d..d9c676f50 100644 --- a/util/simple-gettext.c +++ b/util/simple-gettext.c @@ -28,7 +28,7 @@ #include #ifdef USE_SIMPLE_GETTEXT #if !defined (__MINGW32__) && !defined (__CYGWIN32__) - #error This file can only be used with MingW32 or Cygwin32 +#error This file can only be used with MingW32 or Cygwin32 #endif #include @@ -247,12 +247,21 @@ set_gettext_file( const char *filename ) else { /* relative path - append ".mo" and get dir from the environment */ char *buf = NULL; char *dir; + char *p; dir = read_w32_registry_string( NULL, "Control Panel\\Mingw32\\NLS", "MODir" ); if( dir && (buf=malloc(strlen(dir)+strlen(filename)+1+3+1)) ) { - strcpy(stpcpy(stpcpy(stpcpy( buf, dir),"/"), filename),".mo"); + strcpy(stpcpy(stpcpy(stpcpy( buf, dir),"\\"), filename),".mo"); + /* Better make sure that we don't mix forward and + backward slashes. It seems that some Windoze + versions don't accept this. */ + for (p=buf; *p; p++) + { + if (*p == '/') + *p = '\\'; + } domain = load_domain( buf ); free(buf); } diff --git a/util/strgutil.c b/util/strgutil.c index 858d603e0..e793fc1ce 100644 --- a/util/strgutil.c +++ b/util/strgutil.c @@ -687,18 +687,58 @@ ascii_tolower (int c) int -ascii_strcasecmp( const char *a, const char *b ) +ascii_strcasecmp (const char *a, const char *b) { - if (a == b) - return 0; + const unsigned char *p1 = (const unsigned char *)a; + const unsigned char *p2 = (const unsigned char *)b; + unsigned char c1, c2; - for (; *a && *b; a++, b++) { - if (*a != *b && ascii_toupper(*a) != ascii_toupper(*b)) - break; + if (p1 == p2) + return 0; + + do + { + c1 = ascii_tolower (*p1); + c2 = ascii_tolower (*p2); + + if (c1 == '\0') + break; + + ++p1; + ++p2; } - return *a == *b? 0 : (ascii_toupper (*a) - ascii_toupper (*b)); + while (c1 == c2); + + return c1 - c2; } +int +ascii_strncasecmp (const char *a, const char *b, size_t n) +{ + const unsigned char *p1 = (const unsigned char *)a; + const unsigned char *p2 = (const unsigned char *)b; + unsigned char c1, c2; + + if (p1 == p2 || !n ) + return 0; + + do + { + c1 = ascii_tolower (*p1); + c2 = ascii_tolower (*p2); + + if ( !--n || c1 == '\0') + break; + + ++p1; + ++p2; + } + while (c1 == c2); + + return c1 - c2; +} + + int ascii_memcasecmp( const char *a, const char *b, size_t n ) { @@ -712,6 +752,7 @@ ascii_memcasecmp( const char *a, const char *b, size_t n ) } + /********************************************* ********** missing string functions ********* *********************************************/ diff --git a/util/w32reg.c b/util/w32reg.c index 000ae07b7..fe63fe6a7 100644 --- a/util/w32reg.c +++ b/util/w32reg.c @@ -58,7 +58,7 @@ get_root_key(const char *root) /**************** * Return a string from the Win32 Registry or NULL in case of - * error. Caller must release the return value. A NUKK for root + * error. Caller must release the return value. A NULL for root * is an alias fro HKEY_CURRENT_USER * NOTE: The value is allocated with a plain malloc() - use free() and not * the usual m_free()!!! @@ -67,7 +67,7 @@ char * read_w32_registry_string( const char *root, const char *dir, const char *name ) { HKEY root_key, key_handle; - DWORD n1, nbytes; + DWORD n1, nbytes, type; char *result = NULL; if ( !(root_key = get_root_key(root) ) ) @@ -82,11 +82,48 @@ read_w32_registry_string( const char *root, const char *dir, const char *name ) result = malloc( (n1=nbytes+1) ); if( !result ) goto leave; - if( RegQueryValueEx( key_handle, name, 0, NULL, result, &n1 ) ) { + if( RegQueryValueEx( key_handle, name, 0, &type, result, &n1 ) ) { free(result); result = NULL; goto leave; } result[nbytes] = 0; /* make sure it is really a string */ + if (type == REG_EXPAND_SZ && strchr (result, '%')) { + char *tmp; + + n1 += 1000; + tmp = malloc (n1+1); + if (!tmp) + goto leave; + nbytes = ExpandEnvironmentStrings (result, tmp, n1); + if (nbytes && nbytes > n1) { + free (tmp); + tmp = malloc (n1 + 1); + if (!tmp) + goto leave; + nbytes = ExpandEnvironmentStrings (result, tmp, n1); + if (nbytes && nbytes > n1) { + free (tmp); /* oops - truncated, better don't expand at all */ + goto leave; + } + tmp[nbytes] = 0; + free (result); + result = tmp; + } + else if (nbytes) { /* okay, reduce the length */ + tmp[nbytes] = 0; + free (result); + result = malloc (strlen (tmp)+1); + if (!result) + result = tmp; + else { + strcpy (result, tmp); + free (tmp); + } + } + else { /* error - don't expand */ + free (tmp); + } + } leave: RegCloseKey( key_handle );