Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201105173854-bc9fc8d8c4bc / go / vcs / discovery.go
1 // Copyright 2012 The Go Authors.  All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package vcs
6
7 import (
8         "encoding/xml"
9         "fmt"
10         "io"
11         "strings"
12 )
13
14 // charsetReader returns a reader for the given charset. Currently
15 // it only supports UTF-8 and ASCII. Otherwise, it returns a meaningful
16 // error which is printed by go get, so the user can find why the package
17 // wasn't downloaded if the encoding is not supported. Note that, in
18 // order to reduce potential errors, ASCII is treated as UTF-8 (i.e. characters
19 // greater than 0x7f are not rejected).
20 func charsetReader(charset string, input io.Reader) (io.Reader, error) {
21         switch strings.ToLower(charset) {
22         case "ascii":
23                 return input, nil
24         default:
25                 return nil, fmt.Errorf("can't decode XML document using charset %q", charset)
26         }
27 }
28
29 // parseMetaGoImports returns meta imports from the HTML in r.
30 // Parsing ends at the end of the <head> section or the beginning of the <body>.
31 //
32 // This copy of cmd/go/internal/vcs.parseMetaGoImports always operates
33 // in IgnoreMod ModuleMode.
34 func parseMetaGoImports(r io.Reader) (imports []metaImport, err error) {
35         d := xml.NewDecoder(r)
36         d.CharsetReader = charsetReader
37         d.Strict = false
38         var t xml.Token
39         for {
40                 t, err = d.RawToken()
41                 if err != nil {
42                         if err == io.EOF || len(imports) > 0 {
43                                 err = nil
44                         }
45                         return
46                 }
47                 if e, ok := t.(xml.StartElement); ok && strings.EqualFold(e.Name.Local, "body") {
48                         return
49                 }
50                 if e, ok := t.(xml.EndElement); ok && strings.EqualFold(e.Name.Local, "head") {
51                         return
52                 }
53                 e, ok := t.(xml.StartElement)
54                 if !ok || !strings.EqualFold(e.Name.Local, "meta") {
55                         continue
56                 }
57                 if attrValue(e.Attr, "name") != "go-import" {
58                         continue
59                 }
60                 if f := strings.Fields(attrValue(e.Attr, "content")); len(f) == 3 {
61                         // Ignore VCS type "mod", which is applicable only in module mode.
62                         if f[1] == "mod" {
63                                 continue
64                         }
65                         imports = append(imports, metaImport{
66                                 Prefix:   f[0],
67                                 VCS:      f[1],
68                                 RepoRoot: f[2],
69                         })
70                 }
71         }
72 }
73
74 // attrValue returns the attribute value for the case-insensitive key
75 // `name', or the empty string if nothing is found.
76 func attrValue(attrs []xml.Attr, name string) string {
77         for _, a := range attrs {
78                 if strings.EqualFold(a.Name.Local, name) {
79                         return a.Value
80                 }
81         }
82         return ""
83 }