diff options
| author | Aakarsh Kashyap <[email protected]> | 2026-06-29 12:57:24 +0530 |
|---|---|---|
| committer | Aakarsh Kashyap <[email protected]> | 2026-06-29 12:57:24 +0530 |
| commit | 53a8f41171179663cebdb9afbee5de88f8b6bbd4 (patch) | |
| tree | 1e8eb841e8bb637b97c33670e71875431c16021b /src | |
| parent | 119e47338ef9b0adea7b584239f9f6911e4da5cb (diff) | |
Refactored the codebase so it becomes mine
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.cpp | 131 | ||||
| -rw-r--r-- | src/reader.cpp | 205 |
2 files changed, 212 insertions, 124 deletions
diff --git a/src/main.cpp b/src/main.cpp index 97e9dce..7565371 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,72 +1,85 @@ -#include "../include/reader.h" - -int main(int argc, char *argv[]) { - try { - editor_cfg *cfg = (editor_cfg *)malloc(sizeof(editor_cfg)); - if (cfg == nullptr) { - die("[err]: malloc failed\n"); - } - - enable_raw(cfg); - init_editor(cfg); - - int speed { 250000 }; - - if (argc < 2) - die("[err]: no file provided!\n"); - - if (argc > 3) - die("[err]: too many arguments!\n"); - - if (argc == 3) { - if (!is_number(argv[2])) - die("[err]: invalid speed interval provided!\n"); - speed = std::stoi(argv[2]); - } +/* main.cpp - reader: RSVP-style terminal word reader */ - FILE *fp = fopen(argv[1], "r"); +#define _POSIX_C_SOURCE 200809L - if (fp == nullptr) - die("[err]: fopen failed\n"); +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> - fseek(fp, 0, SEEK_END); - long size = ftell(fp); - rewind(fp); +#include <string> +#include <vector> - std::string content(size, '\0'); - fread(content.data(), 1, size, fp); - - fclose(fp); - - std::vector<std::string> data; - split(content, data, " \t\r\n,;:!?"); +#include "../include/reader.h" - while(1) { - for (std::string &k: data) { - if (k.empty()) continue; - window_size_callback(cfg); - editor_refresh_scrn(cfg); - int mid = k.size() / 2; +int +main(int argc, char *argv[]) +{ + EditorCfg *cfg; + FILE *fp; + long size; + int speed; + std::string content; + std::vector<std::string> data; + size_t i; + std::string *k; + + cfg = (EditorCfg *)malloc(sizeof(EditorCfg)); + speed = 250000; + + if (!cfg) + die("[err]: malloc failed\n"); + + enable_raw(cfg); + init_editor(cfg); + + if (argc < 2) + die("[err]: no file provided!\n"); + if (argc > 3) + die("[err]: too many arguments!\n"); + + if (argc == 3) { + if (!is_number(argv[2])) + die("[err]: invalid speed interval provided!\n"); + speed = atoi(argv[2]); + } - write(STDOUT_FILENO, k.substr(0, mid).c_str(), mid); + fp = fopen(argv[1], "r"); + if (!fp) + die("[err]: fopen failed\n"); + + fseek(fp, 0, SEEK_END); + size = ftell(fp); + rewind(fp); + + content.resize(size, '\0'); + fread(&content[0], 1, size, fp); + fclose(fp); + + split(content, data, " \t\r\n,;:!?"); + + for (;;) { + for (i = 0; i < data.size(); i++) { + k = &data[i]; + if (k->empty()) + continue; + window_size_callback(cfg); + editor_refresh_scrn(cfg); + { + int mid = (int)k->size() / 2; + int remaining = (int)k->size() - mid - 1; + const char *cstr = k->c_str(); + + write(STDOUT_FILENO, cstr, mid); write(STDOUT_FILENO, "\x1b[31m", 5); - write(STDOUT_FILENO, k.substr(mid, 1).c_str(), 1); + write(STDOUT_FILENO, cstr + mid, 1); write(STDOUT_FILENO, "\x1b[m", 3); - - int remaining = k.size() - mid - 1; - - write(STDOUT_FILENO, k.substr(mid + 1, remaining).c_str(), remaining); - usleep(speed); + write(STDOUT_FILENO, cstr + mid + 1, remaining); } + usleep(speed); } - - free(cfg); - - } catch (const std::exception &e) { - die(e.what()); - } catch (...) { - die("[err]: Unknown exception occurred\n"); } + free(cfg); return 0; -} /* main.cpp */ +} diff --git a/src/reader.cpp b/src/reader.cpp index 1d49d4e..4bc88a6 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -1,78 +1,107 @@ -#include "../include/reader.h" +/* reader.cpp - terminal raw mode and editor utilities */ + +#define _POSIX_C_SOURCE 200809L + #include <csignal> -#include <iostream> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <termios.h> +#include <unistd.h> +#include <cctype> +#include <string> +#include <vector> + +#include "../include/reader.h" -void die(const char *s) { +static EditorCfg *g_cfg = NULL; + +void +die(const char *s) +{ write(STDOUT_FILENO, "\x1b[2J", 4); write(STDOUT_FILENO, "\x1b[H", 3); - perror(s); - fprintf(stderr, "[exit]: die(s) invoked, exiting..\n"); + fprintf(stderr, "[exit]: die() invoked, exiting..\n"); exit(1); } -static editor_cfg *g_cfg = nullptr; - -void disable_raw_atexit() { - if (g_cfg) { +static void +disable_raw_atexit(void) +{ + if (g_cfg) tcsetattr(STDIN_FILENO, TCSAFLUSH, &(g_cfg->termios_inst)); - } } -void handle_signal(int sig) { +static void +handle_signal(int sig) +{ disable_raw_atexit(); _exit(128 + sig); } -void disable_raw(editor_cfg *cfg) { - if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &(cfg->termios_inst))) +void +disable_raw(EditorCfg *cfg) +{ + if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &(cfg->termios_inst)) < 0) die("tcsetattr"); } -void enable_raw(editor_cfg *cfg) { - if (tcgetattr(STDIN_FILENO, &(cfg->termios_inst)) == -1) +void +enable_raw(EditorCfg *cfg) +{ + struct termios raw; + + if (tcgetattr(STDIN_FILENO, &(cfg->termios_inst)) < 0) die("tcgetattr"); g_cfg = cfg; - std::atexit(disable_raw_atexit); + atexit(disable_raw_atexit); - std::signal(SIGINT, handle_signal); - std::signal(SIGTERM, handle_signal); - std::signal(SIGQUIT, handle_signal); + signal(SIGINT, handle_signal); + signal(SIGTERM, handle_signal); + signal(SIGQUIT, handle_signal); - struct termios raw = cfg->termios_inst; + raw = cfg->termios_inst; + /* disable XON/XOFF, CR-to-NL, break, parity, strip */ raw.c_iflag &= ~(IXON | ICRNL | BRKINT | INPCK | ISTRIP); + /* disable output processing */ raw.c_oflag &= ~(OPOST); - raw.c_lflag &= - ~(ECHO | ICANON | IEXTEN); // disables several keybinds in terminal + /* disable echo, canonical, extended; disables terminal keybinds */ + raw.c_lflag &= ~(ECHO | ICANON | IEXTEN); - raw.c_cc[VMIN] = 0; + raw.c_cc[VMIN] = 0; raw.c_cc[VTIME] = 1; - if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw) == -1) + if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw) < 0) die("tcsetattr"); } -char editor_readkey() { - int nread; +char +editor_readkey(void) +{ + int nread; char c; while ((nread = read(STDIN_FILENO, &c, 1)) != 1) { - if (nread == -1 && errno != EAGAIN) + if (nread < 0 && errno != EAGAIN) die("read"); } return c; } -int get_cursor_pos(int *rows, int *cols) { - char buff[32]; +int +get_cursor_pos(int *rows, int *cols) +{ + char buff[32]; unsigned int i = 0; - if (write(STDOUT_FILENO, "\x1b[6n", 4) != 4) { + if (write(STDOUT_FILENO, "\x1b[6n", 4) != 4) return -1; - } + while (i < sizeof(buff) - 1) { if (read(STDIN_FILENO, &buff[i], 1) != 1) break; @@ -89,11 +118,13 @@ int get_cursor_pos(int *rows, int *cols) { return 0; } -int get_window_size(int *rows, int *cols) { +int +get_window_size(int *rows, int *cols) +{ struct winsize w_size; - if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &w_size) == -1 || - w_size.ws_col == 0) { + if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &w_size) < 0 || + w_size.ws_col == 0) { if (write(STDOUT_FILENO, "\x1b[999C\x1b[999B", 12) != 12) return -1; return get_cursor_pos(rows, cols); @@ -105,50 +136,94 @@ int get_window_size(int *rows, int *cols) { return 0; } -void window_size_callback(editor_cfg *cfg) { - int a{}; - int b{}; +void +window_size_callback(EditorCfg *cfg) +{ + int rows; + int cols; + + if (get_window_size(&rows, &cols) < 0) { + fprintf(stderr, + "[err]: window_size_callback: get_window_size\n"); + return; + } + if (cfg->screenrows != rows || cfg->screencols != cols) { + cfg->screenrows = rows; + cfg->screencols = cols; + } +} + +void +ab_append(AppendBuf *ab, const char *s, int len) +{ + char *n; - if (get_window_size(&a, &b) != 0) - std::cout << "[err]: window_size_callback: get_window_size\n"; - if ((cfg->screencols != a) || (cfg->screencols != b)) { - cfg->screenrows = a; - cfg->screencols = b; - } + if (!(n = (char *)realloc(ab->b, ab->len + len))) + return; + memcpy(&n[ab->len], s, len); + ab->b = n; + ab->len += len; } -void editor_refresh_scrn(editor_cfg *cfg) { - append_buffer::instance().append("\x1b[2J", 4); - char buff[32]; +void +ab_write(AppendBuf *ab) +{ + write(STDOUT_FILENO, ab->b, ab->len); +} + +void +ab_free(AppendBuf *ab) +{ + free(ab->b); + ab->b = NULL; + ab->len = 0; +} + +void +editor_refresh_scrn(EditorCfg *cfg) +{ + AppendBuf ab = {NULL, 0}; + char buff[32]; + + ab_append(&ab, "\x1b[2J", 4); memset(buff, 0, sizeof(buff)); + snprintf(buff, sizeof(buff), "\x1b[%d;%dH", + cfg->screenrows / 2, cfg->screencols / 2); + ab_append(&ab, buff, strlen(buff)); + ab_write(&ab); + ab_free(&ab); +} + +void +init_editor(EditorCfg *cfg) +{ + if (get_window_size(&(cfg->screenrows), &(cfg->screencols)) < 0) + die("get_window_size"); +} - snprintf(buff, sizeof(buff), "\x1b[%d;%dH", cfg->screenrows / 2, cfg->screencols / 2); +int +is_number(char *strnum) +{ + std::string str = strnum; + std::string::const_iterator it = str.begin(); - append_buffer::instance().append(buff, strlen(buff)); - append_buffer::instance().write_output(); - append_buffer::instance().remove(); + while (it != str.end() && std::isdigit(*it)) + ++it; + return !str.empty() && it == str.end(); } -size_t split(const std::string &txt, std::vector<std::string> &strings, const std::string &delims) { +size_t +split(const std::string &txt, + std::vector<std::string> &strings, + const std::string &delims) +{ size_t initial_pos = txt.find_first_not_of(delims, 0); - size_t pos = txt.find_first_of(delims, initial_pos); + size_t pos = txt.find_first_of(delims, initial_pos); while (initial_pos != std::string::npos) { strings.push_back(txt.substr(initial_pos, pos - initial_pos)); initial_pos = txt.find_first_not_of(delims, pos); - pos = txt.find_first_of(delims, initial_pos); + pos = txt.find_first_of(delims, initial_pos); } return strings.size(); } - -void init_editor(editor_cfg *cfg) { - if (get_window_size(&(cfg->screenrows), &(cfg->screencols)) == -1) - die("get_window_size"); -} - -int is_number(char *strnum) { - std::string str = strnum; - std::string::const_iterator it = str.begin(); - while (it != str.end() && std::isdigit(*it)) ++it; - return !str.empty() && it == str.end(); -} |
