diff --git a/common/init.c b/common/init.c index 03124b30..199b4c55 100644 --- a/common/init.c +++ b/common/init.c @@ -1,8 +1,4 @@ // 19 april 2019 -// TODO get rid of the need for this (it temporarily silences noise so I can find actual build issues) -#ifdef _MSC_VER -#define _CRT_SECURE_NO_WARNINGS -#endif #include #include #include @@ -11,31 +7,6 @@ static bool initialized = false; -#define errAlreadyInitialized "libui already initialized" -#define errOptionsMustBeNULL "options parameter to uiInit() must be NULL" - -static const char *commonInitErrors[] = { - errAlreadyInitialized, - errOptionsMustBeNULL, - NULL, -}; - -static bool checkInitErrorLengths(uiInitError *err, const char **initErrors) -{ - const char **p; - - if (initErrors == NULL) - return true; - for (p = initErrors; *p != NULL; p++) - if (strlen(*p) > 255) { - strcpy(err->Message, "[INTERNAL] uiInit() error too long: "); - strncat(err->Message, *p, 32); - strcat(err->Message, "..."); - return false; - } - return true; -} - bool uiInit(void *options, uiInitError *err) { if (err == NULL) @@ -43,16 +14,11 @@ bool uiInit(void *options, uiInitError *err) if (err->Size != sizeof (uiInitError)) return false; - if (!checkInitErrorLengths(err, commonInitErrors)) - return false; - if (!checkInitErrorLengths(err, uiprivSysInitErrors())) - return false; - if (initialized) - return uiprivInitReturnError(err, errAlreadyInitialized); + return uiprivInitReturnErrorf(err, "libui already initialized"); if (options != NULL) - return uiprivInitReturnError(err, errOptionsMustBeNULL); + return uiprivInitReturnErrorf(err, "options parameter to uiInit() must be NULL"); if (!uiprivSysInit(options, err)) return false; @@ -60,21 +26,24 @@ bool uiInit(void *options, uiInitError *err) return true; } -bool uiprivInitReturnError(uiInitError *err, const char *msg) -{ - // checkInitErrorLengths() above ensures that err->Message[255] will always be '\0' - strncpy(err->Message, msg, 256); - return false; -} - +// TODO rename all msgs to fmt bool uiprivInitReturnErrorf(uiInitError *err, const char *msg, ...) { + int n; va_list ap; - // checkInitErrorLengths() above ensures that err->Message[255] will always be '\0' assuming the formatted string in msg passed to checkInitErrorLengths() is valid va_start(ap, msg); - vsnprintf(err->Message, 256, msg, ap); + n = vsnprintf(err->Message, 256, msg, ap); va_end(ap); + if (n < 0) + uiprivInternalError("encoding error returning initialization error; this means something is very very wrong with libui itself"); + if (n >= 256) { + // the formatted message is too long; truncate it + err->Message[252] = '.'; + err->Message[253] = '.'; + err->Message[254] = '.'; + err->Message[255] = '\0'; + } return false; } diff --git a/common/uipriv.h b/common/uipriv.h index bfd474fa..48f02574 100644 --- a/common/uipriv.h +++ b/common/uipriv.h @@ -20,9 +20,7 @@ extern "C" { #endif // init.c -extern const char **uiprivSysInitErrors(void); extern bool uiprivSysInit(void *options, uiInitError *err); -extern bool uiprivInitReturnError(uiInitError *err, const char *msg); extern bool uiprivInitReturnErrorf(uiInitError *err, const char *msg, ...); extern bool uiprivCheckInitializedAndThreadImpl(const char *func); #define uiprivCheckInitializedAndThread() uiprivCheckInitializedAndThreadImpl(uiprivFunc) diff --git a/darwin/main.m b/darwin/main.m index f1f44ae6..78e01c57 100644 --- a/darwin/main.m +++ b/darwin/main.m @@ -36,18 +36,6 @@ static uiprivApplicationDelegate *uiprivAppDelegate; @end -#define errNSAppAlreadyInitialized "NSApp is not of type uiprivApplication; was likely already initialized beforehand" - -static const char *initErrors[] = { - errNSAppAlreadyInitialized, - NULL, -}; - -const char **uiprivSysInitErrors(void) -{ - return initErrors; -} - static pthread_t mainThread; static BOOL initialized = NO; // TODO deduplicate this from common/init.c @@ -55,7 +43,7 @@ bool uiprivSysInit(void *options, uiInitError *err) { uiprivApp = [uiprivApplication sharedApplication]; if (![NSApp isKindOfClass:[uiprivApplication class]]) - return uiprivInitReturnError(err, errNSAppAlreadyInitialized); + return uiprivInitReturnErrorf(err, "NSApp is not of type uiprivApplication; was likely already initialized beforehand"); // don't check for a NO return; something (launch services?) causes running from application bundles to always return NO when asking to change activation policy, even if the change is to the same activation policy! // see https://github.com/andlabs/ui/issues/6 diff --git a/unix/main.c b/unix/main.c index dda450aa..46e39d64 100644 --- a/unix/main.c +++ b/unix/main.c @@ -1,11 +1,6 @@ // 6 april 2015 #include "uipriv_unix.h" -const char **uiprivSysInitErrors(void) -{ - return NULL; -} - static pthread_t mainThread; static gboolean initialized = FALSE; // TODO deduplicate this from common/init.c @@ -14,8 +9,7 @@ bool uiprivSysInit(void *options, uiInitError *err) GError *gerr = NULL; if (gtk_init_with_args(NULL, NULL, NULL, NULL, NULL, &gerr) == FALSE) { - // TODO make sure this is safe - strncpy(err->Message, gerr->message, 255); + uiprivReturnErrorf(err, "%s", gerr->message); g_error_free(gerr); return false; } diff --git a/windows/main.cpp b/windows/main.cpp index 58150aca..3f2f4acf 100644 --- a/windows/main.cpp +++ b/windows/main.cpp @@ -42,30 +42,8 @@ static inline void setHInstance(void) ICC_DATE_CLASSES | /* date/time picker */ \ 0) -#define errLoadDefaultIconFailed "failed to load default icon" -#define errLoadDefaultCursorFailed "failed to load default cursor" -#define errInitUtilWindowFailed "failed to initialize the utility window" -#define errICCFailed "InitCommonControlsEx() failed" -#define errICCFailedNoLastError "InitCommonControlsEx() failed, but didn't specify why. This usually means you forgot the Common Controls v6 manifest; refer to the libui documentation for instructions." -#define errCoInitializeFailed "CoInitialize() failed" - -#define errHRESULTInitErrorsSuffix ": 0x00000000" -static const char *initErrors[] = { - errLoadDefaultIconFailed errHRESULTInitErrorsSuffix - errLoadDefaultCursorFailed errHRESULTInitErrorsSuffix - errInitUtilWindowFailed errHRESULTInitErrorsSuffix - errICCFailed errHRESULTInitErrorsSuffix, - errICCFailedNoLastError, - errCoInitializeFailed errHRESULTInitErrorsSuffix, - NULL, -}; #define uiprivInitReturnHRESULT(err, msg, hr) uiprivInitReturnErrorf(err, "%s: 0x%08I32X", msg, hr) -const char **uiprivSysInitErrors(void) -{ - return initErrors; -} - static DWORD mainThread; static BOOL initialized = FALSE; // TODO deduplicate this from common/init.c @@ -85,14 +63,14 @@ bool uiprivSysInit(void *options, uiInitError *err) hr = uiprivHrLoadIconW(NULL, IDI_APPLICATION, &hDefaultIcon); if (hr != S_OK) - return uiprivInitReturnHRESULT(err, errLoadDefaultIconFailed, hr); + return uiprivInitReturnHRESULT(err, "failed to load default icon", hr); hr = uiprivHrLoadCursorW(NULL, IDC_ARROW, &hDefaultCursor); if (hr != S_OK) - return uiprivInitReturnHRESULT(err, errLoadDefaultCursorFailed, hr); + return uiprivInitReturnHRESULT(err, "failed to load default cursor", hr); hr = uiprivInitUtilWindow(hDefaultIcon, hDefaultCursor); if (hr != S_OK) - return uiprivInitReturnHRESULT(err, errInitUtilWindowFailed, hr); + return uiprivInitReturnHRESULT(err, "failed to initialize the utility window", hr); ZeroMemory(&icc, sizeof (INITCOMMONCONTROLSEX)); icc.dwSize = sizeof (INITCOMMONCONTROLSEX); @@ -102,14 +80,14 @@ bool uiprivSysInit(void *options, uiInitError *err) lasterr = GetLastError(); if (lasterr == 0) - return uiprivInitReturnError(err, errICCFailedNoLastError); + return uiprivInitReturnErrorf(err, "InitCommonControlsEx() failed, but didn't specify why. This usually means you forgot the Common Controls v6 manifest; refer to the libui documentation for instructions."); hr = HRESULT_FROM_WIN32(lasterr); - return uiprivInitReturnHRESULT(err, errICCFailed, hr); + return uiprivInitReturnHRESULT(err, "InitCommonControlsEx() failed", hr); } /* hr = CoInitialize(NULL); if (hr != S_OK && hr != S_FALSE) - return ieHRESULT("initializing COM", hr); + return uiprivInitReturnHRESULT(err, "CoInitialize() failed", hr); // LONGTERM initialize COM security // LONGTERM turn off COM exception handling */