/* vi: set ts=2 shiftwidth=2 expandtab: * * Copyright (C) 2003-2007 Simon Baldwin and Mark J. Tilford * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA */ /* * Module notes: * * o ... */ #include #include #include #include #include #include #include #include "scare.h" #include "sxprotos.h" /* Assorted definitions and constants. */ static const sc_char NUL = '\0'; /* * sx_trace() * * Debugging trace function; printf wrapper that writes to stdout. Note that * this differs from sc_trace(), which writes to stderr. We use stdout so * that trace output is synchronized to test expectation failure messages. */ void sx_trace (const sc_char *format, ...) { va_list ap; assert (format); va_start (ap, format); vfprintf (stdout, format, ap); va_end (ap); } /* * sx_error() * sx_fatal() * * Error reporting functions. sx_error() prints a message and continues. * sx_fatal() prints a message, then calls abort(). */ void sx_error (const sc_char *format, ...) { va_list ap; assert (format); fprintf (stderr, "sx: "); va_start (ap, format); vfprintf (stderr, format, ap); va_end (ap); } void sx_fatal (const sc_char *format, ...) { va_list ap; assert (format); fprintf (stderr, "sx: internal error: "); va_start (ap, format); vfprintf (stderr, format, ap); va_end (ap); fprintf (stderr, "sx: aborting...\n"); abort (); } /* * sx_malloc() * sx_realloc() * sx_free() * * Non-failing wrappers around malloc functions. */ void * sx_malloc (size_t size) { void *ptr; ptr = malloc (size); if (!ptr) sx_fatal ("sx_malloc: requested %lu bytes\n", (sc_uint) size); return ptr; } void * sx_realloc (void *pointer, size_t size) { void *ptr; ptr = realloc (pointer, size); if (!ptr) sx_fatal ("sx_realloc: requested %lu bytes\n", (sc_uint) size); return ptr; } void sx_free (void *ptr) { free (ptr); } /* * sx_fopen() * * Open a file for a given test name with the extension and mode supplied. * Returns NULL if unsuccessful. */ FILE * sx_fopen (const sc_char *name, const sc_char *extension, const sc_char *mode) { sc_char *filename; FILE *stream; assert (name && extension && mode); filename = sx_malloc (strlen (name) + strlen (extension) + 2); sprintf (filename, "%s.%s", name, extension); stream = fopen (filename, mode); sx_free (filename); return stream; } /* * sx_trim_string() * * Trim leading and trailing whitespace from a string. Modifies the string * in place, and returns the string address for convenience. */ sc_char * sx_trim_string (sc_char *string) { sc_int index_; assert (string); for (index_ = strlen (string) - 1; index_ >= 0 && isspace (string[index_]); index_--) string[index_] = NUL; for (index_ = 0; isspace (string[index_]);) index_++; memmove (string, string + index_, strlen (string) - index_ + 1); return string; } /* * sx_normalize_string() * * Trim a string, set all runs of whitespace to a single space character, * and convert all non-printing characters to '?'. Modifies the string in * place, and returns the string address for convenience. */ sc_char * sx_normalize_string (sc_char *string) { sc_int index_; assert (string); string = sx_trim_string (string); for (index_ = 0; string[index_] != NUL; index_++) { if (isspace (string[index_])) { sc_int cursor; string[index_] = ' '; for (cursor = index_ + 1; isspace (string[cursor]);) cursor++; memmove (string + index_ + 1, string + cursor, strlen (string + cursor) + 1); } else if (!isprint (string[index_])) string[index_] = '?'; } return string; }