#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;
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;
}
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;
}
/* 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);
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;
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
}
}
+#endif
+
/* ------------------------------------------------------------------------- */
/* checked memory allocation and freeing functions */
/* ------------------------------------------------------------------------- */
/* 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)
{
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
+}
/* ------------------------------------------------------------------------- */