+/* ========================================================================= */
+/* some generic helper functions */
+/* ========================================================================= */
+
+/* ------------------------------------------------------------------------- */
+/* platform independent wrappers for printf() et al. (newline aware) */
+/* ------------------------------------------------------------------------- */
+
+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++)
+ strcpy(&buffer[i * line_chars_length], line_chars);
+
+ return buffer;
+}
+
+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_error(char *line_chars, int line_length)
+{
+ printf_error_newline(get_line_string(line_chars, 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);
+}
+
+
+/* ------------------------------------------------------------------------- */
+/* 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;
+ there can be 10 local calls of int2str() without buffering the result --
+ the 11th call will then destroy the result from the first call and so on.
+*/
+
+char *int2str(int number, int size)
+{
+ static char shift_array[10][40];
+ static int shift_counter = 0;
+ char *s = shift_array[shift_counter];
+
+ shift_counter = (shift_counter + 1) % 10;
+
+ if (size > 20)
+ size = 20;
+
+ if (size)
+ {
+ sprintf(s, " %09d", number);
+ return &s[strlen(s) - size];
+ }
+ else
+ {
+ sprintf(s, "%d", number);
+ return s;
+ }
+}
+
+
+/* something similar to "int2str()" above, but allocates its own memory
+ and has a different interface; we cannot use "itoa()", because this
+ seems to be already defined when cross-compiling to the win32 target */
+
+char *i_to_a(unsigned int i)
+{
+ static char *a = NULL;
+
+ checked_free(a);
+
+ if (i > 2147483647) /* yes, this is a kludge */
+ i = 2147483647;
+
+ a = checked_malloc(10 + 1);
+
+ sprintf(a, "%d", i);
+
+ return a;
+}
+
+
+/* calculate base-2 logarithm of argument (rounded down to integer;
+ this function returns the number of the highest bit set in argument) */
+
+int log_2(unsigned int x)
+{
+ int e = 0;
+
+ while ((1 << e) < x)
+ {
+ x -= (1 << e); /* for rounding down (rounding up: remove this line) */
+ e++;
+ }
+
+ return e;
+}
+
+
+/* ------------------------------------------------------------------------- */
+/* counter functions */
+/* ------------------------------------------------------------------------- */
+