strings and bytes.Split: make count of 0 mean 0, not infinite.
Use a count of -1 for infinity.  Ditto for Replace.

R=rsc
CC=golang-dev
https://golang.org/cl/1704044
diff --git a/src/cmd/cgo/gcc.go b/src/cmd/cgo/gcc.go
index bd64f0c..5e12a66 100644
--- a/src/cmd/cgo/gcc.go
+++ b/src/cmd/cgo/gcc.go
@@ -27,7 +27,7 @@
 	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 @@
 	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 @@
 			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
diff --git a/src/cmd/godoc/godoc.go b/src/cmd/godoc/godoc.go
index 2e14b4b..61c53e2 100644
--- a/src/cmd/godoc/godoc.go
+++ b/src/cmd/godoc/godoc.go
@@ -338,8 +338,8 @@
 
 // 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] {
diff --git a/src/cmd/godoc/index.go b/src/cmd/godoc/index.go
index 481519c..8745b8b 100644
--- a/src/cmd/godoc/index.go
+++ b/src/cmd/godoc/index.go
@@ -709,7 +709,7 @@
 // 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 {
diff --git a/src/cmd/godoc/mapping.go b/src/cmd/godoc/mapping.go
index ed2483d..400f97e 100644
--- a/src/cmd/godoc/mapping.go
+++ b/src/cmd/godoc/mapping.go
@@ -77,7 +77,7 @@
 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
diff --git a/src/cmd/gofmt/rewrite.go b/src/cmd/gofmt/rewrite.go
index 9c238fa..a89146c 100644
--- a/src/cmd/gofmt/rewrite.go
+++ b/src/cmd/gofmt/rewrite.go
@@ -21,7 +21,7 @@
 	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)
diff --git a/src/cmd/hgpatch/main.go b/src/cmd/hgpatch/main.go
index 89aebda..f6ea36d 100644
--- a/src/cmd/hgpatch/main.go
+++ b/src/cmd/hgpatch/main.go
@@ -283,7 +283,7 @@
 	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.
diff --git a/src/pkg/asn1/common.go b/src/pkg/asn1/common.go
index 894fc00..14fa304 100644
--- a/src/pkg/asn1/common.go
+++ b/src/pkg/asn1/common.go
@@ -78,7 +78,7 @@
 // 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
diff --git a/src/pkg/bytes/bytes.go b/src/pkg/bytes/bytes.go
index 64292ef..bcf7b86 100644
--- a/src/pkg/bytes/bytes.go
+++ b/src/pkg/bytes/bytes.go
@@ -154,10 +154,13 @@
 // 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 @@
 
 // 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 @@
 
 // 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
diff --git a/src/pkg/bytes/bytes_test.go b/src/pkg/bytes/bytes_test.go
index 26ff2d1..8197543 100644
--- a/src/pkg/bytes/bytes_test.go
+++ b/src/pkg/bytes/bytes_test.go
@@ -211,8 +211,8 @@
 }
 
 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 @@
 }
 
 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 @@
 			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 @@
 }
 
 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 @@
 }
 
 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) {
diff --git a/src/pkg/crypto/x509/x509.go b/src/pkg/crypto/x509/x509.go
index 23b7d0b..7281168 100644
--- a/src/pkg/crypto/x509/x509.go
+++ b/src/pkg/crypto/x509/x509.go
@@ -407,8 +407,8 @@
 		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
diff --git a/src/pkg/exec/exec.go b/src/pkg/exec/exec.go
index 415b900..ee3cec6 100644
--- a/src/pkg/exec/exec.go
+++ b/src/pkg/exec/exec.go
@@ -208,7 +208,7 @@
 		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 = "."
diff --git a/src/pkg/exp/nacl/srpc/client.go b/src/pkg/exp/nacl/srpc/client.go
index d271a82..f45730f 100644
--- a/src/pkg/exp/nacl/srpc/client.go
+++ b/src/pkg/exp/nacl/srpc/client.go
@@ -67,7 +67,7 @@
 		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
diff --git a/src/pkg/exp/ogle/cmd.go b/src/pkg/exp/ogle/cmd.go
index 45b47ef..2f087b7 100644
--- a/src/pkg/exp/ogle/cmd.go
+++ b/src/pkg/exp/ogle/cmd.go
@@ -153,7 +153,7 @@
 		}
 		println("Attached to", pid)
 	} else {
-		parts := strings.Split(path, " ", 0)
+		parts := strings.Split(path, " ", -1)
 		if len(parts) == 0 {
 			fname = ""
 		} else {
diff --git a/src/pkg/go/doc/comment.go b/src/pkg/go/doc/comment.go
index 3fc6396..bbbc6a3 100644
--- a/src/pkg/go/doc/comment.go
+++ b/src/pkg/go/doc/comment.go
@@ -59,7 +59,7 @@
 		}
 
 		// 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 {
diff --git a/src/pkg/http/request.go b/src/pkg/http/request.go
index b1aface..8a72d6c 100644
--- a/src/pkg/http/request.go
+++ b/src/pkg/http/request.go
@@ -568,7 +568,7 @@
 
 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
diff --git a/src/pkg/http/transfer.go b/src/pkg/http/transfer.go
index 26266cb..5e190d7 100644
--- a/src/pkg/http/transfer.go
+++ b/src/pkg/http/transfer.go
@@ -269,7 +269,7 @@
 	}
 
 	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 @@
 
 	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 {
diff --git a/src/pkg/nntp/nntp_test.go b/src/pkg/nntp/nntp_test.go
index 9bd7bd6..bca1857 100644
--- a/src/pkg/nntp/nntp_test.go
+++ b/src/pkg/nntp/nntp_test.go
@@ -31,8 +31,8 @@
 }
 
 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
diff --git a/src/pkg/patch/patch.go b/src/pkg/patch/patch.go
index 9d9aa1b..d4977dc 100644
--- a/src/pkg/patch/patch.go
+++ b/src/pkg/patch/patch.go
@@ -319,4 +319,4 @@
 
 // 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) }
diff --git a/src/pkg/rpc/server.go b/src/pkg/rpc/server.go
index b8a0e5c..d14f6de 100644
--- a/src/pkg/rpc/server.go
+++ b/src/pkg/rpc/server.go
@@ -352,7 +352,7 @@
 			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)
diff --git a/src/pkg/strconv/fp_test.go b/src/pkg/strconv/fp_test.go
index 62fcfc6..4cbadf3 100644
--- a/src/pkg/strconv/fp_test.go
+++ b/src/pkg/strconv/fp_test.go
@@ -116,7 +116,7 @@
 		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
diff --git a/src/pkg/strings/strings.go b/src/pkg/strings/strings.go
index 5de8325..5d3d61e 100644
--- a/src/pkg/strings/strings.go
+++ b/src/pkg/strings/strings.go
@@ -10,9 +10,12 @@
 	"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 @@
 // 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 @@
 
 // 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 @@
 
 // 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
 	}
 
diff --git a/src/pkg/strings/strings_test.go b/src/pkg/strings/strings_test.go
index 5ac6970..06f1f1d 100644
--- a/src/pkg/strings/strings_test.go
+++ b/src/pkg/strings/strings_test.go
@@ -136,14 +136,15 @@
 }
 
 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 @@
 			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 @@
 }
 
 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 @@
 	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 @@
 }
 
 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) {
diff --git a/src/pkg/template/template.go b/src/pkg/template/template.go
index a615b7b..11371ab 100644
--- a/src/pkg/template/template.go
+++ b/src/pkg/template/template.go
@@ -635,7 +635,7 @@
 		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 {
diff --git a/src/pkg/unicode/maketables.go b/src/pkg/unicode/maketables.go
index 75d1641..4fc41cd 100644
--- a/src/pkg/unicode/maketables.go
+++ b/src/pkg/unicode/maketables.go
@@ -236,7 +236,7 @@
 // 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 @@
 		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 @@
 	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)
 	}