1
2
3
4
5
6
7 package importer
8
9 import (
10 "bufio"
11 "fmt"
12 "internal/exportdata"
13 "internal/pkgbits"
14 "internal/saferio"
15 "io"
16 "os"
17 "strings"
18
19 "cmd/compile/internal/types2"
20 )
21
22
23
24
25
26
27 func Import(packages map[string]*types2.Package, path, srcDir string, lookup func(path string) (io.ReadCloser, error)) (pkg *types2.Package, err error) {
28 var rc io.ReadCloser
29 var id string
30 if lookup != nil {
31
32
33 if path == "unsafe" {
34 return types2.Unsafe, nil
35 }
36 id = path
37
38
39 if pkg = packages[id]; pkg != nil && pkg.Complete() {
40 return
41 }
42 f, err := lookup(path)
43 if err != nil {
44 return nil, err
45 }
46 rc = f
47 } else {
48 var filename string
49 filename, id, err = exportdata.FindPkg(path, srcDir)
50 if filename == "" {
51 if path == "unsafe" {
52 return types2.Unsafe, nil
53 }
54 return nil, err
55 }
56
57
58 if pkg = packages[id]; pkg != nil && pkg.Complete() {
59 return
60 }
61
62
63 f, err := os.Open(filename)
64 if err != nil {
65 return nil, err
66 }
67 defer func() {
68 if err != nil {
69
70 err = fmt.Errorf("%s: %v", filename, err)
71 }
72 }()
73 rc = f
74 }
75 defer rc.Close()
76
77 buf := bufio.NewReader(rc)
78 hdr, size, err := exportdata.FindExportData(buf)
79 if err != nil {
80 return
81 }
82
83 switch hdr {
84 case "$$\n":
85 err = fmt.Errorf("import %q: old textual export format no longer supported (recompile package)", path)
86
87 case "$$B\n":
88 var exportFormat byte
89 if exportFormat, err = buf.ReadByte(); err != nil {
90 return
91 }
92 size--
93
94
95
96
97
98 switch exportFormat {
99 case 'u':
100
101 var data []byte
102 var r io.Reader = buf
103 if size >= 0 {
104 if data, err = saferio.ReadData(r, uint64(size)); err != nil {
105 return
106 }
107 } else if data, err = io.ReadAll(r); err != nil {
108 return
109 }
110 s := string(data)
111 s = s[:strings.LastIndex(s, "\n$$\n")]
112
113 input := pkgbits.NewPkgDecoder(id, s)
114 pkg = ReadPackage(nil, packages, input)
115 default:
116 err = fmt.Errorf("import %q: binary export format %q is no longer supported (recompile package)", path, exportFormat)
117 }
118
119 default:
120 err = fmt.Errorf("import %q: unknown export data header: %q", path, hdr)
121 }
122
123 return
124 }
125
View as plain text