]> git.draconx.ca Git - cdecl99.git/blob - src/commands.c
cdecl99: Remove some unused variable declarations.
[cdecl99.git] / src / commands.c
1 /*
2  * Main command implementation routines for cdecl99.
3  * Copyright © 2011-2012, 2020-2021, 2023 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 <stdlib.h>
22
23 #include "cdecl99.h"
24 #include "cdecl.h"
25
26 /*
27  * Format a declaration according to the given function and return a pointer
28  * to the formatted string.  The returned pointer remains valid until the
29  * next call, after which it must not be re-used.
30  *
31  * Returns NULL on failure.
32  */
33 static const char *
34 do_format(size_t func(char *, size_t, struct cdecl *), struct cdecl *decl)
35 {
36         static size_t bufsz;
37         static char *buf;
38
39         size_t rc;
40
41 retry:
42         rc = func(buf, bufsz, decl);
43         if (rc >= bufsz) {
44                 char *tmp;
45
46                 tmp = realloc(buf, rc + 1);
47                 if (!tmp) {
48                         print_error("%s", _("failed to allocate memory"));
49                         return NULL;
50                 }
51
52                 buf = tmp;
53                 bufsz = rc + 1;
54                 goto retry;
55         }
56
57         return buf;
58 }
59
60 int run_command_explain(const char *arg)
61 {
62         struct cdecl *decl;
63         const char *str;
64         int ret = -1;
65
66         decl = cdecl_parse_decl(arg);
67         if (!decl) {
68                 print_error("%s", cdecl_get_error()->str);
69                 goto out;
70         }
71
72         for (struct cdecl *i = decl; i; i = i->next) {
73                 str = do_format(cdecl_explain, i);
74                 if (!str)
75                         goto out;
76
77                 printf("%s\n", str);
78         }
79
80         ret = 0;
81 out:
82         cdecl_free(decl);
83         return ret;
84 }
85
86 int run_command_simplify(const char *arg)
87 {
88         struct cdecl *decl;
89         const char *str;
90         int ret = -1;
91
92         decl = cdecl_parse_decl(arg);
93         if (!decl) {
94                 print_error("%s", cdecl_get_error()->str);
95                 goto out;
96         }
97
98         for (struct cdecl *i = decl; i; i = i->next) {
99                 struct cdecl_declspec *s = i->specifiers;
100
101                 if (i != decl) {
102                         i->specifiers = NULL;
103                         printf(", ");
104                 }
105
106                 str = do_format(cdecl_declare, i);
107                 i->specifiers = s;
108
109                 if (!str)
110                         goto out;
111
112                 printf("%s", str);
113         }
114
115         putchar('\n');
116
117         ret = 0;
118 out:
119         cdecl_free(decl);
120         return ret;
121 }
122
123 int run_command_declare(const char *cmd)
124 {
125         struct cdecl *decl;
126         const char *str;
127         int ret = -1;
128
129         /* The name of the command is significant here. */
130         decl = cdecl_parse_english(cmd);
131         if (!decl) {
132                 print_error("%s", cdecl_get_error()->str);
133                 goto out;
134         }
135
136         /*
137          * English parses have at most one full declarator, so no loop is
138          * needed here.
139          */
140         str = do_format(cdecl_declare, decl);
141         if (!str)
142                 goto out;
143
144         printf("%s\n", str);
145         ret = 0;
146 out:
147         cdecl_free(decl);
148         return ret;
149 }