From 9ce02c0e72500054156fcbbd876782b568173823 Mon Sep 17 00:00:00 2001 From: bigfoot547 Date: Tue, 21 Nov 2023 22:14:54 -0600 Subject: custom assert macros and other stuff --- src/macros.h | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.c | 2 +- src/ui/base.c | 11 ++++++---- src/ui/debug.c | 7 ++++++ src/ui/dock.c | 11 +++++----- src/ui/root.c | 38 +++++++++++++++++++++++++++----- src/ui/ui.internal.h | 3 +++ 7 files changed, 118 insertions(+), 15 deletions(-) create mode 100644 src/macros.h (limited to 'src') diff --git a/src/macros.h b/src/macros.h new file mode 100644 index 0000000..8523a42 --- /dev/null +++ b/src/macros.h @@ -0,0 +1,61 @@ +#ifndef UMPS_MACROS_H_INCLUDED +#define UMPS_MACROS_H_INCLUDED + +/* define handy macros (unreachable and trap) */ + +#ifdef __GNUC__ /* gcc and clang */ + +/* unreachable statement: umps_unreachable; */ +#define umps_unreachable __builtin_unreachable() + +#ifdef NDEBUG + +/* assume a trap will never be hit in release */ +#define umps_trap umps_unreachable + +#else + +#include /* for abort() (guaranteed noreturn) */ +#define umps_trap do { __builtin_trap(); abort(); } while(0) + +#endif /* defined(NDEBUG) */ + +#else /* !defined(__GNUC__) */ + +#include /* for abort() */ +#define umps_unreachable umps_trap +#define umps_trap abort() + +#endif /* defined(__GNUC__) */ + +/* define assert macros */ + +#ifdef NDEBUG +/* asserts do nothing in release builds (arguments could have side effects) */ +#define umps_assert(_e) ((void)(_e)) +#define umps_assert_s(_e, _s) (((void)(_e), (void)(_s))) +#else + +#include /* for fprintf, fflush, stderr */ + +#define umps_assert(_e) do { \ + if (!(_e)) { \ + fprintf(stderr, "!!!! UMPS assertion failed: %s:%d %s %s\n", \ + __FILE__, __LINE__, __func__, #_e); \ + fflush(stderr); \ + umps_trap; \ + } \ +} while(0) + +#define umps_assert_s(_e, _s) do { \ + if (!(_e)) { \ + fprintf(stderr, "!!!! UMPS assertion failed (%s): %s:%d %s %s\n", \ + _s, __FILE__, __LINE__, __func__, #_e); \ + fflush(stderr); \ + umps_trap; \ + } \ +} while(0) + +#endif /* defined(NDEBUG) */ + +#endif /* include guard */ diff --git a/src/main.c b/src/main.c index 28823eb..68f9265 100644 --- a/src/main.c +++ b/src/main.c @@ -6,7 +6,7 @@ int main(void) { - setlocale(LC_ALL, ""); + setlocale(LC_ALL, "C.UTF-8"); printf("%d\n", getpid()); #if 0 diff --git a/src/ui/base.c b/src/ui/base.c index 5607f4e..f251a3a 100644 --- a/src/ui/base.c +++ b/src/ui/base.c @@ -1,6 +1,6 @@ -#include #include #include +#include #include "ui.internal.h" @@ -44,6 +44,7 @@ void ui__init_window_root(struct ui_window_root *root, WINDOW *cwindow) root->super.draw_proc = &ui__root_draw_proc; root->super.layout_proc = &ui__root_layout_proc; + root->undersize_scr = false; root->content = NULL; root->floating = NULL; } @@ -109,7 +110,9 @@ struct ui_window_base *ui__find_focused(void) case UI__WINDOW_TYPE_ROOT: { struct ui_window_root *root = ui__cast(root, window); - if (root->floating) { + if (root->undersize_scr) { + return window; /* gobble up focus */ + } else if (root->floating) { window = root->floating; } else if (root->content) { window = root->content; @@ -197,7 +200,7 @@ void ui_init(void) ui__init_window_dock(maindock); ui__root_set_content(ui_root, ui__cast(base, maindock)); - for (int i = 0; i < UI__WINDOW_DOCK_MAX; ++i) + for (unsigned i = 0; i < UI__WINDOW_DOCK_MAX; ++i) { if (i == UI__WINDOW_DOCK_LEFT) continue; struct ui_window_base *win_traces = malloc(sizeof(struct ui_window_base)); @@ -234,7 +237,7 @@ void ui_handle(void) ui__status_text = "Hello..."; ui__call_draw_proc(ui__cast(base, ui_root)); } else if (inp == NS('w')) { - ui__status_text = "World!"; + ui__status_text = "World\u0416!"; ui__call_draw_proc(ui__cast(base, ui_root)); } } diff --git a/src/ui/debug.c b/src/ui/debug.c index d4f2e94..f30c12c 100644 --- a/src/ui/debug.c +++ b/src/ui/debug.c @@ -23,4 +23,11 @@ struct ui_window_root *ui__check_cast_to_root(void *obj) return obj; } +#else + +/* the file must have a declaration */ +void umps__debug_do_nothing(void) +{ +} + #endif diff --git a/src/ui/dock.c b/src/ui/dock.c index 5b39bd4..178127f 100644 --- a/src/ui/dock.c +++ b/src/ui/dock.c @@ -1,6 +1,7 @@ #include #include +#include "macros.h" #include "ui.internal.h" unsigned ui__dock_position_opposite(unsigned position) @@ -16,7 +17,7 @@ unsigned ui__dock_position_opposite(unsigned position) case UI__WINDOW_DOCK_RIGHT: return UI__WINDOW_DOCK_LEFT; default: - abort(); /* trap: the center dock has no opposite! (or position is invalid) */ + umps_trap; /* trap: the center dock has no opposite! (or position is invalid) */ } } @@ -108,7 +109,7 @@ WINDOW *ui__dock_place_window(struct ui_window_dock *dock, unsigned position, fl out_x = begx; break; default: - assert(false); + umps_trap; } return newwin(out_lines, out_cols, out_y, out_x); @@ -116,9 +117,9 @@ WINDOW *ui__dock_place_window(struct ui_window_dock *dock, unsigned position, fl void ui__dock_add_child(struct ui_window_dock *dock, struct ui_window_base *child, unsigned position, float size) { - assert(!dock->children[position]); /* TODO: handle gracefully (technically invalid usage) */ - assert(!child->parent); /* TODO: take this window from its current parent */ - assert(!child->cwindow); + umps_assert_s(!dock->children[position], "child present"); /* TODO: handle gracefully (technically invalid usage) */ + umps_assert_s(!child->parent, "child parent present"); /* TODO: take this window from its current parent */ + umps_assert_s(!child->cwindow, "child already initialized"); child->parent = (struct ui_window_base *)dock; dock->children[position] = child; diff --git a/src/ui/root.c b/src/ui/root.c index 26ca0ac..7ef536f 100644 --- a/src/ui/root.c +++ b/src/ui/root.c @@ -1,6 +1,8 @@ -#include - #include "ui.internal.h" +#include "macros.h" + +#define UI__ROOT_MIN_Y (24) +#define UI__ROOT_MIN_X (80) /* top margin for menu bar */ #define UI__ROOT_MARGIN_TOP (1) @@ -33,6 +35,18 @@ void ui__root_draw_proc(struct ui_window_base *base) { struct ui_window_root *root = ui__cast(root, base); + int maxy, maxx; + getmaxyx(base->cwindow, maxy, maxx); + if (root->undersize_scr) { + for (int y = 0; y < maxy; ++y) + mvwhline(base->cwindow, y, 0, y < 3 ? ' ' : '/', maxx); + + mvwprintw(base->cwindow, 0, 0, "Your terminal is too small! It must be at least %dx%d.", UI__ROOT_MIN_X, UI__ROOT_MIN_Y); + + wrefresh(base->cwindow); + return; + } + attron(A_REVERSE); mvwhline(base->cwindow, 0, 0, ' ', getmaxx(base->cwindow)); mvwhline(base->cwindow, getmaxy(base->cwindow)-1, 0, ' ', getmaxx(base->cwindow)); @@ -60,6 +74,16 @@ void ui__root_layout_proc(struct ui_window_base *base) { struct ui_window_root *root = ui__cast(root, base); + int maxy, maxx; + getmaxyx(base->cwindow, maxy, maxx); + + if (maxy < UI__ROOT_MIN_Y || maxx < UI__ROOT_MIN_X) { + root->undersize_scr = true; + return; + } + + root->undersize_scr = false; + if (root->content) { delwin(root->content->cwindow); root->content->cwindow = ui__root_place_content_window(root); @@ -69,11 +93,15 @@ void ui__root_layout_proc(struct ui_window_base *base) void ui__root_set_content(struct ui_window_root *root, struct ui_window_base *window) { - assert(!window->parent); - assert(!window->cwindow); - assert(!root->content); + umps_assert(!window->parent); + umps_assert(!window->cwindow); + umps_assert(!root->content); window->cwindow = ui__root_place_content_window(root); root->content = window; window->parent = ui__cast(base, root); } + +void ui__root_set_floating(struct ui_window_root *root, struct ui_window_base *window) +{ +} diff --git a/src/ui/ui.internal.h b/src/ui/ui.internal.h index 6107c94..b570654 100644 --- a/src/ui/ui.internal.h +++ b/src/ui/ui.internal.h @@ -5,6 +5,8 @@ #include "config.h" #include NCURSES_INCLUDE +#include + #define UI__WINDOW_DOCK_TOP (0u) #define UI__WINDOW_DOCK_BOTTOM (1u) #define UI__WINDOW_DOCK_LEFT (2u) @@ -57,6 +59,7 @@ struct ui_window_dock { struct ui_window_root { struct ui_window_base super; + bool undersize_scr; struct ui_window_base *content; struct ui_window_base *floating; -- cgit v1.2.3-70-g09d2