From 47368e1d048c62d085760d8144cde3ade64da8e7 Mon Sep 17 00:00:00 2001 From: Hadeed Ahmad Date: Tue, 3 Oct 2023 10:58:02 +0500 Subject: [PATCH] Add a way to report errors after exit --- include/kilo.h | 3 +++ include/terminal.h | 10 ---------- src/kilo.c | 18 ++++++++++++++++++ src/terminal.c | 46 +++++++++++++++++++++++++++++++--------------- 4 files changed, 52 insertions(+), 25 deletions(-) diff --git a/include/kilo.h b/include/kilo.h index 54ca860..f66f032 100644 --- a/include/kilo.h +++ b/include/kilo.h @@ -21,4 +21,7 @@ extern struct editor_state E; void editor_set_message(const char *fmt, ...); char *editor_prompt(const char *prompt); +extern char *error_message; +void error_set_message(const char *prefix); + #endif // KILO_H diff --git a/include/terminal.h b/include/terminal.h index 616c13c..701fbd1 100644 --- a/include/terminal.h +++ b/include/terminal.h @@ -4,29 +4,19 @@ #include "input.h" #include "utils.h" -// Functions to perform low level terminal operations, using escape codes - ERRCODE terminal_enable_raw(void); -void terminal_disable_raw(void); - -// Cursor positioned at the start ERRCODE terminal_clear(void); -// Hide or show the cursor enum cursor_visibility { CURSOR_SHOWN = 0, CURSOR_HIDDEN = 1 }; ERRCODE terminal_cursor_visibility(enum cursor_visibility visibility); - -// Calculate the current window size ERRCODE terminal_get_win_size(int *rows, int *cols); -// Get and set the cursor position, 1-based indexing ERRCODE terminal_get_cursor_pos(int *row, int *col); ERRCODE terminal_set_cursor_pos(int, int); -// Read input from the terminal and parse it into a KEY KEY terminal_read_key(void); #endif // TERMINAL_H diff --git a/src/kilo.c b/src/kilo.c index 40b730f..cea931f 100644 --- a/src/kilo.c +++ b/src/kilo.c @@ -1,6 +1,7 @@ #define _POSIX_C_SOURCE 199309L #include +#include #include #include #include @@ -51,6 +52,7 @@ void editor_init(char *filename) { editor_set_message("Welcome to kilo! | CTRL-Q: Quit | CTRL-S: SAVE"); terminal_clear(); + error_message = NULL; struct sigaction sa; sa.sa_handler = editor_resize; @@ -126,3 +128,19 @@ void editor_resize() { ui_draw_screen(); } + +/*****************************************************************************/ + +char *error_message; + +void error_set_message(const char *prefix) { + if (error_message) + free(error_message); + + const char *strerror_msg = strerror(errno); + const char *fmt = "%s: %s\n"; + size_t len = strlen(prefix) + 2 + strlen(strerror_msg) + 2; + + error_message = malloc(len); + snprintf(error_message, len, fmt, prefix, strerror_msg); +} diff --git a/src/terminal.c b/src/terminal.c index 214b479..27d6a88 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -1,5 +1,7 @@ +#include #include #include +#include #include #include #include @@ -9,6 +11,34 @@ #include "terminal.h" #include "utils.h" +static void terminal_disable_raw(void) { + if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &E.orig_termios) == -1) + die ("term_disable_raw"); + + write(STDIN_FILENO, "\x1b[?1049l", 8); + + if (error_message) { + write(STDERR_FILENO, error_message, strlen(error_message)); + free(error_message); + } +} + +static char terminal_read_char(void) { + char c; + + ssize_t read_return; + do { + read_return = read(STDIN_FILENO, &c, 1); + } while(read_return == 0 || (read_return == -1 && errno == EINTR)); + + if (read_return == -1) { + error_set_message("read"); + exit(1); + } + + return c; +} + ERRCODE terminal_enable_raw(void) { if (tcgetattr(STDIN_FILENO, &E.orig_termios) == -1) return -1; @@ -27,13 +57,6 @@ ERRCODE terminal_enable_raw(void) { return tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw); } -void terminal_disable_raw(void) { - if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &E.orig_termios) == -1) - die ("term_disable_raw"); - - write(STDIN_FILENO, "\x1b[?1049l", 8); -} - ERRCODE terminal_clear(void) { if (write(STDOUT_FILENO, "\x1b[2J", 4) != 4) return -1; if (write(STDOUT_FILENO, "\x1b[H", 3) != 3) return -1; @@ -100,14 +123,7 @@ ERRCODE terminal_set_cursor_pos(int row, int col) { } KEY terminal_read_key(void) { - char c; - - ssize_t read_return = 0; - while (read_return == 0) - read_return = read(STDIN_FILENO, &c, 1); - - if (read_return == -1) - return NOP; + char c = terminal_read_char(); if (c == '\x1b') { char buf[8] = { '\0' };