X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Flibgame%2Fmisc.c;h=26c338ca20279567276b92a87524994f85f54096;hb=35dd23cea816adff3891d62ea47aec6aa0aba990;hp=a810b6d11072c89d0389712014ae6b54cfb3063f;hpb=4dba06ad2079d7f9df56ec5512c6d27a0cf8c18e;p=rocksndiamonds.git diff --git a/src/libgame/misc.c b/src/libgame/misc.c index a810b6d1..26c338ca 100644 --- a/src/libgame/misc.c +++ b/src/libgame/misc.c @@ -33,32 +33,125 @@ #include "image.h" -/* ------------------------------------------------------------------------- */ +/* ========================================================================= */ /* some generic helper functions */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ +/* platform independent wrappers for printf() et al. (newline aware) */ /* ------------------------------------------------------------------------- */ -void fprintf_line(FILE *stream, char *line_string, int line_length) +static void vfprintf_newline(FILE *stream, char *format, va_list ap) +{ + char *newline = STRING_NEWLINE; + + vfprintf(stream, format, ap); + + fprintf(stream, "%s", newline); +} + +static void vprintf_error_ext(char *format, va_list ap, boolean print_newline) +{ + FILE *error_file = openErrorFile(); /* this returns at least 'stderr' */ + + if (print_newline) + vfprintf_newline(error_file, format, ap); + else + vfprintf(error_file, format, ap); + + if (error_file != stderr) /* do not close stream 'stderr' */ + fclose(error_file); +} + +static void vprintf_error(char *format, va_list ap) +{ + vprintf_error_ext(format, ap, FALSE); +} + +static void vprintf_error_newline(char *format, va_list ap) +{ + vprintf_error_ext(format, ap, TRUE); +} + +static void printf_error(char *format, ...) +{ + if (format) + { + va_list ap; + + va_start(ap, format); + vprintf_error(format, ap); + va_end(ap); + } +} + +static void printf_error_newline(char *format, ...) +{ + if (format) + { + va_list ap; + + va_start(ap, format); + vprintf_error_newline(format, ap); + va_end(ap); + } +} + +static void fprintf_newline(FILE *stream, char *format, ...) +{ + if (format) + { + va_list ap; + + va_start(ap, format); + vfprintf_newline(stream, format, ap); + va_end(ap); + } +} + +static char *get_line_string(char *line_chars, int line_length) { + static char *buffer = NULL; + int line_chars_length = strlen(line_chars); int i; + if (buffer != NULL) + checked_free(buffer); + + buffer = checked_malloc(line_chars_length * line_length + 1); + for (i = 0; i < line_length; i++) - fprintf(stream, "%s", line_string); + strcpy(&buffer[i * line_chars_length], line_chars); + + return buffer; +} - fprintf(stream, "\n"); +void fprintf_line(FILE *stream, char *line_chars, int line_length) +{ + fprintf_newline(stream, get_line_string(line_chars, line_length)); +} + +void printf_line(char *line_chars, int line_length) +{ + fprintf_line(stdout, line_chars, line_length); } -void printf_line(char *line_string, int line_length) +void printf_line_error(char *line_chars, int line_length) { - fprintf_line(stdout, line_string, line_length); + printf_error_newline(get_line_string(line_chars, line_length)); } -void printf_line_with_prefix(char *prefix, char *line_string, int line_length) +void printf_line_with_prefix(char *prefix, char *line_chars, int line_length) { fprintf(stdout, "%s", prefix); - fprintf_line(stdout, line_string, line_length); + fprintf_line(stdout, line_chars, line_length); } +/* ------------------------------------------------------------------------- */ +/* string functions */ +/* ------------------------------------------------------------------------- */ + /* int2str() returns a number converted to a string; the used memory is static, but will be overwritten by later calls, so if you want to save the result, copy it to a private string buffer; @@ -460,12 +553,10 @@ char *getHomeDir() static char *getLastPathSeparatorPtr(char *filename) { - char *last_separator = strrchr(filename, '/'); + char *last_separator = strrchr(filename, CHAR_PATH_SEPARATOR_UNIX); -#if !defined(PLATFORM_UNIX) if (last_separator == NULL) /* also try DOS/Windows variant */ - last_separator = strrchr(filename, '\\'); -#endif + last_separator = strrchr(filename, CHAR_PATH_SEPARATOR_DOS); return last_separator; } @@ -505,21 +596,23 @@ char *getBasePath(char *filename) char *getPath2(char *path1, char *path2) { + char *sep = STRING_PATH_SEPARATOR; char *complete_path = checked_malloc(strlen(path1) + 1 + strlen(path2) + 1); - sprintf(complete_path, "%s/%s", path1, path2); + sprintf(complete_path, "%s%s%s", path1, sep, path2); return complete_path; } char *getPath3(char *path1, char *path2, char *path3) { + char *sep = STRING_PATH_SEPARATOR; char *complete_path = checked_malloc(strlen(path1) + 1 + strlen(path2) + 1 + strlen(path3) + 1); - sprintf(complete_path, "%s/%s/%s", path1, path2, path3); + sprintf(complete_path, "%s%s%s%s%s", path1, sep, path2, sep, path3); return complete_path; } @@ -750,45 +843,6 @@ void GetOptions(char *argv[], void (*print_usage_function)(void)) /* when doing batch processing, always enable verbose mode (warnings) */ options.verbose = TRUE; } -#if 1 -#if DEBUG -#if defined(TARGET_SDL) - else if (strncmp(option, "-SDL_ListModes", option_len) == 0) - { - SDL_Rect **modes; - int i; - - SDL_Init(SDL_INIT_VIDEO); - - /* get available fullscreen/hardware modes */ - modes=SDL_ListModes(NULL, SDL_FULLSCREEN|SDL_HWSURFACE); - - /* check if there are any modes available */ - if (modes == (SDL_Rect **)0) - { - printf("No modes available!\n"); - - exit(-1); - } - - /* check if our resolution is restricted */ - if (modes == (SDL_Rect **)-1) - { - printf("All resolutions available.\n"); - } - else - { - /* print valid modes */ - printf("Available Modes:\n"); - for(i = 0; modes[i]; i++) - printf(" %d x %d\n", modes[i]->w, modes[i]->h); - } - - exit(0); - } -#endif -#endif -#endif else if (*option == '-') { Error(ERR_EXIT_HELP, "unrecognized option '%s'", option_str); @@ -832,6 +886,69 @@ char *GetError() return internal_error; } +#if 1 + +void Error(int mode, char *format, ...) +{ + static boolean last_line_was_separator = FALSE; + char *process_name = ""; + + /* display warnings only when running in verbose mode */ + if (mode & ERR_WARN && !options.verbose) + return; + + if (mode == ERR_RETURN_LINE) + { + if (!last_line_was_separator) + printf_line_error(format, 79); + + last_line_was_separator = TRUE; + + return; + } + + last_line_was_separator = FALSE; + + if (mode & ERR_SOUND_SERVER) + process_name = " sound server"; + else if (mode & ERR_NETWORK_SERVER) + process_name = " network server"; + else if (mode & ERR_NETWORK_CLIENT) + process_name = " network client **"; + + if (format) + { + va_list ap; + + printf_error("%s%s: ", program.command_basename, process_name); + + if (mode & ERR_WARN) + printf_error("warning: "); + + va_start(ap, format); + vprintf_error_newline(format, ap); + va_end(ap); + } + + if (mode & ERR_HELP) + printf_error_newline("%s: Try option '--help' for more information.", + program.command_basename); + + if (mode & ERR_EXIT) + printf_error_newline("%s%s: aborting", + program.command_basename, process_name); + + if (mode & ERR_EXIT) + { + if (mode & ERR_FROM_SERVER) + exit(1); /* child process: normal exit */ + else + program.exit_function(1); /* main process: clean up stuff */ + } +} + +#else + void Error(int mode, char *format, ...) { static boolean last_line_was_separator = FALSE; @@ -855,12 +972,13 @@ void Error(int mode, char *format, ...) last_line_was_separator = FALSE; -#if defined(PLATFORM_MSDOS) +#if defined(PLATFORM_WIN32) || defined(PLATFORM_MSDOS) newline = "\r\n"; if ((error = openErrorFile()) == NULL) { printf("Cannot write to error output file!%s", newline); + program.exit_function(1); } #endif @@ -908,6 +1026,8 @@ void Error(int mode, char *format, ...) } } +#endif + /* ------------------------------------------------------------------------- */ /* checked memory allocation and freeing functions */ @@ -2736,25 +2856,35 @@ void FreeCustomArtworkLists(struct ArtworkListInfo *artwork_info) /* ------------------------------------------------------------------------- */ /* functions only needed for non-Unix (non-command-line) systems */ /* (MS-DOS only; SDL/Windows creates files "stdout.txt" and "stderr.txt") */ +/* (now also added for Windows, to create files in user data directory) */ /* ------------------------------------------------------------------------- */ -#if defined(PLATFORM_MSDOS) - -#define ERROR_FILENAME "stderr.txt" +char *getErrorFilename(char *basename) +{ + return getPath2(getUserDataDir(), basename); +} void initErrorFile() { - unlink(ERROR_FILENAME); + unlink(program.error_filename); } FILE *openErrorFile() { - return fopen(ERROR_FILENAME, MODE_APPEND); + FILE *error_file = stderr; + +#if defined(PLATFORM_WIN32) || defined(PLATFORM_MSDOS) + if ((error_file = fopen(program.error_filename, MODE_APPEND)) == NULL) + fprintf_newline(stderr, "ERROR: cannot open file '%s' for appending!", + program.error_filename); +#endif + + return error_file; } void dumpErrorFile() { - FILE *error_file = fopen(ERROR_FILENAME, MODE_READ); + FILE *error_file = fopen(program.error_filename, MODE_READ); if (error_file != NULL) { @@ -2764,7 +2894,18 @@ void dumpErrorFile() fclose(error_file); } } + +void NotifyUserAboutErrorFile() +{ +#if defined(PLATFORM_WIN32) + char *title_text = getStringCat2(program.program_title, " Error Message"); + char *error_text = getStringCat2("The program was aborted due to an error; " + "for details, see the following error file:" + STRING_NEWLINE, program.error_filename); + + MessageBox(NULL, error_text, title_text, MB_OK); #endif +} /* ------------------------------------------------------------------------- */