func main() { flag.Parse() var filename string switch flag.NArg() { case 0: filename = "/dev/stdin" case 1: filename = flag.Arg(0) default: usage() } src, err := ioutil.ReadFile(filename) if err != nil { scanner.PrintError(os.Stderr, err) } if path.Ext(filename) == ".html" { src = extractEBNF(src) } grammar, err := ebnf.Parse(filename, src) if err != nil { scanner.PrintError(os.Stderr, err) } if err = ebnf.Verify(grammar, *start); err != nil { scanner.PrintError(os.Stderr, err) } }
func main() { flag.Parse() log.SetFlags(0) // If no paths are provided then use the present working directory. roots := flag.Args() if len(roots) == 0 { roots = []string{"."} } // Recursively retrieve all ego templates var v visitor for _, root := range roots { if err := filepath.Walk(root, v.visit); err != nil { scanner.PrintError(os.Stderr, err) os.Exit(1) } } // Parse every *.ego file. for _, path := range v.paths { template, err := egon.ParseFile(path) if err != nil { log.Fatal("parse file: ", err) } pkg := &egon.Package{Template: template} err = pkg.Write() if err != nil { log.Fatal("write: ", err) } } }
// FormatCode runs "goimports -w" on the source file. func (f *SourceFile) FormatCode() error { if NoFormat { return nil } // Parse file into AST fset := token.NewFileSet() file, err := parser.ParseFile(fset, f.Abs(), nil, parser.ParseComments) if err != nil { content, _ := ioutil.ReadFile(f.Abs()) var buf bytes.Buffer scanner.PrintError(&buf, err) return fmt.Errorf("%s\n========\nContent:\n%s", buf.String(), content) } // Clean unused imports imports := astutil.Imports(fset, file) for _, group := range imports { for _, imp := range group { path := strings.Trim(imp.Path.Value, `"`) if !astutil.UsesImport(file, path) { astutil.DeleteImport(fset, file, path) } } } ast.SortImports(fset, file) // Open file to be written w, err := os.OpenFile(f.Abs(), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, os.ModePerm) if err != nil { return err } defer w.Close() // Write formatted code without unused imports return format.Node(w, fset, file) }
// ErrPosition reports an error at position. func (c *Report) ErrPosition(position token.Position, format string, arg ...interface{}) { if c.TraceErrors { fmt.Fprintf(os.Stderr, "%v: %s\n", position, fmt.Sprintf(format, arg...)) } if c.IgnoreErrors { return } c.errorsMu.Lock() // X+ defer c.errorsMu.Unlock() // X- if c.PanicOnError { panic(fmt.Errorf("%s: %v", position, fmt.Sprintf(format, arg...))) } c.errors.Add(position, fmt.Sprintf(format, arg...)) if c.ErrLimit > 0 { c.ErrLimit-- if c.ErrLimit == 0 { scanner.PrintError(os.Stderr, c.errors) log.Fatalf("too many errors") } } }
func main() { log.SetFlags(0) kingpin.CommandLine.Help = "Generate native Go code from ERB-style Templates" kingpin.Parse() if len(egon.Config.Folders) == 0 { egon.Config.Folders = []string{"."} } // Recursively retrieve all templates var v visitor for _, root := range egon.Config.Folders { log.Printf("scanning folder [%s]", root) if err := filepath.Walk(root, v.visit); err != nil { scanner.PrintError(os.Stderr, err) os.Exit(1) } } // Parse every *.ego file. for _, path := range v.paths { template, err := egon.ParseFile(path) if err != nil { log.Fatal("parse file: ", err) } pkg := &egon.Package{Template: template} err = pkg.Write() if err != nil { log.Fatal("write: ", err) } } }
func main() { log.SetFlags(0) list := flag.Bool("l", false, "List assembly code and exit.") trace := flag.Bool("t", false, "Trace execution.") stack := flag.Bool("s", false, "Trace execution and stack.") flag.Parse() if n := flag.NArg(); n != 1 { log.Fatalf("expected 1 argument, got %v", n) } prog, err := pl0.Parse(flag.Arg(0)) if err != nil { scanner.PrintError(os.Stderr, err) os.Stderr.Sync() os.Exit(1) } if *list { prog.List(os.Stdout) return } switch { case *stack: err = prog.Run(pl0.TraceStack()) case *trace: err = prog.Run(pl0.Trace()) default: err = prog.Run() } if err != nil { log.Fatal(err) } }
func Example_undeclared() { _, err := ParseString("", ` CONST a = 42; VAR b; PROCEDURE c; BEGIN CALL aa; CALL c; END; BEGIN b := a; b := d; e := 10; CALL c; CALL f; ? b; ? g; END. `) scanner.PrintError(os.Stdout, err) // Output: // 8:8: undeclared identifier aa // 14:8: undeclared identifier d // 15:3: undeclared identifier e // 17:8: undeclared identifier f // 19:5: undeclared identifier g }
func Example_redeclaration() { _, err := ParseString("", ` CONST a = 42, b = 24, a = 314; VAR b, c, d; PROCEDURE c; BEGIN END; PROCEDURE d; BEGIN END; PROCEDURE e; BEGIN END; PROCEDURE e; BEGIN END; BEGIN END. `) scanner.PrintError(os.Stdout, err) // Output: // 2:24: redeclaration of a at 2:8 // 4:6: redeclaration of b at 2:16 // 6:12: redeclaration of c at 4:9 // 10:12: redeclaration of d at 4:12 // 18:12: redeclaration of e at 14:12 }
func report(err error) { scanner.PrintError(os.Stderr, err) if list, ok := err.(scanner.ErrorList); ok { errorCount += len(list) return } errorCount++ }
func TestTypeCheck(t *testing.T) { flag.Parse() pkgRx, err := regexp.Compile(*pkgPat) if err != nil { t.Fatalf("illegal flag value %q: %s", *pkgPat, err) } pkgs, err := parser.ParseDir(fset, testDir, testFilter, 0) if err != nil { scanner.PrintError(os.Stderr, err) t.Fatalf("packages in %s contain syntax errors", testDir) } for _, pkg := range pkgs { if !pkgRx.MatchString(pkg.Name) { continue // only test selected packages } if *trace { fmt.Println(pkg.Name) } xlist := expectedErrors(t, pkg) err := CheckPackage(fset, pkg, nil) if err != nil { if elist, ok := err.(scanner.ErrorList); ok { // verify that errors match for i := 0; i < len(xlist) && i < len(elist); i++ { checkError(t, xlist[i], elist[i]) } // the correct number or errors must have been found if len(xlist) != len(elist) { fmt.Fprintf(os.Stderr, "%s\n", pkg.Name) scanner.PrintError(os.Stderr, elist) fmt.Fprintln(os.Stderr) t.Errorf("TypeCheck(%s): %d errors expected but %d reported", pkg.Name, len(xlist), len(elist)) } } else { t.Errorf("TypeCheck(%s): %v", pkg.Name, err) } } else if len(xlist) > 0 { t.Errorf("TypeCheck(%s): %d errors expected but 0 reported", pkg.Name, len(xlist)) } } }
func Test(t *testing.T) { err := processFile("testdata/data.go", NewPrototype()) e, ok := err.(scanner.ErrorList) if !ok { t.Fatal(err) } if len(e) != NUM_ERRORS { t.Errorf("expected %d errors", NUM_ERRORS) scanner.PrintError(os.Stderr, err) } }
// MustCompileLexer is like CompileLexer but panics if the definitions cannot be compiled. // It simplifies safe initialization of global variables holding compiled Lexers. func MustCompileLexer(starts [][]int, tokdefs map[string]int, grammar, start string) (lexer *Lexer) { var err error if lexer, err = CompileLexer(starts, tokdefs, grammar, start); err != nil { if list, ok := err.(scanner.ErrorList); ok { scanner.PrintError(os.Stderr, list) } else { log.Fatal(err) } panic(err) } return }
func Main() { world = eval.NewWorld() defineFuncs() r := bufio.NewReader(os.Stdin) for { print("; ") line, err := r.ReadSlice('\n') if err != nil { break } // Try line as a command cmd, rest := getCmd(line) if cmd != nil { err := cmd.handler(rest) if err != nil { scanner.PrintError(os.Stderr, err) } continue } // Try line as code code, err := world.Compile(string(line)) if err != nil { scanner.PrintError(os.Stderr, err) continue } v, err := code.Run() if err != nil { fmt.Fprintf(os.Stderr, err.String()) continue } if v != nil { println(v.String()) } } }
func generate(arch, header, out, test, predefined string) error { m, err := ccgo.NewModel(arch) if err != nil { return err } var cpplog *os.File var s []string opts := []cc.Opt{cc.SysIncludePaths([]string{ccgo.LibcIncludePath})} if *cpp { var err error if cpplog, err = os.Create("log-cpp-" + arch); err != nil { return err } defer cpplog.Close() opts = append(opts, cc.Cpp(func(a []xc.Token) { if len(a) == 0 { return } s = s[:0] for _, v := range a { s = append(s, cc.TokSrc(v)) } fmt.Fprintf(cpplog, "%s: %s\n", a[0].Position(), strings.Join(s, " ")) })) } predefined += fmt.Sprintf("\n#define __MODEL%v\n", ccgo.Archs[arch]) tu, err := cc.Parse(predefined, paths, m, opts...) if err != nil { var buf bytes.Buffer scanner.PrintError(&buf, err) return fmt.Errorf("%s", buf.Bytes()) } return (&ccgo.Job{ DeclarationComments: *pos, Header: header, ImportPath: importPath, In: tu, Model: m, Out: out, Root: root, Test: test, }).Run() }
func checkFiles(t *testing.T, testname string, testfiles []string) { // TODO(gri) Eventually all these different phases should be // subsumed into a single function call that takes // a set of files and creates a fully resolved and // type-checked AST. files, err := parseFiles(t, testname, testfiles) // we are expecting the following errors // (collect these after parsing the files so that // they are found in the file set) errors := expectedErrors(t, testname, files) // verify errors returned by the parser eliminate(t, errors, err) // verify errors returned after resolving identifiers pkg, err := ast.NewPackage(fset, files, GcImport, Universe) eliminate(t, errors, err) // verify errors returned by the typechecker var list scanner.ErrorList errh := func(pos token.Pos, msg string) { list.Add(fset.Position(pos), msg) } err = Check(fset, pkg, errh, nil) eliminate(t, errors, list) if *listErrors { scanner.PrintError(os.Stdout, err) return } // there should be no expected errors left if len(errors) > 0 { t.Errorf("%s: %d errors not reported:", testname, len(errors)) for pos, msg := range errors { t.Errorf("%s: %s\n", fset.Position(pos), msg) } } }
func Example_illegalFactor() { _, err := ParseString("", ` CONST a = 42; VAR b; PROCEDURE c; BEGIN END; BEGIN b := a; b := b; b := c; END. `) scanner.PrintError(os.Stdout, err) // Output: // 13:8: c is not a constant or a variable }
func Example_illegalAssignment() { _, err := ParseString("", ` CONST a = 42; VAR b; PROCEDURE c; BEGIN END; BEGIN a := 1; b := 1; c := 1; END. `) scanner.PrintError(os.Stdout, err) // Output: // 11:3: a is not a variable // 13:3: c is not a variable }
func Example_illegalCall() { _, err := ParseString("", ` CONST a = 42; VAR b; PROCEDURE c; BEGIN END; BEGIN CALL a; CALL b; CALL c; END. `) scanner.PrintError(os.Stdout, err) // Output: // 11:8: a is not a procedure // 12:8: b is not a procedure }
func Example_illegalRead() { _, err := ParseString("", ` CONST a = 42; VAR b; PROCEDURE c; BEGIN END; BEGIN ? a; ? b; ? c; END. `) scanner.PrintError(os.Stdout, err) // Output: // 11:5: a is not a variable // 13:5: c is not a variable }
func main() { flag.Usage = usage flag.Parse() if len(os.Args) == 1 { usage() } log.SetFlags(0) log.SetPrefix("FAIL! ") exitCode := 0 proto := NewPrototype() filenamePath := "" // Scan all files passed in command line. for _, filename := range flag.Args() { switch info, err := os.Stat(filename); { case err != nil: log.Print(err) exitCode = 1 case info.Mode()&os.ModeType == 0: // regular file if err := processFile(filename, proto); err != nil { log.Printf("\t%s\n\n", filename) scanner.PrintError(os.Stderr, err) exitCode = 1 } else if filename == "" { filenamePath = filename } default: log.Print("not regular file: ", filename) exitCode = 1 } } if exitCode != 0 { os.Exit(exitCode) } // Find in header files if errList := proto.find(); errList != nil { for _, e := range errList { log.Print(e) } os.Exit(1) } if len(proto.includes) == 0 { log.Print("prototypes not found") os.Exit(1) } // Create file var err error filew := os.Stdout if *Write { filew, err = os.Create(filepath.Join(filepath.Dir(filenamePath), fmt.Sprintf("z-sys_%s_%s.go", runtime.GOOS, runtime.GOARCH))) if err != nil { log.Fatal(err) } defer func() { if err = filew.Close(); err != nil { log.Print(err) } }() } sort.Strings(proto.includes) sort.Strings(proto.enums) sort.Strings(proto.structs) sort.Strings(proto.unions) // Return '_' for constants not exported. exportConst := func(name string) string { v, found := proto.export[name] if found { if !v { return "_" } } else if !*Export { return "_" } return "" } // Return the name in title case if it is exported. exportIdent := func(name string) string { v, found := proto.export[name] if found { if !v { return name } } else if !*Export { return name } return strings.Title(name) } // Write HEADER = fmt.Sprintf("// %s\n%s", strings.Join(os.Args, " "), HEADER) buftext := new(bytes.Buffer) buftext.WriteString(HEADER) buftext.WriteString("\npackage " + proto.pkgName + "\n\n") for _, v := range proto.includes { buftext.WriteString(fmt.Sprintf("// #include <%s>\n", v)) } buftext.WriteString("import \"C\"\n") for _, group := range proto.consts { // Get the comment for the constant if group[0] != "" { buftext.WriteString("\n" + group[0]) } group = group[1:] sort.Strings(group) if len(group) > 1 { buftext.WriteString("\nconst (\n") for _, v := range group { goIdent := exportConst(v) if newGoIdent, found := proto.newIdent[v]; found { goIdent += newGoIdent } else { goIdent += v } buftext.WriteString(fmt.Sprintf("\t%s = C.%s\n", goIdent, v)) } buftext.WriteString(")\n") } else if len(group) == 1 { cIdent := group[0] goIdent := exportConst(cIdent) if newGoIdent, found := proto.newIdent[cIdent]; found { goIdent += newGoIdent } else { goIdent += cIdent } buftext.WriteString(fmt.Sprintf("\nconst %s = C.%s\n", goIdent, cIdent)) } } for _, v := range proto.enums { buftext.WriteString(fmt.Sprintf("\ntype %s C.enum_%s\n", exportIdent(v), v)) } for _, v := range proto.structs { buftext.WriteString(fmt.Sprintf("\ntype %s C.struct_%s\n", exportIdent(v), v)) } for _, v := range proto.unions { buftext.WriteString(fmt.Sprintf("\ntype %s C.union_%s\n", exportIdent(v), v)) } // Temporary file to be used by cgo f, err := os.Create(filepath.Join(filepath.Dir(filenamePath), fmt.Sprintf("_z-sys_%s_%s.go", runtime.GOOS, runtime.GOARCH))) if err != nil { log.Fatal(err) } if _, err = f.Write(buftext.Bytes()); err != nil { log.Fatal(err) } f.Close() if *Debug { if *Write { fmt.Println(f.Name()) } else { filew.Write(buftext.Bytes()) os.Remove(f.Name()) } os.Exit(0) } defer func() { if err = os.Remove(f.Name()); err != nil { log.Print(err) } }() cmd := exec.Command("go", "tool", "cgo", "-godefs", f.Name()) out, err := cmd.CombinedOutput() if err != nil { log.Fatal(err) } os.RemoveAll("_obj") // directory created by 'go tool cgo' out = append(out[:0], append([]byte(HEADER+"//\n"), out[0:]...)...) if out, err = format.Source(out); err != nil { log.Fatal(err) } if _, err = filew.Write(out); err != nil { log.Fatal(err) } }
func report(err error) { scanner.PrintError(os.Stderr, err) exitCode = 2 }
// This wraps ego to make sure we use the vendored one. // TODO vendor ego :D func main() { outfile := flag.String("o", "ego.go", "output file") pkgname := flag.String("package", "", "package name") flag.Parse() log.SetFlags(0) // If no paths are provided then use the present working directory. roots := flag.Args() if len(roots) == 0 { roots = []string{"."} } // If no package name is set then use the directory name of the output file. if *pkgname == "" { abspath, _ := filepath.Abs(*outfile) *pkgname = filepath.Base(filepath.Dir(abspath)) *pkgname = regexp.MustCompile(`(\w+).*`).ReplaceAllString(*pkgname, "$1") } // Recursively retrieve all ego templates var v visitor for _, root := range roots { if err := filepath.Walk(root, v.visit); err != nil { scanner.PrintError(os.Stderr, err) os.Exit(1) } } // Parse every *.ego file. var templates []*ego.Template for _, path := range v.paths { t, err := ego.ParseFile(path) if err != nil { log.Fatal("parse file: ", err) } templates = append(templates, t) } // If we have no templates then exit. if len(templates) == 0 { os.Exit(0) } // Write package to output file. p := &ego.Package{Templates: templates, Name: *pkgname} f, err := os.Create(*outfile) if err != nil { log.Fatal(err) } defer f.Close() buf := &bytes.Buffer{} if err := p.Write(buf); err != nil { log.Fatalf("write: %s", err) } err = func() error { r := bufio.NewReader(buf) for { line, err := r.ReadString('\n') switch err { case io.EOF: return nil case nil: if !strings.HasPrefix(line, "// Generated by") { _, err = io.WriteString(f, line) if err != nil { return err } } default: return err } } }() if err != nil { log.Fatal(err) } }
func main() { flag.Usage = usage flag.Parse() if *fListSystems { fmt.Print(" = Systems\n\n ") fmt.Println(validSystems) os.Exit(0) } if len(os.Args) == 1 || *fSystem == "" { usage() } log.SetFlags(0) log.SetPrefix("FAIL! ") var isSystem bool *fSystem = strings.ToLower(*fSystem) for _, v := range validSystems { if v == *fSystem { isSystem = true break } } if !isSystem { log.Fatal("system passed in flag -s is invalid") } exitCode := 0 protos := make([]*prototype, 0) // Scan all files passed in command line. for _, filename := range flag.Args() { switch info, err := os.Stat(filename); { case err != nil: log.Print(err) exitCode = 1 case info.Mode()&os.ModeType == 0: // regular file if p, err := processFile(filename); err != nil { log.Printf("\t%s\n\n", filename) scanner.PrintError(os.Stderr, err) exitCode = 1 } else { protos = append(protos, p...) } default: log.Print("not regular file: ", filename) exitCode = 1 } } if len(protos) == 0 { log.Print("prototypes not found") exitCode = 1 } if exitCode != 0 { os.Exit(exitCode) } // Modules and procedures var useInt64 bool mods := make([]string, 0) procs := make([]string, len(protos)) for i, p := range protos { found := false if !useInt64 && p.useInt64 { useInt64 = true } if p.modName == "" { p.modName = "kernel32" } for _, v := range MOD_NAMES { if v == p.modName { found = true break } } if !found { MOD_NAMES = append(MOD_NAMES, p.modName) if *fLazy { mods = append(mods, fmt.Sprintf("mod%s = %sNewLazyDLL(\"%s.dll\")", p.modName, SYSCALL_DOT, p.modName)) } else { mods = append(mods, fmt.Sprintf("mod%s = %sMustLoadDLL(\"%s.dll\")", p.modName, SYSCALL_DOT, p.modName)) } } winFuncName := p.winFuncName if winFuncName == "" { winFuncName = p.goFuncName } if *fLazy { procs[i] = fmt.Sprintf("proc%s = mod%s.NewProc(\"%s\")", p.winFuncName, p.modName, winFuncName) } else { procs[i] = fmt.Sprintf("proc%s = mod%s.MustFindProc(\"%s\")", p.winFuncName, p.modName, winFuncName) } } // Create file var err error var filew, filew32, filew64 *os.File if *fWrite { _file := "zsyscall_" + *fSystem if filew, err = os.Create(_file + ".go"); err != nil { log.Fatal(err) } defer filew.Close() if useInt64 { if filew32, err = os.Create(_file + "_386.go"); err != nil { log.Fatal(err) } defer filew32.Close() if filew64, err = os.Create(_file + "_amd64.go"); err != nil { log.Fatal(err) } defer filew64.Close() } } else { filew = os.Stdout filew32 = os.Stdout filew64 = os.Stdout } // Write var useUnsafe, useUnsafe_arch bool buftext := new(bytes.Buffer) buftext32 := new(bytes.Buffer) buftext64 := new(bytes.Buffer) import1 := "import \"syscall\"\n\n" importUnsafe := "import (\n\t\"syscall\"\n\t\"unsafe\"\n)\n\n" if SYSCALL_DOT == "" { import1 = "" importUnsafe = "import \"unsafe\"\n\n" } bufheader := new(bytes.Buffer) bufheader.WriteString("// " + strings.Join(os.Args, " ") + "\n") bufheader.WriteString(HEADER) buftext.WriteString("var (\n") for _, m := range mods { buftext.WriteString("\t" + m + "\n") } buftext.WriteString("\n") for _, p := range procs { buftext.WriteString("\t" + p + "\n") } buftext.WriteString(")\n") if err = formatVar(buftext); err != nil { log.Fatal(err) } for _, p := range protos { buffunc := new(bytes.Buffer) buffunc.WriteString(fmt.Sprintf("func %s(%s) (%s) {\n", p.goFuncName, p.getArgs("in"), p.getArgs("out"))) vars, syscallArgs, syscallArgs_32b, syscallArgs_64b := p.getSyscallArgs() body, ret := p.getRetValues() if p.useUnsafe { if p.useInt64 { useUnsafe_arch = true } else { useUnsafe = true } } textRet := "" if ret[0] != "_" || ret[1] != "_" || ret[2] != "_" { textRet = fmt.Sprintf("%s, %s, %s := ", ret[0], ret[1], ret[2]) } if vars != "" { buffunc.WriteString(vars) } if p.useInt64 { buftext32.Write(buffunc.Bytes()) buftext32.WriteString(fmt.Sprintf("\t%s%s(%s)\n", textRet, syscallArgs_32b[0], strings.Join(syscallArgs_32b[1:], ", "))) buftext32.WriteString(body) buftext32.WriteString("\treturn\n") buftext32.WriteString("}\n") // amd64 buftext64.Write(buffunc.Bytes()) buftext64.WriteString(fmt.Sprintf("\t%s%s(%s)\n", textRet, syscallArgs_64b[0], strings.Join(syscallArgs_64b[1:], ", "))) buftext64.WriteString(body) buftext64.WriteString("\treturn\n") buftext64.WriteString("}\n") } else { buftext.Write([]byte{'\n'}) buftext.Write(buffunc.Bytes()) buftext.WriteString(fmt.Sprintf("\t%s%s(%s)\n", textRet, syscallArgs[0], strings.Join(syscallArgs[1:], ", "))) buftext.WriteString(body) buftext.WriteString("\treturn\n") buftext.WriteString("}\n") } } if _, err = filew.Write(bufheader.Bytes()); err != nil { log.Fatal(err) } filew.WriteString("package " + PKG_NAME + "\n\n") if useUnsafe { filew.WriteString(importUnsafe) } else { filew.WriteString(import1) } if _, err = filew.Write(buftext.Bytes()); err != nil { log.Fatal(err) } // File per architecture if buftext32.Len() != 0 { if _, err = filew32.Write(bufheader.Bytes()); err != nil { log.Fatal(err) } filew32.WriteString("package " + PKG_NAME + "\n\n") if useUnsafe_arch { filew32.WriteString(importUnsafe) } else { filew32.WriteString(import1) } if _, err = filew32.Write(buftext32.Bytes()); err != nil { log.Fatal(err) } // AMD64 if _, err = filew64.Write(bufheader.Bytes()); err != nil { log.Fatal(err) } filew64.WriteString("package " + PKG_NAME + "\n\n") if useUnsafe_arch { filew64.WriteString(importUnsafe) } else { filew64.WriteString(import1) } if _, err = filew64.Write(buftext64.Bytes()); err != nil { log.Fatal(err) } } }
// Report Errors func report(err error) int { scanner.PrintError(os.Stderr, err) return 2 }
func main() { outfile := flag.String("o", "ego.go", "output file") pkgname := flag.String("package", "", "package name") versionFlag := flag.Bool("version", false, "print version") extFlag := flag.String("ext", ".ego", "all file extensions to scan,use '|' for separation") flag.Parse() log.SetFlags(0) //parse extentions exts := strings.Split(*extFlag, "|") for _, ext := range exts { ext = strings.TrimSpace(ext) if len(ext) == 0 { continue } if ext[0] != '.' { ext = "." + ext } extensions = append(extensions, ext) } // If the version flag is set then print the version. if *versionFlag { fmt.Printf("ego v%s\n", version) return } // If no paths are provided then use the present working directory. roots := flag.Args() if len(roots) == 0 { roots = []string{"."} } // If no package name is set then use the directory name of the output file. if *pkgname == "" { abspath, _ := filepath.Abs(*outfile) *pkgname = filepath.Base(filepath.Dir(abspath)) *pkgname = regexp.MustCompile(`(\w+).*`).ReplaceAllString(*pkgname, "$1") } // Recursively retrieve all ego templates var v visitor for _, root := range roots { if err := filepath.Walk(root, v.visit); err != nil { scanner.PrintError(os.Stderr, err) os.Exit(1) } } // Parse every *.ego file. var templates []*ego.Template for _, path := range v.paths { t, err := ego.ParseFile(path) if err != nil { log.Fatal("parse file: ", err) } templates = append(templates, t) } // If we have no templates then exit. if len(templates) == 0 { os.Exit(0) } // Write package to output file. p := &ego.Package{Templates: templates, Name: *pkgname} f, err := os.Create(*outfile) if err != nil { log.Fatal(err) } defer f.Close() // Write template to file. if err := p.Write(f); err != nil { log.Fatal("write: ", err) } }
func report(err error) { scanner.PrintError(os.Stderr, err) os.Exit(1) }
func (j *Job) Run() (err error) { defer func() { if e := recover(); e != nil { err = fmt.Errorf("\n%s\n%v", debug.Stack(), e) } }() j.init() _, j.ndebug = j.In.Macros[idNDEBUG] var hdr, body bytes.Buffer j.header = newWriter(&hdr) j.body = newWriter(&body) defer func() { var out bytes.Buffer hdr.WriteTo(&out) body.WriteTo(&out) b, e := format.Source(out.Bytes()) if e != nil { var buf bytes.Buffer scanner.PrintError(&buf, e) err = fmt.Errorf("\n====\n%s\n====\n%s", out.Bytes(), buf.Bytes()) return } if e := ioutil.WriteFile(j.Out, b, 0640); e != nil { err = e } }() j.header("%s", j.Header) var a []string // for k, v := range j.In.Macros { // if ip := j.ImportPath(v.DefTok); ip == 0 { // a = append(a, string(xc.Dict.S(k))) // } // } // if len(a) != 0 { // j.body("\nconst (") // sort.Strings(a) // for _, k := range a { // if k[0] == '_' { // continue // } // m := j.In.Macros[xc.Dict.SID(k)] // if m.IsFnLike || m.Type == nil || m.Value == nil { // continue // } // j.body("\nD%s = ", k) // switch x := m.Value.(type) { // case int32: // j.body("%v", x) // default: // todo(m.DefTok) // } // j.body("// %s: %s, (%s)%v", j.pos(m.DefTok), k, m.Type, m.Value) // } // j.body("\n)\n") // } for tu := j.In; tu != nil; tu = tu.TranslationUnit { j.externalDeclaration(tu.ExternalDeclaration) } a = a[:0] for k := range j.imports { a = append(a, string(xc.Dict.S(k))) } if len(a) != 0 { j.header("\n\nimport (") sort.Strings(a) for _, k := range a { j.header("%q\n", k) } j.header("\n)\n") } body0 := body body = bytes.Buffer{} j.body = newWriter(&body) defer body0.WriteTo(&body) a = a[:0] for k := range j.typedefs { a = append(a, string(xc.Dict.S(k))) } if len(a) != 0 { sort.Strings(a) for _, k := range a { id := xc.Dict.SID(k) nm := mangleIdent(id, true) d := j.typedefs[id] t := d.Type for t.Kind() == cc.Ptr || t.Kind() == cc.Array { t = t.Element() } j.structs = append(j.structs, structInfo{t, nm}) s := "" if d.Pos().IsValid() && j.DeclarationComments { s = fmt.Sprintf("// %s: %s, %v\n", j.pos(d), xc.Dict.S(id), t) } j.body("\n\n%stype %s struct {", s, xc.Dict.S(nm)) switch m, incomplete := t.Members(); { case incomplete: j.body("// Incomplete type\n_ byte") case t.Kind() == cc.Union: j.union(d, t) var f func(cc.Type) f = func(t cc.Type) { j.addTag(t) m, _ := t.Members() for _, v := range m { f(v.Type) } } default: for _, v := range m { if v.Bits != 0 { j.bits(d, v) continue } j.addTag(v.Type) id := v.Name nm := mangleIdent(id, true) j.body("\n%s", xc.Dict.S(nm)) j.typ(v.Declarator, v.Type) if t := v.Type; t.Kind() != cc.Union && t.Kind() != cc.Struct { j.body("// %s", v.Type) } } } j.body("\n}") } } tags := j.tags j.tags = map[int]*cc.Declarator{} for _, v := range tags { j.addTag2(v.Type) } a = a[:0] for k := range j.tags { a = append(a, string(xc.Dict.S(k))) } if len(a) != 0 { sort.Strings(a) for _, k := range a { id := xc.Dict.SID(k) nm := mangleTag(id, true) d := j.tags[id] t := d.Type for t.Kind() == cc.Ptr || t.Kind() == cc.Array { t = t.Element() } j.structs = append(j.structs, structInfo{t, nm}) s := "" if d.Pos().IsValid() && j.DeclarationComments { s = fmt.Sprintf("// %s: %s, %v\n", j.pos(d), xc.Dict.S(id), t) } j.body("\n\n%stype %s struct {", s, xc.Dict.S(nm)) switch m, incomplete := t.Members(); { case incomplete: j.body("\n_ byte // Incomplete type.") case t.Kind() == cc.Union: j.union(d, t) default: for _, v := range m { if v.Bits != 0 { j.bits(d, v) continue } id := v.Name nm := mangleIdent(id, true) j.body("\n%s", xc.Dict.S(nm)) j.typ(v.Declarator, v.Type) if t := v.Type; t.Kind() != cc.Union && t.Kind() != cc.Struct { j.body("// %s", v.Type) } } } j.body("\n}") } } a = a[:0] for k := range j.initDecls { a = append(a, string(xc.Dict.S(k))) } if len(a) != 0 { sort.Strings(a) for _, k := range a { id := xc.Dict.SID(k) j.initDeclarator2(j.initDecls[id]) } } j.charConsts(newWriter(&body0)) return j.test() }