Beispiel #1
0
// allow invocation from test
func MainArgs(args []string) {
	//fmt.Println(os.Args)
	os.Args = args

	flag.Usage = use
	if len(os.Args) < 2 {
		use()
	}

	flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ExitOnError)
	debug := flag.Bool("debug", false, "print lots of debug info as we process.")
	outdir := flag.String("o", "odir", "specify output directory")
	pkg := flag.String("p", "main", "specify package for generated code")
	privs := flag.Bool("X", false, "export private as well as public struct fields")
	overwrite := flag.Bool("OVERWRITE", false, "replace named .go files with capid tagged versions.")
	flag.Parse()

	if debug != nil {
		bam.Verbose = *debug
	}

	if outdir == nil || *outdir == "" {
		fmt.Fprintf(os.Stderr, "required -o option missing. Use bambam -o <dirname> myfile.go # to specify the output directory.\n")
		use()
	}

	if !bam.DirExists(*outdir) {
		err := os.MkdirAll(*outdir, 0755)
		if err != nil {
			panic(err)
		}
	}

	if pkg == nil || *pkg == "" {
		fmt.Fprintf(os.Stderr, "required -p option missing. Specify a package name for the generated go code with -p <pkgname>\n")
		use()
	}

	// all the rest are input .go files
	inputFiles := flag.Args()

	if len(inputFiles) == 0 {
		fmt.Fprintf(os.Stderr, "bambam needs at least one .go golang source file to process specified on the command line.\n")
		os.Exit(1)
	}

	for _, fn := range inputFiles {
		if !strings.HasSuffix(fn, ".go") && !strings.HasSuffix(fn, ".go.txt") {
			fmt.Fprintf(os.Stderr, "error: bambam input file '%s' did not end in '.go' or '.go.txt'.\n", fn)
			os.Exit(1)
		}
	}

	x := bam.NewExtractor()
	x.FieldPrefix = "   "
	x.FieldSuffix = "\n"
	x.OutDir = *outdir
	if privs != nil {
		x.ExtractPrivate = *privs
	}
	if overwrite != nil {
		x.Overwrite = *overwrite
	}

	for _, inFile := range inputFiles {
		_, err := x.ExtractStructsFromOneFile(nil, inFile)
		if err != nil {
			panic(err)
		}
	}
	// get rid of default tmp dir
	x.CompileDir = bam.NewTempDir()
	x.CompileDir.Cleanup()

	x.CompileDir.DirPath = *outdir
	x.PkgName = *pkg

	schemaFN := x.CompileDir.DirPath + "/schema.capnp"
	schemaFile, err := os.Create(schemaFN)
	if err != nil {
		panic(err)
	}
	defer schemaFile.Close()

	by := x.GenCapnpHeader()
	schemaFile.Write(by.Bytes())

	_, err = x.WriteToSchema(schemaFile)
	if err != nil {
		panic(err)
	}

	fmt.Fprintf(schemaFile, "\n")
	fmt.Fprintf(schemaFile, "##compile with:\n\n##\n##\n##   capnp compile -ogo %s\n\n", schemaFN)

	// translator library of go functions is separate from the schema

	translateFn := x.CompileDir.DirPath + "/translateCapn.go"
	translatorFile, err := os.Create(translateFn)
	if err != nil {
		panic(err)
	}
	defer translatorFile.Close()
	fmt.Fprintf(translatorFile, `package %s

import (
  capn "github.com/glycerine/go-capnproto"
  "io"
)

`, x.PkgName)

	_, err = x.WriteToTranslators(translatorFile)
	if err != nil {
		panic(err)
	}

	err = x.CopySourceFilesAddCapidTag()
	if err != nil {
		panic(err)
	}

	exec.Command("cp", "-p", "go.capnp", x.CompileDir.DirPath).Run()
	fmt.Printf("generated files in '%s'\n", x.CompileDir.DirPath)
}
Beispiel #2
0
func main() {
	s, err := C.ReadFromStream(os.Stdin, nil)
	assert(err == nil, "%v\n", err)

	req := caps.ReadRootCodeGeneratorRequest(s)
	allfiles := []*node{}

	for _, ni := range req.Nodes().ToArray() {
		n := &node{Node: ni, codecs: make(map[uint64]bool)}
		g_nodes[n.Id()] = n

		if n.Which() == caps.NODE_FILE {
			allfiles = append(allfiles, n)
		}
	}

	g_imported = make(map[string]bool)

	for _, f := range allfiles {
		for _, a := range f.Annotations().ToArray() {
			if v := a.Value(); v.Which() == caps.VALUE_TEXT {
				switch a.Id() {
				case C.Package:
					f.pkg = v.Text()
				case C.Import:
					f.imp = v.Text()
				}
			} else {
				switch a.Id() {
				case caps.CodecCapnp:
					enableCodec(f, caps.CodecCapnp)
					g_imported["io"] = true
					g_imported[GO_CAPNP_IMPORT] = true
				case caps.CodecJson:
					enableCodec(f, caps.CodecJson)
				case caps.CodecMsgp:
					enableCodec(f, caps.CodecMsgp)
				}
			}
		}

		for _, nn := range f.NestedNodes().ToArray() {
			if ni := g_nodes[nn.Id()]; ni != nil {
				ni.resolveName("", nn.Name(), f)
			}
		}
	}

	for _, reqf := range req.RequestedFiles().ToArray() {
		x := bam.NewExtractor()
		x.FieldPrefix = "   "
		x.FieldSuffix = "\n"

		f := findNode(reqf.Id())
		buf := bytes.Buffer{}
		g_segment = C.NewBuffer([]byte{})

		defineConstNodes(&buf, f.nodes)

		for _, n := range f.nodes {
			switch n.Which() {
			case caps.NODE_ANNOTATION:
				n.defineAnnotation(&buf)
			case caps.NODE_ENUM:
				n.defineEnum(&buf, x)
			case caps.NODE_STRUCT:
				if !n.Struct().IsGroup() {
					n.defineStructTypes(&buf, nil, x)
					// n.defineStructEnums(&buf)
				}
			}
		}

		// Write translation functions
		if _, found := f.codecs[caps.CodecCapnp]; found {
			_, err = x.WriteToTranslators(&buf)
			assert(err == nil, "%v\n", err)
		}

		assert(f.pkg != "", "missing package annotation for %s", reqf.Filename())
		x.PkgName = f.pkg

		if dirPath, _ := filepath.Split(reqf.Filename()); dirPath != "" {
			err := os.MkdirAll(dirPath, os.ModePerm)
			assert(err == nil, "%v\n", err)
			x.OutDir = dirPath
		}

		// Create output file
		filename := strings.TrimSuffix(reqf.Filename(), ".capnp")

		file, err := os.Create(filename + ".go")
		assert(err == nil, "%v\n", err)

		// Write package
		fmt.Fprintf(file, "package %s\n\n", f.pkg)
		fmt.Fprintf(file, "// AUTO GENERATED - DO NOT EDIT\n\n")

		// Write imports
		f.writeImports(file)

		// Format sources
		clean, err := format.Source(buf.Bytes())
		assert(err == nil, "%v\n", err)
		file.Write(clean)

		defer file.Close()
	}
}