[#10793] 今度こそ (patch of the ruby-1.4.6 for NT4.0&VC4.0 on DEC Alpha.) — kou@...1609.sip.eee.yamaguchi-u.ac.jp (Koichi Okada)

岡田です。

10 messages 2000/09/01

[#10920] SIGINT on windows — "Nobuyoshi.Nakada" <nobu.nakada@...>

なかだです。

17 messages 2000/09/14
[#11077] Re: SIGINT on windows — matz@... (Yukihiro Matsumoto) 2000/09/27

まつもと ゆきひろです

[#10944] dummy DLL on Windows — "Nobuyoshi.Nakada" <nobu.nakada@...>

なかだです。

19 messages 2000/09/18
[#10955] Re: dummy DLL on Windows — WATANABE Hirofumi <eban@...> 2000/09/19

わたなべです.

[#10963] Re: dummy DLL on Windows — "Nobuyoshi.Nakada" <nobu.nakada@...> 2000/09/19

なかだです。

[#10964] Re: dummy DLL on Windows — WATANABE Hirofumi <eban@...> 2000/09/19

わたなべです.

[#10978] [PATCH] require in require — "Nobuyoshi.Nakada" <nobu.nakada@...>

なかだです。

15 messages 2000/09/20

[#10985] httphead.rb proxy version problem — Katsuyuki Komatsu <komatsu@...>

小松です.

16 messages 2000/09/20
[#10989] Re: httphead.rb proxy version problem — Minero Aoki <aamine@...> 2000/09/20

あおきです。

[ruby-dev:10988] [patch] String#index( sub, pos, range )

From: Minero Aoki <aamine@...>
Date: 2000-09-20 17:44:32 UTC
List: ruby-dev #10988
あおきです。

ちょっと前に話題にした String#index に範囲の第三引数をつける案を
実装してみたので検討してもらえないでしょうか。もちろん 1.7 でいいです。

欲しい理由は、低負荷でお手軽なスキャンに不可欠だからです。
(でも本当は Regexp#match に開始地点と範囲の引数がついててほしい…)
-------------------------------------------------------------------
あおきみねろう

Thu Sep 21 02:40:54 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>

	* string.c, re.c: String#index takes third argument "range".


Index: string.c
===================================================================
RCS file: /home/cvs/ruby/string.c,v
retrieving revision 1.44
diff -u -r1.44 string.c
--- string.c	2000/09/07 06:59:36	1.44
+++ string.c	2000/09/19 17:01:30
@@ -614,9 +614,9 @@
 }
 
 static long
-rb_str_index(str, sub, offset)
+rb_str_index_range(str, sub, offset, range)
     VALUE str, sub;
-    long offset;
+    long offset, range;
 {
     char *s, *e, *p;
     long len;
@@ -630,7 +630,7 @@
     p = RSTRING(sub)->ptr;
     len = RSTRING(sub)->len;
     if (len == 0) return offset;
-    e = RSTRING(str)->ptr + RSTRING(str)->len - len + 1;
+    e = RSTRING(str)->ptr + offset + range - len + 1;
     while (s < e) {
 	if (rb_memcmp(s, p, len) == 0) {
 	    return (s-(RSTRING(str)->ptr));
@@ -640,6 +640,70 @@
     return -1;
 }
 
+#define rb_str_index(str, sub, off) \
+    rb_str_index_range(str, sub , off, RSTRING(str)->len - off)
+
+static long
+rb_str_rindex_range(str, sub, offset, range)
+    VALUE str, sub;
+    long offset, range;
+{
+    int len;
+    char *s, *sbeg, *t;
+
+    len = RSTRING(sub)->len;
+    /* substring longer than string */
+    if (RSTRING(str)->len < len) return Qnil;
+    if (RSTRING(str)->len - offset < len) {
+        offset = RSTRING(str)->len - len;
+    }
+    sbeg = RSTRING(str)->ptr + offset - range;
+    s = RSTRING(str)->ptr + offset;
+    t = RSTRING(sub)->ptr;
+    if (len) {
+        while (sbeg <= s) {
+            if (rb_memcmp(s, t, len) == 0) {
+                return s - RSTRING(str)->ptr;
+            }
+            s--;
+        }
+    }
+    else {
+        return offset;
+    }
+    return -1;
+}
+
+static VALUE
+rb_str_chr(str, c, pos, range)
+    VALUE str;
+    int c;
+    long pos, range;
+{
+    char *p = RSTRING(str)->ptr;
+    long end = pos + range;
+
+    for (; pos < end; pos++) {
+        if (p[pos] == c) return INT2NUM(pos);
+    }
+    return Qnil;
+}
+
+static VALUE
+rb_str_rchr(str, c, pos, range)
+    VALUE str;
+    int c;
+    long pos, range;
+{
+    char *p = RSTRING(str)->ptr;
+    long end = pos - range;
+
+    for (; pos >= end; pos--) {
+        if (p[pos] == c) return INT2NUM(pos);
+    }
+    return Qnil;
+}
+
 static VALUE
 rb_str_index_m(argc, argv, str)
     int argc;
@@ -648,40 +712,50 @@
 {
     VALUE sub;
     VALUE initpos;
-    long pos;
-
-    if (rb_scan_args(argc, argv, "11", &sub, &initpos) == 2) {
+    VALUE initrg;
+    long pos = 0;
+    long range = 0;
+
+    pos = 0;
+    range = RSTRING(str)->len;
+    switch (rb_scan_args(argc, argv, "12", &sub, &initpos, &initrg)) {
+      case 3:
+        range = NUM2LONG(initrg);
+      case 2:
 	pos = NUM2LONG(initpos);
-    }
-    else {
-	pos = 0;
+      default:
+        break;
     }
     if (pos < 0) {
 	pos += RSTRING(str)->len;
 	if (pos < 0) return Qnil;
     }
+    if (pos > RSTRING(str)->len) return Qnil;
+    if (pos + range > RSTRING(str)->len) {
+        range = RSTRING(str)->len - pos;
+    }
+    else if (pos + range < 0) {
+        range = -pos;
+    }
 
     switch (TYPE(sub)) {
       case T_REGEXP:
 	pos = rb_reg_adjust_startpos(sub, str, pos, 0);
-	pos = rb_reg_search(sub, str, pos, 0);
+	pos = rb_reg_search_range(sub, str, pos, range);
 	break;
 
       case T_STRING:
-	pos = rb_str_index(str, sub, pos);
+        if (range >= 0)
+            pos = rb_str_index_range(str, sub, pos, range);
+        else
+            pos = rb_str_rindex_range(str, sub, pos, -range);
 	break;
 
       case T_FIXNUM:
-      {
-	  int c = FIX2INT(sub);
-	  long len = RSTRING(str)->len;
-	  char *p = RSTRING(str)->ptr;
-
-	  for (;pos<len;pos++) {
-	      if (p[pos] == c) return INT2NUM(pos);
-	  }
-	  return Qnil;
-      }
+        if (range >= 0)
+            return rb_str_chr(str, FIX2INT(sub), pos, range);
+        else
+            return rb_str_rchr(str, FIX2INT(sub), pos, -range);
 
       default:
 	rb_raise(rb_eTypeError, "type mismatch: %s given",
@@ -693,78 +767,64 @@
 }
 
 static VALUE
-rb_str_rindex(argc, argv, str)
+rb_str_rindex_m(argc, argv, str)
     int argc;
     VALUE *argv;
     VALUE str;
 {
     VALUE sub;
-    VALUE position;
-    int pos, len;
-    char *s, *sbeg, *t;
+    VALUE initpos;
+    VALUE initrg;
+    long pos;
+    long range;
 
-    if (rb_scan_args(argc, argv, "11", &sub, &position) == 2) {
-	pos = NUM2INT(position);
-        if (pos < 0) {
-	    pos += RSTRING(str)->len;
-	    if (pos < 0) return Qnil;
-        }
-	if (pos > RSTRING(str)->len) pos = RSTRING(str)->len;
+    pos = range = RSTRING(str)->len;
+    switch (rb_scan_args(argc, argv, "12", &sub, &initpos, &initrg)) {
+      case 3:
+        range = NUM2LONG(initrg);
+      case 2:
+	pos = NUM2INT(initpos);
+      default:
+        break;
     }
-    else {
-	pos = RSTRING(str)->len;
+    if (pos < 0) {
+        pos += RSTRING(str)->len;
+        if (pos < 0) return Qnil;
     }
+    if (pos > RSTRING(str)->len)
+        pos = RSTRING(str)->len;
+    if (pos - range < 0)
+        range = pos;
+    if (pos - range > RSTRING(str)->len)
+        range = pos - RSTRING(str)->len;
 
     switch (TYPE(sub)) {
       case T_REGEXP:
 	if (RREGEXP(sub)->len) {
 	    pos = rb_reg_adjust_startpos(sub, str, pos, 1);
-	    pos = rb_reg_search(sub, str, pos, 1);
+	    pos = rb_reg_search_range(sub, str, pos, -range);
 	}
-	if (pos >= 0) return INT2NUM(pos);
 	break;
 
       case T_STRING:
-	len = RSTRING(sub)->len;
-	/* substring longer than string */
-	if (RSTRING(str)->len < len) return Qnil;
-	if (RSTRING(str)->len - pos < len) {
-	    pos = RSTRING(str)->len - len;
-	}
-	sbeg = RSTRING(str)->ptr;
-	s = RSTRING(str)->ptr + pos;
-	t = RSTRING(sub)->ptr;
-	if (len) {
-	    while (sbeg <= s) {
-		if (rb_memcmp(s, t, len) == 0) {
-		    return INT2NUM(s - RSTRING(str)->ptr);
-		}
-		s--;
-	    }
-	}
-	else {
-	    return INT2NUM(pos);
-	}
+        if (range >= 0)
+            pos = rb_str_rindex_range(str, sub, pos, range);
+        else
+            pos = rb_str_index_range(str, sub, pos, range);
 	break;
 
       case T_FIXNUM:
-      {
-	  int c = FIX2INT(sub);
-	  char *p = RSTRING(str)->ptr + pos;
-	  char *pbeg = RSTRING(str)->ptr;
-
-	  while (pbeg <= p) {
-	      if (*p == c) return INT2NUM(p - RSTRING(str)->ptr);
-	      p--;
-	  }
-	  return Qnil;
-      }
+        if (range >= 0)
+            return rb_str_rchr(str, FIX2INT(sub), pos, range);
+        else
+            return rb_str_chr(str, FIX2INT(sub), pos, -range);
 
       default:
 	rb_raise(rb_eTypeError, "type mismatch: %s given",
 		 rb_class2name(CLASS_OF(sub)));
     }
-    return Qnil;
+    if (pos < 0) return Qnil;
+    return INT2NUM(pos);
 }
 
 static char
@@ -2804,7 +2864,7 @@
     rb_define_method(rb_cString, "next!", rb_str_succ_bang, 0);
     rb_define_method(rb_cString, "upto", rb_str_upto_m, 1);
     rb_define_method(rb_cString, "index", rb_str_index_m, -1);
-    rb_define_method(rb_cString, "rindex", rb_str_rindex, -1);
+    rb_define_method(rb_cString, "rindex", rb_str_rindex_m, -1);
     rb_define_method(rb_cString, "replace", rb_str_replace_m, 1);
 
     rb_define_method(rb_cString, "to_i", rb_str_to_i, 0);
Index: re.c
===================================================================
RCS file: /home/cvs/ruby/re.c,v
retrieving revision 1.32
diff -u -r1.32 re.c
--- re.c	2000/09/01 09:18:11	1.32
+++ re.c	2000/09/19 17:01:34
@@ -586,14 +586,13 @@
 }
 
 int
-rb_reg_search(re, str, pos, reverse)
+rb_reg_search_range(re, str, pos, range)
     VALUE re, str;
-    int pos, reverse;
+    int pos, range;
 {
     int result;
     VALUE match;
     static struct re_registers regs;
-    int range;
 
     if (pos > RSTRING(str)->len) return -1;
 
@@ -605,12 +604,6 @@
     else if (reg_kcode != curr_kcode)
 	kcode_reset_option();
 
-    if (reverse) {
-	range = -pos;
-    }
-    else {
-	range = RSTRING(str)->len - pos;
-    }
     result = re_search(RREGEXP(re)->ptr,RSTRING(str)->ptr,RSTRING(str)->len,
 		       pos, range, &regs);
 
@@ -643,6 +636,15 @@
     OBJ_INFECT(match, re);
     OBJ_INFECT(match, str);
     return result;
+}
+
+int
+rb_reg_search(re, str, pos, reverse)
+    VALUE re, str;
+    int pos, reverse;
+{
+    rb_reg_search_range(re, str, pos,
+                        reverse ? -pos : RSTRING(str)->len - pos);
 }
 
 VALUE

In This Thread

Prev Next