なかだです。

At Tue, 26 Jun 2001 17:16:23 +0900,
matz / zetabits.com (Yukihiro Matsumoto) wrote:
>   * 検索時に$arch-$osを付加して検索[ruby-ext:01796]

  これのパッチです。require "foo"を検索する順序は、$LOAD_PATHの
各ディレクトリ$dirに対して次のようになります。

$dir/$arch-$os/foo.rb
$dir/foo.rb
$dir/$arch-$os/foo.so
$dir/foo.so


Index: configure.in =================================================================== RCS file: /cvs/ruby/src/ruby/configure.in,v retrieving revision 1.92 diff -u -2 -p -r1.92 configure.in --- configure.in 2001/06/11 05:31:17 1.92 +++ configure.in 2001/07/16 16:36:04 @@ -1052,7 +1052,9 @@ configure_args=$ac_configure_args AC_SUBST(configure_args)dnl +RUBY_LOAD_ARCH="" if test "$fat_binary" = yes ; then arch="fat-${target_os}" + RUBY_LOAD_ARCH="${RUBY_LOAD_ARCH}__ARCHITECTURE__\"-${target_os}\", " AC_DEFINE_UNQUOTED(RUBY_THIN_ARCHLIB, "${RUBY_LIB_PATH}/" __ARCHITECTURE__ "-${target_os}") @@ -1066,6 +1068,15 @@ else fi +RUBY_LOAD_ARCH="${RUBY_LOAD_ARCH}\"${arch}\", " +case ${target_cpu} in + i*86) + RUBY_LOAD_ARCH="${RUBY_LOAD_ARCH}\"i386-${target_os}\", " + ;; +esac + AC_DEFINE_UNQUOTED(RUBY_ARCHLIB, "${RUBY_LIB_PATH}/${arch}") AC_DEFINE_UNQUOTED(RUBY_SITE_ARCHLIB, "${RUBY_SITE_LIB_PATH2}/${arch}") +RUBY_LOAD_ARCH="${RUBY_LOAD_ARCH}\"\"" +AC_DEFINE_UNQUOTED(RUBY_LOAD_ARCH, ${RUBY_LOAD_ARCH}) AC_ARG_WITH(search-path, Index: eval.c =================================================================== RCS file: /cvs/ruby/src/ruby/eval.c,v retrieving revision 1.193 diff -u -2 -p -r1.193 eval.c --- eval.c 2001/07/14 15:17:18 1.193 +++ eval.c 2001/07/16 15:17:24 @@ -5424,4 +5424,12 @@ rb_f_require(obj, fname) volatile int safe = ruby_safe_level; + static const char *const dlext[] = { + ".rb", DLEXT, +#ifdef DLEXT2 + DLEXT2, +#endif + 0 + }; + SafeStringValue(fname); if (rb_feature_p(RSTRING(fname)->ptr, Qtrue)) @@ -5430,7 +5438,7 @@ rb_f_require(obj, fname) if (ext) { if (strcmp(".rb", ext) == 0) { - feature = rb_str_dup(fname); - tmp = rb_find_file(fname); - if (tmp) { + tmp = fname; + if (rb_find_file_ext(&tmp, NULL)) { + feature = fname; fname = tmp; goto load_rb; @@ -5438,41 +5446,28 @@ rb_f_require(obj, fname) } else if (strcmp(".so", ext) == 0 || strcmp(".o", ext) == 0) { - fname = rb_str_new(RSTRING(fname)->ptr, ext-RSTRING(fname)->ptr); - tmp = rb_str_dup(fname); - rb_str_cat2(tmp, DLEXT); - tmp = rb_find_file(tmp); - if (tmp) { - feature = fname = tmp; - goto load_dyna; - } -#ifdef DLEXT2 - tmp = rb_str_dup(fname); - rb_str_cat2(tmp, DLEXT); - tmp = rb_find_file(tmp); - if (tmp) { - feature = fname = tmp; - goto load_dyna; - } -#endif - } - else if (strcmp(DLEXT, ext) == 0) { - tmp = rb_find_file(fname); - if (tmp) { - feature = fname = tmp; + int type; + feature = rb_str_new(RSTRING(fname)->ptr, ext-RSTRING(fname)->ptr); + tmp = feature; + if (type = rb_find_file_ext(&tmp, dlext + 1)) { + rb_str_cat2(feature, dlext[type]); + fname = tmp; goto load_dyna; } } + else if (strcmp(DLEXT, ext) == 0 #ifdef DLEXT2 - else if (strcmp(DLEXT2, ext) == 0) { - tmp = rb_find_file(fname); - if (tmp) { - feature = fname = tmp; + || strcmp(DLEXT2, ext) == 0 +#endif + ) { + tmp = fname; + if (rb_find_file_ext(&tmp, NULL)) { + feature = fname; + fname = tmp; goto load_dyna; } } -#endif } tmp = fname; - switch (rb_find_file_noext(&tmp)) { + switch (rb_find_file_ext(&tmp, dlext)) { case 0: break; @@ -5485,5 +5480,5 @@ rb_f_require(obj, fname) default: feature = fname; - fname = rb_find_file(tmp); + fname = tmp; goto load_dyna; } Index: file.c =================================================================== RCS file: /cvs/ruby/src/ruby/file.c,v retrieving revision 1.60 diff -u -2 -p -r1.60 file.c --- file.c 2001/07/16 04:22:46 1.60 +++ file.c 2001/07/16 17:35:48 @@ -1510,4 +1510,16 @@ static VALUE separator; static VALUE +rb_str_buf_append_path(str, str2) + VALUE str, str2; +{ + if (!(RSTRING(str)->len && isdirsep(RSTRING(str)->ptr[RSTRING(str)->len - 1])) && + !(RSTRING(str2)->len && isdirsep(RSTRING(str2)->ptr[0]))) { + rb_str_buf_cat(str, "/", 1); + } + if (RSTRING(str2)->len) rb_str_buf_append(str, str2); + return str; +} + +static VALUE rb_file_s_join(klass, args) VALUE klass, args; @@ -2125,5 +2137,5 @@ is_absolute_path(path) # if defined DOSISH if (path[0] == '\\') return 1; - if (strlen(path) > 2 && path[1] == ':') return 1; + if (path[0] && path[1] == ':') return 1; # endif return 0; @@ -2217,36 +2229,39 @@ file_load_ok(file) extern VALUE rb_load_path; +VALUE rb_load_arch; int -rb_find_file_noext(filep) +rb_find_file_ext(filep, ext) VALUE *filep; + const char* const* ext; { - char *path, *e, *found; - char *f = RSTRING(*filep)->ptr; - VALUE fname; - int i, j; - - static char *ext[] = { - ".rb", DLEXT, -#ifdef DLEXT2 - DLEXT2, -#endif - 0 - }; + VALUE path, fname = *filep; + char *f = RSTRING(fname)->ptr; + long plen; + int i, j, k; + + static const char *const noext[] = {"", 0}; + if (!ext) ext = noext; + if (f[0] == '~') { - fname = *filep; fname = rb_file_s_expand_path(1, &fname); + f = RSTRING(fname)->ptr; + } + + path = rb_str_buf_new(MAXPATHLEN); + + if (is_absolute_path(f) || + (f[0] == '.' && (f[1] == '.' ? !f[2] || isdirsep(f[2]) : !f[1] || isdirsep(f[1])))) { if (rb_safe_level() >= 2 && OBJ_TAINTED(fname)) { rb_raise(rb_eSecurityError, "loading from unsafe file %s", f); } - } - - if (is_absolute_path(f)) { + rb_str_buf_append(path, fname); + plen = RSTRING(path)->len; for (i=0; ext[i]; i++) { - fname = rb_str_dup(*filep); - rb_str_cat2(fname, ext[i]); - if (file_load_ok(RSTRING(fname)->ptr)) { - *filep = fname; + RSTRING(path)->len = plen; + rb_str_buf_cat2(path, ext[i]); + if (file_load_ok(RSTRING(path)->ptr)) { + *filep = path; return i+1; } @@ -2258,18 +2273,28 @@ rb_find_file_noext(filep) Check_Type(rb_load_path, T_ARRAY); + Check_Type(rb_load_arch, T_ARRAY); for (i=0;i<RARRAY(rb_load_path)->len;i++) { VALUE str = RARRAY(rb_load_path)->ptr[i]; SafeStringValue(str); - path = RSTRING(str)->ptr; + rb_str_buf_append(path, str); + plen = RSTRING(path)->len; for (j=0; ext[j]; j++) { - fname = rb_str_dup(*filep); - rb_str_cat2(fname, ext[j]); - found = dln_find_file(RSTRING(fname)->ptr, path); - if (found && file_load_ok(found)) { - *filep = fname; - return j+1; + for (k=0; k<RARRAY(rb_load_arch)->len; k++) { + VALUE arch = RARRAY(rb_load_arch)->ptr[k]; + SafeStringValue(arch); + if (*RSTRING(arch)->ptr) { + rb_str_buf_append_path(path, arch); + } + rb_str_buf_append_path(path, fname); + if (*ext[j]) rb_str_buf_cat2(path, ext[j]); + if (file_load_ok(RSTRING(path)->ptr)) { + *filep = path; + return j+1; + } + RSTRING(path)->len = plen; } } + RSTRING(path)->len = 0; } return 0; @@ -2492,3 +2517,13 @@ Init_File() rb_define_method(rb_cStat, "setgid?", rb_stat_sgid, 0); rb_define_method(rb_cStat, "sticky?", rb_stat_sticky, 0); + + rb_define_readonly_variable("$LOAD_ARCH", &rb_load_arch); + rb_load_arch = rb_ary_new(); + { + static const char *const arch[] = {RUBY_LOAD_ARCH, 0}; + const char *const *p = arch; + while (*p) { + rb_ary_push(rb_load_arch, rb_obj_freeze(rb_str_new2(*p++))); + } + } } Index: intern.h =================================================================== RCS file: /cvs/ruby/src/ruby/intern.h,v retrieving revision 1.54 diff -u -2 -p -r1.54 intern.h --- intern.h 2001/07/14 15:17:18 1.54 +++ intern.h 2001/07/16 14:50:35 @@ -183,5 +183,5 @@ int eaccess _((const char*, int)); VALUE rb_file_s_expand_path _((int, VALUE *)); void rb_file_const _((const char*, VALUE)); -int rb_find_file_noext _((VALUE*)); +int rb_find_file_ext _((VALUE*, const char* const*)); VALUE rb_find_file _((VALUE)); /* gc.c */ Index: mkconfig.rb =================================================================== RCS file: /cvs/ruby/src/ruby/mkconfig.rb,v retrieving revision 1.15 diff -u -2 -p -r1.15 mkconfig.rb --- mkconfig.rb 2001/05/31 04:40:37 1.15 +++ mkconfig.rb 2001/07/16 14:25:08 @@ -40,5 +40,5 @@ File.foreach "config.status" do |line| next if $so_name and /^RUBY_SO_NAME$/ =~ name v = " CONFIG[\"" + name + "\"] = " + - val.sub(/^\s*(.*)\s*$/, '"\1"').gsub(/\$\{?(\w+)\}?/) { + val.sub(/^\s*(\"?)(.*)\1\s*$/, '"\2"').gsub(/\$\{?(\w+)\}?/) { "$(#{$1})" } + "\n"
-- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦