From c3d265a9ff61c102483119f0ad0ccafb0a3a0c46 Mon Sep 17 00:00:00 2001 From: John Zaitseff Date: Tue, 19 Jul 2011 21:38:27 +1000 Subject: [PATCH] Clean up utils.c and utils.h Move all function interface comments to the header file (where they should have been in the first place), remove superfluous parentheses where allowed by the precedence of C operators. --- src/utils.c | 243 +++++++++++++++++----------------------------------- src/utils.h | 205 ++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 266 insertions(+), 182 deletions(-) diff --git a/src/utils.c b/src/utils.c index 222a6e1..d63901f 100644 --- a/src/utils.c +++ b/src/utils.c @@ -10,7 +10,7 @@ $Id$ This file, utils.c, contains the implementation of various utility - function for Star Traders. + functions used in Star Traders. This program is free software: you can redistribute it and/or modify it @@ -28,9 +28,15 @@ */ -#include "system.h" -#include "utils.h" -#include "intf.h" +#include "trader.h" + + +/************************************************************************ +* Module-specific constants * +************************************************************************/ + +#define GAME_FILENAME_PROTO "game%d" +#define GAME_FILENAME_BUFSIZE 16 /************************************************************************ @@ -43,28 +49,21 @@ static char *data_directory_str = NULL; // Writable data dir pathname /************************************************************************ -* Utility function definitions * +* Initialisation and environment function definitions * ************************************************************************/ -/*----------------------------------------------------------------------- - Function: init_program_name - Make the program name "canonical" - Arguments: argv - Same as passed to main() - Returns: (nothing) +// These functions are documented in the file "utils.h" - This function modifies the argv[0] pointer to eliminate the leading - path name from the program name. In other words, it strips any leading - directories and leaves just the base name of the program. It also - assigns the module variable "program_name_str". -*/ +/***********************************************************************/ void init_program_name (char *argv[]) { - if ((argv == NULL) || (argv[0] == NULL) || (*(argv[0]) == '\0')) { + if (argv == NULL || argv[0] == NULL || *argv[0] == '\0') { program_name_str = PACKAGE; } else { char *p = strrchr(argv[0], '/'); - if ((p != NULL) && (*++p != '\0')) { + if (p != NULL && *++p != '\0') { argv[0] = p; } @@ -73,16 +72,7 @@ void init_program_name (char *argv[]) } -/*----------------------------------------------------------------------- - Function: program_name - Return the canonical program name - Arguments: (none) - Returns: const char * - Pointer to program name - - This function returns the canonical program name (the program name as - invoked on the command line, without any leading pathname). NULL - should never be returned. -*/ - +/***********************************************************************/ const char *program_name (void) { if (program_name_str == NULL) { @@ -93,24 +83,15 @@ const char *program_name (void) } -/*----------------------------------------------------------------------- - Function: home_directory - Return home directory pathname - Arguments: (none) - Returns: const char * - Pointer to home directory - - This function returns the full pathname to the user's home directory, - using the HOME environment variable. Note that the existance or - writability of this pathname is NOT checked by this function. NULL is - returned if the home directory cannot be determined. -*/ - +/***********************************************************************/ const char *home_directory (void) { if (home_directory_str == NULL) { // Use the HOME environment variable where possible - char *p = getenv("HOME"); - if ((p != NULL) && (*p != '\0')) { - home_directory_str = strdup(p); + char *home = getenv("HOME"); + + if (home != NULL && *home != '\0') { + home_directory_str = strdup(home); } } @@ -118,24 +99,18 @@ const char *home_directory (void) } -/*----------------------------------------------------------------------- - Function: data_directory - Return writable data directory pathname - Arguments: (none) - Returns: const char * - Pointer to data directory - - This function returns the full pathname to a writable subdirectory - within the user's home directory. Essentially, home_directory() + "/." - + program_name() is returned. Note that this path is NOT created by - this function, nor is the writability of this path checked. NULL is - returned if this path cannot be determined. -*/ - +/***********************************************************************/ const char *data_directory (void) { + /* This implementation assumes a POSIX environment by using "/" as + the directory separator. It also assumes a dot-starting directory + name is permissible (again, true on POSIX systems) */ + if (data_directory_str == NULL) { const char *name = program_name(); const char *home = home_directory(); - if ((name != NULL) && (home != NULL)) { + + if (name != NULL && home != NULL) { char *p = malloc(strlen(home) + strlen(name) + 3); if (p != NULL) { strcpy(p, home); @@ -150,38 +125,33 @@ const char *data_directory (void) } -/*----------------------------------------------------------------------- - Function: game_filename - Convert an integer to a game filename - Arguments: game_num - Game number (1-9) as an integer - Returns: char * - Pointer to game filename string - - This function returns the full game filename as a malloc()ed string. - If game_num is between 1 and 9 inclusive, the string returned is in the - form data_directory() + "/" + GAME_FILENAME(game_num). If game_num is - any other integer, NULL is returned. -*/ - -char *game_filename (const int game_num) +/***********************************************************************/ +char *game_filename (int gamenum) { - char buf[GAME_FILENAME_BUFSIZE]; // Buffer for part of filename - const char *dd; // Data directory + /* This implementation assumes a POSIX environment by using "/" as + the directory separator */ + + char buf[GAME_FILENAME_BUFSIZE]; // Buffer for part of filename + const char *dd; // Data directory - if ((game_num < 1) || (game_num > 9)) { + if (gamenum < 1 || gamenum > 9) { return NULL; } dd = data_directory(); - snprintf(buf, GAME_FILENAME_BUFSIZE, GAME_FILENAME_PROTO, game_num); + snprintf(buf, GAME_FILENAME_BUFSIZE, GAME_FILENAME_PROTO, gamenum); if (dd == NULL) { char *p = malloc(strlen(buf) + 1); + if (p != NULL) { strcpy(p, buf); } return p; } else { char *p = malloc(strlen(dd) + strlen(buf) + 2); + if (p != NULL) { strcpy(p, dd); strcat(p, "/"); @@ -192,22 +162,14 @@ char *game_filename (const int game_num) } -/*----------------------------------------------------------------------- - Function: err_exit - Print an error and exit - Arguments: format - printf()-like format of error message - ... - printf()-like arguments - Returns: (does not return) +/************************************************************************ +* Error-reporting function definitions * +************************************************************************/ - This function closes all curses windows, prints the name of the program - and the error message to stderr (using format and following arguments - as if passed to printf()) and exits with error code EXIT_FAILURE. The - format supplied does NOT need to supply the program name nor the - trailing end-line character. The format should not be NULL; user- - supplied strings should ALWAYS be printed using "%s" as the format (and - with the user string as a second argument), NOT passed in as the format - itself. -*/ +// These functions are documented in the file "utils.h" + +/***********************************************************************/ void err_exit (const char *format, ...) { va_list args; @@ -225,21 +187,7 @@ void err_exit (const char *format, ...) } -/*----------------------------------------------------------------------- - Function: errno_exit - Print an error (using errno) and exit - Arguments: format - printf()-like format of error message - ... - printf()-like arguments - Returns: (does not return) - - This function closes all curses windows, prints the name of the - program, the error message (using format and following arguments as if - passed to printf()) and the string corresponding to errno to stderr, - then exits with error code EXIT_FAILURE. The format supplied does NOT - need to supply the program name, any colons nor the trailing end-line - character. The format may be NULL if no intermediate message is - needed. -*/ - +/***********************************************************************/ void errno_exit (const char *format, ...) { va_list args; @@ -261,93 +209,68 @@ void errno_exit (const char *format, ...) } -/*----------------------------------------------------------------------- - Function: err_exit_nomem - Print an "out of memory" error and exit - Arguments: (none) - Returns: (does not return) - - This function calls err_exit with an "out of memory" error message. -*/ - +/***********************************************************************/ void err_exit_nomem (void) { err_exit("out of memory"); } -/*----------------------------------------------------------------------- - Function: init_rand - Initialise the random number generator - Arguments: (none) - Returns: (nothing) +/************************************************************************ +* Random-number function definitions * +************************************************************************/ - This function initialises the pseudo-random number generator. -*/ +// These functions are documented in the file "utils.h" + +/***********************************************************************/ void init_rand (void) { + /* Ideally, initialisation of the random number generator should be + made using seed48() and lcong48(). However, we can only be + assured of no more than 32 bits of "randomness" by using time(), + available on all POSIX systems. If time_t is larger than long + int, we throw away the top bits. */ + time_t curtime = time(NULL); // NB: time_t may be larger than long int srand48((long int) curtime); } -/*----------------------------------------------------------------------- - Function: randf - Return a random number between 0.0 and 1.0 - Arguments: (none) - Returns: double - The random number - - This function returns a pseudo-random number between 0.0 (inclusive) - and 1.0 (not inclusive) as a floating-point number. -*/ - +/***********************************************************************/ extern double randf (void) { return drand48(); } -/*----------------------------------------------------------------------- - Function: randi - Return a random number between 0 and limit - Arguments: limit - Upper limit of random number - Returns: int - The random number - - This function returns a pseudo-random number between 0 (inclusive) and - limit (not inclusive) as an integer. -*/ - +/***********************************************************************/ extern int randi (int limit) { - return randf() * (double) limit; + return drand48() * (double) limit; } -/*----------------------------------------------------------------------- - Function: scramble - Scramble (encrypt) the buffer - Arguments: key - Encryption/decryption key - buf - Pointer to buffer to encrypt - bufsize - Size of buffer - Returns: char * - Pointer to buffer - - This function scrambles (encrypts) the buffer pointed to by buf using a - trivial in-place encryption algorithm. If key is zero, no encryption - takes place. The buffer buf must contain a string terminated by '\0'. - The characters '\r', '\n' and '\0' are guaranteed to remain the same - after encryption. At most bufsize characters are encrypted; buf is - returned as the result. -*/ - +/***********************************************************************/ char *scramble (int key, char *buf, int bufsize) { - if ((buf != NULL) && (key != 0)) { + /* The algorithm used here is reversable: scramble(scramble(...)) + will (or, at least, should!) return the same as the original + buffer. Problematic characters are ignored; however, this + function assumes all other characters are permitted in files. + This is true on all POSIX systems. */ + + if (buf != NULL && key != 0) { char *p = buf; unsigned char k = ~key; int i; - for (i = 0; (i < bufsize) && (*p != '\0'); i++, k++, p++) { + for (i = 0; i < bufsize && *p != '\0'; i++, k++, p++) { char c = *p; char r = c ^ k; // Simple encryption: XOR on a moving key - if ((c != '\r') && (c != '\n') && - (r != '\r') && (r != '\n') && (r != '\0')) { + if (c != '\r' && c != '\n' + && r != '\r' && r != '\n' && r != '\0') { *p = r; } } @@ -357,22 +280,12 @@ char *scramble (int key, char *buf, int bufsize) } -/*----------------------------------------------------------------------- - Function: unscramble - Unscramble (decrypt) the buffer - Arguments: key - Encryption/decryption key - buf - Pointer to buffer to decrypt - bufsize - Size of buffer - Returns: char * - Pointer to buffer - - This function unscrambles (decrypts) the buffer pointed to by buf using - a trivial in-place decryption algorithm. If key is zero, no decryption - takes place. The buffer buf must contain a string terminated by '\0'. - The characters '\r', '\n' and '\0' are guaranteed to remain the same - after decryption. At most bufsize characters are decrypted; buf is - returned as the result. -*/ - +/***********************************************************************/ char *unscramble (int key, char *buf, int bufsize) { return scramble(key, buf, bufsize); } + + +/***********************************************************************/ +// End of file diff --git a/src/utils.h b/src/utils.h index cd5e19f..91f9f03 100644 --- a/src/utils.h +++ b/src/utils.h @@ -9,8 +9,8 @@ Author: John Zaitseff $Id$ - This file, utils.h, contains various utility function declarations for - Star Traders. + This file, utils.h, contains declarations for various utility functions + used in Star Traders. This program is free software: you can redistribute it and/or modify it @@ -32,14 +32,6 @@ #define included_UTILS_H 1 -/************************************************************************ -* Constants and type declarations * -************************************************************************/ - -#define GAME_FILENAME_PROTO "game%d" -#define GAME_FILENAME_BUFSIZE 16 - - /************************************************************************ * Utility macro definitions * ************************************************************************/ @@ -51,37 +43,216 @@ /************************************************************************ -* Utility function prototypes * +* Initialisation and environment function prototypes * ************************************************************************/ -// Initialisation and environment functions +/* + Function: init_program_name - Make the program name "canonical" + Parameters: argv - Same as passed to main() + Returns: (nothing) + This function modifies the argv[0] pointer to eliminate any leading + pathname (directory) components from the program name, leaving just the + basename of the program. It also saves a copy that can be accessed via + the program_name() function. +*/ extern void init_program_name (char *argv[]); + + +/* + Function: program_name - Return the canonical program name + Parameters: (none) + Returns: const char * - Pointer to program name + + This function returns the canonical program name (the program name as + invoked on the command line, without any leading pathname components). + NULL should never be returned; however, init_program_name() SHOULD be + called before using this function. +*/ extern const char *program_name (void); + +/* + Function: home_directory - Return home directory pathname + Parameters: (none) + Returns: const char * - Pointer to home directory + + This function returns the full pathname to the user's home directory, + using the HOME environment variable. Note that the existance or + writability of this pathname is NOT checked by this function. NULL is + returned if the home directory cannot be determined. +*/ extern const char *home_directory (void); + + +/* + Function: data_directory - Return writable data directory pathname + Parameters: (none) + Returns: const char * - Pointer to data directory + + This function returns the full pathname to a potentially-writable + subdirectory within the user's home directory. Essentially, this + function returns home_directory() + "/." + program_name(). Note that + this path is NOT created by this function, nor is the writability of + this path checked. NULL is returned if this path cannot be determined. +*/ extern const char *data_directory (void); -extern char *game_filename (const int game_num); -// Error-reporting functions +/* + Function: game_filename - Convert an integer to a game filename + Parameters: gamenum - Game number (1-9) as an integer + Returns: char * - Pointer to game filename string -extern void err_exit (const char *format, ...) + This function returns the full game filename as a malloc()ed string + (ie, a string that must be freed at a later time by calling free()). + + If gamenum is between 1 and 9 inclusive, the string returned is in the + form data_directory() + "/" + GAME_FILENAME(gamenum). If gamenum is + any other integer, NULL is returned. +*/ +extern char *game_filename (int gamenum); + + +/************************************************************************ +* Error-reporting function prototypes * +************************************************************************/ + +/* + Function: err_exit - Print an error and exit + Parameters: format - printf()-like format of error message + ... - printf()-like arguments + Returns: (does not return) + + This function closes all Curses windows, prints the name of the program + and the error message to stderr (using format and following arguments + as if passed to printf()) and exits with error code EXIT_FAILURE. + + The format supplied does NOT need to supply the program name nor the + trailing end-line character. The format should not be NULL; user- + supplied strings should ALWAYS be printed using "%s" as the format (and + with the user string as a second argument), NOT passed in as the format + itself. +*/ +extern void err_exit (const char *format, ...) __attribute__((noreturn, format (printf, 1, 2))); + + +/* + Function: errno_exit - Print an error message (using errno) and exit + Parameters: format - printf()-like format of error message + ... - printf()-like arguments + Returns: (does not return) + + This function closes all Curses windows, prints the name of the + program, the supplied error message (using format and following + arguments as if passed to printf()), then the string corresponding to + errno to stderr. It then exits with error code EXIT_FAILURE. + + The format supplied does NOT need to supply the program name, any + colons nor the trailing end-line character. The format may be NULL if + no intermediate message is needed. +*/ extern void errno_exit (const char *format, ...) __attribute__((noreturn, format (printf, 1, 2))); + + +/* + Function: err_exit_nomem - Print an "out of memory" error and exit + Parameters: (none) + Returns: (does not return) + + This function calls err_exit() with an "out of memory" error message. + It simply ensures all memory exhaustion error messages are consistent. +*/ extern void err_exit_nomem (void) __attribute__((noreturn)); -// Random number functions +/************************************************************************ +* Random-number function prototypes * +************************************************************************/ + +/* + Function: init_rand - Initialise the random number generator + Parameters: (none) + Returns: (nothing) + + This function initialises the pseudo-random number generator. It + should be called before any random-number functions declared in this + header are called. +*/ extern void init_rand (void); + + +/* + Function: randf - Return a random number between 0.0 and 1.0 + Parameters: (none) + Returns: double - The random number + + This function returns a pseudo-random number between 0.0 (inclusive) + and 1.0 (not inclusive) as a floating-point number. By default, a + linear congruential algorithm is used to generate the random number. +*/ extern double randf (void); + + +/* + Function: randi - Return a random number between 0 and limit + Parameters: limit - Upper limit of random number + Returns: int - The random number + + This function returns a pseudo-random number between 0 (inclusive) and + limit (not inclusive) as an integer. It uses the same algorithm as + randf() to generate the random number. +*/ extern int randi (int limit); -// Encryption and decryption functions to stop casual cheating! +/************************************************************************ +* Encryption function prototypes * +************************************************************************/ + +/* + The functions described here are simple in the extreme: they are only + designed to stop casual cheating! +*/ + +/* + Function: scramble - Scramble (encrypt) the buffer + Parameters: key - Encryption key + buf - Pointer to buffer to encrypt + bufsize - Size of buffer + Returns: char * - Pointer to buffer + + This function scrambles (encrypts) the buffer *buf using a trivial + in-place encryption algorithm. If key is zero, or buf is NULL or + bufsize is less than 1, no encryption takes place. + + The buffer should contain a C-style string terminated by '\0'. The + characters '\r', '\n' and '\0' are guaranteed to remain the same before + and after encryption. At most bufsize bytes are encrypted; buf is + returned as the result. +*/ extern char *scramble (int key, char *buf, int bufsize); + + +/* + Function: unscramble - Unscramble (decrypt) the buffer + Parameters: key - Encryption/decryption key + buf - Pointer to buffer to decrypt + bufsize - Size of buffer + Returns: char * - Pointer to buffer + + This function does the reverse of scramble(): it unscrambles (decrypts) + the buffer *buf using an in-place algorithm. If key is zero, or buf is + NULL or bufsize is less than 1, no decryption takes place. + + The buffer should contain a C-style string terminated by '\0'. As for + scramble(), the characters '\r', '\n' and '\0' will not be changed (nor + will any encrypted character map back to these values). At most + bufsize bytes are decrypted; buf is returned as the result. +*/ extern char *unscramble (int key, char *buf, int bufsize);