diff --git a/mrbgems/mruby-bigint/core/bigint.c b/mrbgems/mruby-bigint/core/bigint.c index 77548f786..59c7bbe8d 100644 --- a/mrbgems/mruby-bigint/core/bigint.c +++ b/mrbgems/mruby-bigint/core/bigint.c @@ -590,7 +590,7 @@ mpz_mdiv(mrb_state *mrb, mpz_t *q, mpz_t *x, mpz_t *y) q->sn = 0; /* now if r != 0 and q < 0 we need to round q towards -inf */ if (!uzero_p(&r) && qsign < 0) - mpz_sub_int(mrb, q, 1); + mpz_add_int(mrb, q, 1); mpz_clear(mrb, &r); } @@ -655,7 +655,7 @@ mpz_mdivmod(mrb_state *mrb, mpz_t *q, mpz_t *r, mpz_t *x, mpz_t *y) q->sn = 0; /* now if r != 0 and q < 0 we need to round q towards -inf */ if (!uzero_p(r) && qsign < 0) - mpz_sub_int(mrb, q, 1); + mpz_add_int(mrb, q, 1); } static void @@ -908,7 +908,7 @@ mpz_get_str(mrb_state *mrb, char *s, mrb_int sz, mrb_int base, mpz_t *x) } // convert to character - for (mp_limb b=b2/base; b>0; b/=base) { + for (mp_limb b=b2; b>=base; b/=base) { char a0 = (char)(a % base); if (a0 < 10) a0 += '0'; else a0 += 'a' - 10; @@ -1134,8 +1134,7 @@ mpz_pow(mrb_state *mrb, mpz_t *zz, mpz_t *x, mrb_int e) return; } - mpz_init(mrb, &t); - mpz_set(mrb, &t, x); + mpz_init_set(mrb, &t, x); for (;!(mask &e); mask>>=1) ; mask>>=1; @@ -1509,6 +1508,8 @@ mrb_bint_add_n(mrb_state *mrb, mrb_value x, mrb_value y) else { mpz_add_int(mrb, &z, n<0 ? -n : n); } + struct RBigint *v = bint_new(mrb, &z); + return mrb_obj_value(v); } } y = mrb_as_bint(mrb, y); @@ -1912,15 +1913,15 @@ mrb_bint_xor(mrb_state *mrb, mrb_value x, mrb_value y) mpz_t a, b, c; bint_as_mpz(RBIGINT(x), &a); - if (mrb_integer_p(y)) { + if (mrb_integer_p(y) && a.sn > 0) { mrb_int z = mrb_integer(y); if (z == 0) return x; if (0 < z && (mp_dbl_limb)z < DIG_BASE) { - z ^= a.p[0]; - return mrb_int_value(mrb, z); + mpz_init_set(mrb, &c, &a); + c.p[0] ^= z; + return bint_norm(mrb, bint_new(mrb, &c)); } } - y = mrb_as_bint(mrb, y); bint_as_mpz(RBIGINT(y), &b); if (zero_p(&a)) return y; diff --git a/mrbgems/mruby-io/include/mruby/ext/io.h b/mrbgems/mruby-io/include/mruby/ext/io.h index 61f7533f5..537bf09c8 100644 --- a/mrbgems/mruby-io/include/mruby/ext/io.h +++ b/mrbgems/mruby-io/include/mruby/ext/io.h @@ -6,7 +6,6 @@ #define MRUBY_IO_H #include -#include #ifdef MRB_NO_STDIO # error IO and File conflicts 'MRB_NO_STDIO' in your build configuration @@ -66,8 +65,8 @@ struct mrb_io { #define MRB_O_DSYNC 0x00008000 #define MRB_O_RSYNC 0x00010000 -#define E_IO_ERROR mrb_exc_get_id(mrb, MRB_SYM(IOError)) -#define E_EOF_ERROR mrb_exc_get_id(mrb, MRB_SYM(EOFError)) +#define E_IO_ERROR mrb_exc_get_id(mrb, MRB_ERROR_SYM(IOError)) +#define E_EOF_ERROR mrb_exc_get_id(mrb, MRB_ERROR_SYM(EOFError)) int mrb_io_fileno(mrb_state *mrb, mrb_value io); 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/src/file_test.c b/mrbgems/mruby-io/src/file_test.c index e04f970b2..342c29a70 100644 --- a/mrbgems/mruby-io/src/file_test.c +++ b/mrbgems/mruby-io/src/file_test.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -38,7 +39,7 @@ extern struct mrb_data_type mrb_io_type; static int mrb_stat0(mrb_state *mrb, mrb_value obj, struct stat *st, int do_lstat) { - if (mrb_obj_is_kind_of(mrb, obj, mrb_class_get(mrb, "IO"))) { + if (mrb_obj_is_kind_of(mrb, obj, mrb_class_get_id(mrb, MRB_SYM(IO)))) { struct mrb_io *fptr; fptr = (struct mrb_io*)mrb_data_get_ptr(mrb, obj, &mrb_io_type); @@ -337,16 +338,16 @@ mrb_init_file_test(mrb_state *mrb) { struct RClass *f; - f = mrb_define_class(mrb, "FileTest", mrb->object_class); + f = mrb_define_class_id(mrb, MRB_SYM(FileTest), mrb->object_class); - mrb_define_class_method(mrb, f, "directory?", mrb_filetest_s_directory_p, MRB_ARGS_REQ(1)); - mrb_define_class_method(mrb, f, "exist?", mrb_filetest_s_exist_p, MRB_ARGS_REQ(1)); - mrb_define_class_method(mrb, f, "exists?", mrb_filetest_s_exist_p, MRB_ARGS_REQ(1)); - mrb_define_class_method(mrb, f, "file?", mrb_filetest_s_file_p, MRB_ARGS_REQ(1)); - mrb_define_class_method(mrb, f, "pipe?", mrb_filetest_s_pipe_p, MRB_ARGS_REQ(1)); - mrb_define_class_method(mrb, f, "size", mrb_filetest_s_size, MRB_ARGS_REQ(1)); - mrb_define_class_method(mrb, f, "size?", mrb_filetest_s_size_p, MRB_ARGS_REQ(1)); - mrb_define_class_method(mrb, f, "socket?", mrb_filetest_s_socket_p, MRB_ARGS_REQ(1)); - mrb_define_class_method(mrb, f, "symlink?", mrb_filetest_s_symlink_p, MRB_ARGS_REQ(1)); - mrb_define_class_method(mrb, f, "zero?", mrb_filetest_s_zero_p, MRB_ARGS_REQ(1)); + mrb_define_class_method_id(mrb, f, MRB_SYM_Q(directory), mrb_filetest_s_directory_p, MRB_ARGS_REQ(1)); + mrb_define_class_method_id(mrb, f, MRB_SYM_Q(exist), mrb_filetest_s_exist_p, MRB_ARGS_REQ(1)); + mrb_define_class_method_id(mrb, f, MRB_SYM_Q(exists), mrb_filetest_s_exist_p, MRB_ARGS_REQ(1)); + mrb_define_class_method_id(mrb, f, MRB_SYM_Q(file), mrb_filetest_s_file_p, MRB_ARGS_REQ(1)); + mrb_define_class_method_id(mrb, f, MRB_SYM_Q(pipe), mrb_filetest_s_pipe_p, MRB_ARGS_REQ(1)); + mrb_define_class_method_id(mrb, f, MRB_SYM(size), mrb_filetest_s_size, MRB_ARGS_REQ(1)); + mrb_define_class_method_id(mrb, f, MRB_SYM_Q(size), mrb_filetest_s_size_p, MRB_ARGS_REQ(1)); + mrb_define_class_method_id(mrb, f, MRB_SYM_Q(socket), mrb_filetest_s_socket_p, MRB_ARGS_REQ(1)); + mrb_define_class_method_id(mrb, f, MRB_SYM_Q(symlink), mrb_filetest_s_symlink_p, MRB_ARGS_REQ(1)); + mrb_define_class_method_id(mrb, f, MRB_SYM_Q(zero), mrb_filetest_s_zero_p, MRB_ARGS_REQ(1)); } 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); + } } diff --git a/src/numeric.c b/src/numeric.c index bfa8465f3..9fe516b10 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -1111,6 +1111,9 @@ int_mod(mrb_state *mrb, mrb_value x) if (mrb_bigint_p(x)) { return mrb_bint_mod(mrb, x, y); } + if (mrb_bigint_p(y)) { + return mrb_bint_mod(mrb, mrb_as_bint(mrb, x), y); + } #endif a = mrb_integer(x); if (a == 0) return x; @@ -1159,6 +1162,9 @@ int_divmod(mrb_state *mrb, mrb_value x) #endif return mrb_bint_divmod(mrb, x, y); } + if (mrb_bigint_p(y)) { + return mrb_bint_divmod(mrb, mrb_as_bint(mrb, x), y); + } #endif if (mrb_integer_p(y)) { mrb_int div, mod;