]> git.draconx.ca Git - cdecl99.git/blob - src/execute.gperf
Release 1.3.
[cdecl99.git] / src / execute.gperf
1 %{
2 /*
3  * Copyright © 2021, 2023-2024 Nick Bowler
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
17  */
18
19 #include <config.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <inttypes.h>
23 #include <assert.h>
24
25 #include "cdecl99.h"
26 #include "commands.h"
27 #include "help.h"
28
29 typedef
30 #if STRTAB_MAX_OFFSET < UINT_LEAST8_MAX
31 uint_least8_t
32 #elif STRTAB_MAX_OFFSET < UINT_LEAST16_MAX
33 uint_least16_t
34 #else
35 #error do not know what type to use
36 #endif
37 cmd_index_type;
38
39 static const struct command *in_word_set();
40 %}
41
42 %struct-type
43 %compare-strncmp
44 %readonly-tables
45 %language=ANSI-C
46 %global-table
47 %pic
48
49 struct command {
50         int_least8_t name;
51         cmd_index_type cmd;
52 };
53 %%
54 explain, cmd_explain
55 simplify, cmd_simplify
56 declare, cmd_declare
57 type, cmd_type
58 help, cmd_help
59 quit, cmd_quit
60 exit, cmd_quit
61 %%
62 #include "cmdlist.h"
63
64 static int run_cmd_help(void)
65 {
66         static const unsigned char offsets[] = CMD_SEQ;
67         unsigned i;
68
69         printf("Commands:\n");
70         for (i = 0; i < sizeof offsets / sizeof offsets[0]; i++) {
71                 const struct command *c = &wordlist[offsets[i]];
72                 int w;
73
74                 w = printf("  %s", stringpool+c->name);
75                 if (w <= 0 || w > 13) {
76                         putchar('\n');
77                         w = 0;
78                 }
79
80                 help_print_desc(NULL, gettext(strtab+c->cmd), 15, w);
81         }
82
83         return 0;
84 }
85
86 int run_command(const char *line, int batch)
87 {
88         const char *cmd = line + strspn(line, " \t");
89         const char *arg = cmd + strcspn(cmd, " \t");
90         const struct command *c;
91
92         /* empty command */
93         if (cmd[0] == '\0')
94                 return 0;
95
96         c = in_word_set(cmd, arg-cmd);
97         if (!c) {
98                 print_error(_("unknown command %.*s"), (int)(arg-cmd), cmd);
99                 if (!batch) {
100                         fprintf(stderr, "%s\n",
101                                 _("Try \"help\" for a list of possible commands."));
102                 }
103                 return -1;
104         }
105
106         switch (c->cmd) {
107         case cmd_help:
108                 return run_cmd_help();
109         case cmd_declare: case cmd_type:
110                 return run_command_cdecl(cmd, INPUT_ENGLISH, OUTPUT_C);
111         case cmd_simplify:
112                 return run_command_cdecl(arg, INPUT_C, OUTPUT_C);
113         case cmd_explain:
114                 return run_command_cdecl(arg, INPUT_C, OUTPUT_ENGLISH);
115         case cmd_quit:
116                 return 1;
117         }
118
119         assert(0);
120 }