gosrc: support vendored std libs and different OS/ARCH std libs

update golang/gddo#508

Change-Id: I7c65e901cd42c5731ae62b16e4baa84d08d3b432
Reviewed-on: https://go-review.googlesource.com/60110
Reviewed-by: Dmitri Shuralyov <shurcool@gmail.com>
diff --git a/gosrc/data.go b/gosrc/data.go
index 64e6708..b3773f6 100644
--- a/gosrc/data.go
+++ b/gosrc/data.go
@@ -239,6 +239,7 @@
 	"internal/race":                     3,
 	"internal/singleflight":             3,
 	"internal/syscall":                  1,
+	"internal/syscall/unix":             3,
 	"internal/syscall/windows":          3,
 	"internal/syscall/windows/registry": 3,
 	"internal/syscall/windows/sysdll":   3,
@@ -331,6 +332,7 @@
 	"vendor/golang_org/x/net/idna":                                  3,
 	"vendor/golang_org/x/net/lex":                                   1,
 	"vendor/golang_org/x/net/lex/httplex":                           3,
+	"vendor/golang_org/x/net/lif":                                   3,
 	"vendor/golang_org/x/net/nettest":                               3,
 	"vendor/golang_org/x/net/proxy":                                 3,
 	"vendor/golang_org/x/net/route":                                 3,
diff --git a/gosrc/gen.go b/gosrc/gen.go
index 29fb535..038e938 100644
--- a/gosrc/gen.go
+++ b/gosrc/gen.go
@@ -55,10 +55,10 @@
 		log.Fatal("usage: decgen [--output filename]")
 	}
 
-	// Build map of standard repository path flags.
+	// Build map of standard repository path flags for each GOOS/GOARCH distribution.
 
-	cmd := exec.Command("go", "list", "std", "cmd")
-	p, err := cmd.Output()
+	cmd := exec.Command("go", "tool", "dist", "list")
+	dists, err := cmd.Output()
 	if err != nil {
 		log.Fatal(err)
 	}
@@ -66,15 +66,27 @@
 		"builtin": packagePath | goRepoPath,
 		"C":       packagePath,
 	}
-	for _, path := range strings.Fields(string(p)) {
-		pathFlags[path] |= packagePath | goRepoPath
-		for {
-			i := strings.LastIndex(path, "/")
-			if i < 0 {
-				break
+
+	for _, dist := range strings.Fields(string(dists)) {
+		c := strings.Split(dist, "/")
+		os.Setenv("GOOS", c[0])
+		os.Setenv("GOARCH", c[1])
+		cmd := exec.Command("go", "list", "std", "cmd")
+		p, err := cmd.Output()
+		if err != nil {
+			log.Fatal(err)
+		}
+
+		for _, path := range strings.Fields(string(p)) {
+			pathFlags[path] |= packagePath | goRepoPath
+			for {
+				i := strings.LastIndex(path, "/")
+				if i < 0 {
+					break
+				}
+				path = path[:i]
+				pathFlags[path] |= goRepoPath
 			}
-			path = path[:i]
-			pathFlags[path] |= goRepoPath
 		}
 	}
 
@@ -85,7 +97,7 @@
 		log.Fatal(err)
 	}
 	defer resp.Body.Close()
-	p, err = ioutil.ReadAll(resp.Body)
+	p, err := ioutil.ReadAll(resp.Body)
 	if err != nil {
 		log.Fatal(err)
 	}
diff --git a/gosrc/path.go b/gosrc/path.go
index cde7c5a..2b0803c 100644
--- a/gosrc/path.go
+++ b/gosrc/path.go
@@ -50,5 +50,7 @@
 
 // IsValidPath returns true if importPath is structurally valid.
 func IsValidPath(importPath string) bool {
-	return pathFlags[importPath]&packagePath != 0 || IsValidRemotePath(importPath)
+	return pathFlags[importPath]&packagePath != 0 ||
+		pathFlags["vendor/"+importPath]&packagePath != 0 ||
+		IsValidRemotePath(importPath)
 }