From b3049b0a1e57af4e917a08d8055ea1d797210e6b Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Sun, 12 May 2019 22:17:24 -0400 Subject: [PATCH] Started reintegrating what used to be called user bugs; they're now called programmer errors. We'll create a much more systematic approach to them. Implemented on macOS. --- common/meson.build | 1 + common/programmererror.c | 41 ++++++++++++++++++++++++++++++++++++++++ common/uipriv.h | 12 ++++++++++++ darwin/main.m | 11 +++++++++++ 4 files changed, 65 insertions(+) create mode 100644 common/programmererror.c diff --git a/common/meson.build b/common/meson.build index e198fc43..7baf3c72 100644 --- a/common/meson.build +++ b/common/meson.build @@ -2,4 +2,5 @@ libui_sources += [ 'common/init.c', + 'common/programmererror.c', ] diff --git a/common/programmererror.c b/common/programmererror.c new file mode 100644 index 00000000..3f68a8d2 --- /dev/null +++ b/common/programmererror.c @@ -0,0 +1,41 @@ +// 12 may 2019 +#include +#include +#include "ui.h" +#include "uipriv.h" + +static const char *messages[] = { + [uiprivProgrammerErrorWrongStructSize] = "wrong size %zu for %s", + [uiprivProgrammerErrorIndexOutOfRange] = "index %d out of range in %s()", +}; + +static void prepareProgrammerError(char *buf, int size, unsigned int which, va_list ap) +{ + int n; + + if (which >= uiprivNumProgrammerErrors) { + // TODO + } + n = vsnprintf(buf, size, messages[which], ap); + if (n < 0) { + // TODO + } + if (n >= size) { + // TODO + buf[size - 4] = '.'; + buf[size - 3] = '.'; + buf[size - 2] = '.'; + buf[size - 1] = '\0'; + } +} + +void uiprivProgrammerError(unsigned int which, ...) +{ + va_list ap; + char buf[256]; + + va_start(ap, which); + prepareProgrammerError(buf, 256, which, ap); + va_end(ap); + uiprivSysProgrammerError(buf); +} diff --git a/common/uipriv.h b/common/uipriv.h index 613e0d0b..86890f60 100644 --- a/common/uipriv.h +++ b/common/uipriv.h @@ -10,6 +10,18 @@ extern int uiprivSysInit(void *options, uiInitError *err); extern int uiprivInitReturnError(uiInitError *err, const char *msg); extern int uiprivInitReturnErrorf(uiInitError *err, const char *msg, ...); +// programmererror.c +enum { + uiprivProgrammerErrorWrongStructSize, // arguments: size_t badSize, const char *structName + uiprivProgrammerErrorIndexOutOfRange, // arguments: int badIndex, __func__ + uiprivNumProgrammerErrors, +}; +extern void uiprivProgrammerError(unsigned int which, ...); +extern void uiprivSysProgrammerError(const char *msg); +#define uiprivProgrammerErrorPrefix "libui programmer error" +// TODO add debugging advice? +#define uiprivProgrammerErrorAdvice "This likely means you are using libui incorrectly. Check your source code and try again. If you have received this warning in error, contact the libui authors." + #ifdef __cplusplus } #endif diff --git a/darwin/main.m b/darwin/main.m index 9e95e3b3..cc78c938 100644 --- a/darwin/main.m +++ b/darwin/main.m @@ -1,4 +1,5 @@ // 20 april 2019 +#import #import "uipriv_darwin.h" @interface uiprivApplication : NSApplication @@ -97,3 +98,13 @@ void uiQueueMain(void (*f)(void *data), void *data) // the signature of f matches dispatch_function_t dispatch_async_f(dispatch_get_main_queue(), data, f); } + +void uiprivSysProgrammerError(const char *msg) +{ + NSLog(@"*** %s: %s. %s", uiprivProgrammerErrorPrefix, msg, uiprivProgrammerErrorAdvice); + // TODO either find an appropriate exception for each message or use a custom exception name + [NSException raise:NSInvalidArgumentException + format:@"%s: %s", uiprivProgrammerErrorPrefix, msg]; + // TODO break into the debugger? + abort(); // we shouldn't reach here +}