diff --git a/mrbgems/mruby-io/mrblib/file.rb b/mrbgems/mruby-io/mrblib/file.rb index 719f4e629..e5594ca50 100644 --- a/mrbgems/mruby-io/mrblib/file.rb +++ b/mrbgems/mruby-io/mrblib/file.rb @@ -149,7 +149,7 @@ class File < IO if drive_prefix.empty? expanded_path else - drive_prefix + expanded_path.gsub("/", File::ALT_SEPARATOR) + drive_prefix + expanded_path end end diff --git a/mrbgems/mruby-io/src/file.c b/mrbgems/mruby-io/src/file.c index 8ea3202ea..4759a401c 100644 --- a/mrbgems/mruby-io/src/file.c +++ b/mrbgems/mruby-io/src/file.c @@ -345,15 +345,14 @@ mrb_file__gethome(mrb_state *mrb, mrb_value klass) mrb_int argc = mrb_get_args(mrb, "|S", &username); if (argc == 0) { home = getenv("HOME"); - if (home == NULL) { - return mrb_nil_value(); - } #ifdef _WIN32 - home = getenv("USERPROFILE"); if (home == NULL) { - return mrb_nil_value(); + home = getenv("USERPROFILE"); } #endif + if (home == NULL) { + return mrb_nil_value(); + } if (!mrb_file_is_absolute_path(home)) { mrb_raise(mrb, E_ARGUMENT_ERROR, "non-absolute home"); } @@ -378,6 +377,15 @@ mrb_file__gethome(mrb_state *mrb, mrb_value klass) home = mrb_utf8_from_locale(home, -1); path = mrb_str_new_cstr(mrb, home); mrb_utf8_free(home); +#ifdef _WIN32 + char *pathp = RSTRING_PTR(path); + const char *const pathend = pathp + RSTRING_LEN(path); + for (;;) { + pathp = memchr(pathp, '\\', pathend - pathp); + if (!pathp) break; + *pathp++ = '/'; + } +#endif return path; } diff --git a/mrbgems/mruby-io/test/file.rb b/mrbgems/mruby-io/test/file.rb index 5746986ad..07e32b325 100644 --- a/mrbgems/mruby-io/test/file.rb +++ b/mrbgems/mruby-io/test/file.rb @@ -204,19 +204,19 @@ assert('File.expand_path') do assert_equal "/", File.expand_path("../../../..", "/") if File._getwd[1] == ":" drive_letter = File._getwd[0] - assert_equal drive_letter + ":\\", File.expand_path(([".."] * 100).join("/")) + assert_equal drive_letter + ":/", File.expand_path(([".."] * 100).join("/")) else assert_equal "/", File.expand_path(([".."] * 100).join("/")) end end -assert('File.expand_path (with ENV)') do - skip unless Object.const_defined?(:ENV) && ENV['HOME'] +assert('File.expand_path (with getenv(3))') do + skip unless MRubyIOTestUtil.const_defined?(:ENV_HOME) - assert_equal ENV['HOME'], File.expand_path("~/"), "home" - assert_equal ENV['HOME'], File.expand_path("~/", "/"), "home with base_dir" + assert_equal MRubyIOTestUtil::ENV_HOME, File.expand_path("~/"), "home" + assert_equal MRubyIOTestUtil::ENV_HOME, File.expand_path("~/", "/"), "home with base_dir" - assert_equal "#{ENV['HOME']}/user", File.expand_path("user", ENV['HOME']), "relative with base_dir" + assert_equal "#{MRubyIOTestUtil::ENV_HOME}/user", File.expand_path("user", MRubyIOTestUtil::ENV_HOME), "relative with base_dir" end assert('File.path') do diff --git a/mrbgems/mruby-io/test/mruby_io_test.c b/mrbgems/mruby-io/test/mruby_io_test.c index a00a911cf..18989a20c 100644 --- a/mrbgems/mruby-io/test/mruby_io_test.c +++ b/mrbgems/mruby-io/test/mruby_io_test.c @@ -243,4 +243,26 @@ mrb_mruby_io_gem_test(mrb_state* mrb) mrb_define_class_method(mrb, io_test, "win?", mrb_io_win_p, MRB_ARGS_NONE()); mrb_define_const(mrb, io_test, "MRB_WITH_IO_PREAD_PWRITE", mrb_bool_value(MRB_WITH_IO_PREAD_PWRITE_ENABLED)); + + const char *env_home = getenv("HOME"); +#ifdef _WIN32 + if (!env_home) { + env_home = getenv("USERPROFILE"); + } +#endif + if (env_home) { + char *utf8 = mrb_utf8_from_locale(env_home, strlen(env_home)); + mrb_value path = mrb_str_new_cstr(mrb, utf8); +#ifdef _WIN32 + char *pathp = RSTRING_PTR(path); + const char *const pathend = pathp + RSTRING_LEN(path); + for (;;) { + pathp = memchr(pathp, '\\', pathend - pathp); + if (!pathp) break; + *pathp++ = '/'; + } +#endif + mrb_define_const(mrb, io_test, "ENV_HOME", path); + mrb_utf8_free(utf8); + } }