[前][次][番号順一覧][スレッド一覧]

ruby-changes:11274

From: nobu <ko1@a...>
Date: Wed, 11 Mar 2009 13:17:08 +0900 (JST)
Subject: [ruby-changes:11274] Ruby:r22885 (trunk): * win32/win32.c (rb_w32_telldir, rb_w32_seekdir): should use long.

nobu	2009-03-11 13:16:56 +0900 (Wed, 11 Mar 2009)

  New Revision: 22885

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=22885

  Log:
    * win32/win32.c (rb_w32_telldir, rb_w32_seekdir): should use long.

  Modified files:
    trunk/ChangeLog
    trunk/win32/dir.h
    trunk/win32/win32.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 22884)
+++ ChangeLog	(revision 22885)
@@ -1,3 +1,7 @@
+Wed Mar 11 13:16:58 2009  Nobuyoshi Nakada  <nobu@r...>
+
+	* win32/win32.c (rb_w32_telldir, rb_w32_seekdir): should use long.
+
 Wed Mar 11 13:03:12 2009  Nobuyoshi Nakada  <nobu@r...>
 
 	* ext/dl/handle.c (rb_dlhandle_sym): fixed heap corruption.
Index: win32/win32.c
===================================================================
--- win32/win32.c	(revision 22884)
+++ win32/win32.c	(revision 22885)
@@ -371,6 +371,18 @@
     return p;
 }
 
+#ifndef CSIDL_LOCAL_APPDATA
+#define CSIDL_LOCAL_APPDATA 28
+#endif
+#ifndef CSIDL_COMMON_APPDATA
+#define CSIDL_COMMON_APPDATA 35
+#endif
+#ifndef CSIDL_WINDOWS
+#define CSIDL_WINDOWS	36
+#endif
+#ifndef CSIDL_SYSTEM
+#define CSIDL_SYSTEM	37
+#endif
 #ifndef CSIDL_PROFILE
 #define CSIDL_PROFILE 40
 #endif
@@ -400,11 +412,27 @@
     }
 }
 
+static UINT
+get_system_directory(WCHAR *path, UINT len)
+{
+    HANDLE hKernel = GetModuleHandle("kernel32.dll");
+
+    if (hKernel) {
+	typedef UINT WINAPI wgetdir_func(WCHAR*, UINT);
+	FARPROC ptr = GetProcAddress(hKernel, "GetSystemWindowsDirectoryW");
+	if (ptr) {
+	    return (*(wgetdir_func *)ptr)(path, len);
+	}
+    }
+    return GetWindowsDirectoryW(path, len);
+}
+
 #define numberof(array) (sizeof(array) / sizeof(*array))
 
 static void
 init_env(void)
 {
+    static const WCHAR TMPDIR[] = L"TMPDIR";
     WCHAR env[_MAX_PATH];
     DWORD len;
     BOOL f;
@@ -442,6 +470,20 @@
 	SetEnvironmentVariableW(L"USER", env);
     }
     NTLoginName = strdup(rb_w32_getenv("USER"));
+
+    if (!GetEnvironmentVariableW(TMPDIR, env, numberof(env)) &&
+	!GetEnvironmentVariableW(L"TMP", env, numberof(env)) &&
+	!GetEnvironmentVariableW(L"TEMP", env, numberof(env)) &&
+	(get_special_folder(CSIDL_LOCAL_APPDATA, env) ||
+	 get_system_directory(env, numberof(env)))) {
+	static const WCHAR temp[] = L"temp";
+	WCHAR *p = translate_wchar(env, L'\\', L'/');
+	if (*(p - 1) != L'/') *p++ = L'/';
+	if (p - env + numberof(temp) < numberof(env)) {
+	    memcpy(p, temp, sizeof(temp));
+	    SetEnvironmentVariableW(TMPDIR, env);
+	}
+    }
 }
 
 
@@ -1639,12 +1681,11 @@
     return TRUE;
 }
 
-static BOOL
-ruby_direct_conv(const WCHAR *file, struct direct *entry, rb_encoding *enc)
+VALUE
+rb_w32_conv_from_wchar(const WCHAR *wstr, rb_encoding *enc)
 {
     static rb_encoding *utf16 = (rb_encoding *)-1;
     VALUE src;
-    VALUE dst;
     VALUE opthash;
     int ecflags;
     VALUE ecopts;
@@ -1656,15 +1697,24 @@
     }
     if (!utf16)
 	/* maybe miniruby */
-	return win32_direct_conv(file, entry, NULL);
+	return Qnil;
 
-    src = rb_enc_str_new((char *)file, lstrlenW(file) * sizeof(WCHAR), utf16);
+    src = rb_enc_str_new((char *)wstr, lstrlenW(wstr) * sizeof(WCHAR), utf16);
     opthash = rb_hash_new();
     rb_hash_aset(opthash, ID2SYM(rb_intern("undef")),
 		 ID2SYM(rb_intern("replace")));
     ecflags = rb_econv_prepare_opts(opthash, &ecopts);
-    dst = rb_str_encode(src, rb_enc_from_encoding(enc), ecflags, ecopts);
+    return rb_str_encode(src, rb_enc_from_encoding(enc), ecflags, ecopts);
+}
 
+static BOOL
+ruby_direct_conv(const WCHAR *file, struct direct *entry, rb_encoding *enc)
+{
+    VALUE dst = rb_w32_conv_from_wchar(file, enc);
+
+    if (NIL_P(dst))
+	return win32_direct_conv(file, entry, NULL);
+
     entry->d_namlen = RSTRING_LEN(dst);
     if (!(entry->d_name = malloc(entry->d_namlen + 1)))
 	return FALSE;
@@ -1727,7 +1777,7 @@
 // Telldir returns the current string pointer position
 //
 
-off_t
+long
 rb_w32_telldir(DIR *dirp)
 {
     return dirp->loc;
@@ -1738,7 +1788,7 @@
 // (Saved by telldir).
 
 void
-rb_w32_seekdir(DIR *dirp, off_t loc)
+rb_w32_seekdir(DIR *dirp, long loc)
 {
     if (dirp->loc > loc) rb_w32_rewinddir(dirp);
 
@@ -4951,3 +5001,58 @@
     return f;
 }
 #endif
+
+BOOL
+rb_w32_get_special_directory(int n, WCHAR *path)
+{
+    if (!get_special_folder(n, path))
+	return FALSE;
+    regulate_path(path);
+    return TRUE;
+}
+
+static VALUE
+w32_get_special_directory(VALUE self, VALUE num)
+{
+    VALUE str;
+    int n = NUM2INT(num);
+    WCHAR path[_MAX_PATH];
+
+    if (!rb_w32_get_special_directory(n, path)) {
+	rb_sys_fail(0);
+    }
+    str = rb_w32_conv_from_wchar(path, rb_filesystem_encoding());
+    OBJ_TAINT(str);
+    return str;
+}
+
+static VALUE
+w32_get_system_directory(VALUE self)
+{
+    VALUE str;
+    WCHAR path[_MAX_PATH];
+
+    if (!get_system_directory(path, numberof(path))) {
+	rb_sys_fail(0);
+    }
+    regulate_path(path);
+    str = rb_w32_conv_from_wchar(path, rb_filesystem_encoding());
+    OBJ_TAINT(str);
+    return str;
+}
+
+void
+Init_win32(void)
+{
+    VALUE mWin32 = rb_define_module("Win32");
+    VALUE dir = rb_define_module_under(mWin32, "Dir");
+    rb_define_module_function(dir, "special", w32_get_special_directory, 1);
+    rb_define_module_function(dir, "system", w32_get_system_directory, 0);
+    rb_define_const(dir, "LOCAL_APPDATA", UINT2NUM(CSIDL_LOCAL_APPDATA));
+    rb_define_const(dir, "COMMON_APPDATA", UINT2NUM(CSIDL_COMMON_APPDATA));
+    rb_define_const(dir, "WINDOWS", UINT2NUM(CSIDL_WINDOWS));
+    rb_define_const(dir, "SYSTEM", UINT2NUM(CSIDL_SYSTEM));
+    rb_define_const(dir, "PROFILE", UINT2NUM(CSIDL_PROFILE));
+    rb_define_const(dir, "PERSONAL", UINT2NUM(CSIDL_PERSONAL));
+    rb_define_const(mWin32, "Version", UINT2NUM(rb_w32_osver()));
+}
Index: win32/dir.h
===================================================================
--- win32/dir.h	(revision 22884)
+++ win32/dir.h	(revision 22885)
@@ -30,8 +30,8 @@
 DIR*           rb_w32_opendir(const char*);
 struct direct* rb_w32_readdir(DIR *);
 struct direct* rb_w32_readdir_with_enc(DIR *, rb_encoding *);
-off_t          rb_w32_telldir(DIR *);
-void           rb_w32_seekdir(DIR *, off_t);
+long           rb_w32_telldir(DIR *);
+void           rb_w32_seekdir(DIR *, long);
 void           rb_w32_rewinddir(DIR *);
 void           rb_w32_closedir(DIR *);
 

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]