summaryrefslogtreecommitdiff
path: root/string.c
diff options
context:
space:
mode:
authorYukihiro Matsumoto <matz@ruby-lang.org>1995-05-19 15:33:23 +0900
committerTakashi Kokubun <takashikkbn@gmail.com>2019-08-17 22:09:32 +0900
commit8bf1c909dc31fd4bcdc1488cda9fe89a62bc2830 (patch)
tree6899d116a280ba8f99f65e21fe9259706474c0aa /string.c
parentb2420d8ffa4d347a75efbbdc376f4ce65c0eb172 (diff)
version 0.76v0_76
https://cache.ruby-lang.org/pub/ruby/1.0/ruby-0.76.tar.gz Fri May 19 15:33:23 1995 Yukihiro Matsumoto <matz@ix-02> * 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 <matz@ix-02> * 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 <matz@ix-02> * 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でコンパイルできるように
Diffstat (limited to 'string.c')
-rw-r--r--string.c238
1 files changed, 134 insertions, 104 deletions
diff --git a/string.c b/string.c
index c733faf..8093525 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; i<str->len; 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");
}