1
0
mirror of https://git.zap.org.au/git/trader.git synced 2024-10-27 18:20:13 -04:00

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.
This commit is contained in:
John Zaitseff 2011-07-19 21:38:27 +10:00
parent c19feab652
commit c3d265a9ff
2 changed files with 266 additions and 182 deletions

View File

@ -10,7 +10,7 @@
$Id$ $Id$
This file, utils.c, contains the implementation of various utility 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 This program is free software: you can redistribute it and/or modify it
@ -28,9 +28,15 @@
*/ */
#include "system.h" #include "trader.h"
#include "utils.h"
#include "intf.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 *
************************************************************************/ ************************************************************************/
/*----------------------------------------------------------------------- // These functions are documented in the file "utils.h"
Function: init_program_name - Make the program name "canonical"
Arguments: argv - Same as passed to main()
Returns: (nothing)
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[]) 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; program_name_str = PACKAGE;
} else { } else {
char *p = strrchr(argv[0], '/'); char *p = strrchr(argv[0], '/');
if ((p != NULL) && (*++p != '\0')) { if (p != NULL && *++p != '\0') {
argv[0] = p; 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) const char *program_name (void)
{ {
if (program_name_str == NULL) { 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) const char *home_directory (void)
{ {
if (home_directory_str == NULL) { if (home_directory_str == NULL) {
// Use the HOME environment variable where possible // Use the HOME environment variable where possible
char *p = getenv("HOME"); char *home = getenv("HOME");
if ((p != NULL) && (*p != '\0')) {
home_directory_str = strdup(p); 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) 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) { if (data_directory_str == NULL) {
const char *name = program_name(); const char *name = program_name();
const char *home = home_directory(); const char *home = home_directory();
if ((name != NULL) && (home != NULL)) {
if (name != NULL && home != NULL) {
char *p = malloc(strlen(home) + strlen(name) + 3); char *p = malloc(strlen(home) + strlen(name) + 3);
if (p != NULL) { if (p != NULL) {
strcpy(p, home); strcpy(p, home);
@ -150,38 +125,33 @@ const char *data_directory (void)
} }
/*----------------------------------------------------------------------- /***********************************************************************/
Function: game_filename - Convert an integer to a game filename char *game_filename (int gamenum)
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)
{ {
/* This implementation assumes a POSIX environment by using "/" as
the directory separator */
char buf[GAME_FILENAME_BUFSIZE]; // Buffer for part of filename char buf[GAME_FILENAME_BUFSIZE]; // Buffer for part of filename
const char *dd; // Data directory const char *dd; // Data directory
if ((game_num < 1) || (game_num > 9)) { if (gamenum < 1 || gamenum > 9) {
return NULL; return NULL;
} }
dd = data_directory(); 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) { if (dd == NULL) {
char *p = malloc(strlen(buf) + 1); char *p = malloc(strlen(buf) + 1);
if (p != NULL) { if (p != NULL) {
strcpy(p, buf); strcpy(p, buf);
} }
return p; return p;
} else { } else {
char *p = malloc(strlen(dd) + strlen(buf) + 2); char *p = malloc(strlen(dd) + strlen(buf) + 2);
if (p != NULL) { if (p != NULL) {
strcpy(p, dd); strcpy(p, dd);
strcat(p, "/"); strcat(p, "/");
@ -192,22 +162,14 @@ char *game_filename (const int game_num)
} }
/*----------------------------------------------------------------------- /************************************************************************
Function: err_exit - Print an error and exit * Error-reporting function definitions *
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 // These functions are documented in the file "utils.h"
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.
*/
/***********************************************************************/
void err_exit (const char *format, ...) void err_exit (const char *format, ...)
{ {
va_list args; 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, ...) void errno_exit (const char *format, ...)
{ {
va_list args; 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) void err_exit_nomem (void)
{ {
err_exit("out of memory"); err_exit("out of memory");
} }
/*----------------------------------------------------------------------- /************************************************************************
Function: init_rand - Initialise the random number generator * Random-number function definitions *
Arguments: (none) ************************************************************************/
Returns: (nothing)
This function initialises the pseudo-random number generator. // These functions are documented in the file "utils.h"
*/
/***********************************************************************/
void init_rand (void) 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 time_t curtime = time(NULL); // NB: time_t may be larger than long int
srand48((long int) curtime); 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) extern double randf (void)
{ {
return drand48(); 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) 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) 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; char *p = buf;
unsigned char k = ~key; unsigned char k = ~key;
int i; 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 c = *p;
char r = c ^ k; // Simple encryption: XOR on a moving key char r = c ^ k; // Simple encryption: XOR on a moving key
if ((c != '\r') && (c != '\n') && if (c != '\r' && c != '\n'
(r != '\r') && (r != '\n') && (r != '\0')) { && r != '\r' && r != '\n' && r != '\0') {
*p = r; *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) char *unscramble (int key, char *buf, int bufsize)
{ {
return scramble(key, buf, bufsize); return scramble(key, buf, bufsize);
} }
/***********************************************************************/
// End of file

View File

@ -9,8 +9,8 @@
Author: John Zaitseff <J.Zaitseff@zap.org.au> Author: John Zaitseff <J.Zaitseff@zap.org.au>
$Id$ $Id$
This file, utils.h, contains various utility function declarations for This file, utils.h, contains declarations for various utility functions
Star Traders. used in Star Traders.
This program is free software: you can redistribute it and/or modify it This program is free software: you can redistribute it and/or modify it
@ -32,14 +32,6 @@
#define included_UTILS_H 1 #define included_UTILS_H 1
/************************************************************************
* Constants and type declarations *
************************************************************************/
#define GAME_FILENAME_PROTO "game%d"
#define GAME_FILENAME_BUFSIZE 16
/************************************************************************ /************************************************************************
* Utility macro definitions * * 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[]); 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); 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); 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 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
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, ...) extern void err_exit (const char *format, ...)
__attribute__((noreturn, format (printf, 1, 2))); __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, ...) extern void errno_exit (const char *format, ...)
__attribute__((noreturn, format (printf, 1, 2))); __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) extern void err_exit_nomem (void)
__attribute__((noreturn)); __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); 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); 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); 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); 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); extern char *unscramble (int key, char *buf, int bufsize);