func doversion() { p := obj.Expstring() if p == "X:none" { p = "" } sep := "" if p != "" { sep = " " } fmt.Printf("compile version %s%s%s\n", obj.Getgoversion(), sep, p) os.Exit(0) }
func importfile(f *Val, indent []byte) { if importpkg != nil { Fatalf("importpkg not nil") } path_, ok := f.U.(string) if !ok { Yyerror("import statement not a string") return } if len(path_) == 0 { Yyerror("import path is empty") return } if isbadimport(path_) { return } // The package name main is no longer reserved, // but we reserve the import path "main" to identify // the main package, just as we reserve the import // path "math" to identify the standard math package. if path_ == "main" { Yyerror("cannot import \"main\"") errorexit() } if myimportpath != "" && path_ == myimportpath { Yyerror("import %q while compiling that package (import cycle)", path_) errorexit() } if mapped, ok := importMap[path_]; ok { path_ = mapped } if path_ == "unsafe" { if safemode { Yyerror("cannot import package unsafe") errorexit() } importpkg = unsafepkg imported_unsafe = true return } if islocalname(path_) { if path_[0] == '/' { Yyerror("import path cannot be absolute path") return } prefix := Ctxt.Pathname if localimport != "" { prefix = localimport } path_ = path.Join(prefix, path_) if isbadimport(path_) { return } } file, found := findpkg(path_) if !found { Yyerror("can't find import: %q", path_) errorexit() } importpkg = mkpkg(path_) if importpkg.Imported { return } importpkg.Imported = true impf, err := os.Open(file) if err != nil { Yyerror("can't open import: %q: %v", path_, err) errorexit() } defer impf.Close() imp := bufio.NewReader(impf) if strings.HasSuffix(file, ".a") { if !skiptopkgdef(imp) { Yyerror("import %s: not a package file", file) errorexit() } } // check object header p, err := imp.ReadString('\n') if err != nil { log.Fatalf("reading input: %v", err) } if len(p) > 0 { p = p[:len(p)-1] } if p != "empty archive" { if !strings.HasPrefix(p, "go object ") { Yyerror("import %s: not a go object file: %s", file, p) errorexit() } q := fmt.Sprintf("%s %s %s %s", obj.Getgoos(), obj.Getgoarch(), obj.Getgoversion(), obj.Expstring()) if p[10:] != q { Yyerror("import %s: object is [%s] expected [%s]", file, p[10:], q) errorexit() } } // process header lines for { p, err = imp.ReadString('\n') if err != nil { log.Fatalf("reading input: %v", err) } if p == "\n" { break // header ends with blank line } if strings.HasPrefix(p, "safe") { importpkg.Safe = true break // ok to ignore rest } } // assume files move (get installed) // so don't record the full path. linehistpragma(file[len(file)-len(path_)-2:]) // acts as #pragma lib // In the importfile, if we find: // $$\n (old format): position the input right after $$\n and return // $$B\n (new format): import directly, then feed the lexer a dummy statement // look for $$ var c byte for { c, err = imp.ReadByte() if err != nil { break } if c == '$' { c, err = imp.ReadByte() if c == '$' || err != nil { break } } } // get character after $$ if err == nil { c, _ = imp.ReadByte() } switch c { case '\n': // old export format parse_import(imp, indent) case 'B': // new export format if Debug_export != 0 { fmt.Printf("importing %s (%s)\n", path_, file) } imp.ReadByte() // skip \n after $$B Import(imp) default: Yyerror("no import in %q", path_) errorexit() } if safemode && !importpkg.Safe { Yyerror("cannot import unsafe package %q", importpkg.Path) } }