Blame


1 e01be473 2021-09-01 xhr /*
2 e01be473 2021-09-01 xhr * Most of this file is copied from the official GNU readline
3 e01be473 2021-09-01 xhr * documentation: https://tiswww.case.edu/php/chet/readline/readline.html
4 e01be473 2021-09-01 xhr *
5 e01be473 2021-09-01 xhr * The documenation was written by
6 e01be473 2021-09-01 xhr * Lionel Cons <Lionel.Cons@cern.ch> (original author)
7 e01be473 2021-09-01 xhr * Karl Berry <karl@freefriends.org>
8 e01be473 2021-09-01 xhr * Olaf Bachmann <obachman@mathematik.uni-kl.de>
9 e01be473 2021-09-01 xhr * and many others.
10 e01be473 2021-09-01 xhr *
11 e01be473 2021-09-01 xhr * LICENSE: GNU GPL v2
12 e01be473 2021-09-01 xhr */
13 e01be473 2021-09-01 xhr
14 8d4e8d33 2021-09-06 xhr #include <ctype.h>
15 5e7ac800 2021-09-01 xhr #include <limits.h>
16 63354cc5 2021-09-01 xhr #include <stdio.h>
17 63354cc5 2021-09-01 xhr #include <stdlib.h>
18 63354cc5 2021-09-01 xhr #include <string.h>
19 63354cc5 2021-09-01 xhr
20 944c5da4 2021-09-01 xhr #include <readline/readline.h>
21 944c5da4 2021-09-01 xhr #include <readline/history.h>
22 944c5da4 2021-09-01 xhr
23 63354cc5 2021-09-01 xhr #include "isscrolls.h"
24 63354cc5 2021-09-01 xhr
25 63354cc5 2021-09-01 xhr static struct command commands[] = {
26 7e01344c 2021-09-09 xhr { "cd", cmd_cd, "Switch to or from a character", 0 },
27 7e01344c 2021-09-09 xhr { "help", cmd_usage, "Show help", 0 },
28 7e01344c 2021-09-09 xhr { "ls", cmd_ls, "List all characters", 0 },
29 7e01344c 2021-09-09 xhr { "quit", cmd_quit, "Quit the program", 0 },
30 7e01344c 2021-09-09 xhr { "q", cmd_quit, "Quit the program", 1 },
31 7e01344c 2021-09-09 xhr { "--- DICE ROLLS ---", NULL, "", 0 },
32 34a72032 2021-09-02 xhr { "action", cmd_roll_action_dice, "Perform an action roll", 0 },
33 7e01344c 2021-09-09 xhr { "challenge", cmd_roll_challenge_die, "Roll a challenge die", 0 },
34 7e01344c 2021-09-09 xhr { "oracle", cmd_roll_oracle_die, "Roll two challenge dice as oracle", 0 },
35 7e01344c 2021-09-09 xhr { "yesorno", cmd_yes_or_no, "Roll oracle to answer a yes/no question", 0 },
36 f4b73ab5 2021-09-05 xhr { "actionoracle", cmd_show_action, "Show a random action oracle", 0 },
37 7e01344c 2021-09-09 xhr { "--- CHARACTER COMMANDS ---", NULL, "", 0 },
38 834ec24f 2021-09-06 xhr { "create", cmd_create_character, "Create a new character", 0 },
39 2b8ffc2d 2021-09-08 xhr { "delete", cmd_delete_character, "Delete currently loaded character", 0 },
40 7e01344c 2021-09-09 xhr { "print", cmd_print_current_character, "Print current character sheet", 0 },
41 36bd7bb9 2021-09-09 xhr { "decrease", cmd_decrease_value, "Decrease a character's value", 0 },
42 36bd7bb9 2021-09-09 xhr { "increase", cmd_increase_value, "Increase a character's value", 0 },
43 7e01344c 2021-09-09 xhr { "toggle", cmd_toogle, "Toggle character's stats", 0 },
44 7e01344c 2021-09-09 xhr { "--- GAME MOVES ---", NULL, "", 0 },
45 7e01344c 2021-09-09 xhr { "battle", cmd_battle, "Roll a 'battle' move", 0 },
46 7e01344c 2021-09-09 xhr { "clash", cmd_clash, "Roll a 'clash' move", 0 },
47 7e01344c 2021-09-09 xhr { "compel", cmd_compel, "Roll a 'compel' move", 0 },
48 9c58a078 2021-09-09 xhr { "drawthecircle", cmd_draw_the_circle, "Roll a 'draw the circle' move", 0 },
49 36bd7bb9 2021-09-09 xhr { "enterthefray", cmd_enter_the_fray, "Roll a 'enter the fray' move", 0 },
50 3bb102f2 2021-09-09 xhr { "facedanger", cmd_face_danger, "Roll a 'face danger' move", 0 },
51 86c8a615 2021-09-09 xhr { "forgeabond", cmd_forge_a_bond, "Roll a 'forge a bond' move", 0 },
52 7e01344c 2021-09-09 xhr { "gatherinformation", cmd_gather_information, "Roll a 'gather information' move", 0 },
53 7e01344c 2021-09-09 xhr { "makecamp", cmd_make_camp, "Roll a 'make camp' move", 0 },
54 5ee9744e 2021-09-09 xhr { "heal", cmd_heal, "Roll a 'heal' move", 0 },
55 7e01344c 2021-09-09 xhr { "resupply", cmd_resupply, "Roll a 'resupply' move", 0 },
56 7e01344c 2021-09-09 xhr { "sojourn", cmd_sojourn, "Roll a 'sojourn' move", 0 },
57 7e01344c 2021-09-09 xhr { "strike", cmd_strike, "Roll a 'strike' move", 0 },
58 b0cb8082 2021-09-11 xhr { "endthefight", cmd_end_the_fight, "Roll a 'end the fight' move", 0 },
59 7e01344c 2021-09-09 xhr { "swearanironvow", cmd_swear_an_iron_vow, "Roll a 'swear an iron vow' move", 0 },
60 36bd7bb9 2021-09-09 xhr { "undertakeajourney", cmd_undertake_a_journey, "Roll a 'undertake a journey' move", 0 },
61 60bf4095 2021-09-11 xhr { "reachyourdestination", cmd_reach_your_destination, "Roll a 'reach your destination' move", 0 },
62 7e01344c 2021-09-09 xhr { "secureanadvantage", cmd_secure_an_advantage, "Roll a 'secure an advantage' move", 0 },
63 7e01344c 2021-09-09 xhr { "testyourbond", cmd_test_your_bond, "Roll a 'test your bond' move", 0 },
64 babd3f1c 2021-09-13 xhr { "endureharm", cmd_endure_harm, "Roll a 'endure harm' move", 0 },
65 80a35657 2021-09-13 xhr { "endurestress", cmd_endure_stress, "Roll a 'endure stress' move", 0 },
66 d2b9d86f 2021-09-13 xhr { "facedeath", cmd_face_death, "Roll a 'face death' move", 0 },
67 7e01344c 2021-09-09 xhr { "--- ORACLE TABLE ROLLS ---", NULL, "", 0 },
68 7e01344c 2021-09-09 xhr { "coastalwaterlocation", cmd_show_coastal_location, "Show a random coastal water location", 0 },
69 7e01344c 2021-09-09 xhr { "combataction", cmd_show_combat_action, "Show a random combat action move", 0 },
70 7e01344c 2021-09-09 xhr { "elfname", cmd_show_elf_name, "Show a random Elf name", 0 },
71 7e01344c 2021-09-09 xhr { "giantname", cmd_show_giant_name, "Show a random Giant name", 0 },
72 ce559d58 2021-09-05 xhr { "ironlandername", cmd_show_iron_name, "Show a random Ironlander name", 0 },
73 1a26b5c7 2021-09-06 xhr { "location", cmd_show_location, "Show a random location", 0 },
74 1a26b5c7 2021-09-06 xhr { "locationdescription", cmd_show_location_description, "Show a random location description", 0 },
75 d49e0a78 2021-09-05 xhr { "mysticbackslash", cmd_show_mystic_backshlash, "Show a random mystic backlash", 0 },
76 3ad507cb 2021-09-13 xhr { "paytheprice", cmd_show_pay_the_price, "Show a random pay the price result", 0 },
77 323180ed 2021-09-05 xhr { "plottwist", cmd_show_plot_twist, "Show a random major plot twist", 0 },
78 36bd7bb9 2021-09-09 xhr { "rank", cmd_show_rank, "Show a random challenge rank", 0 },
79 1a26b5c7 2021-09-06 xhr { "region", cmd_show_region, "Show a random region", 0 },
80 f4b73ab5 2021-09-05 xhr { "theme", cmd_show_theme, "Show a random theme oracle", 0 },
81 ce559d58 2021-09-05 xhr { "trollname", cmd_show_troll_name, "Show a random Troll name", 0 },
82 ce559d58 2021-09-05 xhr { "varouname", cmd_show_varou_name, "Show a random Varou name", 0 },
83 342aad66 2021-09-01 xhr { (char *)NULL, NULL, (char *)NULL, 0 }
84 63354cc5 2021-09-01 xhr };
85 63354cc5 2021-09-01 xhr
86 63354cc5 2021-09-01 xhr void
87 a844ca20 2021-09-05 xhr cmd_usage(__attribute__((unused)) char *unused)
88 63354cc5 2021-09-01 xhr {
89 63354cc5 2021-09-01 xhr int i;
90 63354cc5 2021-09-01 xhr
91 65fe5659 2021-09-08 xhr printf("%-20s %s\n", "COMMAND", "DESCRIPTION");
92 63354cc5 2021-09-01 xhr for (i=0; commands[i].doc; i++)
93 342aad66 2021-09-01 xhr if (commands[i].alias == 0)
94 65fe5659 2021-09-08 xhr printf("%-20s %s\n", commands[i].name, commands[i].doc);
95 ebfaaf19 2021-09-01 xhr else
96 65fe5659 2021-09-08 xhr printf("%-20s\n", commands[i].name);
97 e2ccc91e 2021-09-09 xhr
98 e2ccc91e 2021-09-09 xhr printf("\nFor more detailed information check the man page: $ man isscrolls\n");
99 63354cc5 2021-09-01 xhr }
100 63354cc5 2021-09-01 xhr
101 63354cc5 2021-09-01 xhr char *
102 63354cc5 2021-09-01 xhr stripwhite (char *string)
103 63354cc5 2021-09-01 xhr {
104 63354cc5 2021-09-01 xhr register char *s, *t;
105 63354cc5 2021-09-01 xhr
106 e2a0c4ad 2021-09-06 xhr for (s = string; isspace (*s); s++)
107 63354cc5 2021-09-01 xhr ;
108 63354cc5 2021-09-01 xhr
109 63354cc5 2021-09-01 xhr if (*s == 0)
110 63354cc5 2021-09-01 xhr return (s);
111 63354cc5 2021-09-01 xhr
112 63354cc5 2021-09-01 xhr t = s + strlen (s) - 1;
113 e2a0c4ad 2021-09-06 xhr while (t > s && isspace (*t))
114 63354cc5 2021-09-01 xhr t--;
115 63354cc5 2021-09-01 xhr
116 63354cc5 2021-09-01 xhr *++t = '\0';
117 63354cc5 2021-09-01 xhr
118 63354cc5 2021-09-01 xhr return s;
119 63354cc5 2021-09-01 xhr }
120 63354cc5 2021-09-01 xhr
121 63354cc5 2021-09-01 xhr struct command *
122 63354cc5 2021-09-01 xhr find_command(char *line)
123 63354cc5 2021-09-01 xhr {
124 63354cc5 2021-09-01 xhr int i;
125 63354cc5 2021-09-01 xhr
126 7e01344c 2021-09-09 xhr for (i=0; commands[i].name; i++) {
127 7e01344c 2021-09-09 xhr /* Skip over --- which is a separator for the cmd_usage() */
128 7e01344c 2021-09-09 xhr if (strncasecmp(line, "---", 3) == 0)
129 7e01344c 2021-09-09 xhr continue;
130 63354cc5 2021-09-01 xhr if (strcasecmp(line, commands[i].name) == 0)
131 63354cc5 2021-09-01 xhr return &commands[i];
132 7e01344c 2021-09-09 xhr }
133 63354cc5 2021-09-01 xhr
134 63354cc5 2021-09-01 xhr return NULL;
135 63354cc5 2021-09-01 xhr }
136 63354cc5 2021-09-01 xhr
137 63354cc5 2021-09-01 xhr void
138 180e58f6 2021-09-06 xhr initialize_readline(const char *base_path)
139 63354cc5 2021-09-01 xhr {
140 5e7ac800 2021-09-01 xhr char hist_path[_POSIX_PATH_MAX];
141 5e7ac800 2021-09-01 xhr
142 63354cc5 2021-09-01 xhr rl_readline_name = "issrolls";
143 63354cc5 2021-09-01 xhr
144 63354cc5 2021-09-01 xhr rl_attempted_completion_function = my_completion;
145 5e7ac800 2021-09-01 xhr
146 5e7ac800 2021-09-01 xhr using_history();
147 5e7ac800 2021-09-01 xhr
148 180e58f6 2021-09-06 xhr snprintf(hist_path, _POSIX_PATH_MAX, "%s/history", base_path);
149 5e7ac800 2021-09-01 xhr
150 180e58f6 2021-09-06 xhr log_debug("Reading history from %s\n", hist_path);
151 5e7ac800 2021-09-01 xhr read_history(hist_path);
152 63354cc5 2021-09-01 xhr }
153 63354cc5 2021-09-01 xhr
154 63354cc5 2021-09-01 xhr char **
155 63354cc5 2021-09-01 xhr my_completion(const char *text, int start, int end)
156 63354cc5 2021-09-01 xhr {
157 63354cc5 2021-09-01 xhr char **matches;
158 63354cc5 2021-09-01 xhr
159 63354cc5 2021-09-01 xhr matches = (char **)NULL;
160 63354cc5 2021-09-01 xhr
161 63354cc5 2021-09-01 xhr if (start == 0)
162 63354cc5 2021-09-01 xhr matches = rl_completion_matches(text, command_generator);
163 63354cc5 2021-09-01 xhr
164 63354cc5 2021-09-01 xhr return matches;
165 63354cc5 2021-09-01 xhr }
166 63354cc5 2021-09-01 xhr
167 63354cc5 2021-09-01 xhr char *
168 63354cc5 2021-09-01 xhr command_generator(const char *text, int state)
169 63354cc5 2021-09-01 xhr {
170 99e16831 2021-09-01 xhr const char *name;
171 63354cc5 2021-09-01 xhr static int list_index, len;
172 63354cc5 2021-09-01 xhr
173 63354cc5 2021-09-01 xhr if (!state) {
174 63354cc5 2021-09-01 xhr list_index = 0;
175 63354cc5 2021-09-01 xhr len = strlen(text);
176 63354cc5 2021-09-01 xhr }
177 63354cc5 2021-09-01 xhr
178 63354cc5 2021-09-01 xhr while ((name = commands[list_index].name)) {
179 63354cc5 2021-09-01 xhr list_index++;
180 63354cc5 2021-09-01 xhr if (strncmp(name, text, len) == 0) {
181 63354cc5 2021-09-01 xhr return strdup(name);
182 63354cc5 2021-09-01 xhr }
183 63354cc5 2021-09-01 xhr }
184 63354cc5 2021-09-01 xhr
185 63354cc5 2021-09-01 xhr return (char *)NULL;
186 63354cc5 2021-09-01 xhr }
187 63354cc5 2021-09-01 xhr
188 63354cc5 2021-09-01 xhr void
189 63354cc5 2021-09-01 xhr execute_command(char *line)
190 63354cc5 2021-09-01 xhr {
191 63354cc5 2021-09-01 xhr struct command *cmd;
192 63354cc5 2021-09-01 xhr char *word;
193 63354cc5 2021-09-01 xhr int i = 0;
194 63354cc5 2021-09-01 xhr
195 63354cc5 2021-09-01 xhr /* Skip over white spaces */
196 e2a0c4ad 2021-09-06 xhr while (line[i] && isspace(line[i]))
197 63354cc5 2021-09-01 xhr i++;
198 63354cc5 2021-09-01 xhr
199 63354cc5 2021-09-01 xhr /* Set to char array after last whitespace */
200 63354cc5 2021-09-01 xhr word = line + i;
201 63354cc5 2021-09-01 xhr
202 e2a0c4ad 2021-09-06 xhr /* Skip over all non-isspace characters */
203 e2a0c4ad 2021-09-06 xhr while (line[i] && !isspace(line[i]))
204 63354cc5 2021-09-01 xhr i++;
205 63354cc5 2021-09-01 xhr
206 63354cc5 2021-09-01 xhr /* If line, is still valid, NUL terminate command word */
207 63354cc5 2021-09-01 xhr if (line[i])
208 63354cc5 2021-09-01 xhr line[i++] = '\0';
209 63354cc5 2021-09-01 xhr
210 63354cc5 2021-09-01 xhr cmd = find_command(word);
211 63354cc5 2021-09-01 xhr
212 63354cc5 2021-09-01 xhr if (cmd == NULL) {
213 63354cc5 2021-09-01 xhr printf("Command not found\n");
214 63354cc5 2021-09-01 xhr return;
215 63354cc5 2021-09-01 xhr }
216 63354cc5 2021-09-01 xhr
217 63354cc5 2021-09-01 xhr /* Skip over white spaces after command line */
218 e2a0c4ad 2021-09-06 xhr while (isspace(line[i]))
219 63354cc5 2021-09-01 xhr i++;
220 63354cc5 2021-09-01 xhr
221 63354cc5 2021-09-01 xhr word = line + i;
222 63354cc5 2021-09-01 xhr
223 63354cc5 2021-09-01 xhr ((*(cmd->cmd)) (word));
224 99e16831 2021-09-01 xhr return;
225 63354cc5 2021-09-01 xhr }