2019-04-19 11:32:13 -05:00
// 19 april 2019
2019-04-21 16:28:47 -05:00
// 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
2019-04-21 14:08:09 -05:00
# include <stdarg.h>
2019-04-21 13:49:16 -05:00
# include <stdio.h>
2019-04-19 11:32:13 -05:00
# include <string.h>
# include "ui.h"
# include "uipriv.h"
2019-05-29 20:10:44 -05:00
static bool initialized = false ;
2019-04-19 11:32:13 -05:00
2019-04-20 20:38:26 -05:00
# define errAlreadyInitialized "libui already initialized"
# define errOptionsMustBeNULL "options parameter to uiInit() must be NULL"
static const char * commonInitErrors [ ] = {
errAlreadyInitialized ,
errOptionsMustBeNULL ,
NULL ,
} ;
2019-05-29 20:10:44 -05:00
static bool checkInitErrorLengths ( uiInitError * err , const char * * initErrors )
2019-04-20 20:38:26 -05:00
{
const char * * p ;
2019-04-21 11:24:19 -05:00
if ( initErrors = = NULL )
2019-05-29 20:10:44 -05:00
return true ;
2019-04-20 20:38:26 -05:00
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 , " ... " ) ;
2019-05-29 20:10:44 -05:00
return false ;
2019-04-20 20:38:26 -05:00
}
2019-05-29 20:10:44 -05:00
return true ;
2019-04-20 20:38:26 -05:00
}
2019-05-29 20:10:44 -05:00
bool uiInit ( void * options , uiInitError * err )
2019-04-19 11:32:13 -05:00
{
if ( err = = NULL )
2019-05-29 20:10:44 -05:00
return false ;
2019-04-19 11:32:13 -05:00
if ( err - > Size ! = sizeof ( uiInitError ) )
2019-05-29 20:10:44 -05:00
return false ;
2019-04-19 11:32:13 -05:00
2019-04-20 20:38:26 -05:00
if ( ! checkInitErrorLengths ( err , commonInitErrors ) )
2019-05-29 20:10:44 -05:00
return false ;
2019-05-09 11:07:28 -05:00
if ( ! checkInitErrorLengths ( err , uiprivSysInitErrors ( ) ) )
2019-05-29 20:10:44 -05:00
return false ;
2019-04-20 20:38:26 -05:00
2019-04-19 11:32:13 -05:00
if ( initialized )
2019-04-20 20:38:26 -05:00
return uiprivInitReturnError ( err , errAlreadyInitialized ) ;
2019-04-19 11:32:13 -05:00
if ( options ! = NULL )
2019-04-20 20:38:26 -05:00
return uiprivInitReturnError ( err , errOptionsMustBeNULL ) ;
2019-04-19 11:32:13 -05:00
2019-05-09 11:07:28 -05:00
if ( ! uiprivSysInit ( options , err ) )
2019-05-29 20:10:44 -05:00
return false ;
initialized = true ;
return true ;
2019-04-19 11:32:13 -05:00
}
2019-05-29 20:10:44 -05:00
bool uiprivInitReturnError ( uiInitError * err , const char * msg )
2019-04-19 11:32:13 -05:00
{
2019-04-20 20:38:26 -05:00
// checkInitErrorLengths() above ensures that err->Message[255] will always be '\0'
2019-04-19 11:32:13 -05:00
strncpy ( err - > Message , msg , 256 ) ;
2019-05-29 20:10:44 -05:00
return false ;
2019-04-19 11:32:13 -05:00
}
2019-05-29 20:10:44 -05:00
bool uiprivInitReturnErrorf ( uiInitError * err , const char * msg , . . . )
2019-04-21 13:49:16 -05:00
{
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 ) ;
2019-05-29 20:10:44 -05:00
return false ;
2019-04-21 13:49:16 -05:00
}
2019-05-28 20:54:13 -05:00
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 ;
}