From 5bb48fe35fcbd2f06492b46869279312159b11c7 Mon Sep 17 00:00:00 2001 From: John Zaitseff Date: Sat, 13 Aug 2011 08:50:34 +1000 Subject: [PATCH] Add wrapper functions xmalloc() and xstrdup() to do error handling --- src/exch.c | 15 ++------ src/fileio.c | 44 +++++------------------ src/game.c | 18 +++------- src/intf.c | 99 ++++++++++++---------------------------------------- src/move.c | 14 ++------ src/utils.c | 79 ++++++++++++++++++++++++++++++----------- src/utils.h | 28 +++++++++++++++ 7 files changed, 127 insertions(+), 170 deletions(-) diff --git a/src/exch.c b/src/exch.c index c623e95..5666742 100644 --- a/src/exch.c +++ b/src/exch.c @@ -108,10 +108,7 @@ void exchange_stock (void) if (all_off_map) { center(curwin, 8, attr_normal, "No companies on the map"); } else { - char *buf = malloc(BUFSIZE); - if (buf == NULL) { - err_exit_nomem(); - } + char *buf = xmalloc(BUFSIZE); // Handle the locale's currency symbol snprintf(buf, BUFSIZE, "share (%s)", lconvinfo.currency_symbol); @@ -256,10 +253,7 @@ void visit_bank (void) char *buf; - buf = malloc(BUFSIZE); - if (buf == NULL) { - err_exit_nomem(); - } + buf = xmalloc(BUFSIZE); credit_limit = (total_value(current_player) - player[current_player].debt) * CREDIT_LIMIT_RATE; @@ -470,10 +464,7 @@ void trade_shares (int num, bool *bid_used) assert(num >= 0 && num < MAX_COMPANIES); assert(company[num].on_map); - buf = malloc(BUFSIZE); - if (buf == NULL) { - err_exit_nomem(); - } + buf = xmalloc(BUFSIZE); ownership = (company[num].stock_issued == 0) ? 0.0 : ((double) player[current_player].stock_owned[num] diff --git a/src/fileio.c b/src/fileio.c index bcf41b6..297a4ee 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -107,11 +107,7 @@ static const unsigned char game_file_crypt_key[] = { } \ } \ } else { \ - s = malloc(strlen(buf) + 1); \ - if (s == NULL) { \ - err_exit_nomem(); \ - } \ - strcpy(s, buf); \ + s = xstrdup(buf); \ } \ \ len = strlen(s); \ @@ -137,11 +133,7 @@ static const unsigned char game_file_crypt_key[] = { filename, lineno); \ } \ \ - s = malloc(strlen(buf) + 1); \ - if (s == NULL) { \ - err_exit_nomem(); \ - } \ - strcpy(s, buf); \ + s = xstrdup(buf); \ \ len = strlen(s); \ if (len > 0 && s[len - 1] == '\n') { \ @@ -226,10 +218,7 @@ bool load_game (int num) assert(num >= 1 && num <= 9); - buf = malloc(BUFSIZE); - if (buf == NULL) { - err_exit_nomem(); - } + buf = xmalloc(BUFSIZE); filename = game_filename(num); assert(filename != NULL); @@ -275,29 +264,20 @@ bool load_game (int num) } else { icd = (iconv_t) -1; } - codeset_nl = strdup(GAME_FILE_CHARSET "\n"); - if (codeset_nl == NULL) { - err_exit_nomem(); - } + codeset_nl = xstrdup(GAME_FILE_CHARSET "\n"); #else // ! USE_UTF8_GAME_FILE // Make sure all strings are read in the correct codeset codeset = nl_langinfo(CODESET); if (codeset == NULL) { errno_exit("nl_langinfo(CODESET)"); } - codeset_nl = malloc(strlen(codeset) + 2); - if (codeset_nl == NULL) { - err_exit_nomem(); - } + codeset_nl = xmalloc(strlen(codeset) + 2); strcpy(codeset_nl, codeset); strcat(codeset_nl, "\n"); #endif // ! USE_UTF8_GAME_FILE // Change the formatting of numbers to the POSIX locale for consistency - prev_locale = strdup(setlocale(LC_NUMERIC, NULL)); - if (prev_locale == NULL) { - err_exit_nomem(); - } + prev_locale = xstrdup(setlocale(LC_NUMERIC, NULL)); setlocale(LC_NUMERIC, "C"); // Read the game file header @@ -355,7 +335,7 @@ bool load_game (int num) // Read in company data for (i = 0; i < MAX_COMPANIES; i++) { - company[i].name = strdup(gettext(company_name[i])); + company[i].name = xstrdup(gettext(company_name[i])); load_game_read_double(company[i].share_price, company[i].share_price >= 0.0); load_game_read_double(company[i].share_return, true); load_game_read_long(company[i].stock_issued, company[i].stock_issued >= 0); @@ -432,10 +412,7 @@ bool save_game (int num) assert(num >= 1 && num <= 9); - buf = malloc(BUFSIZE); - if (buf == NULL) { - err_exit_nomem(); - } + buf = xmalloc(BUFSIZE); crypt_key = option_dont_encrypt ? 0 : game_file_crypt_key[randi(GAME_FILE_CRYPT_KEY_SIZE)]; @@ -508,10 +485,7 @@ bool save_game (int num) #endif // ! USE_UTF8_GAME_FILE // Change the formatting of numbers to the POSIX locale for consistency - prev_locale = strdup(setlocale(LC_NUMERIC, NULL)); - if (prev_locale == NULL) { - err_exit_nomem(); - } + prev_locale = xstrdup(setlocale(LC_NUMERIC, NULL)); setlocale(LC_NUMERIC, "C"); // Write out the game file header and encryption key diff --git a/src/game.c b/src/game.c index a56d1c4..41d06f7 100644 --- a/src/game.c +++ b/src/game.c @@ -178,7 +178,7 @@ void init_game (void) // Initialise company data for (i = 0; i < MAX_COMPANIES; i++) { - company[i].name = strdup(gettext(company_name[i])); + company[i].name = xstrdup(gettext(company_name[i])); company[i].share_price = 0.0; company[i].share_return = INITIAL_RETURN; company[i].stock_issued = 0; @@ -489,10 +489,7 @@ void end_game (void) return; } - buf = malloc(BUFSIZE); - if (buf == NULL) { - err_exit_nomem(); - } + buf = xmalloc(BUFSIZE); txdlgbox(MAX_DLG_LINES, 50, 9, WCENTER, attr_error_window, attr_error_title, attr_error_highlight, 0, 0, @@ -577,11 +574,7 @@ void show_map (bool closewin) if (turn_number != max_turn) { const char *initial = "Turn: "; - - char *buf = malloc(BUFSIZE); - if (buf == NULL) { - err_exit_nomem(); - } + char *buf = xmalloc(BUFSIZE); int len1 = strlen(initial); int len2 = snprintf(buf, BUFSIZE, "%d", turn_number); @@ -671,10 +664,7 @@ void show_status (int num) center(curwin, 11, attr_blink, "* * * B A N K R U P T * * *"); } else { - char *buf = malloc(BUFSIZE); - if (buf == NULL) { - err_exit_nomem(); - } + char *buf = xmalloc(BUFSIZE); // Check to see if any companies are on the map bool none = true; diff --git a/src/intf.c b/src/intf.c index d0ef68c..b3e4493 100644 --- a/src/intf.c +++ b/src/intf.c @@ -384,14 +384,9 @@ void init_title (void) addch(attr_game_title | ' '); } - chbuf = malloc(BUFSIZE * sizeof(chtype)); - if (chbuf == NULL) { - err_exit_nomem(); - } - + chbuf = xmalloc(BUFSIZE * sizeof(chtype)); lines = prepstr(chbuf, BUFSIZE, attr_game_title, 0, 0, 1, COLS, &width, 1, _("Star Traders")); - pr_center(stdscr, 0, 0, chbuf, lines, &width); attrset(attr_root_window); free(chbuf); @@ -451,13 +446,9 @@ WINDOW *newtxwin (int nlines, int ncols, int begin_y, int begin_x, err_exit_nomem(); } - nw = malloc(sizeof(txwin_t)); - if (nw == NULL) { - err_exit_nomem(); - } - // Insert the new window into the txwin stack + nw = xmalloc(sizeof(txwin_t)); nw->win = win; nw->next = NULL; nw->prev = topwin; @@ -586,15 +577,8 @@ int txdlgbox (int maxlines, int ncols, int begin_y, int begin_x, assert(maxlines > 0); - chbuf = malloc(BUFSIZE * sizeof(chtype)); - if (chbuf == NULL) { - err_exit_nomem(); - } - - widthbuf = malloc(maxlines * sizeof(int)); - if (widthbuf == NULL) { - err_exit_nomem(); - } + chbuf = xmalloc(BUFSIZE * sizeof(chtype)); + widthbuf = xmalloc(maxlines * sizeof(int)); va_start(args, format); lines = vprepstr(chbuf, BUFSIZE, norm_attr, alt1_attr, alt2_attr, maxlines, @@ -605,15 +589,10 @@ int txdlgbox (int maxlines, int ncols, int begin_y, int begin_x, true, bkgd_attr); if (usetitle) { - chtype *titlebuf; + chtype *titlebuf = xmalloc(BUFSIZE * sizeof(chtype)); int titlewidth; int titlelines; - titlebuf = malloc(BUFSIZE * sizeof(chtype)); - if (titlebuf == NULL) { - err_exit_nomem(); - } - titlelines = prepstr(titlebuf, BUFSIZE, title_attr, 0, 0, 1, ncols - 4, &titlewidth, 1, boxtitle); pr_center(curwin, 1, 0, titlebuf, titlelines, &titlewidth); @@ -995,10 +974,7 @@ int vprepstr (chtype *restrict chbuf, int chbufsize, chtype attr_norm, int count = 0; const char *str; - char *buf = malloc(BUFSIZE); - if (buf == NULL) { - err_exit_nomem(); - } + char *buf = xmalloc(BUFSIZE); while (inspec && *format != '\0') { char c = *format++; @@ -1215,11 +1191,7 @@ chtype *chbufdup (const chtype *restrict chbuf, int chbufsize) for (len = 1, p = chbuf; *p != '\0' && len <= chbufsize; p++, len++) ; - ret = malloc(len * sizeof(chtype)); - if (ret == NULL) { - err_exit_nomem(); - } - + ret = xmalloc(len * sizeof(chtype)); memcpy(ret, chbuf, len * sizeof(chtype)); ret[len - 1] = '\0'; // Terminating NUL, just in case not present @@ -1358,10 +1330,7 @@ int center (WINDOW *win, int y, chtype attr, const char *restrict format, ...) assert(win != NULL); assert(format != NULL); - buf = malloc(BUFSIZE); - if (buf == NULL) { - err_exit_nomem(); - } + buf = xmalloc(BUFSIZE); chtype oldattr = getattrs(win); chtype oldbkgd = getbkgd(win); @@ -1406,10 +1375,7 @@ int center2 (WINDOW *win, int y, chtype attr1, chtype attr2, assert(initial != NULL); assert(format != NULL); - buf = malloc(BUFSIZE); - if (buf == NULL) { - err_exit_nomem(); - } + buf = xmalloc(BUFSIZE); chtype oldattr = getattrs(win); chtype oldbkgd = getbkgd(win); @@ -1460,10 +1426,7 @@ int center3 (WINDOW *win, int y, chtype attr1, chtype attr3, chtype attr2, assert(final != NULL); assert(format != NULL); - buf = malloc(BUFSIZE); - if (buf == NULL) { - err_exit_nomem(); - } + buf = xmalloc(BUFSIZE); chtype oldattr = getattrs(win); chtype oldbkgd = getbkgd(win); @@ -2191,11 +2154,7 @@ int gettxstr (WINDOW *win, char **bufptr, bool *restrict modified, // Allocate the result buffer if needed if (*bufptr == NULL) { - *bufptr = malloc(BUFSIZE); - if (*bufptr == NULL) { - err_exit_nomem(); - } - + *bufptr = xmalloc(BUFSIZE); **bufptr = '\0'; } @@ -2275,16 +2234,11 @@ int gettxdouble (WINDOW *win, double *restrict result, double min, assert(result != NULL); assert(min <= max); - buf = malloc(BUFSIZE); - bufcopy = malloc(BUFSIZE); - allowed = malloc(BUFSIZE); - emptystr = malloc(BUFSIZE); - defaultstr = malloc(BUFSIZE); - - if (buf == NULL || bufcopy == NULL || allowed == NULL - || emptystr == NULL || defaultstr == NULL) { - err_exit_nomem(); - } + buf = xmalloc(BUFSIZE); + bufcopy = xmalloc(BUFSIZE); + allowed = xmalloc(BUFSIZE); + emptystr = xmalloc(BUFSIZE); + defaultstr = xmalloc(BUFSIZE); *buf = '\0'; @@ -2348,16 +2302,11 @@ int gettxlong (WINDOW *win, long int *restrict result, long int min, assert(result != NULL); assert(min <= max); - buf = malloc(BUFSIZE); - bufcopy = malloc(BUFSIZE); - allowed = malloc(BUFSIZE); - emptystr = malloc(BUFSIZE); - defaultstr = malloc(BUFSIZE); - - if (buf == NULL || bufcopy == NULL || allowed == NULL - || emptystr == NULL || defaultstr == NULL) { - err_exit_nomem(); - } + buf = xmalloc(BUFSIZE); + bufcopy = xmalloc(BUFSIZE); + allowed = xmalloc(BUFSIZE); + emptystr = xmalloc(BUFSIZE); + defaultstr = xmalloc(BUFSIZE); *buf = '\0'; @@ -2481,11 +2430,7 @@ void wait_for_key (WINDOW *win, int y, chtype attr) meta(win, true); wtimeout(win, -1); - chbuf = malloc(BUFSIZE * sizeof(chtype)); - if (chbuf == NULL) { - err_exit_nomem(); - } - + chbuf = xmalloc(BUFSIZE * sizeof(chtype)); lines = prepstr(chbuf, BUFSIZE, attr, 0, 0, 1, getmaxx(win) - 4, &width, 1, _("[ Press to continue ] ")); pr_center(win, y, 0, chbuf, lines, &width); diff --git a/src/move.c b/src/move.c index 49f3aa9..98fc17e 100644 --- a/src/move.c +++ b/src/move.c @@ -746,14 +746,9 @@ void merge_companies (map_val_t a, map_val_t b) long int old_stock, new_stock, total_new; int x, y, i, line; double bonus; - char *buf; + char *buf = xmalloc(BUFSIZE); - buf = malloc(BUFSIZE); - if (buf == NULL) { - err_exit_nomem(); - } - if (val_aa < val_bb) { // Make sure aa is the dominant company map_val_t t; @@ -930,12 +925,7 @@ void adjust_values (void) } else { double rate = randf(); - char *buf; - - buf = malloc(BUFSIZE); - if (buf == NULL) { - err_exit_nomem(); - } + char *buf = xmalloc(BUFSIZE); for (i = 0; i < number_players; i++) { if (player[i].in_game) { diff --git a/src/utils.c b/src/utils.c index 9c2ecd1..d106c72 100644 --- a/src/utils.c +++ b/src/utils.c @@ -114,7 +114,7 @@ const char *home_directory (void) char *home = getenv("HOME"); if (home != NULL && *home != '\0') { - home_directory_str = strdup(home); + home_directory_str = xstrdup(home); } } @@ -136,13 +136,12 @@ const char *data_directory (void) const char *home = home_directory(); if (name != NULL && home != NULL) { - char *p = malloc(strlen(home) + strlen(name) + 3); - if (p != NULL) { - strcpy(p, home); - strcat(p, "/."); - strcat(p, name); - data_directory_str = p; - } + char *p = xmalloc(strlen(home) + strlen(name) + 3); + + strcpy(p, home); + strcat(p, "/."); + strcat(p, name); + data_directory_str = p; } } @@ -170,20 +169,13 @@ char *game_filename (int gamenum) 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; + return xstrdup(buf); } else { - char *p = malloc(strlen(dd) + strlen(buf) + 2); + char *p = xmalloc(strlen(dd) + strlen(buf) + 2); - if (p != NULL) { - strcpy(p, dd); - strcat(p, "/"); - strcat(p, buf); - } + strcpy(p, dd); + strcat(p, "/"); + strcat(p, buf); return p; } } @@ -439,5 +431,52 @@ char *unscramble (int key, char *restrict buf, int bufsize) } +/************************************************************************ +* Miscellaneous function definitions * +************************************************************************/ + +// These functions are documented in the file "utils.h" + + +/***********************************************************************/ +// xmalloc: Allocate a new block of memory, with checking + +void *xmalloc (size_t size) +{ + void *p; + + + if (size < 1) + size = 1; + + p = malloc(size); + if (p == NULL) { + err_exit_nomem(); + } + + return p; +} + + +/***********************************************************************/ +// xstrdup: Duplicate a string, with checking + +char *xstrdup (const char *str) +{ + char *s; + + + if (str == NULL) + str = ""; + + s = strdup(str); + if (s == NULL) { + err_exit_nomem(); + } + + return s; +} + + /***********************************************************************/ // End of file diff --git a/src/utils.h b/src/utils.h index 70f717a..4c9aabe 100644 --- a/src/utils.h +++ b/src/utils.h @@ -300,4 +300,32 @@ extern char *scramble (int key, char *restrict buf, int bufsize); extern char *unscramble (int key, char *restrict buf, int bufsize); +/************************************************************************ +* Miscellaneous function prototypes * +************************************************************************/ + +/* + Function: xmalloc - Allocate a new block of memory, with checking + Parameters: size - Size of new block of memory in bytes + Returns: void * - Pointer to new block of memory + + This wrapper function allocates a new block of memory by calling + malloc(), then checks if a NULL pointer has been returned. If so, the + program terminates with an "Out of memory" error. +*/ +extern void *xmalloc (size_t size); + + +/* + Function: xstrdup - Duplicate a string, with checking + Parameters: str - String to duplicate + Returns: char * - Pointer to new string, allocated with malloc() + + This wrapper function duplicates a string by calling strdup(), then + checks if a NULL pointer has been returned. If so, the program + terminates with an "Out of memory" error. +*/ +extern char *xstrdup (const char *str); + + #endif /* included_UTILS_H */