Test: Threaded string builder on *nix

This commit is contained in:
Vicki Pfau 2020-07-13 01:19:19 -07:00
parent 6bdae813be
commit 0fd6532b38
2 changed files with 65 additions and 0 deletions

View File

@ -292,6 +292,7 @@ include(CheckIncludeFiles)
check_function_exists(strdup HAVE_STRDUP)
check_function_exists(strndup HAVE_STRNDUP)
check_function_exists(strlcpy HAVE_STRLCPY)
check_function_exists(vasprintf HAVE_VASPRINTF)
if(NOT DEFINED PSP2)
check_function_exists(localtime_r HAVE_LOCALTIME_R)
endif()
@ -374,6 +375,10 @@ if(HAVE_STRLCPY)
list(APPEND FUNCTION_DEFINES HAVE_STRLCPY)
endif()
if(HAVE_VASPRINTF)
list(APPEND FUNCTION_DEFINES HAVE_VASPRINTF)
endif()
if(HAVE_LOCALTIME_R)
list(APPEND FUNCTION_DEFINES HAVE_LOCALTIME_R)
endif()

View File

@ -85,6 +85,11 @@ DEFINE_VECTOR(CInemaTestList, struct CInemaTest)
DECLARE_VECTOR(ImageList, void*)
DEFINE_VECTOR(ImageList, void*)
struct StringBuilder {
struct StringList out;
struct StringList err;
};
static bool showVersion = false;
static bool showUsage = false;
static char base[PATH_MAX] = {0};
@ -102,6 +107,7 @@ static size_t jobIndex = 0;
static Mutex jobMutex;
static Thread jobThreads[MAX_JOBS];
static int jobStatus;
static ThreadLocal stringBuilder;
bool CInemaTestInit(struct CInemaTest*, const char* directory, const char* filename);
void CInemaTestRun(struct CInemaTest*);
@ -117,7 +123,16 @@ ATTRIBUTE_FORMAT(printf, 2, 3) void CIlog(int minlevel, const char* format, ...)
}
va_list args;
va_start(args, format);
#ifdef HAVE_VASPRINTF
struct StringBuilder* builder = ThreadLocalGetValue(stringBuilder);
if (!builder) {
vprintf(format, args);
} else {
vasprintf(StringListAppend(&builder->out), format, args);
}
#else
vprintf(format, args);
#endif
va_end(args);
}
@ -127,10 +142,39 @@ ATTRIBUTE_FORMAT(printf, 2, 3) void CIerr(int minlevel, const char* format, ...)
}
va_list args;
va_start(args, format);
#ifdef HAVE_VASPRINTF
struct StringBuilder* builder = ThreadLocalGetValue(stringBuilder);
if (!builder) {
vfprintf(stderr, format, args);
} else {
vasprintf(StringListAppend(&builder->err), format, args);
}
#else
vfprintf(stderr, format, args);
#endif
va_end(args);
}
void CIflush(struct StringList* list, FILE* out) {
size_t len = 0;
size_t i;
for (i = 0; i < StringListSize(list); ++i) {
len += strlen(*StringListGetPointer(list, i));
}
char* string = calloc(len + 1, sizeof(char));
char* cur = string;
for (i = 0; i < StringListSize(list); ++i) {
char* brick = *StringListGetPointer(list, i);
size_t portion = strlen(brick);
memcpy(cur, brick, portion);
free(brick);
cur += portion;
}
fputs(string, out);
free(string);
StringListClear(list);
}
static bool parseCInemaArgs(int argc, char* const* argv) {
int ch;
int index = 0;
@ -886,6 +930,11 @@ static bool CInemaTask(struct CInemaTestList* tests, size_t i) {
static THREAD_ENTRY CInemaJob(void* context) {
struct CInemaTestList* tests = context;
struct StringBuilder builder;
StringListInit(&builder.out, 0);
StringListInit(&builder.err, 0);
ThreadLocalSetKey(stringBuilder, &builder);
bool success = true;
while (true) {
size_t i;
@ -899,12 +948,20 @@ static THREAD_ENTRY CInemaJob(void* context) {
if (!CInemaTask(tests, i)) {
success = false;
}
CIflush(&builder.out, stdout);
CIflush(&builder.err, stderr);
}
MutexLock(&jobMutex);
if (!success) {
jobStatus = 1;
}
MutexUnlock(&jobMutex);
CIflush(&builder.out, stdout);
StringListDeinit(&builder.out);
CIflush(&builder.err, stderr);
StringListDeinit(&builder.err);
}
void _log(struct mLogger* log, int category, enum mLogLevel level, const char* format, va_list args) {
@ -935,6 +992,9 @@ void _log(struct mLogger* log, int category, enum mLogLevel level, const char* f
}
int main(int argc, char** argv) {
ThreadLocalInitKey(&stringBuilder);
ThreadLocalSetKey(stringBuilder, NULL);
int status = 0;
if (!parseCInemaArgs(argc, argv)) {
status = 1;