ruby-changes:22981
From: usa <ko1@a...>
Date: Thu, 15 Mar 2012 12:57:16 +0900 (JST)
Subject: [ruby-changes:22981] usa:r35030 (trunk): * win32/win32.c, include/ruby/win32.h (rb_w32_ugetenv): new API to
usa 2012-03-15 12:57:02 +0900 (Thu, 15 Mar 2012) New Revision: 35030 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=35030 Log: * win32/win32.c, include/ruby/win32.h (rb_w32_ugetenv): new API to accept and to return UTF-8 strings. * win32/win32.c (rb_w32_getenv): follow above change. * win32/win32.c (rb_w32_get_environ): returns UTF-8 environment area. * hash.c (env_str_new, rb_f_getenv, env_fetch): follow above changes. [Bug #5570] [ruby-core:40737] Modified files: trunk/ChangeLog trunk/hash.c trunk/include/ruby/win32.h trunk/win32/win32.c Index: include/ruby/win32.h =================================================================== --- include/ruby/win32.h (revision 35029) +++ include/ruby/win32.h (revision 35030) @@ -268,6 +268,7 @@ extern struct servent *WSAAPI rb_w32_getservbyport(int, const char *); extern int rb_w32_socketpair(int, int, int, int *); extern char * rb_w32_getcwd(char *, int); +extern char * rb_w32_ugetenv(const char *); extern char * rb_w32_getenv(const char *); extern int rb_w32_rename(const char *, const char *); extern int rb_w32_urename(const char *, const char *); Index: ChangeLog =================================================================== --- ChangeLog (revision 35029) +++ ChangeLog (revision 35030) @@ -1,3 +1,15 @@ +Thu Mar 15 12:44:50 2012 NAKAMURA Usaku <usa@r...> + + * win32/win32.c, include/ruby/win32.h (rb_w32_ugetenv): new API to + accept and to return UTF-8 strings. + + * win32/win32.c (rb_w32_getenv): follow above change. + + * win32/win32.c (rb_w32_get_environ): returns UTF-8 environment area. + + * hash.c (env_str_new, rb_f_getenv, env_fetch): follow above changes. + [Bug #5570] [ruby-core:40737] + Thu Mar 15 10:57:27 2012 Shugo Maeda <shugo@r...> * enumerator.c (lazy_cycle): add Enumerable::Lazy#cycle. Index: win32/win32.c =================================================================== --- win32/win32.c (revision 35029) +++ win32/win32.c (revision 35030) @@ -630,6 +630,7 @@ static int NtSocketsInitialized = 0; static st_table *socklist = NULL; static char *envarea; +static char *uenvarea; /* License: Ruby's */ static void @@ -648,6 +649,10 @@ FreeEnvironmentStrings(envarea); envarea = NULL; } + if (uenvarea) { + free(uenvarea); + uenvarea = NULL; + } } /* License: Artistic or GPL */ @@ -4236,13 +4241,58 @@ /* License: Ruby's */ char * +rb_w32_ugetenv(const char *name) +{ + WCHAR *wenvarea, *wenv; + int len = strlen(name); + char *env; + int wlen; + + if (len == 0) return NULL; + + if (uenvarea) { + free(uenvarea); + uenvarea = NULL; + } + if (envarea) { + FreeEnvironmentStrings(envarea); + envarea = NULL; + } + wenvarea = GetEnvironmentStringsW(); + if (!wenvarea) { + map_errno(GetLastError()); + return NULL; + } + for (wenv = wenvarea, wlen = 1; *wenv; wenv += lstrlenW(wenv) + 1) + wlen += lstrlenW(wenv) + 1; + uenvarea = wstr_to_mbstr(CP_UTF8, wenvarea, wlen, NULL); + FreeEnvironmentStringsW(wenvarea); + if (!uenvarea) + return NULL; + + for (env = uenvarea; *env; env += strlen(env) + 1) + if (strncasecmp(env, name, len) == 0 && *(env + len) == '=') + return env + len + 1; + + return NULL; +} + +/* License: Ruby's */ +char * rb_w32_getenv(const char *name) { int len = strlen(name); char *env; if (len == 0) return NULL; - if (envarea) FreeEnvironmentStrings(envarea); + if (uenvarea) { + free(uenvarea); + uenvarea = NULL; + } + if (envarea) { + FreeEnvironmentStrings(envarea); + envarea = NULL; + } envarea = GetEnvironmentStrings(); if (!envarea) { map_errno(GetLastError()); @@ -5011,7 +5061,7 @@ char ** rb_w32_get_environ(void) { - char *envtop, *env; + WCHAR *envtop, *env; char **myenvtop, **myenv; int num; @@ -5022,23 +5072,24 @@ * CygWin deals these values by changing first `=' to '!'. But we don't * use such trick and follow cmd.exe's way that just doesn't show these * values. - * (U.N. 2001-11-15) + * + * This function returns UTF-8 strings. */ - envtop = GetEnvironmentStrings(); - for (env = envtop, num = 0; *env; env += strlen(env) + 1) + envtop = GetEnvironmentStringsW(); + for (env = envtop, num = 0; *env; env += lstrlenW(env) + 1) if (*env != '=') num++; myenvtop = (char **)malloc(sizeof(char *) * (num + 1)); - for (env = envtop, myenv = myenvtop; *env; env += strlen(env) + 1) { + for (env = envtop, myenv = myenvtop; *env; env += lstrlenW(env) + 1) { if (*env != '=') { - if (!(*myenv = strdup(env))) { + if (!(*myenv = wstr_to_utf8(env, NULL))) { break; } myenv++; } } *myenv = NULL; - FreeEnvironmentStrings(envtop); + FreeEnvironmentStringsW(envtop); return myenvtop; } Index: hash.c =================================================================== --- hash.c (revision 35029) +++ hash.c (revision 35030) @@ -2008,6 +2008,8 @@ static char **my_environ; #undef environ #define environ my_environ +#undef getenv +#define getenv(n) rb_w32_ugetenv(n) #elif defined(__APPLE__) #undef environ #define environ (*_NSGetEnviron()) @@ -2029,7 +2031,11 @@ static VALUE env_str_new(const char *ptr, long len) { +#ifdef _WIN32 + VALUE str = rb_str_encode(rb_enc_str_new(ptr, len, rb_utf8_encoding()), rb_enc_from_encoding(rb_locale_encoding()), 0, Qnil); +#else VALUE str = rb_locale_str_new(ptr, len); +#endif rb_obj_freeze(str); return str; @@ -2108,7 +2114,11 @@ env = getenv(nam); if (env) { if (ENVMATCH(nam, PATH_ENV) && !env_path_tainted(env)) { +#ifdef _WIN32 + VALUE str = rb_str_encode(rb_enc_str_new(env, strlen(env), rb_utf8_encoding()), rb_enc_from_encoding(rb_filesystem_encoding()), 0, Qnil); +#else VALUE str = rb_filesystem_str_new_cstr(env); +#endif rb_obj_freeze(str); return str; @@ -2159,7 +2169,11 @@ return if_none; } if (ENVMATCH(nam, PATH_ENV) && !env_path_tainted(env)) +#ifdef _WIN32 + return rb_str_encode(rb_enc_str_new(env, strlen(env), rb_utf8_encoding()), rb_enc_from_encoding(rb_filesystem_encoding()), 0, Qnil); +#else return rb_filesystem_str_new_cstr(env); +#endif return env_str_new2(env); } -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/