Replaced 'panic' with an error return, and a call to 'printAndExit'

master
Aadhavan Srinivasan 2 months ago
parent 71051ce7f0
commit 2a007ba56c

@ -49,10 +49,11 @@ func newColor(colorString string) (color, error) {
return clr, nil return clr, nil
} }
// newColorMust is similar to newColor, but panics if the given color isn't valid. // newColorMust is similar to newColor, but prints an error and exits if the given color isn't valid.
func newColorMust(colorString string) color { func newColorMust(colorString string) color {
if clr, err := newColor(colorString); err != nil { if clr, err := newColor(colorString); err != nil {
panic(err) printAndExit(err.Error())
panic(err) // NEVER REACHED
} else { } else {
return clr return clr
} }

@ -16,16 +16,18 @@ type colorunit struct {
// The slice of colorunits is used to fill in the color for each character. // The slice of colorunits is used to fill in the color for each character.
// The slice of bytes is used to perform the regex matching. // The slice of bytes is used to perform the regex matching.
// The color will be set to the current terminal foreground color. // The color will be set to the current terminal foreground color.
func loadInputFile(fileName string) ([]colorunit, []byte) { //
// If there is any error reading the file, that error is returned.
func loadInputFile(fileName string) ([]colorunit, []byte, error) {
data, err := os.ReadFile(fileName) data, err := os.ReadFile(fileName)
if err != nil { if err != nil {
panic(err) return nil, nil, err
} }
units := make([]colorunit, len(data)) units := make([]colorunit, len(data))
for idx, c := range data { for idx, c := range data {
units[idx] = colorunit{byte(c), newColorMust("NONE")} units[idx] = colorunit{byte(c), newColorMust("NONE")}
} }
return units, data return units, data, nil
} }
// print is used to print out the character in the given colorunit, according to // print is used to print out the character in the given colorunit, according to

@ -17,14 +17,14 @@ import (
func loadConfig(configFilename string) (stack.Stack[regColor], error) { func loadConfig(configFilename string) (stack.Stack[regColor], error) {
configFile, err := os.ReadFile(configFilename) configFile, err := os.ReadFile(configFilename)
if err != nil { if err != nil {
panic(err) return *stack.NewStack[regColor](0), err
} }
// Here, I create a MapSlice. This is a slice of key-value pairs, and will // Here, I create a MapSlice. This is a slice of key-value pairs, and will
// store the results of unmarshalling the YAML file. // store the results of unmarshalling the YAML file.
tempMapSlice := yaml.MapSlice{} tempMapSlice := yaml.MapSlice{}
if err := yaml.Unmarshal(configFile, &tempMapSlice); err != nil { if err := yaml.Unmarshal(configFile, &tempMapSlice); err != nil {
panic(err) return *stack.NewStack[regColor](0), err
} }
// Here, I create the stack which will eventually be returned. // Here, I create the stack which will eventually be returned.
@ -37,9 +37,9 @@ func loadConfig(configFilename string) (stack.Stack[regColor], error) {
re := regexp.MustCompile(item.Key.(string)) re := regexp.MustCompile(item.Key.(string))
clr, err := newColor(item.Value.(string)) clr, err := newColor(item.Value.(string))
if err != nil { if err != nil {
panic(err) return *stack.NewStack[regColor](0), err
} }
// If we got past the panic, then the color _must_ be valid. // If we got past the errors, then the color _must_ be valid.
regColorStack.Push(regColor{re, clr}) regColorStack.Push(regColor{re, clr})
} }

@ -8,22 +8,23 @@ import (
) )
// fileExists returns true if the given file exists, and false if it // fileExists returns true if the given file exists, and false if it
// doesn't. It panics if an error is encountered. // doesn't. If it encounters an error, it prints the error and exits.
func fileExists(filename string) bool { func fileExists(filename string) bool {
if _, err := os.Stat(filename); err == nil { if _, err := os.Stat(filename); err == nil {
return true return true
} else if errors.Is(err, os.ErrNotExist) { } else if errors.Is(err, os.ErrNotExist) {
return false return false
} else { } else {
panic(err) printAndExit(err.Error())
return false // NEVER REACHED
} }
} }
// mustExist can be called to ensure that a file exists; it panics if // mustExist can be called to ensure that a file exists; it errors and exits if
// the file doesn't exist. // the file doesn't exist.
func mustExist(filename string) { func mustExist(filename string) {
if fileExists(filename) != true { if fileExists(filename) != true {
panic(os.ErrNotExist) printAndExit(os.ErrNotExist.Error())
} }
} }
@ -51,7 +52,7 @@ func printFile(fileName string) {
mustExist(fileName) mustExist(fileName)
data, err := os.ReadFile(fileName) data, err := os.ReadFile(fileName)
if err != nil { if err != nil {
panic(err) printAndExit(err.Error())
} }
fmt.Print(string(data)) fmt.Print(string(data))
return return
@ -61,7 +62,7 @@ func main() {
// Check if user has provided a file name // Check if user has provided a file name
if len(os.Args) != 2 { if len(os.Args) != 2 {
panic("ERROR: Invalid number of arguments") printAndExit("Invalid number of arguments")
} }
fileName := os.Args[1] fileName := os.Args[1]
mustExist(fileName) mustExist(fileName)
@ -77,11 +78,14 @@ func main() {
// If the given file has a config, load the config into a stack of regColors. // If the given file has a config, load the config into a stack of regColors.
regColorStack, err := loadConfig(configFilename) regColorStack, err := loadConfig(configFilename)
if err != nil { if err != nil {
panic(err) printAndExit(err.Error())
} }
// Load the input file into a colorunit slice (units) and a byte slice (data) // Load the input file into a colorunit slice (units) and a byte slice (data)
units, data := loadInputFile(fileName) units, data, err := loadInputFile(fileName)
if err != nil {
printAndExit(err.Error())
}
// For each regular expression in the stack, apply it to the byte slice. Find // For each regular expression in the stack, apply it to the byte slice. Find
// the first and last index of all matches of the regex. Then apply the corresponding color // the first and last index of all matches of the regex. Then apply the corresponding color

Loading…
Cancel
Save