From: Christian Heller Date: Thu, 5 Sep 2013 04:08:48 +0000 (+0200) Subject: Heavy refactoring of all file I/O and some memory handling; also repaired some incons... X-Git-Tag: tce~975 X-Git-Url: https://plomlompom.com/repos/%7B%7B%20web_path%20%7D%7D/decks/%7B%7Bdb.prefix%7D%7D/static/blog?a=commitdiff_plain;h=ec5c4edd169be8fe8c778cabdfc7ada665629ffd;p=plomrogue Heavy refactoring of all file I/O and some memory handling; also repaired some inconsistencies via the resulting standardizations. --- diff --git a/config/windows/Win_i b/config/windows/Win_i index 948c2ec..9751da9 100644 --- a/config/windows/Win_i +++ b/config/windows/Win_i @@ -1,3 +1,3 @@ Info 3 -12 +33 diff --git a/config/windows/Win_k b/config/windows/Win_k index 67c674e..a719bf3 100644 --- a/config/windows/Win_k +++ b/config/windows/Win_k @@ -1,3 +1,3 @@ Keys 0 -42 +29 diff --git a/config/windows/Win_l b/config/windows/Win_l index 023229d..d31eb53 100644 --- a/config/windows/Win_l +++ b/config/windows/Win_l @@ -1,3 +1,3 @@ Log -4 -12 +33 diff --git a/config/windows/Win_m b/config/windows/Win_m index cd42830..ef4cd11 100644 --- a/config/windows/Win_m +++ b/config/windows/Win_m @@ -1,3 +1,3 @@ Map 0 --56 +-64 diff --git a/config/windows/toggle_order b/config/windows/toggle_order index e45bc97..0b431e9 100644 --- a/config/windows/toggle_order +++ b/config/windows/toggle_order @@ -1,2 +1 @@ kmil - \ No newline at end of file diff --git a/src/command_db.c b/src/command_db.c index 61ae4b1..0bf7c84 100644 --- a/src/command_db.c +++ b/src/command_db.c @@ -1,25 +1,24 @@ /* command.c */ #include "command_db.h" -#include /* for malloc() */ -#include /* for FILE typedef, fopen(), fclose(), fgets() */ +#include /* for free() */ +#include /* for FILE typedef, fgets() */ #include /* for uint8_t */ #include /* for strlen(), strtok() */ #include "main.h" /* for World struct */ #include "rexit.h" /* for exit_err() */ -#include "readwrite.h" /* for textfile_sizes() */ +#include "readwrite.h" /* for textfile_sizes(), try_fopen(), try_fclose() */ +#include "misc.h" /* for try_malloc() */ -/* Build string pointed to by "ch_ptr" from next token delimited by "delim", - * exit_err() with "err" as error message on malloc() failure. - */ -static void copy_tokenized_string(struct World * world, - char ** ch_ptr, char * delim, char * err) +/* Build string pointed to by "ch_ptr" from next token delimited by "delim". */ +static void copy_tokenized_string(struct World * world, char ** ch_ptr, + char * delim) { + char * f_name = "copy_tokenized_string()"; char * dsc_ptr = strtok(NULL, delim); - * ch_ptr = malloc(strlen(dsc_ptr) + 1); - exit_err(NULL == * ch_ptr, world, err); + * ch_ptr = try_malloc(strlen(dsc_ptr) + 1, world, f_name); memcpy(* ch_ptr, dsc_ptr, strlen(dsc_ptr) + 1); } @@ -77,31 +76,28 @@ extern char * get_command_longdsc(struct World * world, char * dsc_short) extern void init_command_db(struct World * world) { - char * err_o = "Trouble in init_cmds() with fopen() on file 'commands'."; + char * f_name = "init_command_db()"; char * err_s = "Trouble in init_cmds() with textfile_sizes()."; - char * err_m = "Trouble in init_cmds() with malloc()."; - char * err_c = "Trouble in init_cmds() with fclose() on file 'commands'."; char * path = "config/commands"; - FILE * file = fopen(path, "r"); - exit_err(NULL == file, world, err_o); + FILE * file = try_fopen(path, "r", world, f_name); uint16_t lines, linemax; exit_err(textfile_sizes(file, &linemax, &lines), world, err_s); char line[linemax + 1]; - struct Command * cmds = malloc(lines * sizeof(struct Command)); - exit_err(NULL == line, world, err_m); + struct Command * cmds = try_malloc(lines * sizeof(struct Command), + world, f_name); uint8_t i = 0; while (fgets(line, linemax + 1, file)) { cmds[i].id = atoi(strtok(line, " ")); - copy_tokenized_string(world, &cmds[i].dsc_short, " ", err_m); - copy_tokenized_string(world, &cmds[i].dsc_long, "\n", err_m); + copy_tokenized_string(world, &cmds[i].dsc_short, " "); + copy_tokenized_string(world, &cmds[i].dsc_long, "\n"); i++; } - exit_err(fclose(file), world, err_c); + try_fclose(file, world, f_name); - world->cmd_db = malloc(sizeof(struct CommandDB)); + world->cmd_db = try_malloc(sizeof(struct CommandDB), world, f_name); world->cmd_db->cmds = cmds; world->cmd_db->n = lines; } diff --git a/src/draw_wins.c b/src/draw_wins.c index b036d12..5d395f6 100644 --- a/src/draw_wins.c +++ b/src/draw_wins.c @@ -1,7 +1,7 @@ /* draw_wins.c */ #include "draw_wins.h" -#include /* for malloc(), free() */ +#include /* for free() */ #include /* for uint16_t */ #include /* for strlen() */ #include /* for mvwaddch() */ @@ -214,13 +214,12 @@ extern void draw_info_win(struct Win * win) char * dsc_score = "\nScore: "; uint16_t maxl = strlen(dsc_turn) + strlen(dsc_hitpoints) + strlen(dsc_score) + 10 + 5 + 10; /* max strlens of numbers to be used */ - char * text = malloc(maxl + 1); + char text[maxl + 1]; sprintf(text, "%s%d%s%d%s%d", dsc_turn, world->turn, dsc_hitpoints, world->player->hitpoints, dsc_score, world->score); draw_with_linebreaks(win, text, 0); - free(text); } @@ -232,7 +231,8 @@ extern void draw_keys_win(struct Win * win) offset = center_offset(world->keyswindata->select, world->keyswindata->max, win->frame.size.y - 1); uint8_t keydescwidth = 9 + 1; /* max length assured by get_keyname() + \0 */ - char * keydesc = malloc(keydescwidth), * keyname; + char keydesc[keydescwidth]; + char * keyname; char * err_hint = "Trouble with draw_scroll_hint() in draw_keys_win()."; attr_t attri; char * cmd_dsc; @@ -263,7 +263,7 @@ extern void draw_keys_win(struct Win * win) attri = attri | A_BLINK; } } - keyname = get_keyname(world->keybindings[y + offset].key); + keyname = get_keyname(world, world->keybindings[y + offset].key); snprintf(keydesc, keydescwidth, "%-9s", keyname); free(keyname); cmd_dsc = get_command_longdsc(world, @@ -286,7 +286,6 @@ extern void draw_keys_win(struct Win * win) } } } - free(keydesc); } @@ -317,9 +316,8 @@ extern void draw_winconf(struct Win * win) uint16_t maxl = strlen(title) + strlen(h_t_d) + strlen(h_t) + strlen(h_d) + 6 + strlen(w_t_d) + strlen(w_t) + strlen(w_d) + 6 + 1; - char * text = malloc(maxl + 1); + char text[maxl + 1]; sprintf(text, "%s%s%s%s%d%s%s%s%d", title, h_t_d, h_t, h_d, wcp->height, w_t_d, w_t, w_d, wcp->width); draw_with_linebreaks(win, text, 0); - free(text); } diff --git a/src/keybindings.c b/src/keybindings.c index 75fe728..92e4d6d 100644 --- a/src/keybindings.c +++ b/src/keybindings.c @@ -1,41 +1,46 @@ /* keybindings.c */ - - #include "keybindings.h" -#include /* for malloc(), free(), atoi() */ +#include /* for FILE typedef*/ +#include /* for free(), atoi() */ #include /* for uint16_t */ #include /* for keycode defines in get_keyname() */ #include /* for strchr(), strlen(), strcmp(), memcpy()*/ #include "windows.h" /* for draw_all_wins() and WinMeta struct */ -#include "readwrite.h" /* for texfile_sizes() */ +#include "readwrite.h" /* for texfile_sizes(), try_fopen(), try_fclose() + * try_fclose_unlink_rename() + */ #include "main.h" /* for World struct */ #include "rexit.h" /* for err_exit() */ +#include "misc.h" /* for try_malloc() */ extern void init_keybindings(struct World * world) { - FILE * file = fopen("config/keybindings", "r"); + char * f_name = "init_keybindings()"; + char * path = "config/keybindings"; + FILE * file = try_fopen(path, "r", world, f_name); uint16_t lines, linemax; char * err = "textfile_sizes() in init_keybindings() returns error."; exit_err(textfile_sizes(file, &linemax, &lines), world, err); - struct KeyBinding * keybindings = malloc(lines * sizeof(struct KeyBinding)); - char * command = malloc(linemax + 1); + struct KeyBinding * keybindings; + keybindings = try_malloc(lines * sizeof(struct KeyBinding), world, f_name); + char command[linemax + 1]; uint16_t commcount = 0; char * cmdptr; while (fgets(command, linemax + 1, file)) { keybindings[commcount].key = atoi(command); cmdptr = strchr(command, ' ') + 1; - keybindings[commcount].name = malloc(strlen(cmdptr)); + keybindings[commcount].name = try_malloc(strlen(cmdptr), world, f_name); memcpy(keybindings[commcount].name, cmdptr, strlen(cmdptr) - 1); keybindings[commcount].name[strlen(cmdptr) - 1] = '\0'; commcount++; } - free(command); - fclose(file); - struct KeysWinData * keyswindata = malloc(sizeof(struct KeysWinData)); + try_fclose(file, world, f_name); + struct KeysWinData * keyswindata; + keyswindata = try_malloc(sizeof(struct KeysWinData), world, f_name); keyswindata->max = lines - 1; keyswindata->select = 0; keyswindata->edit = 0; @@ -47,10 +52,13 @@ extern void init_keybindings(struct World * world) extern void save_keybindings(struct World * world) { + char * f_name = "save_keybindings()"; struct KeysWinData * keyswindata = (struct KeysWinData *) world->keyswindata; struct KeyBinding * keybindings = world->keybindings; - FILE * file = fopen("config/keybindings", "w"); + char * path = "config/keybindings"; + char * path_tmp = "config/keybindings_tmp"; + FILE * file = try_fopen(path_tmp, "w", world, f_name); uint16_t linemax = 0; uint16_t i; for (i = 0; i <= keyswindata->max; i++) @@ -61,15 +69,14 @@ extern void save_keybindings(struct World * world) } } linemax = linemax + 6; /* + 6 = + 3 digits + whitespace + \n + \0 */ - char * line = malloc(linemax); + char line[linemax]; for (i = 0; i <= keyswindata->max; i++) { snprintf(line, linemax, "%d %s\n", keybindings[i].key, keybindings[i].name); fwrite(line, sizeof(char), strlen(line), file); } - free(line); - fclose(file); + try_fclose_unlink_rename(file, path_tmp, path, world, f_name); } @@ -86,10 +93,10 @@ extern uint16_t get_action_key(struct KeyBinding * keybindings, char * name) -extern char * get_keyname(uint16_t keycode) +extern char * get_keyname(struct World * world, uint16_t keycode) { - char * keyname; - keyname = malloc(15); + char * f_name = "get_keyname()"; + char * keyname = try_malloc(15, world, f_name); if (32 < keycode && keycode < 127) { sprintf(keyname, "%c", keycode); diff --git a/src/keybindings.h b/src/keybindings.h index 085de9a..e0fdadb 100644 --- a/src/keybindings.h +++ b/src/keybindings.h @@ -45,7 +45,7 @@ extern uint16_t get_action_key(struct KeyBinding * keybindings, char * name); /* Translate keycode to readable names of max 9 chars where possible. */ -extern char * get_keyname(uint16_t keycode); +extern char * get_keyname(struct World * world, uint16_t keycode); diff --git a/src/main.c b/src/main.c index fcf677e..0cdcaf1 100644 --- a/src/main.c +++ b/src/main.c @@ -1,13 +1,12 @@ /* main.c */ #include "main.h" -#include /* for atoi(), exit(), EXIT_FAILURE, calloc() */ -#include /* for FILE typedef, F_OK, rename() */ +#include /* for atoi(), exit(), EXIT_FAILURE */ +#include /* for FILE typedef, F_OK */ #include /* for initscr(), noecho(), curs_set(), keypad(), raw() */ #include /* for time() */ #include /* for getopt(), optarg */ #include /* for uint16_t, uint32_t */ -#include /* for errno */ #include "windows.h" /* for structs WinMeta, Win, init_win(), init_win_meta(), * draw_all_wins() */ @@ -15,18 +14,22 @@ * draw_log_win() */ #include "keybindings.h" /* for init_keybindings(), get_action_key() */ -#include "readwrite.h" /* for [read/write]_uint[8/16/32][_bigendian]() */ +#include "readwrite.h" /* for [read/write]_uint[8/16/32][_bigendian](), + * try_fopen(), try_fclose(), try_fclose_unlink_renmae() + */ #include "map_objects.h" /* for structs Monster, Item, Player, * init_map_object_defs(), read_map_objects(), * build_map_objects() */ #include "map.h" /* for struct Map, init_map() */ -#include "misc.h" /* for update_log(), find_passable_pos(), save_game() */ +#include "misc.h" /* for update_log(), find_passable_pos(), save_game(), + * try_calloc(), check_tempfile(), check_xor_files() + */ #include "wincontrol.h" /* for create_winconfs(), init_winconfs(), init_wins(), * sorted_wintoggle() */ #include "rrand.h" /* for rrand(), rrand_seed() */ -#include "rexit.h" /* for exit_game() */ +#include "rexit.h" /* for exit_game(), exit_err() */ #include "control.h" /* for meta_control() */ #include "command_db.h" /* for init_command_db() */ @@ -34,6 +37,7 @@ int main(int argc, char *argv[]) { + char * f_name = "main()"; struct World world; world.turn = 0; /* Turns to 1 when map and objects are initalized. */ @@ -45,30 +49,14 @@ int main(int argc, char *argv[]) char * savefile = "savefile"; char * recordfile_tmp = "record_tmp"; char * savefile_tmp = "savefile_tmp"; - char * err_x = "A file 'record' exists, but no 'savefile'. If everything " - "was in order, both or none would exist. I won't start " - "until this is corrected."; - if (!access(recordfile, F_OK) && access(savefile, F_OK)) - { - errno = 0; - exit_err(1, &world, err_x); - } - err_x = "A 'savefile' exists, but no file 'record'. If everything " - "was in order, both or none would exist. I won't start " - "until this is corrected."; - if (!access(savefile, F_OK) && access(recordfile, F_OK)) - { - errno = 0; - exit_err(1, &world, err_x); - } - err_x = "A file 'recordfile_tmp' exists, probably from a corrupted " - "previous record saving process. To avoid game record " - "corruption, I won't start until it is removed or renamed."; - exit_err(!access(recordfile_tmp, F_OK), &world, err_x); - err_x = "A file 'savefile_tmp' exists, probably from a corrupted " - "previous game saving process. To avoid savegame " - "corruption, I won't start until it is removed or renamed."; - exit_err(!access(savefile_tmp, F_OK), &world, err_x); + check_files_xor(savefile, recordfile, &world); + check_tempfile(recordfile_tmp, &world); + check_tempfile(savefile_tmp, &world); + check_tempfile("config/windows/Win_tmp_k", &world); + check_tempfile("config/windows/Win_tmp_m", &world); + check_tempfile("config/windows/Win_tmp_i", &world); + check_tempfile("config/windows/Win_tmp_l", &world); + check_tempfile("config/windows/toggle_order_tmp", &world); /* Read in startup options (i.e. replay option and replay start turn). */ int opt; @@ -97,7 +85,7 @@ int main(int argc, char *argv[]) /* Initialize log, player, monster/item definitions and monsters/items. */ world.score = 0; - world.log = calloc(1, sizeof(char)); + world.log = try_calloc(1, sizeof(char), &world, f_name); set_cleanup_flag(CLEANUP_LOG); update_log(&world, " "); struct Player player; @@ -109,17 +97,12 @@ int main(int argc, char *argv[]) set_cleanup_flag(CLEANUP_MAP_OBJECT_DEFS); /* For interactive mode, try to load world state from savefile. */ - char * err_o = "Trouble loading game (fopen() in main()) / " - "opening 'savefile' for reading."; char * err_r = "Trouble loading game (in main()) / " "reading from opened 'savefile'."; - char * err_c = "Trouble loading game (fclose() in main()) / " - "closing opened 'savefile'."; FILE * file; if (1 == world.interactive && 0 == access(savefile, F_OK)) { - file = fopen(savefile, "r"); - exit_err(0 == file, &world, err_o); + file = try_fopen(savefile, "r", &world, f_name); if ( read_uint32_bigendian(file, &world.seed) || read_uint32_bigendian(file, &world.turn) || read_uint16_bigendian(file, &world.score) @@ -132,7 +115,7 @@ int main(int argc, char *argv[]) exit_err(1, &world, err_r); } set_cleanup_flag(CLEANUP_MAP_OBJECTS); - exit_err(fclose(file), &world, err_c); + try_fclose(file, &world, f_name); player.pos.y--; player.pos.x--; } @@ -140,14 +123,11 @@ int main(int argc, char *argv[]) /* For non-interactive mode, try to load world state from record file. */ else { - err_o = "Trouble loading record file (fopen() in main()) / " - "opening file 'record' for reading."; - err_r = "Trouble loading record file (read_uint32_bigendian() in " - "main()) / reading from opened file 'record'."; + err_r = "Trouble reading from 'record' file (read_uint32_bigendian() in " + "main())."; if (0 == world.interactive) { - file = fopen(recordfile, "r"); - exit_err(NULL == file, &world, err_o); + file = try_fopen(recordfile, "r", &world, f_name); exit_err(read_uint32_bigendian(file, &world.seed), &world, err_r); } @@ -158,20 +138,13 @@ int main(int argc, char *argv[]) { world.seed = time(NULL); - err_o = "Trouble recording new seed (fopen() in main()) / " - "opening 'record_tmp' file for writing."; char * err_w = "Trouble recording new seed " "(write_uint32_bigendian() in main()) / writing to " - "opened file 'record_tmp'."; - err_c = "Trouble recording new seed (fclose() in main()) / " - "closing opened file 'record_tmp'."; - char * err_m = "Trouble recording new seed (rename() in main()) : " - "renaming file 'record_tmp' to 'record'."; - file = fopen(recordfile_tmp, "w"); - exit_err(0 == file, &world, err_o); + "file 'record_tmp'."; + file = try_fopen(recordfile_tmp, "w", &world, f_name); exit_err(write_uint32_bigendian(world.seed, file), &world, err_w); - exit_err(fclose(file), &world, err_c); - exit_err(rename(recordfile_tmp, recordfile), &world, err_m); + try_fclose_unlink_rename(file, recordfile_tmp, recordfile, + &world, f_name); } } @@ -207,7 +180,6 @@ int main(int argc, char *argv[]) char * err_winmem = "Trouble with init_win_meta() in main ()."; exit_err(init_win_meta(screen, &world.wmeta), &world, err_winmem); set_cleanup_flag(CLEANUP_WIN_META); - // create_winconfs(&world); init_winconfs(&world); set_cleanup_flag(CLEANUP_WINCONFS); init_wins(&world); @@ -247,8 +219,7 @@ int main(int argc, char *argv[]) } else if (meta_control(key, &world)) { - err_c = "Trouble closing 'record' file (fclose() in main())."; - exit_err(fclose(file), &world, err_c); + try_fclose(file, &world, f_name); exit_game(&world); } } diff --git a/src/map.c b/src/map.c index a975043..94def76 100644 --- a/src/map.c +++ b/src/map.c @@ -1,22 +1,23 @@ #include "map.h" -#include /* for malloc() */ #include /* for uint16_t, uint32_t */ -#include "misc.h" /* for center_offset() */ +#include "misc.h" /* for try_malloc(), center_offset() */ #include "map_objects.h" /* for Player struct */ #include "yx_uint16.h" /* for yx_uint16 and dir enums */ #include "rrand.h" /* for rrand() */ +struct World; -struct Map init_map () +struct Map init_map(struct World * world) { + char * f_name = "init_map()"; struct Map map; map.size.x = 64; map.size.y = 64; map.offset.x = 0; map.offset.y = 0; uint32_t size = map.size.x * map.size.y; - map.cells = malloc(size); + map.cells = try_malloc(size, world, f_name); uint16_t y, x; for (y = 0; y < map.size.y; y++) { diff --git a/src/map_object_actions.c b/src/map_object_actions.c index 97f33d6..1b14339 100644 --- a/src/map_object_actions.c +++ b/src/map_object_actions.c @@ -1,10 +1,10 @@ /* map_object_actions.c */ #include "map_object_actions.h" -#include /* for malloc(), calloc(), free() */ +#include /* for free() */ #include /* for strlen() */ #include "yx_uint16.h" /* for yx_uint16 struct, mv_yx_in_dir(), yx_uint16_cmp */ -#include "misc.h" /* for update_log(), turn_over()*/ +#include "misc.h" /* for update_log(), turn_over(), try_malloc() */ #include "map.h" /* for Map struct */ #include "main.h" /* for World struct */ #include "map_objects.h" /* for map object (definition) structs */ @@ -41,11 +41,9 @@ static void monster_bumps_monster(struct World * world, char * dsc_monster1, { char * bump_dsc = " bumps into "; struct MapObjDef * mod = get_map_obj_def(world, monster2->map_obj.type); - char * msg = malloc(strlen(dsc_monster1) + strlen(bump_dsc) - + strlen(mod->desc) + 3); + char msg[strlen(dsc_monster1) + strlen(bump_dsc) + strlen(mod->desc) + 3]; sprintf(msg, "\n%s%s%s.", dsc_monster1, bump_dsc, mod->desc); update_log(world, msg); - free(msg); } @@ -53,10 +51,9 @@ static void monster_bumps_monster(struct World * world, char * dsc_monster1, static void monster_hits_player(struct World * world, char * dsc_monster) { char * hit_dsc = " hits you"; - char * msg = malloc(strlen(dsc_monster) + strlen(hit_dsc) + 3); + char msg[strlen(dsc_monster) + strlen(hit_dsc) + 3]; sprintf(msg, "\n%s%s.", dsc_monster, hit_dsc); update_log(world, msg); - free(msg); world->player->hitpoints--; if (0 == world->player->hitpoints) { @@ -68,23 +65,22 @@ static void monster_hits_player(struct World * world, char * dsc_monster) static void player_hits_monster(struct World * world, struct Monster * monster) { + char * f_name = "player_hits_monster()"; struct MapObjDef * mod = get_map_obj_def(world, monster->map_obj.type); char * hit_dsc = "You hit the "; char * monster_dsc = mod->desc; - char * msg = malloc(strlen(hit_dsc) + strlen(monster_dsc) + 3); - sprintf(msg, "\n%s%s.", hit_dsc, monster_dsc); - update_log(world, msg); - free(msg); + char hitmsg[strlen(hit_dsc) + strlen(monster_dsc) + 3]; + sprintf(hitmsg, "\n%s%s.", hit_dsc, monster_dsc); + update_log(world, hitmsg); monster->hitpoints--; if (0 == monster->hitpoints) { hit_dsc = "You kill the "; - msg = malloc(strlen(hit_dsc) + strlen(monster_dsc) + 3); - sprintf(msg, "\n%s%s.", hit_dsc, monster_dsc); - update_log(world, msg); - free(msg); + char kill_msg[strlen(hit_dsc) + strlen(monster_dsc) + 3]; + sprintf(kill_msg, "\n%s%s.", hit_dsc, monster_dsc); + update_log(world, kill_msg); struct MonsterDef * md = (struct MonsterDef * ) mod; - struct Item * corpse = malloc(sizeof(struct Item)); + struct Item * corpse = try_malloc(sizeof(struct Item), world, f_name); corpse->map_obj.type = md->corpse_id; corpse->map_obj.pos = monster->map_obj.pos; corpse->map_obj.next = world->item; @@ -137,10 +133,9 @@ static void try_player_move(struct World * world, dsc_move = "You move "; world->player->pos = target; } - char * msg = malloc(strlen(dsc_move) + strlen (dsc_dir) + 3); + char msg[strlen(dsc_move) + strlen (dsc_dir) + 3]; sprintf(msg, "\n%s%s.", dsc_move, dsc_dir); update_log(world, msg); - free(msg); } @@ -183,7 +178,7 @@ extern void move_player(struct World * world, enum dir d) { char * action_dsc_prototype = "player_"; uint8_t len = strlen(action_dsc_prototype); - char * action_dsc = malloc(len + 2); + char action_dsc[len + 2]; memcpy(action_dsc, action_dsc_prototype, len); if (NORTH == d) { diff --git a/src/map_objects.c b/src/map_objects.c index 2edb31d..8d08ae0 100644 --- a/src/map_objects.c +++ b/src/map_objects.c @@ -1,14 +1,14 @@ /* map_objects.c */ #include "map_objects.h" -#include /* for malloc(), calloc(), free(), atoi() */ +#include /* for free(), atoi() */ #include /* for uint8_t */ #include /* for FILE typedef */ #include /* for strchr(), strlen(), memcpy(), strtok() */ -#include "readwrite.h" /* for textfile_sizes(), +#include "readwrite.h" /* for get_linemax(), try_fopen(), try_fclose() * [read/write]_uint[8/16/23][_bigendian]() */ -#include "misc.h" /* for find_passable_pos() */ +#include "misc.h" /* for try_malloc(), try_calloc(), find_passable_pos() */ #include "main.h" /* for World struct */ #include "rexit.h" /* for err_exit() */ @@ -16,10 +16,9 @@ /* Return pointer to newly allocated map object struct of size "size". If first * in map object chain ("first" pointing to !0), point "start" to it. - * - * Returns NULL instead of MapObj pointer if malloc() failed. */ -static struct MapObj * get_next_map_obj(void * start, char * first, +static struct MapObj * get_next_map_obj(struct World * world, + void * start, char * first, size_t size, struct MapObj * map_obj); @@ -34,19 +33,21 @@ static uint8_t read_map_objects_monsterdata( void * start, FILE * file); -static struct MapObj * get_next_map_obj(void * start, char * first, +static struct MapObj * get_next_map_obj(struct World * world, + void * start, char * first, size_t size, struct MapObj * map_obj) { + char * f_name = "get_next_map_obj()"; if (* first) { struct MapObj * * z = start; - map_obj = malloc(size); + map_obj = try_malloc(size, world, f_name); * z = map_obj; * first = 0; } else { - map_obj->next = malloc(size); + map_obj->next = try_malloc(size, world, f_name); map_obj = map_obj->next; } return map_obj; @@ -92,16 +93,9 @@ static uint8_t read_map_objects_monsterdata (void * start, FILE * file) extern void init_map_object_defs(struct World * world, char * filename) { - char * err_o = "Trouble in init_map_object_defs() with fopen()."; - char * err_s = "Trouble in init_map_object_defs() with textfile_sizes()."; - char * err_m = "Trouble in init_map_object_defs() with malloc()/calloc()."; - char * err_c = "Trouble in init_map_object_defs() with fclose()."; - - FILE * file = fopen(filename, "r"); - exit_err(NULL == file, world, err_o); - uint16_t linemax; - exit_err(textfile_sizes(file, &linemax, NULL), world, err_s); - + char * f_name = "init_map_object_defs()"; + FILE * file = try_fopen(filename, "r", world, f_name); + uint16_t linemax = get_linemax(file, world, f_name); struct MapObjDef mod; struct ItemDef id; struct MonsterDef md; @@ -128,28 +122,24 @@ extern void init_map_object_defs(struct World * world, char * filename) md.hitpoints_start = atoi(strtok(NULL, delim)); line_p = strtok(NULL, delim); } - mod.desc = calloc(strlen(line_p), sizeof(char)); - exit_err(NULL == mod.desc, world, err_m); + mod.desc = try_calloc(strlen(line_p), sizeof(char), world, f_name); memcpy(mod.desc, line_p, strlen(line_p) - 1); if ('i' == mod.m_or_i) { id.map_obj_def = mod; - * p_p_id = malloc(sizeof(struct ItemDef)); - exit_err(NULL == p_p_id, world, err_m); + * p_p_id = try_malloc(sizeof(struct ItemDef), world, f_name); * * p_p_id = id; p_p_id = (struct ItemDef * *) * p_p_id; } else { md.map_obj_def = mod; - * p_p_md = malloc(sizeof(struct MonsterDef)); - exit_err(NULL == p_p_md, world, err_m); + * p_p_md = try_malloc(sizeof(struct MonsterDef), world, f_name); * * p_p_md = md; p_p_md = (struct MonsterDef * *) * p_p_md; } } - - exit_err(fclose(file), world, err_c); + try_fclose(file, world, f_name); } @@ -241,7 +231,7 @@ extern uint8_t read_map_objects(struct World * world, void * start, FILE * file) { size = sizeof(struct Item); } - map_obj = get_next_map_obj(start, &first, size, map_obj); + map_obj = get_next_map_obj(world, start, &first, size, map_obj); exit_err(NULL == map_obj, world, err); map_obj->type = type; if ( read_uint16_bigendian(file, &map_obj->pos.y) @@ -287,7 +277,7 @@ extern void * build_map_objects(struct World * world, void * start, char def_id, } for (i = 0; i < n; i++) { - mo = get_next_map_obj(start, &first, size, mo); + mo = get_next_map_obj(world, start, &first, size, mo); exit_err(NULL == mo, world, err); mo->pos = find_passable_pos(world->map); if ('i' == mod->m_or_i) diff --git a/src/misc.c b/src/misc.c index 4632a0b..50fee64 100644 --- a/src/misc.c +++ b/src/misc.c @@ -1,12 +1,14 @@ /* misc.c */ #include "misc.h" -#include /* for rename() */ +#include /* for errno */ #include /* for unlink(), acess() */ -#include /* for calloc(), free() */ +#include /* for size_t, calloc(), free() */ #include /* for strlen(), strcmp(), memcpy() */ #include /* for uint8_t, uint16_t */ -#include "readwrite.h" /* for [read/write]_uint[8/16/32][_bigendian]() */ +#include "readwrite.h" /* for [read/write]_uint[8/16/32][_bigendian](), + * try_fopen(), try_fclose() + */ #include "map_objects.h" /* for struct Monster, write_map_objects(), */ #include "map_object_actions.h" /* for is_passable(), move_monster() */ #include "map.h" /* for Map struct */ @@ -17,19 +19,96 @@ +extern char * trouble_msg(struct World * w, char * parent, char * child) +{ + char * p1 = "Trouble in "; + char * p2 = " with "; + char * p3 = "."; + uint16_t size = strlen(p1) + strlen(parent) + strlen(p2) + strlen(child) + + strlen(p3) + 1; + char * msg = malloc(size); + exit_err(NULL == msg, w, "malloc() in trouble_msg() failed."); + sprintf(msg, "%s%s%s%s%s", p1, parent, p2, child, p3); + return msg; +} + + + +extern void * try_malloc(size_t size, struct World * w, char * f) +{ + char * msg = trouble_msg(w, f, "malloc()"); + void * p = malloc(size); + exit_err(NULL == p, w, msg); + free(msg); + return p; +} + + + +extern void * try_calloc(size_t size1, size_t size2, struct World * w, char * f) +{ + char * msg = trouble_msg(w, f, "calloc()"); + void * p = calloc(size1, size2); + exit_err(NULL == p, w, msg); + free(msg); + return p; +} + + + +extern void check_files_xor(char * p1, char * p2, struct World * w) +{ + char * msg1 = "A file '"; + char * msg2 = "' exists, but no file '"; + char * msg3 = "'. If everything was in order, both or noe would exist. " + "The game won't start until this is corrected."; + uint16_t size = strlen(msg1) + strlen(p1) + strlen(msg2) + strlen(p2) + + strlen(msg3); + char msg[size]; + if (!access(p1, F_OK) && access(p2, F_OK)) + { + sprintf(msg, "%s%s%s%s%s", msg1, p1, msg2, p2, msg3); + errno = 0; + exit_err(1, w, msg); + } + else if (access(p1, F_OK) && !access(p2, F_OK)) + { + sprintf(msg, "%s%s%s%s%s", msg1, p2, msg2, p1, msg3); + errno = 0; + exit_err(1, w, msg); + } +} + + + +extern void check_tempfile(char * path, struct World * w) +{ + char * msg1 = "A file '"; + char * msg2 = "' exists, probably from a corrupted previous file saving " + "process. To avoid corruption of game files, the game won't " + "start until it is removed or renamed."; + uint16_t size = strlen(msg1) + strlen(path) + strlen(msg2); + char msg[size]; + sprintf(msg, "%s%s%s", msg1, path, msg2); + exit_err(!access(path, F_OK), w, msg); +} + + + extern void update_log(struct World * world, char * text) { + char * f_name = "update_log()"; static char * last_msg; /* TODO: valgrind is dissatisfied */ - if (0 == last_msg) /* with this calloc'd pointer */ - { /* never being freed. */ - last_msg = calloc(1, sizeof(char)); /* Rectify this ? */ + if (0 == last_msg) /* with this calloc'd pointer not */ + { /* being freed. Rectify this? */ + last_msg = try_calloc(1, sizeof(char), world, f_name); } char * new_text; uint16_t len_old = strlen(world->log); if (0 == strcmp(last_msg, text)) { uint16_t len_whole = len_old + 1; - new_text = calloc(len_whole + 1, sizeof(char)); + new_text = try_calloc(len_whole + 1, sizeof(char), world, f_name); memcpy(new_text, world->log, len_old); memcpy(new_text + len_old, ".", 1); } @@ -37,10 +116,10 @@ extern void update_log(struct World * world, char * text) { uint16_t len_new = strlen(text); uint16_t len_whole = len_old + len_new + 1; - new_text = calloc(len_whole, sizeof(char)); + new_text = try_calloc(len_whole, sizeof(char), world, f_name); memcpy(new_text, world->log, len_old); memcpy(new_text + len_old, text, len_new); - last_msg = calloc(len_new + 1, sizeof(char)); + last_msg = try_calloc(len_new + 1, sizeof(char), world, f_name); memcpy(last_msg, text, len_new); } free(world->log); @@ -74,36 +153,26 @@ extern uint16_t center_offset(uint16_t pos, uint16_t mapsize, extern void turn_over(struct World * world, char action) { - char * err_open = "Trouble in turn_over() with fopen() " - "opening file 'record_tmp' for appending."; + char * f_name = "turn_over()"; char * err_write = "Trouble in turn_over() with write_uint8() " "writing to opened file 'record_tmp'."; - char * err_close = "Trouble in turn_over() with fclose() " - "closing opened file 'record'."; - char * err_unl = "Trouble in turn_over() with unlink() " - "unlinking old file 'record'."; - char * err_move = "Trouble in turn_over() with rename() " - "renaming file 'record_tmp' to 'record'."; + char * recordfile_tmp = "record_tmp"; char * recordfile = "record"; if (1 == world->interactive) { - FILE * file_old = fopen(recordfile, "r"); - FILE * file_new = fopen(recordfile_tmp, "w"); - exit_err(0 == file_old, world, err_open); + FILE * file_old = try_fopen(recordfile, "r", world, f_name); + FILE * file_new = try_fopen(recordfile_tmp, "w", world, f_name); char c = fgetc(file_old); while (EOF != c) { exit_err(write_uint8(c, file_new), world, err_write); c = fgetc(file_old); } - exit_err(fclose(file_old), world, err_close); + try_fclose(file_old, world, f_name); exit_err(write_uint8(action, file_new), world, err_write); - err_close = "Trouble in turn_over() with fclose() " - "closing opened file 'record_tmp'."; - exit_err(fclose(file_new), world, err_close); - exit_err(unlink(recordfile), world, err_unl); - exit_err(rename(recordfile_tmp, recordfile), world, err_move); + try_fclose_unlink_rename(file_new, recordfile_tmp, recordfile, + world, f_name); } world->turn++; rrand_seed(world->seed * world->turn); @@ -120,20 +189,13 @@ extern void turn_over(struct World * world, char action) extern void save_game(struct World * world) { - char * err_open = "Trouble in save_game() with fopen() " - "opening file 'savefile_tmp' for writing."; + char * f_name = "save_game()"; char * err_write = "Trouble in save_game() " "writing to opened file 'savefile_tmp'."; - char * err_close = "Trouble in save_game() with fclose() " - "closing opened file 'savefile_tmp'."; - char * err_unl = "Trouble in save_game() with unlink() " - "unlinking old 'savefile' file."; - char * err_move = "Trouble in save_game() with rename() " - "renaming 'file savefile_tmp' to 'savefile'."; + char * savefile_tmp = "savefile_tmp"; char * savefile = "savefile"; - FILE * file = fopen(savefile_tmp, "w"); - exit_err(0 == file, world, err_open); + FILE * file = try_fopen(savefile_tmp, "w", world, f_name); if ( write_uint32_bigendian(world->seed, file) || write_uint32_bigendian(world->turn, file) || write_uint16_bigendian(world->score, file) @@ -145,12 +207,7 @@ extern void save_game(struct World * world) { exit_err(1, world, err_write); } - exit_err(fclose(file), world, err_close); - if (!access(savefile, F_OK)) - { - exit_err(unlink(savefile), world, err_unl); - } - exit_err(rename(savefile_tmp, savefile), world, err_move); + try_fclose_unlink_rename(file, savefile_tmp, savefile, world, f_name); } diff --git a/src/misc.h b/src/misc.h index c7b8855..5101e47 100644 --- a/src/misc.h +++ b/src/misc.h @@ -9,6 +9,7 @@ +#include /* for size_t */ #include /* for uint16_t */ #include "yx_uint16.h" /* for yx_uint16 coordinates */ struct World; @@ -16,6 +17,26 @@ struct Map; +/* Returns message: "Trouble in ".parent." with ".child."." (try_*() helper) */ +extern char * trouble_msg(struct World * w, char * parent, char * child); + +/* Wrappers to malloc(), calloc() from function called "f" calling exit_err() + * with trouble_msg() error message if necessary. + */ +extern void * try_malloc(size_t size, struct World * w, char * f); +extern void * try_calloc(size_t nmemb, size_t size, + struct World * w, char * f); + + + +/* Check if tempfile "path" exists, and if so, exit with explanation that. */ +extern void check_tempfile(char * path, struct World * f); + +/* If one and only one of files at "p1", "p2" exists, fail with explanation. */ +extern void check_files_xor(char * p1, char * p2, struct World * w); + + + /* Update game log by appending "text", or by appending a "." if "text" is the * same as the last one passed. */ diff --git a/src/readwrite.c b/src/readwrite.c index 96505ad..4b2f2a6 100644 --- a/src/readwrite.c +++ b/src/readwrite.c @@ -1,8 +1,15 @@ /* readwrite.c */ #include "readwrite.h" -#include /* for FILE typedef, fgetc(), fputc(), fseek() */ +#include /* for FILE typedef, fopen(), fgetc(), fputc(), fseek(), + * sprintf() + */ #include /* for uint8_t, uint16_t, uint32_t */ +#include /* for strlen()*/ +#include /* for unlink() */ +#include "rexit.h" /* for exit_err() */ +#include "misc.h" /* for trouble_msg() */ +struct World; @@ -26,6 +33,79 @@ static uint8_t write_uintX_bigendian(FILE * file, uint32_t x, uint8_t size); +extern FILE * try_fopen(char * path, char * mode, struct World * w, char * f) +{ + char * msg1 = "Trouble in "; + char * msg2 = " with fopen() (mode '"; + char * msg3 = "') on path '"; + char * msg4 = "'."; + uint16_t size = strlen(msg1) + strlen(msg2) + strlen(msg3) + strlen(msg4) + + strlen(f) + strlen(path) + strlen(mode) + 1; + char msg[size]; + sprintf(msg, "%s%s%s%s%s%s%s", msg1, f, msg2, mode, msg3, path, msg4); + FILE * file_p = fopen(path, mode); + exit_err(NULL == file_p, w, msg); + return file_p; +} + + + +extern void try_fclose(FILE * file, struct World * w, char * f) +{ + char * msg = trouble_msg(w, f, "fclose()"); + exit_err(fclose(file), w, msg); + free(msg); +} + + + +extern void try_fgets(char * line, int linemax, FILE * file, + struct World * w, char * f) +{ + char * msg = trouble_msg(w, f, "fgets()"); + exit_err(NULL == fgets(line, linemax, file), w, msg); + free(msg); +} + + + +extern void try_fclose_unlink_rename(FILE * file, char * p1, char * p2, + struct World * w, char * f) +{ + try_fclose(file, w, f); + char * msg1 = "Trouble in "; + char * msg4 = "'."; + if (!access(p2, F_OK)) + { + char * msg2 = " with unlink() on path '"; + uint16_t size = strlen(msg1) + strlen(msg2) + strlen(msg4) + + strlen(f) + strlen(p2) + 1; + char msg[size]; + sprintf(msg, "%s%s%s%s%s", msg1, f, msg2, p2, msg4); + exit_err(unlink(p2), w, msg); + } + char * msg2 = " with rename() from '"; + char * msg3 = "' to '"; + uint16_t size = strlen(msg1) + strlen(f) + strlen(msg2) + strlen(p1) + + strlen(msg3) + strlen(p2) + strlen(msg4) + 1; + char msg[size]; + sprintf(msg, "%s%s%s%s%s%s%s", msg1, f, msg2, p1, msg3, p2, msg4); + exit_err(rename(p1, p2), w, msg); +} + + + +extern uint16_t get_linemax(FILE * file, struct World * w, char * f) +{ + char * msg = trouble_msg(w, f, "textfile_sizes()"); + uint16_t linemax; + exit_err(textfile_sizes(file, &linemax, NULL), w, msg); + free(msg); + return linemax; +} + + + extern uint8_t textfile_sizes(FILE * file, uint16_t * linemax_p, uint16_t * n_lines_p) { diff --git a/src/readwrite.h b/src/readwrite.h index 128e44a..bcdf10e 100644 --- a/src/readwrite.h +++ b/src/readwrite.h @@ -10,6 +10,34 @@ #include /* for FILE typedef */ #include /* for uint8_t, uint16_t, uint32_t */ +struct World; + + + +/* Wrappers to calling from function called "f" of fopen(), fclose() and fgets() + * and calling exit_err() with appropriate error messages. + */ +extern FILE * try_fopen(char * path, char * mode, struct World * w, char * f); +extern void try_fclose(FILE * file, struct World * w, char * f); +extern void try_fgets(char * line, int size, FILE * file, + struct World * w, char * f); + + + +/* Wrapper to successive call of fclose() from function called "f" on "file", + * then unlink() on file at "p2" if it exists, then rename() on "p1" to "p2". + * Used for handling atomic saving of files via temp files. + */ +extern void try_fclose_unlink_rename(FILE * file, char * p1, char * p2, + struct World * w, char * f); + + + +/* Wrapper: Call textfile_sizes() from function called "f" to get max line + * length of "file", exit via exit_err() with trouble_msg()-generated error + * message on failure. + */ +extern uint16_t get_linemax(FILE * file, struct World * w, char * f); diff --git a/src/wincontrol.c b/src/wincontrol.c index aeae7b2..d8cb40f 100644 --- a/src/wincontrol.c +++ b/src/wincontrol.c @@ -1,10 +1,10 @@ /* wincontrol.c */ #include "wincontrol.h" -#include /* for malloc(), free() */ +#include /* for free() */ #include /* for strlen() */ #include /* for uint8_t, uint16_t */ -#include /* for fopen(), fclose(), fwrite() */ +#include /* for fwrite() */ #include /* for access(), unlink() */ #include "windows.h" /* for suspend_win(), append_win(), reset_pad_offset(), * resize_active_win(), init_win(), free_win(), @@ -12,13 +12,15 @@ */ #include "yx_uint16.h" /* for yx_uint16 struct */ #include "main.h" /* for Wins struct */ -#include "readwrite.h" /* for textfile_sizes() */ +#include "readwrite.h" /* for get_linemax(), try_fopen(), try_fclose(), + * try_fgets(), try_fclose_unlink_rename() + */ #include "rexit.h" /* for exit_err() */ #include "main.h" /* for World, Wins structs */ #include "draw_wins.h" /* for draw_keys_win(), draw_info_win(), draw_log_win(), * draw_map_win */ - +#include "misc.h" /* for try_malloc() */ /* Return string "prefix" + "id"; malloc()'s string, remember to call free()! */ @@ -26,7 +28,7 @@ static char * string_prefixed_id(struct World * world, char * prefix, char id); -/* Create Winconf, initialize ->iew/height_type/width_type to 0, ->id to "id" +/* Create Winconf, initialize ->view/height_type/width_type to 0, ->id to "id" * and ->draw to f. */ static void create_winconf(char id, struct WinConf * wcp, @@ -58,10 +60,8 @@ static char get_id_by_win(struct World * world, struct Win * win); static char * string_prefixed_id(struct World * world, char * prefix, char id) { - char * err = "Trouble in string_prefixed_id() with malloc()."; uint8_t size = strlen(prefix) + 2; - char * path = malloc(size); - exit_err(NULL == path, world, err); + char * path = try_malloc(size, world, "string_prefixed_id()"); sprintf(path, "%s_", prefix); path[size - 2] = id; return path; @@ -83,39 +83,33 @@ static void create_winconf(char id, struct WinConf * wcp, static void init_winconf_from_file(struct World * world, char id) { - char * err_o = "Trouble in init_win_from_file() with fopen()."; - char * err_m = "Trouble in init_win_from_file() with malloc()."; - char * err_s = "Trouble in init_win_from_file() with textfile_sizes()."; - char * err_g = "Trouble in init_win_from_file() with fgets()."; - char * err_c = "Trouble in init_win_from_file() with fclose()."; + char * f_name = "init_winconf_from_file()"; char * path = string_prefixed_id(world, "config/windows/Win_", id); - FILE * file = fopen(path, "r"); - exit_err(NULL == file, world, err_o); + FILE * file = try_fopen(path, "r", world, f_name); free(path); - uint16_t linemax; - exit_err(textfile_sizes(file, &linemax, NULL), world, err_s); + uint16_t linemax = get_linemax(file, world, f_name); char line[linemax + 1]; struct WinConf * winconf = get_winconf_by_id(world, id); - exit_err(NULL == fgets(line, linemax + 1, file), world, err_g); - exit_err(NULL == (winconf->title = malloc(strlen(line))), world, err_m); + try_fgets(line, linemax + 1, file, world, f_name); + winconf->title = try_malloc(strlen(line), world, f_name); memcpy(winconf->title, line, strlen(line) - 1); /* Eliminate newline char */ winconf->title[strlen(line) - 1] = '\0'; /* char at end of string. */ - exit_err(NULL == fgets(line, linemax + 1, file), world, err_g); + try_fgets(line, linemax + 1, file, world, f_name); winconf->height = atoi(line); if (0 >= winconf->height) { winconf->height_type = 1; } - exit_err(NULL == fgets(line, linemax + 1, file), world, err_g); + try_fgets(line, linemax + 1, file, world, f_name); winconf->width = atoi(line); if (0 >= winconf->width) { winconf->width_type = 1; } - exit_err(fclose(file), world, err_c); + try_fclose(file, world, f_name); } @@ -133,14 +127,10 @@ static void init_win_from_winconf(struct World * world, char id) extern void save_win_config(struct World * world, char id) { - char * err_o = "Trouble in save_win_config() with fopen()."; - char * err_c = "Trouble in save_win_config() with fclose()."; - char * err_u = "Trouble in save_win_config() with unlink()."; - char * err_r = "Trouble in save_win_config() with rename()."; + char * f_name = "save_win_config()"; char * path_tmp = string_prefixed_id(world, "config/windows/Win_tmp_", id); - FILE * file = fopen(path_tmp, "w"); - exit_err(NULL == file, world, err_o); + FILE * file = try_fopen(path_tmp, "w", world, f_name); struct WinConf * wc = get_winconf_by_id(world, id); uint8_t size = strlen(wc->title) + 2; @@ -156,13 +146,8 @@ extern void save_win_config(struct World * world, char id) sprintf(line, "%d\n", wc->width); fwrite(line, sizeof(char), strlen(line), file); - exit_err(fclose(file), world, err_c); char * path = string_prefixed_id(world, "config/windows/Win_", id); - if (!access(path, F_OK)) - { - exit_err(unlink(path), world, err_u); - } - exit_err(rename(path_tmp, path), world, err_r); + try_fclose_unlink_rename(file, path_tmp, path, world, f_name); free(path); free(path_tmp); } @@ -242,9 +227,9 @@ extern struct Win * get_win_by_id(struct World * world, char id) extern void init_winconfs(struct World * world) { - char * err = "Trouble with malloc() in init_winconfs()."; - struct WinConf * winconfs = malloc(4 * sizeof(struct WinConf)); - exit_err(NULL == winconfs, world, err); + char * f_name = "init_winconfs()"; + struct WinConf * winconfs = try_malloc(4 * sizeof(struct WinConf), + world, f_name); create_winconf('i', &winconfs[0], draw_info_win); create_winconf('k', &winconfs[1], draw_keys_win); create_winconf('l', &winconfs[2], draw_log_win); @@ -299,21 +284,13 @@ extern void free_wins(struct World * world) extern void sorted_wintoggle(struct World * world) { - char * err_o = "Trouble in sorted_wintoggle() with fopen()."; - char * err_s = "Trouble in sorted_wintoggle() with textfile_sizes()."; - char * err_g = "Trouble in sorted_wintoggle() with fgets()."; - char * err_c = "Trouble in sorted_wintoggle() with fclose()."; - + char * f_name = "sorted_wintoggle()"; char * path = "config/windows/toggle_order"; - FILE * file = fopen(path, "r"); - exit_err(NULL == file, world, err_o); - uint16_t linemax; - exit_err(textfile_sizes(file, &linemax, NULL), world, err_s); + FILE * file = try_fopen(path, "r", world, f_name); + uint16_t linemax = get_linemax(file, world, f_name); char win_order[linemax + 1]; - - exit_err(NULL == fgets(win_order, linemax + 1, file), world, err_g); - exit_err(fclose(file), world, err_c); - + try_fgets(win_order, linemax + 1, file, world, f_name); + try_fclose(file, world, f_name); uint8_t i = 0; for (; i < linemax - 1; i++) { @@ -340,20 +317,16 @@ extern void reload_win_config(struct World * world) extern void save_win_configs(struct World * world) { + char * f_name = "save_win_configs()"; + save_win_config(world, 'i'); save_win_config(world, 'k'); save_win_config(world, 'l'); save_win_config(world, 'm'); - char * err_o = "Trouble in save_win_configs() with fopen()."; - char * err_c = "Trouble in save_win_configs() with fclose()."; - char * err_u = "Trouble in save_win_configs() with unlink()."; - char * err_r = "Trouble in save_win_configs() with rename()."; - char * path = "config/windows/toggle_order"; char * path_tmp = "config/windows/toggle_order_tmp"; - FILE * file = fopen(path_tmp, "w"); - exit_err(NULL == file, world, err_o); + FILE * file = try_fopen(path_tmp, "w", world, f_name); char line[6]; struct Win * w_p = world->wmeta->_chain_start; @@ -367,12 +340,7 @@ extern void save_win_configs(struct World * world) line[i] = '\n'; fwrite(line, sizeof(char), strlen(line), file); - exit_err(fclose(file), world, err_c); - if (!access(path, F_OK)) - { - exit_err(unlink(path), world, err_u); - } - exit_err(rename(path_tmp, path), world, err_r); + try_fclose_unlink_rename(file, path_tmp, path, world, f_name); }