summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>1998-02-09 10:56:24 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>1998-02-09 10:56:24 +0000
commitb814252d728cb08f159da1777feca4f8e9362327 (patch)
treede6617897dbf6bce78045e3fa2ea84ea2422f166
parent1bbcd202e4dab0894bc5ed68ce4ea84dc916980f (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--ChangeLog35
-rw-r--r--array.c42
-rw-r--r--bignum.c2
-rw-r--r--class.c24
-rw-r--r--enum.c20
-rw-r--r--eval.c351
-rw-r--r--ext/dbm/dbm.c21
-rw-r--r--ext/fcntl/fcntl.c2
-rw-r--r--file.c31
-rw-r--r--gc.c24
-rw-r--r--hash.c36
-rw-r--r--io.c68
-rw-r--r--io.h1
-rw-r--r--lib/tempfile.rb23
-rw-r--r--lib/thread.rb30
-rw-r--r--marshal.c2
-rw-r--r--numeric.c53
-rw-r--r--object.c18
-rw-r--r--parse.y35
-rw-r--r--re.c2
-rw-r--r--ruby.c102
-rw-r--r--ruby.h16
-rw-r--r--sample/from.rb22
-rw-r--r--sample/rbc.rb42
-rw-r--r--sample/test.rb3
-rw-r--r--sample/tkfrom.rb40
-rw-r--r--string.c104
-rw-r--r--time.c8
28 files changed, 704 insertions, 453 deletions
diff --git a/ChangeLog b/ChangeLog
index 1f4c7ae15f..6b720736f7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
diff --git a/array.c b/array.c
index 6a6dce4697..e39f1f167c 100644
--- a/array.c
+++ b/array.c
@@ -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);
diff --git a/bignum.c b/bignum.c
index 481a35efcf..8a6e54a9da 100644
--- a/bignum.c
+++ b/bignum.c
@@ -1181,7 +1181,7 @@ big_abs(x)
x = big_clone(x);
RBIGNUM(x)->sign = 1;
}
- return (VALUE)x;
+ return x;
}
/* !!!warnig!!!!
diff --git a/class.c b/class.c
index 4e6ef327e5..b5bfecfbd5 100644
--- a/class.c
+++ b/class.c
@@ -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
diff --git a/enum.c b/enum.c
index e37fee7f03..3b804fae48 100644
--- a/enum.c
+++ b/enum.c
@@ -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");
diff --git a/eval.c b/eval.c
index 5d66e25d7d..182471cd6d 100644
--- a/eval.c
+++ b/eval.c
@@ -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
************************************************/
diff --git a/file.c b/file.c
index 1ff0463694..01c26eea41 100644
--- a/file.c
+++ b/file.c
@@ -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);
diff --git a/gc.c b/gc.c
index bc3517e4d8..9eab3b6c18 100644
--- a/gc.c
+++ b/gc.c
@@ -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);
}
diff --git a/hash.c b/hash.c
index ba531f4ded..920885709e 100644
--- a/hash.c
+++ b/hash.c
@@ -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);
diff --git a/io.c b/io.c
index 5b10bb6091..6e4c7e7d76 100644
--- a/io.c
+++ b/io.c
@@ -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 {
diff --git a/io.h b/io.h
index 73acbd7812..ddb49961dc 100644
--- a/io.h
+++ b/io.h
@@ -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
diff --git a/marshal.c b/marshal.c
index ac95e438ae..7d4d987829 100644
--- a/marshal.c
+++ b/marshal.c
@@ -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;
}
diff --git a/numeric.c b/numeric.c
index 28adaa6671..61e695a605 100644
--- a/numeric.c
+++ b/numeric.c
@@ -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
diff --git a/object.c b/object.c
index 834055e996..90d774a1f0 100644
--- a/object.c
+++ b/object.c
@@ -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");
diff --git a/parse.y b/parse.y
index 1033f60e7a..8a3c2ef9a7 100644
--- a/parse.y
+++ b/parse.y
@@ -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;
diff --git a/re.c b/re.c
index 41f5ff887b..245bcbea48 100644
--- a/re.c
+++ b/re.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;
}
diff --git a/ruby.c b/ruby.c
index ed4e653190..43250e7c16 100644
--- a/ruby.c
+++ b/ruby.c
@@ -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);
+ }
}
diff --git a/ruby.h b/ruby.h
index a3e3f47dc9..d40456b01a 100644
--- a/ruby.h
+++ b/ruby.h
@@ -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
diff --git a/string.c b/string.c
index aea64dff0b..220f6f1bfb 100644
--- a/string.c
+++ b/string.c
@@ -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);
diff --git a/time.c b/time.c
index c16a11641f..4bbe4fbd4f 100644
--- a/time.c
+++ b/time.c
@@ -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