package exiter import ( "errors" "gitlab.com/CRThaze/cworthy/exit" ) // ExitCode represents an unsigned 16 bit integer used to define exit statuses. type ExitCode exit.ExitT const ( ExitOK ExitCode = ExitCode(exit.EX_OK) // 0: successful termination ExitError ExitCode = ExitCode(1) // 1: generic error ExitUsage ExitCode = ExitCode(exit.EX_USAGE) // 64: command line usage error ExitDataErr ExitCode = ExitCode(exit.EX_DATAERR) // 65: data format error ExitNoInput ExitCode = ExitCode(exit.EX_NOINPUT) // 66: cannot open input ExitNoUser ExitCode = ExitCode(exit.EX_NOUSER) // 67: addressee unknown ExitNoHost ExitCode = ExitCode(exit.EX_NOHOST) // 68: host name unknown ExitUnavailable ExitCode = ExitCode(exit.EX_UNAVAILABLE) // 69: service unavailable ExitSoftware ExitCode = ExitCode(exit.EX_SOFTWARE) // 70: internal software error ExitOSErr ExitCode = ExitCode(exit.EX_OSERR) // 71: system error (e.g., can't fork) ExitOSFile ExitCode = ExitCode(exit.EX_OSFILE) // 72: critical OS file missing ExitCantCreate ExitCode = ExitCode(exit.EX_CANTCREAT) // 73: can't create (user) output file ExitIOErr ExitCode = ExitCode(exit.EX_IOERR) // 74: input/output error ExitTempFail ExitCode = ExitCode(exit.EX_TEMPFAIL) // 75: temp failure; user is invited to retry ExitProtocol ExitCode = ExitCode(exit.EX_PROTOCOL) // 76: remote error in protocol ExitNoPerm ExitCode = ExitCode(exit.EX_NOPERM) // 77: permission denied ExitConfig ExitCode = ExitCode(exit.EX_CONFIG) // 78: configuration error ExitAbort ExitCode = ExitCode(exit.EX_ABORT) // 134: process was aborted ) var exitCodeDescs [^ExitCode(0)]string func init() { exitCodeDescs = exit.GetAllExitCodeDescriptions() exitCodeDescs[ExitError] = "generic error" } // Desc returns the description string for a given ExitCode. func (e ExitCode) Desc() string { return exitCodeDescs[e] } // RegisterNewExitCode reserves an ExitCode and stores its corresponding // description string for recall. // It returns an error if the given integer is already in use or outside the // usable range. And also if the description string is empty. func RegisterNewExitCode(num int, desc string) (ExitCode, error) { if num < 0 || num > int(^ExitCode(0)) { return 0, errors.New("New exit code out of range") } if num == 0 || num == int(exit.EX_ABORT) || (num >= int(exit.EX__BASE) && num <= int(exit.EX__MAX)) { return 0, errors.New("New exit code not user reservable") } if exitCodeDescs[num] != "" { return 0, errors.New("New exit code already defined") } if desc == "" { return 0, errors.New("New exit code description cannot be blank") } exitCodeDescs[num] = desc return ExitCode(num), nil } // RegisterNextExitCode find the next available ExitCode number and associates the // given description string with it. // It returns an error if there are no more available numbers to reserve. func RegisterNextExitCode(desc string) (ExitCode, error) { nextUsable := func(n int) int { n++ for n == int(exit.EX_ABORT) || (n >= int(exit.EX__BASE) && n <= int(exit.EX__MAX)) { n++ } return n } for i := 1; i <= int(^ExitCode(0)); i = nextUsable(i) { if exitCodeDescs[i] == "" { exitCodeDescs[i] = desc return ExitCode(i), nil } } return 0, errors.New("Available exit codes exhausted") } func mapCodes(codes []string, offset int, m map[ExitCode]string) { for i, desc := range codes { if desc != "" { m[ExitCode(i+offset)] = desc } } } // UserCodeMap returns a map of ExitCodes and their associated description strings // with in the User-Definable range. func UserCodeMap() (m map[ExitCode]string) { m = map[ExitCode]string{} mapCodes(exitCodeDescs[1:exit.EX__BASE], 1, m) mapCodes(exitCodeDescs[exit.EX__MAX+1:exit.EX_ABORT], int(exit.EX__MAX)+1, m) mapCodes(exitCodeDescs[exit.EX_ABORT+1:], int(exit.EX_ABORT)+1, m) return } // FullCodeMap returns a map of all ExitCodes and their associated description // strings. func FullCodeMap() (m map[ExitCode]string) { m = map[ExitCode]string{} mapCodes(exitCodeDescs[:], 0, m) return } // GetAllExitCodeDescriptions returns an array of all possible ExitCode description // strings (where the index is the exit code). Any unreserved ExitCodes are also // included with empty string descriptions. func GetAllExitCodeDescriptions() [^ExitCode(0)]string { return exitCodeDescs }