home · contact · privacy
Minor refactoring in file parsing.
[plomrogue] / src / client / command_db.c
1 /* src/client/command_db.c */
2
3 #define _POSIX_C_SOURCE 200809L /* strdup() */
4 #include "command_db.h"
5 #include <stddef.h> /* NULL */
6 #include <stdint.h> /* uint8_t */
7 #include <stdlib.h> /* free() */
8 #include <string.h> /* memset(), strcmp(), strdup() */
9 #include "../common/parse_file.h" /* EDIT_STARTED, parse_file(), set_val(),
10                                    * token_from_line(), err_line(),
11                                    * finalize_by_readyflag()
12                                    */
13 #include "../common/try_malloc.h" /* try_malloc() */
14 #include "array_append.h" /* array_append() */
15 #include "world.h" /* global world */
16 #include "cleanup.h" /* set_cleanup_flag() */
17
18
19
20 /* Flags for defining state of command DB config file entries. */
21 enum cmd_flag
22 {
23     DESC_SET      = 0x02,
24     SERVERCMD_SET = 0x04,
25     SERVERARG_SET = 0x08,
26     READY_CMD = DESC_SET
27 };
28
29
30
31 /* Get tokens from "context" and, by their order (in the individual context and
32  * in subsequent calls of this function), interpret them as data to write into
33  * the CommandDB.
34  *
35  * Individual CommandDB entries are put together line by line before being
36  * written. Writing happens after all necessary members of an entry have been
37  * assembled, and when additionally a) a new entry is started by a
38  * context->token0 of "COMMAND"; or b) a NULL context->token0 is passed.
39  */
40 static void tokens_into_entries(char * token0, char * token1);
41
42
43
44 static void tokens_into_entries(char * token0, char * token1)
45 {
46     char * f_name = "tokens_into_entries()";
47     char * str_cmd = "COMMAND";
48     static uint8_t cmd_flags = READY_CMD;
49     static struct Command * cmd = NULL;
50     if (!token0 || !strcmp(token0, str_cmd))
51     {
52         finalize_by_readyflag(&cmd_flags, READY_CMD);
53         if (cmd)
54         {
55             array_append(world.commandDB.n, sizeof(struct Command),
56                          (void *) cmd, (void **) &world.commandDB.cmds);
57             world.commandDB.n++;
58             free(cmd);
59             cmd = NULL;
60         }
61     }
62     err_line(token0 && NULL != token_from_line(NULL), "Too many values.");
63     if (token0 && !strcmp(token0, str_cmd))
64     {
65         char * err_uniq = "Declaration of ID already used.";
66         cmd_flags = EDIT_STARTED;
67         cmd = try_malloc(sizeof(struct Command), f_name);
68         memset(cmd, 0, sizeof(struct Command));
69         cmd->dsc_short = strdup(token1);
70         err_line(NULL != get_command(cmd->dsc_short), err_uniq);
71     }
72     else if (   token0
73              && !(   set_val(token0, token1, "DESCRIPTION", &cmd_flags,
74                              DESC_SET, 's', (char *) &cmd->dsc_long)
75                   || set_val(token0, token1, "SERVER_COMMAND", &cmd_flags,
76                              SERVERCMD_SET, 's', (char *) &cmd->server_msg)
77                   || set_val(token0, token1, "SERVER_ARGUMENT", &cmd_flags,
78                              SERVERARG_SET, 'c', (char *) &cmd->arg)))
79     {
80         err_line(1, "Unknown arguemnt.");
81     }
82 }
83
84
85
86 extern struct Command * get_command(char * dsc_short)
87 {
88     struct Command * cmd_ptr = world.commandDB.cmds;
89     uint8_t i = 0;
90     while (i < world.commandDB.n)
91     {
92         if (0 == strcmp(dsc_short, cmd_ptr->dsc_short))
93         {
94             return cmd_ptr;
95         }
96         cmd_ptr = &cmd_ptr[1];
97         i++;
98     }
99     return NULL;
100 }
101
102
103
104 extern void init_command_db()
105 {
106     parse_file(world.path_commands, tokens_into_entries);
107     set_cleanup_flag(CLEANUP_COMMANDS);
108 }
109
110
111
112 extern void free_command_db()
113 {
114     uint8_t i = 0;
115     while (i < world.commandDB.n)
116     {
117         free(world.commandDB.cmds[i].dsc_short);
118         free(world.commandDB.cmds[i].dsc_long);
119         free(world.commandDB.cmds[i].server_msg);
120         i++;
121     }
122     free(world.commandDB.cmds);
123 }