From: Christian Heller Date: Tue, 28 Jan 2014 04:26:00 +0000 (+0100) Subject: Added previously forgotten err_try_fgets library (and moved it to src/common/). X-Git-Tag: tce~853 X-Git-Url: https://plomlompom.com/repos/%7B%7Bdb.prefix%7D%7D/%7B%7B%20web_path%20%7D%7D/static/%7B%7Bprefix%7D%7D/blog?a=commitdiff_plain;h=6f98f0b029c3e84f1df0f2f3642f88e91b17cf33;p=plomrogue Added previously forgotten err_try_fgets library (and moved it to src/common/). --- diff --git a/src/client/command_db.c b/src/client/command_db.c index 57ea2f3..aed92c9 100644 --- a/src/client/command_db.c +++ b/src/client/command_db.c @@ -6,10 +6,10 @@ #include /* FILE, sprintf() */ #include /* free() */ #include /* memset(), strlen(), strcmp() */ +#include "../common/err_try_fgets.h" /* reset_err_try_fgets_counter() */ #include "../common/readwrite.h" /* try_fopen(),try_fclose(),textfile_sizes() */ #include "../common/rexit.h" /* exit_trouble() */ #include "../common/try_malloc.h" /* try_malloc() */ -#include "err_try_fgets.h" /* reset_err_try_fgets_counter() */ #include "misc.h" /* array_append() */ #include "world.h" /* global world */ #include "cleanup.h" /* set_cleanup_flag() */ diff --git a/src/client/keybindings.c b/src/client/keybindings.c index eb67f26..14d603b 100644 --- a/src/client/keybindings.c +++ b/src/client/keybindings.c @@ -7,10 +7,10 @@ #include /* FILE, sprintf() */ #include /* free(), atoi() */ #include /* strlen(), strchr(), strcmp() */ +#include "../common/err_try_fgets.h" /* err_try_fgets(), err_line() */ #include "../common/readwrite.h" /* try_fwrite()*/ #include "../common/try_malloc.h" /* try_malloc() */ #include "command_db.h" /* get_command() */ -#include "err_try_fgets.h" /* err_try_fgets(), err_line() */ #include "windows.h" /* draw_all_wins() */ #include "world.h" /* global world */ diff --git a/src/client/main.c b/src/client/main.c index 6599d62..c25c4f9 100644 --- a/src/client/main.c +++ b/src/client/main.c @@ -6,6 +6,7 @@ #include /* exit() */ #include /* memset() */ #include /* access() */ +#include "../common/err_try_fgets.h" /* set_err_try_fgets_delim() */ #include "../common/rexit.h" /* set_cleanup_func(), exit_trouble(),exit_err() */ #include "cleanup.h" /* cleanup(), set_cleanup_flag() */ #include "command_db.h" /* init_command_db() */ @@ -30,6 +31,7 @@ int main(int argc, char * argv[]) world.path_interface = "confclient/interface_conf"; world.winDB.legal_ids = "012ciklm"; world.delim = "%\n"; + set_err_try_fgets_delim(world.delim); /* Parse command line arguments. */ obey_argv(argc, argv); diff --git a/src/client/misc.c b/src/client/misc.c index 3bcd784..17a12da 100644 --- a/src/client/misc.c +++ b/src/client/misc.c @@ -8,13 +8,13 @@ #include /* free(), exit() */ #include /* memcpy(), strlen() */ #include /* global optarg, getopt() */ +#include "../common/err_try_fgets.h" /* reset_err_try_fgets_counter() */ #include "../common/readwrite.h" /* try_fopen(), try_fclose(), textfile_sizes(), * try_fclose_unlink_rename(), */ #include "../common/rexit.h" /* exit_err() */ #include "../common/try_malloc.h" /* try_malloc() */ #include "cleanup.h" /* set_cleanup_flag() */ -#include "err_try_fgets.h" /* reset_err_try_fgets_counter() */ #include "keybindings.h" /* free_keybindings(), read_keybindings_from_file(), * write_keybindings_to_file() */ diff --git a/src/client/windows.c b/src/client/windows.c index cd3ad8c..b0734dc 100644 --- a/src/client/windows.c +++ b/src/client/windows.c @@ -11,6 +11,7 @@ #include /* uint8_t, uint16_t, uint32_t, UINT16_MAX */ #include /* sprintf() */ #include /* memcpy(), strlen(), strnlen(), strchr(), memset() */ +#include "../common/err_try_fgets.h" /* err_try_fgets(), err_line() */ #include "../common/readwrite.h" /* try_fputc(), try_write(), try_fgetc() */ #include "../common/rexit.h" /* exit_trouble(), exit_err() */ #include "../common/try_malloc.h" /* try_malloc() */ @@ -22,7 +23,6 @@ * draw_win_keybindings_winconf_geometry(), * draw_win_keybindings_global() */ -#include "err_try_fgets.h" /* err_try_fgets(), err_line() */ #include "keybindings.h" /* free_keybindings(), write_keybidings_to_file(), * read_keybindings_from_file() */ diff --git a/src/common/err_try_fgets.c b/src/common/err_try_fgets.c new file mode 100644 index 0000000..7f399a9 --- /dev/null +++ b/src/common/err_try_fgets.c @@ -0,0 +1,86 @@ +/* err_try_fgets.c */ + +#include /* uint8_t, uint32_t */ +#include /* FILE, sprintf() */ +#include /* strlen(), strchr(), strcmp() */ +#include "../common/readwrite.h" /* try_fgets() */ +#include "../common/rexit.h" /* exit_err() */ +#include "../common/try_malloc.h" /* try_malloc() */ + + + +/* Increments by one on each err_try_fgets() call, servers as a line counter. */ +static uint32_t err_try_fgets_counter = 0; + +/* Delimiter to use for err_try_fgets()' 'c' test. */ +char * err_try_fgets_delim = ""; + + + +extern void reset_err_try_fgets_counter() +{ + err_try_fgets_counter = 0; +} + + + +extern void set_err_try_fgets_delim(char * delim) +{ + err_try_fgets_delim = delim; +} + + + +extern void err_line(uint8_t test, char * line, char * intro, char * msg) +{ + if (!test) + { + return; + } + char * f_name = "err_line()"; + char * line_intro = " Offending line "; + char * err = try_malloc(strlen(intro) + strlen(msg) + strlen(line_intro) + + 10 + 1 + 1 + strlen(line) + 1, f_name); + sprintf(err, "%s%s%s%d:\n%s", intro, msg, line_intro, err_try_fgets_counter, + line); + exit_err(1, err); +} + + + +extern void err_try_fgets(char * line, uint32_t linemax, FILE * file, + char * context, char * test) +{ + char * err_end = "File ended unexpectedly."; + char * err_empty = "Hit empty line where non-empty line was expected."; + char * err_many = "Too many characters; expected only one."; + char * err_int = "Expected valid positive or negative integer number."; + char * err_full = "Hit non-empty line where empty line was expected."; + char * err_delim = "Expected proper delimiter, found something else."; + char * f_name = "err_try_fgets()"; + line[0] = '\0'; + try_fgets(line, linemax + 1, file, f_name); + err_try_fgets_counter++; + err_line(strchr(test, '0') && !(strlen(line)), line, context, err_end); + err_line(strchr(test, 'n') && line[strlen(line) - 1] != '\n', line, context, + err_end); + err_line(strchr(test, 'e') && '\n' != line[0], line, context, err_full); + err_line(strchr(test, 'f') && '\n' == line[0], line, context, err_empty); + err_line(strchr(test, 's') && strlen(line) > 2, line, context, err_many); + err_line(strchr(test, 'd') && strcmp(line, err_try_fgets_delim), line, + context, err_delim); + if (strchr(test, 'i')) + { + err_line(!(strchr(test, 'f')) && strlen(line) < 2, line, context, + err_int); + uint8_t i; + for (i = 0; '\n' != line[i] && '\0' != line[i]; i++) + { + uint8_t test = (0 == i && ('-' == line[i] || '+' == line[i])) + || ('0' <= line[i] && line[i] <= '9'); + err_line(!test, line, context, err_int); + } + err_line(strlen(line) < 2 && ('-' == line[i] || '+' == line[i]), + line, context, err_int); + } +} diff --git a/src/common/err_try_fgets.h b/src/common/err_try_fgets.h new file mode 100644 index 0000000..deefe98 --- /dev/null +++ b/src/common/err_try_fgets.h @@ -0,0 +1,52 @@ +/* err_try_fgets.h + * + * For superficial syntax checks of individual text file lines. + */ + +#ifndef ERR_TRY_FGETS_H +#define ERR_TRY_FGETS_H + +#include /* uint8_t, uint32_t */ +#include /* FILE */ + + + +/* Reset err_try_fgets() file line counter back to zero. */ +extern void reset_err_try_fgets_counter(); + +/* Set delimiter expected by err_try_fgets()'s 'c' test. */ +extern void set_err_try_fgets_delim(char * delim); + +/* If "test", print error message of "intro" + "msg" and output offending line's + * number and content. + */ +extern void err_line(uint8_t test, char * line, char * intro, char * msg); + +/* fgets() / try_fgets() wrapper (therefore the common arguments "line", + * "linemax", "file") that performs various checks as defined by characters in + * "test". On failure, these tests exit the game with an error message that + * pre-pends "context" to a description of the individual test failure and + * output of the offending line's number and content. + * + * Note that for the file line count to be correct, it is necessary to call + * reset_err_try_fgets_counter() before reading the line, and each line must be + * read with a call of err_try_fgets(). + * + * The available "test" conditions are as follows: + * + * '0': check against the line being empty (not even containing a \n char) + * 'n': check for "line" ending with an \n char + * 'e': check for "line" starting with an \n char + * 'f': check for "line" not starting with an \n char + * 's': check for "line" containing two chars (the second may be \n) + * 'd': check for "line" being equal to the world.delim delimiter + * 'i': check for "line" describing an integer in all its chars before end or \n + * (i.e. all other chars must be digits, except the first char, which may + * be '+' or '-'; a '+' or '-' without digits following is invalid) + */ +extern void err_try_fgets(char * line, uint32_t linemax, FILE * file, + char * context, char * test); + + + +#endif