func parseFlags(o *plugin.Options) (*source, []string, error) {
	flag := o.Flagset
	flagDiffBase := flag.StringList("diff_base", "", "Source of base profile for comparison")
	flagBase := flag.StringList("base", "", "Source of base profile for profile subtraction")
	flagSymbolize := flag.String("symbolize", "", "Options for profile symbolization")
	flagBuildID := flag.String("buildid", "", "Override build id for first mapping")
	flagTimeout := flag.Int("timeout", -1, "Timeout in seconds for fetching a profile")
	flagAddComment := flag.String("add_comment", "", "Annotation string to record in the profile")
	flagSeconds := flag.Int("seconds", -1, "Length of time for dynamic profiles")
	flagInUseSpace := flag.Bool("inuse_space", false, "Display in-use memory size")
	flagInUseObjects := flag.Bool("inuse_objects", false, "Display in-use object counts")
	flagAllocSpace := flag.Bool("alloc_space", false, "Display allocated memory size")
	flagAllocObjects := flag.Bool("alloc_objects", false, "Display allocated object counts")
	flagTotalDelay := flag.Bool("total_delay", false, "Display total delay at each region")
	flagContentions := flag.Bool("contentions", false, "Display number of delays at each region")
	flagMeanDelay := flag.Bool("mean_delay", false, "Display mean delay at each region")
	flagTools := flag.String("tools", os.Getenv("PPROF_TOOLS"), "Path for object tool pathnames")
	flagHTTP := flag.String("http", "", "Present interactive web UI at the specified http host:port")
	flagNoBrowser := flag.Bool("no_browser", false, "Skip opening a browswer for the interactive web UI")
	cfg := currentConfig()
	configFlagSetter := installConfigFlags(flag, &cfg)
	flagCommands := make(map[string]*bool)
	flagParamCommands := make(map[string]*string)
	for name, cmd := range pprofCommands {
		if cmd.hasParam {
			flagParamCommands[name] = flag.String(name, "", "Generate a report in "+name+" format, matching regexp")
		} else {
			flagCommands[name] = flag.Bool(name, false, "Generate a report in "+name+" format")
		}
	}
	args := flag.Parse(func() {
		o.UI.Print(usageMsgHdr +
			usage(true) +
			usageMsgSrc +
			flag.ExtraUsage() +
			usageMsgVars)
	})
	if len(args) == 0 {
		return nil, nil, errors.New("no profile source specified")
	}
	var execName string
	if len(args) > 1 {
		arg0 := args[0]
		if file, err := o.Obj.Open(arg0, 0, ^uint64(0), 0); err == nil {
			file.Close()
			execName = arg0
			args = args[1:]
		} else if *flagBuildID == "" && isBuildID(arg0) {
			*flagBuildID = arg0
			args = args[1:]
		}
	}
	if err := configFlagSetter(); err != nil {
		return nil, nil, err
	}
	cmd, err := outputFormat(flagCommands, flagParamCommands)
	if err != nil {
		return nil, nil, err
	}
	if cmd != nil && *flagHTTP != "" {
		return nil, nil, errors.New("-http is not compatible with an output format on the command line")
	}
	if *flagNoBrowser && *flagHTTP == "" {
		return nil, nil, errors.New("-no_browser only makes sense with -http")
	}
	si := cfg.SampleIndex
	si = sampleIndex(flagTotalDelay, si, "delay", "-total_delay", o.UI)
	si = sampleIndex(flagMeanDelay, si, "delay", "-mean_delay", o.UI)
	si = sampleIndex(flagContentions, si, "contentions", "-contentions", o.UI)
	si = sampleIndex(flagInUseSpace, si, "inuse_space", "-inuse_space", o.UI)
	si = sampleIndex(flagInUseObjects, si, "inuse_objects", "-inuse_objects", o.UI)
	si = sampleIndex(flagAllocSpace, si, "alloc_space", "-alloc_space", o.UI)
	si = sampleIndex(flagAllocObjects, si, "alloc_objects", "-alloc_objects", o.UI)
	cfg.SampleIndex = si
	if *flagMeanDelay {
		cfg.Mean = true
	}
	source := &source{
		Sources:            args,
		ExecName:           execName,
		BuildID:            *flagBuildID,
		Seconds:            *flagSeconds,
		Timeout:            *flagTimeout,
		Symbolize:          *flagSymbolize,
		HTTPHostport:       *flagHTTP,
		HTTPDisableBrowser: *flagNoBrowser,
		Comment:            *flagAddComment,
	}
	if err := source.addBaseProfiles(*flagBase, *flagDiffBase); err != nil {
		return nil, nil, err
	}
	normalize := cfg.Normalize
	if normalize && len(source.Base) == 0 {
		return nil, nil, errors.New("must have base profile to normalize by")
	}
	source.Normalize = normalize
	if bu, ok := o.Obj.(*binutils.Binutils); ok {
		bu.SetTools(*flagTools)
	}
	setCurrentConfig(cfg)
	return source, cmd, nil
}
parseFlags parses the command lines through the specified flags package
and returns the source of the profile and optionally the command
for the kind of report to generate (nil for interactive use).
package driver
import (
	"errors"
	"fmt"
	"os"
	"strings"
	"github.com/google/pprof/internal/binutils"
	"github.com/google/pprof/internal/plugin"
)
type source struct {
	Sources   []string
	ExecName  string
	BuildID   string
	Base      []string
	DiffBase  bool
	Normalize bool
	Seconds            int
	Timeout            int
	Symbolize          string
	HTTPHostport       string
	HTTPDisableBrowser bool
	Comment            string
}