From: Christian Heller Date: Tue, 8 Apr 2014 03:37:35 +0000 (+0200) Subject: Refactor file parsing patterns. X-Git-Tag: tce~778 X-Git-Url: https://plomlompom.com/repos/%7B%7Bdb.prefix%7D%7D/%7B%7B%20web_path%20%7D%7D/%7B%7Bprefix%7D%7D/todo?a=commitdiff_plain;h=d361b21fb63d9e1fd2ff7774c2322fab3e4eb239;p=plomrogue Refactor file parsing patterns. --- diff --git a/src/client/command_db.c b/src/client/command_db.c index 9e99f5e..29ef83d 100644 --- a/src/client/command_db.c +++ b/src/client/command_db.c @@ -5,12 +5,12 @@ #include /* NULL */ #include /* uint8_t */ #include /* free() */ -#include /* memset(), strcmp(), strdup() */ -#include "../common/parse_file.h" /* EDIT_STARTED, parse_file(), set_val(), - * token_from_line(), err_line(), - * finalize_by_readyflag() +#include /* strcmp(), strdup() */ +#include "../common/parse_file.h" /* EDIT_STARTED,parse_init_entry(), + * parse_id_uniq(), parse_unknown_arg(), + * parsetest_too_many_values(), parse_file(), + * parse_and_reduce_to_readyflag(),parse_val() */ -#include "../common/try_malloc.h" /* try_malloc() */ #include "array_append.h" /* array_append() */ #include "world.h" /* global world */ #include "cleanup.h" /* set_cleanup_flag() */ @@ -28,14 +28,12 @@ enum cmd_flag -/* Get tokens from "context" and, by their order (in the individual context and - * in subsequent calls of this function), interpret them as data to write into - * the CommandDB. +/* Interpret "token0" and "token1" as data to write into the CommandDB. * * Individual CommandDB entries are put together line by line before being * written. Writing happens after all necessary members of an entry have been - * assembled, and when additionally a) a new entry is started by a - * context->token0 of "COMMAND"; or b) a NULL context->token0 is passed. + * assembled, and when additionally a) a new entry is started by a "token0" of + * "COMMAND"; or b) of "token0" of NULL is passed. */ static void tokens_into_entries(char * token0, char * token1); @@ -43,13 +41,12 @@ static void tokens_into_entries(char * token0, char * token1); static void tokens_into_entries(char * token0, char * token1) { - char * f_name = "tokens_into_entries()"; char * str_cmd = "COMMAND"; static uint8_t cmd_flags = READY_CMD; static struct Command * cmd = NULL; if (!token0 || !strcmp(token0, str_cmd)) { - finalize_by_readyflag(&cmd_flags, READY_CMD); + parse_and_reduce_to_readyflag(&cmd_flags, READY_CMD); if (cmd) { array_append(world.commandDB.n, sizeof(struct Command), @@ -59,25 +56,25 @@ static void tokens_into_entries(char * token0, char * token1) cmd = NULL; } } - err_line(token0 && NULL != token_from_line(NULL), "Too many values."); - if (token0 && !strcmp(token0, str_cmd)) + if (token0) { - char * err_uniq = "Declaration of ID already used."; - cmd_flags = EDIT_STARTED; - cmd = try_malloc(sizeof(struct Command), f_name); - memset(cmd, 0, sizeof(struct Command)); - cmd->dsc_short = strdup(token1); - err_line(NULL != get_command(cmd->dsc_short), err_uniq); - } - else if ( token0 - && !( set_val(token0, token1, "DESCRIPTION", &cmd_flags, - DESC_SET, 's', (char *) &cmd->dsc_long) - || set_val(token0, token1, "SERVER_COMMAND", &cmd_flags, - SERVERCMD_SET, 's', (char *) &cmd->server_msg) - || set_val(token0, token1, "SERVER_ARGUMENT", &cmd_flags, - SERVERARG_SET, 'c', (char *) &cmd->arg))) - { - err_line(1, "Unknown arguemnt."); + parsetest_too_many_values(); + if (!strcmp(token0, str_cmd)) + { + cmd = (struct Command *) parse_init_entry(&cmd_flags, + sizeof(struct Command)); + cmd->dsc_short = strdup(token1); + parse_id_uniq(NULL != get_command(cmd->dsc_short)); + } + else if (!( parse_val(token0, token1, "DESCRIPTION", &cmd_flags, + DESC_SET, 's', (char *) &cmd->dsc_long) + || parse_val(token0, token1, "SERVER_COMMAND", &cmd_flags, + SERVERCMD_SET, 's', (char *) &cmd->server_msg) + || parse_val(token0, token1, "SERVER_ARGUMENT", &cmd_flags, + SERVERARG_SET, 'c', (char *) &cmd->arg))) + { + parse_unknown_arg(); + } } } diff --git a/src/client/interface_conf.c b/src/client/interface_conf.c index afc3ede..2b7560e 100644 --- a/src/client/interface_conf.c +++ b/src/client/interface_conf.c @@ -7,10 +7,14 @@ #include /* UINT8_MAX, uint8_t, uint32_t */ #include /* EXIT_SUCCESS, atoi(), exit(), free() */ #include /* FILE, sprintf() */ -#include /* memset(), strchr(), strcmp(), strdup(), strlen() */ +#include /* strchr(), strcmp(), strdup(), strlen() */ #include /* optarg, getopt() */ -#include "../common/parse_file.h" /* EDIT_STARTED, parse_file(), set_val(), - * token_from_line(), finalize_by_readyflag() +#include "../common/parse_file.h" /* EDIT_STARTED, parse_file(), parse_val(), + * token_from_line(), parsetest_singlechar(), + * parse_and_reduce_to_readyflag(), + * parsetest_defcontext(),parse_unknown_arg(), + * parsetest_too_many_values(), + * parse_id_uniq(), parse_init_entry() */ #include "../common/readwrite.h" /* try_fopen(), try_fclose_unlink_rename(), * try_fwrite() @@ -101,15 +105,14 @@ static uint8_t start_kbd(char * token0, char * token1, char * str_kbd, * "token0" is "KEY", a keybinding is defined and "token2" is read / must not be * NULL. In that case, the line read is checked against having a 4th token. */ -static uint8_t set_members(char * token0, char * token1, char * token2, - uint8_t * win_flags, uint8_t * ord_flags, - uint8_t kbd_flags, +static uint8_t set_members(char * token0, char * token1, uint8_t * win_flags, + uint8_t * ord_flags, uint8_t kbd_flags, struct Win * win, struct KeyBindingDB * kbdb); /* Add keybinding defined in "token1" as keycode and "token2" as command to * "kbdb" if "flags" are set to EDIT_STARTED. */ -static void set_keybindings(char * token1, char * token2, uint8_t flags, +static void set_keybindings(char * token1, uint8_t flags, struct KeyBindingDB * kbdb); @@ -187,25 +190,25 @@ static void tokens_into_entries(char * token0, char * token1) if (!token0 || !strcmp(token0, str_win) || !strcmp(token0, str_ord) || !strcmp(token0, str_kbd)) { - finalize_by_readyflag(&win_flags, READY_WIN); - finalize_by_readyflag(&ord_flags, READY_ORD); - finalize_by_readyflag(&kbd_flags, READY_KBD); + parse_and_reduce_to_readyflag(&win_flags, READY_WIN); + parse_and_reduce_to_readyflag(&ord_flags, READY_ORD); + parse_and_reduce_to_readyflag(&kbd_flags, READY_KBD); write_if_win(&win); } - if (!token0) + if (token0) { - return; - } - char * token2 = token_from_line(NULL); - err_line(strcmp(token0, "KEY") && NULL != token2, "Too many values."); - if ( start_win(token0, token1, str_win, &win_flags, &win) - || start_ord(token0, token1, str_ord, &ord_flags) - || start_kbd(token0, token1, str_kbd, &kbd_flags, &kbdb) - || set_members(token0, token1, token2, &win_flags, &ord_flags, - kbd_flags, win, kbdb)); - else - { - err_line(1, "Unknown argument."); + if (strcmp(token0, "KEY")) + { + parsetest_too_many_values(); + } + if (!( start_win(token0, token1, str_win, &win_flags, &win) + || start_ord(token0, token1, str_ord, &ord_flags) + || start_kbd(token0, token1, str_kbd, &kbd_flags, &kbdb) + || set_members(token0, token1, &win_flags, &ord_flags, kbd_flags, + win, kbdb))) + { + parse_unknown_arg(); + } } } @@ -241,14 +244,9 @@ static uint8_t start_win(char * token0, char * token1, char * str_win, { return 0; } - char * f_name = "start_win()"; - char * err_uniq = "Declaration of ID already used."; - *win_flags = EDIT_STARTED; - *win = try_malloc(sizeof(struct Win), f_name); - memset(*win, 0, sizeof(struct Win)); - err_line(1 != strlen(token1), "Value must be single ASCII character."); - err_line( world.winDB.ids - && (NULL != strchr(world.winDB.ids, token1[0])), err_uniq); + *win = (struct Win *) parse_init_entry(win_flags, sizeof(struct Win)); + parsetest_singlechar(token1); + parse_id_uniq(world.winDB.ids && (NULL!=strchr(world.winDB.ids,token1[0]))); (*win)->id = token1[0]; return 1; } @@ -308,24 +306,23 @@ static uint8_t start_kbd(char * token0, char * token1, char * str_kbd, -static uint8_t set_members(char * token0, char * token1, char * token2, - uint8_t * win_flags, uint8_t * ord_flags, - uint8_t kbd_flags, +static uint8_t set_members(char * token0, char * token1, uint8_t * win_flags, + uint8_t * ord_flags, uint8_t kbd_flags, struct Win * win, struct KeyBindingDB * kbdb) { - if ( set_val(token0, token1, "NAME", win_flags, - NAME_SET, 's', (char *) &win->title) - || set_val(token0, token1, "WIDTH", win_flags, - WIDTH_SET, 'i', (char *) &win->target_width) - || set_val(token0, token1, "HEIGHT", win_flags, - HEIGHT_SET, 'i', (char *) &win->target_height)); - else if (set_val(token0, token1, "BREAK", win_flags, - BREAK_SET, '8', (char *) &win->linebreak)) + if ( parse_val(token0, token1, "NAME", win_flags, + NAME_SET, 's', (char *) &win->title) + || parse_val(token0, token1, "WIDTH", win_flags, + WIDTH_SET, 'i', (char *) &win->target_width) + || parse_val(token0, token1, "HEIGHT", win_flags, + HEIGHT_SET, 'i', (char *) &win->target_height)); + else if (parse_val(token0, token1, "BREAK", win_flags, + BREAK_SET, '8', (char *) &win->linebreak)) { err_line(2 < win->linebreak, "Value must be 0, 1 or 2."); } - else if (set_val(token0, token1, "WIN_FOCUS", ord_flags, - FOCUS_SET, 'c', &tmp_active)) + else if (parse_val(token0, token1, "WIN_FOCUS", ord_flags, + FOCUS_SET, 'c', &tmp_active)) { char * err_null = "Value not empty as it should be."; char * err_outside = "ID not found in WIN_ORDER ID series."; @@ -334,14 +331,13 @@ static uint8_t set_members(char * token0, char * token1, char * token2, } else if (!strcmp(token0, "KEY")) { - err_line(NULL != token_from_line(NULL), "Too many values."); - if (* win_flags & EDIT_STARTED) + if (*win_flags & EDIT_STARTED) { - set_keybindings(token1, token2, * win_flags, &win->kb); + set_keybindings(token1, *win_flags, &win->kb); } else { - set_keybindings(token1, token2, kbd_flags, kbdb); + set_keybindings(token1, kbd_flags, kbdb); } } else @@ -353,13 +349,14 @@ static uint8_t set_members(char * token0, char * token1, char * token2, -static void set_keybindings(char * token1, char * token2, uint8_t flags, +static void set_keybindings(char * token1, uint8_t flags, struct KeyBindingDB * kbdb) { - char * err_out = "Outside appropriate definition's context."; - char * err_code = "Invalid keycode. Must be >= 0 and < 1000."; - err_line(!(flags & EDIT_STARTED), err_out); + char * token2 = token_from_line(NULL); err_line(!token2, "No binding to key given."); + parsetest_too_many_values(); + char * err_code = "Invalid keycode. Must be >= 0 and < 1000."; + parsetest_defcontext(flags); char * err_many = "No more than 255 keybindings allowed in one section."; err_line(UINT8_MAX == kbdb->n_of_kbs, err_many); struct KeyBinding kb; @@ -491,4 +488,3 @@ extern void reload_interface_conf() map_center(); world.winDB.v_screen_offset = 0; } - diff --git a/src/common/parse_file.c b/src/common/parse_file.c index 3632f40..ab35ab0 100644 --- a/src/common/parse_file.c +++ b/src/common/parse_file.c @@ -145,7 +145,7 @@ extern char * token_from_line(char * line) -extern void test_for_int(char * string, char type) +extern void parsetest_int(char * string, char type) { char * err; if ('8' == type) @@ -175,15 +175,59 @@ extern void test_for_int(char * string, char type) -extern uint8_t set_val(char * token0, char * token1, char * comparand, - uint8_t * flags, uint8_t set_flag, char type, - char * element) +extern void parsetest_defcontext(uint8_t flags) +{ + err_line(!(flags & EDIT_STARTED),"Outside appropriate definition context."); +} + + + +extern void parsetest_singlechar(char * string) +{ + err_line(1 != strlen(string), "Value must be single ASCII character."); +} + + + +extern void parsetest_too_many_values() +{ + err_line(NULL != token_from_line(NULL), "Too many values."); +} + + + +extern void parse_id_uniq(int test) +{ + err_line(0 != test, "Declaration of ID already used."); +} + + + +extern void parse_unknown_arg() +{ + err_line(1, "Unknown argument."); +} + + + +extern char * parse_init_entry(uint8_t * flags, size_t size) +{ + char * f_name = "parse_init_entry()"; + *flags = EDIT_STARTED; + char * p = try_malloc(size, f_name); + memset(p, 0, size); + return p; +} + + + +extern uint8_t parse_val(char * token0, char * token1, char * comparand, + uint8_t * flags, uint8_t set_flag, char type, + char * element) { if (!strcmp(token0, comparand)) { - char * err_out = "Outside appropriate definition's context."; - char * err_singlechar = "Value must be single ASCII character."; - err_line(!(*flags & EDIT_STARTED), err_out); + parsetest_defcontext(*flags); *flags = *flags | set_flag; if ('s' == type) { @@ -191,17 +235,17 @@ extern uint8_t set_val(char * token0, char * token1, char * comparand, } else if ('c' == type) { - err_line(1 != strlen(token1), err_singlechar); + parsetest_singlechar(token1); *element = (token1)[0]; } else if ('8' == type) { - test_for_int(token1, '8'); + parsetest_int(token1, '8'); * (uint8_t *) element = atoi(token1); } else if ('i' == type) { - test_for_int(token1, 'i'); + parsetest_int(token1, 'i'); * (int16_t *) element = atoi(token1); } return 1; @@ -211,7 +255,7 @@ extern uint8_t set_val(char * token0, char * token1, char * comparand, -extern void finalize_by_readyflag(uint8_t * flags, uint8_t ready_flag) +extern void parse_and_reduce_to_readyflag(uint8_t * flags, uint8_t ready_flag) { char * err_fin = "Last definition block not finished yet."; err_line((*flags & ready_flag) ^ ready_flag, err_fin); diff --git a/src/common/parse_file.h b/src/common/parse_file.h index 5c002fc..29e7ae1 100644 --- a/src/common/parse_file.h +++ b/src/common/parse_file.h @@ -6,6 +6,7 @@ #ifndef PARSE_FILE_H #define PARSE_FILE_H +#include /* size_t */ #include /* uint8_t */ @@ -42,18 +43,36 @@ extern void err_line(uint8_t test, char * msg); extern char * token_from_line(char * line); /* Test for "string" to represent proper int16 (type: "i") or uint8 ("8"). */ -extern void test_for_int(char * string, char type); +extern void parsetest_int(char * string, char type); + +/* Test for "string" to be of length 1 (excluding "\0" terminator). */ +extern void parsetest_singlechar(char * string); + +/* Calls err_line() with fitting message if EDIT_STARTED not set in "flags". */ +extern void parsetest_defcontext(uint8_t flags); + +/* Ensure token_from_line() does not find any more tokens on the line. */ +extern void parsetest_too_many_values(); + +/* Trigger err_line() with "Unknown argument" message. */ +extern void parse_unknown_arg(); + +/* If "test"!=0 call err_line() with "Declaration of ID already used" message.*/ +extern void parse_id_uniq(int test); + +/* Set "flags"=EDIT_STARTED and return pointer to new zeroed array of "size". */ +extern char * parse_init_entry(uint8_t * flags, size_t size); /* If "token0" fits "comparand", set "element" to value read from "token1" as * string (type: "s"), char ("c") uint8 ("8") or int16 ("i"), set that element's * flag to "flags" and return 1; else return 0. */ -extern uint8_t set_val(char * token0, char * token1, char * comparand, - uint8_t * flags, uint8_t set_flag, char type, - char * element); +extern uint8_t parse_val(char * token0, char * token1, char * comparand, + uint8_t * flags, uint8_t set_flag, char type, + char * element); /* Check "ready_flag" is set in "flags", re-set "flags" to "ready_flag" only. */ -extern void finalize_by_readyflag(uint8_t * flags, uint8_t ready_flag); +extern void parse_and_reduce_to_readyflag(uint8_t * flags, uint8_t ready_flag); diff --git a/src/server/configfile.c b/src/server/configfile.c index 026f658..a48c494 100644 --- a/src/server/configfile.c +++ b/src/server/configfile.c @@ -5,9 +5,10 @@ #include /* uint8_t */ #include /* atoi(), free() */ #include /* strcmp() */ -#include "../common/parse_file.h" /* EDIT_STARTED, set_val(), test_for_int(), - * err_line(), parse_file(),token_from_line(), - * finalize_by_readyflag() +#include "../common/parse_file.h" /* EDIT_STARTED, parsetest_int(),parse_file(), + * parsetest_too_many_values(),parse_id_uniq() + * parse_unknown_arg(), parse_init_entry(), + * parse_and_reduce_to_readyflag(),parse_val() */ #include "../common/rexit.h" /* exit_err(), exit_trouble() */ #include "../common/try_malloc.h" /* try_malloc() */ @@ -66,7 +67,7 @@ static void tokens_into_entries(char * token0, char * token1); * reading. Check that "token1" id of new entry has not already been used in DB * starting at "entry_cmp". */ -static uint8_t new_entry(char * token0, char * token1, char * comparand, +static uint8_t start_entry(char * token0, char * token1, char * comparand, uint8_t * flags, size_t size, struct EntryHead ** entry, struct EntryHead * entry_cmp); @@ -111,47 +112,47 @@ static void tokens_into_entries(char * token0, char * token1) static struct EntryHead * mod = NULL; if (!token0 || !strcmp(token0,str_act) || !strcmp(token0,str_obj)) { - finalize_by_readyflag(&action_flags, READY_ACT); - finalize_by_readyflag(&object_flags, READY_OBJ); + parse_and_reduce_to_readyflag(&action_flags, READY_ACT); + parse_and_reduce_to_readyflag(&object_flags, READY_OBJ); write_if_entry(&moa, (struct EntryHead ***) &moa_p_p); write_if_entry(&mod, (struct EntryHead ***) &mod_p_p); } - err_line(token0 && NULL != token_from_line(NULL), "Too many values."); - if ( token0 - && !( new_entry(token0, token1, str_act, &action_flags, - sizeof(struct MapObjAct), (struct EntryHead**) &moa, - (struct EntryHead *) world.map_obj_acts) - || new_entry(token0, token1, str_obj, &object_flags, - sizeof(struct MapObjDef), (struct EntryHead**) &mod, - (struct EntryHead *) world.map_obj_defs) - || set_members(token0, token1, &object_flags, &action_flags, - (struct MapObjDef *) mod, (struct MapObjAct *) moa))) + if (token0) { - err_line(1, "Unknown argument."); + parsetest_too_many_values(); + if (!( start_entry(token0, token1, str_act, &action_flags, + sizeof(struct MapObjAct),(struct EntryHead**) &moa, + (struct EntryHead *) world.map_obj_acts) + || start_entry(token0, token1, str_obj, &object_flags, + sizeof(struct MapObjDef),(struct EntryHead**) &mod, + (struct EntryHead *) world.map_obj_defs) + || set_members(token0, token1, &object_flags, &action_flags, + (struct MapObjDef *)mod,(struct MapObjAct *) moa))) + { + parse_unknown_arg(); + } } } -static uint8_t new_entry(char * token0, char * token1, char * comparand, - uint8_t * flags, size_t size, - struct EntryHead ** entry,struct EntryHead * entry_cmp) +static uint8_t start_entry(char * token0, char * token1, char * comparand, + uint8_t * flags, size_t size, + struct EntryHead ** entry, + struct EntryHead * entry_cmp) { - char * f_name = "new_entry()"; - if (!strcmp(token0, comparand)) + if (strcmp(token0, comparand)) { - char * err_uniq = "Declaration of ID already used."; - * flags = EDIT_STARTED; - * entry = try_malloc(size, f_name); - test_for_int(token1, '8'); - (*entry)-> id = atoi(token1); - for (; NULL != entry_cmp; entry_cmp = entry_cmp->next) - { - err_line((*entry)->id == entry_cmp->id, err_uniq); - } - return 1; + return 0; } - return 0; + *entry = (struct EntryHead *) parse_init_entry(flags, size); + parsetest_int(token1, '8'); + (*entry)-> id = atoi(token1); + for (; NULL != entry_cmp; entry_cmp = entry_cmp->next) + { + parse_id_uniq((*entry)->id == entry_cmp->id); + } + return 1; } @@ -204,8 +205,8 @@ static uint8_t set_members(char * token0, char * token1, uint8_t * object_flags, struct MapObjAct * moa) { if ( *action_flags & EDIT_STARTED - && set_val(token0, token1, "NAME", action_flags, - NAME_SET, 's', (char *) &moa->name)) + && parse_val(token0, token1, "NAME", action_flags, + NAME_SET, 's', (char *) &moa->name)) { if (!( try_func_name(moa, "move", actor_move) || try_func_name(moa, "pick_up", actor_pick) @@ -217,18 +218,18 @@ static uint8_t set_members(char * token0, char * token1, uint8_t * object_flags, *action_flags = *action_flags | NAME_SET; return 1; } - else if ( set_val(token0, token1, "NAME", object_flags, - NAME_SET, 's', (char *) &mod->name) - || set_val(token0, token1, "SYMBOL", object_flags, - SYMBOL_SET, 'c', (char *) &mod->char_on_map) - || set_val(token0, token1, "EFFORT", action_flags, - EFFORT_SET, '8', (char *) &moa->effort) - || set_val(token0, token1, "LIFEPOINTS", object_flags, - LIFEPOINTS_SET, '8', (char *) &mod->lifepoints) - || set_val(token0, token1, "CONSUMABLE", object_flags, - CONSUMABLE_SET, '8', (char *) &mod->consumable) - || set_val(token0, token1, "CORPSE_ID", object_flags, - CORPSE_ID_SET, '8', (char *) &mod->corpse_id)) + else if ( parse_val(token0, token1, "NAME", object_flags, + NAME_SET, 's', (char *) &mod->name) + || parse_val(token0, token1, "SYMBOL", object_flags, + SYMBOL_SET, 'c', (char *) &mod->char_on_map) + || parse_val(token0, token1, "EFFORT", action_flags, + EFFORT_SET, '8', (char *) &moa->effort) + || parse_val(token0, token1, "LIFEPOINTS", object_flags, + LIFEPOINTS_SET, '8', (char *) &mod->lifepoints) + || parse_val(token0, token1, "CONSUMABLE", object_flags, + CONSUMABLE_SET, '8', (char *) &mod->consumable) + || parse_val(token0, token1, "CORPSE_ID", object_flags, + CORPSE_ID_SET, '8', (char *) &mod->corpse_id)) { return 1; }