aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar bigfoot547 <[email protected]>2023-11-21 22:14:54 -0600
committerLibravatar bigfoot547 <[email protected]>2023-11-21 22:14:54 -0600
commit9ce02c0e72500054156fcbbd876782b568173823 (patch)
treef4560da5cd2d3bf4a9aea686292a60827c9681d0 /src
parentfix trap (diff)
custom assert macros and other stuff
Diffstat (limited to 'src')
-rw-r--r--src/macros.h61
-rw-r--r--src/main.c2
-rw-r--r--src/ui/base.c11
-rw-r--r--src/ui/debug.c7
-rw-r--r--src/ui/dock.c11
-rw-r--r--src/ui/root.c38
-rw-r--r--src/ui/ui.internal.h3
7 files changed, 118 insertions, 15 deletions
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 <stdlib.h> /* for abort() (guaranteed noreturn) */
+#define umps_trap do { __builtin_trap(); abort(); } while(0)
+
+#endif /* defined(NDEBUG) */
+
+#else /* !defined(__GNUC__) */
+
+#include <stdlib.h> /* 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 <stdio.h> /* 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 <curses.h>
#include <stdlib.h>
#include <assert.h>
+#include <string.h>
#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 <stdlib.h>
#include <assert.h>
+#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 <assert.h>
-
#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 <stdbool.h>
+
#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;