Commit 762eb408 authored by Russ Cox's avatar Russ Cox

cmd/go: split out cmd/go/internal/str

This is one CL in a long sequence of changes to break up the
go command from one package into a plausible group of packages.

This sequence is concerned only with moving code, not changing
or cleaning up code. There will still be more cleanup after this sequence.

The entire sequence will be submitted together: it is not a goal
for the tree to build at every step.

For #18653.

Change-Id: I63f578f5ac99c707b599ac5659293c46b275567d
Reviewed-on: https://go-review.googlesource.com/36190Reviewed-by: default avatarDavid Crawshaw <crawshaw@golang.org>
parent d9e6835b
...@@ -7,6 +7,7 @@ package main ...@@ -7,6 +7,7 @@ package main
import ( import (
"bufio" "bufio"
"bytes" "bytes"
"cmd/go/internal/str"
"container/heap" "container/heap"
"debug/elf" "debug/elf"
"errors" "errors"
...@@ -2091,7 +2092,7 @@ func (b *builder) run(dir string, desc string, env []string, cmdargs ...interfac ...@@ -2091,7 +2092,7 @@ func (b *builder) run(dir string, desc string, env []string, cmdargs ...interfac
out, err := b.runOut(dir, desc, env, cmdargs...) out, err := b.runOut(dir, desc, env, cmdargs...)
if len(out) > 0 { if len(out) > 0 {
if desc == "" { if desc == "" {
desc = b.fmtcmd(dir, "%s", strings.Join(stringList(cmdargs...), " ")) desc = b.fmtcmd(dir, "%s", strings.Join(str.StringList(cmdargs...), " "))
} }
b.showOutput(dir, desc, b.processOutput(out)) b.showOutput(dir, desc, b.processOutput(out))
if err != nil { if err != nil {
...@@ -2121,7 +2122,7 @@ func (b *builder) processOutput(out []byte) string { ...@@ -2121,7 +2122,7 @@ func (b *builder) processOutput(out []byte) string {
// runOut runs the command given by cmdline in the directory dir. // runOut runs the command given by cmdline in the directory dir.
// It returns the command output and any errors that occurred. // It returns the command output and any errors that occurred.
func (b *builder) runOut(dir string, desc string, env []string, cmdargs ...interface{}) ([]byte, error) { func (b *builder) runOut(dir string, desc string, env []string, cmdargs ...interface{}) ([]byte, error) {
cmdline := stringList(cmdargs...) cmdline := str.StringList(cmdargs...)
if buildN || buildX { if buildN || buildX {
var envcmdline string var envcmdline string
for i := range env { for i := range env {
...@@ -2450,7 +2451,7 @@ func toolVerify(b *builder, p *Package, newTool string, ofile string, args []int ...@@ -2450,7 +2451,7 @@ func toolVerify(b *builder, p *Package, newTool string, ofile string, args []int
return err return err
} }
if !bytes.Equal(data1, data2) { if !bytes.Equal(data1, data2) {
return fmt.Errorf("%s and %s produced different output files:\n%s\n%s", filepath.Base(args[1].(string)), newTool, strings.Join(stringList(args...), " "), strings.Join(stringList(newArgs...), " ")) return fmt.Errorf("%s and %s produced different output files:\n%s\n%s", filepath.Base(args[1].(string)), newTool, strings.Join(str.StringList(args...), " "), strings.Join(str.StringList(newArgs...), " "))
} }
os.Remove(ofile + ".new") os.Remove(ofile + ".new")
return nil return nil
...@@ -2477,7 +2478,7 @@ func (gcToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []s ...@@ -2477,7 +2478,7 @@ func (gcToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []s
} }
if buildN || buildX { if buildN || buildX {
cmdline := stringList("pack", "r", absAfile, absOfiles) cmdline := str.StringList("pack", "r", absAfile, absOfiles)
b.showcmd(p.Dir, "%s # internal", joinUnambiguously(cmdline)) b.showcmd(p.Dir, "%s # internal", joinUnambiguously(cmdline))
} }
if buildN { if buildN {
...@@ -2692,7 +2693,7 @@ func (tools gccgoToolchain) gc(b *builder, p *Package, archive, obj string, asmh ...@@ -2692,7 +2693,7 @@ func (tools gccgoToolchain) gc(b *builder, p *Package, archive, obj string, asmh
if p.localPrefix != "" { if p.localPrefix != "" {
gcargs = append(gcargs, "-fgo-relative-import-path="+p.localPrefix) gcargs = append(gcargs, "-fgo-relative-import-path="+p.localPrefix)
} }
args := stringList(tools.compiler(), importArgs, "-c", gcargs, "-o", ofile, buildGccgoflags) args := str.StringList(tools.compiler(), importArgs, "-c", gcargs, "-o", ofile, buildGccgoflags)
for _, f := range gofiles { for _, f := range gofiles {
args = append(args, mkAbs(p.Dir, f)) args = append(args, mkAbs(p.Dir, f))
} }
...@@ -2913,7 +2914,7 @@ func (tools gccgoToolchain) link(b *builder, root *action, out string, allaction ...@@ -2913,7 +2914,7 @@ func (tools gccgoToolchain) link(b *builder, root *action, out string, allaction
ldflags = append(ldflags, root.p.CgoLDFLAGS...) ldflags = append(ldflags, root.p.CgoLDFLAGS...)
} }
ldflags = stringList("-Wl,-(", ldflags, "-Wl,-)") ldflags = str.StringList("-Wl,-(", ldflags, "-Wl,-)")
for _, shlib := range shlibs { for _, shlib := range shlibs {
ldflags = append( ldflags = append(
...@@ -3244,11 +3245,11 @@ func envList(key, def string) []string { ...@@ -3244,11 +3245,11 @@ func envList(key, def string) []string {
func (b *builder) cflags(p *Package) (cppflags, cflags, cxxflags, fflags, ldflags []string) { func (b *builder) cflags(p *Package) (cppflags, cflags, cxxflags, fflags, ldflags []string) {
defaults := "-g -O2" defaults := "-g -O2"
cppflags = stringList(envList("CGO_CPPFLAGS", ""), p.CgoCPPFLAGS) cppflags = str.StringList(envList("CGO_CPPFLAGS", ""), p.CgoCPPFLAGS)
cflags = stringList(envList("CGO_CFLAGS", defaults), p.CgoCFLAGS) cflags = str.StringList(envList("CGO_CFLAGS", defaults), p.CgoCFLAGS)
cxxflags = stringList(envList("CGO_CXXFLAGS", defaults), p.CgoCXXFLAGS) cxxflags = str.StringList(envList("CGO_CXXFLAGS", defaults), p.CgoCXXFLAGS)
fflags = stringList(envList("CGO_FFLAGS", defaults), p.CgoFFLAGS) fflags = str.StringList(envList("CGO_FFLAGS", defaults), p.CgoFFLAGS)
ldflags = stringList(envList("CGO_LDFLAGS", defaults), p.CgoLDFLAGS) ldflags = str.StringList(envList("CGO_LDFLAGS", defaults), p.CgoLDFLAGS)
return return
} }
...@@ -3354,7 +3355,7 @@ func (b *builder) cgo(a *action, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, cgofil ...@@ -3354,7 +3355,7 @@ func (b *builder) cgo(a *action, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, cgofil
outGo = append(outGo, gofiles...) outGo = append(outGo, gofiles...)
// gcc // gcc
cflags := stringList(cgoCPPFLAGS, cgoCFLAGS) cflags := str.StringList(cgoCPPFLAGS, cgoCFLAGS)
for _, cfile := range cfiles { for _, cfile := range cfiles {
ofile := obj + cfile[:len(cfile)-1] + "o" ofile := obj + cfile[:len(cfile)-1] + "o"
if err := b.gcc(p, ofile, cflags, obj+cfile); err != nil { if err := b.gcc(p, ofile, cflags, obj+cfile); err != nil {
...@@ -3372,7 +3373,7 @@ func (b *builder) cgo(a *action, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, cgofil ...@@ -3372,7 +3373,7 @@ func (b *builder) cgo(a *action, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, cgofil
outObj = append(outObj, ofile) outObj = append(outObj, ofile)
} }
cxxflags := stringList(cgoCPPFLAGS, cgoCXXFLAGS) cxxflags := str.StringList(cgoCPPFLAGS, cgoCXXFLAGS)
for _, file := range gxxfiles { for _, file := range gxxfiles {
// Append .o to the file, just in case the pkg has file.c and file.cpp // Append .o to the file, just in case the pkg has file.c and file.cpp
ofile := obj + cgoRe.ReplaceAllString(filepath.Base(file), "_") + ".o" ofile := obj + cgoRe.ReplaceAllString(filepath.Base(file), "_") + ".o"
...@@ -3391,7 +3392,7 @@ func (b *builder) cgo(a *action, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, cgofil ...@@ -3391,7 +3392,7 @@ func (b *builder) cgo(a *action, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, cgofil
outObj = append(outObj, ofile) outObj = append(outObj, ofile)
} }
fflags := stringList(cgoCPPFLAGS, cgoFFLAGS) fflags := str.StringList(cgoCPPFLAGS, cgoFFLAGS)
for _, file := range ffiles { for _, file := range ffiles {
// Append .o to the file, just in case the pkg has file.c and file.f // Append .o to the file, just in case the pkg has file.c and file.f
ofile := obj + cgoRe.ReplaceAllString(filepath.Base(file), "_") + ".o" ofile := obj + cgoRe.ReplaceAllString(filepath.Base(file), "_") + ".o"
...@@ -3440,7 +3441,7 @@ func (b *builder) dynimport(p *Package, obj, importGo, cgoExe string, cflags, cg ...@@ -3440,7 +3441,7 @@ func (b *builder) dynimport(p *Package, obj, importGo, cgoExe string, cflags, cg
return err return err
} }
linkobj := stringList(ofile, outObj, p.SysoFiles) linkobj := str.StringList(ofile, outObj, p.SysoFiles)
dynobj := obj + "_cgo_.o" dynobj := obj + "_cgo_.o"
// we need to use -pie for Linux/ARM to get accurate imported sym // we need to use -pie for Linux/ARM to get accurate imported sym
...@@ -3672,9 +3673,9 @@ func (b *builder) swigOne(p *Package, file, obj string, pcCFLAGS []string, cxx b ...@@ -3672,9 +3673,9 @@ func (b *builder) swigOne(p *Package, file, obj string, pcCFLAGS []string, cxx b
cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, _, _ := b.cflags(p) cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, _, _ := b.cflags(p)
var cflags []string var cflags []string
if cxx { if cxx {
cflags = stringList(cgoCPPFLAGS, pcCFLAGS, cgoCXXFLAGS) cflags = str.StringList(cgoCPPFLAGS, pcCFLAGS, cgoCXXFLAGS)
} else { } else {
cflags = stringList(cgoCPPFLAGS, pcCFLAGS, cgoCFLAGS) cflags = str.StringList(cgoCPPFLAGS, pcCFLAGS, cgoCFLAGS)
} }
n := 5 // length of ".swig" n := 5 // length of ".swig"
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
package main package main
import "cmd/go/internal/str"
var cmdFix = &Command{ var cmdFix = &Command{
Run: runFix, Run: runFix,
UsageLine: "fix [packages]", UsageLine: "fix [packages]",
...@@ -25,6 +27,6 @@ func runFix(cmd *Command, args []string) { ...@@ -25,6 +27,6 @@ func runFix(cmd *Command, args []string) {
// Use pkg.gofiles instead of pkg.Dir so that // Use pkg.gofiles instead of pkg.Dir so that
// the command only applies to this package, // the command only applies to this package,
// not to packages in subdirectories. // not to packages in subdirectories.
run(stringList(buildToolExec, tool("fix"), relPaths(pkg.allgofiles))) run(str.StringList(buildToolExec, tool("fix"), relPaths(pkg.allgofiles)))
} }
} }
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
package main package main
import ( import (
"cmd/go/internal/str"
"os" "os"
"path/filepath" "path/filepath"
) )
...@@ -39,7 +40,7 @@ func runFmt(cmd *Command, args []string) { ...@@ -39,7 +40,7 @@ func runFmt(cmd *Command, args []string) {
// Use pkg.gofiles instead of pkg.Dir so that // Use pkg.gofiles instead of pkg.Dir so that
// the command only applies to this package, // the command only applies to this package,
// not to packages in subdirectories. // not to packages in subdirectories.
run(stringList(gofmt, "-l", "-w", relPaths(pkg.allgofiles))) run(str.StringList(gofmt, "-l", "-w", relPaths(pkg.allgofiles)))
} }
} }
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
package main package main
import ( import (
"cmd/go/internal/str"
"fmt" "fmt"
"go/build" "go/build"
"os" "os"
...@@ -302,7 +303,7 @@ func download(arg string, parent *Package, stk *importStack, mode int) { ...@@ -302,7 +303,7 @@ func download(arg string, parent *Package, stk *importStack, mode int) {
// due to wildcard expansion. // due to wildcard expansion.
for _, p := range pkgs { for _, p := range pkgs {
if *getFix { if *getFix {
run(buildToolExec, stringList(tool("fix"), relPaths(p.allgofiles))) run(buildToolExec, str.StringList(tool("fix"), relPaths(p.allgofiles)))
// The imports might have changed, so reload again. // The imports might have changed, so reload again.
p = reloadPackage(arg, stk) p = reloadPackage(arg, stk)
...@@ -324,7 +325,7 @@ func download(arg string, parent *Package, stk *importStack, mode int) { ...@@ -324,7 +325,7 @@ func download(arg string, parent *Package, stk *importStack, mode int) {
// Process test dependencies when -t is specified. // Process test dependencies when -t is specified.
// (But don't get test dependencies for test dependencies: // (But don't get test dependencies for test dependencies:
// we always pass mode 0 to the recursive calls below.) // we always pass mode 0 to the recursive calls below.)
imports = stringList(imports, p.TestImports, p.XTestImports) imports = str.StringList(imports, p.TestImports, p.XTestImports)
} }
for i, path := range imports { for i, path := range imports {
if path == "C" { if path == "C" {
......
// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package str provides string manipulation utilities.
package str
import (
"bytes"
"fmt"
"unicode"
"unicode/utf8"
)
// StringList flattens its arguments into a single []string.
// Each argument in args must have type string or []string.
func StringList(args ...interface{}) []string {
var x []string
for _, arg := range args {
switch arg := arg.(type) {
case []string:
x = append(x, arg...)
case string:
x = append(x, arg)
default:
panic("stringList: invalid argument of type " + fmt.Sprintf("%T", arg))
}
}
return x
}
// toFold returns a string with the property that
// strings.EqualFold(s, t) iff toFold(s) == toFold(t)
// This lets us test a large set of strings for fold-equivalent
// duplicates without making a quadratic number of calls
// to EqualFold. Note that strings.ToUpper and strings.ToLower
// do not have the desired property in some corner cases.
func toFold(s string) string {
// Fast path: all ASCII, no upper case.
// Most paths look like this already.
for i := 0; i < len(s); i++ {
c := s[i]
if c >= utf8.RuneSelf || 'A' <= c && c <= 'Z' {
goto Slow
}
}
return s
Slow:
var buf bytes.Buffer
for _, r := range s {
// SimpleFold(x) cycles to the next equivalent rune > x
// or wraps around to smaller values. Iterate until it wraps,
// and we've found the minimum value.
for {
r0 := r
r = unicode.SimpleFold(r0)
if r <= r0 {
break
}
}
// Exception to allow fast path above: A-Z => a-z
if 'A' <= r && r <= 'Z' {
r += 'a' - 'A'
}
buf.WriteRune(r)
}
return buf.String()
}
// FoldDup reports a pair of strings from the list that are
// equal according to strings.EqualFold.
// It returns "", "" if there are no such strings.
func FoldDup(list []string) (string, string) {
clash := map[string]string{}
for _, s := range list {
fold := toFold(s)
if t := clash[fold]; t != "" {
if s > t {
s, t = t, s
}
return s, t
}
clash[fold] = s
}
return "", ""
}
// Contains reports whether x contains s.
func Contains(x []string, s string) bool {
for _, t := range x {
if t == s {
return true
}
}
return false
}
...@@ -7,6 +7,7 @@ package main ...@@ -7,6 +7,7 @@ package main
import ( import (
"bufio" "bufio"
"bytes" "bytes"
"cmd/go/internal/str"
"flag" "flag"
"fmt" "fmt"
"go/build" "go/build"
...@@ -453,7 +454,7 @@ func exitIfErrors() { ...@@ -453,7 +454,7 @@ func exitIfErrors() {
} }
func run(cmdargs ...interface{}) { func run(cmdargs ...interface{}) {
cmdline := stringList(cmdargs...) cmdline := str.StringList(cmdargs...)
if buildN || buildX { if buildN || buildX {
fmt.Printf("%s\n", strings.Join(cmdline, " ")) fmt.Printf("%s\n", strings.Join(cmdline, " "))
if buildN { if buildN {
...@@ -730,77 +731,3 @@ func matchPackagesInFS(pattern string) []string { ...@@ -730,77 +731,3 @@ func matchPackagesInFS(pattern string) []string {
}) })
return pkgs return pkgs
} }
// stringList's arguments should be a sequence of string or []string values.
// stringList flattens them into a single []string.
func stringList(args ...interface{}) []string {
var x []string
for _, arg := range args {
switch arg := arg.(type) {
case []string:
x = append(x, arg...)
case string:
x = append(x, arg)
default:
panic("stringList: invalid argument of type " + fmt.Sprintf("%T", arg))
}
}
return x
}
// toFold returns a string with the property that
// strings.EqualFold(s, t) iff toFold(s) == toFold(t)
// This lets us test a large set of strings for fold-equivalent
// duplicates without making a quadratic number of calls
// to EqualFold. Note that strings.ToUpper and strings.ToLower
// have the desired property in some corner cases.
func toFold(s string) string {
// Fast path: all ASCII, no upper case.
// Most paths look like this already.
for i := 0; i < len(s); i++ {
c := s[i]
if c >= utf8.RuneSelf || 'A' <= c && c <= 'Z' {
goto Slow
}
}
return s
Slow:
var buf bytes.Buffer
for _, r := range s {
// SimpleFold(x) cycles to the next equivalent rune > x
// or wraps around to smaller values. Iterate until it wraps,
// and we've found the minimum value.
for {
r0 := r
r = unicode.SimpleFold(r0)
if r <= r0 {
break
}
}
// Exception to allow fast path above: A-Z => a-z
if 'A' <= r && r <= 'Z' {
r += 'a' - 'A'
}
buf.WriteRune(r)
}
return buf.String()
}
// foldDup reports a pair of strings from the list that are
// equal according to strings.EqualFold.
// It returns "", "" if there are no such strings.
func foldDup(list []string) (string, string) {
clash := map[string]string{}
for _, s := range list {
fold := toFold(s)
if t := clash[fold]; t != "" {
if s > t {
s, t = t, s
}
return s, t
}
clash[fold] = s
}
return "", ""
}
...@@ -6,6 +6,7 @@ package main ...@@ -6,6 +6,7 @@ package main
import ( import (
"bytes" "bytes"
"cmd/go/internal/str"
"crypto/sha1" "crypto/sha1"
"errors" "errors"
"fmt" "fmt"
...@@ -971,19 +972,19 @@ func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package ...@@ -971,19 +972,19 @@ func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package
// Build list of full paths to all Go files in the package, // Build list of full paths to all Go files in the package,
// for use by commands like go fmt. // for use by commands like go fmt.
p.gofiles = stringList(p.GoFiles, p.CgoFiles, p.TestGoFiles, p.XTestGoFiles) p.gofiles = str.StringList(p.GoFiles, p.CgoFiles, p.TestGoFiles, p.XTestGoFiles)
for i := range p.gofiles { for i := range p.gofiles {
p.gofiles[i] = filepath.Join(p.Dir, p.gofiles[i]) p.gofiles[i] = filepath.Join(p.Dir, p.gofiles[i])
} }
sort.Strings(p.gofiles) sort.Strings(p.gofiles)
p.sfiles = stringList(p.SFiles) p.sfiles = str.StringList(p.SFiles)
for i := range p.sfiles { for i := range p.sfiles {
p.sfiles[i] = filepath.Join(p.Dir, p.sfiles[i]) p.sfiles[i] = filepath.Join(p.Dir, p.sfiles[i])
} }
sort.Strings(p.sfiles) sort.Strings(p.sfiles)
p.allgofiles = stringList(p.IgnoredGoFiles) p.allgofiles = str.StringList(p.IgnoredGoFiles)
for i := range p.allgofiles { for i := range p.allgofiles {
p.allgofiles[i] = filepath.Join(p.Dir, p.allgofiles[i]) p.allgofiles[i] = filepath.Join(p.Dir, p.allgofiles[i])
} }
...@@ -994,7 +995,7 @@ func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package ...@@ -994,7 +995,7 @@ func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package
// To avoid problems on case-insensitive files, we reject any package // To avoid problems on case-insensitive files, we reject any package
// where two different input files have equal names under a case-insensitive // where two different input files have equal names under a case-insensitive
// comparison. // comparison.
f1, f2 := foldDup(stringList( f1, f2 := str.FoldDup(str.StringList(
p.GoFiles, p.GoFiles,
p.CgoFiles, p.CgoFiles,
p.IgnoredGoFiles, p.IgnoredGoFiles,
...@@ -1112,7 +1113,7 @@ func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package ...@@ -1112,7 +1113,7 @@ func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package
// In the absence of errors lower in the dependency tree, // In the absence of errors lower in the dependency tree,
// check for case-insensitive collisions of import paths. // check for case-insensitive collisions of import paths.
if len(p.DepsErrors) == 0 { if len(p.DepsErrors) == 0 {
dep1, dep2 := foldDup(p.Deps) dep1, dep2 := str.FoldDup(p.Deps)
if dep1 != "" { if dep1 != "" {
p.Error = &PackageError{ p.Error = &PackageError{
ImportStack: stk.copy(), ImportStack: stk.copy(),
...@@ -1605,7 +1606,7 @@ func isStale(p *Package) (bool, string) { ...@@ -1605,7 +1606,7 @@ func isStale(p *Package) (bool, string) {
// to test for write access, and then skip GOPATH roots we don't have write // to test for write access, and then skip GOPATH roots we don't have write
// access to. But hopefully we can just use the mtimes always. // access to. But hopefully we can just use the mtimes always.
srcs := stringList(p.GoFiles, p.CFiles, p.CXXFiles, p.MFiles, p.HFiles, p.FFiles, p.SFiles, p.CgoFiles, p.SysoFiles, p.SwigFiles, p.SwigCXXFiles) srcs := str.StringList(p.GoFiles, p.CFiles, p.CXXFiles, p.MFiles, p.HFiles, p.FFiles, p.SFiles, p.CgoFiles, p.SysoFiles, p.SwigFiles, p.SwigCXXFiles)
for _, src := range srcs { for _, src := range srcs {
if olderThan(filepath.Join(p.Dir, src)) { if olderThan(filepath.Join(p.Dir, src)) {
return true, "newer source file" return true, "newer source file"
...@@ -1623,7 +1624,7 @@ func computeBuildID(p *Package) { ...@@ -1623,7 +1624,7 @@ func computeBuildID(p *Package) {
// Include the list of files compiled as part of the package. // Include the list of files compiled as part of the package.
// This lets us detect removed files. See issue 3895. // This lets us detect removed files. See issue 3895.
inputFiles := stringList( inputFiles := str.StringList(
p.GoFiles, p.GoFiles,
p.CgoFiles, p.CgoFiles,
p.CFiles, p.CFiles,
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
package main package main
import ( import (
"cmd/go/internal/str"
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
...@@ -17,16 +18,16 @@ var foldDupTests = []struct { ...@@ -17,16 +18,16 @@ var foldDupTests = []struct {
list []string list []string
f1, f2 string f1, f2 string
}{ }{
{stringList("math/rand", "math/big"), "", ""}, {str.StringList("math/rand", "math/big"), "", ""},
{stringList("math", "strings"), "", ""}, {str.StringList("math", "strings"), "", ""},
{stringList("strings"), "", ""}, {str.StringList("strings"), "", ""},
{stringList("strings", "strings"), "strings", "strings"}, {str.StringList("strings", "strings"), "strings", "strings"},
{stringList("Rand", "rand", "math", "math/rand", "math/Rand"), "Rand", "rand"}, {str.StringList("Rand", "rand", "math", "math/rand", "math/Rand"), "Rand", "rand"},
} }
func TestFoldDup(t *testing.T) { func TestFoldDup(t *testing.T) {
for _, tt := range foldDupTests { for _, tt := range foldDupTests {
f1, f2 := foldDup(tt.list) f1, f2 := str.FoldDup(tt.list)
if f1 != tt.f1 || f2 != tt.f2 { if f1 != tt.f1 || f2 != tt.f2 {
t.Errorf("foldDup(%q) = %q, %q, want %q, %q", tt.list, f1, f2, tt.f1, tt.f2) t.Errorf("foldDup(%q) = %q, %q, want %q, %q", tt.list, f1, f2, tt.f1, tt.f2)
} }
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
package main package main
import ( import (
"cmd/go/internal/str"
"fmt" "fmt"
"os" "os"
"os/exec" "os/exec"
...@@ -130,7 +131,7 @@ func runRun(cmd *Command, args []string) { ...@@ -130,7 +131,7 @@ func runRun(cmd *Command, args []string) {
// runProgram is the action for running a binary that has already // runProgram is the action for running a binary that has already
// been compiled. We ignore exit status. // been compiled. We ignore exit status.
func (b *builder) runProgram(a *action) error { func (b *builder) runProgram(a *action) error {
cmdline := stringList(findExecCmd(), a.deps[0].target, a.args) cmdline := str.StringList(findExecCmd(), a.deps[0].target, a.args)
if buildN || buildX { if buildN || buildX {
b.showcmd("", "%s", strings.Join(cmdline, " ")) b.showcmd("", "%s", strings.Join(cmdline, " "))
if buildN { if buildN {
......
...@@ -6,6 +6,7 @@ package main ...@@ -6,6 +6,7 @@ package main
import ( import (
"bytes" "bytes"
"cmd/go/internal/str"
"errors" "errors"
"fmt" "fmt"
"go/ast" "go/ast"
...@@ -636,15 +637,6 @@ func runTest(cmd *Command, args []string) { ...@@ -636,15 +637,6 @@ func runTest(cmd *Command, args []string) {
b.do(root) b.do(root)
} }
func contains(x []string, s string) bool {
for _, t := range x {
if t == s {
return true
}
}
return false
}
var windowsBadWords = []string{ var windowsBadWords = []string{
"install", "install",
"patch", "patch",
...@@ -679,7 +671,7 @@ func builderTest(b *builder, p *Package) (buildAction, runAction, printAction *a ...@@ -679,7 +671,7 @@ func builderTest(b *builder, p *Package) (buildAction, runAction, printAction *a
err.Pos = "" // show full import stack err.Pos = "" // show full import stack
return nil, nil, nil, err return nil, nil, nil, err
} }
if contains(p1.Deps, p.ImportPath) || p1.ImportPath == p.ImportPath { if str.Contains(p1.Deps, p.ImportPath) || p1.ImportPath == p.ImportPath {
// Same error that loadPackage returns (via reusePackage) in pkg.go. // Same error that loadPackage returns (via reusePackage) in pkg.go.
// Can't change that code, because that code is only for loading the // Can't change that code, because that code is only for loading the
// non-test copy of a package. // non-test copy of a package.
...@@ -764,7 +756,7 @@ func builderTest(b *builder, p *Package) (buildAction, runAction, printAction *a ...@@ -764,7 +756,7 @@ func builderTest(b *builder, p *Package) (buildAction, runAction, printAction *a
ptest.GoFiles = append(ptest.GoFiles, p.GoFiles...) ptest.GoFiles = append(ptest.GoFiles, p.GoFiles...)
ptest.GoFiles = append(ptest.GoFiles, p.TestGoFiles...) ptest.GoFiles = append(ptest.GoFiles, p.TestGoFiles...)
ptest.target = "" ptest.target = ""
ptest.Imports = stringList(p.Imports, p.TestImports) ptest.Imports = str.StringList(p.Imports, p.TestImports)
ptest.imports = append(append([]*Package{}, p.imports...), imports...) ptest.imports = append(append([]*Package{}, p.imports...), imports...)
ptest.pkgdir = testDir ptest.pkgdir = testDir
ptest.fake = true ptest.fake = true
...@@ -1016,7 +1008,7 @@ func testImportStack(top string, p *Package, target string) []string { ...@@ -1016,7 +1008,7 @@ func testImportStack(top string, p *Package, target string) []string {
Search: Search:
for p.ImportPath != target { for p.ImportPath != target {
for _, p1 := range p.imports { for _, p1 := range p.imports {
if p1.ImportPath == target || contains(p1.Deps, target) { if p1.ImportPath == target || str.Contains(p1.Deps, target) {
stk = append(stk, p1.ImportPath) stk = append(stk, p1.ImportPath)
p = p1 p = p1
continue Search continue Search
...@@ -1103,7 +1095,7 @@ var noTestsToRun = []byte("\ntesting: warning: no tests to run\n") ...@@ -1103,7 +1095,7 @@ var noTestsToRun = []byte("\ntesting: warning: no tests to run\n")
// builderRunTest is the action for running a test binary. // builderRunTest is the action for running a test binary.
func builderRunTest(b *builder, a *action) error { func builderRunTest(b *builder, a *action) error {
args := stringList(findExecCmd(), a.deps[0].target, testArgs) args := str.StringList(findExecCmd(), a.deps[0].target, testArgs)
a.testOutput = new(bytes.Buffer) a.testOutput = new(bytes.Buffer)
if buildN || buildX { if buildN || buildX {
......
...@@ -4,7 +4,11 @@ ...@@ -4,7 +4,11 @@
package main package main
import "path/filepath" import (
"path/filepath"
"cmd/go/internal/str"
)
func init() { func init() {
addBuildFlags(cmdVet) addBuildFlags(cmdVet)
...@@ -36,10 +40,10 @@ func runVet(cmd *Command, args []string) { ...@@ -36,10 +40,10 @@ func runVet(cmd *Command, args []string) {
// Vet expects to be given a set of files all from the same package. // Vet expects to be given a set of files all from the same package.
// Run once for package p and once for package p_test. // Run once for package p and once for package p_test.
if len(p.GoFiles)+len(p.CgoFiles)+len(p.TestGoFiles) > 0 { if len(p.GoFiles)+len(p.CgoFiles)+len(p.TestGoFiles) > 0 {
runVetFiles(p, stringList(p.GoFiles, p.CgoFiles, p.TestGoFiles, p.SFiles)) runVetFiles(p, str.StringList(p.GoFiles, p.CgoFiles, p.TestGoFiles, p.SFiles))
} }
if len(p.XTestGoFiles) > 0 { if len(p.XTestGoFiles) > 0 {
runVetFiles(p, stringList(p.XTestGoFiles)) runVetFiles(p, str.StringList(p.XTestGoFiles))
} }
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment