From 765255b737235a65daea6679c4672541bb67ecb4 Mon Sep 17 00:00:00 2001 From: matz Date: Fri, 2 Feb 2001 11:38:20 +0000 Subject: * 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 --- ChangeLog | 17 ++++++++++++ ToDo | 3 +- array.c | 28 +++++++++++++++++-- env.h | 2 +- eval.c | 79 +++++++++++++++++++++++++++++++++++++++-------------- gc.c | 22 +++++++-------- intern.h | 1 + io.c | 8 +++--- lib/irb/ruby-lex.rb | 30 ++++++++++---------- lib/observer.rb | 2 +- parse.y | 7 ++--- range.c | 6 ++-- re.c | 26 +++++++++--------- string.c | 5 +++- 14 files changed, 159 insertions(+), 77 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9e900ef5ed..010416d277 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +Fri Feb 2 16:14:51 2001 Yukihiro Matsumoto + + * 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 * configure.in: gcc-2.95.2-7(cygwin) support. @@ -5,6 +13,15 @@ Wed Jan 31 22:27:29 2001 WATANABE Hirofumi * cygwin/GNUmakefile: ditto. +Tue Jan 30 17:56:48 2001 Yukihiro Matsumoto + + * array.c (rb_ary_fetch): new method. + +Mon Jan 29 17:36:19 2001 TOYOFUKU Chikanobu + + * 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 * eval.c (block_pass): return from block jumps directory to diff --git a/ToDo b/ToDo index 52901914af..f2178e17de 100644 --- a/ToDo +++ b/ToDo @@ -44,11 +44,13 @@ Hacking Interpreter * warn for inconsistent local variable usage (lv m and method m at the same time). * MicroRuby * Built-in Interactive Ruby. +* regex /\ba/ on "[a in HIRAGANA]a[a in HIRAGANA]" Standard Libraries - Module#define_method which takes a name and a body (block, proc or method). - Enume#inject +- Array#fetch * Enumerable#sort_by for Schwartzian transformation * String#scanf(?) * Object#fmt(?) @@ -69,7 +71,6 @@ Standard Libraries * fork_and_kill_other_threads. * way to specify immortal (fork endurance) thread; * or raise ForkException to every thread but fork caller. -* Array#fetch * Hash::new{default} or recommend Hash#fetch? Extension Libraries diff --git a/array.c b/array.c index 1dc1627fb8..93b3659d06 100644 --- a/array.c +++ b/array.c @@ -384,7 +384,7 @@ rb_ary_entry(ary, offset) if (RARRAY(ary)->len == 0) return Qnil; if (offset < 0) { - offset = RARRAY(ary)->len + offset; + offset += RARRAY(ary)->len; } if (offset < 0 || RARRAY(ary)->len <= offset) { return Qnil; @@ -431,7 +431,7 @@ rb_ary_aref(argc, argv, ary) beg = NUM2LONG(arg1); len = NUM2LONG(arg2); if (beg < 0) { - beg = RARRAY(ary)->len + beg; + beg += RARRAY(ary)->len; } return rb_ary_subseq(ary, beg, len); } @@ -480,6 +480,27 @@ rb_ary_last(ary) 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 rb_ary_index(ary, val) VALUE ary; @@ -979,7 +1000,7 @@ rb_ary_sort_bang(ary) VALUE 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 */ 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_aset, -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, "last", rb_ary_last, 0); rb_define_method(rb_cArray, "concat", rb_ary_concat, 1); diff --git a/env.h b/env.h index 7060fbec8f..2ec325efa4 100644 --- a/env.h +++ b/env.h @@ -37,7 +37,7 @@ extern struct SCOPE { struct RBasic super; ID *local_tbl; VALUE *local_vars; - int flag; + int flags; } *ruby_scope; #define SCOPE_ALLOCA 0 diff --git a/eval.c b/eval.c index 3292cc411d..26ed7e39ce 100644 --- a/eval.c +++ b/eval.c @@ -602,6 +602,8 @@ struct RVarmap *ruby_dyna_vars; ruby_dyna_vars = 0; #define POP_VARS() \ + if (_old && (ruby_scope->flags & SCOPE_DONT_RECYCLE)) \ + FL_SET(_old, DVAR_DONT_RECYCLE); \ ruby_dyna_vars = _old; \ } @@ -808,7 +810,7 @@ static VALUE ruby_wrapper; /* security wrapper */ OBJSETUP(_scope, 0, T_SCOPE); \ _scope->local_tbl = 0; \ _scope->local_vars = 0; \ - _scope->flag = 0; \ + _scope->flags = 0; \ _old = ruby_scope; \ ruby_scope = _scope; \ scope_vmode = SCOPE_PUBLIC; @@ -819,18 +821,18 @@ static rb_thread_t main_thread; static void scope_dup _((struct SCOPE *)); #define POP_SCOPE() \ - if (ruby_scope->flag & SCOPE_DONT_RECYCLE) {\ + if (ruby_scope->flags & SCOPE_DONT_RECYCLE) {\ 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_tbl = 0; \ - if (!(ruby_scope->flag & SCOPE_DONT_RECYCLE) && \ + if (!(ruby_scope->flags & SCOPE_DONT_RECYCLE) && \ ruby_scope != top_scope) { \ rb_gc_force_recycle((VALUE)ruby_scope);\ } \ } \ - ruby_scope->flag |= SCOPE_NOSTACK; \ + ruby_scope->flags |= SCOPE_NOSTACK; \ ruby_scope = _old; \ scope_vmode = _vmode; \ } @@ -1305,7 +1307,7 @@ rb_eval_cmd(cmd, arg) 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); ruby_scope = saved_scope; ruby_safe_level = safe; @@ -2234,10 +2236,9 @@ rb_eval(self, n) state = EXEC_TAG(); if (state == 0) { + PUSH_ITER(ITER_PRE); if (nd_type(node) == NODE_ITER) { - PUSH_ITER(ITER_PRE); result = rb_eval(self, node->nd_iter); - POP_ITER(); } else { VALUE recv; @@ -2245,13 +2246,14 @@ rb_eval(self, n) int line = ruby_sourceline; _block.flags &= ~BLOCK_D_SCOPE; + BEGIN_CALLARGS; recv = rb_eval(self, node->nd_iter); - PUSH_ITER(ITER_PRE); + END_CALLARGS; ruby_sourcefile = file; ruby_sourceline = line; result = rb_call(CLASS_OF(recv),recv,each,0,0,0); - POP_ITER(); } + POP_ITER(); } else if (_block.tag->dst == state) { state &= TAG_MASK; @@ -3580,8 +3582,11 @@ rb_yield_0(val, self, klass, acheck) pop_state: POP_ITER(); POP_CLASS(); +#if 0 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; 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(); ruby_block = block; ruby_frame = ruby_frame->prev; - if (ruby_scope->flag & SCOPE_DONT_RECYCLE) + if (ruby_scope->flags & SCOPE_DONT_RECYCLE) scope_dup(old_scope); ruby_scope = old_scope; if (state) { @@ -4739,7 +4760,6 @@ eval(self, src, scope, file, line) } Data_Get_Struct(scope, struct BLOCK, data); - /* PUSH BLOCK from data */ frame = data->frame; frame.tmp = ruby_frame; /* gc protection */ @@ -4785,14 +4805,33 @@ eval(self, src, scope, file, line) POP_CLASS(); ruby_in_eval--; if (!NIL_P(scope)) { + int dont_recycle = ruby_scope->flags & SCOPE_DONT_RECYCLE; + ruby_frame = frame.tmp; - if (ruby_scope->flag & SCOPE_DONT_RECYCLE) - scope_dup(old_scope); ruby_scope = old_scope; ruby_block = old_block; ruby_dyna_vars = old_dyna_vars; data->vmode = scope_vmode; /* write back visibility mode */ 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 { ruby_frame->iter = iter; @@ -5116,7 +5155,7 @@ rb_load(fname, wrap) } } 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 */ free(ruby_scope->local_tbl); } @@ -5896,8 +5935,8 @@ scope_dup(scope) ID *tbl; VALUE *vars; - scope->flag |= SCOPE_DONT_RECYCLE; - if (scope->flag & SCOPE_MALLOC) return; + scope->flags |= SCOPE_DONT_RECYCLE; + if (scope->flags & SCOPE_MALLOC) return; if (scope->local_tbl) { tbl = scope->local_tbl; @@ -5905,7 +5944,7 @@ scope_dup(scope) *vars++ = scope->local_vars[-1]; MEMCPY(vars, scope->local_vars, VALUE, tbl[0]); scope->local_vars = vars; - scope->flag |= SCOPE_MALLOC; + scope->flags |= SCOPE_MALLOC; } } @@ -6163,7 +6202,7 @@ static int blk_orphan(data) struct BLOCK *data; { - if (!(data->scope->flag & SCOPE_NOSTACK)) { + if (!(data->scope->flags & SCOPE_NOSTACK)) { return 0; } if ((data->tag->flags & BLOCK_ORPHAN)) { diff --git a/gc.c b/gc.c index c40d36aed6..989fbfe74c 100644 --- a/gc.c +++ b/gc.c @@ -219,7 +219,7 @@ rb_global_variable(var) typedef struct RVALUE { union { struct { - unsigned long flag; /* always 0 for freed obj */ + unsigned long flags; /* always 0 for freed obj */ struct RVALUE *next; } free; struct RBasic basic; @@ -275,7 +275,7 @@ add_heap() if (himem < pend) himem = pend; while (p < pend) { - p->as.free.flag = 0; + p->as.free.flags = 0; p->as.free.next = freelist; freelist = p; p++; @@ -627,7 +627,7 @@ rb_gc_mark(ptr) break; 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; VALUE *vars = &obj->as.scope.local_vars[-1]; @@ -689,12 +689,12 @@ gc_sweep() obj_free((VALUE)p); } 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; final_list = p; } else { - p->as.free.flag = 0; + p->as.free.flags = 0; p->as.free.next = freelist; freelist = p; } @@ -728,7 +728,7 @@ gc_sweep() for (p = final_list; p; p = tmp) { tmp = p->as.free.next; run_final((VALUE)p); - p->as.free.flag = 0; + p->as.free.flags = 0; p->as.free.next = freelist; freelist = p; } @@ -739,7 +739,7 @@ void rb_gc_force_recycle(p) VALUE p; { - RANY(p)->as.free.flag = 0; + RANY(p)->as.free.flags = 0; RANY(p)->as.free.next = freelist; freelist = RANY(p); } @@ -852,11 +852,11 @@ obj_free(obj) case T_SCOPE: 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; if (vars[0] == 0) 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)); } break; @@ -1257,11 +1257,11 @@ rb_gc_call_finalizer_at_exit() while (p < pend) { if (BUILTIN_TYPE(p) == T_DATA && 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)); } 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); } p++; diff --git a/intern.h b/intern.h index 25b2e8e93e..58e39c705f 100644 --- a/intern.h +++ b/intern.h @@ -107,6 +107,7 @@ VALUE rb_exc_new3 _((VALUE, VALUE)); NORETURN(void rb_loaderror __((const char*, ...))); void rb_compile_error __((const char*, ...)); void rb_compile_error_append __((const char*, ...)); +NORETURN(void rb_load_fail _((char*))); NORETURN(void rb_error_frozen _((char*))); /* eval.c */ NORETURN(void rb_exc_raise _((VALUE))); diff --git a/io.c b/io.c index e0feee93dc..061e466fbc 100644 --- a/io.c +++ b/io.c @@ -1325,18 +1325,18 @@ rb_io_flags_mode(flags) } static int -rb_sysopen(fname, flag, mode) +rb_sysopen(fname, flags, mode) char *fname; - int flag; + int flags; unsigned int mode; { int fd; - fd = open(fname, flag, mode); + fd = open(fname, flags, mode); if (fd < 0) { if (errno == EMFILE || errno == ENFILE) { rb_gc(); - fd = open(fname, flag, mode); + fd = open(fname, flags, mode); } if (fd < 0) { rb_sys_fail(fname); diff --git a/lib/irb/ruby-lex.rb b/lib/irb/ruby-lex.rb index 534870e329..24db325214 100644 --- a/lib/irb/ruby-lex.rb +++ b/lib/irb/ruby-lex.rb @@ -28,7 +28,7 @@ class RubyLex include RubyToken class << self - attr :debug_level, TRUE + attr_accessor :debug_level def debug? @debug_level > 0 end @@ -54,14 +54,14 @@ class RubyLex @exception_on_syntax_error = true end - attr :skip_space, true - attr :readed_auto_clean_up, true - attr :exception_on_syntax_error, true + attr_accessor :skip_space + attr_accessor :readed_auto_clean_up + attr_accessor :exception_on_syntax_error - attr :seek - attr :char_no - attr :line_no - attr :indent + attr_reader :seek + attr_reader :char_no + attr_reader :line_no + attr_reader :indent # io functions def set_input(io, p = nil) @@ -203,7 +203,7 @@ class RubyLex @here_header = false prompt - @continue = FALSE + @continue = false @line = "" @exp_line_no = @line_no @@ -212,7 +212,7 @@ class RubyLex def each_top_level_statement initialize_input loop do - @continue = FALSE + @continue = false prompt unless l = lex break if @line == '' @@ -315,7 +315,7 @@ class RubyLex end @OP.def_rules(" ", "\t", "\f", "\r", "\13") do - @space_seen = TRUE + @space_seen = true while getc =~ /[ \t\f\r\13]/; end ungetc Token(TkSPACE) @@ -342,9 +342,9 @@ class RubyLex print "\\n\n" if RubyLex.debug? case @lex_state when EXPR_BEG, EXPR_FNAME, EXPR_DOT - @continue = TRUE + @continue = true else - @continue = FALSE + @continue = false @lex_state = EXPR_BEG end @here_header = false @@ -835,8 +835,8 @@ class RubyLex end type = TkINTEGER - allow_point = TRUE - allow_e = TRUE + allow_point = true + allow_e = true while ch = getc case ch when /[0-9_]/ diff --git a/lib/observer.rb b/lib/observer.rb index 08e75f5125..e1b249e885 100644 --- a/lib/observer.rb +++ b/lib/observer.rb @@ -5,7 +5,7 @@ module Observable def add_observer(observer) @observer_peers = [] unless defined? @observer_peers - unless defined? observer.update + unless observer.respond_to? :update raise NameError, "observer needs to respond to `update'" end @observer_peers.push observer diff --git a/parse.y b/parse.y index 6603f51a62..00ca543606 100644 --- a/parse.y +++ b/parse.y @@ -3392,8 +3392,7 @@ yylex() return c; case '{': - if (lex_state != EXPR_END && - lex_state != EXPR_ARG) + if (lex_state != EXPR_END && lex_state != EXPR_ARG) c = tLBRACE; lex_state = EXPR_BEG; return c; @@ -4694,7 +4693,7 @@ top_local_setup() i = ruby_scope->local_tbl?ruby_scope->local_tbl[0]:0; 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); if (ruby_scope->local_vars) { *vars++ = ruby_scope->local_vars[-1]; @@ -4706,7 +4705,7 @@ top_local_setup() rb_mem_clear(vars, len); } ruby_scope->local_vars = vars; - ruby_scope->flag |= SCOPE_MALLOC; + ruby_scope->flags |= SCOPE_MALLOC; } else { VALUE *vars = ruby_scope->local_vars-1; diff --git a/range.c b/range.c index 68229b7696..2ad20df83d 100644 --- a/range.c +++ b/range.c @@ -68,14 +68,14 @@ range_initialize(argc, argv, obj) VALUE *argv; 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. */ if (rb_ivar_defined(obj, id_beg)) { rb_raise(rb_eNameError, "`initialize' called twice"); } - range_init(obj, beg, end, RTEST(flag)); + range_init(obj, beg, end, RTEST(flags)); return Qnil; } diff --git a/re.c b/re.c index 865d767813..ef614dd6f6 100644 --- a/re.c +++ b/re.c @@ -389,9 +389,9 @@ rb_reg_kcode_m(re) } static Regexp* -make_regexp(s, len, flag) +make_regexp(s, len, flags) const char *s; - int len, flag; + int len, flags; { Regexp *rp; char *err; @@ -408,8 +408,8 @@ make_regexp(s, len, flag) rp->buffer = ALLOC_N(char, 16); rp->allocated = 16; rp->fastmap = ALLOC_N(char, 256); - if (flag) { - rp->options = flag; + if (flags) { + rp->options = flags; } err = re_compile_pattern(s, len, rp); if (err != NULL) { @@ -973,30 +973,30 @@ rb_reg_initialize_m(argc, argv, self) VALUE self; { VALUE src; - int flag = 0; + int flags = 0; if (argc == 0 || argc > 3) { rb_raise(rb_eArgError, "wrong # of argument"); } if (argc >= 2) { - if (FIXNUM_P(argv[1])) flag = FIX2INT(argv[1]); - else if (RTEST(argv[1])) flag = RE_OPTION_IGNORECASE; + if (FIXNUM_P(argv[1])) flags = FIX2INT(argv[1]); + else if (RTEST(argv[1])) flags = RE_OPTION_IGNORECASE; } if (argc == 3) { char *kcode = STR2CSTR(argv[2]); switch (kcode[0]) { case 'n': case 'N': - flag |= 16; + flags |= 16; break; case 'e': case 'E': - flag |= 32; + flags |= 32; break; case 's': case 'S': - flag |= 48; + flags |= 48; break; case 'u': case 'U': - flag |= 64; + flags |= 64; break; default: break; @@ -1006,14 +1006,14 @@ rb_reg_initialize_m(argc, argv, self) src = argv[0]; if (TYPE(src) == T_REGEXP) { 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 { char *p; int len; p = rb_str2cstr(src, &len); - rb_reg_initialize(self, p, len, flag); + rb_reg_initialize(self, p, len, flags); } return self; } diff --git a/string.c b/string.c index cb7e86e84c..adc1c8d3c2 100644 --- a/string.c +++ b/string.c @@ -1288,17 +1288,20 @@ str_gsub(argc, argv, str, bang) if (str_independent(str)) { free(RSTRING(str)->ptr); } + else { + RSTRING(str)->orig = 0; + } } else { NEWOBJ(dup, struct RString); OBJSETUP(dup, rb_cString, T_STRING); OBJ_INFECT(dup, str); str = (VALUE)dup; + dup->orig = 0; } RSTRING(str)->ptr = buf; RSTRING(str)->len = len = bp - buf; RSTRING(str)->ptr[len] = '\0'; - RSTRING(str)->orig = 0; if (tainted) OBJ_TAINT(str); return str; -- cgit v1.2.3