From 8bf1c909dc31fd4bcdc1488cda9fe89a62bc2830 Mon Sep 17 00:00:00 2001 From: Yukihiro Matsumoto Date: Fri, 19 May 1995 15:33:23 +0900 Subject: version 0.76 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://cache.ruby-lang.org/pub/ruby/1.0/ruby-0.76.tar.gz Fri May 19 15:33:23 1995 Yukihiro Matsumoto * version 0.76 Fri May 19 00:48:08 1995 Yukihiro Matsumoto (matz@dyna) * string.c (Fstr_each): イテレータブロック中で文字列の変更が行われ たかどうかをチェック.ポインタの値が変わっていれば例外を発生する. * ruby-mode.el: ruby-electric-braceの新設. Thu May 18 12:27:23 1995 Yukihiro Matsumoto * string.c (Fstr_tr): trの置換対象に`\0'を含む時に正しく置換を行わ ないバグがあった.更に置換文字列をASCII順に指定しないと動作しな い問題もあった.結果としてtrを書き換えたので,copyrightの問題は 無くなった(と思う). * gc.c (gc): the_scopeをマークしていなかったので,ローカル変数が間 違って開放される場合があった. * gc.c (mark_locations_array): 若干の高速化. Mon May 15 11:43:49 1995 Yukihiro Matsumoto * ext/extmk.rb.in: Dynamic Loadモジュールのコンパイル用チェックを 行うruby script.autoconfに近い感覚で使える.新しいモジュールを 提供したい人はextの下にディレクトリを作るだけで良い.必須のファ イルはファイル名の一覧を記録した`MANIFEST'というファイルのみ.必 要に応じて`depend'(ファイルの依存関係を記述するファイル gcc -MM の出力),`extconf.rb'(コンパイル用にライブラリと関数の存在チェッ クするファイル)を用意できる. * eval.c (rb_call): rubyメソッドの引数チェック時に未初期化の jmp_bufを使用していた. * parse.y: `or'と`and'の優先順位を同じにした. Wed May 3 18:21:36 1995 Yukihiro Matsumoto (matz@dyna) * dln.c: Linuxでは`__.SYMDEF/'であった. * dln.c: system callのエラーチェックを忘れていた. Wed Apr 26 09:50:56 1995 Yukihiro Matsumoto (matz@ix-02) * parse.y: イテレータブロックの変数宣言を`|'で括るようにした.これ でイテレータ変数がない時は宣言そのものを省略できる.文法の変更は 久しぶりだ. Tue Apr 25 12:04:17 1995 Yukihiro Matsumoto (matz@ix-02) * eval.c(require): loadからダイナミックロードの機能を移してきた. さらに拡張子の補完機能を追加してユーザがdln/dlopenの差を意識する 必要のないようにした. * string.c(sub,sub): イテレータとしても動作するように. * object.c: init_object -> initialize. Mon Apr 24 14:22:39 1995 Yukihiro Matsumoto (matz@ix-02) * NEWS-OS 3.4対応 * io.c: Solarisのstdioの動作が違うようだ.signalでEOFを返してしま う….perlでも同様の問題がある. Fri Apr 21 20:04:39 1995 Yukihiro Matsumoto (matz@ix-02) * version 0.75 * signal.c: trapがなくなっていた.うーむ. * configure: Solaris 2.3対応. * io.c: #elifのないcppもある. * dir.c: autoconf 2.xへの対応が不十分 Thu Apr 20 12:31:24 1995 Yukihiro Matsumoto (matz@ix-02) * version 0.74 * env.h, gc.c, regex.c: IRIXへの移植対応 * configure: picを生成するoptionの検出のため,システムタイプをチェッ クするように. Tue Apr 18 19:08:17 1995 Yukihiro Matsumoto (matz@ix-02) * gc.c(xrealloc): ptr=nilの時,malloc()と同じ働きを * array.c(astore): 空の配列の0番目の要素に代入するとsize=0で realloc()を呼んでいた. * configure, glob.c: Solaris 2.xでコンパイルできるように --- string.c | 238 +++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 134 insertions(+), 104 deletions(-) (limited to 'string.c') diff --git a/string.c b/string.c index c733faf9e4..80935255d2 100644 --- a/string.c +++ b/string.c @@ -6,7 +6,7 @@ $Date: 1995/01/10 10:43:01 $ created at: Mon Aug 9 17:12:58 JST 1993 - Copyright (C) 1995 Yukihiro Matsumoto + Copyright (C) 1993-1995 Yukihiro Matsumoto ************************************************/ @@ -561,7 +561,7 @@ Fstr_upto(beg, end) } static VALUE -Fstr_aref_internal(str, indx) +str_aref(str, indx) struct RString *str; VALUE indx; { @@ -619,7 +619,7 @@ Fstr_aref(argc, argv, str) if (rb_scan_args(argc, argv, "11", &arg1, &arg2) == 2) { return str_substr(str, NUM2INT(arg1), NUM2INT(arg2)); } - return Fstr_aref_internal(str, arg1); + return str_aref(str, arg1); } static void @@ -676,6 +676,21 @@ str_sub(str, pat, val, once) { int beg, end, offset, n; + Check_Type(val, T_STRING); + str_modify(str); + + switch (TYPE(pat)) { + case T_REGEXP: + break; + + case T_STRING: + return str_sub(str, re_regcomp(pat), val, once); + + default: + /* type failed */ + Check_Type(pat, T_REGEXP); + } + for (offset=0, n=0; (beg=research(pat, str, offset)) >= 0; offset=BEG(0)+STRLEN(val)) { @@ -690,7 +705,7 @@ str_sub(str, pat, val, once) } static VALUE -Fstr_aset_internal(str, indx, val) +str_aset(str, indx, val) struct RString *str; VALUE indx, val; { @@ -771,52 +786,20 @@ Fstr_aset(argc, argv, str) str_replace(str, beg, len, arg3); return arg3; } - return Fstr_aset_internal(str, arg1, arg2); -} - -static VALUE -Fstr_sub_internal(str, pat, val, once) - VALUE str, pat, val; - int once; -{ - Check_Type(val, T_STRING); - str_modify(str); - - switch (TYPE(pat)) { - case T_REGEXP: - return str_sub(str, pat, val, once); - - case T_STRING: - return str_sub(str, re_regcomp(pat), val, once); - - default: - /* type failed */ - Check_Type(pat, T_REGEXP); - } - return Qnil; /* not reached */ -} - -static VALUE -Fstr_sub(str, pat, val) - VALUE str, pat, val; -{ - return Fstr_sub_internal(str, pat, val, 1); + return str_aset(str, arg1, arg2); } static VALUE -Fstr_gsub(str, pat, val) - VALUE str, pat, val; -{ - return Fstr_sub_internal(str, pat, val, 0); -} - -static VALUE -Fstr_esub(str, pat) +str_sub_iter(str, pat, once) VALUE str, pat; { VALUE val; int beg, end, offset, n; + if (!iterator_p()) { + Fail("Wrong # of arguments(1 for 2)"); + } + str_modify(str); switch (TYPE(pat)) { case T_REGEXP: @@ -837,34 +820,67 @@ Fstr_esub(str, pat) val = obj_as_string(val); str_replace2(str, beg, END(0)-1, val); offset=BEG(0)+STRLEN(val); + if (once) break; } return (VALUE)str; } -extern VALUE rb_lastline; +static VALUE +Fstr_sub(argc, argv, str) + int argc; + VALUE *argv; + VALUE str; +{ + VALUE pat, val; + + if (rb_scan_args(argc, argv, "11", &pat, &val) == 1) { + return str_sub_iter(str, pat, 1); + } + return str_sub(str, pat, val, 1); +} static VALUE -Fsub(obj, pat, val) - VALUE obj, pat, val; +Fstr_gsub(argc, argv, str) + int argc; + VALUE *argv; + VALUE str; { - Check_Type(rb_lastline, T_STRING); - return Fstr_sub_internal(rb_lastline, pat, val, 1); + VALUE pat, val; + + if (rb_scan_args(argc, argv, "11", &pat, &val) == 1) { + return str_sub_iter(str, pat, 0); + } + return str_sub(str, pat, val, 0); } +extern VALUE rb_lastline; + static VALUE -Fgsub(obj, pat, val) - VALUE obj, pat, val; +Fsub(argc, argv) + int argc; + VALUE *argv; { + VALUE pat, val; + Check_Type(rb_lastline, T_STRING); - return Fstr_sub_internal(rb_lastline, pat, val, 0); + if (rb_scan_args(argc, argv, "11", &pat, &val) == 1) { + return str_sub_iter(rb_lastline, pat, 1); + } + return str_sub(rb_lastline, pat, val, 1); } static VALUE -Fesub(obj, pat) - VALUE obj, pat; +Fgsub(argc, argv) + int argc; + VALUE *argv; { + VALUE pat, val; + Check_Type(rb_lastline, T_STRING); - return Fstr_esub(rb_lastline, pat); + if (rb_scan_args(argc, argv, "11", &pat, &val) == 1) { + return str_sub_iter(rb_lastline, pat, 0); + } + return str_sub(rb_lastline, pat, val, 0); } static VALUE @@ -1077,36 +1093,39 @@ Fstr_tolower(str) } struct tr { - int last, max; + unsigned char gen, now, max; char *p, *pend; } trsrc, trrepl; -static +static char trnext(t) struct tr *t; { - while (t->p < t->pend) { - if (t->max) { - if (++t->last < t->max) - return t->last; - t->last = t->max = 0; - } - else if (t->last && *t->p == '-') { - t->p++; - t->max = *t->p; - if (t->p == t->pend) { - t->p--; - return '-'; - } - else if (t->max < t->last) { - t->last = t->max - 1; - return '-'; + for (;;) { + if (!t->gen) { + if (t->p == t->pend) return -1; + t->now = *t->p++; + if (t->p < t->pend && *t->p == '-') { + t->p++; + if (t->p < t->pend) { + if (t->now > *t->p) { + t->p++; + continue; + } + t->gen = 1; + t->max = *t->p++; + } } - continue; + return t->now; + } + else if (++t->now < t->max) { + return t->now; + } + else { + t->gen = 0; + return t->max; } - return t->last = *t->p++; } - return -1; } static VALUE @@ -1114,8 +1133,8 @@ Fstr_tr(str, src, repl) struct RString *str, *src, *repl; { struct tr trsrc, trrepl; - char trans[256]; int cflag = 0; + char trans[256]; int i, c, save; char *s, *send, *t; @@ -1127,34 +1146,46 @@ Fstr_tr(str, src, repl) } Check_Type(repl, T_STRING); trrepl.p = repl->ptr; trrepl.pend = trrepl.p + repl->len; - trsrc.last = trrepl.last = trsrc.max = trrepl.max = 0; + trsrc.gen = trrepl.gen = 0; + trsrc.now = trrepl.now = 0; + trsrc.max = trrepl.max = 0; - for (i=0; i<256; i++) { - trans[i] = cflag ? 1 : 0; - } - - while ((c = trnext(&trsrc)) >= 0) { - trans[c & 0xff] = cflag ? 0 : 1; - } - - c = 0; - for (i=0; i<256; i++) { - if (trans[i] == 0) { - trans[i] = i; + if (cflag) { + for (i=0; i<256; i++) { + trans[i] = 1; } - else { - c = trnext(&trrepl); - if (c == -1) { - trans[i] = trrepl.last; + while ((c = trnext(&trsrc)) >= 0) { + trans[c & 0xff] = 0; + } + for (i=0; i<256; i++) { + if (trans[i] == 0) { + trans[i] = i; } else { - trans[i] = c; + c = trnext(&trrepl); + if (c == -1) { + trans[i] = trrepl.now; + } + else { + trans[i] = c; + } } } } + else { + char r; + + for (i=0; i<256; i++) { + trans[i] = 0; + } + while ((c = trnext(&trsrc)) >= 0) { + r = trnext(&trrepl); + if (r == -1) r = trrepl.now; + trans[c & 0xff] = r; + } + } str_modify(str); - t = s = str->ptr; send = s + str->len; while (s < send) { c = *s++ & 0xff; @@ -1162,7 +1193,6 @@ Fstr_tr(str, src, repl) *t++ = c; } *t = '\0'; - str->len = t - str->ptr; return (VALUE)str; } @@ -1177,7 +1207,7 @@ tr_setup_table(str, table) char c; tr.p = str->ptr; tr.pend = tr.p + str->len; - tr.last = tr.max = 0; + tr.gen = tr.now = tr.max = 0; if (str->len > 2 && str->ptr[0] == '^') { cflag++; tr.p++; @@ -1422,6 +1452,7 @@ Fstr_each(str) int newline; int rslen; char *p = str->ptr, *pend = p + str->len, *s; + char *ptr = p; if (RS == Qnil) { rb_yield(str); @@ -1447,6 +1478,7 @@ Fstr_each(str) memcmp(RSTRING(RS)->ptr, p-rslen+1, rslen) == 0)) { rb_lastline = str_new(s, p - s + 1); rb_yield(rb_lastline); + if (str->ptr != ptr) Fail("string modified"); s = p + 1; } } @@ -1465,8 +1497,8 @@ Fstr_each_byte(str) { int i; - for (i=0; str->len; i++) { - rb_yield(str->ptr[i] & 0xff); + for (i=0; ilen; i++) { + rb_yield(INT2FIX(str->ptr[i] & 0xff)); } return (VALUE)str; } @@ -1705,9 +1737,8 @@ Init_String() rb_define_method(C_String, "rjust", Fstr_rjust, 1); rb_define_method(C_String, "center", Fstr_center, 1); - rb_define_method(C_String, "sub", Fstr_sub, 2); - rb_define_method(C_String, "gsub", Fstr_gsub, 2); - rb_define_method(C_String, "esub", Fstr_esub, 1); + rb_define_method(C_String, "sub", Fstr_sub, -1); + rb_define_method(C_String, "gsub", Fstr_gsub, -1); rb_define_method(C_String, "chop", Fstr_chop, 0); rb_define_method(C_String, "strip", Fstr_strip, 0); @@ -1721,9 +1752,8 @@ Init_String() rb_define_method(C_String, "sum", Fstr_sum, -1); - rb_define_private_method(C_Kernel, "sub", Fsub, 2); - rb_define_private_method(C_Kernel, "gsub", Fgsub, 2); - rb_define_private_method(C_Kernel, "esub", Fesub, 1); + rb_define_private_method(C_Kernel, "sub", Fsub, -1); + rb_define_private_method(C_Kernel, "gsub", Fgsub, -1); pr_str = rb_intern("to_s"); } -- cgit v1.2.3