func (ctxt *context) checkCyclic(c *command, path *vector.StringVector) { fmt.Printf("checkCyclic %s\n", c.name) if c.visit { ctxt.fail("cyclic dependency at %s, path %v", c.name, path) } c.visit = true path.Push(c.name) for _, e := range c.conns { if e.gender == Female { ctxt.checkCyclic(e.male.cmd, path) } } path.Pop() c.visit = false }
// convert rpn to nice infix notation and string // the r must be valid rpn form func rpnstr(r []int) (ret string) { s := new(vector.StringVector) for k, t := range r { switch t { case ADD, SUB, MUL, DIV: a := s.Pop() b := s.Pop() if k == len(r)-1 { s.Push(b + mop[t] + a) } else { s.Push("(" + b + mop[t] + a + ")") } default: s.Push(strconv.Itoa(t)) } } for _, v := range *s { ret += v } return }
func main() { flag.Parse() if flag.NArg() != 2 { printUsageAndExit() } command := flag.Arg(0) if command != "build" && command != "test" { printUsageAndExit() } // Grab dependency and file information for every local package, starting // with the specified one. We consider a package local if it starts with "./". requiredFiles := make(map[string]*set.StringSet) packageDeps := make(map[string]*set.StringSet) specifiedPackage := flag.Arg(1) var remainingPackages vector.StringVector remainingPackages.Push(specifiedPackage) for remainingPackages.Len() > 0 { packageName := remainingPackages.Pop() // Have we already processed this directory? _, alreadyDone := packageDeps[packageName] if alreadyDone { continue } dir := "./" + packageName dirInfo := build.GetDirectoryInfo(dir) if dirInfo.PackageName == "" { fmt.Printf("Couldn't find .go files to build in directory: %s\n", dir) os.Exit(1) } // Stash information about this package, and add its local dependencies to // the queue. requiredFiles[packageName] = dirInfo.Files packageDeps[packageName] = dirInfo.Deps // If we're testing and this is the package under test, also add its test // files and dependencies. if packageName == specifiedPackage && command == "test" { requiredFiles[packageName].Union(dirInfo.TestFiles) packageDeps[packageName].Union(dirInfo.TestDeps) } for dep := range packageDeps[packageName].Iter() { remainingPackages.Push(dep) } } // Order the packages by their dependencies. totalOrder := deps.BuildTotalOrder(packageDeps) fmt.Println("Found these packages to compile:") for _, packageName := range totalOrder { fmt.Printf(" %s\n", packageName) } // Create a directory to hold outputs, deleting the old one first. os.RemoveAll("igo-out") os.Mkdir("igo-out", 0700) // Compile each of the packages in turn. for _, currentPackage := range totalOrder { fmt.Printf("\nCompiling package: %s\n", currentPackage) compileFiles(requiredFiles[currentPackage], currentPackage) } // If this is a binary, also link it. if build.GetDirectoryInfo(specifiedPackage).PackageName == "main" { linkBinary(specifiedPackage) } // If we're testing, create a test runner, build it, and run it. if command == "test" { const outputFile = "igo-out/test_runner.go" testFuncs := build.GetDirectoryInfo(specifiedPackage).TestFuncs code := test.GenerateTestMain(specifiedPackage, testFuncs) err := ioutil.WriteFile("igo-out/test_runner.go", strings.Bytes(code), 0600) if err != nil { panic(err) } var files set.StringSet files.Insert("igo-out/test_runner.go") compileFiles(&files, "test_runner") linkBinary("test_runner") if !executeCommand("igo-out/test_runner", []string{}, "") { os.Exit(1) } } }