X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Flibgame%2Fmisc.c;h=660f4df6a80ee83a2a4cfc9733514b1c126f5cf2;hb=4e745044fe35b4b093b1490a6e3da0fe4ee512de;hp=c123892d60343c061caa9b7741b5a35c909c28a2;hpb=4fb7d637c3bcc3381918636fdd22733ff7bae3ac;p=rocksndiamonds.git diff --git a/src/libgame/misc.c b/src/libgame/misc.c index c123892d..660f4df6 100644 --- a/src/libgame/misc.c +++ b/src/libgame/misc.c @@ -38,93 +38,149 @@ /* ========================================================================= */ /* ------------------------------------------------------------------------- */ -/* platform independent wrappers for printf() et al. (newline aware) */ +/* logging functions */ /* ------------------------------------------------------------------------- */ +#define DUPLICATE_LOG_OUTPUT_TO_STDERR TRUE + + #if defined(PLATFORM_ANDROID) static int android_log_prio = ANDROID_LOG_INFO; -#endif +static char *android_log_buffer = NULL; -#if 0 -static void vfPrintLog(FILE *stream, char *format, va_list ap) +static void append_to_android_log_buffer(char *format, va_list ap) { -} + char text_new[MAX_OUTPUT_LINESIZE]; -static void vfPrintLog(FILE *stream, char *format, va_list ap) -{ + // print text to temporary string + vsnprintf(text_new, MAX_OUTPUT_LINESIZE, format, ap); + + if (android_log_buffer == NULL) + { + android_log_buffer = getStringCopy(text_new); + } + else + { + char *android_log_buffer_old = android_log_buffer; + + // append new text to existing text + android_log_buffer = getStringCat2(android_log_buffer, text_new); + + checked_free(android_log_buffer_old); + } } -static void fPrintLog(FILE *stream, char *format, va_list ap) +static void vprintf_log_nonewline(char *format, va_list ap) { + // add log output to buffer until text with newline is printed + append_to_android_log_buffer(format, ap); } -static void fPrintLog(FILE *stream, char *format, va_list ap) +static void vprintf_log(char *format, va_list ap) { + // add log output to buffer + append_to_android_log_buffer(format, ap); + + // __android_log_vprint(android_log_prio, program.program_title, format, ap); + __android_log_write(android_log_prio, program.program_title, + android_log_buffer); + + checked_free(android_log_buffer); + android_log_buffer = NULL; } -#endif -static void vfprintf_nonewline(FILE *stream, char *format, va_list ap) -{ -#if defined(PLATFORM_ANDROID) - // (prefix text of logging output is currently skipped on Android) - //__android_log_vprint(android_log_prio, program.program_title, format, ap); #else - va_list ap2; - va_copy(ap2, ap); - vfprintf(stream, format, ap); - vfprintf(stderr, format, ap2); +static void vprintf_log_nonewline(char *format, va_list ap) +{ + FILE *file = program.error_file; + +#if DUPLICATE_LOG_OUTPUT_TO_STDERR + if (file != stderr) + { + va_list ap2; + va_copy(ap2, ap); + + vfprintf(stderr, format, ap2); - va_end(ap2); + va_end(ap2); + } #endif + + vfprintf(file, format, ap); } -static void vfprintf_newline(FILE *stream, char *format, va_list ap) +static void vprintf_log(char *format, va_list ap) { -#if defined(PLATFORM_ANDROID) - __android_log_vprint(android_log_prio, program.program_title, format, ap); -#else + FILE *file = program.error_file; char *newline = STRING_NEWLINE; - va_list ap2; - va_copy(ap2, ap); - - vfprintf(stream, format, ap); - fprintf(stream, "%s", newline); +#if DUPLICATE_LOG_OUTPUT_TO_STDERR + if (file != stderr) + { + va_list ap2; + va_copy(ap2, ap); - vfprintf(stderr, format, ap2); - fprintf(stderr, "%s", newline); + vfprintf(stderr, format, ap2); + fprintf(stderr, "%s", newline); - va_end(ap2); + va_end(ap2); + } #endif + + vfprintf(file, format, ap); + fprintf(file, "%s", newline); } +#endif -static void fprintf_nonewline(FILE *stream, char *format, ...) +static void printf_log_nonewline(char *format, ...) { va_list ap; va_start(ap, format); - vfprintf_nonewline(stream, format, ap); + vprintf_log_nonewline(format, ap); va_end(ap); } -static void fprintf_newline(FILE *stream, char *format, ...) +static void printf_log(char *format, ...) { va_list ap; va_start(ap, format); - vfprintf_newline(stream, format, ap); + vprintf_log(format, ap); va_end(ap); } -void fprintf_line(FILE *stream, char *line_chars, int line_length) +static void printf_log_line(char *line_chars, int line_length) +{ + int i; + + for (i = 0; i < line_length; i++) + printf_log_nonewline("%s", line_chars); + + printf_log(""); +} + + +/* ------------------------------------------------------------------------- */ +/* platform independent wrappers for printf() et al. */ +/* ------------------------------------------------------------------------- */ + +void fprintf_line(FILE *file, char *line_chars, int line_length) { int i; for (i = 0; i < line_length; i++) - fprintf_nonewline(stream, "%s", line_chars); + fprintf(file, "%s", line_chars); - fprintf_newline(stream, ""); + fprintf(file, "\n"); +} + +void fprintf_line_with_prefix(FILE *file, char *prefix, char *line_chars, + int line_length) +{ + fprintf(file, "%s", prefix); + fprintf_line(file, line_chars, line_length); } void printf_line(char *line_chars, int line_length) @@ -134,8 +190,7 @@ void printf_line(char *line_chars, int line_length) void printf_line_with_prefix(char *prefix, char *line_chars, int line_length) { - fprintf(stdout, "%s", prefix); - fprintf_line(stdout, line_chars, line_length); + fprintf_line_with_prefix(stdout, prefix, line_chars, line_length); } @@ -555,6 +610,9 @@ static char *getProgramMainDataPath() char *getStringCat2WithSeparator(char *s1, char *s2, char *sep) { + if (s1 == NULL || s2 == NULL || sep == NULL) + return NULL; + char *complete_string = checked_malloc(strlen(s1) + strlen(sep) + strlen(s2) + 1); @@ -565,6 +623,9 @@ char *getStringCat2WithSeparator(char *s1, char *s2, char *sep) char *getStringCat3WithSeparator(char *s1, char *s2, char *s3, char *sep) { + if (s1 == NULL || s2 == NULL || s3 == NULL || sep == NULL) + return NULL; + char *complete_string = checked_malloc(strlen(s1) + strlen(sep) + strlen(s2) + strlen(sep) + strlen(s3) + 1); @@ -587,9 +648,11 @@ char *getStringCat3(char *s1, char *s2, char *s3) char *getPath2(char *path1, char *path2) { #if defined(PLATFORM_ANDROID) - // workaround for reading from APK assets directory -- skip leading "./" + // workaround for reading from assets directory -- skip "." subdirs in path if (strEqual(path1, ".")) return getStringCopy(path2); + else if (strEqual(path2, ".")) + return getStringCopy(path1); #endif return getStringCat2WithSeparator(path1, path2, STRING_PATH_SEPARATOR); @@ -598,14 +661,60 @@ char *getPath2(char *path1, char *path2) char *getPath3(char *path1, char *path2, char *path3) { #if defined(PLATFORM_ANDROID) - // workaround for reading from APK assets directory -- skip leading "./" + // workaround for reading from assets directory -- skip "." subdirs in path if (strEqual(path1, ".")) return getStringCat2WithSeparator(path2, path3, STRING_PATH_SEPARATOR); + else if (strEqual(path2, ".")) + return getStringCat2WithSeparator(path1, path3, STRING_PATH_SEPARATOR); + else if (strEqual(path3, ".")) + return getStringCat2WithSeparator(path1, path2, STRING_PATH_SEPARATOR); #endif return getStringCat3WithSeparator(path1, path2, path3, STRING_PATH_SEPARATOR); } +char *getImg2(char *path1, char *path2) +{ + char *filename = getPath2(path1, path2); + + if (!fileExists(filename) && strSuffix(path2, ".png")) + { + // backward compatibility: if PNG file not found, check for PCX file + char *path2pcx = getStringCopy(path2); + + strcpy(&path2pcx[strlen(path2pcx) - 3], "pcx"); + + free(filename); + + filename = getPath2(path1, path2pcx); + + free(path2pcx); + } + + return filename; +} + +char *getImg3(char *path1, char *path2, char *path3) +{ + char *filename = getPath3(path1, path2, path3); + + if (!fileExists(filename) && strSuffix(path3, ".png")) + { + // backward compatibility: if PNG file not found, check for PCX file + char *path3pcx = getStringCopy(path3); + + strcpy(&path3pcx[strlen(path3pcx) - 3], "pcx"); + + free(filename); + + filename = getPath3(path1, path2, path3pcx); + + free(path3pcx); + } + + return filename; +} + char *getStringCopy(const char *s) { char *s_copy; @@ -964,6 +1073,9 @@ void Error(int mode, char *format, ...) static boolean last_line_was_separator = FALSE; char *process_name = ""; + if (program.error_file == NULL) + return; + #if defined(PLATFORM_ANDROID) android_log_prio = (mode & ERR_DEBUG ? ANDROID_LOG_DEBUG : mode & ERR_INFO ? ANDROID_LOG_INFO : @@ -979,7 +1091,7 @@ void Error(int mode, char *format, ...) if (mode == ERR_INFO_LINE) { if (!last_line_was_separator) - fprintf_line(program.error_file, format, 79); + printf_log_line(format, 79); last_line_was_separator = TRUE; @@ -997,19 +1109,20 @@ void Error(int mode, char *format, ...) if (format) { - va_list ap; - - fprintf_nonewline(program.error_file, "%s%s: ", program.command_basename, - process_name); +#if !defined(PLATFORM_ANDROID) + printf_log_nonewline("%s%s: ", program.command_basename, process_name); +#endif if (mode & ERR_WARN) - fprintf_nonewline(program.error_file, "warning: "); + printf_log_nonewline("warning: "); if (mode & ERR_EXIT) - fprintf_nonewline(program.error_file, "fatal error: "); + printf_log_nonewline("fatal error: "); + + va_list ap; va_start(ap, format); - vfprintf_newline(program.error_file, format, ap); + vprintf_log(format, ap); va_end(ap); if ((mode & ERR_EXIT) && !(mode & ERR_FROM_SERVER)) @@ -1021,13 +1134,11 @@ void Error(int mode, char *format, ...) } if (mode & ERR_HELP) - fprintf_newline(program.error_file, - "%s: Try option '--help' for more information.", - program.command_basename); + printf_log("%s: Try option '--help' for more information.", + program.command_basename); if (mode & ERR_EXIT) - fprintf_newline(program.error_file, "%s%s: aborting", - program.command_basename, process_name); + printf_log("%s%s: aborting", program.command_basename, process_name); if (mode & ERR_EXIT) { @@ -1857,6 +1968,10 @@ void addNodeToList(ListNode **node_first, char *key, void *content) node_new->key = getStringCopy(key); node_new->content = content; node_new->next = *node_first; + + if (*node_first) + (*node_first)->prev = node_new; + *node_first = node_new; } @@ -1869,8 +1984,15 @@ void deleteNodeFromList(ListNode **node_first, char *key, if (strEqual((*node_first)->key, key)) { checked_free((*node_first)->key); + if (destructor_function) destructor_function((*node_first)->content); + + if ((*node_first)->next) + (*node_first)->next->prev = (*node_first)->prev; + + checked_free(*node_first); + *node_first = (*node_first)->next; } else @@ -3386,7 +3508,7 @@ void openErrorFile() void closeErrorFile() { - if (program.error_file != stderr) /* do not close stream 'stderr' */ + if (program.error_file != stderr) /* do not close file 'stderr' */ fclose(program.error_file); }