]> Cypherpunks repositories - gostls13.git/commitdiff
strings and bytes.Split: make count of 0 mean 0, not infinite.
authorRob Pike <r@golang.org>
Thu, 1 Jul 2010 21:08:14 +0000 (14:08 -0700)
committerRob Pike <r@golang.org>
Thu, 1 Jul 2010 21:08:14 +0000 (14:08 -0700)
Use a count of -1 for infinity.  Ditto for Replace.

R=rsc
CC=golang-dev
https://golang.org/cl/1704044

24 files changed:
src/cmd/cgo/gcc.go
src/cmd/godoc/godoc.go
src/cmd/godoc/index.go
src/cmd/godoc/mapping.go
src/cmd/gofmt/rewrite.go
src/cmd/hgpatch/main.go
src/pkg/asn1/common.go
src/pkg/bytes/bytes.go
src/pkg/bytes/bytes_test.go
src/pkg/crypto/x509/x509.go
src/pkg/exec/exec.go
src/pkg/exp/nacl/srpc/client.go
src/pkg/exp/ogle/cmd.go
src/pkg/go/doc/comment.go
src/pkg/http/request.go
src/pkg/http/transfer.go
src/pkg/nntp/nntp_test.go
src/pkg/patch/patch.go
src/pkg/rpc/server.go
src/pkg/strconv/fp_test.go
src/pkg/strings/strings.go
src/pkg/strings/strings_test.go
src/pkg/template/template.go
src/pkg/unicode/maketables.go

index bd64f0cb4b5d5db478a3f21f07e4adb71c7fa002..5e12a668773a8c6e5f61891fac04a51682d7ce89 100644 (file)
@@ -27,7 +27,7 @@ func (p *Prog) loadDebugInfo() {
        b.WriteString(p.Preamble)
        stdout := p.gccPostProc(b.Bytes())
        defines := make(map[string]string)
-       for _, line := range strings.Split(stdout, "\n", 0) {
+       for _, line := range strings.Split(stdout, "\n", -1) {
                if len(line) < 9 || line[0:7] != "#define" {
                        continue
                }
@@ -110,7 +110,7 @@ func (p *Prog) loadDebugInfo() {
        if stderr == "" {
                fatal("gcc produced no output")
        }
-       for _, line := range strings.Split(stderr, "\n", 0) {
+       for _, line := range strings.Split(stderr, "\n", -1) {
                if len(line) < 9 || line[0:9] != "cgo-test:" {
                        continue
                }
@@ -631,7 +631,7 @@ func (c *typeConv) Type(dtype dwarf.Type) *Type {
                        if ss, ok := cnameMap[s]; ok {
                                s = ss
                        }
-                       s = strings.Join(strings.Split(s, " ", 0), "") // strip spaces
+                       s = strings.Join(strings.Split(s, " ", -1), "") // strip spaces
                        name := c.Ident("_C_" + s)
                        c.typedef[name.Name()] = t.Go
                        t.Go = name
index 2e14b4b73361ca782028feece66d3d5b8f9f4a09..61c53e2c39bf0e80eeccb245a74311125fc068e5 100644 (file)
@@ -338,8 +338,8 @@ func (dir *Directory) lookupLocal(name string) *Directory {
 
 // lookup looks for the *Directory for a given path, relative to dir.
 func (dir *Directory) lookup(path string) *Directory {
-       d := strings.Split(dir.Path, "/", 0)
-       p := strings.Split(path, "/", 0)
+       d := strings.Split(dir.Path, "/", -1)
+       p := strings.Split(path, "/", -1)
        i := 0
        for i < len(d) {
                if i >= len(p) || d[i] != p[i] {
index 481519c66fe3a890199862790b9f5220ae3b64cd..8745b8b0a290237015bda61d78b09a24411f1abe 100644 (file)
@@ -709,7 +709,7 @@ func isIdentifier(s string) bool {
 // identifier, Lookup returns a LookupResult, and a list of alternative
 // spellings, if any. If the query syntax is wrong, illegal is set.
 func (x *Index) Lookup(query string) (match *LookupResult, alt *AltWords, illegal bool) {
-       ss := strings.Split(query, ".", 0)
+       ss := strings.Split(query, ".", -1)
 
        // check query syntax
        for _, s := range ss {
index ed2483d8be481e53e49109c7127a760849e20d8c..400f97e1f7222f6aa24a6a0a873b380d1e4c5357 100644 (file)
@@ -77,7 +77,7 @@ type mapping struct {
 func (m *Mapping) Init(paths string) {
        cwd, _ := os.Getwd() // ignore errors
 
-       pathlist := strings.Split(paths, ":", 0)
+       pathlist := strings.Split(paths, ":", -1)
 
        list := make([]mapping, len(pathlist))
        n := 0 // number of mappings
index 9c238fab20b38e918a67052faf6e4ffc00d902fd..a89146ca0e1ff7233ba9c366ec0e9d4ec95ee9db 100644 (file)
@@ -21,7 +21,7 @@ func initRewrite() {
        if *rewriteRule == "" {
                return
        }
-       f := strings.Split(*rewriteRule, "->", 0)
+       f := strings.Split(*rewriteRule, "->", -1)
        if len(f) != 2 {
                fmt.Fprintf(os.Stderr, "rewrite rule must be of the form 'pattern -> replacement'\n")
                os.Exit(2)
index 89aebda55228079cc3307b45b4d5c4dcba22af95..f6ea36da8518e0bf746fe502c8bb6ba4c0378515 100644 (file)
@@ -283,7 +283,7 @@ func hgModified() ([]string, os.Error) {
        if err != nil {
                return nil, err
        }
-       return strings.Split(strings.TrimSpace(out), "\n", 0), nil
+       return strings.Split(strings.TrimSpace(out), "\n", -1), nil
 }
 
 // hgAdd adds name to the repository.
index 894fc002ab2671713554784c83223b73572042b1..14fa30426972c2211d1385b52c121bb574e24dc9 100644 (file)
@@ -78,7 +78,7 @@ type fieldParameters struct {
 // parseFieldParameters will parse it into a fieldParameters structure,
 // ignoring unknown parts of the string.
 func parseFieldParameters(str string) (ret fieldParameters) {
-       for _, part := range strings.Split(str, ",", 0) {
+       for _, part := range strings.Split(str, ",", -1) {
                switch {
                case part == "optional":
                        ret.optional = true
index 64292ef6481270dfd4232b563fb730fb0817055d..bcf7b8609b34d7453082cb057b67358e0b97000c 100644 (file)
@@ -154,10 +154,13 @@ func IndexAny(s []byte, chars string) int {
 // Generic split: splits after each instance of sep,
 // including sepSave bytes of sep in the subarrays.
 func genSplit(s, sep []byte, sepSave, n int) [][]byte {
+       if n == 0 {
+               return nil
+       }
        if len(sep) == 0 {
                return explode(s, n)
        }
-       if n <= 0 {
+       if n < 0 {
                n = Count(s, sep) + 1
        }
        c := sep[0]
@@ -178,13 +181,15 @@ func genSplit(s, sep []byte, sepSave, n int) [][]byte {
 
 // Split splits the array s around each instance of sep, returning an array of subarrays of s.
 // If sep is empty, Split splits s after each UTF-8 sequence.
-// If n > 0, Split splits s into at most n subarrays; the last subarray will contain an unsplit remainder.
+// If n >= 0, Split splits s into at most n subarrays; the last subarray will contain an unsplit remainder.
+// Thus if n == 0, the result will ne nil.
 func Split(s, sep []byte, n int) [][]byte { return genSplit(s, sep, 0, n) }
 
 // SplitAfter splits the array s after each instance of sep, returning an array of subarrays of s.
 // If sep is empty, SplitAfter splits s after each UTF-8 sequence.
-// If n > 0, SplitAfter splits s into at most n subarrays; the last subarray will contain an
+// If n >= 0, SplitAfter splits s into at most n subarrays; the last subarray will contain an
 // unsplit remainder.
+// Thus if n == 0, the result will ne nil.
 func SplitAfter(s, sep []byte, n int) [][]byte {
        return genSplit(s, sep, len(sep), n)
 }
@@ -465,8 +470,11 @@ func Runes(s []byte) []int {
 
 // Replace returns a copy of the slice s with the first n
 // non-overlapping instances of old replaced by new.
-// If n <= 0, there is no limit on the number of replacements.
+// If n < 0, there is no limit on the number of replacements.
 func Replace(s, old, new []byte, n int) []byte {
+       if n == 0 {
+               return s // avoid allocation
+       }
        // Compute number of replacements.
        if m := Count(s, old); m == 0 {
                return s // avoid allocation
index 26ff2d16f3c8a47e8161e760de62192271e448bf..8197543dcfba5553c3edef7c2cfe27c9988ba712 100644 (file)
@@ -211,8 +211,8 @@ type ExplodeTest struct {
 }
 
 var explodetests = []ExplodeTest{
-       ExplodeTest{abcd, 0, []string{"a", "b", "c", "d"}},
-       ExplodeTest{faces, 0, []string{"☺", "☻", "☹"}},
+       ExplodeTest{abcd, -1, []string{"a", "b", "c", "d"}},
+       ExplodeTest{faces, -1, []string{"☺", "☻", "☹"}},
        ExplodeTest{abcd, 2, []string{"a", "bcd"}},
 }
 
@@ -240,16 +240,16 @@ type SplitTest struct {
 }
 
 var splittests = []SplitTest{
-       SplitTest{abcd, "a", 0, []string{"", "bcd"}},
-       SplitTest{abcd, "z", 0, []string{"abcd"}},
-       SplitTest{abcd, "", 0, []string{"a", "b", "c", "d"}},
-       SplitTest{commas, ",", 0, []string{"1", "2", "3", "4"}},
-       SplitTest{dots, "...", 0, []string{"1", ".2", ".3", ".4"}},
-       SplitTest{faces, "☹", 0, []string{"☺☻", ""}},
-       SplitTest{faces, "~", 0, []string{faces}},
-       SplitTest{faces, "", 0, []string{"☺", "☻", "☹"}},
+       SplitTest{abcd, "a", 0, nil},
+       SplitTest{abcd, "a", -1, []string{"", "bcd"}},
+       SplitTest{abcd, "z", -1, []string{"abcd"}},
+       SplitTest{abcd, "", -1, []string{"a", "b", "c", "d"}},
+       SplitTest{commas, ",", -1, []string{"1", "2", "3", "4"}},
+       SplitTest{dots, "...", -1, []string{"1", ".2", ".3", ".4"}},
+       SplitTest{faces, "☹", -1, []string{"☺☻", ""}},
+       SplitTest{faces, "~", -1, []string{faces}},
+       SplitTest{faces, "", -1, []string{"☺", "☻", "☹"}},
        SplitTest{"1 2 3 4", " ", 3, []string{"1", "2", "3 4"}},
-       SplitTest{"1 2 3", " ", 3, []string{"1", "2", "3"}},
        SplitTest{"1 2", " ", 3, []string{"1", "2"}},
        SplitTest{"123", "", 2, []string{"1", "23"}},
        SplitTest{"123", "", 17, []string{"1", "2", "3"}},
@@ -263,6 +263,9 @@ func TestSplit(t *testing.T) {
                        t.Errorf(`Split(%q, %q, %d) = %v; want %v`, tt.s, tt.sep, tt.n, result, tt.a)
                        continue
                }
+               if tt.n == 0 {
+                       continue
+               }
                s := Join(a, []byte(tt.sep))
                if string(s) != tt.s {
                        t.Errorf(`Join(Split(%q, %q, %d), %q) = %q`, tt.s, tt.sep, tt.n, tt.sep, s)
@@ -271,14 +274,14 @@ func TestSplit(t *testing.T) {
 }
 
 var splitaftertests = []SplitTest{
-       SplitTest{abcd, "a", 0, []string{"a", "bcd"}},
-       SplitTest{abcd, "z", 0, []string{"abcd"}},
-       SplitTest{abcd, "", 0, []string{"a", "b", "c", "d"}},
-       SplitTest{commas, ",", 0, []string{"1,", "2,", "3,", "4"}},
-       SplitTest{dots, "...", 0, []string{"1...", ".2...", ".3...", ".4"}},
-       SplitTest{faces, "☹", 0, []string{"☺☻☹", ""}},
-       SplitTest{faces, "~", 0, []string{faces}},
-       SplitTest{faces, "", 0, []string{"☺", "☻", "☹"}},
+       SplitTest{abcd, "a", -1, []string{"a", "bcd"}},
+       SplitTest{abcd, "z", -1, []string{"abcd"}},
+       SplitTest{abcd, "", -1, []string{"a", "b", "c", "d"}},
+       SplitTest{commas, ",", -1, []string{"1,", "2,", "3,", "4"}},
+       SplitTest{dots, "...", -1, []string{"1...", ".2...", ".3...", ".4"}},
+       SplitTest{faces, "☹", -1, []string{"☺☻☹", ""}},
+       SplitTest{faces, "~", -1, []string{faces}},
+       SplitTest{faces, "", -1, []string{"☺", "☻", "☹"}},
        SplitTest{"1 2 3 4", " ", 3, []string{"1 ", "2 ", "3 4"}},
        SplitTest{"1 2 3", " ", 3, []string{"1 ", "2 ", "3"}},
        SplitTest{"1 2", " ", 3, []string{"1 ", "2"}},
@@ -654,24 +657,25 @@ type ReplaceTest struct {
 }
 
 var ReplaceTests = []ReplaceTest{
-       ReplaceTest{"hello", "l", "L", 0, "heLLo"},
-       ReplaceTest{"hello", "x", "X", 0, "hello"},
-       ReplaceTest{"", "x", "X", 0, ""},
-       ReplaceTest{"radar", "r", "<r>", 0, "<r>ada<r>"},
-       ReplaceTest{"", "", "<>", 0, "<>"},
-       ReplaceTest{"banana", "a", "<>", 0, "b<>n<>n<>"},
+       ReplaceTest{"hello", "l", "L", 0, "hello"},
+       ReplaceTest{"hello", "l", "L", -1, "heLLo"},
+       ReplaceTest{"hello", "x", "X", -1, "hello"},
+       ReplaceTest{"", "x", "X", -1, ""},
+       ReplaceTest{"radar", "r", "<r>", -1, "<r>ada<r>"},
+       ReplaceTest{"", "", "<>", -1, "<>"},
+       ReplaceTest{"banana", "a", "<>", -1, "b<>n<>n<>"},
        ReplaceTest{"banana", "a", "<>", 1, "b<>nana"},
        ReplaceTest{"banana", "a", "<>", 1000, "b<>n<>n<>"},
-       ReplaceTest{"banana", "an", "<>", 0, "b<><>a"},
-       ReplaceTest{"banana", "ana", "<>", 0, "b<>na"},
-       ReplaceTest{"banana", "", "<>", 0, "<>b<>a<>n<>a<>n<>a<>"},
+       ReplaceTest{"banana", "an", "<>", -1, "b<><>a"},
+       ReplaceTest{"banana", "ana", "<>", -1, "b<>na"},
+       ReplaceTest{"banana", "", "<>", -1, "<>b<>a<>n<>a<>n<>a<>"},
        ReplaceTest{"banana", "", "<>", 10, "<>b<>a<>n<>a<>n<>a<>"},
        ReplaceTest{"banana", "", "<>", 6, "<>b<>a<>n<>a<>n<>a"},
        ReplaceTest{"banana", "", "<>", 5, "<>b<>a<>n<>a<>na"},
        ReplaceTest{"banana", "", "<>", 1, "<>banana"},
-       ReplaceTest{"banana", "a", "a", 0, "banana"},
+       ReplaceTest{"banana", "a", "a", -1, "banana"},
        ReplaceTest{"banana", "a", "a", 1, "banana"},
-       ReplaceTest{"☺☻☹", "", "<>", 0, "<>☺<>☻<>☹<>"},
+       ReplaceTest{"☺☻☹", "", "<>", -1, "<>☺<>☻<>☹<>"},
 }
 
 func TestReplace(t *testing.T) {
index 23b7d0b629bc1122bff3591177334fffec3c6f5e..728116850fbcd152d6858019f93a6d006c55bd95 100644 (file)
@@ -407,8 +407,8 @@ func matchHostnames(pattern, host string) bool {
                return false
        }
 
-       patternParts := strings.Split(pattern, ".", 0)
-       hostParts := strings.Split(host, ".", 0)
+       patternParts := strings.Split(pattern, ".", -1)
+       hostParts := strings.Split(host, ".", -1)
 
        if len(patternParts) != len(hostParts) {
                return false
index 415b900b9c751747940fa223a07952d0060811a9..ee3cec686ba233296c3599930a1e00250fc4cec5 100644 (file)
@@ -208,7 +208,7 @@ func LookPath(file string) (string, os.Error) {
                return "", os.ENOENT
        }
        pathenv := os.Getenv("PATH")
-       for _, dir := range strings.Split(pathenv, ":", 0) {
+       for _, dir := range strings.Split(pathenv, ":", -1) {
                if dir == "" {
                        // Unix shell semantics: path element "" means "."
                        dir = "."
index d271a82ffe4dc9592da70a8b63fba6b658c64827..f45730ffafb1232ab10ec41ed3816a5195401091 100644 (file)
@@ -67,7 +67,7 @@ func NewClient(fd int) (c *Client, err os.Error) {
                log.Stderrf("NewClient service_discovery: %s", m.status)
                return nil, m.status
        }
-       for n, line := range bytes.Split(m.Ret[0].([]byte), []byte{'\n'}, 0) {
+       for n, line := range bytes.Split(m.Ret[0].([]byte), []byte{'\n'}, -1) {
                i := bytes.Index(line, []byte{':'})
                if i < 0 {
                        continue
index 45b47ef5b81a19382088cba345db627de42a3918..2f087b777f2f1c6225ee2851ae8c1761f03cc227 100644 (file)
@@ -153,7 +153,7 @@ func cmdLoad(args []byte) os.Error {
                }
                println("Attached to", pid)
        } else {
-               parts := strings.Split(path, " ", 0)
+               parts := strings.Split(path, " ", -1)
                if len(parts) == 0 {
                        fname = ""
                } else {
index 3fc63966373c6b5cddbdf568dca8510ed0f6ed57..bbbc6a3c2595c17f9c6a6b520249dca50524c4b7 100644 (file)
@@ -59,7 +59,7 @@ func CommentText(comment *ast.CommentGroup) string {
                }
 
                // Split on newlines.
-               cl := strings.Split(c, "\n", 0)
+               cl := strings.Split(c, "\n", -1)
 
                // Walk lines, stripping trailing white space and adding to list.
                for _, l := range cl {
index b1aface466acefd4a327835eda0ecbb318b705c6..8a72d6cfad98a5ae0e4cb44c3cc46ca83583da19 100644 (file)
@@ -568,7 +568,7 @@ func ReadRequest(b *bufio.Reader) (req *Request, err os.Error) {
 
 func ParseQuery(query string) (m map[string][]string, err os.Error) {
        m = make(map[string][]string)
-       for _, kv := range strings.Split(query, "&", 0) {
+       for _, kv := range strings.Split(query, "&", -1) {
                kvPair := strings.Split(kv, "=", 2)
 
                var key, value string
index 26266cbcac8e3535f01eb62541131e4a98431ce0..5e190d74c6c6d1678291a55ef54a182e076cbd11 100644 (file)
@@ -269,7 +269,7 @@ func fixTransferEncoding(header map[string]string) ([]string, os.Error) {
        }
 
        header["Transfer-Encoding"] = "", false
-       encodings := strings.Split(raw, ",", 0)
+       encodings := strings.Split(raw, ",", -1)
        te := make([]string, 0, len(encodings))
        // TODO: Even though we only support "identity" and "chunked"
        // encodings, the loop below is designed with foresight. One
@@ -373,7 +373,7 @@ func fixTrailer(header map[string]string, te []string) (map[string]string, os.Er
 
        header["Trailer"] = "", false
        trailer := make(map[string]string)
-       keys := strings.Split(raw, ",", 0)
+       keys := strings.Split(raw, ",", -1)
        for _, key := range keys {
                key = CanonicalHeaderKey(strings.TrimSpace(key))
                switch key {
index 9bd7bd6b6d33911beb1e14946a6b1e6237af221e..bca18572246e37404c61d7b75ff0d312553e338c 100644 (file)
@@ -31,8 +31,8 @@ func (f faker) Close() os.Error {
 }
 
 func TestBasic(t *testing.T) {
-       basicServer = strings.Join(strings.Split(basicServer, "\n", 0), "\r\n")
-       basicClient = strings.Join(strings.Split(basicClient, "\n", 0), "\r\n")
+       basicServer = strings.Join(strings.Split(basicServer, "\n", -1), "\r\n")
+       basicClient = strings.Join(strings.Split(basicClient, "\n", -1), "\r\n")
 
        var cmdbuf bytes.Buffer
        var fake faker
index 9d9aa1b485eea723e7eaf6c3b803953e85610fed..d4977dc990203137aeb2afee21b514ec1d8ff458 100644 (file)
@@ -319,4 +319,4 @@ func hasPrefix(s []byte, t string) bool {
 
 // splitLines returns the result of splitting s into lines.
 // The \n on each line is preserved.
-func splitLines(s []byte) [][]byte { return bytes.SplitAfter(s, newline, 0) }
+func splitLines(s []byte) [][]byte { return bytes.SplitAfter(s, newline, -1) }
index b8a0e5ccc0ebb876767a6b39ea6215626fbd3a0e..d14f6ded2cfdd8f0a0cf6473f86e29e094702adf 100644 (file)
@@ -352,7 +352,7 @@ func (server *serverType) input(codec ServerCodec) {
                        sendResponse(sending, req, invalidRequest, codec, s)
                        break
                }
-               serviceMethod := strings.Split(req.ServiceMethod, ".", 0)
+               serviceMethod := strings.Split(req.ServiceMethod, ".", -1)
                if len(serviceMethod) != 2 {
                        s := "rpc: service/method request ill-formed: " + req.ServiceMethod
                        sendResponse(sending, req, invalidRequest, codec, s)
index 62fcfc677aa0b8c4b4cdfe3d27e5fc69dbb10c03..4cbadf316be6c506e551dcf88fb6860564033b20 100644 (file)
@@ -116,7 +116,7 @@ func TestFp(t *testing.T) {
                if len(line) == 0 || line[0] == '#' {
                        continue
                }
-               a := strings.Split(line, " ", 0)
+               a := strings.Split(line, " ", -1)
                if len(a) != 4 {
                        t.Error("testfp.txt:", lineno, ": wrong field count\n")
                        continue
index 5de83250c1142d0465dd04948ab9b47b4142026a..5d3d61e19516272c8a6c8b82efdab9c238dbaebe 100644 (file)
@@ -10,9 +10,12 @@ import (
        "utf8"
 )
 
-// explode splits s into an array of UTF-8 sequences, one per Unicode character (still strings) up to a maximum of n (n <= 0 means no limit).
+// explode splits s into an array of UTF-8 sequences, one per Unicode character (still strings) up to a maximum of n (n < 0 means no limit).
 // Invalid UTF-8 sequences become correct encodings of U+FFF8.
 func explode(s string, n int) []string {
+       if n == 0 {
+               return nil
+       }
        l := utf8.RuneCountInString(s)
        if n <= 0 || n > l {
                n = l
@@ -135,10 +138,13 @@ func IndexAny(s, chars string) int {
 // Generic split: splits after each instance of sep,
 // including sepSave bytes of sep in the subarrays.
 func genSplit(s, sep string, sepSave, n int) []string {
+       if n == 0 {
+               return nil
+       }
        if sep == "" {
                return explode(s, n)
        }
-       if n <= 0 {
+       if n < 0 {
                n = Count(s, sep) + 1
        }
        c := sep[0]
@@ -159,12 +165,14 @@ func genSplit(s, sep string, sepSave, n int) []string {
 
 // Split splits the string s around each instance of sep, returning an array of substrings of s.
 // If sep is empty, Split splits s after each UTF-8 sequence.
-// If n > 0, Split splits s into at most n substrings; the last substring will be the unsplit remainder.
+// If n >= 0, Split splits s into at most n substrings; the last substring will be the unsplit remainder.
+// Thus if n == 0, the result will be nil.
 func Split(s, sep string, n int) []string { return genSplit(s, sep, 0, n) }
 
 // SplitAfter splits the string s after each instance of sep, returning an array of substrings of s.
 // If sep is empty, SplitAfter splits s after each UTF-8 sequence.
-// If n > 0, SplitAfter splits s into at most n substrings; the last substring will be the unsplit remainder.
+// If n >= 0, SplitAfter splits s into at most n substrings; the last substring will be the unsplit remainder.
+// Thus if n == 0, the result will be nil.
 func SplitAfter(s, sep string, n int) []string {
        return genSplit(s, sep, len(sep), n)
 }
@@ -462,16 +470,16 @@ func TrimSpace(s string) string {
 
 // Replace returns a copy of the string s with the first n
 // non-overlapping instances of old replaced by new.
-// If n <= 0, there is no limit on the number of replacements.
+// If n < 0, there is no limit on the number of replacements.
 func Replace(s, old, new string, n int) string {
-       if old == new {
+       if old == new || n == 0 {
                return s // avoid allocation
        }
 
        // Compute number of replacements.
        if m := Count(s, old); m == 0 {
                return s // avoid allocation
-       } else if n <= 0 || m < n {
+       } else if n < 0 || m < n {
                n = m
        }
 
index 5ac6970c6b3f3fcb6bc9667c6fec2902f3fb5839..06f1f1de1de89bae0b6c770791f2efcea6a99488 100644 (file)
@@ -136,14 +136,15 @@ type SplitTest struct {
 }
 
 var splittests = []SplitTest{
-       SplitTest{abcd, "a", 0, []string{"", "bcd"}},
-       SplitTest{abcd, "z", 0, []string{"abcd"}},
-       SplitTest{abcd, "", 0, []string{"a", "b", "c", "d"}},
-       SplitTest{commas, ",", 0, []string{"1", "2", "3", "4"}},
-       SplitTest{dots, "...", 0, []string{"1", ".2", ".3", ".4"}},
-       SplitTest{faces, "☹", 0, []string{"☺☻", ""}},
-       SplitTest{faces, "~", 0, []string{faces}},
-       SplitTest{faces, "", 0, []string{"☺", "☻", "☹"}},
+       SplitTest{abcd, "a", 0, nil},
+       SplitTest{abcd, "a", -1, []string{"", "bcd"}},
+       SplitTest{abcd, "z", -1, []string{"abcd"}},
+       SplitTest{abcd, "", -1, []string{"a", "b", "c", "d"}},
+       SplitTest{commas, ",", -1, []string{"1", "2", "3", "4"}},
+       SplitTest{dots, "...", -1, []string{"1", ".2", ".3", ".4"}},
+       SplitTest{faces, "☹", -1, []string{"☺☻", ""}},
+       SplitTest{faces, "~", -1, []string{faces}},
+       SplitTest{faces, "", -1, []string{"☺", "☻", "☹"}},
        SplitTest{"1 2 3 4", " ", 3, []string{"1", "2", "3 4"}},
        SplitTest{"1 2", " ", 3, []string{"1", "2"}},
        SplitTest{"123", "", 2, []string{"1", "23"}},
@@ -157,6 +158,9 @@ func TestSplit(t *testing.T) {
                        t.Errorf("Split(%q, %q, %d) = %v; want %v", tt.s, tt.sep, tt.n, a, tt.a)
                        continue
                }
+               if tt.n == 0 {
+                       continue
+               }
                s := Join(a, tt.sep)
                if s != tt.s {
                        t.Errorf("Join(Split(%q, %q, %d), %q) = %q", tt.s, tt.sep, tt.n, tt.sep, s)
@@ -165,14 +169,14 @@ func TestSplit(t *testing.T) {
 }
 
 var splitaftertests = []SplitTest{
-       SplitTest{abcd, "a", 0, []string{"a", "bcd"}},
-       SplitTest{abcd, "z", 0, []string{"abcd"}},
-       SplitTest{abcd, "", 0, []string{"a", "b", "c", "d"}},
-       SplitTest{commas, ",", 0, []string{"1,", "2,", "3,", "4"}},
-       SplitTest{dots, "...", 0, []string{"1...", ".2...", ".3...", ".4"}},
-       SplitTest{faces, "☹", 0, []string{"☺☻☹", ""}},
-       SplitTest{faces, "~", 0, []string{faces}},
-       SplitTest{faces, "", 0, []string{"☺", "☻", "☹"}},
+       SplitTest{abcd, "a", -1, []string{"a", "bcd"}},
+       SplitTest{abcd, "z", -1, []string{"abcd"}},
+       SplitTest{abcd, "", -1, []string{"a", "b", "c", "d"}},
+       SplitTest{commas, ",", -1, []string{"1,", "2,", "3,", "4"}},
+       SplitTest{dots, "...", -1, []string{"1...", ".2...", ".3...", ".4"}},
+       SplitTest{faces, "☹", -1, []string{"☺☻☹", ""}},
+       SplitTest{faces, "~", -1, []string{faces}},
+       SplitTest{faces, "", -1, []string{"☺", "☻", "☹"}},
        SplitTest{"1 2 3 4", " ", 3, []string{"1 ", "2 ", "3 4"}},
        SplitTest{"1 2 3", " ", 3, []string{"1 ", "2 ", "3"}},
        SplitTest{"1 2", " ", 3, []string{"1 ", "2"}},
@@ -554,8 +558,8 @@ func equal(m string, s1, s2 string, t *testing.T) bool {
        if s1 == s2 {
                return true
        }
-       e1 := Split(s1, "", 0)
-       e2 := Split(s2, "", 0)
+       e1 := Split(s1, "", -1)
+       e2 := Split(s2, "", -1)
        for i, c1 := range e1 {
                if i > len(e2) {
                        break
@@ -709,24 +713,25 @@ type ReplaceTest struct {
 }
 
 var ReplaceTests = []ReplaceTest{
-       ReplaceTest{"hello", "l", "L", 0, "heLLo"},
-       ReplaceTest{"hello", "x", "X", 0, "hello"},
-       ReplaceTest{"", "x", "X", 0, ""},
-       ReplaceTest{"radar", "r", "<r>", 0, "<r>ada<r>"},
-       ReplaceTest{"", "", "<>", 0, "<>"},
-       ReplaceTest{"banana", "a", "<>", 0, "b<>n<>n<>"},
+       ReplaceTest{"hello", "l", "L", 0, "hello"},
+       ReplaceTest{"hello", "l", "L", -1, "heLLo"},
+       ReplaceTest{"hello", "x", "X", -1, "hello"},
+       ReplaceTest{"", "x", "X", -1, ""},
+       ReplaceTest{"radar", "r", "<r>", -1, "<r>ada<r>"},
+       ReplaceTest{"", "", "<>", -1, "<>"},
+       ReplaceTest{"banana", "a", "<>", -1, "b<>n<>n<>"},
        ReplaceTest{"banana", "a", "<>", 1, "b<>nana"},
        ReplaceTest{"banana", "a", "<>", 1000, "b<>n<>n<>"},
-       ReplaceTest{"banana", "an", "<>", 0, "b<><>a"},
-       ReplaceTest{"banana", "ana", "<>", 0, "b<>na"},
-       ReplaceTest{"banana", "", "<>", 0, "<>b<>a<>n<>a<>n<>a<>"},
+       ReplaceTest{"banana", "an", "<>", -1, "b<><>a"},
+       ReplaceTest{"banana", "ana", "<>", -1, "b<>na"},
+       ReplaceTest{"banana", "", "<>", -1, "<>b<>a<>n<>a<>n<>a<>"},
        ReplaceTest{"banana", "", "<>", 10, "<>b<>a<>n<>a<>n<>a<>"},
        ReplaceTest{"banana", "", "<>", 6, "<>b<>a<>n<>a<>n<>a"},
        ReplaceTest{"banana", "", "<>", 5, "<>b<>a<>n<>a<>na"},
        ReplaceTest{"banana", "", "<>", 1, "<>banana"},
-       ReplaceTest{"banana", "a", "a", 0, "banana"},
+       ReplaceTest{"banana", "a", "a", -1, "banana"},
        ReplaceTest{"banana", "a", "a", 1, "banana"},
-       ReplaceTest{"☺☻☹", "", "<>", 0, "<>☺<>☻<>☹<>"},
+       ReplaceTest{"☺☻☹", "", "<>", -1, "<>☺<>☻<>☹<>"},
 }
 
 func TestReplace(t *testing.T) {
index a615b7b418b6a1ab097ef1d42789c39c0e48623b..11371abe70c9aa2a20dd04d8d16cec6689ad5dc5 100644 (file)
@@ -635,7 +635,7 @@ func (st *state) findVar(s string) reflect.Value {
                return st.data
        }
        data := st.data
-       for _, elem := range strings.Split(s, ".", 0) {
+       for _, elem := range strings.Split(s, ".", -1) {
                // Look up field; data must be a struct or map.
                data = lookup(data, elem)
                if data == nil {
index 75d16418efc4c9abcf801b291c7d7b488bb92138..4fc41cdea0211ed82dd8a7c00f21dd9b46f68a6e 100644 (file)
@@ -236,7 +236,7 @@ func all(scripts map[string][]Script) []string {
 // Extract the version number from the URL
 func version() string {
        // Break on slashes and look for the first numeric field
-       fields := strings.Split(*url, "/", 0)
+       fields := strings.Split(*url, "/", -1)
        for _, f := range fields {
                if len(f) > 0 && '0' <= f[0] && f[0] <= '9' {
                        return f
@@ -304,7 +304,7 @@ func printCategories() {
                return
        }
        // Find out which categories to dump
-       list := strings.Split(*tablelist, ",", 0)
+       list := strings.Split(*tablelist, ",", -1)
        if *tablelist == "all" {
                list = allCategories()
        }
@@ -580,7 +580,7 @@ func printScriptOrProperty(doProps bool) {
        resp.Body.Close()
 
        // Find out which scripts to dump
-       list := strings.Split(flaglist, ",", 0)
+       list := strings.Split(flaglist, ",", -1)
        if flaglist == "all" {
                list = all(table)
        }