diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 1998-02-09 10:56:24 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 1998-02-09 10:56:24 +0000 |
commit | b814252d728cb08f159da1777feca4f8e9362327 (patch) | |
tree | de6617897dbf6bce78045e3fa2ea84ea2422f166 | |
parent | 1bbcd202e4dab0894bc5ed68ce4ea84dc916980f (diff) |
1.1b7 pre
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/v1_1r@67 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 35 | ||||
-rw-r--r-- | array.c | 42 | ||||
-rw-r--r-- | bignum.c | 2 | ||||
-rw-r--r-- | class.c | 24 | ||||
-rw-r--r-- | enum.c | 20 | ||||
-rw-r--r-- | eval.c | 351 | ||||
-rw-r--r-- | ext/dbm/dbm.c | 21 | ||||
-rw-r--r-- | ext/fcntl/fcntl.c | 2 | ||||
-rw-r--r-- | file.c | 31 | ||||
-rw-r--r-- | gc.c | 24 | ||||
-rw-r--r-- | hash.c | 36 | ||||
-rw-r--r-- | io.c | 68 | ||||
-rw-r--r-- | io.h | 1 | ||||
-rw-r--r-- | lib/tempfile.rb | 23 | ||||
-rw-r--r-- | lib/thread.rb | 30 | ||||
-rw-r--r-- | marshal.c | 2 | ||||
-rw-r--r-- | numeric.c | 53 | ||||
-rw-r--r-- | object.c | 18 | ||||
-rw-r--r-- | parse.y | 35 | ||||
-rw-r--r-- | re.c | 2 | ||||
-rw-r--r-- | ruby.c | 102 | ||||
-rw-r--r-- | ruby.h | 16 | ||||
-rw-r--r-- | sample/from.rb | 22 | ||||
-rw-r--r-- | sample/rbc.rb | 42 | ||||
-rw-r--r-- | sample/test.rb | 3 | ||||
-rw-r--r-- | sample/tkfrom.rb | 40 | ||||
-rw-r--r-- | string.c | 104 | ||||
-rw-r--r-- | time.c | 8 |
28 files changed, 704 insertions, 453 deletions
@@ -1,3 +1,38 @@ +Mon Feb 9 14:51:56 1998 Yukihiro Matsumoto <matz@netlab.co.jp> + + * numeric.c (do_coerce): proper error message. + + * string.c (str_sum): bug - masked by wrong value. (sigh..) + +Sat Feb 7 15:11:14 1998 Yukihiro Matsumoto <matz@netlab.co.jp> + + * string.c (str_empty): new method + +Fri Feb 6 01:42:15 1998 Yukihiro Matsumoto <matz@netlab.co.jp> + + * time.c (time_asctime): use asctime(3), not strftime(3). + +Thu Feb 5 18:58:46 1998 Yukihiro Matsumoto <matz@netlab.co.jp> + + * io.c (io_fptr_close): do not free path on close(). + + * array.c (ary_filter): new method. + + * enum.c (enum_each_with_index): new method. + +Thu Feb 5 14:10:35 1998 Yukihiro Matsumoto <matz@netlab.co.jp> + + * parse.y (primary): singleton class def can be appeared inside + method bodies. + + * hash.c (hash_replace): replace content. + + * string.c (str_replace_method): replace content. + + * array.c (ary_replace_method): replace elements. + + * string.c (str_succ_bang): String#succ! + Thu Feb 5 18:20:30 1998 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp> * string.c (str_upcase_bang): multi byte character support. @@ -403,24 +403,19 @@ ary_index(ary, val) } static VALUE -ary_indexes(ary, args) - VALUE ary, args; +ary_indexes(argc, argv, ary) + int argc; + VALUE *argv; + VALUE ary; { - VALUE *p, *pend; VALUE new_ary; - int i = 0; + int i; - if (!args || NIL_P(args) || RARRAY(args)->len == 0) { - return ary_new2(0); + new_ary = ary_new2(argc); + for (i=0; i<argc; i++) { + ary_store(new_ary, i, ary_entry(ary, NUM2INT(argv[i]))); } - new_ary = ary_new2(RARRAY(args)->len); - - p = RARRAY(args)->ptr; pend = p + RARRAY(args)->len; - while (p < pend) { - ary_store(new_ary, i++, ary_entry(ary, NUM2INT(*p))); - p++; - } return new_ary; } @@ -821,20 +816,27 @@ ary_delete_if(ary) return ary; } -#if 0 static VALUE -ary_replace(ary) +ary_filter(ary) VALUE ary; { int i; + ary_modify(ary); for (i = 0; i < RARRAY(ary)->len; i++) { RARRAY(ary)->ptr[i] = rb_yield(RARRAY(ary)->ptr[i]); } + return ary; +} +static VALUE +ary_replace_method(ary, ary2) + VALUE ary, ary2; +{ + Check_Type(ary2, T_ARRAY); + ary_replace(ary, 0, RARRAY(ary2)->len, ary2); return ary; } -#endif static VALUE ary_clear(ary) @@ -1188,7 +1190,8 @@ Init_Array() rb_define_alias(cArray, "size", "length"); rb_define_method(cArray, "empty?", ary_empty_p, 0); rb_define_method(cArray, "index", ary_index, 1); - rb_define_method(cArray, "indexes", ary_indexes, -2); + rb_define_method(cArray, "indexes", ary_indexes, -1); + rb_define_method(cArray, "indices", ary_indexes, -1); rb_define_method(cArray, "clone", ary_clone, 0); rb_define_method(cArray, "dup", ary_dup, 0); rb_define_method(cArray, "join", ary_join_method, -1); @@ -1199,9 +1202,8 @@ Init_Array() rb_define_method(cArray, "delete", ary_delete, 1); rb_define_method(cArray, "delete_at", ary_delete_at, 1); rb_define_method(cArray, "delete_if", ary_delete_if, 0); -#if 0 - rb_define_method(cArray, "replace", ary_replace, 0); -#endif + rb_define_method(cArray, "filter", ary_filter, 0); + rb_define_method(cArray, "replace", ary_replace_method, 1); rb_define_method(cArray, "clear", ary_clear, 0); rb_define_method(cArray, "fill", ary_fill, -1); rb_define_method(cArray, "include?", ary_includes, 1); @@ -1181,7 +1181,7 @@ big_abs(x) x = big_clone(x); RBIGNUM(x)->sign = 1; } - return (VALUE)x; + return x; } /* !!!warnig!!!! @@ -95,11 +95,11 @@ rb_define_class_id(id, super) klass = class_new(super); rb_name_class(klass, id); /* make metaclass */ - RBASIC(klass)->class = singleton_class_new(RBASIC(super)->class); - singleton_class_attached(RBASIC(klass)->class, klass); + RBASIC(klass)->klass = singleton_class_new(RBASIC(super)->klass); + singleton_class_attached(RBASIC(klass)->klass, klass); rb_funcall(super, rb_intern("inherited"), 1, klass); - return (VALUE)klass; + return klass; } VALUE @@ -201,10 +201,10 @@ include_class_new(module, super) klass->iv_tbl = RCLASS(module)->iv_tbl; klass->super = super; if (TYPE(module) == T_ICLASS) { - RBASIC(klass)->class = RBASIC(module)->class; + RBASIC(klass)->klass = RBASIC(module)->klass; } else { - RBASIC(klass)->class = module; + RBASIC(klass)->klass = module; } return (VALUE)klass; @@ -253,7 +253,7 @@ mod_included_modules(mod) for (p = RCLASS(mod)->super; p; p = RCLASS(p)->super) { if (BUILTIN_TYPE(p) == T_ICLASS) { - ary_push(ary, RBASIC(p)->class); + ary_push(ary, RBASIC(p)->klass); } } return ary; @@ -270,7 +270,7 @@ mod_ancestors(mod) if (FL_TEST(p, FL_SINGLETON)) continue; if (BUILTIN_TYPE(p) == T_ICLASS) { - ary_push(ary, RBASIC(p)->class); + ary_push(ary, RBASIC(p)->klass); } else { ary_push(ary, p); @@ -453,12 +453,12 @@ rb_singleton_class(obj) if (rb_special_const_p(obj)) { TypeError("cannot define singleton"); } - if (FL_TEST(RBASIC(obj)->class, FL_SINGLETON)) { - return (VALUE)RBASIC(obj)->class; + if (FL_TEST(RBASIC(obj)->klass, FL_SINGLETON)) { + return RBASIC(obj)->klass; } - RBASIC(obj)->class = singleton_class_new(RBASIC(obj)->class); - singleton_class_attached(RBASIC(obj)->class, obj); - return RBASIC(obj)->class; + RBASIC(obj)->klass = singleton_class_new(RBASIC(obj)->klass); + singleton_class_attached(RBASIC(obj)->klass, obj); + return RBASIC(obj)->klass; } void @@ -356,6 +356,25 @@ enum_length(obj) return INT2FIX(length); } +each_with_index_i(val, indexp) + VALUE val; + int *indexp; +{ + rb_yield(assoc_new(val, INT2FIX(*indexp))); + (*indexp)++; + return Qnil; +} + +VALUE +enum_each_with_index(obj) + VALUE obj; +{ + int index = 0; + + rb_iterate(rb_each, obj, each_with_index_i, (VALUE)&index); + return Qnil; +} + void Init_Enumerable() { @@ -376,6 +395,7 @@ Init_Enumerable() rb_define_method(mEnumerable,"include?", enum_member, 1); rb_define_method(mEnumerable,"length", enum_length, 0); rb_define_method(mEnumerable,"size", enum_length, 0); + rb_define_method(mEnumerable,"each_with_index", enum_each_with_index, 0); id_eqq = rb_intern("==="); id_each = rb_intern("each"); @@ -52,7 +52,7 @@ static void f_END _((void)); struct cache_entry { /* method hash table. */ ID mid; /* method's id */ ID mid0; /* method's original id */ - VALUE class; /* receiver's class */ + VALUE klass; /* receiver's class */ VALUE origin; /* where method defined */ NODE *method; int noex; @@ -88,80 +88,80 @@ rb_clear_cache_by_id(id) } void -rb_add_method(class, mid, node, noex) - VALUE class; +rb_add_method(klass, mid, node, noex) + VALUE klass; ID mid; NODE *node; int noex; { NODE *body; - if (NIL_P(class)) class = cObject; + if (NIL_P(klass)) klass = cObject; body = NEW_METHOD(node, noex); - st_insert(RCLASS(class)->m_tbl, mid, body); + st_insert(RCLASS(klass)->m_tbl, mid, body); } void -rb_remove_method(class, mid) - VALUE class; +rb_remove_method(klass, mid) + VALUE klass; ID mid; { NODE *body; - if (!st_delete(RCLASS(class)->m_tbl, &mid, &body)) { + if (!st_delete(RCLASS(klass)->m_tbl, &mid, &body)) { NameError("method `%s' not defined in %s", - rb_id2name(mid), rb_class2name(class)); + rb_id2name(mid), rb_class2name(klass)); } rb_clear_cache_by_id(mid); } static NODE* -search_method(class, id, origin) - VALUE class, *origin; +search_method(klass, id, origin) + VALUE klass, *origin; ID id; { NODE *body; - while (!st_lookup(RCLASS(class)->m_tbl, id, &body)) { - class = (VALUE)RCLASS(class)->super; - if (!class) return 0; + while (!st_lookup(RCLASS(klass)->m_tbl, id, &body)) { + klass = RCLASS(klass)->super; + if (!klass) return 0; } - if (origin) *origin = class; + if (origin) *origin = klass; return body; } static NODE* -rb_get_method_body(classp, idp, noexp) - VALUE *classp; +rb_get_method_body(klassp, idp, noexp) + VALUE *klassp; ID *idp; int *noexp; { ID id = *idp; - VALUE class = *classp; + VALUE klass = *klassp; VALUE origin; NODE *body; struct cache_entry *ent; - if ((body = search_method(class, id, &origin)) == 0) { + if ((body = search_method(klass, id, &origin)) == 0) { return 0; } if (!body->nd_body) return 0; /* store in cache */ - ent = cache + EXPR1(class, id); - ent->class = class; + ent = cache + EXPR1(klass, id); + ent->klass = klass; ent->noex = body->nd_noex; body = body->nd_body; if (nd_type(body) == NODE_FBODY) { ent->mid = id; - *classp = body->nd_orig; + *klassp = body->nd_orig; ent->origin = body->nd_orig; *idp = ent->mid0 = body->nd_mid; body = ent->method = body->nd_head; } else { - *classp = (VALUE)origin; + *klassp = origin; ent->origin = origin; ent->mid = ent->mid0 = id; ent->method = body; @@ -172,23 +172,23 @@ rb_get_method_body(classp, idp, noexp) } void -rb_alias(class, name, def) - VALUE class; +rb_alias(klass, name, def) + VALUE klass; ID name, def; { VALUE origin; NODE *orig, *body; if (name == def) return; - orig = search_method(class, def, &origin); + orig = search_method(klass, def, &origin); if (!orig || !orig->nd_body) { - if (TYPE(class) == T_MODULE) { + if (TYPE(klass) == T_MODULE) { orig = search_method(cObject, def, &origin); } } if (!orig || !orig->nd_body) { NameError("undefined method `%s' for `%s'", - rb_id2name(def), rb_class2name((VALUE)class)); + rb_id2name(def), rb_class2name(klass)); } body = orig->nd_body; if (nd_type(body) == NODE_FBODY) { /* was alias */ @@ -197,47 +197,47 @@ rb_alias(class, name, def) origin = body->nd_orig; } - st_insert(RCLASS(class)->m_tbl, name, + st_insert(RCLASS(klass)->m_tbl, name, NEW_METHOD(NEW_FBODY(body, def, origin), orig->nd_noex)); } static void -rb_export_method(class, name, noex) - VALUE class; +rb_export_method(klass, name, noex) + VALUE klass; ID name; int noex; { NODE *body; - struct RClass *origin; + VALUE origin; - body = search_method(class, name, &origin); - if (!body && TYPE(class) == T_MODULE) { + body = search_method(klass, name, &origin); + if (!body && TYPE(klass) == T_MODULE) { body = search_method(cObject, name, &origin); } if (!body) { NameError("undefined method `%s' for `%s'", - rb_id2name(name), rb_class2name(class)); + rb_id2name(name), rb_class2name(klass)); } if (body->nd_noex != noex) { - if (class == (VALUE)origin) { + if (klass == origin) { body->nd_noex = noex; } else { rb_clear_cache_by_id(name); - rb_add_method(class, name, NEW_ZSUPER(), noex); + rb_add_method(klass, name, NEW_ZSUPER(), noex); } } } static VALUE -method_boundp(class, id, ex) - VALUE class; +method_boundp(klass, id, ex) + VALUE klass; ID id; int ex; { int noex; - if (rb_get_method_body(&class, &id, &noex)) { + if (rb_get_method_body(&klass, &id, &noex)) { if (ex && noex == NOEX_PRIVATE) return FALSE; return TRUE; @@ -246,12 +246,12 @@ method_boundp(class, id, ex) } int -rb_method_boundp(class, id, ex) - VALUE class; +rb_method_boundp(klass, id, ex) + VALUE klass; ID id; int ex; { - if (method_boundp(class, id, ex)) + if (method_boundp(klass, id, ex)) return TRUE; return FALSE; } @@ -299,7 +299,7 @@ struct BLOCK { VALUE self; struct FRAME frame; struct SCOPE *scope; - VALUE class; + VALUE klass; struct tag *tag; int iter; struct RVarmap *d_vars; @@ -316,7 +316,7 @@ struct BLOCK { _block.body = b; \ _block.self = self; \ _block.frame = *the_frame; \ - _block.class = the_class; \ + _block.klass = the_class; \ _block.frame.file = sourcefile; \ _block.frame.line = sourceline; \ _block.scope = the_scope; \ @@ -733,13 +733,14 @@ ruby_options(argc, argv) PUSH_TAG(PROT_NONE) if ((state = EXEC_TAG()) == 0) { + NODE *save; ruby_process_options(argc, argv); - Init_ext(); - ext_init = 1; - ruby_require_modules(); + ext_init = 1; /* Init_ext() called in ruby_process_options */ + save = eval_tree; eval_tree = 0; - ruby_load_script(); + ruby_require_modules(); + eval_tree = save; } POP_TAG(); if (state) { @@ -1012,10 +1013,10 @@ ev_const_defined(cref, id) NODE *cbase = cref; while (cbase && cbase->nd_clss != cObject) { - struct RClass *class = RCLASS(cbase->nd_clss); + struct RClass *klass = RCLASS(cbase->nd_clss); - if (class->iv_tbl && - st_lookup(class->iv_tbl, id, 0)) { + if (klass->iv_tbl && + st_lookup(klass->iv_tbl, id, 0)) { return TRUE; } cbase = cbase->nd_next; @@ -1032,10 +1033,10 @@ ev_const_get(cref, id) VALUE result; while (cbase && cbase->nd_clss != cObject) { - struct RClass *class = RCLASS(cbase->nd_clss); + struct RClass *klass = RCLASS(cbase->nd_clss); - if (class->iv_tbl && - st_lookup(class->iv_tbl, id, &result)) { + if (klass->iv_tbl && + st_lookup(klass->iv_tbl, id, &result)) { return result; } cbase = cbase->nd_next; @@ -1091,12 +1092,12 @@ mod_undef_method(mod, name) } static VALUE -mod_alias_method(mod, new, old) - VALUE mod, new, old; +mod_alias_method(mod, newname, oldname) + VALUE mod, newname, oldname; { - ID id = rb_to_id(new); + ID id = rb_to_id(newname); - rb_alias(mod, id, rb_to_id(old)); + rb_alias(mod, id, rb_to_id(oldname)); rb_clear_cache_by_id(id); return mod; } @@ -1821,7 +1822,7 @@ rb_eval(self, node) PUSH_SCOPE(); PUSH_TAG(PROT_NONE); - if (node->nd_rval) the_frame->cbase = (VALUE)node->nd_rval; + if (node->nd_rval) the_frame->cbase = node->nd_rval; if (node->nd_tbl) { VALUE *vars = ALLOCA_N(VALUE, node->nd_tbl[0]+1); *vars++ = (VALUE)node; @@ -1953,18 +1954,18 @@ rb_eval(self, node) case NODE_COLON2: { - VALUE cls; + VALUE klass; - cls = rb_eval(self, node->nd_head); - switch (TYPE(cls)) { + klass = rb_eval(self, node->nd_head); + switch (TYPE(klass)) { case T_CLASS: case T_MODULE: break; default: - Check_Type(cls, T_CLASS); + Check_Type(klass, T_CLASS); break; } - result = rb_const_get_at(cls, node->nd_mid); + result = rb_const_get_at(klass, node->nd_mid); } break; @@ -2109,7 +2110,7 @@ rb_eval(self, node) body = search_method(the_class, node->nd_mid, &origin); if (body) { - if (origin == (VALUE)the_class) { + if (origin == the_class) { Warning("discarding old %s", rb_id2name(node->nd_mid)); } rb_clear_cache_by_id(node->nd_mid); @@ -2144,7 +2145,7 @@ rb_eval(self, node) case NODE_DEFS: if (node->nd_defn) { VALUE recv = rb_eval(self, node->nd_recv); - VALUE class; + VALUE klass; NODE *body; if (FIXNUM_P(recv)) { @@ -2160,12 +2161,12 @@ rb_eval(self, node) rb_id2name(node->nd_mid)); } - class = rb_singleton_class(recv); - if (st_lookup(RCLASS(class)->m_tbl, node->nd_mid, &body)) { + klass = rb_singleton_class(recv); + if (st_lookup(RCLASS(klass)->m_tbl, node->nd_mid, &body)) { Warning("redefine %s", rb_id2name(node->nd_mid)); } rb_clear_cache_by_id(node->nd_mid); - rb_add_method(class, node->nd_mid, node->nd_defn, NOEX_PUBLIC); + rb_add_method(klass, node->nd_mid, node->nd_defn, NOEX_PUBLIC); rb_funcall(recv, rb_intern("singleton_method_added"), 1, INT2FIX(node->nd_mid)); result = Qnil; @@ -2180,7 +2181,7 @@ rb_eval(self, node) body = search_method(the_class, node->nd_mid, &origin); if (!body || !body->nd_body) { NameError("undefined method `%s' for class `%s'", - rb_id2name(node->nd_mid), rb_class2name((VALUE)the_class)); + rb_id2name(node->nd_mid), rb_class2name(the_class)); } rb_clear_cache_by_id(node->nd_mid); rb_add_method(the_class, node->nd_mid, 0, NOEX_PUBLIC); @@ -2202,7 +2203,7 @@ rb_eval(self, node) case NODE_CLASS: { - VALUE super, class, tmp; + VALUE super, klass, tmp; if (node->nd_super) { super = superclass(self, node->nd_super); @@ -2212,15 +2213,15 @@ rb_eval(self, node) } if (rb_const_defined_at(the_class, node->nd_cname) && - ((VALUE)the_class != cObject || + (the_class != cObject || !rb_autoload_defined(node->nd_cname))) { - class = rb_const_get_at(the_class, node->nd_cname); - if (TYPE(class) != T_CLASS) { + klass = rb_const_get_at(the_class, node->nd_cname); + if (TYPE(klass) != T_CLASS) { TypeError("%s is not a class", rb_id2name(node->nd_cname)); } if (super) { - tmp = RCLASS(class)->super; + tmp = RCLASS(klass)->super; if (FL_TEST(tmp, FL_SINGLETON)) { tmp = RCLASS(tmp)->super; } @@ -2239,12 +2240,12 @@ rb_eval(self, node) } else { if (!super) super = cObject; - class = rb_define_class_id(node->nd_cname, super); - rb_const_set(the_class, node->nd_cname, class); - rb_set_class_path(class,the_class,rb_id2name(node->nd_cname)); + klass = rb_define_class_id(node->nd_cname, super); + rb_const_set(the_class, node->nd_cname, klass); + rb_set_class_path(klass,the_class,rb_id2name(node->nd_cname)); } - return module_setup(class, node->nd_body); + return module_setup(klass, node->nd_body); } break; @@ -2253,7 +2254,7 @@ rb_eval(self, node) VALUE module; if (rb_const_defined_at(the_class, node->nd_cname) && - ((VALUE)the_class != cObject || + (the_class != cObject || !rb_autoload_defined(node->nd_cname))) { module = rb_const_get_at(the_class, node->nd_cname); @@ -2276,24 +2277,24 @@ rb_eval(self, node) case NODE_SCLASS: { - VALUE class; + VALUE klass; - class = rb_eval(self, node->nd_recv); - if (FIXNUM_P(class)) { + klass = rb_eval(self, node->nd_recv); + if (FIXNUM_P(klass)) { TypeError("No virtual class for Fixnums"); } - if (NIL_P(class)) { + if (NIL_P(klass)) { TypeError("No virtual class for nil"); } - if (rb_special_const_p(class)) { + if (rb_special_const_p(klass)) { TypeError("No virtual class for special constants"); } - if (FL_TEST(CLASS_OF(class), FL_SINGLETON)) { + if (FL_TEST(CLASS_OF(klass), FL_SINGLETON)) { rb_clear_cache(); } - class = rb_singleton_class(class); + klass = rb_singleton_class(klass); - result = module_setup(class, node->nd_body); + result = module_setup(klass, node->nd_body); } break; @@ -2364,7 +2365,7 @@ module_setup(module, node) call_trace_func("class", file, line, the_class, the_frame->last_func); } - result = rb_eval((VALUE)the_class, node->nd_body); + result = rb_eval(the_class, node->nd_body); } POP_TAG(); POP_SCOPE(); @@ -2624,7 +2625,7 @@ rb_yield_0(val, self) the_scope = block->scope; the_block = block->prev; the_dyna_vars = block->d_vars; - the_class = block->class; + the_class = block->klass; if (!self) self = block->self; node = block->body; if (block->var) { @@ -3033,8 +3034,8 @@ stack_length() } static VALUE -rb_call(class, recv, mid, argc, argv, scope) - VALUE class, recv; +rb_call(klass, recv, mid, argc, argv, scope) + VALUE klass, recv; ID mid; int argc; /* OK */ VALUE *argv; /* OK */ @@ -3052,14 +3053,14 @@ rb_call(class, recv, mid, argc, argv, scope) again: /* is it in the method cache? */ - ent = cache + EXPR1(class, mid); - if (ent->mid == mid && ent->class == class) { - class = ent->origin; + ent = cache + EXPR1(klass, mid); + if (ent->mid == mid && ent->klass == klass) { + klass = ent->origin; id = ent->mid0; noex = ent->noex; body = ent->method; } - else if ((body = rb_get_method_body(&class, &id, &noex)) == 0) { + else if ((body = rb_get_method_body(&klass, &id, &noex)) == 0) { return rb_undefined(recv, mid, argc, argv, scope==2?CSTAT_VCALL:0); } @@ -3082,19 +3083,19 @@ rb_call(class, recv, mid, argc, argv, scope) /* for re-scoped/renamed method */ mid = id; if (scope == 0) scope = 1; - if (RCLASS(class)->super == 0) { + if (RCLASS(klass)->super == 0) { /* origin is the Module, so need to scan superclass hierarchy. */ - struct RClass *cl = RCLASS(class); + struct RClass *cl = RCLASS(klass); - class = RBASIC(recv)->class; - while (class) { - if (RCLASS(class)->m_tbl == cl->m_tbl) + klass = RBASIC(recv)->klass; + while (klass) { + if (RCLASS(klass)->m_tbl == cl->m_tbl) break; - class = RCLASS(class)->super; + klass = RCLASS(klass)->super; } } else { - class = RCLASS(class)->super; + klass = RCLASS(klass)->super; } goto again; } @@ -3105,7 +3106,7 @@ rb_call(class, recv, mid, argc, argv, scope) PUSH_ITER(itr); PUSH_FRAME(); the_frame->last_func = id; - the_frame->last_class = class; + the_frame->last_class = klass; the_frame->argc = argc; the_frame->argv = argv; @@ -3212,7 +3213,7 @@ rb_call(class, recv, mid, argc, argv, scope) default: if (len < 0) { Bug("bad argc(%d) specified for `%s(%s)'", - len, rb_class2name((VALUE)class), rb_id2name(mid)); + len, rb_class2name(klass), rb_id2name(mid)); } else { ArgError("too many arguments(%d)", len); @@ -3584,7 +3585,7 @@ eval(self, src, scope) rb_in_eval++; if (TYPE(the_class) == T_ICLASS) { - the_class = RBASIC(the_class)->class; + the_class = RBASIC(the_class)->klass; } PUSH_TAG(PROT_NONE); if ((state = EXEC_TAG()) == 0) { @@ -4075,17 +4076,17 @@ mod_include(argc, argv, module) } VALUE -class_new_instance(argc, argv, class) +class_new_instance(argc, argv, klass) int argc; VALUE *argv; - VALUE class; + VALUE klass; { VALUE obj; - if (FL_TEST(class, FL_SINGLETON)) { + if (FL_TEST(klass, FL_SINGLETON)) { TypeError("can't create instance of virtual class"); } - obj = obj_alloc(class); + obj = obj_alloc(klass); PUSH_ITER(iterator_p()?ITER_PRE:ITER_NOT); rb_funcall2(obj, init, argc, argv); POP_ITER(); @@ -4369,8 +4370,8 @@ f_binding(self) #define PROC_TMASK (FL_USER1|FL_USER2) static VALUE -proc_s_new(class) - VALUE class; +proc_s_new(klass) + VALUE klass; { volatile VALUE proc; struct BLOCK *data; @@ -4379,7 +4380,7 @@ proc_s_new(class) ArgError("tryed to create Procedure-Object out of iterator"); } - proc = Data_Make_Struct(class, struct BLOCK, blk_mark, blk_free, data); + proc = Data_Make_Struct(klass, struct BLOCK, blk_mark, blk_free, data); *data = *the_block; #ifdef THREAD @@ -4414,6 +4415,22 @@ f_lambda() return proc_s_new(cProc); } +static int +blk_orphan(data) + struct BLOCK *data; +{ + if (data->scope && data->scope != top_scope && + (data->scope->flag & SCOPE_NOSTACK)) { + return 1; + } +#ifdef THREAD + if (data->orig_thread != thread_current()) { + return 1; + } +#endif + return 0; +} + static VALUE proc_call(proc, args) VALUE proc, args; /* OK */ @@ -4436,32 +4453,22 @@ proc_call(proc, args) } Data_Get_Struct(proc, struct BLOCK, data); + orphan = blk_orphan(data); + + /* PUSH BLOCK from data */ + PUSH_BLOCK2(data); + PUSH_ITER(ITER_CUR); + the_frame->iter = ITER_CUR; - if (data->scope && (data->scope->flag & SCOPE_NOSTACK)) { - orphan = 1; - } - else { -#ifdef THREAD - if (data->orig_thread != thread_current()) { - orphan = 1; - } - else -#endif - orphan = 0; - } if (orphan) {/* orphan procedure */ if (iterator_p()) { - data->frame.iter = ITER_CUR; + the_block->frame.iter = ITER_CUR; } else { - data->frame.iter = ITER_NOT; + the_block->frame.iter = ITER_NOT; } } - /* PUSH BLOCK from data */ - PUSH_BLOCK2(data); - PUSH_ITER(ITER_CUR); - the_frame->iter = ITER_CUR; if (FL_TEST(proc, PROC_TAINT)) { switch (RBASIC(proc)->flags & PROC_TMASK) { case PROC_T3: @@ -4509,6 +4516,76 @@ proc_call(proc, args) return result; } +static VALUE +proc_iterate(proc) + VALUE proc; +{ + VALUE lambda = f_lambda(); + struct BLOCK *data; + volatile VALUE result = Qnil; + int state; + volatile int orphan; + volatile int safe = safe_level; + + Data_Get_Struct(lambda, struct BLOCK, data); + data->frame.iter = ITER_PRE; + data->iter = ITER_PRE; + + Data_Get_Struct(proc, struct BLOCK, data); + orphan = blk_orphan(data); + + /* PUSH BLOCK from data */ + PUSH_BLOCK2(data); + PUSH_ITER(ITER_PRE); + the_frame->iter = ITER_PRE; + if (FL_TEST(proc, PROC_TAINT)) { + switch (RBASIC(proc)->flags & PROC_TMASK) { + case PROC_T3: + safe_level = 3; + break; + case PROC_T4: + safe_level = 4; + break; + case PROC_T5: + safe_level = 5; + break; + } + } + + PUSH_TAG(PROT_NONE); + state = EXEC_TAG(); + if (state == 0) { + result = proc_call(lambda, Qnil); + } + POP_TAG(); + + POP_ITER(); + if (the_block->tag->dst == state) { + state &= TAG_MASK; + orphan = 2; + } + POP_BLOCK(); + safe_level = safe; + + if (state) { + if (orphan == 2) {/* escape from orphan procedure */ + switch (state) { + case TAG_BREAK: + Raise(eLocalJumpError, "break from proc-closure"); + break; + case TAG_RETRY: + Raise(eLocalJumpError, "retry from proc-closure"); + break; + case TAG_RETURN: + Raise(eLocalJumpError, "return from proc-closure"); + break; + } + } + JUMP_TAG(state); + } + return result; +} + void Init_Proc() { @@ -4518,6 +4595,7 @@ Init_Proc() rb_define_singleton_method(cProc, "new", proc_s_new, 0); rb_define_method(cProc, "call", proc_call, -2); + rb_define_method(cProc, "iterate", proc_iterate, 0); rb_define_global_function("proc", f_lambda, 0); rb_define_global_function("lambda", f_lambda, 0); rb_define_global_function("binding", f_binding, 0); @@ -4584,7 +4662,7 @@ struct thread { struct BLOCK *block; struct iter *iter; struct tag *tag; - VALUE class; + VALUE klass; VALUE trace; @@ -4729,7 +4807,7 @@ thread_save_context(th) th->frame = the_frame; th->scope = the_scope; - th->class = the_class; + th->klass = the_class; th->dyna_vars = the_dyna_vars; th->block = the_block; th->iter = the_iter; @@ -4786,12 +4864,11 @@ thread_restore_context(th, exit) the_frame = th->frame; the_scope = th->scope; - the_class = th->class; + the_class = th->klass; the_dyna_vars = th->dyna_vars; the_block = th->block; the_iter = th->iter; prot_tag = th->tag; - the_class = th->class; errat = th->errat; errinfo = th->errinfo; last_status = th->last_status; @@ -5398,7 +5475,7 @@ thread_alloc() th->frame = 0; th->scope = 0; - th->class = 0; + th->klass = 0; th->dyna_vars = 0; th->block = 0; th->iter = 0; diff --git a/ext/dbm/dbm.c b/ext/dbm/dbm.c index b416802241..2941877dd6 100644 --- a/ext/dbm/dbm.c +++ b/ext/dbm/dbm.c @@ -122,19 +122,19 @@ fdbm_fetch(obj, keystr) } static VALUE -fdbm_indexes(obj, ag) - VALUE obj, ag; +fdbm_indexes(argc, argv, obj) + int argc; + VALUE *argv; + VALUE obj; { - VALUE *p, *pend; VALUE new; - int i = 0; - struct RArray *args = RARRAY(rb_Array(ag)); + int i; - new = ary_new2(args->len); - p = args->ptr; pend = p + args->len; - while (p < pend) { - ary_push(new, fdbm_fetch(obj, *p++)); + new = ary_new2(argc); + for (i=0; i<argc; i++) { + ary_push(new, fdbm_fetch(obj, argv[i])); } + return new; } @@ -489,7 +489,8 @@ Init_dbm() rb_define_method(cDBM, "close", fdbm_close, 0); rb_define_method(cDBM, "[]", fdbm_fetch, 1); rb_define_method(cDBM, "[]=", fdbm_store, 2); - rb_define_method(cDBM, "indexes", fdbm_indexes, -2); + rb_define_method(cDBM, "indexes", fdbm_indexes, -1); + rb_define_method(cDBM, "indices", fdbm_indexes, -1); rb_define_method(cDBM, "length", fdbm_length, 0); rb_define_alias(cDBM, "size", "length"); rb_define_method(cDBM, "empty?", fdbm_empty_p, 0); diff --git a/ext/fcntl/fcntl.c b/ext/fcntl/fcntl.c index 17aacb13c3..186f9ac893 100644 --- a/ext/fcntl/fcntl.c +++ b/ext/fcntl/fcntl.c @@ -5,7 +5,7 @@ $Author$ created at: Mon Apr 7 18:53:05 JST 1997 - Copyright (C) 1997 Yukihiro Matsumoto + Copyright (C) 1997-1998 Yukihiro Matsumoto ************************************************/ @@ -77,10 +77,10 @@ file_open(fname, mode) } static VALUE -file_s_open(argc, argv, class) +file_s_open(argc, argv, klass) int argc; VALUE *argv; - VALUE class; + VALUE klass; { VALUE fname, vmode, file; char *mode; @@ -96,7 +96,7 @@ file_s_open(argc, argv, class) } file = file_open(RSTRING(fname)->ptr, mode); - RBASIC(file)->class = class; + RBASIC(file)->klass = klass; if (iterator_p()) { rb_ensure(rb_yield, file, io_close, file); } @@ -185,7 +185,7 @@ file_tell(obj) long pos; GetOpenFile(obj, fptr); - + io_check_closed(fptr); pos = ftell(fptr->f); if (ferror(fptr->f) != 0) rb_sys_fail(0); @@ -200,7 +200,7 @@ file_seek(obj, offset, ptrname) long pos; GetOpenFile(obj, fptr); - + io_check_closed(fptr); pos = fseek(fptr->f, NUM2INT(offset), NUM2INT(ptrname)); if (pos != 0) rb_sys_fail(0); clearerr(fptr->f); @@ -216,6 +216,7 @@ file_set_pos(obj, offset) long pos; GetOpenFile(obj, fptr); + io_check_closed(fptr); pos = fseek(fptr->f, NUM2INT(offset), 0); if (pos != 0) rb_sys_fail(0); clearerr(fptr->f); @@ -230,6 +231,7 @@ file_rewind(obj) OpenFile *fptr; GetOpenFile(obj, fptr); + io_check_closed(fptr); if (fseek(fptr->f, 0L, 0) != 0) rb_sys_fail(0); clearerr(fptr->f); @@ -243,6 +245,7 @@ file_eof(obj) OpenFile *fptr; GetOpenFile(obj, fptr); + io_check_closed(fptr); if (feof(fptr->f) == 0) return FALSE; return TRUE; } @@ -254,16 +257,10 @@ file_path(obj) OpenFile *fptr; GetOpenFile(obj, fptr); + if (fptr->path == NULL) return Qnil; return str_new2(fptr->path); } -static VALUE -file_isatty(obj) - VALUE obj; -{ - return FALSE; -} - #include <sys/types.h> #ifndef NT #include <sys/file.h> @@ -379,6 +376,7 @@ file_lstat(obj) struct stat st; GetOpenFile(obj, fptr); + io_check_closed(fptr); if (lstat(fptr->path, &st) == -1) { rb_sys_fail(fptr->path); } @@ -938,6 +936,7 @@ file_chmod(obj, vmode) GetOpenFile(obj, fptr); #if defined(DJGPP) || defined(__CYGWIN32__) || defined(NT) + io_check_closed(fptr); if (chmod(fptr->path, mode) == -1) rb_sys_fail(fptr->path); #else @@ -997,6 +996,7 @@ file_chown(obj, owner, group) rb_secure(2); GetOpenFile(obj, fptr); #if defined(DJGPP) || defined(__CYGWIN32__) || defined(NT) + io_check_closed(fptr); if (chown(fptr->path, NUM2INT(owner), NUM2INT(group)) == -1) rb_sys_fail(fptr->path); #else @@ -1315,7 +1315,7 @@ file_s_basename(argc, argv) f = rmext(RSTRING(fname)->ptr, RSTRING(ext)->ptr); if (f) return str_new(RSTRING(fname)->ptr, f); } - return (VALUE)fname; + return fname; } p++; /* skip last `/' */ if (!NIL_P(ext)) { @@ -1688,12 +1688,11 @@ Init_File() rb_define_method(cFile, "tell", file_tell, 0); rb_define_method(cFile, "seek", file_seek, 2); + rb_define_method(cFile, "rewind", file_rewind, 0); + rb_define_method(cFile, "pos", file_tell, 0); rb_define_method(cFile, "pos=", file_set_pos, 1); - rb_define_method(cFile, "rewind", file_rewind, 0); - rb_define_method(cFile, "isatty", file_isatty, 0); - rb_define_method(cFile, "tty?", file_isatty, 0); rb_define_method(cFile, "eof", file_eof, 0); rb_define_method(cFile, "eof?", file_eof, 0); @@ -173,7 +173,7 @@ typedef struct RVALUE { } free; struct RBasic basic; struct RObject object; - struct RClass class; + struct RClass klass; struct RFloat flonum; struct RString string; struct RArray array; @@ -249,14 +249,14 @@ rb_newobj() } VALUE -data_object_alloc(class, datap, dmark, dfree) - VALUE class; +data_object_alloc(klass, datap, dmark, dfree) + VALUE klass; void *datap; void (*dfree)(); void (*dmark)(); { NEWOBJ(data, struct RData); - OBJSETUP(data, class, T_DATA); + OBJSETUP(data, klass, T_DATA); data->data = datap; data->dfree = dfree; data->dmark = dmark; @@ -466,19 +466,19 @@ gc_mark(ptr) return; /* no need to mark class. */ } - gc_mark(obj->as.basic.class); + gc_mark(obj->as.basic.klass); switch (obj->as.basic.flags & T_MASK) { case T_ICLASS: - gc_mark(obj->as.class.super); - mark_tbl(obj->as.class.iv_tbl); - mark_tbl(obj->as.class.m_tbl); + gc_mark(obj->as.klass.super); + mark_tbl(obj->as.klass.iv_tbl); + mark_tbl(obj->as.klass.m_tbl); break; case T_CLASS: case T_MODULE: - gc_mark(obj->as.class.super); - mark_tbl(obj->as.class.m_tbl); - mark_tbl(obj->as.class.iv_tbl); + gc_mark(obj->as.klass.super); + mark_tbl(obj->as.klass.m_tbl); + mark_tbl(obj->as.klass.iv_tbl); break; case T_ARRAY: @@ -644,7 +644,7 @@ obj_free(obj) case T_MODULE: case T_CLASS: rb_clear_cache(); - st_free_table(RANY(obj)->as.class.m_tbl); + st_free_table(RANY(obj)->as.klass.m_tbl); if (RANY(obj)->as.object.iv_tbl) { st_free_table(RANY(obj)->as.object.iv_tbl); } @@ -179,7 +179,7 @@ hash_foreach(hash, func, farg) arg.hash = hash; arg.func = func; arg.arg = farg; - return rb_ensure(hash_foreach_call, (VALUE)&arg, hash_foreach_ensure, (VALUE)hash); + return rb_ensure(hash_foreach_call, (VALUE)&arg, hash_foreach_ensure, hash); } static VALUE @@ -307,7 +307,7 @@ hash_rehash(hash) RHASH(hash)->tbl = tbl; if (RHASH(hash)->iter_lev > 0) RHASH(hash)->status |= HASH_REHASHED; - return (VALUE)hash; + return hash; } VALUE @@ -405,7 +405,7 @@ hash_delete_if(hash) hash_modify(hash); hash_foreach(hash, delete_if_i, 0); - return (VALUE)hash; + return hash; } static int @@ -422,7 +422,7 @@ hash_clear(hash) hash_modify(hash); st_foreach(RHASH(hash)->tbl, clear_i); - return (VALUE)hash; + return hash; } VALUE @@ -441,6 +441,25 @@ hash_aset(hash, key, val) return val; } +static int +replace_i(key, val, hash) + VALUE key, val, hash; +{ + hash_aset(hash, key, val); + return ST_CONTINUE; +} + +static VALUE +hash_replace(hash, hash2) + VALUE hash, hash2; +{ + Check_Type(hash2, T_HASH); + hash_clear(hash); + st_foreach(RHASH(hash2)->tbl, replace_i, hash); + + return hash; +} + static VALUE hash_length(hash) VALUE hash; @@ -471,7 +490,7 @@ hash_each_value(hash) VALUE hash; { hash_foreach(hash, each_value_i); - return (VALUE)hash; + return hash; } static int @@ -488,7 +507,7 @@ hash_each_key(hash) VALUE hash; { hash_foreach(hash, each_key_i); - return (VALUE)hash; + return hash; } static int @@ -505,7 +524,7 @@ hash_each_pair(hash) VALUE hash; { hash_foreach(hash, each_pair_i); - return (VALUE)hash; + return hash; } static int @@ -1095,6 +1114,7 @@ Init_Hash() rb_define_method(cHash,"[]", hash_aref, 1); rb_define_method(cHash,"[]=", hash_aset, 2); rb_define_method(cHash,"indexes", hash_indexes, -1); + rb_define_method(cHash,"indices", hash_indexes, -1); rb_define_method(cHash,"length", hash_length, 0); rb_define_alias(cHash, "size", "length"); rb_define_method(cHash,"empty?", hash_empty_p, 0); @@ -1113,6 +1133,7 @@ Init_Hash() rb_define_method(cHash,"clear", hash_clear, 0); rb_define_method(cHash,"invert", hash_invert, 0); rb_define_method(cHash,"update", hash_update, 1); + rb_define_method(cHash,"replace", hash_replace, 1); rb_define_method(cHash,"include?", hash_has_key, 1); rb_define_method(cHash,"has_key?", hash_has_key, 1); @@ -1135,6 +1156,7 @@ Init_Hash() rb_define_singleton_method(envtbl,"rehash", env_none, 0); rb_define_singleton_method(envtbl,"to_a", env_to_a, 0); rb_define_singleton_method(envtbl,"indexes", env_indexes, -1); + rb_define_singleton_method(envtbl,"indices", env_indexes, -1); rb_define_singleton_method(envtbl,"length", env_size, 0); rb_define_singleton_method(envtbl,"empty?", env_empty_p, 0); rb_define_singleton_method(envtbl,"keys", env_keys, 0); @@ -108,27 +108,31 @@ eof_error() } void -io_writable(fptr) +io_check_closed(fptr) OpenFile *fptr; { - if (!(fptr->mode & FMODE_WRITABLE)) { - Raise(eIOError, "not opened for writing"); - } + if (fptr->f == NULL) + Raise(eIOError, "closed stream"); } void io_readable(fptr) OpenFile *fptr; { + io_check_closed(fptr); if (!(fptr->mode & FMODE_READABLE)) { Raise(eIOError, "not opened for reading"); } } -static void -closed() +void +io_writable(fptr) + OpenFile *fptr; { - Raise(eIOError, "closed stream"); + io_check_closed(fptr); + if (!(fptr->mode & FMODE_WRITABLE)) { + Raise(eIOError, "not opened for writing"); + } } /* writing functions */ @@ -153,7 +157,6 @@ io_write(io, str) io_writable(fptr); f = GetWriteFile(fptr); - if (f == NULL) closed(); #ifdef __human68k__ { @@ -197,7 +200,6 @@ io_flush(io) GetOpenFile(io, fptr); io_writable(fptr); f = GetWriteFile(fptr); - if (f == NULL) closed(); if (fflush(f) == EOF) rb_sys_fail(0); @@ -213,7 +215,6 @@ io_eof(io) GetOpenFile(io, fptr); io_readable(fptr); - if (fptr->f == NULL) closed(); if (READ_DATA_PENDING(fptr->f)) return FALSE; if (feof(fptr->f)) return TRUE; @@ -289,7 +290,6 @@ read_all(port) GetOpenFile(port, fptr); io_readable(fptr); - if (fptr->f == NULL) closed(); if (fstat(fileno(fptr->f), &st) == 0 && S_ISREG(st.st_mode)) { if (st.st_size == 0) return Qnil; @@ -335,7 +335,6 @@ io_read(argc, argv, io) len = NUM2INT(length); GetOpenFile(io, fptr); io_readable(fptr); - if (fptr->f == NULL) closed(); str = str_new(0, len); @@ -379,7 +378,6 @@ io_gets_method(argc, argv, io) GetOpenFile(io, fptr); io_readable(fptr); f = fptr->f; - if (f == NULL) closed(); if (!NIL_P(rs)) { rslen = RSTRING(rs)->len; @@ -546,7 +544,6 @@ io_each_byte(io) GetOpenFile(io, fptr); io_readable(fptr); f = fptr->f; - if (f == NULL) closed(); for (;;) { READ_CHECK(f); @@ -571,7 +568,6 @@ io_getc(io) GetOpenFile(io, fptr); io_readable(fptr); f = fptr->f; - if (f == NULL) closed(); READ_CHECK(f); TRAP_BEG; @@ -606,7 +602,6 @@ io_ungetc(io, c) Check_Type(c, T_FIXNUM); GetOpenFile(io, fptr); io_readable(fptr); - if (fptr->f == NULL) closed(); if (ungetc(FIX2INT(c), fptr->f) == EOF) rb_sys_fail(fptr->path); @@ -620,7 +615,7 @@ io_isatty(io) OpenFile *fptr; GetOpenFile(io, fptr); - if (fptr->f == NULL) closed(); + io_check_closed(fptr); if (isatty(fileno(fptr->f)) == 0) return FALSE; return TRUE; @@ -636,23 +631,20 @@ fptr_finalize(fptr) if (fptr->f2 != NULL) { fclose(fptr->f2); } - if (fptr->path) { - free(fptr->path); - fptr->path = NULL; - } if (fptr->pid) { rb_syswait(fptr->pid); fptr->pid = 0; } } -void -io_fptr_finalize(fptr) +static void +io_fptr_close(fptr) OpenFile *fptr; { + if (fptr->f == NULL) return; + if (fptr->finalize) { (*fptr->finalize)(fptr); - fptr->finalize = 0; } else { fptr_finalize(fptr); @@ -660,6 +652,17 @@ io_fptr_finalize(fptr) fptr->f = fptr->f2 = NULL; } +void +io_fptr_finalize(fptr) + OpenFile *fptr; +{ + io_fptr_close(fptr); + if (fptr->path) { + free(fptr->path); + fptr->path = NULL; + } +} + VALUE io_close(io) VALUE io; @@ -667,7 +670,7 @@ io_close(io) OpenFile *fptr; GetOpenFile(io, fptr); - io_fptr_finalize(fptr); + io_fptr_close(fptr); return Qnil; } @@ -697,7 +700,6 @@ io_syswrite(io, str) GetOpenFile(io, fptr); io_writable(fptr); f = GetWriteFile(fptr); - if (f == NULL) closed(); #ifdef THREAD thread_fd_writable(fileno(f)); @@ -720,7 +722,6 @@ io_sysread(io, len) ilen = NUM2INT(len); GetOpenFile(io, fptr); io_readable(fptr); - if (fptr->f == NULL) closed(); str = str_new(0, ilen); @@ -1169,7 +1170,7 @@ io_reopen(io, nfile) io_binmode(io); } - RBASIC(io)->class = RBASIC(nfile)->class; + RBASIC(io)->klass = RBASIC(nfile)->klass; return io; } @@ -1709,14 +1710,13 @@ f_select(argc, argv, obj) FD_ZERO(&pset); if (!NIL_P(read)) { - Check_Type(read, T_ARRAY); rp = &rset; FD_ZERO(rp); for (i=0; i<RARRAY(read)->len; i++) { Check_Type(RARRAY(read)->ptr[i], T_FILE); GetOpenFile(RARRAY(read)->ptr[i], fptr); - if (fptr->f == NULL) closed(); + io_check_closed(fptr); FD_SET(fileno(fptr->f), rp); if (READ_DATA_PENDING(fptr->f)) { /* check for buffered data */ pending++; @@ -1739,7 +1739,7 @@ f_select(argc, argv, obj) for (i=0; i<RARRAY(write)->len; i++) { Check_Type(RARRAY(write)->ptr[i], T_FILE); GetOpenFile(RARRAY(write)->ptr[i], fptr); - if (fptr->f == NULL) closed(); + io_check_closed(fptr); FD_SET(fileno(fptr->f), wp); if (max > fileno(fptr->f)) max = fileno(fptr->f); if (fptr->f2) { @@ -1758,7 +1758,7 @@ f_select(argc, argv, obj) for (i=0; i<RARRAY(except)->len; i++) { Check_Type(RARRAY(except)->ptr[i], T_FILE); GetOpenFile(RARRAY(except)->ptr[i], fptr); - if (fptr->f == NULL) closed(); + io_check_closed(fptr); FD_SET(fileno(fptr->f), ep); if (max < fileno(fptr->f)) max = fileno(fptr->f); if (fptr->f2) { @@ -1854,13 +1854,13 @@ io_ctl(io, req, arg, io_p) rb_secure(2); GetOpenFile(io, fptr); - if (NIL_P(arg) || (VALUE)arg == FALSE) { + if (NIL_P(arg) || arg == FALSE) { narg = 0; } else if (FIXNUM_P(arg)) { narg = FIX2INT(arg); } - else if ((VALUE)arg == TRUE) { + else if (arg == TRUE) { narg = 1; } else { @@ -54,5 +54,6 @@ void io_writable _((OpenFile *)); void io_readable _((OpenFile *)); void io_fptr_finalize _((OpenFile *)); void io_unbuffered _((OpenFile *)); +void io_check_closed _((OpenFile *)); #endif diff --git a/lib/tempfile.rb b/lib/tempfile.rb index 78b770c5a4..9d986e7691 100644 --- a/lib/tempfile.rb +++ b/lib/tempfile.rb @@ -15,6 +15,19 @@ require 'final' class Tempfile < SimpleDelegator Max_try = 10 + def Tempfile.callback(path) + lambda{ + print "removing ", path, "..." + if File.exist?(path) + File.unlink(path) + end + if File.exist?(path + '.lock') + File.unlink(path + '.lock') + end + print "done\n" + } + end + def initialize(basename, tmpdir = '/tmp') umask = File.umask(0177) begin @@ -33,14 +46,7 @@ class Tempfile < SimpleDelegator n += 1 end - @clean_files = proc {|id| - if File.exist?(@tmpname) - File.unlink(@tmpname) - end - if File.exist?(@tmpname + '.lock') - File.unlink(@tmpname + '.lock') - end - } + @clean_files = Tempfile.callback(@tmpname) ObjectSpace.define_finalizer(self, @clean_files) @tmpfile = File.open(@tmpname, 'w+') @@ -75,6 +81,7 @@ if __FILE__ == $0 f = Tempfile.new("foo") f.print("foo\n") f.close + f = nil f.open p f.gets # => "foo\n" f.close(true) diff --git a/lib/thread.rb b/lib/thread.rb index 4f294cc9a3..8f7f6cdd6a 100644 --- a/lib/thread.rb +++ b/lib/thread.rb @@ -13,6 +13,10 @@ unless defined? ThreadError end end +if $DEBUG + Thread.abort_on_exception = true +end + class Mutex def initialize @waiting = [] @@ -107,4 +111,30 @@ class Queue def length @que.length end + alias size length +end + +class SizedQueue<Queue + def initialize(max) + @max = max + @queue_wait = [] + super() + end + + def push(obj) + while @que.length >= @max + @queue_wait.push Thread.current + Thread.stop + end + super + end + + def pop(*args) + if @que.length < @max + t = @queue_wait.shift + t.run if t + end + pop = super + pop + end end @@ -621,7 +621,7 @@ r_object(arg) if (rb_special_const_p(v)) { ArgError("dump format error (user class)"); } - RBASIC(v)->class = c; + RBASIC(v)->klass = c; return v; } @@ -40,20 +40,48 @@ num_coerce(x, y) return assoc_new(rb_Float(x),rb_Float(y)); } -VALUE -num_coerce_bin(x, y) - VALUE x, y; +coerce_body(x) + VALUE *x; +{ + return rb_funcall(x[1], coerce, 1, x[0]); +} + +coerce_rescue(x) + VALUE *x; +{ + TypeError("%s can't convert into %s", + rb_class2name(CLASS_OF(x[1])), + rb_class2name(CLASS_OF(x[0]))); +} + +static void +do_coerce(x, y) + VALUE *x, *y; { VALUE ary; +#if 0 + VALUE a[2]; - ary = rb_funcall(y, coerce, 1, x); + a[0] = *x; a[1] = *y; + ary = rb_rescue(coerce_body, a, coerce_rescue, a); +#else + ary = rb_funcall(*y, coerce, 1, *x); +#endif if (TYPE(ary) != T_ARRAY || RARRAY(ary)->len != 2) { TypeError("coerce must return [x, y]"); } - x = RARRAY(ary)->ptr[0]; - y = RARRAY(ary)->ptr[1]; + *x = RARRAY(ary)->ptr[0]; + *y = RARRAY(ary)->ptr[1]; +} +VALUE +num_coerce_bin(x, y) + VALUE x, y; +{ + VALUE ary; + + do_coerce(&x, &y); return rb_funcall(x, rb_frame_last_func(), 1, y); } @@ -68,17 +96,12 @@ static VALUE num_uminus(num) VALUE num; { - VALUE ary, x, y; - - ary = rb_funcall(num, coerce, 1, INT2FIX(0)); - if (TYPE(ary) != T_ARRAY || RARRAY(ary)->len != 2) { - TypeError("coerce must return [x, y]"); - } + VALUE zero; - x = RARRAY(ary)->ptr[0]; - y = RARRAY(ary)->ptr[1]; + zero = INT2FIX(0); + do_coerce(&num, &zero); - return rb_funcall(x, '-', 1, y); + return rb_funcall(zero, '-', 1, num); } static VALUE @@ -96,11 +96,11 @@ obj_clone(obj) if (TYPE(obj) != T_OBJECT) { TypeError("can't clone %s", rb_class2name(CLASS_OF(obj))); } - clone = obj_alloc(RBASIC(obj)->class); + clone = obj_alloc(RBASIC(obj)->klass); CLONESETUP(clone,obj); if (ROBJECT(obj)->iv_tbl) { ROBJECT(clone)->iv_tbl = st_copy(ROBJECT(obj)->iv_tbl); - RBASIC(clone)->class = singleton_class_clone(RBASIC(obj)->class); + RBASIC(clone)->klass = singleton_class_clone(RBASIC(obj)->klass); RBASIC(clone)->flags = RBASIC(obj)->flags; } @@ -488,8 +488,8 @@ class_s_new(argc, argv) } klass = class_new(super); /* make metaclass */ - RBASIC(klass)->class = singleton_class_new(RBASIC(super)->class); - singleton_class_attached(RBASIC(klass)->class, klass); + RBASIC(klass)->klass = singleton_class_new(RBASIC(super)->klass); + singleton_class_attached(RBASIC(klass)->klass, klass); return klass; } @@ -774,7 +774,7 @@ boot_defclass(name, super) rb_name_class(obj, id); st_add_direct(rb_class_tbl, id, obj); - return (VALUE)obj; + return obj; } VALUE @@ -786,7 +786,7 @@ rb_class_of(obj) if (obj == FALSE) return cFalseClass; if (obj == TRUE) return cTrueClass; - return RBASIC(obj)->class; + return RBASIC(obj)->klass; } VALUE TopSelf; @@ -800,11 +800,11 @@ Init_Object() cModule = boot_defclass("Module", cObject); cClass = boot_defclass("Class", cModule); - metaclass = RBASIC(cObject)->class = singleton_class_new(cClass); + metaclass = RBASIC(cObject)->klass = singleton_class_new(cClass); singleton_class_attached(metaclass, cObject); - metaclass = RBASIC(cModule)->class = singleton_class_new(metaclass); + metaclass = RBASIC(cModule)->klass = singleton_class_new(metaclass); singleton_class_attached(metaclass, cModule); - metaclass = RBASIC(cClass)->class = singleton_class_new(metaclass); + metaclass = RBASIC(cClass)->klass = singleton_class_new(metaclass); singleton_class_attached(metaclass, cClass); mKernel = rb_define_module("Kernel"); @@ -210,6 +210,7 @@ static void top_local_setup(); %right kNOT %nonassoc kDEFINED %right '=' OP_ASGN +%right '?' ':' %nonassoc DOT2 DOT3 %left OROP %left ANDOP @@ -694,6 +695,12 @@ arg : variable '=' arg in_defined = 0; $$ = NEW_DEFINED($4); } + | arg '?' arg ':' arg + { + value_expr($1); + $$ = NEW_IF(cond($1), $3, $5); + fixpos($$, $1); + } | primary { $$ = $1; @@ -975,9 +982,6 @@ primary : literal } | kCLASS LSHFT expr term { - if (cur_mid || in_single) - yyerror("class definition in method body"); - class_nest++; cref_push(); local_push(); @@ -1257,7 +1261,7 @@ superclass : term { $$ = $3; } - | error term {yyerrok;} + | error term {yyerrok; $$ = 0} f_arglist : '(' f_args ')' { @@ -2307,7 +2311,20 @@ retry: return parse_qstring(c); case '?': - if ((c = nextc()) == '\\') { + if (lex_state == EXPR_END) { + Warning("a?b:c is undocumented feature ^^;;;"); + lex_state = EXPR_BEG; + return '?'; + } + c = nextc(); + if (lex_state == EXPR_ARG && space_seen && isspace(c)){ + pushback(c); + arg_ambiguous(); + lex_state = EXPR_BEG; + Warning("a?b:c is undocumented feature ^^;;;"); + return '?'; + } + if (c == '\\') { c = read_escape(); } c &= 0xff; @@ -2388,6 +2405,7 @@ retry: return OP_ASGN; } if (c == '>') { + Warning("-> is undocumented feature ^^;;;"); lex_state = EXPR_BEG; return KW_ASSOC; } @@ -2553,8 +2571,10 @@ retry: return COLON2; } pushback(c); - if (isspace(c)) + if (lex_state == EXPR_END || isspace(c)) { + lex_state = EXPR_BEG; return ':'; + } lex_state = EXPR_FNAME; return SYMBEG; @@ -2588,9 +2608,6 @@ retry: return c; case ',': - lex_state = EXPR_BEG; - return c; - case ';': lex_state = EXPR_BEG; return c; @@ -929,7 +929,7 @@ reg_regsub(str, src, regs) if (!val) val = str_new(p, e-p); else str_cat(val, p, e-p); } - if (!val) return (VALUE)str; + if (!val) return str; return val; } @@ -6,7 +6,7 @@ $Date$ created at: Tue Aug 10 12:47:31 JST 1993 - Copyright (C) 1993-1998 Yukihiro Matsumoto + Copyright (C) 1993-1996 Yukihiro Matsumoto ************************************************/ @@ -56,25 +56,12 @@ static void forbid_setid _((char *)); static VALUE do_loop = FALSE, do_print = FALSE; static VALUE do_check = FALSE, do_line = FALSE; static VALUE do_split = FALSE; -static int do_search = FALSE; + static char *script; -static char *e_body; static int origargc; static char **origargv; -#if defined(NeXT) && defined(__DYNAMIC__) - -#include <mach-o/dyld.h> -extern char *** environ_pointer; -#define environ (*environ_pointer) -#else -#ifndef NT -extern char **environ; -#endif -#endif -static char **origenviron; - extern int sourceline; extern char *sourcefile; @@ -158,7 +145,7 @@ proc_options(argcp, argvp) { int argc = *argcp; char **argv = *argvp; - int script_given; + int script_given, do_search; char *s; if (argc == 0) return; @@ -232,11 +219,11 @@ proc_options(argcp, argvp) script_given++; if (script == 0) script = "-e"; if (argv[1]) { - e_body = argv[1]; + compile_string("-e", argv[1], strlen(argv[1])); argc--,argv++; } else { - e_body = ""; + compile_string("-e", "", 0); } break; @@ -374,24 +361,40 @@ proc_options(argcp, argvp) show_copyright(); } + Init_ext(); /* should be called here for some reason :-( */ if (script_given == FALSE) { if (argc == 0) { /* no more args */ if (verbose == 3) exit(0); script = "-"; + load_stdin(); } else { script = argv[0]; if (script[0] == '\0') { script = "-"; + load_stdin(); } else { - script = argv[0]; + if (do_search) { + char *path = getenv("RUBYPATH"); + + script = 0; + if (path) { + script = dln_find_file(argv[0], path); + } + if (!script) { + script = dln_find_file(argv[0], getenv("PATH")); + } + if (!script) script = argv[0]; + } + load_file(script, 1); } argc--; argv++; } } if (verbose) verbose = TRUE; + xflag = FALSE; *argvp = argv; *argcp = argc; @@ -418,41 +421,6 @@ proc_options(argcp, argvp) } -void -ruby_load_script() -{ - if (script[0] == '-') { - if (script[1] == '\0') { - load_stdin(); - } - else if (script[1] == 'e') { - compile_string("-e", e_body, strlen(e_body)); - } - } - else { - if (do_search) { - char *path = getenv("RUBYPATH"); - char *s = 0; - - if (path) { - s = dln_find_file(script, path); - } - if (!s) { - s = dln_find_file(script, getenv("PATH")); - } - if (s) script = s; - } - load_file(script, 1); - } - xflag = FALSE; - if (do_print) { - yyappend_print(); - } - if (do_loop) { - yywhile_loop(do_line, do_split); - } -} - static void load_file(fname, script) char *fname; @@ -508,7 +476,7 @@ load_file(fname, script) char *path; char *pend = RSTRING(line)->ptr + RSTRING(line)->len; - p = RSTRING(line)->ptr + 1; /* skip `#!' */ + p = RSTRING(line)->ptr + 2; /* skip `#!' */ if (pend[-1] == '\n') pend--; /* chomp line */ if (pend[-1] == '\r') pend--; *pend = '\0'; @@ -547,9 +515,6 @@ load_file(fname, script) RSTRING(line)->ptr[RSTRING(line)->len-2] = '\0'; argc = 2; argv[0] = 0; argv[1] = p + 5; proc_options(&argc, &argvp); -#if 0 - proc_sflag(&argc, &argvp); -#endif } } } @@ -589,7 +554,7 @@ set_arg0(val, id) int i; static int len; - if (origargv == 0) ArgError("$0 not initialized"); + if (origargv == 0) Fail("$0 not initialized"); Check_Type(val, T_STRING); if (len == 0) { s = origargv[0]; @@ -599,14 +564,6 @@ set_arg0(val, id) if (origargv[i] == s + 1) s += strlen(++s); /* this one is ok too */ } - /* can grab env area too? */ - if (origenviron && origenviron[0] == s + 1) { - setenv("NoNe SuCh", "Ruby Compiler :-)", 1); - /* force copy of environment */ - for (i = 0; origenviron[i]; i++) - if (origenviron[i] == s + 1) - s += strlen(++s); - } len = s - origargv[0]; } s = RSTRING(val)->ptr; @@ -773,11 +730,6 @@ ruby_process_options(argc, argv) int i; origargc = argc; origargv = argv; -#if defined(NeXT) && defined(__DYNAMIC__) - _dyld_lookup_and_bind("__environ", (unsigned long*)&environ_pointer, NULL); -#endif /* environ */ - origenviron = environ; - ruby_script(argv[0]); /* for the time being */ rb_argv0 = str_taint(str_new2(argv[0])); #if defined(USE_DLN_A_OUT) @@ -791,4 +743,10 @@ ruby_process_options(argc, argv) printf("Syntax OK\n"); exit(0); } + if (do_print) { + yyappend_print(); + } + if (do_loop) { + yywhile_loop(do_line, do_split); + } } @@ -171,17 +171,17 @@ char *str2cstr _((VALUE)); VALUE rb_newobj _((void)); #define NEWOBJ(obj,type) type *obj = (type*)rb_newobj() #define OBJSETUP(obj,c,t) {\ - RBASIC(obj)->class = (c);\ + RBASIC(obj)->klass = (c);\ RBASIC(obj)->flags = (t);\ } #define CLONESETUP(clone,obj) {\ - OBJSETUP(clone,singleton_class_clone(RBASIC(obj)->class),RBASIC(obj)->flags);\ - singleton_class_attached(RBASIC(clone)->class, (VALUE)clone);\ + OBJSETUP(clone,singleton_class_clone(RBASIC(obj)->klass),RBASIC(obj)->flags);\ + singleton_class_attached(RBASIC(clone)->klass, (VALUE)clone);\ } struct RBasic { UINT flags; - VALUE class; + VALUE klass; }; struct RObject { @@ -243,14 +243,14 @@ struct RData { #define DATA_PTR(dta) (RDATA(dta)->data) VALUE data_object_alloc _((VALUE,void*,void (*)(),void (*)())); -#define Data_Make_Struct(class,type,mark,free,sval) (\ +#define Data_Make_Struct(klass,type,mark,free,sval) (\ sval = ALLOC(type),\ memset(sval, 0, sizeof(type)),\ - data_object_alloc(class,sval,mark,free)\ + data_object_alloc(klass,sval,mark,free)\ ) -#define Data_Wrap_Struct(class,mark,free,sval) (\ - data_object_alloc(class,sval,mark,free)\ +#define Data_Wrap_Struct(klass,mark,free,sval) (\ + data_object_alloc(klass,sval,mark,free)\ ) #define Data_Get_Struct(obj,type,sval) {\ diff --git a/sample/from.rb b/sample/from.rb index d39bb70084..39aa4b7553 100644 --- a/sample/from.rb +++ b/sample/from.rb @@ -9,8 +9,6 @@ include Kconv class String - public :kconv - def kconv(code = Kconv::EUC) Kconv.kconv(self, code, Kconv::AUTO) end @@ -35,10 +33,11 @@ if ARGV.length == 0 user = ENV['USER'] else user = ARGV[0] + ARGV.clear end [ENV['SPOOLDIR'], '/usr/spool', '/var/spool', '/usr', '/var'].each do |m| - break if File.exist? ARGV[0] = "#{m}/mail/#{user}" + break if File.exist? file = "#{m}/mail/#{user}" end $outcount = 0; @@ -67,14 +66,19 @@ def fromout(date, from, subj) $outcount += 1 end -for file in ARGV - next if !File.exist?(file) +if File.exist?(file) + atime = File.atime(file) + mtime = File.mtime(file) f = open(file, "r") - while !f.eof? - mail = Mail.new(f) - fromout mail.header['Date'], mail.header['From'], mail.header['Subject'] + begin + until f.eof? + mail = Mail.new(f) + fromout mail.header['Date'],mail.header['From'],mail.header['Subject'] + end + ensure + f.close + File.utime(atime, mtime, file) end - f.close end if $outcount == 0 diff --git a/sample/rbc.rb b/sample/rbc.rb index b3a4851ef5..7ab0edba12 100644 --- a/sample/rbc.rb +++ b/sample/rbc.rb @@ -11,29 +11,29 @@ # # rbc.rb [options] file_name opts # options: -# -d デバッグモード(利用しない方が良いでしょう) -# -m bcモード(分数, 行列の計算ができます) -# -r load-module ruby -r と同じ -# --inspect 結果出力にinspectを用いる(bcモード以外はデ -# フォルト). -# --noinspect 結果出力にinspectを用いない. -# --noreadline readlineライブラリを利用しない(デフォルト -# ではreadlineライブラリを利用しようとする). +# -d debug mode(not encouraged) +# -m bc mode(calculate rational, matrix) +# -r load-module same as `ruby -r' +# --inspect use inspect for output. +# (default except in bc mode) +# --noinspect do not use inspect for output. +# --noreadline do not use readline library. +# (rbc tries to use readline as default). # -# 追加 private method: -# exit, quit 終了する. -# inspect(sw = nil) インスペクトモードのトグル -# trace_load(sw = nil) load/require時にrbcのfile読み込み機能を用 -# いるモードのスイッチ(デフォルトはトレース -# モード) +# additional private methods: +# exit, quit quit +# inspect(sw = nil) toggle inspect mode +# trace_load(sw = nil) toggle trace mode for load/require. +# (default is trace mode on) # require "e2mmap.rb" $stdout.sync = TRUE module BC_APPLICATION__ - RCS_ID='-$Header: /home/keiju/var/src/var.lib/ruby/ruby/RCS/rbc.rb,v 1.2 1997/11/27 13:46:06 keiju Exp keiju $-' - + + RCS_ID=%q$Id: rbc.rb,v 1.2 1997/11/27 13:46:06 keiju Exp keiju $ + extend Exception2MessageMapper def_exception :UnrecognizedSwitch, "Unrecognized switch: %s" @@ -186,7 +186,7 @@ module BC_APPLICATION__ PARCENT_LTYPE = { "q" => "\'", - "Q" => "\"", + "Q" => "\"", #" "x" => "\`", "r" => "\/" } @@ -332,7 +332,7 @@ module BC_APPLICATION__ @lex_state = EXPR_BEG end end - @OP.def_rule('$') do + @OP.def_rule('$') do #' |op, rests| identify_gvar(rests) end @@ -444,7 +444,7 @@ module BC_APPLICATION__ print token, "\n" if $DEBUG if state = CLAUSE_STATE_TRANS[token] if @lex_state != EXPR_BEG and token =~ /^(if|unless|while|until)/ - # 修飾子 + # $B=$>~;R(B else if ENINDENT_CLAUSE.include?(token) @indent += 1 @@ -472,7 +472,7 @@ module BC_APPLICATION__ if lt = PARCENT_LTYPE[ch] ch = chrs.shift else - lt = "\"" + lt = "\"" #" end if ch !~ /\W/ chrs.unshift ch @@ -618,7 +618,7 @@ module BC_APPLICATION__ def_exception :ErrNodeAlreadyExists, "node already exists" class Node - # postprocがなければ抽象ノード, nilじゃなければ具象ノード + # postproc$B$,$J$1$l$PCj>]%N!<%I(B, nil$B$8$c$J$1$l$P6q>]%N!<%I(B def initialize(preproc = nil, postproc = nil) @Tree = {} @preproc = preproc diff --git a/sample/test.rb b/sample/test.rb index 0a9d41c2ed..ce0822685a 100644 --- a/sample/test.rb +++ b/sample/test.rb @@ -120,7 +120,7 @@ $bad = false tmp = open("while_tmp", "r") while tmp.gets() if gsub!('vt100', 'VT100') - gsub!('VT100', 'Vt100') + p gsub!('VT100', 'Vt100') redo; end $bad = 1 if /vt100/; @@ -453,6 +453,7 @@ ok($x+1 == 815915283247897734345611269596115894272000000001) ok($x/fact(20) == 335367096786357081410764800000) $x = -$x ok($x == -815915283247897734345611269596115894272000000000) +p [2**32, 2-(2**32), -(2**32-2)] ok(2-(2**32) == -(2**32-2)) ok(2**32 - 5 == (2**32-3)-2) diff --git a/sample/tkfrom.rb b/sample/tkfrom.rb index b0ef8995ca..ba0e547799 100644 --- a/sample/tkfrom.rb +++ b/sample/tkfrom.rb @@ -94,25 +94,31 @@ root.bind "space", proc{exit} $outcount = 0; for file in ARGV - next if !File.exist?(file) + next if File.exist?(file) + atime = File.atime(file) + mtime = File.mtime(file) f = open(file, "r") - while !f.eof - mail = Mail.new(f) - date = mail.header['Date'] - next if !date - from = mail.header['From'] - subj = mail.header['Subject'] - y = m = d = 0 - y, m, d = parsedate(date) if date - from = "sombody@somewhere" if ! from - subj = "(nil)" if ! subj - from = decode_b(from) - subj = decode_b(subj) - list.insert 'end', format('%-02d/%02d/%02d [%-28.28s] %s',y,m,d,from,subj) - $outcount += 1 + begin + until f.eof + mail = Mail.new(f) + date = mail.header['Date'] + next unless date + from = mail.header['From'] + subj = mail.header['Subject'] + y = m = d = 0 + y, m, d = parsedate(date) if date + from = "sombody@somewhere" unless from + subj = "(nil)" unless subj + from = decode_b(from) + subj = decode_b(subj) + list.insert 'end', format('%-02d/%02d/%02d [%-28.28s] %s',y,m,d,from,subj) + $outcount += 1 + end + ensure + f.close + File.utime(atime, mtime, file) + list.see 'end' end - f.close - list.see 'end' end limit = 10000 @@ -100,6 +100,20 @@ str_new4(orig) return (VALUE)str; } +static void +str_assign(str, str2) + VALUE str, str2; +{ + if (NIL_P(str2) || str == str2) return; + free(RSTRING(str)->ptr); + RSTRING(str)->ptr = RSTRING(str2)->ptr; + RSTRING(str)->len = RSTRING(str2)->len; + RSTRING(str)->orig = RSTRING(str2)->orig; + RSTRING(str2)->ptr = 0; /* abandon str2 */ + RSTRING(str2)->len = 0; + if (str_tainted(str2)) str_taint(str); +} + static ID pr_str; VALUE @@ -171,6 +185,15 @@ str_length(str) return INT2FIX(RSTRING(str)->len); } +static VALUE +str_empty(str) + VALUE str; +{ + if (RSTRING(str)->len == 0) + return TRUE; + return FALSE; +} + VALUE str_plus(str1, str2) VALUE str1, str2; @@ -185,7 +208,7 @@ str_plus(str1, str2) if (str_tainted(str1) || str_tainted(str2)) return str_taint(str3); - return (VALUE)str3; + return str3; } VALUE @@ -208,7 +231,7 @@ str_times(str, times) RSTRING(str2)->ptr[RSTRING(str2)->len] = '\0'; if (str_tainted(str)) { - return str_taint((VALUE)str2); + return str_taint(str2); } return str2; @@ -371,7 +394,7 @@ str_resize(str, len) RSTRING(str)->len = len; RSTRING(str)->ptr[len] = '\0'; /* sentinel */ } - return (VALUE)str; + return str; } VALUE @@ -696,6 +719,16 @@ str_succ(orig) return str; } +static VALUE +str_succ_bang(str) + VALUE str; +{ + str_modify(str); + str_assign(str, str_succ(str)); + + return str; +} + VALUE str_upto(beg, end) VALUE beg, end; @@ -735,7 +768,7 @@ str_aref(str, indx) if (idx < 0 || RSTRING(str)->len <= idx) { return Qnil; } - return (VALUE)INT2FIX(RSTRING(str)->ptr[idx] & 0xff); + return INT2FIX(RSTRING(str)->ptr[idx] & 0xff); case T_REGEXP: if (str_match(str, indx)) @@ -900,13 +933,10 @@ str_sub_f(str, pat, val, once) str_modify(str); result = str_sub_s(str, pat, val, once); - if (NIL_P(result)) return Qnil; - str_resize(str, RSTRING(result)->len); - memcpy(RSTRING(str)->ptr, RSTRING(result)->ptr, RSTRING(result)->len); - if (str_tainted(result)) str_taint(str); + str_assign(str, result); - return (VALUE)str; + return str; } static VALUE @@ -981,12 +1011,10 @@ str_sub_iter_f(str, pat, once) str_modify(str); result = str_sub_iter_s(str, pat, once); - if (NIL_P(result)) return Qnil; - str_resize(str, RSTRING(result)->len); - memcpy(RSTRING(str)->ptr, RSTRING(result)->ptr, RSTRING(result)->len); + str_assign(str, result); - return (VALUE)str; + return str; } static VALUE @@ -1131,6 +1159,20 @@ str_gsub(argc, argv, str) } static VALUE +str_replace_method(str, str2) + VALUE str, str2; +{ + Check_Type(str2, T_STRING); + + str_modify(str); + str_resize(str, RSTRING(str2)->len); + memcpy(RSTRING(str)->ptr, RSTRING(str2)->ptr, RSTRING(str2)->len); + if (str_tainted(str2)) str_taint(str); + + return str; +} + +static VALUE uscore_get() { VALUE line; @@ -1227,7 +1269,7 @@ str_reverse_bang(str) } MEMCPY(RSTRING(str)->ptr, p, char, RSTRING(str)->len); - return (VALUE)str; + return str; } static VALUE @@ -1406,7 +1448,7 @@ str_upcase_bang(str) s++; } - return (VALUE)str; + return str; } static VALUE @@ -1434,7 +1476,7 @@ str_downcase_bang(str) s++; } - return (VALUE)str; + return str; } static VALUE @@ -1462,7 +1504,7 @@ str_capitalize_bang(str) *s = tolower(*s); } } - return (VALUE)str; + return str; } static VALUE @@ -1493,7 +1535,7 @@ str_swapcase_bang(str) s++; } - return (VALUE)str; + return str; } static VALUE @@ -1623,7 +1665,7 @@ tr_trans(str, src, repl, sflag) *t = '\0'; if (sflag) RSTRING(str)->len = (t - RSTRING(str)->ptr); - return (VALUE)str; + return str; } static VALUE @@ -1687,7 +1729,7 @@ str_delete_bang(str1, str2) *t = '\0'; RSTRING(str1)->len = t - RSTRING(str1)->ptr; - return (VALUE)str1; + return str1; } static VALUE @@ -1730,7 +1772,7 @@ tr_squeeze(str1, str2) *t = '\0'; RSTRING(str1)->len = t - RSTRING(str1)->ptr; - return (VALUE)str1; + return str1; } static VALUE @@ -2112,7 +2154,7 @@ str_strip_bang(str) RSTRING(str)->ptr[RSTRING(str)->len] = '\0'; } - return (VALUE)str; + return str; } static VALUE @@ -2241,7 +2283,7 @@ str_sum(argc, argv, str) else bits = NUM2INT(vbits); p = RSTRING(str)->ptr; pend = p + RSTRING(str)->len; - if (bits > 32) { + if (bits > sizeof(UINT)*CHAR_BIT) { VALUE res = INT2FIX(0); VALUE mod; @@ -2250,20 +2292,23 @@ str_sum(argc, argv, str) while (p < pend) { res = rb_funcall(res, '+', 1, INT2FIX((UINT)*p)); - res = rb_funcall(res, '%', 1, mod); p++; } + res = rb_funcall(res, '&', 1, mod); return res; } else { UINT res = 0; UINT mod = (1<<bits)-1; + if (mod == 0) { + mod = -1; + } while (p < pend) { res += (UINT)*p; - res %= mod; p++; } + res &= mod; return int2inum(res); } } @@ -2277,7 +2322,7 @@ str_ljust(str, w) VALUE res; UCHAR *p, *pend; - if (RSTRING(str)->len >= width) return (VALUE)str; + if (RSTRING(str)->len >= width) return str; res = str_new(0, width); memcpy(RSTRING(res)->ptr, RSTRING(str)->ptr, RSTRING(str)->len); p = RSTRING(res)->ptr + RSTRING(str)->len; pend = RSTRING(res)->ptr + width; @@ -2296,7 +2341,7 @@ str_rjust(str, w) VALUE res; UCHAR *p, *pend; - if (RSTRING(str)->len >= width) return (VALUE)str; + if (RSTRING(str)->len >= width) return str; res = str_new(0, width); p = RSTRING(res)->ptr; pend = p + width - RSTRING(str)->len; while (p < pend) { @@ -2316,7 +2361,7 @@ str_center(str, w) UCHAR *p, *pend; int n; - if (RSTRING(str)->len >= width) return (VALUE)str; + if (RSTRING(str)->len >= width) return str; res = str_new(0, width); n = (width - RSTRING(str)->len)/2; p = RSTRING(res)->ptr; pend = p + n; @@ -2357,12 +2402,15 @@ Init_String() rb_define_method(cString, "[]=", str_aset_method, -1); rb_define_method(cString, "length", str_length, 0); rb_define_alias(cString, "size", "length"); + rb_define_method(cString, "empty?", str_empty, 0); rb_define_method(cString, "=~", str_match, 1); rb_define_method(cString, "~", str_match2, 0); rb_define_method(cString, "succ", str_succ, 0); + rb_define_method(cString, "succ!", str_succ_bang, 0); rb_define_method(cString, "upto", str_upto, 1); rb_define_method(cString, "index", str_index_method, -1); rb_define_method(cString, "rindex", str_rindex, -1); + rb_define_method(cString, "replace", str_replace_method, 1); rb_define_method(cString, "freeze", str_freeze, 0); rb_define_method(cString, "frozen?", str_frozen_p, 0); @@ -414,16 +414,16 @@ time_asctime(time) VALUE time; { struct time_object *tobj; - char buf[64]; - int len; + char *s; GetTimeval(time, tobj); if (tobj->tm_got == 0) { time_localtime(time); } - len = strftime(buf, 64, "%c", &(tobj->tm)); + s = asctime(&(tobj->tm)); + if (s[24] == '\n') s[24] = '\0'; - return str_new(buf, len); + return str_new2(s); } static VALUE |