1
0
mirror of https://github.com/golang/go synced 2024-11-19 01:54:39 -07:00
go/cmd/oracle/main.go
Alan Donovan b21b4e8c88 go.tools/importer: negate "cgo" build tag to avoid native code in "net".
This removes the need for the caller to specify CGO_ENABLED=0
in the environment.

R=crawshaw
CC=golang-dev
https://golang.org/cl/13464045
2013-09-04 15:20:38 -04:00

132 lines
3.0 KiB
Go

// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// oracle: a tool for answering questions about Go source code.
//
// With -format=plain, the oracle prints query results to the standard
// output in an editor-friendly format in which every line of output
// is of the form "pos: text", where pos = "-" if unknown.
//
// With -format=json, the oracle prints structured data in JSON syntax.
//
package main
import (
"bufio"
"bytes"
"encoding/json"
"flag"
"fmt"
"go/build"
"io"
"log"
"os"
"runtime"
"runtime/pprof"
"code.google.com/p/go.tools/oracle"
)
var posFlag = flag.String("pos", "",
"Filename and byte offset or extent of a syntax element about which to query, "+
"e.g. foo.go:#123-#456, bar.go:#123.")
var modeFlag = flag.String("mode", "",
"Mode of query to perform: e.g. callers, describe, etc.")
var ptalogFlag = flag.String("ptalog", "",
"Location of the points-to analysis log file, or empty to disable logging.")
var formatFlag = flag.String("format", "plain", "Output format: 'plain' or 'json'.")
const usage = `Go source code oracle.
Usage: oracle [<flag> ...] [<file.go> ...] [<arg> ...]
Use -help flag to display options.
Examples:
% oracle -pos=hello.go:#123 hello.go
% oracle -pos=hello.go:#123-#456 hello.go
`
var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")
func init() {
// If $GOMAXPROCS isn't set, use the full capacity of the machine.
// For small machines, use at least 4 threads.
if os.Getenv("GOMAXPROCS") == "" {
n := runtime.NumCPU()
if n < 4 {
n = 4
}
runtime.GOMAXPROCS(n)
}
}
func main() {
flag.Parse()
args := flag.Args()
if len(args) == 0 {
fmt.Fprint(os.Stderr, usage)
os.Exit(1)
}
// Set up points-to analysis log file.
var ptalog io.Writer
if *ptalogFlag != "" {
if f, err := os.Create(*ptalogFlag); err != nil {
log.Fatalf(err.Error())
} else {
buf := bufio.NewWriter(f)
ptalog = buf
defer func() {
buf.Flush()
f.Close()
}()
}
}
// Profiling support.
if *cpuprofile != "" {
f, err := os.Create(*cpuprofile)
if err != nil {
log.Fatal(err)
}
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()
}
// -format flag
if *formatFlag != "json" && *formatFlag != "plain" {
fmt.Fprintf(os.Stderr, "Error: illegal -format value: %q", *formatFlag)
os.Exit(1)
}
// Ask the oracle.
res, err := oracle.Query(args, *modeFlag, *posFlag, ptalog, &build.Default)
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %s\n", err)
os.Exit(1)
}
// Print the result.
switch *formatFlag {
case "json":
b, err := json.Marshal(res)
if err != nil {
fmt.Fprintf(os.Stderr, "JSON error: %s\n", err.Error())
os.Exit(1)
}
var buf bytes.Buffer
if err := json.Indent(&buf, b, "", "\t"); err != nil {
fmt.Fprintf(os.Stderr, "json.Indent failed: %s", err)
os.Exit(1)
}
os.Stdout.Write(buf.Bytes())
case "plain":
res.WriteTo(os.Stdout)
}
}