Example #1
0
// doQuery poses query q to the oracle and writes its response and
// error (if any) to out.
func doQuery(out io.Writer, q *query, useJson bool) {
	fmt.Fprintf(out, "-------- @%s %s --------\n", q.verb, q.id)

	var buildContext = build.Default
	buildContext.GOPATH = "testdata"
	query := oracle.Query{
		Mode:       q.verb,
		Pos:        q.queryPos,
		Build:      &buildContext,
		Scope:      []string{q.filename},
		Reflection: true,
	}
	if err := oracle.Run(&query); err != nil {
		fmt.Fprintf(out, "\nError: %s\n", err)
		return
	}

	if useJson {
		// JSON output
		b, err := json.MarshalIndent(query.Serial(), "", "\t")
		if err != nil {
			fmt.Fprintf(out, "JSON error: %s\n", err.Error())
			return
		}
		out.Write(b)
		fmt.Fprintln(out)
	} else {
		// "plain" (compiler diagnostic format) output
		WriteResult(out, &query)
	}
}
Example #2
0
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
}
Example #3
0
// 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)
	}
}
Example #4
0
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)
	}
}