func runOracle(cmd *command.Command, args []string) error { if len(args) < 2 { cmd.Usage() return os.ErrInvalid } if os.Getenv("GOMAXPROCS") == "" { n := runtime.NumCPU() if n < 4 { n = 4 } runtime.GOMAXPROCS(n) } mode := args[0] args = args[1:] if args[0] == "." { pkgPath, err := os.Getwd() if err != nil { log.Fatalln(err) } pkg, err := build.Default.ImportDir(pkgPath, 0) if err != nil { log.Fatalln(err) } args = pkg.GoFiles //log.Println(pkg.ImportPath) if pkg.ImportPath != "." && pkg.ImportPath != "" { args = []string{pkg.ImportPath} } } query := oracle.Query{ Mode: mode, Pos: oraclePos, Build: &build.Default, Scope: args, PTALog: nil, Reflection: oracleReflect, } if err := oracle.Run(&query); err != nil { fmt.Fprintf(os.Stderr, "oracle: %s.\n", err) return err } if mode == "referrers" { ref := query.Serial().Referrers if ref != nil { fmt.Fprintln(os.Stdout, ref.Desc) fmt.Fprintln(os.Stdout, ref.ObjPos) for _, v := range ref.Refs { fmt.Fprintln(os.Stdout, v) } } } else { query.WriteTo(os.Stdout) } return nil }
// WriteResult writes res (-format=plain) to w, stripping file locations. func WriteResult(w io.Writer, q *oracle.Query) { capture := new(bytes.Buffer) // capture standard output q.WriteTo(capture) for _, line := range strings.Split(capture.String(), "\n") { // Remove a "file:line: " prefix. if i := strings.Index(line, ": "); i >= 0 { line = line[i+2:] } fmt.Fprintf(w, "%s\n", line) } }
func main() { // Don't print full help unless -help was requested. // Just gently remind users that it's there. flag.Usage = func() { fmt.Fprint(os.Stderr, useHelp) } flag.CommandLine.Init(os.Args[0], flag.ContinueOnError) // hack if err := flag.CommandLine.Parse(os.Args[1:]); err != nil { // (err has already been printed) if err == flag.ErrHelp { printHelp() } os.Exit(2) } args := flag.Args() if len(args) == 0 || args[0] == "" { fmt.Fprint(os.Stderr, "oracle: a mode argument is required.\n"+useHelp) os.Exit(2) } mode := args[0] args = args[1:] if mode == "help" { printHelp() os.Exit(2) } // Set up points-to analysis log file. var ptalog io.Writer if *ptalogFlag != "" { if f, err := os.Create(*ptalogFlag); err != nil { log.Fatalf("Failed to create PTA log file: %s", err) } else { buf := bufio.NewWriter(f) ptalog = buf defer func() { if err := buf.Flush(); err != nil { log.Printf("flush: %s", err) } if err := f.Close(); err != nil { log.Printf("close: %s", err) } }() } } // Profiling support. if *cpuprofile != "" { f, err := os.Create(*cpuprofile) if err != nil { log.Fatal(err) } pprof.StartCPUProfile(f) defer pprof.StopCPUProfile() } // -format flag switch *formatFlag { case "json", "plain", "xml": // ok default: fmt.Fprintf(os.Stderr, "oracle: illegal -format value: %q.\n"+useHelp, *formatFlag) os.Exit(2) } // Ask the oracle. query := oracle.Query{ Mode: mode, Pos: *posFlag, Build: &build.Default, Scope: args, PTALog: ptalog, Reflection: *reflectFlag, } if err := oracle.Run(&query); err != nil { fmt.Fprintf(os.Stderr, "oracle: %s\n", err) os.Exit(1) } // Print the result. switch *formatFlag { case "json": b, err := json.MarshalIndent(query.Serial(), "", "\t") if err != nil { fmt.Fprintf(os.Stderr, "oracle: JSON error: %s\n", err) os.Exit(1) } os.Stdout.Write(b) case "xml": b, err := xml.MarshalIndent(query.Serial(), "", "\t") if err != nil { fmt.Fprintf(os.Stderr, "oracle: XML error: %s\n", err) os.Exit(1) } os.Stdout.Write(b) case "plain": query.WriteTo(os.Stdout) } }