package main import ( "flag" "fmt" "os" "os/user" "path/filepath" "strings" ) const ( argsError = 1 fileError = iota lexError compileError ) func fileExists(p string) (bool, error) { _, err := os.Stat(p) if err == nil { return true, nil } if os.IsNotExist(err) { return false, nil } return false, err } func setIn() { args := flag.Args() if len(args) == 0 { fmt.Fprintf(os.Stderr, "No input file\n") os.Exit(argsError) } else if len(args) > 1 { fmt.Fprintf(os.Stderr, "Too many input files (%d), needed 1\n", len(args)) os.Exit(argsError) } in = absFilepath(args[0]) exists, err := fileExists(in) if err != nil { fmt.Fprintf(os.Stderr, "Could not open file\n\t%s", err.Error()) os.Exit(fileError) } else if !exists { fmt.Fprintf(os.Stderr, "%q does not exist\n", in) os.Exit(fileError) } } func setOut(o string) { if o == "" { out = "out.rom" } else { out = o } } func isHexValue(v byte) bool { if (v >= 0x30 && v <= 0x39) || (v >= 0x41 && v <= 0x46) || (v >= 0x61 && v <= 0x66) { return true } return false } func isHex(s string) bool { if len(s) != 2 { return false } for _, b := range []byte(s) { if !isHexValue(b) { return false } } return true } func loadFile(p string) string { b, err := os.ReadFile(p) if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(fileError) } return string(b) } func absFilepath(p string) string { if strings.HasPrefix(p, "~") { if p == "~" || strings.HasPrefix(p, "~/") { homedir, _ := os.UserHomeDir() if len(p) <= 2 { p = homedir } else if len(p) > 2 { p = filepath.Join(homedir, p[2:]) } } else { i := strings.IndexRune(p, '/') var u string var remainder string if i < 0 { u = p[1:] remainder = "" } else { u = p[1:i] remainder = p[i:] } usr, err := user.Lookup(u) if err != nil { p = filepath.Join("/home", u, remainder) } else { p = filepath.Join(usr.HomeDir, remainder) } } } else if !strings.HasPrefix(p, "/") { wd, _ := os.Getwd() p = filepath.Join(wd, p) } path, _ := filepath.Abs(p) return path }