home · contact · privacy
Client: Fit interface_conf to new config file style. Also, refactorings.
authorChristian Heller <c.heller@plomlompom.de>
Sun, 6 Apr 2014 20:18:02 +0000 (22:18 +0200)
committerChristian Heller <c.heller@plomlompom.de>
Sun, 6 Apr 2014 20:18:02 +0000 (22:18 +0200)
22 files changed:
TODO
confclient/interface_conf
src/client/command_db.c
src/client/command_db.h
src/client/draw_wins.c
src/client/interface_conf.c
src/client/keybindings.c
src/client/keybindings.h
src/client/main.c
src/client/windows.c
src/client/windows.h
src/client/world.h
src/common/err_try_fgets.c [deleted file]
src/common/err_try_fgets.h [deleted file]
src/common/parse_file.c
src/common/parse_file.h
src/server/configfile.c
src/server/init.c
src/server/io.c
src/server/main.c
src/server/map_object_actions.c
src/server/map_objects.h

diff --git a/TODO b/TODO
index 16d126be2371c5374c1ab8b51ad0f58689f9700a..17d136419b53d61ce5a03d2f5d6a540bc328c3b3 100644 (file)
--- a/TODO
+++ b/TODO
@@ -9,8 +9,6 @@ BOTH SERVER/CLIENT:
 
 - 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
@@ -29,5 +27,3 @@ CLIENT:
 - enable toggling of window borders
 
 - make log scrollable
-
-- implement server-config-file-like parsing for client-config-files, too
index 0396282a099e6625f43b31c06318831d205d0164..15ab6e00ee9bdaae5084716eb0f6593be833bcd4 100644 (file)
-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
index a1c3551fc9567ebe919267876cba64a403597d9b..ef84c493fb42f1f04c886d323c61d0bfafd67388 100644 (file)
@@ -6,11 +6,9 @@
 #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 */
@@ -38,49 +36,48 @@ enum cmd_flag
  * 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.");
     }
 }
 
index bed89c433c10e467762b587d3befa52ba4fd0fde..09273d145274830ea2d6871168ece26c6a114f64 100644 (file)
@@ -33,7 +33,7 @@ struct CommandDB
  */
 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. */
index d075d7ab1f8d27ff4e7dacb82de163cdcf49ae32..b55b998bb403ba359ca373d2a12808ef7a922689 100644 (file)
@@ -276,7 +276,7 @@ static void draw_keybinding_config(struct Win * win, struct KeyBindingDB * kbdb,
         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;
@@ -302,7 +302,7 @@ static void draw_titled_keybinding_list(char * title, struct Win * win,
                                         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)
index c668376a44c42f63e7df11399634ff63afb3e454..69ef9eb54675fe2f009359e0de502727103801df 100644 (file)
 /* 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;
@@ -48,19 +409,36 @@ extern void save_interface_conf()
 {
     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);
 }
 
 
@@ -68,41 +446,22 @@ extern void save_interface_conf()
 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);
 }
 
@@ -112,10 +471,13 @@ extern void unload_interface_conf()
 {
     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);
@@ -133,3 +495,4 @@ extern void reload_interface_conf()
     map_center();
     world.winDB.v_screen_offset = 0;
 }
+
index 10cbffba43f48d261f389ca8a3f02d9a27a11b85..4231da492531cf8a832f5e5bc817a8427e724682 100644 (file)
@@ -5,16 +5,10 @@
 #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
@@ -68,7 +62,7 @@ static uint8_t try_keycode(uint16_t keycode_given, char * keyname,
 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)
@@ -121,72 +115,6 @@ extern char * get_keyname_to_keycode(uint16_t 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);
index c6477c855d4882e38dcb3293712edfc2ea506d4d..bc9c0001151340f19c64ea75b4cf775f3cd585ec 100644 (file)
@@ -7,7 +7,6 @@
 #define KEYBINDINGS_H
 
 #include <stdint.h> /* uint8_t, uint16_t */
-#include <stdio.h> /* FILE */
 struct Command;
 
 
@@ -21,9 +20,9 @@ struct KeyBinding
 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 */
 };
 
 
@@ -37,11 +36,6 @@ extern struct Command * get_command_to_keycode(struct KeyBindingDB * kbdb,
  */
 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.
index 569d6f6ccfa2e92627eba39fcbcfad767d9d5cfa..5f48fa2f85c4decd615037d1e90d222e789610e8 100644 (file)
@@ -7,7 +7,6 @@
 #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() */
@@ -31,8 +30,6 @@ int main(int argc, char * argv[])
     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";
 
index e84d652554c74ba12face4114501818193f500ad..4952a4d3a689c029a82a6f2481c13a490fba48b8 100644 (file)
 #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(),
@@ -25,9 +21,6 @@
                         * 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 */
 
@@ -393,133 +386,6 @@ extern struct Win * get_win_by_id(char id)
 
 
 
-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()";
@@ -549,10 +415,8 @@ extern void free_winDB()
         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);
 }
index 1708fab1432b31f1bac6b1aef0acd8e0e41ac319..dd03d8b151138079c0dbd1884c632be391b0d026 100644 (file)
@@ -78,27 +78,6 @@ extern uint16_t center_offset(uint16_t position,
 /* 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();
 
index d27a0a3ff363ed23eb5161e18103fbe7dc68980f..508d1af53ab9fa300c9fae27564ced3757cff080 100644 (file)
@@ -32,7 +32,6 @@ struct World
     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() */
diff --git a/src/common/err_try_fgets.c b/src/common/err_try_fgets.c
deleted file mode 100644 (file)
index 797a442..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/* 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;
-}
diff --git a/src/common/err_try_fgets.h b/src/common/err_try_fgets.h
deleted file mode 100644 (file)
index 7258a88..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/* 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
index d6c6949af396ab8884a5e787e5881823564e3b59..9e55d16fa8eb53aa326d70220d34cbc683ec0df9 100644 (file)
 
 #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;
@@ -69,117 +145,66 @@ static char * token_from_line(char * line)
 
 
 
-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;
 }
index 28865c4a2536188881b38440ef77a8eb703f6fd0..b10f3f36b284e3efc156565b406daa71e9e7e08d 100644 (file)
 
 
 
-/* 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
@@ -29,25 +17,41 @@ enum parse_flags
 
 
 
-/* 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
index e9cb34eed406ade751e71673ee300336b6a5af32..38404bd3a82b9306989d6dce7454d918b10f53ab 100644 (file)
@@ -1,15 +1,14 @@
 /* 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
@@ -38,8 +37,8 @@ enum flag
 
 
 
-/* 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
 {
@@ -49,23 +48,24 @@ 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);
@@ -79,14 +79,14 @@ static void write_if_entry(struct EntryHead ** entry,
  */
 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);
 
@@ -98,7 +98,7 @@ static uint8_t try_func_name(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";
@@ -108,50 +108,48 @@ static void tokens_into_entries(struct Context * context)
     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;
     }
@@ -165,10 +163,10 @@ static void write_if_entry(struct EntryHead ** entry,
 {
     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. */
     }
 }
 
@@ -177,10 +175,11 @@ static void write_if_entry(struct EntryHead ** 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)
     {
@@ -193,7 +192,8 @@ static void test_corpse_ids()
                 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);
@@ -201,12 +201,12 @@ static void test_corpse_ids()
 
 
 
-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)
@@ -219,17 +219,17 @@ static uint8_t set_members(struct Context * context, uint8_t * object_flags,
         *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;
@@ -239,8 +239,8 @@ static uint8_t set_members(struct Context * context, uint8_t * object_flags,
 
 
 
-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))
     {
index 9b3f86b016c2e87154694503d2f77486dff0c652..fec2fcee3216bce835b5d66ee2dfa21b7e7b4427 100644 (file)
@@ -1,6 +1,5 @@
 /* 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 */
index c4c60478ec0253b1c17695e23006afb7baca49fb..8e7f9e9a2716fd632c55df8e6ec0e92083140b36 100644 (file)
@@ -12,7 +12,6 @@
 #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()
                                   */
index 3c8829b7067ec010267382f27d80b04d9da47bcf..642a6fe5179c4f618d0b4aae7de148eb9177f3f1 100644 (file)
@@ -2,7 +2,6 @@
 
 #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(),
@@ -41,7 +40,6 @@ int main(int argc, char ** argv)
     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();
index 987f13581eb86d9a51d521e712035b06763ba4ca..17d74d5825feebad5555a81820ae4a1c7a02914e 100644 (file)
 /* 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.
  */
index 52d87e1a2276101f265a92892cc834b8ef7e12b7..fdd11f91c9180cc4226e199ac3d1a0abba28cc8c 100644 (file)
@@ -8,9 +8,7 @@
 #define MAP_OBJECTS_H
 
 #include <stdint.h> /* uint8_t */
-//#include <stdio.h> /* FILE */
 #include "../common/yx_uint8.h" /* yx_uint8 structs */
-//struct EntrySkeleton;
 
 
 
@@ -40,12 +38,6 @@ struct MapObjDef
 
 
 
-/* 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);