Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
opt_lines.cpp
Go to the documentation of this file.
1
29// expand _TEST_EXPORT macros
30#define _RWSTD_TEST_SRC
31
32#include "opt_lines.h"
33
34#include <rw_cmdopt.h>
35
36#include <assert.h>
37#include <stdio.h>
38#include <stdlib.h>
39#include <string.h>
40
41
42enum {
43 l_enabled = 1, // line is enabled
44 l_disabled = 2, // line is disabled
45 l_expected = 4 // diagnostic on line is expected to be active
46};
47
49 int first;
50 int last;
51 unsigned flags: 8;
52 char id [80];
53};
54
55static size_t nlineranges;
56static linerange_t *lineranges;
57static size_t rangebufsize;
58
59
61static int
62_rw_enable_lines (int first, int last, int flags)
63{
64 if (nlineranges == rangebufsize) {
65 const size_t newbufsize = 2 * nlineranges + 1;
66
67 linerange_t* const newranges =
68 (linerange_t*)malloc (newbufsize * sizeof (linerange_t));
69
70 if (0 == newranges) {
71 abort ();
72 }
73
74 memcpy (newranges, lineranges, nlineranges * sizeof (linerange_t));
75
76 free (lineranges);
77
78 lineranges = newranges;
79 rangebufsize = newbufsize;
80 }
81
82 lineranges [nlineranges].first = first;
83 lineranges [nlineranges].last = last;
84
85 lineranges [nlineranges].flags = flags;
86
87 ++nlineranges;
88
89 return 0;
90}
91
92
93static int
94_rw_enable_line (int argc, char *argv[], int flags)
95{
96 _RWSTD_UNUSED (argc);
97
98 char *parg = strchr (argv [0], '=');
99 assert (0 != parg);
100
101 const char* const argbeg = ++parg;
102
103 // the lower bound of a range of lines to be enabled or disabled
104 // negative values are not valid and denote an implicit lower bound
105 // of 1 (such as in "-3" which is a shorthand for "1-3")
106 long first = -1;
107
108 for ( ; '\0' != *parg ; ) {
109
110 // skip any leading whitespace
111 for ( ; ' ' == *parg; ++parg);
112
113 if ('-' == *parg) {
114 if (first < 0) {
115 first = 0;
116 ++parg;
117 }
118 else {
119 fprintf (stderr,
120 "invalid character '%c' at position %d: \"%s\"\n",
121 *parg, int (parg - argbeg), argv [0]);
122 return 2;
123 }
124 }
125
126 // parse a numeric argument
127 char *end;
128 long line = strtol (parg, &end, 0);
129
130 // skip any trailing whitespace
131 for ( ; ' ' == *end; ++end);
132
133 if (end == parg || ('-' != *end && ',' != *end && '\0' != *end)) {
134 fprintf (stderr,
135 "invalid character '%c' at position %d: \"%s\"\n",
136 *end, int (parg - argbeg), argv [0]);
137 return 2;
138 }
139
140 if (0 <= first) {
141 if (line < 0) {
142 fprintf (stderr,
143 "invalid value %ld at position %d: \"%s\"\n",
144 line, int (parg - argbeg), argv [0]);
145 return 2;
146 }
147
148 ++line;
149
150 if ((',' == *end || '-' == *end) && end [1])
151 ++end;
152 }
153 else if (',' == *end) {
154 first = line++;
155 if ('\0' == end [1]) {
156 fprintf (stderr,
157 "invalid character '%c' at position %d: \"%s\"\n",
158 *end, int (parg - argbeg), argv [0]);
159 return 2;
160 }
161
162 ++end;
163 }
164 else if ('-' == *end) {
165 first = line;
166 while (' ' == *++end);
167 if ('\0' == *end) {
168 line = _RWSTD_INT_MAX;
169 }
170 else if (',' == *end) {
171 line = _RWSTD_INT_MAX;
172 ++end;
173 }
174 else
175 line = -1;
176 }
177 else if ('\0' == *end) {
178 first = line++;
179 }
180 else {
181 fprintf (stderr,
182 "invalid character '%c' at position %d: \"%s\"\n",
183 *end, int (parg - argbeg), argv [0]);
184 return 2;
185 }
186
187 parg = end;
188
189 if (0 <= first && first < line) {
190 _rw_enable_lines (int (first), int (line), flags);
191 first = -1;
192 }
193 }
194
195 return 0;
196}
197
198
200static int
201_rw_opt_enable_line (int argc, char *argv[])
202{
203 if (1 == argc && argv && 0 == argv [0]) {
204
205 static const char helpstr[] = {
206 "Enables the line or lines specified by <arg>.\n"
207 "The syntax of <arg> is as follows: \n"
208 "<arg> ::= <range> [ , <range> ]\n"
209 "<range> ::= [ - ] <number> | <number> - [ <number> ]\n"
210 };
211
212 argv [0] = _RWSTD_CONST_CAST (char*, helpstr);
213
214 return 0;
215 }
216
217 return _rw_enable_line (argc, argv, l_enabled);
218}
219
220
222static int
223_rw_opt_no_line (int argc, char *argv[])
224{
225 if (1 == argc && argv && 0 == argv [0]) {
226
227 static const char helpstr[] = {
228 "Disables the line or lines specified by <arg>.\n"
229 "The syntax of <arg> is as follows: \n"
230 "<arg> ::= <range> [ , <range> ]\n"
231 "<range> ::= [ - ] <number> | <number> - [ <number> ]\n"
232 };
233
234 argv [0] = _RWSTD_CONST_CAST (char*, helpstr);
235
236 return 0;
237 }
238
239 return _rw_enable_line (argc, argv, l_disabled);
240}
241
242
244static int
245_rw_opt_expect_line (int argc, char *argv[])
246{
247 if (1 == argc && argv && 0 == argv [0]) {
248
249 static const char helpstr[] = {
250 "Marks the line or lines specified by <arg> as \"expected\".\n"
251 "Inactive diagnostics on such lines will be issued as unexpected.\n"
252 "The syntax of <arg> is as follows: \n"
253 "<arg> ::= <range> [ , <range> ]\n"
254 "<range> ::= [ - ] <number> | <number> - [ <number> ]\n"
255 };
256
257 argv [0] = _RWSTD_CONST_CAST (char*, helpstr);
258
259 return 0;
260 }
261
262 return _rw_enable_line (argc, argv, l_expected);
263}
264
265
267/* extern */ int
269{
270 const int result =
271 rw_setopts ("|-enable-line=" // argument required
272 "|-expect= " // argument required
273 "|-no-line= ", // argument required
274 _rw_opt_enable_line,
275 _rw_opt_expect_line,
276 _rw_opt_no_line);
277
278 return result;
279}
280
281
283/* extern */ int
285{
286 int line_expected = 0;
287
288 for (size_t i = 0; i != nlineranges; ++i) {
289
290 const int first = lineranges [i].first;
291 const int last = lineranges [i].last;
292
293 if (lineranges [i].flags & (l_disabled | l_enabled)) {
294 continue;
295 }
296
297 if (first <= line && line < last)
298 line_expected = 0 != (lineranges [i].flags & l_expected);
299 }
300
301 return line_expected;
302}
303
304
306_TEST_EXPORT int
308{
309 int nenabled = 0;
310 int ndisabled = 0;
311
312 int line_enabled = -1;
313
314 for (size_t i = 0; i != nlineranges; ++i) {
315
316 const int first = lineranges [i].first;
317 const int last = lineranges [i].last;
318
319 if (lineranges [i].flags & l_disabled) {
320 ++ndisabled;
321 }
322 else if (lineranges [i].flags & l_enabled) {
323 ++nenabled;
324 }
325 else {
326 continue;
327 }
328
329 if (first <= line && line < last)
330 line_enabled = 0 != (lineranges [i].flags & l_enabled);
331 }
332
333 if (nenabled && -1 == line_enabled)
334 line_enabled = 0;
335
336 return line_enabled;
337}
#define i
Definition 17.names.cpp:126
#define line
Definition 17.names.cpp:490
#define last
Definition 17.names.cpp:487
volatile int result
#define flags
const int end
#define assert(expr)
Definition _cassert.h:40
#define stderr
#define _RWSTD_UNUSED(arg)
Definition _defs.h:972
#define _RWSTD_CONST_CAST(T, x)
Definition _defs.h:536
_TEST_EXPORT int rw_enabled(int line)
@ l_disabled
Definition opt_lines.cpp:44
@ l_enabled
Definition opt_lines.cpp:43
@ l_expected
Definition opt_lines.cpp:45
int _rw_setopts_lines()
int _rw_expected(int line)
_TEST_EXPORT int rw_setopts(const char *optspec,...)
Definition cmdopt.cpp:652
#define _TEST_EXPORT
Definition rw_testdefs.h:55
unsigned flags
Definition opt_lines.cpp:51