2 * Main command implementation routines for cdecl99.
3 * Copyright © 2011-2012, 2020-2021, 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/>.
26 static struct cdecl *do_parse(const char *s, int input_mode)
30 if (input_mode == INPUT_C)
31 parse = cdecl_parse_decl(s);
33 parse = cdecl_parse_english(s);
36 print_error("%s", cdecl_get_error()->str);
42 * Format a declaration according to the given function and return a pointer
43 * to the formatted string. The returned pointer remains valid until the
44 * next call, after which it must not be re-used.
46 * Returns NULL on failure.
48 static const char *do_render(struct cdecl *decl, int output_mode)
55 if (output_mode == OUTPUT_C)
56 rc = cdecl_declare(buf, bufsz, decl);
58 rc = cdecl_explain(buf, bufsz, decl);
63 tmp = realloc(buf, rc + 1);
65 print_error("%s", _("failed to allocate memory"));
78 * Parse the given string as either C or English (based on input_mode),
79 * then print the result as either C or English (based on output_mode).
81 int run_command_cdecl(const char *s, int input_mode, int output_mode)
83 struct cdecl *i, *parse;
86 if (!(parse = do_parse(s, input_mode)))
89 for (i = parse; i; i = i->next) {
93 if (!(str = do_render(i, output_mode)))
97 * In C output, only the first declarator needs specifiers
98 * printed, and only the last declarator needs a newline.
100 if (output_mode == OUTPUT_C && i->next) {
101 i->next->specifiers = NULL;
105 printf(", %s%s" + 2*!!i->specifiers, str, "\n" + no_nl);