improve error handling

This commit is contained in:
Justin Overfelt 2019-04-30 20:18:28 -04:00
parent cecc399c38
commit 6ea5754e57
8 changed files with 113 additions and 54 deletions

View File

@ -35,9 +35,6 @@ const (
End End
Whitespace Whitespace
number
letter
ws
illegal illegal
) )
@ -159,7 +156,3 @@ func isLetter(ch rune) bool {
func isDigit(ch rune) bool { func isDigit(ch rune) bool {
return ch >= '0' && ch <= '9' return ch >= '0' && ch <= '9'
} }
func isEOF(ch rune) bool {
return ch == rune(0)
}

View File

@ -194,7 +194,3 @@ func isWhitespace(ch rune) bool {
func isText(ch rune) bool { func isText(ch rune) bool {
return ch >= '!' && ch <= '~' && ch != equal && ch != l_brace && ch != r_brace return ch >= '!' && ch <= '~' && ch != equal && ch != l_brace && ch != r_brace
} }
func isEOF(ch rune) bool {
return ch == eof
}

View File

@ -86,7 +86,10 @@ func (p *Parser) Parse() (Config, error) {
} }
switch section { switch section {
case "BOOKMARKS": case "BOOKMARKS":
c.Bookmarks.Add([]string{keyval.Value, keyval.Key}) err := c.Bookmarks.Add([]string{keyval.Value, keyval.Key})
if err != nil {
return c, err
}
case "COLORS": case "COLORS":
c.Colors = append(c.Colors, keyval) c.Colors = append(c.Colors, keyval)
case "SETTINGS": case "SETTINGS":

View File

@ -57,7 +57,11 @@ func moveCursorToward(dir string, amount int) {
func Exit() { func Exit() {
moveCursorToward("down", 500) moveCursorToward("down", 500)
moveCursorToward("right", 500) moveCursorToward("right", 500)
SetLineMode() err := SetLineMode()
if err != nil {
panic(err)
}
fmt.Print("\n") fmt.Print("\n")
fmt.Print("\033[?25h") fmt.Print("\033[?25h")
os.Exit(0) os.Exit(0)
@ -79,7 +83,7 @@ func Clear(dir string) {
} }
func WrapLines(s []string, length int) []string { func wrapLines(s []string, length int) []string {
out := []string{} out := []string{}
for _, ln := range s { for _, ln := range s {
if len(ln) <= length { if len(ln) <= length {
@ -121,26 +125,43 @@ func Getch() rune {
return char return char
} }
func GetLine() string { func GetLine() (string, error) {
SetLineMode() err := SetLineMode()
if err != nil {
return "", err
}
reader := bufio.NewReader(os.Stdin) reader := bufio.NewReader(os.Stdin)
fmt.Print(": ") fmt.Print(": ")
text, _ := reader.ReadString('\n') text, err := reader.ReadString('\n')
SetCharMode() if err != nil {
return text[:len(text)-1] return "", err
}
err = SetCharMode()
if err != nil {
return "", err
}
return text[:len(text)-1], nil
} }
func SetCharMode() { func SetCharMode() error {
cmd := exec.Command("stty", "cbreak", "-echo") cmd := exec.Command("stty", "cbreak", "-echo")
cmd.Stdin = os.Stdin cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout cmd.Stdout = os.Stdout
cmd.Run() err := cmd.Run()
fmt.Print("\033[?25l") if err != nil {
return err
}
_, err = fmt.Print("\033[?25l")
return err
} }
func SetLineMode() { func SetLineMode() error {
cmd := exec.Command("stty", "-cbreak", "echo") cmd := exec.Command("stty", "-cbreak", "echo")
cmd.Stdin = os.Stdin cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout cmd.Stdout = os.Stdout
cmd.Run() return cmd.Run()
} }

View File

@ -142,7 +142,7 @@ func (s *Screen) GetSize() {
// NewScreen is a constructor function that returns a pointer // NewScreen is a constructor function that returns a pointer
// to a Screen struct // to a Screen struct
func NewScreen() *Screen { func NewScreen() (*Screen, error) {
if screenInit { if screenInit {
fmt.Println("Fatal error: Cannot create multiple screens") fmt.Println("Fatal error: Cannot create multiple screens")
os.Exit(1) os.Exit(1)
@ -152,8 +152,12 @@ func NewScreen() *Screen {
for i := 0; i < s.Height; i++ { for i := 0; i < s.Height; i++ {
fmt.Println() fmt.Println()
} }
SetCharMode() err := SetCharMode()
if err != nil {
return nil, err
}
Clear("screen") Clear("screen")
screenInit = true screenInit = true
return &s return &s, nil
} }

View File

@ -64,7 +64,7 @@ func (w *Window) DrawContent() {
height := w.Box.row2 - w.Box.row1 + borderThickness height := w.Box.row2 - w.Box.row1 + borderThickness
width := w.Box.col2 - w.Box.col1 + borderThickness width := w.Box.col2 - w.Box.col1 + borderThickness
content := WrapLines(w.Content, width) content := wrapLines(w.Content, width)
if len(content) < w.Scrollposition+height { if len(content) < w.Scrollposition+height {
maxlines = len(content) maxlines = len(content)

View File

@ -33,7 +33,7 @@ func MakeUrl(u string) (Url, error) {
re := regexp.MustCompile(`^((?P<scheme>gopher|http|https|ftp|telnet):\/\/)?(?P<host>[\w\-\.\d]+)(?::(?P<port>\d+)?)?(?:/(?P<type>[01345679gIhisp])?)?(?P<resource>(?:[\/|Uu].*)?)?$`) re := regexp.MustCompile(`^((?P<scheme>gopher|http|https|ftp|telnet):\/\/)?(?P<host>[\w\-\.\d]+)(?::(?P<port>\d+)?)?(?:/(?P<type>[01345679gIhisp])?)?(?P<resource>(?:[\/|Uu].*)?)?$`)
match := re.FindStringSubmatch(u) match := re.FindStringSubmatch(u)
if valid := re.MatchString(u); valid != true { if valid := re.MatchString(u); !valid {
return out, errors.New("Invalid URL or command character") return out, errors.New("Invalid URL or command character")
} }

92
main.go
View File

@ -27,11 +27,6 @@ var options = map[string]string{
"httpbrowser": "lynx", "httpbrowser": "lynx",
} }
func errExit(err string, code int) {
fmt.Println(err)
os.Exit(code)
}
func saveFile(address, name string) error { func saveFile(address, name string) error {
quickMessage("Saving file...", false) quickMessage("Saving file...", false)
defer quickMessage("Saving file...", true) defer quickMessage("Saving file...", true)
@ -73,7 +68,12 @@ func search(u string) error {
cui.Clear("line") cui.Clear("line")
fmt.Print("Enter form input: ") fmt.Print("Enter form input: ")
cui.MoveCursorTo(screen.Height-1, 17) cui.MoveCursorTo(screen.Height-1, 17)
entry := cui.GetLine()
entry, err := cui.GetLine()
if err != nil {
return err
}
quickMessage("Searching...", false) quickMessage("Searching...", false)
searchurl := fmt.Sprintf("%s\t%s", u, entry) searchurl := fmt.Sprintf("%s\t%s", u, entry)
sv, err := gopher.Visit(searchurl, options["openhttp"]) sv, err := gopher.Visit(searchurl, options["openhttp"])
@ -126,9 +126,6 @@ func toggleBookmarks() {
bookmarks.Active = true bookmarks.Active = true
} }
if screen.Activewindow == 0 {
} else {
}
screen.ReflashScreen(false) screen.ReflashScreen(false)
} }
@ -230,10 +227,18 @@ func doLinkCommand(action, target string) error {
switch action { switch action {
case "DELETE", "D": case "DELETE", "D":
err := settings.Bookmarks.Del(num) err := settings.Bookmarks.Del(num)
if err != nil {
return err
}
screen.Windows[1].Content = settings.Bookmarks.List() screen.Windows[1].Content = settings.Bookmarks.List()
saveConfig() err = saveConfig()
if err != nil {
return err
}
screen.ReflashScreen(false) screen.ReflashScreen(false)
return err return nil
case "BOOKMARKS", "B": case "BOOKMARKS", "B":
if num > len(settings.Bookmarks.Links)-1 { if num > len(settings.Bookmarks.Links)-1 {
return fmt.Errorf("There is no bookmark with ID %d", num) return fmt.Errorf("There is no bookmark with ID %d", num)
@ -260,8 +265,13 @@ func doCommandAs(action string, values []string) error {
if err != nil { if err != nil {
return err return err
} }
screen.Windows[1].Content = settings.Bookmarks.List() screen.Windows[1].Content = settings.Bookmarks.List()
saveConfig() err = saveConfig()
if err != nil {
return err
}
screen.ReflashScreen(false) screen.ReflashScreen(false)
return nil return nil
case "WRITE", "W": case "WRITE", "W":
@ -269,8 +279,7 @@ func doCommandAs(action string, values []string) error {
case "SET", "S": case "SET", "S":
if _, ok := options[values[0]]; ok { if _, ok := options[values[0]]; ok {
options[values[0]] = strings.Join(values[1:], " ") options[values[0]] = strings.Join(values[1:], " ")
saveConfig() return saveConfig()
return nil
} }
return fmt.Errorf("Unable to set %s, it does not exist", values[0]) return fmt.Errorf("Unable to set %s, it does not exist", values[0])
} }
@ -295,8 +304,14 @@ func doLinkCommandAs(action, target string, values []string) error {
if err != nil { if err != nil {
return err return err
} }
screen.Windows[1].Content = settings.Bookmarks.List() screen.Windows[1].Content = settings.Bookmarks.List()
saveConfig()
err = saveConfig()
if err != nil {
return err
}
screen.ReflashScreen(false) screen.ReflashScreen(false)
return nil return nil
case "WRITE", "W": case "WRITE", "W":
@ -329,7 +344,7 @@ func quickMessage(msg string, clearMsg bool) {
} }
} }
func saveConfig() { func saveConfig() error {
bkmrks := settings.Bookmarks.IniDump() bkmrks := settings.Bookmarks.IniDump()
opts := "\n[SETTINGS]\n" opts := "\n[SETTINGS]\n"
for k, v := range options { for k, v := range options {
@ -338,14 +353,19 @@ func saveConfig() {
opts += v opts += v
opts += "\n" opts += "\n"
} }
ioutil.WriteFile(userinfo.HomeDir+"/.bombadillo.ini", []byte(bkmrks+opts), 0644)
return ioutil.WriteFile(userinfo.HomeDir+"/.bombadillo.ini", []byte(bkmrks+opts), 0644)
} }
func loadConfig() { func loadConfig() error {
file, err := os.Open(userinfo.HomeDir + "/.bombadillo.ini") file, err := os.Open(userinfo.HomeDir + "/.bombadillo.ini")
if err != nil { if err != nil {
saveConfig() err = saveConfig()
if err != nil {
return err
}
} }
confparser := config.NewParser(file) confparser := config.NewParser(file)
settings, _ = confparser.Parse() settings, _ = confparser.Parse()
file.Close() file.Close()
@ -356,6 +376,8 @@ func loadConfig() {
options[lowerkey] = v.Value options[lowerkey] = v.Value
} }
} }
return nil
} }
func toggleActiveWindow() { func toggleActiveWindow() {
@ -378,10 +400,20 @@ func displayError(err error) {
fmt.Print("\033[41m\033[37m", err, "\033[0m") fmt.Print("\033[41m\033[37m", err, "\033[0m")
} }
func initClient() { func initClient() error {
history.Position = -1 history.Position = -1
screen = cui.NewScreen()
cui.SetCharMode() var err error
screen, err = cui.NewScreen()
if err != nil {
return err
}
err = cui.SetCharMode()
if err != nil {
return err
}
screen.AddWindow(2, 1, screen.Height-2, screen.Width, false, false, true) screen.AddWindow(2, 1, screen.Height-2, screen.Width, false, false, true)
screen.Windows[0].Active = true screen.Windows[0].Active = true
screen.AddMsgBar(1, " ((( Bombadillo ))) ", " A fun gopher client!", true) screen.AddMsgBar(1, " ((( Bombadillo ))) ", " A fun gopher client!", true)
@ -390,12 +422,18 @@ func initClient() {
bookmarksWidth = screen.Width bookmarksWidth = screen.Width
} }
screen.AddWindow(2, screen.Width-bookmarksWidth, screen.Height-2, screen.Width, false, true, false) screen.AddWindow(2, screen.Width-bookmarksWidth, screen.Height-2, screen.Width, false, true, false)
loadConfig() return loadConfig()
} }
func main() { func main() {
defer cui.Exit() defer cui.Exit()
initClient() err := initClient()
if err != nil {
// if we can't initialize the window,
// we can't do anything!
panic(err)
}
mainWindow := screen.Windows[0] mainWindow := screen.Windows[0]
firstLoad := true firstLoad := true
@ -440,7 +478,11 @@ func main() {
toggleActiveWindow() toggleActiveWindow()
case ':', ' ': case ':', ' ':
cui.MoveCursorTo(screen.Height-1, 0) cui.MoveCursorTo(screen.Height-1, 0)
entry := cui.GetLine() entry, err := cui.GetLine()
if err != nil {
displayError(err)
}
// Clear entry line and error line // Clear entry line and error line
clearInput(true) clearInput(true)
if entry == "" { if entry == "" {