* array.c (rb_ary_sort_bang): returns self, even if its length is

less than 2.

* eval.c (POP_VARS): propagate DVAR_DONT_RECYCLE, if
  SCOPE_DONT_RECYCLE of ruby_scope is set.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1156 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
matz 2001-02-02 11:38:20 +00:00
parent e9f9915a4c
commit 765255b737
14 changed files with 159 additions and 77 deletions

View File

@ -1,3 +1,11 @@
Fri Feb 2 16:14:51 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
* array.c (rb_ary_sort_bang): returns self, even if its length is
less than 2.
* eval.c (POP_VARS): propagate DVAR_DONT_RECYCLE, if
SCOPE_DONT_RECYCLE of ruby_scope is set.
Wed Jan 31 22:27:29 2001 WATANABE Hirofumi <eban@ruby-lang.org> Wed Jan 31 22:27:29 2001 WATANABE Hirofumi <eban@ruby-lang.org>
* configure.in: gcc-2.95.2-7(cygwin) support. * configure.in: gcc-2.95.2-7(cygwin) support.
@ -5,6 +13,15 @@ Wed Jan 31 22:27:29 2001 WATANABE Hirofumi <eban@ruby-lang.org>
* cygwin/GNUmakefile: ditto. * cygwin/GNUmakefile: ditto.
Tue Jan 30 17:56:48 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
* array.c (rb_ary_fetch): new method.
Mon Jan 29 17:36:19 2001 TOYOFUKU Chikanobu <toyofuku@juice.or.jp>
* eval.c (rb_eval): nd_iter evaluation should be wrapped by
BEGIN_CALLARGS and END_CALLARGS.
Mon Jan 29 14:25:39 2001 Yukihiro Matsumoto <matz@ruby-lang.org> Mon Jan 29 14:25:39 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
* eval.c (block_pass): return from block jumps directory to * eval.c (block_pass): return from block jumps directory to

3
ToDo
View File

@ -44,11 +44,13 @@ Hacking Interpreter
* warn for inconsistent local variable usage (lv m and method m at the same time). * warn for inconsistent local variable usage (lv m and method m at the same time).
* MicroRuby * MicroRuby
* Built-in Interactive Ruby. * Built-in Interactive Ruby.
* regex /\ba/ on "[a in HIRAGANA]a[a in HIRAGANA]"
Standard Libraries Standard Libraries
- Module#define_method which takes a name and a body (block, proc or method). - Module#define_method which takes a name and a body (block, proc or method).
- Enume#inject - Enume#inject
- Array#fetch
* Enumerable#sort_by for Schwartzian transformation * Enumerable#sort_by for Schwartzian transformation
* String#scanf(?) * String#scanf(?)
* Object#fmt(?) * Object#fmt(?)
@ -69,7 +71,6 @@ Standard Libraries
* fork_and_kill_other_threads. * fork_and_kill_other_threads.
* way to specify immortal (fork endurance) thread; * way to specify immortal (fork endurance) thread;
* or raise ForkException to every thread but fork caller. * or raise ForkException to every thread but fork caller.
* Array#fetch
* Hash::new{default} or recommend Hash#fetch? * Hash::new{default} or recommend Hash#fetch?
Extension Libraries Extension Libraries

28
array.c
View File

@ -384,7 +384,7 @@ rb_ary_entry(ary, offset)
if (RARRAY(ary)->len == 0) return Qnil; if (RARRAY(ary)->len == 0) return Qnil;
if (offset < 0) { if (offset < 0) {
offset = RARRAY(ary)->len + offset; offset += RARRAY(ary)->len;
} }
if (offset < 0 || RARRAY(ary)->len <= offset) { if (offset < 0 || RARRAY(ary)->len <= offset) {
return Qnil; return Qnil;
@ -431,7 +431,7 @@ rb_ary_aref(argc, argv, ary)
beg = NUM2LONG(arg1); beg = NUM2LONG(arg1);
len = NUM2LONG(arg2); len = NUM2LONG(arg2);
if (beg < 0) { if (beg < 0) {
beg = RARRAY(ary)->len + beg; beg += RARRAY(ary)->len;
} }
return rb_ary_subseq(ary, beg, len); return rb_ary_subseq(ary, beg, len);
} }
@ -480,6 +480,27 @@ rb_ary_last(ary)
return RARRAY(ary)->ptr[RARRAY(ary)->len-1]; return RARRAY(ary)->ptr[RARRAY(ary)->len-1];
} }
static VALUE
rb_ary_fetch(argc, argv, ary)
int argc;
VALUE *argv;
VALUE ary;
{
VALUE pos, ifnone;
long idx;
rb_scan_args(argc, argv, "11", &pos, &ifnone);
idx = NUM2LONG(pos);
if (idx < 0) {
idx += RARRAY(ary)->len;
}
if (idx < 0 || RARRAY(ary)->len <= idx) {
return ifnone;
}
return RARRAY(ary)->ptr[idx];
}
static VALUE static VALUE
rb_ary_index(ary, val) rb_ary_index(ary, val)
VALUE ary; VALUE ary;
@ -979,7 +1000,7 @@ rb_ary_sort_bang(ary)
VALUE ary; VALUE ary;
{ {
rb_ary_modify(ary); rb_ary_modify(ary);
if (RARRAY(ary)->len <= 1) return Qnil; if (RARRAY(ary)->len <= 1) return ary;
FL_SET(ary, ARY_TMPLOCK); /* prohibit modification during sort */ FL_SET(ary, ARY_TMPLOCK); /* prohibit modification during sort */
rb_ensure(sort_internal, ary, sort_unlock, ary); rb_ensure(sort_internal, ary, sort_unlock, ary);
@ -1649,6 +1670,7 @@ Init_Array()
rb_define_method(rb_cArray, "[]", rb_ary_aref, -1); rb_define_method(rb_cArray, "[]", rb_ary_aref, -1);
rb_define_method(rb_cArray, "[]=", rb_ary_aset, -1); rb_define_method(rb_cArray, "[]=", rb_ary_aset, -1);
rb_define_method(rb_cArray, "at", rb_ary_at, 1); rb_define_method(rb_cArray, "at", rb_ary_at, 1);
rb_define_method(rb_cArray, "fetch", rb_ary_fetch, -1);
rb_define_method(rb_cArray, "first", rb_ary_first, 0); rb_define_method(rb_cArray, "first", rb_ary_first, 0);
rb_define_method(rb_cArray, "last", rb_ary_last, 0); rb_define_method(rb_cArray, "last", rb_ary_last, 0);
rb_define_method(rb_cArray, "concat", rb_ary_concat, 1); rb_define_method(rb_cArray, "concat", rb_ary_concat, 1);

2
env.h
View File

@ -37,7 +37,7 @@ extern struct SCOPE {
struct RBasic super; struct RBasic super;
ID *local_tbl; ID *local_tbl;
VALUE *local_vars; VALUE *local_vars;
int flag; int flags;
} *ruby_scope; } *ruby_scope;
#define SCOPE_ALLOCA 0 #define SCOPE_ALLOCA 0

79
eval.c
View File

@ -602,6 +602,8 @@ struct RVarmap *ruby_dyna_vars;
ruby_dyna_vars = 0; ruby_dyna_vars = 0;
#define POP_VARS() \ #define POP_VARS() \
if (_old && (ruby_scope->flags & SCOPE_DONT_RECYCLE)) \
FL_SET(_old, DVAR_DONT_RECYCLE); \
ruby_dyna_vars = _old; \ ruby_dyna_vars = _old; \
} }
@ -808,7 +810,7 @@ static VALUE ruby_wrapper; /* security wrapper */
OBJSETUP(_scope, 0, T_SCOPE); \ OBJSETUP(_scope, 0, T_SCOPE); \
_scope->local_tbl = 0; \ _scope->local_tbl = 0; \
_scope->local_vars = 0; \ _scope->local_vars = 0; \
_scope->flag = 0; \ _scope->flags = 0; \
_old = ruby_scope; \ _old = ruby_scope; \
ruby_scope = _scope; \ ruby_scope = _scope; \
scope_vmode = SCOPE_PUBLIC; scope_vmode = SCOPE_PUBLIC;
@ -819,18 +821,18 @@ static rb_thread_t main_thread;
static void scope_dup _((struct SCOPE *)); static void scope_dup _((struct SCOPE *));
#define POP_SCOPE() \ #define POP_SCOPE() \
if (ruby_scope->flag & SCOPE_DONT_RECYCLE) {\ if (ruby_scope->flags & SCOPE_DONT_RECYCLE) {\
if (_old) scope_dup(_old); \ if (_old) scope_dup(_old); \
} \ } \
if (!(ruby_scope->flag & SCOPE_MALLOC)) {\ if (!(ruby_scope->flags & SCOPE_MALLOC)) {\
ruby_scope->local_vars = 0; \ ruby_scope->local_vars = 0; \
ruby_scope->local_tbl = 0; \ ruby_scope->local_tbl = 0; \
if (!(ruby_scope->flag & SCOPE_DONT_RECYCLE) && \ if (!(ruby_scope->flags & SCOPE_DONT_RECYCLE) && \
ruby_scope != top_scope) { \ ruby_scope != top_scope) { \
rb_gc_force_recycle((VALUE)ruby_scope);\ rb_gc_force_recycle((VALUE)ruby_scope);\
} \ } \
} \ } \
ruby_scope->flag |= SCOPE_NOSTACK; \ ruby_scope->flags |= SCOPE_NOSTACK; \
ruby_scope = _old; \ ruby_scope = _old; \
scope_vmode = _vmode; \ scope_vmode = _vmode; \
} }
@ -1305,7 +1307,7 @@ rb_eval_cmd(cmd, arg)
val = eval(ruby_top_self, cmd, Qnil, 0, 0); val = eval(ruby_top_self, cmd, Qnil, 0, 0);
} }
if (ruby_scope->flag & SCOPE_DONT_RECYCLE) if (ruby_scope->flags & SCOPE_DONT_RECYCLE)
scope_dup(saved_scope); scope_dup(saved_scope);
ruby_scope = saved_scope; ruby_scope = saved_scope;
ruby_safe_level = safe; ruby_safe_level = safe;
@ -2234,10 +2236,9 @@ rb_eval(self, n)
state = EXEC_TAG(); state = EXEC_TAG();
if (state == 0) { if (state == 0) {
PUSH_ITER(ITER_PRE);
if (nd_type(node) == NODE_ITER) { if (nd_type(node) == NODE_ITER) {
PUSH_ITER(ITER_PRE);
result = rb_eval(self, node->nd_iter); result = rb_eval(self, node->nd_iter);
POP_ITER();
} }
else { else {
VALUE recv; VALUE recv;
@ -2245,13 +2246,14 @@ rb_eval(self, n)
int line = ruby_sourceline; int line = ruby_sourceline;
_block.flags &= ~BLOCK_D_SCOPE; _block.flags &= ~BLOCK_D_SCOPE;
BEGIN_CALLARGS;
recv = rb_eval(self, node->nd_iter); recv = rb_eval(self, node->nd_iter);
PUSH_ITER(ITER_PRE); END_CALLARGS;
ruby_sourcefile = file; ruby_sourcefile = file;
ruby_sourceline = line; ruby_sourceline = line;
result = rb_call(CLASS_OF(recv),recv,each,0,0,0); result = rb_call(CLASS_OF(recv),recv,each,0,0,0);
POP_ITER();
} }
POP_ITER();
} }
else if (_block.tag->dst == state) { else if (_block.tag->dst == state) {
state &= TAG_MASK; state &= TAG_MASK;
@ -3580,8 +3582,11 @@ rb_yield_0(val, self, klass, acheck)
pop_state: pop_state:
POP_ITER(); POP_ITER();
POP_CLASS(); POP_CLASS();
#if 0
if (ruby_dyna_vars && (block->flags & BLOCK_D_SCOPE) && if (ruby_dyna_vars && (block->flags & BLOCK_D_SCOPE) &&
!FL_TEST(ruby_dyna_vars, DVAR_DONT_RECYCLE)) { (!(ruby_scope->flags & SCOPE_DONT_RECYCLE) ||
!(block->tag->flags & BLOCK_DYNAMIC) ||
!FL_TEST(ruby_dyna_vars, DVAR_DONT_RECYCLE))) {
struct RVarmap *vars, *tmp; struct RVarmap *vars, *tmp;
if (ruby_dyna_vars->id == 0) { if (ruby_dyna_vars->id == 0) {
@ -3594,10 +3599,26 @@ rb_yield_0(val, self, klass, acheck)
} }
} }
} }
#else
if (ruby_dyna_vars && (block->flags & BLOCK_D_SCOPE) &&
!FL_TEST(ruby_dyna_vars, DVAR_DONT_RECYCLE)) {
struct RVarmap *vars = ruby_dyna_vars;
if (ruby_dyna_vars->id == 0) {
vars = ruby_dyna_vars->next;
rb_gc_force_recycle((VALUE)ruby_dyna_vars);
while (vars && vars->id != 0) {
struct RVarmap *tmp = vars->next;
rb_gc_force_recycle((VALUE)vars);
vars = tmp;
}
}
}
#endif
POP_VARS(); POP_VARS();
ruby_block = block; ruby_block = block;
ruby_frame = ruby_frame->prev; ruby_frame = ruby_frame->prev;
if (ruby_scope->flag & SCOPE_DONT_RECYCLE) if (ruby_scope->flags & SCOPE_DONT_RECYCLE)
scope_dup(old_scope); scope_dup(old_scope);
ruby_scope = old_scope; ruby_scope = old_scope;
if (state) { if (state) {
@ -4739,7 +4760,6 @@ eval(self, src, scope, file, line)
} }
Data_Get_Struct(scope, struct BLOCK, data); Data_Get_Struct(scope, struct BLOCK, data);
/* PUSH BLOCK from data */ /* PUSH BLOCK from data */
frame = data->frame; frame = data->frame;
frame.tmp = ruby_frame; /* gc protection */ frame.tmp = ruby_frame; /* gc protection */
@ -4785,14 +4805,33 @@ eval(self, src, scope, file, line)
POP_CLASS(); POP_CLASS();
ruby_in_eval--; ruby_in_eval--;
if (!NIL_P(scope)) { if (!NIL_P(scope)) {
int dont_recycle = ruby_scope->flags & SCOPE_DONT_RECYCLE;
ruby_frame = frame.tmp; ruby_frame = frame.tmp;
if (ruby_scope->flag & SCOPE_DONT_RECYCLE)
scope_dup(old_scope);
ruby_scope = old_scope; ruby_scope = old_scope;
ruby_block = old_block; ruby_block = old_block;
ruby_dyna_vars = old_dyna_vars; ruby_dyna_vars = old_dyna_vars;
data->vmode = scope_vmode; /* write back visibility mode */ data->vmode = scope_vmode; /* write back visibility mode */
scope_vmode = old_vmode; scope_vmode = old_vmode;
if (dont_recycle) {
struct tag *tag;
struct RVarmap *vars;
scope_dup(ruby_scope);
for (tag=prot_tag; tag; tag=tag->prev) {
scope_dup(tag->scope);
}
if (ruby_block) {
struct BLOCK *block = ruby_block;
while (block) {
block->tag->flags |= BLOCK_DYNAMIC;
block = block->prev;
}
}
for (vars = ruby_dyna_vars; vars; vars = vars->next) {
FL_SET(vars, DVAR_DONT_RECYCLE);
}
}
} }
else { else {
ruby_frame->iter = iter; ruby_frame->iter = iter;
@ -5116,7 +5155,7 @@ rb_load(fname, wrap)
} }
} }
ruby_frame->last_func = last_func; ruby_frame->last_func = last_func;
if (ruby_scope->flag == SCOPE_ALLOCA && ruby_class == rb_cObject) { if (ruby_scope->flags == SCOPE_ALLOCA && ruby_class == rb_cObject) {
if (ruby_scope->local_tbl) /* toplevel was empty */ if (ruby_scope->local_tbl) /* toplevel was empty */
free(ruby_scope->local_tbl); free(ruby_scope->local_tbl);
} }
@ -5896,8 +5935,8 @@ scope_dup(scope)
ID *tbl; ID *tbl;
VALUE *vars; VALUE *vars;
scope->flag |= SCOPE_DONT_RECYCLE; scope->flags |= SCOPE_DONT_RECYCLE;
if (scope->flag & SCOPE_MALLOC) return; if (scope->flags & SCOPE_MALLOC) return;
if (scope->local_tbl) { if (scope->local_tbl) {
tbl = scope->local_tbl; tbl = scope->local_tbl;
@ -5905,7 +5944,7 @@ scope_dup(scope)
*vars++ = scope->local_vars[-1]; *vars++ = scope->local_vars[-1];
MEMCPY(vars, scope->local_vars, VALUE, tbl[0]); MEMCPY(vars, scope->local_vars, VALUE, tbl[0]);
scope->local_vars = vars; scope->local_vars = vars;
scope->flag |= SCOPE_MALLOC; scope->flags |= SCOPE_MALLOC;
} }
} }
@ -6163,7 +6202,7 @@ static int
blk_orphan(data) blk_orphan(data)
struct BLOCK *data; struct BLOCK *data;
{ {
if (!(data->scope->flag & SCOPE_NOSTACK)) { if (!(data->scope->flags & SCOPE_NOSTACK)) {
return 0; return 0;
} }
if ((data->tag->flags & BLOCK_ORPHAN)) { if ((data->tag->flags & BLOCK_ORPHAN)) {

22
gc.c
View File

@ -219,7 +219,7 @@ rb_global_variable(var)
typedef struct RVALUE { typedef struct RVALUE {
union { union {
struct { struct {
unsigned long flag; /* always 0 for freed obj */ unsigned long flags; /* always 0 for freed obj */
struct RVALUE *next; struct RVALUE *next;
} free; } free;
struct RBasic basic; struct RBasic basic;
@ -275,7 +275,7 @@ add_heap()
if (himem < pend) himem = pend; if (himem < pend) himem = pend;
while (p < pend) { while (p < pend) {
p->as.free.flag = 0; p->as.free.flags = 0;
p->as.free.next = freelist; p->as.free.next = freelist;
freelist = p; freelist = p;
p++; p++;
@ -627,7 +627,7 @@ rb_gc_mark(ptr)
break; break;
case T_SCOPE: case T_SCOPE:
if (obj->as.scope.local_vars && (obj->as.scope.flag & SCOPE_MALLOC)) { if (obj->as.scope.local_vars && (obj->as.scope.flags & SCOPE_MALLOC)) {
int n = obj->as.scope.local_tbl[0]+1; int n = obj->as.scope.local_tbl[0]+1;
VALUE *vars = &obj->as.scope.local_vars[-1]; VALUE *vars = &obj->as.scope.local_vars[-1];
@ -689,12 +689,12 @@ gc_sweep()
obj_free((VALUE)p); obj_free((VALUE)p);
} }
if (need_call_final && FL_TEST(p, FL_FINALIZE)) { if (need_call_final && FL_TEST(p, FL_FINALIZE)) {
p->as.free.flag = FL_MARK; /* remain marked */ p->as.free.flags = FL_MARK; /* remain marked */
p->as.free.next = final_list; p->as.free.next = final_list;
final_list = p; final_list = p;
} }
else { else {
p->as.free.flag = 0; p->as.free.flags = 0;
p->as.free.next = freelist; p->as.free.next = freelist;
freelist = p; freelist = p;
} }
@ -728,7 +728,7 @@ gc_sweep()
for (p = final_list; p; p = tmp) { for (p = final_list; p; p = tmp) {
tmp = p->as.free.next; tmp = p->as.free.next;
run_final((VALUE)p); run_final((VALUE)p);
p->as.free.flag = 0; p->as.free.flags = 0;
p->as.free.next = freelist; p->as.free.next = freelist;
freelist = p; freelist = p;
} }
@ -739,7 +739,7 @@ void
rb_gc_force_recycle(p) rb_gc_force_recycle(p)
VALUE p; VALUE p;
{ {
RANY(p)->as.free.flag = 0; RANY(p)->as.free.flags = 0;
RANY(p)->as.free.next = freelist; RANY(p)->as.free.next = freelist;
freelist = RANY(p); freelist = RANY(p);
} }
@ -852,11 +852,11 @@ obj_free(obj)
case T_SCOPE: case T_SCOPE:
if (RANY(obj)->as.scope.local_vars && if (RANY(obj)->as.scope.local_vars &&
RANY(obj)->as.scope.flag != SCOPE_ALLOCA) { RANY(obj)->as.scope.flags != SCOPE_ALLOCA) {
VALUE *vars = RANY(obj)->as.scope.local_vars-1; VALUE *vars = RANY(obj)->as.scope.local_vars-1;
if (vars[0] == 0) if (vars[0] == 0)
RUBY_CRITICAL(free(RANY(obj)->as.scope.local_tbl)); RUBY_CRITICAL(free(RANY(obj)->as.scope.local_tbl));
if (RANY(obj)->as.scope.flag&SCOPE_MALLOC) if (RANY(obj)->as.scope.flags & SCOPE_MALLOC)
RUBY_CRITICAL(free(vars)); RUBY_CRITICAL(free(vars));
} }
break; break;
@ -1257,11 +1257,11 @@ rb_gc_call_finalizer_at_exit()
while (p < pend) { while (p < pend) {
if (BUILTIN_TYPE(p) == T_DATA && if (BUILTIN_TYPE(p) == T_DATA &&
DATA_PTR(p) && RANY(p)->as.data.dfree) { DATA_PTR(p) && RANY(p)->as.data.dfree) {
p->as.free.flag = 0; p->as.free.flags = 0;
(*RANY(p)->as.data.dfree)(DATA_PTR(p)); (*RANY(p)->as.data.dfree)(DATA_PTR(p));
} }
else if (BUILTIN_TYPE(p) == T_FILE) { else if (BUILTIN_TYPE(p) == T_FILE) {
p->as.free.flag = 0; p->as.free.flags = 0;
rb_io_fptr_finalize(RANY(p)->as.file.fptr); rb_io_fptr_finalize(RANY(p)->as.file.fptr);
} }
p++; p++;

View File

@ -107,6 +107,7 @@ VALUE rb_exc_new3 _((VALUE, VALUE));
NORETURN(void rb_loaderror __((const char*, ...))); NORETURN(void rb_loaderror __((const char*, ...)));
void rb_compile_error __((const char*, ...)); void rb_compile_error __((const char*, ...));
void rb_compile_error_append __((const char*, ...)); void rb_compile_error_append __((const char*, ...));
NORETURN(void rb_load_fail _((char*)));
NORETURN(void rb_error_frozen _((char*))); NORETURN(void rb_error_frozen _((char*)));
/* eval.c */ /* eval.c */
NORETURN(void rb_exc_raise _((VALUE))); NORETURN(void rb_exc_raise _((VALUE)));

8
io.c
View File

@ -1325,18 +1325,18 @@ rb_io_flags_mode(flags)
} }
static int static int
rb_sysopen(fname, flag, mode) rb_sysopen(fname, flags, mode)
char *fname; char *fname;
int flag; int flags;
unsigned int mode; unsigned int mode;
{ {
int fd; int fd;
fd = open(fname, flag, mode); fd = open(fname, flags, mode);
if (fd < 0) { if (fd < 0) {
if (errno == EMFILE || errno == ENFILE) { if (errno == EMFILE || errno == ENFILE) {
rb_gc(); rb_gc();
fd = open(fname, flag, mode); fd = open(fname, flags, mode);
} }
if (fd < 0) { if (fd < 0) {
rb_sys_fail(fname); rb_sys_fail(fname);

View File

@ -28,7 +28,7 @@ class RubyLex
include RubyToken include RubyToken
class << self class << self
attr :debug_level, TRUE attr_accessor :debug_level
def debug? def debug?
@debug_level > 0 @debug_level > 0
end end
@ -54,14 +54,14 @@ class RubyLex
@exception_on_syntax_error = true @exception_on_syntax_error = true
end end
attr :skip_space, true attr_accessor :skip_space
attr :readed_auto_clean_up, true attr_accessor :readed_auto_clean_up
attr :exception_on_syntax_error, true attr_accessor :exception_on_syntax_error
attr :seek attr_reader :seek
attr :char_no attr_reader :char_no
attr :line_no attr_reader :line_no
attr :indent attr_reader :indent
# io functions # io functions
def set_input(io, p = nil) def set_input(io, p = nil)
@ -203,7 +203,7 @@ class RubyLex
@here_header = false @here_header = false
prompt prompt
@continue = FALSE @continue = false
@line = "" @line = ""
@exp_line_no = @line_no @exp_line_no = @line_no
@ -212,7 +212,7 @@ class RubyLex
def each_top_level_statement def each_top_level_statement
initialize_input initialize_input
loop do loop do
@continue = FALSE @continue = false
prompt prompt
unless l = lex unless l = lex
break if @line == '' break if @line == ''
@ -315,7 +315,7 @@ class RubyLex
end end
@OP.def_rules(" ", "\t", "\f", "\r", "\13") do @OP.def_rules(" ", "\t", "\f", "\r", "\13") do
@space_seen = TRUE @space_seen = true
while getc =~ /[ \t\f\r\13]/; end while getc =~ /[ \t\f\r\13]/; end
ungetc ungetc
Token(TkSPACE) Token(TkSPACE)
@ -342,9 +342,9 @@ class RubyLex
print "\\n\n" if RubyLex.debug? print "\\n\n" if RubyLex.debug?
case @lex_state case @lex_state
when EXPR_BEG, EXPR_FNAME, EXPR_DOT when EXPR_BEG, EXPR_FNAME, EXPR_DOT
@continue = TRUE @continue = true
else else
@continue = FALSE @continue = false
@lex_state = EXPR_BEG @lex_state = EXPR_BEG
end end
@here_header = false @here_header = false
@ -835,8 +835,8 @@ class RubyLex
end end
type = TkINTEGER type = TkINTEGER
allow_point = TRUE allow_point = true
allow_e = TRUE allow_e = true
while ch = getc while ch = getc
case ch case ch
when /[0-9_]/ when /[0-9_]/

View File

@ -5,7 +5,7 @@
module Observable module Observable
def add_observer(observer) def add_observer(observer)
@observer_peers = [] unless defined? @observer_peers @observer_peers = [] unless defined? @observer_peers
unless defined? observer.update unless observer.respond_to? :update
raise NameError, "observer needs to respond to `update'" raise NameError, "observer needs to respond to `update'"
end end
@observer_peers.push observer @observer_peers.push observer

View File

@ -3392,8 +3392,7 @@ yylex()
return c; return c;
case '{': case '{':
if (lex_state != EXPR_END && if (lex_state != EXPR_END && lex_state != EXPR_ARG)
lex_state != EXPR_ARG)
c = tLBRACE; c = tLBRACE;
lex_state = EXPR_BEG; lex_state = EXPR_BEG;
return c; return c;
@ -4694,7 +4693,7 @@ top_local_setup()
i = ruby_scope->local_tbl?ruby_scope->local_tbl[0]:0; i = ruby_scope->local_tbl?ruby_scope->local_tbl[0]:0;
if (i < len) { if (i < len) {
if (i == 0 || (ruby_scope->flag & SCOPE_MALLOC) == 0) { if (i == 0 || (ruby_scope->flags & SCOPE_MALLOC) == 0) {
VALUE *vars = ALLOC_N(VALUE, len+1); VALUE *vars = ALLOC_N(VALUE, len+1);
if (ruby_scope->local_vars) { if (ruby_scope->local_vars) {
*vars++ = ruby_scope->local_vars[-1]; *vars++ = ruby_scope->local_vars[-1];
@ -4706,7 +4705,7 @@ top_local_setup()
rb_mem_clear(vars, len); rb_mem_clear(vars, len);
} }
ruby_scope->local_vars = vars; ruby_scope->local_vars = vars;
ruby_scope->flag |= SCOPE_MALLOC; ruby_scope->flags |= SCOPE_MALLOC;
} }
else { else {
VALUE *vars = ruby_scope->local_vars-1; VALUE *vars = ruby_scope->local_vars-1;

View File

@ -68,14 +68,14 @@ range_initialize(argc, argv, obj)
VALUE *argv; VALUE *argv;
VALUE obj; VALUE obj;
{ {
VALUE beg, end, flag; VALUE beg, end, flags;
rb_scan_args(argc, argv, "21", &beg, &end, &flag); rb_scan_args(argc, argv, "21", &beg, &end, &flags);
/* Ranges are immutable, so that they should be initialized only once. */ /* Ranges are immutable, so that they should be initialized only once. */
if (rb_ivar_defined(obj, id_beg)) { if (rb_ivar_defined(obj, id_beg)) {
rb_raise(rb_eNameError, "`initialize' called twice"); rb_raise(rb_eNameError, "`initialize' called twice");
} }
range_init(obj, beg, end, RTEST(flag)); range_init(obj, beg, end, RTEST(flags));
return Qnil; return Qnil;
} }

26
re.c
View File

@ -389,9 +389,9 @@ rb_reg_kcode_m(re)
} }
static Regexp* static Regexp*
make_regexp(s, len, flag) make_regexp(s, len, flags)
const char *s; const char *s;
int len, flag; int len, flags;
{ {
Regexp *rp; Regexp *rp;
char *err; char *err;
@ -408,8 +408,8 @@ make_regexp(s, len, flag)
rp->buffer = ALLOC_N(char, 16); rp->buffer = ALLOC_N(char, 16);
rp->allocated = 16; rp->allocated = 16;
rp->fastmap = ALLOC_N(char, 256); rp->fastmap = ALLOC_N(char, 256);
if (flag) { if (flags) {
rp->options = flag; rp->options = flags;
} }
err = re_compile_pattern(s, len, rp); err = re_compile_pattern(s, len, rp);
if (err != NULL) { if (err != NULL) {
@ -973,30 +973,30 @@ rb_reg_initialize_m(argc, argv, self)
VALUE self; VALUE self;
{ {
VALUE src; VALUE src;
int flag = 0; int flags = 0;
if (argc == 0 || argc > 3) { if (argc == 0 || argc > 3) {
rb_raise(rb_eArgError, "wrong # of argument"); rb_raise(rb_eArgError, "wrong # of argument");
} }
if (argc >= 2) { if (argc >= 2) {
if (FIXNUM_P(argv[1])) flag = FIX2INT(argv[1]); if (FIXNUM_P(argv[1])) flags = FIX2INT(argv[1]);
else if (RTEST(argv[1])) flag = RE_OPTION_IGNORECASE; else if (RTEST(argv[1])) flags = RE_OPTION_IGNORECASE;
} }
if (argc == 3) { if (argc == 3) {
char *kcode = STR2CSTR(argv[2]); char *kcode = STR2CSTR(argv[2]);
switch (kcode[0]) { switch (kcode[0]) {
case 'n': case 'N': case 'n': case 'N':
flag |= 16; flags |= 16;
break; break;
case 'e': case 'E': case 'e': case 'E':
flag |= 32; flags |= 32;
break; break;
case 's': case 'S': case 's': case 'S':
flag |= 48; flags |= 48;
break; break;
case 'u': case 'U': case 'u': case 'U':
flag |= 64; flags |= 64;
break; break;
default: default:
break; break;
@ -1006,14 +1006,14 @@ rb_reg_initialize_m(argc, argv, self)
src = argv[0]; src = argv[0];
if (TYPE(src) == T_REGEXP) { if (TYPE(src) == T_REGEXP) {
rb_reg_check(src); rb_reg_check(src);
rb_reg_initialize(self, RREGEXP(src)->str, RREGEXP(src)->len, flag); rb_reg_initialize(self, RREGEXP(src)->str, RREGEXP(src)->len, flags);
} }
else { else {
char *p; char *p;
int len; int len;
p = rb_str2cstr(src, &len); p = rb_str2cstr(src, &len);
rb_reg_initialize(self, p, len, flag); rb_reg_initialize(self, p, len, flags);
} }
return self; return self;
} }

View File

@ -1288,17 +1288,20 @@ str_gsub(argc, argv, str, bang)
if (str_independent(str)) { if (str_independent(str)) {
free(RSTRING(str)->ptr); free(RSTRING(str)->ptr);
} }
else {
RSTRING(str)->orig = 0;
}
} }
else { else {
NEWOBJ(dup, struct RString); NEWOBJ(dup, struct RString);
OBJSETUP(dup, rb_cString, T_STRING); OBJSETUP(dup, rb_cString, T_STRING);
OBJ_INFECT(dup, str); OBJ_INFECT(dup, str);
str = (VALUE)dup; str = (VALUE)dup;
dup->orig = 0;
} }
RSTRING(str)->ptr = buf; RSTRING(str)->ptr = buf;
RSTRING(str)->len = len = bp - buf; RSTRING(str)->len = len = bp - buf;
RSTRING(str)->ptr[len] = '\0'; RSTRING(str)->ptr[len] = '\0';
RSTRING(str)->orig = 0;
if (tainted) OBJ_TAINT(str); if (tainted) OBJ_TAINT(str);
return str; return str;