change utf8.FullRuneInString and utf8.DecodeRuneInString
to use single string argument instead of string, index.
R=r
DELTA=136 (9 added, 7 deleted, 120 changed)
OCL=28642
CL=28644
diff --git a/src/lib/fmt/print.go b/src/lib/fmt/print.go
index 229c264..66174c7 100644
--- a/src/lib/fmt/print.go
+++ b/src/lib/fmt/print.go
@@ -469,7 +469,7 @@
end := len(format) - 1;
fieldnum := 0; // we process one field per non-trivial format
for i := 0; i <= end; {
- c, w := utf8.DecodeRuneInString(format, i);
+ c, w := utf8.DecodeRuneInString(format[i:len(format)]);
if c != '%' || i == end {
p.add(c);
i += w;
@@ -500,7 +500,7 @@
if i < end && format[i] == '.' {
p.fmt.prec, p.fmt.prec_present, i = parsenum(format, i+1, end);
}
- c, w = utf8.DecodeRuneInString(format, i);
+ c, w = utf8.DecodeRuneInString(format[i:len(format)]);
i += w;
// percent is special - absorbs no operand
if c == '%' {
diff --git a/src/lib/go/ast/ast.go b/src/lib/go/ast/ast.go
index 6045c94..e6c3d85 100644
--- a/src/lib/go/ast/ast.go
+++ b/src/lib/go/ast/ast.go
@@ -426,7 +426,7 @@
// IsExported returns whether name is an exported Go symbol
// (i.e., whether it begins with an uppercase letter).
func IsExported(name string) bool {
- ch, len := utf8.DecodeRuneInString(name, 0);
+ ch, len := utf8.DecodeRuneInString(name);
return unicode.IsUpper(ch);
}
diff --git a/src/lib/json/parse.go b/src/lib/json/parse.go
index 1069e11..e33b9db 100644
--- a/src/lib/json/parse.go
+++ b/src/lib/json/parse.go
@@ -114,7 +114,7 @@
w++;
// Coerce to well-formed UTF-8.
default:
- rune, size := utf8.DecodeRuneInString(s, r);
+ rune, size := utf8.DecodeRuneInString(s[r:len(s)]);
r += size;
w += utf8.EncodeRune(rune, b[w:len(b)]);
}
diff --git a/src/lib/reflect/type.go b/src/lib/reflect/type.go
index 1ab2424..917dc28 100644
--- a/src/lib/reflect/type.go
+++ b/src/lib/reflect/type.go
@@ -698,7 +698,7 @@
return;
}
start := p.index;
- c, w := utf8.DecodeRuneInString(p.str, p.index);
+ c, w := utf8.DecodeRuneInString(p.str[p.index:len(p.str)]);
p.index += w;
switch {
case c == '<':
diff --git a/src/lib/regexp/regexp.go b/src/lib/regexp/regexp.go
index 8cbd380..b79800d 100644
--- a/src/lib/regexp/regexp.go
+++ b/src/lib/regexp/regexp.go
@@ -263,7 +263,7 @@
if p.pos >= len(p.re.expr) {
p.ch = endOfFile
} else {
- c, w := utf8.DecodeRuneInString(p.re.expr, p.pos);
+ c, w := utf8.DecodeRuneInString(p.re.expr[p.pos:len(p.re.expr)]);
p.ch = c;
p.pos += w;
}
@@ -653,7 +653,7 @@
charwidth := 1;
c := endOfFile;
if pos < len(str) {
- c, charwidth = utf8.DecodeRuneInString(str, pos);
+ c, charwidth = utf8.DecodeRuneInString(str[pos:len(str)]);
}
for i := 0; i < len(s[in]); i++ {
st := s[in][i];
diff --git a/src/lib/strconv/quote.go b/src/lib/strconv/quote.go
index 4fcec9a..8d7900d 100644
--- a/src/lib/strconv/quote.go
+++ b/src/lib/strconv/quote.go
@@ -18,38 +18,38 @@
func Quote(s string) string {
// TODO(rsc): String accumulation could be more efficient.
t := `"`;
- for i := 0; i < len(s); i++ {
- switch {
- case s[i] == '"':
+ for ; len(s) > 0; s = s[1:len(s)] {
+ switch c := s[0]; {
+ case c == '"':
t += `\"`;
- case s[i] == '\\':
+ case c == '\\':
t += `\\`;
- case ' ' <= s[i] && s[i] <= '~':
- t += string(s[i]);
- case s[i] == '\a':
+ case ' ' <= c && c <= '~':
+ t += string(c);
+ case c == '\a':
t += `\a`;
- case s[i] == '\b':
+ case c == '\b':
t += `\b`;
- case s[i] == '\f':
+ case c == '\f':
t += `\f`;
- case s[i] == '\n':
+ case c == '\n':
t += `\n`;
- case s[i] == '\r':
+ case c == '\r':
t += `\r`;
- case s[i] == '\t':
+ case c == '\t':
t += `\t`;
- case s[i] == '\v':
+ case c == '\v':
t += `\v`;
- case s[i] < utf8.RuneSelf:
- t += `\x` + string(lowerhex[s[i]>>4]) + string(lowerhex[s[i]&0xF]);
+ case c < utf8.RuneSelf:
+ t += `\x` + string(lowerhex[c>>4]) + string(lowerhex[c&0xF]);
- case utf8.FullRuneInString(s, i):
- r, size := utf8.DecodeRuneInString(s, i);
+ case utf8.FullRuneInString(s):
+ r, size := utf8.DecodeRuneInString(s);
if r == utf8.RuneError && size == 1 {
goto EscX;
}
- i += size-1; // i++ on next iteration
+ s = s[size-1:len(s)]; // next iteration will slice off 1 more
if r < 0x10000 {
t += `\u`;
for j:=uint(0); j<4; j++ {
@@ -65,8 +65,8 @@
default:
EscX:
t += `\x`;
- t += string(lowerhex[s[i]>>4]);
- t += string(lowerhex[s[i]&0xF]);
+ t += string(lowerhex[c>>4]);
+ t += string(lowerhex[c&0xF]);
}
}
t += `"`;
@@ -97,42 +97,42 @@
return;
}
-func unquoteChar(s string, i int, q byte) (t string, ii int, err os.Error) {
+func unquoteChar(s string, q byte) (t, ns string, err os.Error) {
err = os.EINVAL; // assume error for easy return
// easy cases
- switch c := s[i]; {
+ switch c := s[0]; {
case c >= utf8.RuneSelf:
- r, size := utf8.DecodeRuneInString(s, i);
- return s[i:i+size], i+size, nil;
+ r, size := utf8.DecodeRuneInString(s);
+ return s[0:size], s[size:len(s)], nil;
case c == q:
return;
case c != '\\':
- return s[i:i+1], i+1, nil;
+ return s[0:1], s[1:len(s)], nil;
}
// hard case: c is backslash
- if i+1 >= len(s) {
+ if len(s) <= 1 {
return;
}
- c := s[i+1];
- i += 2;
+ c := s[1];
+ s = s[2:len(s)];
switch c {
case 'a':
- return "\a", i, nil;
+ return "\a", s, nil;
case 'b':
- return "\b", i, nil;
+ return "\b", s, nil;
case 'f':
- return "\f", i, nil;
+ return "\f", s, nil;
case 'n':
- return "\n", i, nil;
+ return "\n", s, nil;
case 'r':
- return "\r", i, nil;
+ return "\r", s, nil;
case 't':
- return "\t", i, nil;
+ return "\t", s, nil;
case 'v':
- return "\v", i, nil;
+ return "\v", s, nil;
case 'x', 'u', 'U':
n := 0;
switch c {
@@ -144,43 +144,45 @@
n = 8;
}
v := 0;
+ if len(s) < n {
+ return;
+ }
for j := 0; j < n; j++ {
- if i+j >= len(s) {
- return;
- }
- x, ok := unhex(s[i+j]);
+ x, ok := unhex(s[j]);
if !ok {
return;
}
v = v<<4 | x;
}
+ s = s[n:len(s)];
if c == 'x' {
- return string([]byte{byte(v)}), i+n, nil;
+ // single-byte string, possibly not UTF-8
+ return string([]byte{byte(v)}), s, nil;
}
if v > utf8.RuneMax {
return;
}
- return string(v), i+n, nil;
+ return string(v), s, nil;
case '0', '1', '2', '3', '4', '5', '6', '7':
- v := 0;
- i--;
- for j := 0; j < 3; j++ {
- if i+j >= len(s) {
- return;
- }
- x := int(s[i+j]) - '0';
+ v := int(c) - '0';
+ if len(s) < 2 {
+ return;
+ }
+ for j := 0; j < 2; j++ { // one digit already; two more
+ x := int(s[j]) - '0';
if x < 0 || x > 7 {
return;
}
v = (v<<3) | x;
}
+ s = s[2:len(s)];
if v > 255 {
return;
}
- return string(v), i+3, nil;
-
+ return string(v), s, nil;
+
case '\\', q:
- return string(c), i, nil;
+ return string(c), s, nil;
}
return;
}
@@ -193,37 +195,35 @@
func Unquote(s string) (t string, err os.Error) {
err = os.EINVAL; // assume error for easy return
n := len(s);
- if n < 2 || s[0] != s[n-1] {
+ if n < 2 {
+ return;
+ }
+ quote := s[0];
+ if quote != s[n-1] {
+ return;
+ }
+ s = s[1:n-1];
+
+ if quote == '`' {
+ return s, nil;
+ }
+ if quote != '"' && quote != '\'' {
return;
}
- switch s[0] {
- case '`':
- t := s[1:n-1];
- return t, nil;
-
- case '"', '\'':
- // TODO(rsc): String accumulation could be more efficient.
- t := "";
- q := s[0];
- var c string;
- var err os.Error;
- for i := 1; i < n-1; {
- c, i, err = unquoteChar(s, i, q);
- if err != nil {
- return "", err;
- }
- t += c;
- if q == '\'' && i != n-1 {
- // single-quoted must be single character
- return;
- }
- if i > n-1 {
- // read too far
- return;
- }
+ // TODO(rsc): String accumulation could be more efficient.
+ var c, tt string;
+ var err1 os.Error;
+ for len(s) > 0 {
+ if c, s, err1 = unquoteChar(s, quote); err1 != nil {
+ err = err1;
+ return;
}
- return t, nil
+ tt += c;
+ if quote == '\'' && len(s) != 0 {
+ // single-quoted must be single character
+ return;
+ }
}
- return;
+ return tt, nil
}
diff --git a/src/lib/strings/strings.go b/src/lib/strings/strings.go
index 33adab2..fabd932 100644
--- a/src/lib/strings/strings.go
+++ b/src/lib/strings/strings.go
@@ -11,12 +11,13 @@
// Invalid UTF-8 sequences become correct encodings of U+FFF8.
func Explode(s string) []string {
a := make([]string, utf8.RuneCountInString(s));
- j := 0;
var size, rune int;
- for i := 0; i < len(a); i++ {
- rune, size = utf8.DecodeRuneInString(s, j);
+ i := 0;
+ for len(s) > 0 {
+ rune, size = utf8.DecodeRuneInString(s);
+ s = s[size:len(s)];
a[i] = string(rune);
- j += size;
+ i++;
}
return a
}
diff --git a/src/lib/utf8/utf8.go b/src/lib/utf8/utf8.go
index 5ce5989..9c2ac79 100644
--- a/src/lib/utf8/utf8.go
+++ b/src/lib/utf8/utf8.go
@@ -108,11 +108,12 @@
return RuneError, 1, false
}
-func decodeRuneInStringInternal(s string, i int, n int) (rune, size int, short bool) {
+func decodeRuneInStringInternal(s string) (rune, size int, short bool) {
+ n := len(s);
if n < 1 {
return RuneError, 0, true;
}
- c0 := s[i];
+ c0 := s[0];
// 1-byte, 7-bit sequence?
if c0 < _Tx {
@@ -128,7 +129,7 @@
if n < 2 {
return RuneError, 1, true
}
- c1 := s[i+1];
+ c1 := s[1];
if c1 < _Tx || _T2 <= c1 {
return RuneError, 1, false
}
@@ -146,7 +147,7 @@
if n < 3 {
return RuneError, 1, true
}
- c2 := s[i+2];
+ c2 := s[2];
if c2 < _Tx || _T2 <= c2 {
return RuneError, 1, false
}
@@ -164,7 +165,7 @@
if n < 4 {
return RuneError, 1, true
}
- c3 := s[i+3];
+ c3 := s[3];
if c3 < _Tx || _T2 <= c3 {
return RuneError, 1, false
}
@@ -190,8 +191,8 @@
}
// FullRuneInString is like FullRune but its input is a string.
-func FullRuneInString(s string, i int) bool {
- rune, size, short := decodeRuneInStringInternal(s, i, len(s) - i);
+func FullRuneInString(s string) bool {
+ rune, size, short := decodeRuneInStringInternal(s);
return !short
}
@@ -203,9 +204,9 @@
}
// DecodeRuneInString is like DecodeRune but its input is a string.
-func DecodeRuneInString(s string, i int) (rune, size int) {
+func DecodeRuneInString(s string) (rune, size int) {
var short bool;
- rune, size, short = decodeRuneInStringInternal(s, i, len(s) - i);
+ rune, size, short = decodeRuneInStringInternal(s);
return;
}
@@ -281,7 +282,7 @@
if s[i] < RuneSelf {
i++;
} else {
- rune, size, short := decodeRuneInStringInternal(s, i, ei - i);
+ rune, size, short := decodeRuneInStringInternal(s[i:ei]);
i += size;
}
}
diff --git a/src/lib/utf8/utf8_test.go b/src/lib/utf8/utf8_test.go
index 3ba5ee2..d6d20a1 100644
--- a/src/lib/utf8/utf8_test.go
+++ b/src/lib/utf8/utf8_test.go
@@ -58,17 +58,17 @@
if !utf8.FullRune(b) {
t.Errorf("FullRune(%q) (rune %04x) = false, want true", b, m.rune);
}
- s := "xx"+m.str;
- if !utf8.FullRuneInString(s, 2) {
- t.Errorf("FullRuneInString(%q, 2) (rune %04x) = false, want true", s, m.rune);
+ s := m.str;
+ if !utf8.FullRuneInString(s) {
+ t.Errorf("FullRuneInString(%q) (rune %04x) = false, want true", s, m.rune);
}
b1 := b[0:len(b)-1];
if utf8.FullRune(b1) {
t.Errorf("FullRune(%q) = true, want false", b1);
}
- s1 := "xxx"+string(b1);
- if utf8.FullRuneInString(s1, 3) {
- t.Errorf("FullRune(%q, 3) = true, want false", s1);
+ s1 := string(b1);
+ if utf8.FullRuneInString(s1) {
+ t.Errorf("FullRune(%q) = true, want false", s1);
}
}
}
@@ -106,10 +106,10 @@
if rune != m.rune || size != len(b) {
t.Errorf("DecodeRune(%q) = 0x%04x, %d want 0x%04x, %d", b, rune, size, m.rune, len(b));
}
- s := "xx"+m.str;
- rune, size = utf8.DecodeRuneInString(s, 2);
+ s := m.str;
+ rune, size = utf8.DecodeRuneInString(s);
if rune != m.rune || size != len(b) {
- t.Errorf("DecodeRune(%q, 2) = 0x%04x, %d want 0x%04x, %d", s, rune, size, m.rune, len(b));
+ t.Errorf("DecodeRune(%q) = 0x%04x, %d want 0x%04x, %d", s, rune, size, m.rune, len(b));
}
// there's an extra byte that bytes left behind - make sure trailing byte works
@@ -117,10 +117,10 @@
if rune != m.rune || size != len(b) {
t.Errorf("DecodeRune(%q) = 0x%04x, %d want 0x%04x, %d", b, rune, size, m.rune, len(b));
}
- s = "x"+m.str+"\x00";
- rune, size = utf8.DecodeRuneInString(s, 1);
+ s = m.str+"\x00";
+ rune, size = utf8.DecodeRuneInString(s);
if rune != m.rune || size != len(b) {
- t.Errorf("DecodeRuneInString(%q, 1) = 0x%04x, %d want 0x%04x, %d", s, rune, size, m.rune, len(b));
+ t.Errorf("DecodeRuneInString(%q) = 0x%04x, %d want 0x%04x, %d", s, rune, size, m.rune, len(b));
}
// make sure missing bytes fail
@@ -132,10 +132,10 @@
if rune != RuneError || size != wantsize {
t.Errorf("DecodeRune(%q) = 0x%04x, %d want 0x%04x, %d", b[0:len(b)-1], rune, size, RuneError, wantsize);
}
- s = "xxx"+m.str[0:len(m.str)-1];
- rune, size = utf8.DecodeRuneInString(s, 3);
+ s = m.str[0:len(m.str)-1];
+ rune, size = utf8.DecodeRuneInString(s);
if rune != RuneError || size != wantsize {
- t.Errorf("DecodeRuneInString(%q, 3) = 0x%04x, %d want 0x%04x, %d", s, rune, size, RuneError, wantsize);
+ t.Errorf("DecodeRuneInString(%q) = 0x%04x, %d want 0x%04x, %d", s, rune, size, RuneError, wantsize);
}
// make sure bad sequences fail
@@ -148,10 +148,10 @@
if rune != RuneError || size != 1 {
t.Errorf("DecodeRune(%q) = 0x%04x, %d want 0x%04x, %d", b, rune, size, RuneError, 1);
}
- s = "xxxx"+string(b);
+ s = string(b);
rune, size = utf8.DecodeRune(b);
if rune != RuneError || size != 1 {
- t.Errorf("DecodeRuneInString(%q, 4) = 0x%04x, %d want 0x%04x, %d", s, rune, size, RuneError, 1);
+ t.Errorf("DecodeRuneInString(%q) = 0x%04x, %d want 0x%04x, %d", s, rune, size, RuneError, 1);
}
}
}
diff --git a/test/stringrange.go b/test/stringrange.go
index 32ed1e5..6169e97 100644
--- a/test/stringrange.go
+++ b/test/stringrange.go
@@ -21,7 +21,7 @@
ok := true;
cnum := 0;
for i, c = range s {
- rune, size := utf8.DecodeRuneInString(s, i); // check it another way
+ rune, size := utf8.DecodeRuneInString(s[i:len(s)]); // check it another way
if i != offset {
fmt.Printf("unexpected offset %d not %d\n", i, offset);
ok = false;
diff --git a/test/utf.go b/test/utf.go
index a93cb69..59b0ffa 100644
--- a/test/utf.go
+++ b/test/utf.go
@@ -23,7 +23,7 @@
var l = len(s);
for w, i, j := 0,0,0; i < l; i += w {
var r int;
- r, w = utf8.DecodeRuneInString(s, i);
+ r, w = utf8.DecodeRuneInString(s[i:len(s)]);
if w == 0 { panic("zero width in string") }
if r != chars[j] { panic("wrong value from string") }
j++;