2 * Helper to verify scanner output.
3 * Copyright © 2023 Nick Bowler
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.
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.
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/>.
25 #include "cdecl-internal.h"
29 static union { struct parse_item item; char buf[1000]; } stub_item;
30 struct parse_item *cdecl__alloc_item(size_t sz)
32 return &stub_item.item;
35 void cdecl__errmsg(unsigned msg)
39 void cdecl__err(unsigned code, const char *fmt, const char *arg)
43 size_t cdecl__strlcpy(char *dst, const char *src, size_t len)
48 #define PROGNAME "scantest"
49 static const char *progname = PROGNAME;
50 static const char sopts[] = "ECVH";
51 static const struct option lopts[] = {
52 { "cdecl", 0, NULL, 'C' },
53 { "english", 0, NULL, 'E' },
54 { "version", 0, NULL, 'V' },
55 { "help", 0, NULL, 'H' },
59 static void print_usage(FILE *f)
61 fprintf(f, "Usage: %s [options] string [string ...]\n", progname);
64 static void print_help(void)
67 puts("Test the scanner by tokenizing one or more strings.\n");
68 test_print_options(lopts);
76 static int print_uintmax_rec(char *buf, uintmax_t v)
81 rc = print_uintmax_rec(buf, v/10);
89 static void print_uintmax(char *buf, uintmax_t v)
91 buf[print_uintmax_rec(buf, v)] = 0;
94 static int do_scan(const char *s, int mode)
96 YY_BUFFER_STATE state;
102 if (cdecl__yylex_init_extra(mode, &scanner) != 0)
105 state = cdecl__yy_scan_string(s, scanner);
107 while ((tok = cdecl__yylex(&lval, &lloc, scanner))) {
108 const char *tname = cdecl__token_name(tok);
112 print_uintmax(stub_item.item.s, lval.uintval);
113 lval.item = &stub_item.item;
115 printf("%s %s\n", tname, lval.item->s);
118 printf("%s\n", tname);
123 cdecl__yy_delete_buffer(state, scanner);
124 cdecl__yylex_destroy(scanner);
128 int main(int argc, char **argv)
130 int i, opt, mode = MODE_CDECL;
135 while ((opt = getopt_long(argc, argv, sopts, lopts, NULL)) != -1) {
144 test_print_version(PROGNAME);
160 for (i = optind; i < argc; i++) {
161 if (do_scan(argv[i], mode) != 0)