1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

1.1b7 pre

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/v1_1r@67 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
matz 1998-02-09 10:56:24 +00:00
parent 1bbcd202e4
commit b814252d72
28 changed files with 710 additions and 459 deletions

View file

@ -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.

44
array.c
View file

@ -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;
}
#endif
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;
}
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);

View file

@ -1181,7 +1181,7 @@ big_abs(x)
x = big_clone(x);
RBIGNUM(x)->sign = 1;
}
return (VALUE)x;
return x;
}
/* !!!warnig!!!!

24
class.c
View file

@ -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

20
enum.c
View file

@ -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");

357
eval.c
View file

@ -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);
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;
}
else {
data->frame.iter = ITER_NOT;
}
}
orphan = blk_orphan(data);
/* PUSH BLOCK from data */
PUSH_BLOCK2(data);
PUSH_ITER(ITER_CUR);
the_frame->iter = ITER_CUR;
if (orphan) {/* orphan procedure */
if (iterator_p()) {
the_block->frame.iter = ITER_CUR;
}
else {
the_block->frame.iter = ITER_NOT;
}
}
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;

View file

@ -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);

View file

@ -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
************************************************/

31
file.c
View file

@ -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);

24
gc.c
View file

@ -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);
}

36
hash.c
View file

@ -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);

68
io.c
View file

@ -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 {

1
io.h
View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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;
}

View file

@ -40,20 +40,48 @@ num_coerce(x, y)
return assoc_new(rb_Float(x),rb_Float(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];
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];
}
VALUE
num_coerce_bin(x, y)
VALUE x, y;
{
VALUE ary;
ary = rb_funcall(y, coerce, 1, x);
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];
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;
VALUE zero;
ary = rb_funcall(num, coerce, 1, INT2FIX(0));
if (TYPE(ary) != T_ARRAY || RARRAY(ary)->len != 2) {
TypeError("coerce must return [x, y]");
}
zero = INT2FIX(0);
do_coerce(&num, &zero);
x = RARRAY(ary)->ptr[0];
y = RARRAY(ary)->ptr[1];
return rb_funcall(x, '-', 1, y);
return rb_funcall(zero, '-', 1, num);
}
static VALUE

View file

@ -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");

35
parse.y
View file

@ -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;

2
re.c
View file

@ -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;
}

102
ruby.c
View file

@ -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);
}
}

16
ruby.h
View file

@ -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) {\

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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

104
string.c
View file

@ -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
@ -1130,6 +1158,20 @@ str_gsub(argc, argv, str)
return v;
}
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()
{
@ -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);

8
time.c
View file

@ -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