Merge branch 'master' into tests_for_bigint

This commit is contained in:
Hoshiumi Arata
2024-12-12 17:01:06 +09:00
8 changed files with 73 additions and 36 deletions
+10 -9
View File
@@ -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;
+2 -3
View File
@@ -6,7 +6,6 @@
#define MRUBY_IO_H
#include <mruby.h>
#include <mruby/presym.h>
#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);
+1 -1
View File
@@ -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
+13 -5
View File
@@ -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;
}
+13 -12
View File
@@ -8,6 +8,7 @@
#include <mruby/string.h>
#include <mruby/ext/io.h>
#include <mruby/error.h>
#include <mruby/presym.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -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));
}
+6 -6
View File
@@ -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
+22
View File
@@ -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);
}
}
+6
View File
@@ -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;