github.com/nickng/gospal@v1.0.0/cmd/ssaview/main.go (about)

     1  // Command ssaview is a SSA printer using standard static analysis options.
     2  //
     3  package main
     4  
     5  import (
     6  	"flag"
     7  	"fmt"
     8  	"io"
     9  	"log"
    10  	"os"
    11  
    12  	"github.com/nickng/gospal/ssa/build"
    13  )
    14  
    15  const (
    16  	Usage = `ssaview is a tool for printing SSA IR of Go source code.
    17  
    18  Usage:
    19  
    20    ssaview [options] file.go [files.go...]
    21  
    22  Options:
    23  
    24  `
    25  )
    26  
    27  var (
    28  	buildlogPath string
    29  	defaultArgs  bool
    30  	outPath      string
    31  	viewFunc     string
    32  
    33  	out io.Writer
    34  )
    35  
    36  const mainMain = "main.main"
    37  
    38  func init() {
    39  	flag.BoolVar(&defaultArgs, "default", true, "Use default SSA build arguments")
    40  	flag.StringVar(&buildlogPath, "log", "", "Specify build log file (use '-' for stdout)")
    41  	flag.StringVar(&outPath, "out", "", "Specify output file (default: stdout)")
    42  	flag.StringVar(&viewFunc, "func", mainMain, `Specify the function to view (format: (import/path).FuncName`)
    43  }
    44  
    45  func main() {
    46  	flag.Parse()
    47  	if flag.NArg() == 0 {
    48  		fmt.Fprintf(os.Stderr, Usage)
    49  		flag.PrintDefaults()
    50  		os.Exit(0)
    51  	}
    52  
    53  	conf := build.FromFiles(flag.Args()...)
    54  	if defaultArgs {
    55  		conf = conf.Default()
    56  	}
    57  
    58  	switch buildlogPath {
    59  	case "":
    60  	case "-":
    61  		conf = conf.WithBuildLog(os.Stdout, log.LstdFlags)
    62  	default:
    63  		f, err := os.Create(buildlogPath)
    64  		if err != nil {
    65  			log.Fatalf("Cannot create log %s: %v", buildlogPath, err)
    66  		}
    67  		defer f.Close()
    68  		conf = conf.WithBuildLog(f, log.LstdFlags)
    69  	}
    70  
    71  	switch outPath {
    72  	case "":
    73  		out = os.Stdout
    74  	default:
    75  		f, err := os.Create(outPath)
    76  		if err != nil {
    77  			log.Fatalf("Cannot create output file %s: %v", outPath, err)
    78  		}
    79  		defer f.Close()
    80  		out = f
    81  	}
    82  
    83  	info, err := conf.Build()
    84  	if err != nil {
    85  		log.Fatal("Cannot build SSA from files:", err)
    86  	}
    87  	if viewFunc != mainMain {
    88  		if _, err := info.WriteFunc(out, viewFunc); err != nil {
    89  			log.Fatal("Cannot write SSA:", err)
    90  		}
    91  	} else {
    92  		if _, err := info.WriteTo(out); err != nil {
    93  			log.Fatal("Cannot write SSA:", err)
    94  		}
    95  	}
    96  }