[#44909] VRDdeClientについて — Toshiyasu Soejima <clev@...2.so-net.ne.jp>

17 messages 2008/05/11

[#44936] yamlとencoding — "Yutaka Kanemoto" <kinpoco@...>

金本と申します。

16 messages 2008/05/14

[ruby-list:44916] Re: Dir.entriesのエンコーディング (was Re: Ruby 1.9のARGVのエンコーディング)

From: "NARUSE, Yui" <naruse@...>
Date: 2008-05-11 22:17:42 UTC
List: ruby-list #44916
成瀬です。

とりあえず異論がなさそうな範囲を実装してみたパッチです。

わたしはとりあえず、なかむらさんの提案に対して、
* ディレクトリのパスが戻り値のリストのエンコーディングが異なる場合、
  :list_encoding を用いるのを第一とする
* fallback 系の引数を取れるようにする
を加えればよいように感じています。

-- 
NARUSE, Yui  <naruse@airemix.jp>

Attachments (1)

encoding_of_dir_entries.patch (4.31 KB, text/x-diff)
--- dir.c	(revision 16336)
+++ dir.c	(working copy)
@@ -12,6 +12,7 @@
 **********************************************************************/
 
 #include "ruby/ruby.h"
+#include "ruby/encoding.h"
 
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -350,6 +351,7 @@ VALUE rb_cDir;
 struct dir_data {
     DIR *dir;
     char *path;
+    rb_encoding *enc;
 };
 
 static void
@@ -372,6 +374,7 @@ dir_s_alloc(VALUE klass)
 
     dirp->dir = NULL;
     dirp->path = NULL;
+    dirp->enc = NULL;
 
     return obj;
 }
@@ -386,9 +389,25 @@ static VALUE
 dir_initialize(VALUE dir, VALUE dirname)
 {
     struct dir_data *dp;
+    int dirname_encidx = rb_enc_get_index(dirname);
+    rb_encoding *fs_enc = rb_locale_encoding();
+    int fs_encidx = rb_enc_to_index(fs_enc);
 
-    FilePathValue(dirname);
     Data_Get_Struct(dir, struct dir_data, dp);
+    if (rb_usascii_encindex() == dirname_encidx ||
+	rb_ascii8bit_encindex() == dirname_encidx) {
+	dp->enc = rb_locale_encoding();
+    }
+    else if (fs_encidx == dirname_encidx) {
+	dp->enc = fs_enc;
+    }
+    else {
+	rb_raise(rb_eNotImpError, "dirname must equal filesystem encoding now");
+	/* dp->enc = rb_enc_from_index(dirname_encidx); */
+        /* transode dirname from dirname_encidx to fs_enc */
+    }
+    FilePathValue(dirname);
+
     if (dp->dir) closedir(dp->dir);
     if (dp->path) free(dp->path);
     dp->dir = NULL;
@@ -491,7 +510,7 @@ dir_path(VALUE dir)
 
     Data_Get_Struct(dir, struct dir_data, dirp);
     if (!dirp->path) return Qnil;
-    return rb_str_new2(dirp->path);
+    return rb_enc_str_new2(dirp->path, dirp->enc);
 }
 
 /*
@@ -516,7 +535,7 @@ dir_read(VALUE dir)
     errno = 0;
     dp = readdir(dirp->dir);
     if (dp) {
-	return rb_tainted_str_new(dp->d_name, NAMLEN(dp));
+	return rb_tainted_enc_str_new(dp->d_name, NAMLEN(dp), dirp->enc);
     }
     else if (errno == 0) {	/* end of stream */
 	return Qnil;
@@ -554,7 +573,7 @@ dir_each(VALUE dir)
     GetDIR(dir, dirp);
     rewinddir(dirp->dir);
     for (dp = readdir(dirp->dir); dp != NULL; dp = readdir(dirp->dir)) {
-	rb_yield(rb_tainted_str_new(dp->d_name, NAMLEN(dp)));
+	rb_yield(rb_tainted_enc_str_new(dp->d_name, NAMLEN(dp), dirp->enc));
 	if (dirp->dir == NULL) dir_closed();
     }
     return dir;
--- encoding.c	(revision 16336)
+++ encoding.c	(working copy)
@@ -934,7 +934,13 @@ rb_ascii8bit_encoding(void)
     if (!enc_table.list) {
 	rb_enc_init();
     }
-    return enc_table.list[0].enc;
+    return enc_table.list[ENCINDEX_ASCII].enc;
+}
+
+int
+rb_ascii8bit_encindex(void)
+{
+    return ENCINDEX_ASCII;
 }
 
 rb_encoding *
--- include/ruby/encoding.h	(revision 16336)
+++ include/ruby/encoding.h	(working copy)
@@ -90,6 +90,9 @@ int rb_enc_internal_get_index(VALUE obj)
 void rb_enc_internal_set_index(VALUE obj, int encindex);
 
 VALUE rb_enc_str_new(const char*, long, rb_encoding*);
+VALUE rb_enc_str_new2(const char*, rb_encoding *);
+VALUE rb_tainted_enc_str_new(const char*, long, rb_encoding *);
+VALUE rb_tainted_enc_str_new2(const char*, rb_encoding *);
 VALUE rb_enc_reg_new(const char*, long, rb_encoding*, int);
 PRINTF_ARGS(VALUE rb_enc_sprintf(rb_encoding *, const char*, ...), 2, 3);
 VALUE rb_enc_vsprintf(rb_encoding *, const char*, va_list);
@@ -173,6 +176,7 @@ rb_encoding *rb_usascii_encoding(void);
 rb_encoding *rb_locale_encoding(void);
 rb_encoding *rb_default_external_encoding(void);
 int rb_usascii_encindex(void);
+int rb_ascii8bit_encindex(void);
 VALUE rb_enc_default_external(void);
 void rb_enc_set_default_external(VALUE encoding);
 VALUE rb_locale_charmap(VALUE klass);
--- string.c	(revision 16336)
+++ string.c	(working copy)
@@ -410,6 +410,15 @@ rb_str_new2(const char *ptr)
 }
 
 VALUE
+rb_enc_str_new2(const char *ptr, rb_encoding *enc)
+{
+    if (!ptr) {
+	rb_raise(rb_eArgError, "NULL pointer given");
+    }
+    return rb_enc_str_new(ptr, strlen(ptr), enc);
+}
+
+VALUE
 rb_usascii_str_new2(const char *ptr)
 {
     if (!ptr) {
@@ -436,6 +445,24 @@ rb_tainted_str_new2(const char *ptr)
     return str;
 }
 
+VALUE
+rb_tainted_enc_str_new(const char *ptr, long len, rb_encoding *enc)
+{
+    VALUE str = rb_enc_str_new(ptr, len, enc);
+
+    OBJ_TAINT(str);
+    return str;
+}
+
+VALUE
+rb_tainted_enc_str_new2(const char *ptr, rb_encoding *enc)
+{
+    VALUE str = rb_enc_str_new2(ptr, enc);
+
+    OBJ_TAINT(str);
+    return str;
+}
+
 static VALUE
 str_replace_shared(VALUE str2, VALUE str)
 {

In This Thread

Prev Next