94 lines
2.5 KiB
C
94 lines
2.5 KiB
C
// 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 <stdarg.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include "ui.h"
|
|
#include "uipriv.h"
|
|
|
|
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)
|
|
return false;
|
|
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);
|
|
|
|
if (options != NULL)
|
|
return uiprivInitReturnError(err, errOptionsMustBeNULL);
|
|
|
|
if (!uiprivSysInit(options, err))
|
|
return false;
|
|
initialized = true;
|
|
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;
|
|
}
|
|
|
|
bool uiprivInitReturnErrorf(uiInitError *err, const char *msg, ...)
|
|
{
|
|
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);
|
|
va_end(ap);
|
|
return false;
|
|
}
|
|
|
|
bool uiprivCheckInitializedAndThreadImpl(const char *func)
|
|
{
|
|
// While it does seem risky to not lock this, if this changes during the execution of this function it means only that it was changed from a different thread, and since it can only change from false to true, an error will be reported anyway.
|
|
if (!initialized) {
|
|
uiprivProgrammerError(uiprivProgrammerErrorNotInitialized, func);
|
|
return false;
|
|
}
|
|
if (!uiprivSysCheckThread()) {
|
|
uiprivProgrammerError(uiprivProgrammerErrorWrongThread, func);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|