mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Merge branch 'master' into tests_for_bigint
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user