- be more strict and humble when allocating memory from the stack
-- may err_line store the processed line internally as it does the line count
-
SERVER:
- implement field of view / line of sight and obstacles for those on the map
- enable toggling of window borders
- make log scrollable
-
-- implement server-config-file-like parsing for client-config-files, too
-81 quit
-265 to_a_keywin
-266 to_mapwin
-267 to_infowin
-268 to_inv
-269 to_logwin
-270 to_g_keywin
-271 to_wg_keywin
-272 to_wk_keywin
-119 winconf
-62 cyc_win_f
-60 cyc_win_b
-262 scrl_l
-360 scrl_r
-82 reload_conf
-67 save_conf
-%
-258 shift_f
-259 shift_b
-42 grow_h
-95 shri_h
-43 grow_v
-45 shri_v
-98 to_break
-121 to_height_t
-120 to_width_t
-%
-258 w_keys_d
-259 w_keys_u
-10 w_keys_m
-%
-kmicl
-m
-%
-0
-Global keys
-0
--13
-29
-258 g_keys_d
-259 g_keys_u
-10 g_keys_m
-%
-1
-Window geometry keys
-0
-8
-29
-258 wg_keys_d
-259 wg_keys_u
-10 wg_keys_m
-%
-2
-Window keybinding keys
-0
-3
-29
-258 wk_keys_d
-259 wk_keys_u
-10 wk_keys_m
-%
-c
-Inventory
-2
-4
-28
-100 drop
-259 inv_u
-258 inv_d
-99 use
-%
-i
-Info
-2
-1
-28
-%
-k
-Available keys
-1
-0
-29
-%
-l
-Log
-0
--7
-28
-%
-m
-Map
-0
-0
--59
-112 pick
-58 wait
-107 move_8
-117 move_9
-108 move_6
-110 move_3
-106 move_2
-98 move_1
-104 move_4
-121 move_7
-259 map_u
-258 map_d
-260 map_l
-261 map_r
-46 map_c
-%
+
+KEYBINDINGS 'global'
+KEY 81 quit
+KEY 265 to_a_keywin
+KEY 266 to_mapwin
+KEY 267 to_infowin
+KEY 268 to_inv
+KEY 269 to_logwin
+KEY 270 to_g_keywin
+KEY 271 to_wg_keywin
+KEY 272 to_wk_keywin
+KEY 119 winconf
+KEY 62 cyc_win_f
+KEY 60 cyc_win_b
+KEY 262 scrl_l
+KEY 360 scrl_r
+KEY 82 reload_conf
+KEY 67 save_conf
+
+KEYBINDINGS 'wingeom'
+KEY 258 shift_f
+KEY 259 shift_b
+KEY 42 grow_h
+KEY 95 shri_h
+KEY 43 grow_v
+KEY 45 shri_v
+KEY 98 to_break
+KEY 121 to_height_t
+KEY 120 to_width_t
+
+KEYBINDINGS 'winkeys'
+KEY 258 w_keys_d
+KEY 259 w_keys_u
+KEY 10 w_keys_m
+
+WIN_ORDER 'kmicl'
+WIN_FOCUS 'm'
+
+WINDOW 1
+NAME 'Window geometry keys'
+BREAK 0
+WIDTH 29
+HEIGHT 8
+KEY 258 wg_keys_d
+KEY 259 wg_keys_u
+KEY 10 wg_keys_m
+
+WINDOW 2
+NAME 'Window keybinding keys'
+BREAK 0
+WIDTH 29
+HEIGHT 3
+KEY 258 wk_keys_d
+KEY 259 wk_keys_u
+KEY 10 wk_keys_m
+
+WINDOW c
+NAME 'Inventory'
+BREAK 2
+WIDTH 28
+HEIGHT 4
+KEY 100 drop
+KEY 259 inv_u
+KEY 258 inv_d
+KEY 99 use
+
+WINDOW i
+NAME 'Info'
+BREAK 2
+WIDTH 28
+HEIGHT 1
+
+WINDOW k
+NAME 'Available keys'
+BREAK 1
+WIDTH 29
+HEIGHT 0
+
+WINDOW l
+NAME 'Log'
+BREAK 0
+WIDTH 28
+HEIGHT -7
+
+WINDOW m
+NAME 'Map'
+BREAK 0
+WIDTH -59
+HEIGHT 0
+KEY 112 pick
+KEY 58 wait
+KEY 107 move_8
+KEY 117 move_9
+KEY 108 move_6
+KEY 110 move_3
+KEY 106 move_2
+KEY 98 move_1
+KEY 104 move_4
+KEY 121 move_7
+KEY 259 map_u
+KEY 258 map_d
+KEY 260 map_l
+KEY 261 map_r
+KEY 46 map_c
+
+WINDOW 0
+NAME 'Global keys'
+BREAK 0
+WIDTH 29
+HEIGHT -13
+KEY 258 g_keys_d
+KEY 259 g_keys_u
+KEY 10 g_keys_m
#include <stdint.h> /* uint8_t */
#include <stdlib.h> /* free() */
#include <string.h> /* memset(), strcmp(), strdup() */
-#include "../common/err_try_fgets.h" /* err_line() */
-#include "../common/parse_file.h" /* Context, EDIT_STARTED, parse_file(),
- * set_val()
+#include "../common/parse_file.h" /* EDIT_STARTED, parse_file(), set_val(),
+ * token_from_line(), err_line()
*/
-#include "../common/rexit.h" /* exit_trouble() */
#include "../common/try_malloc.h" /* try_malloc() */
#include "array_append.h" /* array_append() */
#include "world.h" /* global world */
* assembled, and when additionally a) a new entry is started by a
* context->token0 of "COMMAND"; or b) a NULL context->token0 is passed.
*/
-static void tokens_into_entries(struct Context * context);
+static void tokens_into_entries(char * token0, char * token1);
-static void tokens_into_entries(struct Context * context)
+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 (!context->token0 || !strcmp(context->token0, str_cmd))
+ if (!token0 || !strcmp(token0, str_cmd))
{
char * err_fin = "Last definition block not finished yet.";
- err_line((cmd_flags & READY_CMD) ^ READY_CMD,
- context->line, context->err_pre, err_fin);
+ err_line((cmd_flags & READY_CMD) ^ READY_CMD, err_fin);
if (cmd)
{
array_append(world.commandDB.n, sizeof(struct Command),
(void *) cmd, (void **) &world.commandDB.cmds);
world.commandDB.n++;
+ free(cmd);
cmd = NULL;
}
}
- if (context->token0 && !strcmp(context->token0, str_cmd))
+ err_line(token0 && NULL != token_from_line(NULL), "Too many values.");
+ if (token0 && !strcmp(token0, str_cmd))
{
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(context->token1);
- err_line(NULL != get_command(cmd->dsc_short),
- context->line, context->err_pre, err_uniq);
+ cmd->dsc_short = strdup(token1);
+ err_line(NULL != get_command(cmd->dsc_short), err_uniq);
}
- else if ( context->token0
- && !( set_val(context, "DESCRIPTION", &cmd_flags,
+ else if ( token0
+ && !( set_val(token0, token1, "DESCRIPTION", &cmd_flags,
DESC_SET, 's', (char *) &cmd->dsc_long)
- || set_val(context, "SERVER_COMMAND", &cmd_flags,
+ || set_val(token0, token1, "SERVER_COMMAND", &cmd_flags,
SERVERCMD_SET, 's', (char *) &cmd->server_msg)
- || set_val(context, "SERVER_ARGUMENT", &cmd_flags,
+ || set_val(token0, token1, "SERVER_ARGUMENT", &cmd_flags,
SERVERARG_SET, 'c', (char *) &cmd->arg)))
{
- char * err_unknown = "Unknown argument.";
- err_line(1, context->line, context->err_pre, err_unknown);
+ err_line(1, "Unknown arguemnt.");
}
}
*/
extern struct Command * get_command(char * dsc_short);
-/* Reads in CommandDB config file. */
+/* Read in CommandDB config file. */
extern void init_command_db();
/* Free all memory allocated with init_command_db. */
add_line(win, "(none)", 0, &offset, 0);
return;
}
- uint16_t kb_n;
+ uint8_t kb_n;
for (kb_n = 0; kb_n < kbdb->n_of_kbs; kb_n++)
{
attr_t attri = 0;
struct KeyBindingDB * kbdb)
{
uint8_t state = 0;
- uint16_t kb_n = 0;
+ uint8_t kb_n = 0;
while (0 == state || kb_n < kbdb->n_of_kbs)
{
if (0 == state)
/* src/client/interface_conf.c */
-#define _POSIX_C_SOURCE 2 /* getopt(), optarg */
+#define _POSIX_C_SOURCE 200809L /* getopt(), optarg, strdup() */
#include "interface_conf.h"
#include <ncurses.h> /* delwin() */
-#include <stdint.h> /* uint8_t, uint32_t */
+#include <stddef.h> /* NULL, size_t */
+#include <stdint.h> /* UINT8_MAX, uint8_t, uint32_t */
+#include <stdlib.h> /* EXIT_SUCCESS, atoi(), exit(), free() */
#include <stdio.h> /* FILE, sprintf() */
-#include <stdlib.h> /* free(), exit() */
-#include <string.h> /* strlen() */
-#include <unistd.h> /* global optarg, getopt() */
-#include "../common/err_try_fgets.h" /* reset_err_try_fgets_counter() */
-#include "../common/readwrite.h" /* try_fopen(), try_fclose(), textfile_width(),
- * try_fclose_unlink_rename(),
+#include <string.h> /* memset(), strchr(), strcmp(), strdup(), strlen() */
+#include <unistd.h> /* optarg, getopt() */
+#include "../common/parse_file.h" /* EDIT_STARTED, parse_file(), set_val(),
+ * token_from_line()
+ */
+#include "../common/readwrite.h" /* try_fopen(), try_fclose_unlink_rename(),
+ * try_fwrite()
*/
-#include "../common/rexit.h" /* exit_err() */
+#include "../common/rexit.h" /* exit_err(), exit_trouble() */
+#include "../common/try_malloc.h" /* try_malloc() */
+#include "array_append.h" /* array_append() */
#include "cleanup.h" /* set_cleanup_flag() */
-#include "keybindings.h" /* read_keybindings_from_file(),
- * write_keybindings_to_file()
- */
+#include "command_db.h" /* get_command() */
+#include "keybindings.h" /* KeyBinding, KeyBindingDB, get_command_to_keycode() */
#include "map.h" /* map_center() */
#include "wincontrol.h" /* toggle_window() */
-#include "windows.h" /* free_winDB(), make_v_screen_and_init_win_sizes(),
- * read_winconf_from_file(), write_winconf_of_id_to_file(),
- */
+#include "windows.h" /* Win, free_winDB(), make_v_screen_and_init_win_sizes() */
#include "world.h" /* global world */
+/* Editing state flags set / checked in tokens_into_entries(). */
+enum flag
+{
+ NAME_SET = 0x02,
+ WIDTH_SET = 0x04,
+ HEIGHT_SET = 0x08,
+ BREAK_SET = 0x10,
+ FOCUS_SET = 0x02,
+ READY_WIN = NAME_SET | WIDTH_SET | HEIGHT_SET | BREAK_SET,
+ READY_ORD = 0x00,
+ READY_KBD = 0x00
+};
+
+
+
+/* Used in load_interface_conf() to temporarily store designated values for
+ * world.winDB.order and world.winDB.active. If those were set right away
+ * without all windows having already been initialized, orderly exits on error
+ * would be impossible, for windows are cleaned out by working toggling them off
+ * piece by peice following these values in unload_interfac_conf().
+ */
+static char * tmp_order;
+static char tmp_active;
+
+
+
+/* Write into "file" keybindings in "kbdb" in config file format. */
+static void write_keybindings(FILE * file, struct KeyBindingDB * kbdb);
+
+/* Write into file "val" interpreted as pointing either to string (type = 's'),
+ * int16 ('i') or char ('c'), prefixed with "prefix" and put into single quotes
+ * if 0 != "quotes".
+ */
+static void write_def(FILE * file, char * prefix, uint8_t quotes, char * val,
+ char type);
+
+/* Read in "token0" and "token1" as interface config definition lines, apply
+ * definitions to WinDB, KeyBindingsDBs and tmp_order/tmp_active. If argument is
+ * "KEY", get third token via token_from_line() for complete keybinding.
+ */
+static void tokens_into_entries(char * token0, char * token1);
+
+/* If "win" points to non-NULL Win struct, append to it to WinDB.wins array and
+ * add its ID to world.winDB.ids.
+ */
+static void write_if_win(struct Win ** win);
+
+/* Start block setting data for window "token1" id if "token0" == "str_win".*/
+static uint8_t start_win(char * token0, char * token1, char * str_win,
+ uint8_t * win_flags, struct Win ** win);
+
+/* Start block setting window order and focus if "token0" = "str_ord".
+ * "tmp_order" stores the designated world.winDB.order string (only later to
+ * be realized in load_interface_conf() when all windows have been initialized),
+ * as does "tmp_active" for the designated world.winDB.active char, defaulting
+ * to the first char in the window order string if not otherwise specified.
+ */
+static uint8_t start_ord(char * token0, char * token1, char * str_ord,
+ uint8_t * ord_flags);
+
+/* Start block setting non-window-specific keybindings if "token0" == "str_kbd".
+ * "token1" must be "global", "wingeom" or "winkeys" to set KeyBindingDB to edit
+ * ("kbdb") to world.kb_global, world.kb_wingeom or world.kb_winkeys.
+ */
+static uint8_t start_kbd(char * token0, char * token1, char * str_kbd,
+ uint8_t * kbd_flags, struct KeyBindingDB ** kbdb);
+
+/* Helper to tokens_into_entries(), sets specific entry member data. "token0"
+ * and the state of flags determine what entry member to edit; "win" and "kbdb"
+ * are entries to write "token1" data into (as is the global "tmp_active"). If
+ * "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,
+ 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,
+ struct KeyBindingDB * kbdb);
+
+
+
+static void write_keybindings(FILE * file, struct KeyBindingDB * kbdb)
+{
+ char * f_name = "write_keybindings()";
+ char * sep = " ";
+ char * tok0 = "KEY";
+ uint8_t i_kb;
+ for (i_kb = 0; i_kb < kbdb->n_of_kbs; i_kb++)
+ {
+ size_t size = strlen(tok0) + strlen(sep) + 3 + strlen(sep)
+ + strlen(kbdb->kbs[i_kb].command->dsc_short) + 1 + 1;
+ char * line = try_malloc(size, f_name);
+ int test = snprintf(line, size, "%s%s%d%s%s\n",
+ tok0, sep, kbdb->kbs[i_kb].keycode, sep,
+ kbdb->kbs[i_kb].command->dsc_short);
+ exit_trouble(test < 0, f_name, "snprintf()");
+ try_fwrite(line, sizeof(char), strlen(line), file, f_name);
+ free(line);
+ }
+}
+
+
+
+static void write_def(FILE * file, char * prefix, uint8_t quotes, char * val,
+ char type)
+{
+ char * f_name = "write_def()";
+ char * val_str;
+ int test_val_str = 1;
+ if ('s' == type)
+ {
+ val_str = strdup(val);
+ }
+ if ('i' == type)
+ {
+ size_t size_val_str = 6 + 1;
+ val_str = try_malloc(size_val_str, f_name);
+ test_val_str = snprintf(val_str, size_val_str, "%d", (int16_t) *val);
+ }
+ else if ('c' == type)
+ {
+ size_t size_val_str = 1 + 1;
+ val_str = try_malloc(size_val_str, f_name);
+ test_val_str = snprintf(val_str, size_val_str, "%c", * val);
+ }
+ exit_trouble(test_val_str < 0, f_name, "snprintf()");
+ char * quote = quotes ? "'": "";
+ char * affix = "\n";
+ size_t size = strlen(prefix) + strlen(val_str) + (2 * strlen(quote))
+ + strlen(affix) + 1;
+ char * line = try_malloc(size, f_name);
+ int test = snprintf(line, size, "%s%s%s%s%s",
+ prefix, quote, val_str, quote, affix);
+ exit_trouble(test < 0, f_name, "snprintf()");
+ free(val_str);
+ try_fwrite(line, sizeof(char), strlen(line), file, f_name);
+ free(line);
+}
+
+
+
+static void tokens_into_entries(char * token0, char * token1)
+{
+ char * str_win = "WINDOW";
+ char * str_ord = "WIN_ORDER";
+ char * str_kbd = "KEYBINDINGS";
+ static uint8_t win_flags = READY_WIN;
+ static uint8_t ord_flags = READY_ORD;
+ static uint8_t kbd_flags = READY_KBD;
+ static struct Win * win = NULL;
+ static struct KeyBindingDB * kbdb = NULL;
+ if (!token0 || !strcmp(token0, str_win) || !strcmp(token0, str_ord)
+ || !strcmp(token0, str_kbd))
+ {
+ err_line( ((win_flags & READY_WIN) ^ READY_WIN)
+ || ((ord_flags & READY_ORD) ^ READY_ORD)
+ || ((kbd_flags & READY_KBD) ^ READY_KBD),
+ "Last definition block not yet finished yet.");
+ write_if_win(&win);
+ ord_flags = READY_ORD;
+ win_flags = READY_WIN;
+ kbd_flags = READY_KBD;
+ }
+ 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.");
+ }
+}
+
+
+
+static void write_if_win(struct Win ** win)
+{
+ char * f_name = "write_if_win()";
+ if (*win)
+ {
+ (*win)->target_height_type = (0 >= (*win)->target_height);
+ (*win)->target_width_type = (0 >= (*win)->target_width);;
+ size_t old_ids_size = strlen(world.winDB.ids);
+ size_t new_size = old_ids_size + 1 + 1;
+ char * new_ids = try_malloc(new_size, f_name);
+ int test = snprintf(new_ids,new_size,"%s%c",world.winDB.ids,(*win)->id);
+ exit_trouble(test < 0, f_name, "snprintf()");
+ free(world.winDB.ids);
+ world.winDB.ids = new_ids;
+ array_append(old_ids_size, sizeof(struct Win), *win,
+ (void **) &world.winDB.wins);
+ free(*win);
+ *win = NULL;
+ }
+}
+
+
+
+static uint8_t start_win(char * token0, char * token1, char * str_win,
+ uint8_t * win_flags, struct Win ** win)
+{
+ if (strcmp(token0, 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)->id = token1[0];
+ return 1;
+}
+
+
+
+static uint8_t start_ord(char * token0, char * token1, char * str_ord,
+ uint8_t * ord_flags)
+{
+ if (strcmp(token0, str_ord))
+ {
+ return 0;
+ }
+ *ord_flags = EDIT_STARTED;
+ uint32_t i = 0;
+ for (; i < strlen(token1); i++)
+ {
+ err_line(!strchr(world.winDB.legal_ids, token1[i]), "Illegal ID(s).");
+ }
+ free(tmp_order);
+ tmp_order = strdup(token1);
+ if (0 < strlen(tmp_order))
+ {
+ tmp_active = tmp_order[0];
+ }
+ return 1;
+}
+
+
+
+static uint8_t start_kbd(char * token0, char * token1, char * str_kbd,
+ uint8_t * kbd_flags, struct KeyBindingDB ** kbdb)
+{
+ if (strcmp(token0, str_kbd))
+ {
+ return 0;
+ }
+ *kbd_flags = EDIT_STARTED;
+ if (!strcmp(token1, "global"))
+ {
+ *kbdb = &world.kb_global;
+ }
+ else if (!strcmp(token1, "wingeom"))
+ {
+ *kbdb = &world.kb_wingeom;
+ }
+ else if (!strcmp(token1, "winkeys"))
+ {
+ *kbdb = &world.kb_winkeys;
+ }
+ else
+ {
+ err_line(1, "Value must be 'global', 'wingeom' or 'winkeys'.");
+ }
+ return 1;
+}
+
+
+
+static uint8_t set_members(char * token0, char * token1, char * token2,
+ 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))
+ {
+ 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))
+ {
+ char * err_null = "Value not empty as it should be.";
+ char * err_outside = "ID not found in WIN_ORDER ID series.";
+ err_line(!strlen(tmp_order) && tmp_active, err_null);
+ err_line(!strchr(tmp_order, tmp_active), err_outside);
+ }
+ else if (!strcmp(token0, "KEY"))
+ {
+ err_line(NULL != token_from_line(NULL), "Too many values.");
+ if (* win_flags & EDIT_STARTED)
+ {
+ set_keybindings(token1, token2, * win_flags, &win->kb);
+ }
+ else
+ {
+ set_keybindings(token1, token2, kbd_flags, kbdb);
+ }
+ }
+ else
+ {
+ return 0;
+ }
+ return 1;
+}
+
+
+
+static void set_keybindings(char * token1, char * token2, 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);
+ err_line(!token2, "No binding to key given.");
+ 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;
+ uint8_t test = strlen(token1);
+ err_line(!test, err_code);
+ uint8_t i;
+ for (i = 0; '\0' != token1[i]; i++)
+ {
+ test= i > 2 || '0' > token1[i] || '9' < token1[i];
+ err_line(test, err_code);
+ }
+ kb.keycode = atoi(token1);
+ char * err_uniq = "Binding to key already defined.";
+ err_line(NULL != get_command_to_keycode(kbdb, kb.keycode), err_uniq);
+ kb.command = get_command(token2);
+ err_line(!(kb.command), "No such command in command DB.");
+ array_append(kbdb->n_of_kbs, sizeof(struct KeyBinding), (void *) &kb,
+ (void **) kbdb);
+ kbdb->n_of_kbs++;
+}
+
+
+
extern void obey_argv(int argc, char * argv[])
{
int opt;
{
char * f_name = "save_interface_conf()";
char * path = world.path_interface;
- char path_tmp[strlen(path) + 4 + 1];
- sprintf(path_tmp, "%s_tmp", path);
+ size_t size = strlen(path) + 4 + 1;
+ char * path_tmp = try_malloc(size, f_name);
+ int test = snprintf(path_tmp, size, "%s_tmp", path);
+ exit_trouble(test < 0, f_name, "snprintf()");
FILE * file = try_fopen(path_tmp, "w", f_name);
- write_keybindings_to_file(file, &world.kb_global);
- write_keybindings_to_file(file, &world.kb_wingeom);
- write_keybindings_to_file(file, &world.kb_winkeys);
- write_order_wins_visible_active(file);
+ char * str_keybs = "\nKEYBINDINGS ";
+ write_def(file, str_keybs, 1, "global", 's');
+ write_keybindings(file, &world.kb_global);
+ write_def(file, str_keybs, 1, "wingeom", 's');
+ write_keybindings(file, &world.kb_wingeom);
+ write_def(file, str_keybs, 1, "winkeys", 's');
+ write_keybindings(file, &world.kb_winkeys);
+ write_def(file, "\nWIN_ORDER ", 1, world.winDB.order, 's');
+ if (world.winDB.active)
+ {
+ write_def(file, "WIN_FOCUS ", 1, &world.winDB.active, 'c');
+ }
uint8_t i;
for (i = 0; i < strlen(world.winDB.ids); i++)
{
- write_winconf_of_id_to_file(file, world.winDB.ids[i]);
+ write_def(file, "\nWINDOW ", 0, &world.winDB.ids[i], 'c');
+ struct Win * win = get_win_by_id(world.winDB.ids[i]);
+ write_def(file, "NAME ", 1, win->title, 's');
+ write_def(file, "BREAK ", 0, (char *) &win->linebreak, 'i');
+ write_def(file, "WIDTH ", 0, (char *) &win->target_width, 'i');
+ write_def(file, "HEIGHT ", 0, (char *) &win->target_height, 'i');
+ write_keybindings(file, &win->kb);
}
try_fclose_unlink_rename(file, path_tmp, path, f_name);
+ free(path_tmp);
}
extern void load_interface_conf()
{
char * f_name = "load_interface_conf()";
-
- /* Read keybindings and WincConf DB from interface config file. */
- reset_err_try_fgets_counter();
- FILE * file = try_fopen(world.path_interface, "r", f_name);
- uint32_t linemax = textfile_width(file);
- char line[linemax + 1];
- read_keybindings_from_file(line, linemax, file, &world.kb_global);
- read_keybindings_from_file(line, linemax, file, &world.kb_wingeom);
- read_keybindings_from_file(line, linemax, file, &world.kb_winkeys);
- char active_tmp;
- char * order_tmp;
- read_order_wins_visible_active(line, linemax, file, &order_tmp,&active_tmp);
- while (read_winconf_from_file(line, linemax, file));
- try_fclose(file, f_name);
-
- /* Check that windows of all legal IDs have been initalized. The validity of
- * this test relies on read_winconf_from_file() failing on duplicates. Only
- * on success initialize the windows as visible, to enable safe cleaning up.
- */
- char * err = "Failed to initialize all expected windows.";
+ world.winDB.ids = try_malloc(1, f_name);
+ world.winDB.ids[0] = '\0';
+ world.winDB.wins = NULL;
+ tmp_order = try_malloc(1, f_name);
+ tmp_order[0] = '\0';
+ tmp_active = '\0';
+ parse_file(world.path_interface, tokens_into_entries);
+ char * err = "Not all expected windows defined in config file.";
exit_err(strlen(world.winDB.legal_ids) != strlen(world.winDB.ids), err);
- world.winDB.active = active_tmp;
- world.winDB.order = order_tmp;
-
- /* Build windows as defined by read interface data and toggle them on. */
make_v_screen_and_init_win_sizes();
- char tmp_active = world.winDB.active;
- char tmp_order[strlen(world.winDB.order) + 1];
- sprintf(tmp_order, "%s", world.winDB.order);
+ world.winDB.order = try_malloc(1, f_name);
world.winDB.order[0] = '\0';
uint8_t i;
for (i = 0; i < strlen(tmp_order); toggle_window(tmp_order[i]), i++);
world.winDB.active = tmp_active;
-
- /* So that the interface config data and the window structs get freed. */
+ free(tmp_order);
set_cleanup_flag(CLEANUP_INTERFACE);
}
{
free(world.kb_global.kbs);
world.kb_global.kbs = NULL;
+ world.kb_global.n_of_kbs = 0;
free(world.kb_wingeom.kbs);
world.kb_wingeom.kbs = NULL;
+ world.kb_wingeom.n_of_kbs = 0;
free(world.kb_winkeys.kbs);
world.kb_winkeys.kbs = NULL;
+ world.kb_winkeys.n_of_kbs = 0;
while ('\0' != world.winDB.active)
{
toggle_window(world.winDB.active);
map_center();
world.winDB.v_screen_offset = 0;
}
+
#include <stddef.h> /* NULL */
#include <stdint.h> /* uint8_t, uint16_t, uint32_t */
#include <stdio.h> /* FILE, sprintf() */
-#include <stdlib.h> /* atoi() */
-#include <string.h> /* 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 "array_append.h" /* array_append() */
#include "windows.h" /* draw_all_wins() */
#include "world.h" /* global world */
-
+struct Command;
/* Return pointer to global keybindings or to keybindings for wingeometry config
extern struct Command * get_command_to_keycode(struct KeyBindingDB * kbdb,
uint16_t keycode)
{
- uint16_t n_kb;
+ uint8_t n_kb;
for (n_kb = 0; n_kb < kbdb->n_of_kbs; n_kb++)
{
if (keycode == kbdb->kbs[n_kb].keycode)
-extern void write_keybindings_to_file(FILE * file, struct KeyBindingDB * kbd)
-{
- char * f_name = "write_keybindings_to_file()";
- uint16_t linemax = 0;
- uint16_t n_kb;
- for (n_kb = 0; n_kb < kbd->n_of_kbs; n_kb++)
- {
- if (strlen(kbd->kbs[n_kb].command->dsc_short) > linemax)
- {
- linemax = strlen(kbd->kbs[n_kb].command->dsc_short);
- }
- }
- linemax = linemax + 6; /* + 6 = + 3 digits + ' ' + '\n' + '\0' */
- char line[linemax];
- for (n_kb = 0; n_kb < kbd->n_of_kbs; n_kb++)
- {
- sprintf(line, "%d %s\n",
- kbd->kbs[n_kb].keycode, kbd->kbs[n_kb].command->dsc_short);
- try_fwrite(line, sizeof(char), strlen(line), file, f_name);
- }
- try_fwrite(world.delim, strlen(world.delim), 1, file, f_name);
-}
-
-
-
-extern void read_keybindings_from_file(char * line, uint32_t linemax,
- FILE * file, struct KeyBindingDB * kbdb)
-{
- char * context = "Failed reading keybindings from interface config file. ";
- char * err_space = "Line illegally ends in whitespace.";
- char * err_nospace = "No whitespace found in line.";
- char * err_int = "Line starts not with a decimal number in digits.";
- char * err_toolarge = "Keycode number too large, must be below 1000.";
- char * err_cmd = "No such command in command DB.";
- kbdb->n_of_kbs = 0;
- while (1)
- {
- err_try_fgets(line, linemax, file, context, "0nf");
- if (!strcmp(world.delim, line))
- {
- break;
- }
- err_line(' ' == line[strlen(line) - 2], line, context, err_space);
- char * ptr_space;
- err_line(!(ptr_space = strchr(line, ' ')), line, context, err_nospace);
- uint8_t i = 0;
- err_line(0 == (ptr_space - line), line, context, err_int);
- for (; i < (ptr_space - line); i++)
- {
- err_line(line[i] < '0' || '9' < line[i], line, context, err_int);
- }
- err_line(i > 3, line, context, err_toolarge);
-
- struct KeyBinding kb;
- line[strlen(line) - 1] = '\0';
- kb.command = get_command(ptr_space + 1);
- err_line(!(kb.command), line, context, err_cmd);
- kb.keycode = atoi(line);
- array_append(kbdb->n_of_kbs, sizeof(struct KeyBinding), (void *) &kb,
- (void **) kbdb);
- kbdb->n_of_kbs++;
- }
-}
-
-
-
extern void mod_selected_keyb(char kb_c)
{
struct KeyBindingDB * kbdb = char_selected_kb_db(kb_c);
#define KEYBINDINGS_H
#include <stdint.h> /* uint8_t, uint16_t */
-#include <stdio.h> /* FILE */
struct Command;
struct KeyBindingDB
{
struct KeyBinding * kbs;
- uint16_t n_of_kbs; /* how many KeyBinding structs are stored below .kbs? */
- uint16_t select; /* linear list index of keybinding selected for editing */
- uint8_t edit; /* 1 if currently editing a keybinding, else 0 */
+ uint8_t n_of_kbs; /* how many KeyBinding structs are stored below .kbs? */
+ uint8_t select; /* linear list index of keybinding selected for editing */
+ uint8_t edit; /* 1 if currently editing a keybinding, else 0 */
};
*/
extern char * get_keyname_to_keycode(uint16_t keycode);
-/* Read/write from/to "file" "kbd", delimited by world.delim. */
-extern void write_keybindings_to_file(FILE * file, struct KeyBindingDB * kbd);
-extern void read_keybindings_from_file(char * line, uint32_t linemax,
- FILE * file, struct KeyBindingDB * kbd);
-
/* Mark keybinding in KeybindingDB (char_selected_kb_db()-) selected by "kb_c"
* as being edited, get user input to modify it, then unmark it again. Ensure
* there are max. three digits in the ASCII string of the kecode read from user.
#include <stdlib.h> /* exit() */
#include <string.h> /* memset() */
#include <unistd.h> /* access() */
-#include "../common/err_try_fgets.h" /* set_err_try_fgets_delim() */
#include "../common/readwrite.h" /* try_fopen() */
#include "../common/rexit.h" /* set_cleanup_func(), exit_trouble(),exit_err() */
#include "cleanup.h" /* cleanup(), set_cleanup_flag() */
world.path_commands = "confclient/commands";
world.path_interface = "confclient/interface_conf";
world.winDB.legal_ids = "012ciklm";
- world.delim = "%\n";
- set_err_try_fgets_delim(world.delim);
char * path_server_in = "server/in";
char * path_server_out = "server/out";
#include <stddef.h> /* NULL */
#include <stdint.h> /* uint8_t, uint16_t, uint32_t, UINT16_MAX */
#include <stdio.h> /* sprintf() */
-#include <stdlib.h> /* free(), atoi() */
-#include <string.h> /* 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 <stdlib.h> /* free() */
+#include <string.h> /* memcpy(), strlen(), strnlen(), memset() */
#include "../common/rexit.h" /* exit_trouble(), exit_err() */
-#include "../common/try_malloc.h" /* try_malloc() */
#include "../common/yx_uint16.h" /* struct yx_uint16 */
-#include "array_append.h" /* array_append() */
#include "draw_wins.h" /* draw_winconf_geometry(), draw_winconf_keybindings(),
* draw_win_inventory(), draw_win_info(), draw_win_log(),
* draw_win_available_keybindings(), draw_win_map(),
* draw_win_keybindings_winconf_geometry(),
* draw_win_keybindings_global()
*/
-#include "keybindings.h" /* write_keybidings_to_file(),
- * read_keybindings_from_file()
- */
#include "wincontrol.h" /* toggle_window() */
#include "world.h" /* global world */
-extern uint8_t read_winconf_from_file(char * line, uint32_t linemax,
- FILE * file)
-{
- char * f_name = "read_winconf_from_file()";
- char * context = "Failed reading individual window's configuration from "
- "interface config file. ";
- char * err_id = "Illegal ID(s) selected.";
- char * err_2 = "Double-initialized window.";
- char * err_brk = "Illegal line break type index.";
- int test_for_end = try_fgetc(file, f_name);
- if (EOF == test_for_end || '\n' == test_for_end)
- {
- return 0;
- }
- exit_trouble(EOF == ungetc(test_for_end, file), f_name, "ungetc()");
- err_try_fgets(line, linemax, file, context, "ns");
- err_line(NULL == strchr(world.winDB.legal_ids, line[0]), line, context,
- err_id);
- exit_err(world.winDB.ids && NULL!=strchr(world.winDB.ids, line[0]), err_2);
- struct Win win;
- memset(&win, 0, sizeof(struct Win));
- win.id = (char) line[0];
- err_try_fgets(line, linemax, file, context, "0n");
- win.title = try_malloc(strlen(line), f_name);
- memcpy(win.title, line, strlen(line) - 1); /* Eliminate newline char */
- win.title[strlen(line) - 1] = '\0'; /* char at end of string. */
- err_try_fgets(line, linemax, file, context, "0nsi");
- err_line(atoi(line) > 2, line, context, err_brk);
- win.linebreak = atoi(line);
- err_try_fgets(line, linemax, file, context, "0ni");
- win.target_height = atoi(line);
- win.target_height_type = (0 >= win.target_height);
- err_try_fgets(line, linemax, file, context, "0ni");
- win.target_width = atoi(line);
- win.target_width_type = (0 >= win.target_width);
- read_keybindings_from_file(line, linemax, file, &win.kb);
- if (world.winDB.ids)
- {
- uint8_t old_ids_size = strlen(world.winDB.ids);
- char * new_ids = try_malloc(old_ids_size + 1 + 1, f_name);
- sprintf(new_ids, "%s%c", world.winDB.ids, win.id);
- free(world.winDB.ids);
- world.winDB.ids = new_ids;
- array_append(old_ids_size, sizeof(struct Win), (void *) &win,
- (void **) &world.winDB.wins);
- return 1;
- }
- world.winDB.ids = try_malloc(2, f_name);
- sprintf(world.winDB.ids, "%c", win.id);
- world.winDB.wins = try_malloc(sizeof(struct Win), f_name);
- world.winDB.wins[0] = win;
- return 1;
-}
-
-
-
-extern void write_winconf_of_id_to_file(FILE * file, char c)
-{
- char * f_name = "write_winconf_of_id_to_file()";
- struct Win * wc = get_win_by_id(c);
- uint8_t size = strlen(wc->title) + 2;
- if (size < 7) /* Ensure that at least 5 + 2 char fit into line so that */
- { /* the digit representation of any uint16_t may be stored. */
- size = 7;
- }
- char line[size];
- sprintf(line, "%c\n", wc->id);
- try_fwrite(line, sizeof(char), strlen(line), file, f_name);
- sprintf(line, "%s\n", wc->title);
- try_fwrite(line, sizeof(char), strlen(line), file, f_name);
- sprintf(line, "%d\n", wc->linebreak);
- try_fwrite(line, sizeof(char), strlen(line), file, f_name);
- sprintf(line, "%d\n", wc->target_height);
- try_fwrite(line, sizeof(char), strlen(line), file, f_name);
- sprintf(line, "%d\n", wc->target_width);
- try_fwrite(line, sizeof(char), strlen(line), file, f_name);
- write_keybindings_to_file(file, &wc->kb);
-}
-
-
-
-extern void read_order_wins_visible_active(char * line, uint32_t linemax,
- FILE * file, char ** tmp_order,
- char * tmp_active)
-{
- char * f_name = "read_order_wins_visible_active()";
- char * context = "Failed reading order and activation of visible windows "
- "from interface config file. ";
- char * err_id = "Illegal ID(s) selected.";
- err_try_fgets(line, linemax, file, context, "01");
- uint32_t i = 0;
- for (; i < strlen(line) - 1; i++)
- {
- char * test = strchr(world.winDB.legal_ids, line[i]);
- err_line(!test, line, context, err_id);
- }
- line[strlen(line) - 1] = '\0';
- *tmp_order = try_malloc(strlen(line) + 1, f_name);
- sprintf(*tmp_order, "%s", line);
- if (*tmp_order[0])
- {
- err_try_fgets(line, linemax, file, context, "0nfs");
- err_line(NULL == strchr(*tmp_order, line[0]), line, context, err_id);
- *tmp_active = line[0];
- }
- else
- {
- err_try_fgets(line, linemax, file, context, "0ne");
- *tmp_active = '\0';
- }
- err_try_fgets(line, linemax, file, context, "d");
-}
-
-
-
-extern void write_order_wins_visible_active(FILE * file)
-{
- char * f_name = "write_order_wins_visible_active()";
- try_fwrite(world.winDB.order, strlen(world.winDB.order), 1, file, f_name);
- try_fputc('\n', file, f_name);
- try_fputc(world.winDB.active, file, f_name);
- try_fputc('\n', file, f_name);
- try_fwrite(world.delim, strlen(world.delim), 1, file, f_name);
-}
-
-
-
extern void make_v_screen_and_init_win_sizes()
{
char * f_name = "make_v_screen_and_init_win_sizes()";
struct Win * wc = get_win_by_id(id);
free(wc->title);
free(wc->kb.kbs);
- wc->kb.kbs = NULL;
}
- free(world.winDB.ids); /* NULL this since read_winconf_from_file() checks */
- world.winDB.ids = NULL;/* for it to detect its first post-DB-purge round. */
+ free(world.winDB.ids);
free(world.winDB.wins);
free(world.winDB.order);
}
/* Get Win of "id". */
extern struct Win * get_win_by_id(char id);
-/* Read/write individual Win (identified by "c") and world.winDB.order /
- * world.winDB.active from/to "file" up to the world.delim delimiter. Use "line"
- * and "linemax" as expected by try_fgets().
- *
- * Note that read_winconf_from_file() returns 1 on success and 0 if it detects
- * having found the end of the valid interface configuration file by either
- * hitting a EOF or a newline (so empty newlines at the end of the file are ok).
- *
- * Note that read_order_wins_visible_active() only reads the promised values
- * into pointers for temporary storage. This is due to the order in which window
- * data is initialized: winDB.order and winDB.active should only be set when all
- * windows have been initialized, so cleaning up on error is not confused.
- */
-extern uint8_t read_winconf_from_file(char * line, uint32_t linemax,
- FILE * file);
-extern void write_winconf_of_id_to_file(FILE * file, char c);
-extern void read_order_wins_visible_active(char * line, uint32_t linemax,
- FILE * file, char ** tmp_order,
- char * tmp_active);
-extern void write_order_wins_visible_active(FILE * file);
-
/* Builds virtual sreen from .t_screen's size, fits win's sizes to them.*/
extern void make_v_screen_and_init_win_sizes();
char * path_interface; /* path of interface configuration file */
char * path_commands; /* path of commands config file */
char * player_inventory; /* one-item-per-line string list of owned items */
- char * delim; /* delimiter for multi-line blocks in config files */
struct yx_uint8 player_pos; /* coordinates of player on map */
uint16_t turn; /* world/game turn */
uint8_t halfdelay; /* how long to wait for getch() input in io_loop() */
+++ /dev/null
-/* err_try_fgets.c */
-
-#include <stdint.h> /* uint8_t, uint32_t, UINT8_MAX */
-#include <stdio.h> /* FILE, sprintf() */
-#include <stdlib.h> /* atoi() */
-#include <string.h> /* 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()' 'd' 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 char * 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 * err_uint8 = "Value is too large. Must be 255 or less.";
- char * f_name = "err_try_fgets()";
- line[0] = '\0';
- char * fgets_return = 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') || strchr(test, '8'))
- {
- 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);
- }
- err_line(strchr(test, '8') && atoi(line) > UINT8_MAX, line, context,
- err_uint8);
- return fgets_return;
-}
+++ /dev/null
-/* err_try_fgets.h
- *
- * For superficial syntax checks of individual text file lines.
- */
-
-#ifndef ERR_TRY_FGETS_H
-#define ERR_TRY_FGETS_H
-
-#include <stdint.h> /* uint8_t, uint32_t */
-#include <stdio.h> /* 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 for "line" not 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)
- * '8': check for "line" describing an integer smaller than or equal UINT8_MAX
-*/
-extern char * err_try_fgets(char * line, uint32_t linemax, FILE * file,
- char * context, char * test);
-
-
-
-#endif
#define _POSIX_C_SOURCE 200809L /* strdup() */
#include "parse_file.h"
-#include <stddef.h> /* NULL */ // size_t
-#include <stdio.h> /* FILE, sprintf() */
-#include <stdint.h> /* uint8_t, uint32_t */
-#include <stdlib.h> /* free() */ // atoi()
-#include <string.h> /* strchr, strdup(), strlen() */ // strcmp()
+#include <stddef.h> /* size_t, NULL */
+#include <stdio.h> /* FILE, snprintf() */
+#include <stdint.h> /* int16_t,uint8_t,uint32_t, INT16_MIN, UINT{8,16,32}_MAX */
+#include <stdlib.h> /* atoi(), free() */
+#include <string.h> /* strchr, strcmp(), strdup(), strlen() */
#include <unistd.h> /* access(), F_OK */
-#include "err_try_fgets.h" /* err_line(), err_try_fgets(),
- * reset_err_try_fgets_counter()
- */
-#include "readwrite.h" /* try_fopen(),try_fclose(), textfile_width() */
-#include "rexit.h" /* exit_err() */
+#include "readwrite.h" /* try_fopen(), try_fclose(), textfile_width() */
+#include "rexit.h" /* exit_err(), exit_trouble() */
#include "try_malloc.h" /* try_malloc() */
-/* Return next token from "line" or NULL if none is found. Tokens either a)
- * start at the first non-whitespace character and end before the next
- * whitespace character after that; or b) if the first non-whitespace character
- * is a single quote followed by at least one other single quote some time later
- * on the line, the token starts after that first single quote and ends before
- * the second, with the next token_from_line() call starting its token search
- * after that second quote. The only way to return an empty string (instead of
- * NULL) as a token is to delimit the token by two succeeding single quotes.
- * */
-static char * token_from_line(char * line);
+/* Set by parse_file(), used by err_line() for more informative messages. */
+static uint32_t err_line_count = 0;
+static char * err_line_line = NULL;
+static char * err_line_intro = NULL;
+
+
/* Determines the end of the token_from_line() token. */
static void set_token_end(char ** start, char ** limit_char);
-static char * token_from_line(char * line)
+static void set_token_end(char ** start, char ** limit_char)
+{
+ char * end_quote = ('\'' == (* start)[0]) ? strchr(* start + 1, '\''): NULL;
+ * start = (end_quote) ? * start + 1 : *start;
+ if (end_quote)
+ {
+ * end_quote = '\0';
+ * limit_char = end_quote;
+ return;
+ }
+ char * space = strchr(*start, ' ');
+ char * tab = strchr(*start, '\t');
+ space = (!space || (tab && tab < space)) ? tab : space;
+ if (space)
+ {
+ * space = '\0';
+ }
+ *limit_char = strchr(*start, '\0');
+}
+
+
+
+extern void parse_file(char * path, void (* token_to_entry) (char *, char *))
+{
+ char * f_name = "read_new_config_file()";
+ char * prefix = "Failed reading config file: \"";
+ char * affix = "\". ";
+ size_t size = strlen(prefix) + strlen(path) + strlen(affix) + 1;
+ err_line_intro = try_malloc(size, f_name);
+ int test = snprintf(err_line_intro, size, "%s%s%s", prefix, path, affix);
+ exit_trouble(test < 0, f_name, "snprintf()");
+ exit_err(access(path, F_OK), err_line_intro);
+ FILE * file = try_fopen(path, "r", f_name);
+ uint32_t linemax = textfile_width(file);
+ err_line_line = try_malloc(linemax + 1, f_name);
+ err_line_count = 0;
+ err_line(0 == linemax, "File is empty.");
+ char * token0 = NULL; /* For final token_to_entry() if while() stagnates. */
+ char * token1;
+ char * err_val = "No value given.";
+ while (try_fgets(err_line_line, linemax + 1, file, f_name))
+ {
+ err_line_count++;
+ err_line(UINT32_MAX == err_line_count, "Line reaches max lines limit.");
+ char * line_copy = strdup(err_line_line);
+ token0 = token_from_line(line_copy);
+ if (token0)
+ {
+ err_line(0 == (token1 = token_from_line(NULL)), err_val);
+ token_to_entry(token0, token1);
+ token0 = NULL;
+ }
+ free(line_copy);
+ }
+ token_to_entry(token0, token1);
+ try_fclose(file, f_name);
+ free(err_line_line);
+ free(err_line_intro);
+}
+
+
+
+extern void err_line(uint8_t test, char * msg)
+{
+ if (!test)
+ {
+ return;
+ }
+ char * f_name = "err_line()";
+ char * prefix = " Offending line ";
+ char * affix = ":\n";
+ size_t size = strlen(err_line_intro) + strlen(msg) + strlen(prefix)
+ + 10 /* strlen for uint32_t representations */
+ + strlen(affix) + strlen(err_line_line) + 1;
+ char * err = try_malloc(size, f_name);
+ int ret = snprintf(err, size, "%s%s%s%d%s%s", err_line_intro, msg, prefix,
+ err_line_count, affix, err_line_line);
+ exit_trouble(ret < 0, f_name, "snprintf()");
+ exit_err(1, err);
+}
+
+
+
+extern char * token_from_line(char * line)
{
static char * final_char = NULL;
static char * limit_char = NULL;
-static void set_token_end(char ** start, char ** limit_char)
+extern void test_for_int(char * string, char type)
{
- char * end_quote = ('\'' == (*start)[0]) ? strchr(*start + 1, '\'') : NULL;
- *start = (end_quote) ? *start + 1 : *start;
- if (end_quote)
+ char * err;
+ if ('8' == type)
{
- *end_quote = '\0';
- *limit_char = end_quote;
- return;
+ err = "Value must be proper representation of unsigned 8 bit integer.";
}
- char * space = strchr(*start, ' ');
- char * tab = strchr(*start, '\t');
- space = (!space || (tab && tab < space)) ? tab : space;
- if (space)
+ if ('i' == type)
{
- * space = '\0';
+ err = "Value must be proper representation of signed 16 bit integer.";
}
- *limit_char = strchr(*start, '\0');
-}
-
-
-
-extern void set_uint8(struct Context * context, uint8_t * target)
-{
- char * err_uint8 = "Value not unsigned decimal number between 0 and 255.";
+ err_line(strlen(string) < 1, err);
uint8_t i;
- uint8_t is_uint8 = 1;
- for (i = 0; '\0' != context->token1[i]; i++)
+ uint8_t test;
+ for (i = 0; '\0' != string[i]; i++)
{
- if (i > 2 || '0' > context->token1[i] || '9' < context->token1[i])
- {
- is_uint8 = 0;
- }
+ char * err_many = "Value of too many characters.";
+ err_line(string[i + 1] && UINT8_MAX == i, err_many);
+ test = ( (0 == i && ('-' == string[i] || '+' == string[i]))
+ || ('0' <= string[i] && string[i] <= '9'));
+ err_line(!test, err);
}
- if (is_uint8 && atoi(context->token1) > UINT8_MAX)
- {
- is_uint8 = 0;
- }
- err_line(!(is_uint8), context->line, context->err_pre, err_uint8);
- *target = atoi(context->token1);
+ err_line(strlen(string) < 2 && ('-' == string[i] || '+' == string[i]), err);
+ err_line('8'==type && (atoi(string) < 0 || atoi(string) > UINT8_MAX), err);
+ test = 'i'==type && (atoi(string) < INT16_MIN || atoi(string) > INT16_MAX);
+ err_line(test, err);
}
-extern uint8_t set_val(struct Context * context, char * comparand,
+extern uint8_t set_val(char * token0, char * token1, char * comparand,
uint8_t * flags, uint8_t set_flag, char type,
char * element)
{
- char * err_out = "Outside appropriate definition's context.";
- char * err_singlechar = "Value must be single ASCII character.";
- if (!strcmp(context->token0, comparand))
+ if (!strcmp(token0, comparand))
{
- err_line(!(* flags & EDIT_STARTED),
- context->line, context->err_pre, err_out);
- * flags = * flags | set_flag;
+ char * err_out = "Outside appropriate definition's context.";
+ char * err_singlechar = "Value must be single ASCII character.";
+ err_line(!(*flags & EDIT_STARTED), err_out);
+ *flags = *flags | set_flag;
if ('s' == type)
{
- * (char **) element = strdup(context->token1);
+ * (char **) element = strdup(token1);
}
else if ('c' == type)
{
- err_line(1 != strlen(context->token1),
- context->line, context->err_pre, err_singlechar);
- * element = (context->token1)[0];
+ err_line(1 != strlen(token1), err_singlechar);
+ *element = (token1)[0];
}
else if ('8' == type)
{
- set_uint8(context, (uint8_t *) element);
+ test_for_int(token1, '8');
+ * (uint8_t *) element = atoi(token1);
}
- return 1;
- }
- return 0;
-}
-
-
-
-extern void parse_file(char * path, void (* token_to_entry) (struct Context *))
-{
- char * f_name = "read_new_config_file()";
- struct Context context;
- char * err_pre_prefix = "Failed reading config file: \"";
- char * err_pre_affix = "\". ";
- context.err_pre = try_malloc(strlen(err_pre_prefix) + strlen(path)
- + strlen(err_pre_affix) + 1, f_name);
- sprintf(context.err_pre, "%s%s%s", err_pre_prefix, path, err_pre_affix);
- exit_err(access(path, F_OK), context.err_pre);
- FILE * file = try_fopen(path, "r", f_name);
- uint32_t linemax = textfile_width(file);
- context.line = try_malloc(linemax + 1, f_name);
- reset_err_try_fgets_counter();
- err_line(0 == linemax, context.line, context.err_pre, "File is empty.");
- context.token0 = NULL; /* For token_to_entry() if while() stagnates. */
- char * err_val = "No value given.";
- char * err_many = "Too many values.";
- while (err_try_fgets(context.line, linemax + 1, file, context.err_pre, ""))
- {
- char * line_copy = strdup(context.line);
- context.token0 = token_from_line(line_copy);
- if (context.token0)
+ else if ('i' == type)
{
- err_line(0 == (context.token1 = token_from_line(NULL)),
- context.line, context.err_pre, err_val);
- err_line(NULL != token_from_line(NULL),
- context.line, context.err_pre, err_many);
- token_to_entry(&context);
- context.token0 = NULL;
+ test_for_int(token1, 'i');
+ * (int16_t *) element = atoi(token1);
}
- free(line_copy);
+ return 1;
}
- token_to_entry(&context);
- try_fclose(file, f_name);
- free(context.line);
- free(context.err_pre);
+ return 0;
}
-/* Many functions working on config file lines / tokens work with these elements
- * that only change on line change. Makes sense to pass them over together.
- */
-struct Context {
- char * line;
- char * token0;
- char * token1;
- char * err_pre;
-};
-
-
-
enum parse_flags
{
EDIT_STARTED = 0x01
-/* Writes "context"->token1 to "target" only if it describes a proper uint8. */
-extern void set_uint8(struct Context * context, uint8_t * target);
+/* Parse file at "path" by passing each line's first two tokens to
+ * "token_to_entry". Ignore empty line. Non-empty lines must feature at least
+ * two tokens as delimited either be whitespace or single quotes (to allow for
+ * tokens featuring whitespaces). When EOF is reached, token_to_entry() is
+ * called a last time with a first token of NULL.
+ */
+extern void parse_file(char * path, void ( *token_to_entry) (char *, char *));
-/* If "context"->token0 fits "comparand", set "element" to value read from
- * ->token1 as either string (type: "s"), char ("c") or uint8 ("8"), set
- * that element's flag to "flags" and return 1; else return 0.
+/* If "test" != 0, exit on output of "msg" and faulty line and line number as
+ * parsed by parse_file(). (Ought to be called as offspring to parse_file().)
+ */
+extern void err_line(uint8_t test, char * msg);
+
+/* Return next token from "line" or NULL if none is found. Tokens either a)
+ * start at the first non-whitespace character and end before the next
+ * whitespace character after that; or b) if the first non-whitespace character
+ * is a single quote followed by at least one other single quote some time later
+ * on the line, the token starts after that first single quote and ends before
+ * the second, with the next token_from_line() call starting its token search
+ * after that second quote. The only way to return an empty string (instead of
+ * NULL) as a token is to delimit the token by two succeeding single quotes.
+ * */
+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);
+
+/* 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(struct Context * context, char * comparand,
+extern uint8_t set_val(char * token0, char * token1, char * comparand,
uint8_t * flags, uint8_t set_flag, char type,
char * element);
-/* Parse file at "path" by passing each line's tokens to "token_to_entry"
- * encapsulated into "Context". Empty lines are ignored. Non-empty lines have to
- * feature exactly two tokens as delimited either be whitespace or single quotes
- * (to allow for tokens featuring whitespaces). When EOF is reached,
- * token_to_entry() is called a last time with an empty Context.token0.
- */
-extern void parse_file(char * path, void ( *token_to_entry) (struct Context *));
-
#endif
/* src/server/configfile.c */
#include <stddef.h> /* size_t, NULL */
-#include <stdio.h> /* sprintf() */
+#include <stdio.h> /* snprintf() */
#include <stdint.h> /* uint8_t */
#include <stdlib.h> /* atoi(), free() */
#include <string.h> /* strcmp() */
-#include "../common/err_try_fgets.h" /* err_line() */
-#include "../common/parse_file.h" /* Context, EDIT_STARTED, set_val(),
- * set_uint8(), parse_file()
+#include "../common/parse_file.h" /* EDIT_STARTED, set_val(), test_for_int(),
+ * err_line(), parse_file(),token_from_line()
*/
-#include "../common/rexit.h" /* exit_err() */
+#include "../common/rexit.h" /* exit_err(), exit_trouble() */
#include "../common/try_malloc.h" /* try_malloc() */
#include "cleanup.h" /* set_cleanup_flag(), CLEANUP_MAP_OBJ_DEFS,
* CLEANUP_MAP_OBJ_ACTS
-/* What MapObjDef and MapObjAct structs have in common at their top. Used to
- * have common functions run over structs of both types.
+/* What MapObjDef and MapObjAct structs have in common at their top. Use this to
+ * allow same functions run over structs of both types.
*/
struct EntryHead
{
-/* 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 MapObjAct / MapObjDef DB.
+/* Interpret "token0" and "token1" as data to write into the MapObjAct /
+ * MapObjDef DB.
*
* Individual MapObjDef / MapObjAct DB entries are put together line by line
* before being written. Writing only 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 "ACTION" or "OBJECT"; or b) context->token0 is NULL.
+ * a "token0" of "ACTION" or "OBJECT"; or b) "token0" is NULL.
+ *
+ * Also check against the line parse_file() read tokens from having more tokens.
*/
-static void tokens_into_entries(struct Context * context);
+static void tokens_into_entries(char * token0, char * token1);
-/* Start reading a new DB entry of "size" from tokens in "context" if ->token0
- * matches "comparand". Set EDIT_STARTED in "flags" to mark beginning of new
- * entry reading. Check that id of new entry in ->token1 has not already been
- * used in DB starting at "entry_cmp".
+/* Start reading a new DB entry of "size" from tokens if "token0" matches
+ * "comparand". Set EDIT_STARTED in "flags" to mark beginning of new entry
+ * reading. Check that "token1" id of new entry has not already been used in DB
+ * starting at "entry_cmp".
*/
-static uint8_t new_entry(struct Context * context, char * comparand,
+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 void test_corpse_ids();
-/* Try to read tokens in "context" as members for the entry currently edited,
- * which must be either "mod" or "moa". What member of which of the two is set
- * depends on which of "object_flags" and "action_flags" has EDIT_STARTED set
- * and on the key name of ->token0. Return 1 if interpretation succeeds, else 0.
+/* Try to read tokens as members for the entry currently edited, which must be
+ * either "mod" or "moa". What member of which of the two is set depends on
+ * which of "object_flags" and "action_flags" has EDIT_STARTED set and on the
+ * key name in "token0". Return 1 if interpretation succeeds, else 0.
*
* Note that MapObjAct entries' .name also determines their .func.
*/
-static uint8_t set_members(struct Context * context, uint8_t * object_flags,
+static uint8_t set_members(char * token0, char * token1, uint8_t * object_flags,
uint8_t * action_flags, struct MapObjDef * mod,
struct MapObjAct * moa);
-static void tokens_into_entries(struct Context * context)
+static void tokens_into_entries(char * token0, char * token1)
{
char * str_act = "ACTION";
char * str_obj = "OBJECT";
static uint8_t object_flags = READY_OBJ;
static struct EntryHead * moa = NULL;
static struct EntryHead * mod = NULL;
- if ( !context->token0
- || !strcmp(context->token0,str_act) || !strcmp(context->token0,str_obj))
+ if (!token0 || !strcmp(token0,str_act) || !strcmp(token0,str_obj))
{
- char * err_fin = "Last definition block not finished yet.";
- err_line((action_flags & READY_ACT) ^ READY_ACT,
- context->line, context->err_pre, err_fin);
- err_line((object_flags & READY_OBJ) ^ READY_OBJ,
- context->line, context->err_pre, err_fin);
+ err_line( ((action_flags & READY_ACT) ^ READY_ACT)
+ || ((object_flags & READY_OBJ) ^ READY_OBJ),
+ "Last definitino block not finished yet.");
write_if_entry(&moa, (struct EntryHead ***) &moa_p_p);
write_if_entry(&mod, (struct EntryHead ***) &mod_p_p);
- object_flags = action_flags = READY_OBJ;
+ action_flags = READY_ACT;
+ object_flags = READY_OBJ;
}
- if ( context->token0
- && !( new_entry(context, str_act, &action_flags,
+ 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(context, str_obj, &object_flags,
+ || new_entry(token0, token1, str_obj, &object_flags,
sizeof(struct MapObjDef), (struct EntryHead**) &mod,
(struct EntryHead *) world.map_obj_defs)
- || set_members(context, &object_flags, &action_flags,
+ || set_members(token0, token1, &object_flags, &action_flags,
(struct MapObjDef *) mod, (struct MapObjAct *) moa)))
{
- char * err_unknown = "Unknown argument.";
- err_line(1, context->line, context->err_pre, err_unknown);
+ err_line(1, "Unknown argument.");
}
}
-static uint8_t new_entry(struct Context * context, char * comparand,
+static uint8_t new_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()";
- char * err_uni = "Declaration of ID already used.";
- if (!strcmp(context->token0, comparand))
+ if (!strcmp(token0, comparand))
{
+ char * err_uniq = "Declaration of ID already used.";
* flags = EDIT_STARTED;
* entry = try_malloc(size, f_name);
- set_uint8(context, &((*entry)->id));
+ 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,
- context->line, context->err_pre, err_uni);
+ err_line((*entry)->id == entry_cmp->id, err_uniq);
}
return 1;
}
{
if (*entry)
{
- (* entry)->next = NULL;
- ** entry_p_p_p = *entry;
- * entry_p_p_p = &((*entry)->next);
- * entry = NULL; /* So later runs of this don't re-append same entry. */
+ (*entry)->next = NULL;
+ **entry_p_p_p = *entry;
+ *entry_p_p_p = &((*entry)->next);
+ *entry = NULL; /* So later runs of this don't re-append same entry. */
}
}
static void test_corpse_ids()
{
char * f_name = "test_corpse_ids()";
- char * err_corpse_prefix = "In the object definition DB, one object corpse "
- "ID does not reference any known object in the "
- "DB. ID of responsible object: ";
- char * err_corpse = try_malloc(strlen(err_corpse_prefix) + 3 + 1, f_name);
+ char * prefix = "In the object definitions DB, one object corpse ID does "
+ "not reference any known object in the DB. ID of "
+ "responsible object: ";
+ size_t size = strlen(prefix) + 3 + 1; /* 3: uint8_t representation strlen */
+ char * err_corpse = try_malloc(size, f_name);
struct MapObjDef * test_entry_0 = world.map_obj_defs;
for (; test_entry_0; test_entry_0 = test_entry_0->next)
{
corpse_id_found = 1;
}
}
- sprintf(err_corpse, "%s%d", err_corpse_prefix, test_entry_0->id);
+ int test = snprintf(err_corpse, size, "%s%d", prefix, test_entry_0->id);
+ exit_trouble(test < 0, f_name, "snprintf()");
exit_err(!corpse_id_found, err_corpse);
}
free(err_corpse);
-static uint8_t set_members(struct Context * context, uint8_t * object_flags,
+static uint8_t set_members(char * token0, char * token1, uint8_t * object_flags,
uint8_t * action_flags, struct MapObjDef * mod,
struct MapObjAct * moa)
{
- if ( * action_flags & EDIT_STARTED
- && set_val(context, "NAME", action_flags,
+ if ( *action_flags & EDIT_STARTED
+ && set_val(token0, token1, "NAME", action_flags,
NAME_SET, 's', (char *) &moa->name))
{
if (!( try_func_name(moa, "move", actor_move)
*action_flags = *action_flags | NAME_SET;
return 1;
}
- else if ( set_val(context, "NAME", object_flags,
+ else if ( set_val(token0, token1, "NAME", object_flags,
NAME_SET, 's', (char *) &mod->name)
- || set_val(context, "SYMBOL", object_flags,
+ || set_val(token0, token1, "SYMBOL", object_flags,
SYMBOL_SET, 'c', (char *) &mod->char_on_map)
- || set_val(context, "EFFORT", action_flags,
+ || set_val(token0, token1, "EFFORT", action_flags,
EFFORT_SET, '8', (char *) &moa->effort)
- || set_val(context, "LIFEPOINTS", object_flags,
+ || set_val(token0, token1, "LIFEPOINTS", object_flags,
LIFEPOINTS_SET, '8', (char *) &mod->lifepoints)
- || set_val(context, "CONSUMABLE", object_flags,
+ || set_val(token0, token1, "CONSUMABLE", object_flags,
CONSUMABLE_SET, '8', (char *) &mod->consumable)
- || set_val(context, "CORPSE_ID", object_flags,
+ || set_val(token0, token1, "CORPSE_ID", object_flags,
CORPSE_ID_SET, '8', (char *) &mod->corpse_id))
{
return 1;
-static uint8_t try_func_name(struct MapObjAct * moa,
- char * name, void (* func) (struct MapObj *))
+static uint8_t try_func_name(struct MapObjAct * moa, char * name,
+ void (* func) (struct MapObj *))
{
if (0 == strcmp(moa->name, name))
{
/* src/server/init.c */
-//#define _POSIX_C_SOURCE 2 /* getopt(), optarg */
#define _POSIX_C_SOURCE 200809L /* getopt(), optarg, strdup() */
#include "init.h"
#include <errno.h> /* global errno, EEXIST */
#include <sys/types.h> /* time_t */
#include <time.h> /* time() */
#include <unistd.h> /* usleep() */
-#include "../common/err_try_fgets.h" /* err_line() */
#include "../common/readwrite.h" /* try_fopen(), try_fclose_unlink_rename(),
* try_fwrite(), try_fputc(), try_fgetc()
*/
#include <stdio.h> /* printf() */
#include <stdlib.h> /* exit() */
-#include "../common/err_try_fgets.h" /* set_err_try_fgets_delim() */
#include "../common/rexit.h" /* exit_err, set_cleanup_func() */
#include "cleanup.h" /* set_cleanup_flag(), cleanup() */
#include "init.h" /* run_game(), obey_argv(), obey_argv(), setup_server_io(),
world.path_in = "server/in";
world.path_record = "record";
world.tmp_suffix = "_tmp";
- set_err_try_fgets_delim("%%\n");
/* Init map, map object configurations and server i/o files. */
init_map_and_map_objects_configs();
/* Append "text" to game log, or a "." if "text" is the same as the last one. */
static void update_log(char * text);
-/* If "name" fits "moa"->name, set "moa"->func to "func". */
-//static uint8_t try_func_name(struct MapObjAct * moa,
-// char * name, void (* func) (struct MapObj *));
-
/* One actor "wounds" another actor, decrementing his lifepoints and, if they
* reach zero in the process, killing it. Generates appropriate log message.
*/
#define MAP_OBJECTS_H
#include <stdint.h> /* uint8_t */
-//#include <stdio.h> /* FILE */
#include "../common/yx_uint8.h" /* yx_uint8 structs */
-//struct EntrySkeleton;
-/* Read-in to "entry" multi-line entry from MapObjDef config "file", using
- * pre-allocated "line", "linemax" and "context" as input for err_try_fgets().
- */
-//extern void read_map_object_def(char * line, uint32_t linemax, char * context,
-// struct EntrySkeleton * entry, FILE * file);
-
/* Free map object definitions chain starting at "mod_start". */
extern void free_map_object_defs(struct MapObjDef * mod_start);