From 9481face427a93e1a557ecd980ec82f5d04da8d5 Mon Sep 17 00:00:00 2001 From: matz Date: Sat, 7 Jun 2003 15:34:31 +0000 Subject: * parse.y (value_expr0): class and module statements should not be warned for "void value expression". [ruby-talk:72989] * gc.c (add_final): should determine type by respond_to? * gc.c (define_final): ditto. * io.c (rb_io_ctl): should not depend on respond_to? * range.c (range_step): rb_check_string_type(). * process.c (proc_setgroups): new functions. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@3918 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 19 ++++++++++++ eval.c | 25 +++++++--------- gc.c | 8 ++--- io.c | 31 +++++++++++--------- parse.y | 2 -- process.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ range.c | 57 +++++++++++++++++++----------------- sample/test.rb | 2 +- 8 files changed, 175 insertions(+), 61 deletions(-) diff --git a/ChangeLog b/ChangeLog index e456425d11..9105f64070 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +Sat Jun 7 22:22:03 2003 Yukihiro Matsumoto + + * parse.y (value_expr0): class and module statements should not be + warned for "void value expression". [ruby-talk:72989] + +Sat Jun 7 01:46:41 2003 Yukihiro Matsumoto + + * gc.c (add_final): should determine type by respond_to? + + * gc.c (define_final): ditto. + + * io.c (rb_io_ctl): should not depend on respond_to? + + * range.c (range_step): rb_check_string_type(). + Fri Jun 6 20:29:14 2003 Nobuyoshi Nakada * eval.c (error_print): needs to be exception proof. @@ -13,6 +28,10 @@ Fri Jun 6 20:29:14 2003 Nobuyoshi Nakada * parse.y (cmd_brace_block, do_block, brace_block): initialize block variables at the beginning of the block. [ruby-talk:72521] +Fri Jun 6 18:49:11 2003 Yukihiro Matsumoto + + * process.c (proc_setgroups): new functions. + Fri Jun 6 18:33:27 2003 Yukihiro Matsumoto * gc.c (define_final): eliminate rb_f_lambda() call. diff --git a/eval.c b/eval.c index 11e470aa6c..101a27149e 100644 --- a/eval.c +++ b/eval.c @@ -6838,14 +6838,15 @@ block_alloc(klass, proc) struct RVarmap *vars; if (!rb_block_given_p() && !rb_f_block_given_p()) { - rb_raise(rb_eArgError, "tried to create Block object without a block"); + rb_raise(rb_eArgError, "tried to create %s object without a block", + proc ? "Proc" : "Block"); + } + if (proc && !rb_block_given_p()) { + rb_warn("tried to create Proc object without a block"); } - if (ruby_block->block_obj) { - if ((proc && (ruby_block->flags & BLOCK_PROC)) || - (!proc && !(ruby_block->flags & BLOCK_PROC))) - return ruby_block->block_obj; - ruby_block->flags &= ~BLOCK_PROC; + if (!proc && ruby_block->block_obj) { + return ruby_block->block_obj; } block = Data_Make_Struct(klass, struct BLOCK, blk_mark, blk_free, data); *data = *ruby_block; @@ -6873,9 +6874,10 @@ block_alloc(klass, proc) block_save_safe_level(block); if (proc) { data->flags |= BLOCK_PROC; - ruby_block->flags |= BLOCK_PROC; } - ruby_block->block_obj = block; + else { + ruby_block->block_obj = block; + } return block; } @@ -6895,12 +6897,7 @@ block_s_new(argc, argv, klass) VALUE rb_block_new() { - if (ruby_block->flags & BLOCK_PROC) { - return block_alloc(rb_cProc, Qtrue); - } - else { - return block_alloc(rb_cBlock, Qfalse); - } + return block_alloc(rb_cBlock, Qfalse); } static VALUE diff --git a/gc.c b/gc.c index 01f59dac94..a34a3238a2 100644 --- a/gc.c +++ b/gc.c @@ -1415,8 +1415,8 @@ add_final(os, block) VALUE os, block; { rb_warn("ObjectSpace::add_finalizer is deprecated; use define_finalizer"); - if (!rb_obj_is_kind_of(block, rb_cBlock)) { - rb_raise(rb_eArgError, "wrong type argument %s (Block required)", + if (!rb_respond_to(block, rb_intern("call"))) { + rb_raise(rb_eArgError, "wrong type argument %s (should be callable)", rb_obj_classname(block)); } rb_ary_push(finalizers, block); @@ -1471,8 +1471,8 @@ define_final(argc, argv, os) if (argc == 1) { block = rb_block_new(); } - else if (!rb_obj_is_kind_of(block, rb_cBlock)) { - rb_raise(rb_eArgError, "wrong type argument %s (Block required)", + else if (!rb_respond_to(block, rb_intern("call"))) { + rb_raise(rb_eArgError, "wrong type argument %s (should be callable)", rb_obj_classname(block)); } need_call_final = 1; diff --git a/io.c b/io.c index 79c2ea3461..8fac72a0ce 100644 --- a/io.c +++ b/io.c @@ -3338,32 +3338,35 @@ rb_io_ctl(io, req, arg, io_p) else if (arg == Qtrue) { narg = 1; } - else if (rb_obj_is_kind_of(arg, rb_cInteger)) { - narg = NUM2LONG(arg); - } else { - StringValue(arg); + VALUE tmp = rb_check_string_type(arg); + if (NIL_P(tmp)) { + narg = NUM2LONG(arg); + } + else { + arg = tmp; #ifdef IOCPARM_MASK #ifndef IOCPARM_LEN #define IOCPARM_LEN(x) (((x) >> 16) & IOCPARM_MASK) #endif #endif #ifdef IOCPARM_LEN - len = IOCPARM_LEN(cmd); /* on BSDish systems we're safe */ + len = IOCPARM_LEN(cmd); /* on BSDish systems we're safe */ #else - len = 256; /* otherwise guess at what's safe */ + len = 256; /* otherwise guess at what's safe */ #endif - rb_str_modify(arg); + rb_str_modify(arg); - if (len <= RSTRING(arg)->len) { - len = RSTRING(arg)->len; - } - if (RSTRING(arg)->len < len) { - rb_str_resize(arg, len+1); + if (len <= RSTRING(arg)->len) { + len = RSTRING(arg)->len; + } + if (RSTRING(arg)->len < len) { + rb_str_resize(arg, len+1); + } + RSTRING(arg)->ptr[len] = 17; /* a little sanity check here */ + narg = (long)RSTRING(arg)->ptr; } - RSTRING(arg)->ptr[len] = 17; /* a little sanity check here */ - narg = (long)RSTRING(arg)->ptr; } retval = io_cntl(fileno(fptr->f), cmd, narg, io_p); if (retval < 0) rb_sys_fail(fptr->path); diff --git a/parse.y b/parse.y index 55b5a5fda2..c09522de30 100644 --- a/parse.y +++ b/parse.y @@ -4957,8 +4957,6 @@ value_expr0(node) while (node) { switch (nd_type(node)) { - case NODE_CLASS: - case NODE_MODULE: case NODE_DEFN: case NODE_DEFS: parser_warning(node, "void value expression"); diff --git a/process.c b/process.c index 514c30c87f..2ee27d1d01 100644 --- a/process.c +++ b/process.c @@ -45,6 +45,8 @@ struct timeval rb_time_interval _((VALUE)); #include #endif +#include + #if defined(HAVE_TIMES) || defined(_WIN32) static VALUE S_Tms; #endif @@ -1219,6 +1221,92 @@ proc_setgid(obj, id) return INT2FIX(gid); } + +static size_t maxgroups = 32; + +static VALUE +proc_getgroups(VALUE obj) +{ + VALUE ary; + size_t ngroups = 32; + gid_t *groups; + int i; + + groups = ALLOCA_N(gid_t, maxgroups); + + ngroups = getgroups(ngroups, groups); + if (ngroups == -1) + rb_sys_fail(0); + + ary = rb_ary_new(); + for (i = 0; i < ngroups; i++) + rb_ary_push(ary, INT2NUM(groups[i])); + + return ary; +} + +static VALUE +proc_setgroups(VALUE obj, VALUE ary) +{ + size_t ngroups; + gid_t *groups; + int i; + struct group *gr; + + Check_Type(ary, T_ARRAY); + + ngroups = RARRAY(ary)->len; + if (ngroups > maxgroups) + rb_raise(rb_eArgError, "too many groups, %d max", maxgroups); + + groups = ALLOCA_N(gid_t, ngroups); + + for (i = 0; i < ngroups; i++) { + VALUE g = RARRAY(ary)->ptr[i]; + + if (FIXNUM_P(g)) { + groups[i] = FIX2INT(g); + } + else { + VALUE tmp = rb_check_string_type(g); + + if (NIL_P(tmp)) { + groups[i] = NUM2INT(g); + } + else { + gr = getgrnam(RSTRING(g)->ptr); + } + } + } + + i = setgroups(ngroups, groups); + if (i == -1) + rb_sys_fail(0); + + return proc_getgroups(obj); +} + +static VALUE +proc_getmaxgroups(obj) + VALUE obj; +{ + return INT2FIX(maxgroups); +} + +static VALUE +proc_setmaxgroups(obj, val) + VALUE obj; +{ + size_t ngroups = INT2FIX(val); + + if (ngroups > 4096) + ngroups = 4096; + + maxgroups = ngroups; + + return INT2FIX(maxgroups); +} + static VALUE proc_geteuid(obj) VALUE obj; @@ -1396,6 +1484,10 @@ Init_process() rb_define_module_function(rb_mProcess, "euid=", proc_seteuid, 1); rb_define_module_function(rb_mProcess, "egid", proc_getegid, 0); rb_define_module_function(rb_mProcess, "egid=", proc_setegid, 1); + rb_define_module_function(rb_mProcess, "groups", proc_getgroups, 0); + rb_define_module_function(rb_mProcess, "groups=", proc_setgroups, 1); + rb_define_module_function(rb_mProcess, "maxgroups", proc_getmaxgroups, 0); + rb_define_module_function(rb_mProcess, "maxgroups=", proc_setmaxgroups, 1); rb_define_module_function(rb_mProcess, "times", rb_proc_times, 0); diff --git a/range.c b/range.c index b7ef175440..da8eeda513 100644 --- a/range.c +++ b/range.c @@ -257,36 +257,41 @@ range_step(argc, argv, range) rb_yield(LONG2NUM(i)); } } - else if (rb_obj_is_kind_of(b, rb_cNumeric)) { - ID c = rb_intern(EXCL(range) ? "<" : "<="); - - if (rb_equal(step, INT2FIX(0))) rb_raise(rb_eArgError, "step can't be 0"); - while (RTEST(rb_funcall(b, c, 1, e))) { - rb_yield(b); - b = rb_funcall(b, '+', 1, step); - } - } - else if (TYPE(b) == T_STRING) { - VALUE args[5]; - long iter[2]; - - if (unit == 0) rb_raise(rb_eArgError, "step can't be 0"); - args[0] = b; args[1] = e; args[2] = range; - iter[0] = 1; iter[1] = unit; - rb_iterate((VALUE(*)_((VALUE)))str_step, (VALUE)args, step_i, (VALUE)iter); - } else { - long args[2]; + VALUE tmp = rb_check_string_type(b); - if (unit == 0) rb_raise(rb_eArgError, "step can't be 0"); - if (!rb_respond_to(b, id_succ)) { - rb_raise(rb_eTypeError, "cannot iterate from %s", - rb_obj_classname(b)); + if (!NIL_P(tmp)) { + VALUE args[5]; + long iter[2]; + + b = tmp; + if (unit == 0) rb_raise(rb_eArgError, "step can't be 0"); + args[0] = b; args[1] = e; args[2] = range; + iter[0] = 1; iter[1] = unit; + rb_iterate((VALUE(*)_((VALUE)))str_step, (VALUE)args, step_i, (VALUE)iter); + } + else if (rb_obj_is_kind_of(b, rb_cNumeric)) { + ID c = rb_intern(EXCL(range) ? "<" : "<="); + + if (rb_equal(step, INT2FIX(0))) rb_raise(rb_eArgError, "step can't be 0"); + while (RTEST(rb_funcall(b, c, 1, e))) { + rb_yield(b); + b = rb_funcall(b, '+', 1, step); + } } + else { + long args[2]; + + if (unit == 0) rb_raise(rb_eArgError, "step can't be 0"); + if (!rb_respond_to(b, id_succ)) { + rb_raise(rb_eTypeError, "cannot iterate from %s", + rb_obj_classname(b)); + } - args[0] = 1; - args[1] = unit; - range_each_func(range, step_i, b, e, args); + args[0] = 1; + args[1] = unit; + range_each_func(range, step_i, b, e, args); + } } return range; } diff --git a/sample/test.rb b/sample/test.rb index c4a0c6176a..7d4c2f9584 100644 --- a/sample/test.rb +++ b/sample/test.rb @@ -1031,7 +1031,7 @@ test_ok(block.clone.call == 11) test_ok(proc.clone.call == 44) test_ok(get_block(&block).class == Block) -test_ok(get_block(&proc).class == Proc) +test_ok(get_block(&proc).class == Block) test_ok(Block.new{|a,| a}.call(1,2,3) == 1) argument_test(false, Proc.new{|a,| p a}, 1,2) -- cgit v1.2.3