Bug Summary

File:src/hest/parseHest.c
Location:line 1045, column 33
Description:Dereference of null pointer

Annotated Source Code

1/*
2 Teem: Tools to process and visualize scientific data and images .
3 Copyright (C) 2013, 2012, 2011, 2010, 2009 University of Chicago
4 Copyright (C) 2008, 2007, 2006, 2005 Gordon Kindlmann
5 Copyright (C) 2004, 2003, 2002, 2001, 2000, 1999, 1998 University of Utah
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public License
9 (LGPL) as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
11 The terms of redistributing and/or modifying this software also
12 include exceptions to the LGPL that facilitate static linking.
13
14 This library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
18
19 You should have received a copy of the GNU Lesser General Public License
20 along with this library; if not, write to Free Software Foundation, Inc.,
21 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22*/
23
24/*
25learned: well duh: when you send arguments to printf(), they will
26be evaluated before printf() sees them, so you can't use _hestIdent()
27twice with differen values
28*/
29
30#include "hest.h"
31#include "privateHest.h"
32
33#include <string.h>
34
35#define ME((parm && parm->verbosity) ? me : "") ((parm && parm->verbosity) ? me : "")
36
37/*
38** _hestArgsInResponseFiles()
39**
40** returns the number of args that will be parsed from the response files.
41** The role of this function is solely to simplify the task of avoiding
42** memory leaks. By knowing exactly how many args we'll get in the response
43** file, then hestParse() can allocate its local argv[] for exactly as
44** long as it needs to be, and we can avoid using an airArray. The drawback
45** is that we open and read through the response files twice. Alas.
46*/
47int
48_hestArgsInResponseFiles(int *argcP, int *nrfP,
49 const char **argv, char *err,
50 const hestParm *parm) {
51 FILE *file;
52 char me[]="_hestArgsInResponseFiles: ", line[AIR_STRLEN_HUGE(1024+1)], *pound;
53 int ai, len;
54
55 *argcP = 0;
56 *nrfP = 0;
57 if (!parm->respFileEnable) {
58 /* don't do response files; we're done */
59 return 0;
60 }
61
62 ai = 0;
63 while (argv[ai]) {
64 if (parm->respFileFlag == argv[ai][0]) {
65 if (!(file = fopen(argv[ai]+1, "rb"))) {
66 /* can't open the indicated response file for reading */
67 sprintf(err, "%scouldn't open \"%s\" for reading as response file",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%scouldn't open \"%s\" for reading as response file"
, ((parm && parm->verbosity) ? me : ""), argv[ai]+
1)
68 ME, argv[ai]+1)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%scouldn't open \"%s\" for reading as response file"
, ((parm && parm->verbosity) ? me : ""), argv[ai]+
1)
;
69 *argcP = 0;
70 *nrfP = 0;
71 return 1;
72 }
73 len = airOneLine(file, line, AIR_STRLEN_HUGE(1024+1));
74 while (len > 0) {
75 if ( (pound = strchr(line, parm->respFileComment)) )
76 *pound = '\0';
77 airOneLinify(line);
78 *argcP += airStrntok(line, AIR_WHITESPACE" \t\n\r\v\f");
79 len = airOneLine(file, line, AIR_STRLEN_HUGE(1024+1));
80 }
81 fclose(file);
82 (*nrfP)++;
83 }
84 ai++;
85 }
86 return 0;
87}
88
89/*
90** _hestResponseFiles()
91**
92** This function is badly named. Even if there are no response files,
93** even if response files are disabled, this is the function that
94** copies from the user's argc,argv to our local copy.
95*/
96int
97_hestResponseFiles(char **newArgv, const char **oldArgv,
98 const hestParm *parm, airArray *pmop) {
99 char line[AIR_STRLEN_HUGE(1024+1)], *pound;
100 int len, newArgc, oldArgc, incr, ai;
101 FILE *file;
102
103 newArgc = oldArgc = 0;
104 while(oldArgv[oldArgc]) {
105 if (parm->verbosity) {
106 printf("!%s:________ newArgc = %d, oldArgc = %d\n",
107 "dammit", newArgc, oldArgc);
108 _hestPrintArgv(newArgc, newArgv);
109 }
110 if (!parm->respFileEnable
111 || parm->respFileFlag != oldArgv[oldArgc][0]) {
112 /* nothing to do with a response file */
113 newArgv[newArgc] = airStrdup(oldArgv[oldArgc]);
114 airMopAdd(pmop, newArgv[newArgc], airFree, airMopAlways);
115 newArgc += 1;
116 }
117 else {
118 /* It is a response file. Error checking on open-ability
119 should have been done by _hestArgsInResponseFiles() */
120 file = fopen(oldArgv[oldArgc]+1, "rb");
121 len = airOneLine(file, line, AIR_STRLEN_HUGE(1024+1));
122 while (len > 0) {
123 if (parm->verbosity)
124 printf("_hestResponseFiles: line: |%s|\n", line);
125 if ( (pound = strchr(line, parm->respFileComment)) )
126 *pound = '\0';
127 if (parm->verbosity)
128 printf("_hestResponseFiles: -0-> line: |%s|\n", line);
129 airOneLinify(line);
130 incr = airStrntok(line, AIR_WHITESPACE" \t\n\r\v\f");
131 if (parm->verbosity)
132 printf("_hestResponseFiles: -1-> line: |%s|, incr=%d\n",
133 line, incr);
134 airParseStrS(newArgv + newArgc, line, AIR_WHITESPACE" \t\n\r\v\f", incr, AIR_FALSE0);
135 for (ai=0; ai<incr; ai++) {
136 /* This time, we did allocate memory. We can use airFree and
137 not airFreeP because these will not be reset before mopping */
138 airMopAdd(pmop, newArgv[newArgc+ai], airFree, airMopAlways);
139 }
140 len = airOneLine(file, line, AIR_STRLEN_HUGE(1024+1));
141 newArgc += incr;
142 }
143 fclose(file);
144 }
145 oldArgc++;
146 if (parm->verbosity) {
147 _hestPrintArgv(newArgc, newArgv);
148 printf("!%s: ^^^^^^^ newArgc = %d, oldArgc = %d\n",
149 "dammit", newArgc, oldArgc);
150 }
151 }
152 newArgv[newArgc] = NULL((void*)0);
153
154 return 0;
155}
156
157/*
158** _hestPanic()
159**
160** all error checking on the given hest array itself (not the
161** command line to be parsed). Also, sets the "kind" field of
162** the opt struct
163*/
164int
165_hestPanic(hestOpt *opt, char *err, const hestParm *parm) {
166 char me[]="_hestPanic: ", tbuff[AIR_STRLEN_HUGE(1024+1)], *sep;
167 int numvar, op, numOpts;
168
169 numOpts = _hestNumOpts(opt);
170 numvar = 0;
171 for (op=0; op<numOpts; op++) {
172 opt[op].kind = _hestKind(opt + op);
173 if (!(AIR_IN_OP(airTypeUnknown, opt[op].type, airTypeLast)((airTypeUnknown) < (opt[op].type) && (opt[op].type
) < (airTypeLast))
)) {
174 if (err)
175 sprintf(err, "%s!!!!!! opt[%d].type (%d) not in valid range [%d,%d]",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%s!!!!!! opt[%d].type (%d) not in valid range [%d,%d]"
, ((parm && parm->verbosity) ? me : ""), op, opt[op
].type, airTypeUnknown+1, airTypeLast-1)
176 ME, op, opt[op].type, airTypeUnknown+1, airTypeLast-1)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%s!!!!!! opt[%d].type (%d) not in valid range [%d,%d]"
, ((parm && parm->verbosity) ? me : ""), op, opt[op
].type, airTypeUnknown+1, airTypeLast-1)
;
177 else
178 fprintf(stderr__stderrp, "%s: panic 0\n", me);
179 return 1;
180 }
181 if (!( opt[op].valueP )) {
182 if (err)
183 sprintf(err, "%s!!!!!! opt[%d]'s valueP is NULL!", ME, op)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%s!!!!!! opt[%d]'s valueP is NULL!", ((parm
&& parm->verbosity) ? me : ""), op)
;
184 else
185 fprintf(stderr__stderrp, "%s: panic 0.5\n", me);
186 return 1;
187 }
188 if (-1 == opt[op].kind) {
189 if (err)
190 sprintf(err, "%s!!!!!! opt[%d]'s min (%d) and max (%d) incompatible",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%s!!!!!! opt[%d]'s min (%d) and max (%d) incompatible"
, ((parm && parm->verbosity) ? me : ""), op, opt[op
].min, opt[op].max)
191 ME, op, opt[op].min, opt[op].max)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%s!!!!!! opt[%d]'s min (%d) and max (%d) incompatible"
, ((parm && parm->verbosity) ? me : ""), op, opt[op
].min, opt[op].max)
;
192 else
193 fprintf(stderr__stderrp, "%s: panic 1\n", me);
194 return 1;
195 }
196 if (5 == opt[op].kind && !(opt[op].sawP)) {
197 if (err)
198 sprintf(err, "%s!!!!!! have multiple variable parameters, "__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%s!!!!!! have multiple variable parameters, "
"but sawP is NULL", ((parm && parm->verbosity) ? me
: ""))
199 "but sawP is NULL", ME)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%s!!!!!! have multiple variable parameters, "
"but sawP is NULL", ((parm && parm->verbosity) ? me
: ""))
;
200 else
201 fprintf(stderr__stderrp, "%s: panic 2\n", me);
202 return 1;
203 }
204 if (airTypeEnum == opt[op].type) {
205 if (!(opt[op].enm)) {
206 if (err) {
207 sprintf(err, "%s!!!!!! opt[%d] (%s) is type \"enum\", but no "__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%s!!!!!! opt[%d] (%s) is type \"enum\", but no "
"airEnum pointer given", ((parm && parm->verbosity
) ? me : ""), op, opt[op].flag ? opt[op].flag : "?")
208 "airEnum pointer given", ME, op,__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%s!!!!!! opt[%d] (%s) is type \"enum\", but no "
"airEnum pointer given", ((parm && parm->verbosity
) ? me : ""), op, opt[op].flag ? opt[op].flag : "?")
209 opt[op].flag ? opt[op].flag : "?")__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%s!!!!!! opt[%d] (%s) is type \"enum\", but no "
"airEnum pointer given", ((parm && parm->verbosity
) ? me : ""), op, opt[op].flag ? opt[op].flag : "?")
;
210 } else {
211 fprintf(stderr__stderrp, "%s: panic 3\n", me);
212 }
213 return 1;
214 }
215 }
216 if (airTypeOther == opt[op].type) {
217 if (!(opt[op].CB)) {
218 if (err) {
219 sprintf(err, "%s!!!!!! opt[%d] (%s) is type \"other\", but no "__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%s!!!!!! opt[%d] (%s) is type \"other\", but no "
"callbacks given", ((parm && parm->verbosity) ? me
: ""), op, opt[op].flag ? opt[op].flag : "?")
220 "callbacks given", ME, op,__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%s!!!!!! opt[%d] (%s) is type \"other\", but no "
"callbacks given", ((parm && parm->verbosity) ? me
: ""), op, opt[op].flag ? opt[op].flag : "?")
221 opt[op].flag ? opt[op].flag : "?")__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%s!!!!!! opt[%d] (%s) is type \"other\", but no "
"callbacks given", ((parm && parm->verbosity) ? me
: ""), op, opt[op].flag ? opt[op].flag : "?")
;
222 } else {
223 fprintf(stderr__stderrp, "%s: panic 4\n", me);
224 }
225 return 1;
226 }
227 if (!( opt[op].CB->size > 0 )) {
228 if (err)
229 sprintf(err, "%s!!!!!! opt[%d]'s \"size\" (%d) invalid",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%s!!!!!! opt[%d]'s \"size\" (%d) invalid",
((parm && parm->verbosity) ? me : ""), op, (int)(
opt[op].CB->size))
230 ME, op, (int)(opt[op].CB->size))__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%s!!!!!! opt[%d]'s \"size\" (%d) invalid",
((parm && parm->verbosity) ? me : ""), op, (int)(
opt[op].CB->size))
;
231 else
232 fprintf(stderr__stderrp, "%s: panic 5\n", me);
233 return 1;
234 }
235 if (!( opt[op].type )) {
236 if (err)
237 sprintf(err, "%s!!!!!! opt[%d]'s \"type\" is NULL",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%s!!!!!! opt[%d]'s \"type\" is NULL", ((parm
&& parm->verbosity) ? me : ""), op)
238 ME, op)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%s!!!!!! opt[%d]'s \"type\" is NULL", ((parm
&& parm->verbosity) ? me : ""), op)
;
239 else
240 fprintf(stderr__stderrp, "%s: panic 6\n", me);
241 return 1;
242
243 }
244 if (!( opt[op].CB->parse )) {
245 if (err)
246 sprintf(err, "%s!!!!!! opt[%d]'s \"parse\" callback NULL", ME, op)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%s!!!!!! opt[%d]'s \"parse\" callback NULL"
, ((parm && parm->verbosity) ? me : ""), op)
;
247 else
248 fprintf(stderr__stderrp, "%s: panic 7\n", me);
249 return 1;
250 }
251 if (opt[op].CB->destroy && (sizeof(void*) != opt[op].CB->size)) {
252 if (err)
253 sprintf(err, "%s!!!!!! opt[%d] has a \"destroy\", but size isn't "__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%s!!!!!! opt[%d] has a \"destroy\", but size isn't "
"sizeof(void*)", ((parm && parm->verbosity) ? me :
""), op)
254 "sizeof(void*)", ME, op)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%s!!!!!! opt[%d] has a \"destroy\", but size isn't "
"sizeof(void*)", ((parm && parm->verbosity) ? me :
""), op)
;
255 else
256 fprintf(stderr__stderrp, "%s: panic 8\n", me);
257 return 1;
258 }
259 }
260 if (opt[op].flag) {
261 strcpy(tbuff, opt[op].flag)__builtin___strcpy_chk (tbuff, opt[op].flag, __builtin_object_size
(tbuff, 2 > 1 ? 1 : 0))
;
262 if (( sep = strchr(tbuff, parm->multiFlagSep) )) {
263 *sep = '\0';
264 if (!( strlen(tbuff) && strlen(sep+1) )) {
265 if (err)
266 sprintf(err, "%s!!!!!! either short (\"%s\") or long (\"%s\") flag"__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%s!!!!!! either short (\"%s\") or long (\"%s\") flag"
" of opt[%d] is zero length", ((parm && parm->verbosity
) ? me : ""), tbuff, sep+1, op)
267 " of opt[%d] is zero length", ME, tbuff, sep+1, op)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%s!!!!!! either short (\"%s\") or long (\"%s\") flag"
" of opt[%d] is zero length", ((parm && parm->verbosity
) ? me : ""), tbuff, sep+1, op)
;
268 else
269 fprintf(stderr__stderrp, "%s: panic 9\n", me);
270 return 1;
271 }
272 }
273 else {
274 if (!strlen(opt[op].flag)) {
275 if (err)
276 sprintf(err, "%s!!!!!! opt[%d].flag is zero length",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%s!!!!!! opt[%d].flag is zero length", ((parm
&& parm->verbosity) ? me : ""), op)
277 ME, op)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%s!!!!!! opt[%d].flag is zero length", ((parm
&& parm->verbosity) ? me : ""), op)
;
278 else
279 fprintf(stderr__stderrp, "%s: panic 10\n", me);
280 return 1;
281 }
282 }
283 if (4 == opt[op].kind) {
284 if (!opt[op].dflt) {
285 if (err)
286 sprintf(err, "%s!!!!!! flagged single variable parameter must "__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%s!!!!!! flagged single variable parameter must "
"specify a default", ((parm && parm->verbosity) ?
me : ""))
287 "specify a default", ME)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%s!!!!!! flagged single variable parameter must "
"specify a default", ((parm && parm->verbosity) ?
me : ""))
;
288 else
289 fprintf(stderr__stderrp, "%s: panic 11\n", me);
290 return 1;
291 }
292 if (!strlen(opt[op].dflt)) {
293 if (err)
294 sprintf(err, "%s!!!!!! flagged single variable parameter default "__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%s!!!!!! flagged single variable parameter default "
"must be non-zero length", ((parm && parm->verbosity
) ? me : ""))
295 "must be non-zero length", ME)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%s!!!!!! flagged single variable parameter default "
"must be non-zero length", ((parm && parm->verbosity
) ? me : ""))
;
296 else
297 fprintf(stderr__stderrp, "%s: panic 12\n", me);
298 return 1;
299 }
300 }
301 /*
302 sprintf(tbuff, "-%s", opt[op].flag);
303 if (1 == sscanf(tbuff, "%f", &tmpF)) {
304 if (err)
305 sprintf(err, "%s!!!!!! opt[%d].flag (\"%s\") is numeric, bad news",
306 ME, op, opt[op].flag);
307 return 1;
308 }
309 */
310 }
311 if (1 == opt[op].kind) {
312 if (!opt[op].flag) {
313 if (err)
314 sprintf(err, "%s!!!!!! flags must have flags", ME)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%s!!!!!! flags must have flags", ((parm &&
parm->verbosity) ? me : ""))
;
315 else
316 fprintf(stderr__stderrp, "%s: panic 13\n", me);
317 return 1;
318 }
319 }
320 else {
321 if (!opt[op].name) {
322 if (err)
323 sprintf(err, "%s!!!!!! opt[%d] isn't a flag: must have \"name\"",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%s!!!!!! opt[%d] isn't a flag: must have \"name\""
, ((parm && parm->verbosity) ? me : ""), op)
324 ME, op)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%s!!!!!! opt[%d] isn't a flag: must have \"name\""
, ((parm && parm->verbosity) ? me : ""), op)
;
325 else
326 fprintf(stderr__stderrp, "%s: panic 14\n", me);
327 return 1;
328 }
329 }
330 if (4 == opt[op].kind && !opt[op].dflt) {
331 if (err)
332 sprintf(err, "%s!!!!!! opt[%d] is single variable parameter, but "__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%s!!!!!! opt[%d] is single variable parameter, but "
"no default set", ((parm && parm->verbosity) ? me
: ""), op)
333 "no default set", ME, op)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%s!!!!!! opt[%d] is single variable parameter, but "
"no default set", ((parm && parm->verbosity) ? me
: ""), op)
;
334 else
335 fprintf(stderr__stderrp, "%s: panic 15\n", me);
336 return 1;
337 }
338 numvar += ((int)opt[op].min < _hestMax(opt[op].max) && (NULL((void*)0) == opt[op].flag)); /* HEY scrutinize casts */
339 }
340 if (numvar > 1) {
341 if (err)
342 sprintf(err, "%s!!!!!! can't have %d unflagged min<max opts, only one",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%s!!!!!! can't have %d unflagged min<max opts, only one"
, ((parm && parm->verbosity) ? me : ""), numvar)
343 ME, numvar)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%s!!!!!! can't have %d unflagged min<max opts, only one"
, ((parm && parm->verbosity) ? me : ""), numvar)
;
344 else
345 fprintf(stderr__stderrp, "%s: panic 16\n", me);
346 return 1;
347 }
348 return 0;
349}
350
351int
352_hestErrStrlen(const hestOpt *opt, int argc, const char **argv) {
353 int a, numOpts, ret, other;
354
355 ret = 0;
356 numOpts = _hestNumOpts(opt);
357 other = AIR_FALSE0;
358 if (argv) {
359 for (a=0; a<argc; a++) {
360 ret = AIR_MAX(ret, (int)airStrlen(argv[a]))((ret) > ((int)airStrlen(argv[a])) ? (ret) : ((int)airStrlen
(argv[a])))
;
361 }
362 }
363 for (a=0; a<numOpts; a++) {
364 ret = AIR_MAX(ret, (int)airStrlen(opt[a].flag))((ret) > ((int)airStrlen(opt[a].flag)) ? (ret) : ((int)airStrlen
(opt[a].flag)))
;
365 ret = AIR_MAX(ret, (int)airStrlen(opt[a].name))((ret) > ((int)airStrlen(opt[a].name)) ? (ret) : ((int)airStrlen
(opt[a].name)))
;
366 other |= opt[a].type == airTypeOther;
367 }
368 for (a=airTypeUnknown+1; a<airTypeLast; a++) {
369 ret = AIR_MAX(ret, (int)airStrlen(airTypeStr[a]))((ret) > ((int)airStrlen(airTypeStr[a])) ? (ret) : ((int)airStrlen
(airTypeStr[a])))
;
370 }
371 if (other) {
372 /* the callback's error() function may sprintf an error message
373 into a buffer which is size AIR_STRLEN_HUGE */
374 ret += AIR_STRLEN_HUGE(1024+1);
375 }
376 ret += 4 * 12; /* as many as 4 ints per error message */
377 ret += 257; /* function name and text of hest's error message */
378
379 return ret;
380}
381
382/*
383** _hestExtractFlagged()
384**
385** extracts the parameters associated with all flagged options from the
386** given argc and argv, storing them in prms[], recording the number
387** of parameters in nprm[], and whether or not the flagged option appeared
388** in appr[].
389**
390** The "saw" information is not set here, since it is better set
391** at value parsing time, which happens after defaults are enstated.
392*/
393int
394_hestExtractFlagged(char **prms, unsigned int *nprm, int *appr,
395 int *argcP, char **argv,
396 hestOpt *opt,
397 char *err, const hestParm *parm, airArray *pmop) {
398 char me[]="_hestExtractFlagged: ", ident1[AIR_STRLEN_HUGE(1024+1)],
399 ident2[AIR_STRLEN_HUGE(1024+1)];
400 int a, np, flag, endflag, numOpts, op;
401
402 a = 0;
403 if (parm->verbosity)
404 printf("!%s: *argcP = %d\n", me, *argcP);
405 while (a<=*argcP-1) {
406 if (parm->verbosity)
407 printf("!%s: a = %d -> argv[a] = %s\n", me, a, argv[a]);
408 flag = _hestWhichFlag(opt, argv[a], parm);
409 if (parm->verbosity)
410 printf("!%s: A: a = %d -> flag = %d\n", me, a, flag);
411 if (!(0 <= flag)) {
412 /* not a flag, move on */
413 a++;
414 continue;
415 }
416 /* see if we can associate some parameters with the flag */
417 np = 0;
418 endflag = 0;
419 while (np < _hestMax(opt[flag].max) &&
420 a+np+1 <= *argcP-1 &&
421 -1 == (endflag = _hestWhichFlag(opt, argv[a+np+1], parm))) {
422 np++;
423 if (parm->verbosity)
424 printf("!%s: np --> %d with endflag = %d\n", me, np, endflag);
425 }
426 /* we stopped because we got the max number of parameters, or
427 because we hit the end of the command line, or
428 because _hestWhichFlag() returned something other than -1,
429 which means it returned -2, or a valid option index. If
430 we stopped because of _hestWhichFlag()'s return value,
431 endflag has been set to that return value */
432 if (parm->verbosity)
433 printf("!%s: B: np = %d; endflag = %d\n", me, np, endflag);
434 if (np < (int)opt[flag].min) { /* HEY scrutinize casts */
435 /* didn't get minimum number of parameters */
436 if (!( a+np+1 <= *argcP-1 )) {
437 sprintf(err, "%shit end of line before getting %d parameter%s "__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%shit end of line before getting %d parameter%s "
"for %s (got %d)", ((parm && parm->verbosity) ? me
: ""), opt[flag].min, opt[flag].min > 1 ? "s" : "", _hestIdent
(ident1, opt+flag, parm, 1), np)
438 "for %s (got %d)",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%shit end of line before getting %d parameter%s "
"for %s (got %d)", ((parm && parm->verbosity) ? me
: ""), opt[flag].min, opt[flag].min > 1 ? "s" : "", _hestIdent
(ident1, opt+flag, parm, 1), np)
439 ME, opt[flag].min, opt[flag].min > 1 ? "s" : "",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%shit end of line before getting %d parameter%s "
"for %s (got %d)", ((parm && parm->verbosity) ? me
: ""), opt[flag].min, opt[flag].min > 1 ? "s" : "", _hestIdent
(ident1, opt+flag, parm, 1), np)
440 _hestIdent(ident1, opt+flag, parm, AIR_TRUE), np)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%shit end of line before getting %d parameter%s "
"for %s (got %d)", ((parm && parm->verbosity) ? me
: ""), opt[flag].min, opt[flag].min > 1 ? "s" : "", _hestIdent
(ident1, opt+flag, parm, 1), np)
;
441 }
442 else {
443 sprintf(err, "%shit %s before getting %d parameter%s for %s (got %d)",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%shit %s before getting %d parameter%s for %s (got %d)"
, ((parm && parm->verbosity) ? me : ""), _hestIdent
(ident1, opt+endflag, parm, 0), opt[flag].min, opt[flag].min >
1 ? "s" : "", _hestIdent(ident2, opt+flag, parm, 0), np)
444 ME, _hestIdent(ident1, opt+endflag, parm, AIR_FALSE),__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%shit %s before getting %d parameter%s for %s (got %d)"
, ((parm && parm->verbosity) ? me : ""), _hestIdent
(ident1, opt+endflag, parm, 0), opt[flag].min, opt[flag].min >
1 ? "s" : "", _hestIdent(ident2, opt+flag, parm, 0), np)
445 opt[flag].min, opt[flag].min > 1 ? "s" : "",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%shit %s before getting %d parameter%s for %s (got %d)"
, ((parm && parm->verbosity) ? me : ""), _hestIdent
(ident1, opt+endflag, parm, 0), opt[flag].min, opt[flag].min >
1 ? "s" : "", _hestIdent(ident2, opt+flag, parm, 0), np)
446 _hestIdent(ident2, opt+flag, parm, AIR_FALSE), np)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%shit %s before getting %d parameter%s for %s (got %d)"
, ((parm && parm->verbosity) ? me : ""), _hestIdent
(ident1, opt+endflag, parm, 0), opt[flag].min, opt[flag].min >
1 ? "s" : "", _hestIdent(ident2, opt+flag, parm, 0), np)
;
447 }
448 return 1;
449 }
450 nprm[flag] = np;
451 if (parm->verbosity) {
452 printf("!%s:________ a=%d, *argcP = %d -> flag = %d\n",
453 me, a, *argcP, flag);
454 _hestPrintArgv(*argcP, argv);
455 }
456 /* lose the flag argument */
457 free(_hestExtract(argcP, argv, a, 1));
458 /* extract the args after the flag */
459 if (appr[flag]) {
460 airMopSub(pmop, prms[flag], airFree);
461 prms[flag] = (char *)airFree(prms[flag]);
462 }
463 prms[flag] = _hestExtract(argcP, argv, a, nprm[flag]);
464 airMopAdd(pmop, prms[flag], airFree, airMopAlways);
465 appr[flag] = AIR_TRUE1;
466 if (-2 == endflag) {
467 /* we should lose the end-of-variable-parameter marker */
468 free(_hestExtract(argcP, argv, a, 1));
469 }
470 if (parm->verbosity) {
471 _hestPrintArgv(*argcP, argv);
472 printf("!%s:^^^^^^^^ *argcP = %d\n", me, *argcP);
473 printf("!%s: prms[%d] = %s\n", me, flag,
474 prms[flag] ? prms[flag] : "(null)");
475 }
476 }
477
478 /* make sure that flagged options without default were given */
479 numOpts = _hestNumOpts(opt);
480 for (op=0; op<numOpts; op++) {
481 if (1 != opt[op].kind && opt[op].flag && !opt[op].dflt && !appr[op]) {
482 sprintf(err, "%sdidn't get required %s",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%sdidn't get required %s", ((parm &&
parm->verbosity) ? me : ""), _hestIdent(ident1, opt+op, parm
, 0))
483 ME, _hestIdent(ident1, opt+op, parm, AIR_FALSE))__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%sdidn't get required %s", ((parm &&
parm->verbosity) ? me : ""), _hestIdent(ident1, opt+op, parm
, 0))
;
484 return 1;
485 }
486 }
487
488 return 0;
489}
490
491int
492_hestNextUnflagged(int op, hestOpt *opt, int numOpts) {
493
494 for(; op<=numOpts-1; op++) {
495 if (!opt[op].flag)
496 break;
497 }
498 return op;
499}
500
501int
502_hestExtractUnflagged(char **prms, unsigned int *nprm,
503 int *argcP, char **argv,
504 hestOpt *opt,
505 char *err, const hestParm *parm, airArray *pmop) {
506 char me[]="_hestExtractUnflagged: ", ident[AIR_STRLEN_HUGE(1024+1)];
507 int nvp, np, op, unflag1st, unflagVar, numOpts;
508
509 numOpts = _hestNumOpts(opt);
510 unflag1st = _hestNextUnflagged(0, opt, numOpts);
511 if (numOpts == unflag1st) {
512 /* no unflagged options; we're done */
513 return 0;
514 }
515
516 for (unflagVar = unflag1st;
517 unflagVar != numOpts;
518 unflagVar = _hestNextUnflagged(unflagVar+1, opt, numOpts)) {
519 if ((int)opt[unflagVar].min < _hestMax(opt[unflagVar].max)) /* HEY scrutinize casts */
520 break;
521 }
522 /* now, if there is a variable parameter unflagged opt, unflagVar is its
523 index in opt[], or else unflagVar is numOpts */
524
525 /* grab parameters for all unflagged opts before opt[t] */
526 for (op = _hestNextUnflagged(0, opt, numOpts);
527 op < unflagVar;
528 op = _hestNextUnflagged(op+1, opt, numOpts)) {
529 /* printf("!%s: op = %d; unflagVar = %d\n", me, op, unflagVar); */
530 np = opt[op].min; /* min == max */
531 if (!(np <= *argcP)) {
532 sprintf(err, "%sdon't have %d parameter%s %s%s%sfor %s",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%sdon't have %d parameter%s %s%s%sfor %s",
((parm && parm->verbosity) ? me : ""), np, np >
1 ? "s" : "", argv[0] ? "starting at \"" : "", argv[0] ? argv
[0] : "", argv[0] ? "\" " : "", _hestIdent(ident, opt+op, parm
, 1))
533 ME, np, np > 1 ? "s" : "",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%sdon't have %d parameter%s %s%s%sfor %s",
((parm && parm->verbosity) ? me : ""), np, np >
1 ? "s" : "", argv[0] ? "starting at \"" : "", argv[0] ? argv
[0] : "", argv[0] ? "\" " : "", _hestIdent(ident, opt+op, parm
, 1))
534 argv[0] ? "starting at \"" : "",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%sdon't have %d parameter%s %s%s%sfor %s",
((parm && parm->verbosity) ? me : ""), np, np >
1 ? "s" : "", argv[0] ? "starting at \"" : "", argv[0] ? argv
[0] : "", argv[0] ? "\" " : "", _hestIdent(ident, opt+op, parm
, 1))
535 argv[0] ? argv[0] : "",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%sdon't have %d parameter%s %s%s%sfor %s",
((parm && parm->verbosity) ? me : ""), np, np >
1 ? "s" : "", argv[0] ? "starting at \"" : "", argv[0] ? argv
[0] : "", argv[0] ? "\" " : "", _hestIdent(ident, opt+op, parm
, 1))
536 argv[0] ? "\" " : "",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%sdon't have %d parameter%s %s%s%sfor %s",
((parm && parm->verbosity) ? me : ""), np, np >
1 ? "s" : "", argv[0] ? "starting at \"" : "", argv[0] ? argv
[0] : "", argv[0] ? "\" " : "", _hestIdent(ident, opt+op, parm
, 1))
537 _hestIdent(ident, opt+op, parm, AIR_TRUE))__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%sdon't have %d parameter%s %s%s%sfor %s",
((parm && parm->verbosity) ? me : ""), np, np >
1 ? "s" : "", argv[0] ? "starting at \"" : "", argv[0] ? argv
[0] : "", argv[0] ? "\" " : "", _hestIdent(ident, opt+op, parm
, 1))
;
538 return 1;
539 }
540 prms[op] = _hestExtract(argcP, argv, 0, np);
541 airMopAdd(pmop, prms[op], airFree, airMopAlways);
542 nprm[op] = np;
543 }
544 /*
545 _hestPrintArgv(*argcP, argv);
546 */
547 /* we skip over the variable parameter unflagged option, subtract from *argcP
548 the number of parameters in all the opts which follow it, in order to get
549 the number of parameters in the sole variable parameter option,
550 store this in nvp */
551 nvp = *argcP;
552 for (op = _hestNextUnflagged(unflagVar+1, opt, numOpts);
553 op < numOpts;
554 op = _hestNextUnflagged(op+1, opt, numOpts)) {
555 nvp -= opt[op].min; /* min == max */
556 }
557 if (nvp < 0) {
558 op = _hestNextUnflagged(unflagVar+1, opt, numOpts);
559 np = opt[op].min;
560 sprintf(err, "%sdon't have %d parameter%s for %s",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%sdon't have %d parameter%s for %s", ((parm
&& parm->verbosity) ? me : ""), np, np > 1 ? "s"
: "", _hestIdent(ident, opt+op, parm, 0))
561 ME, np, np > 1 ? "s" : "",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%sdon't have %d parameter%s for %s", ((parm
&& parm->verbosity) ? me : ""), np, np > 1 ? "s"
: "", _hestIdent(ident, opt+op, parm, 0))
562 _hestIdent(ident, opt+op, parm, AIR_FALSE))__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%sdon't have %d parameter%s for %s", ((parm
&& parm->verbosity) ? me : ""), np, np > 1 ? "s"
: "", _hestIdent(ident, opt+op, parm, 0))
;
563 return 1;
564 }
565 /* else we had enough args for all the unflagged options following
566 the sole variable parameter unflagged option, so snarf them up */
567 for (op = _hestNextUnflagged(unflagVar+1, opt, numOpts);
568 op < numOpts;
569 op = _hestNextUnflagged(op+1, opt, numOpts)) {
570 np = opt[op].min;
571 prms[op] = _hestExtract(argcP, argv, nvp, np);
572 airMopAdd(pmop, prms[op], airFree, airMopAlways);
573 nprm[op] = np;
574 }
575
576 /* now we grab the parameters of the sole variable parameter unflagged opt,
577 if it exists (unflagVar < numOpts) */
578 if (unflagVar < numOpts) {
579 /*
580 printf("!%s: unflagVar=%d: min, nvp, max = %d %d %d\n", me, unflagVar,
581 opt[unflagVar].min, nvp, _hestMax(opt[unflagVar].max));
582 */
583 /* we'll do error checking for unexpected args later */
584 nvp = AIR_MIN(nvp, _hestMax(opt[unflagVar].max))((nvp) < (_hestMax(opt[unflagVar].max)) ? (nvp) : (_hestMax
(opt[unflagVar].max)))
;
585 if (nvp < (int)opt[unflagVar].min) { /* HEY scrutinize casts */
586 sprintf(err, "%sdidn't get minimum of %d arg%s for %s (got %d)",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%sdidn't get minimum of %d arg%s for %s (got %d)"
, ((parm && parm->verbosity) ? me : ""), opt[unflagVar
].min, opt[unflagVar].min > 1 ? "s" : "", _hestIdent(ident
, opt+unflagVar, parm, 1), nvp)
587 ME, opt[unflagVar].min,__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%sdidn't get minimum of %d arg%s for %s (got %d)"
, ((parm && parm->verbosity) ? me : ""), opt[unflagVar
].min, opt[unflagVar].min > 1 ? "s" : "", _hestIdent(ident
, opt+unflagVar, parm, 1), nvp)
588 opt[unflagVar].min > 1 ? "s" : "",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%sdidn't get minimum of %d arg%s for %s (got %d)"
, ((parm && parm->verbosity) ? me : ""), opt[unflagVar
].min, opt[unflagVar].min > 1 ? "s" : "", _hestIdent(ident
, opt+unflagVar, parm, 1), nvp)
589 _hestIdent(ident, opt+unflagVar, parm, AIR_TRUE), nvp)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%sdidn't get minimum of %d arg%s for %s (got %d)"
, ((parm && parm->verbosity) ? me : ""), opt[unflagVar
].min, opt[unflagVar].min > 1 ? "s" : "", _hestIdent(ident
, opt+unflagVar, parm, 1), nvp)
;
590 return 1;
591 }
592 if (nvp) {
593 prms[unflagVar] = _hestExtract(argcP, argv, 0, nvp);
594 airMopAdd(pmop, prms[unflagVar], airFree, airMopAlways);
595 nprm[unflagVar] = nvp;
596 }
597 else {
598 prms[unflagVar] = NULL((void*)0);
599 nprm[unflagVar] = 0;
600 }
601 }
602 return 0;
603}
604
605int
606_hestDefaults(char **prms, int *udflt, unsigned int *nprm, int *appr,
607 hestOpt *opt,
608 char *err, const hestParm *parm, airArray *mop) {
609 char *tmpS, me[]="_hestDefaults: ", ident[AIR_STRLEN_HUGE(1024+1)];
610 int op, numOpts;
611
612 numOpts = _hestNumOpts(opt);
613 for (op=0; op<numOpts; op++) {
614 if (parm->verbosity)
615 printf("%s op=%d/%d: \"%s\" --> kind=%d, nprm=%u, appr=%d\n",
616 me, op, numOpts-1, prms[op], opt[op].kind,
617 nprm[op], appr[op]);
618 switch(opt[op].kind) {
619 case 1:
620 /* -------- (no-parameter) boolean flags -------- */
621 /* default is indeed always ignored for the sake of setting the
622 option's value, but udflt is used downstream to set
623 the option's source. The info came from the user if
624 the flag appears, otherwise it is from the default. */
625 udflt[op] = !appr[op];
626 break;
627 case 2:
628 case 3:
629 /* -------- one required parameter -------- */
630 /* -------- multiple required parameters -------- */
631 /* we'll used defaults if the flag didn't appear */
632 udflt[op] = opt[op].flag && !appr[op];
633 break;
634 case 4:
635 /* -------- optional single variables -------- */
636 /* if the flag appeared (if there is a flag) but the paramter didn't,
637 we'll "invert" the default; if the flag didn't appear (or if there
638 isn't a flag) and the parameter also didn't appear, we'll use the
639 default. In either case, nprm[op] will be zero, and in both cases,
640 we need to use the default information. */
641 udflt[op] = (0 == nprm[op]);
642 /*
643 fprintf(stderr, "%s nprm[%d] = %u --> udflt[%d] = %d\n", me,
644 op, nprm[op], op, udflt[op]);
645 */
646 break;
647 case 5:
648 /* -------- multiple optional parameters -------- */
649 /* we'll use the default if the flag didn't appear (if there is a
650 flag) Otherwise, if nprm[op] is zero, then the user is saying,
651 I want zero parameters */
652 udflt[op] = opt[op].flag && !appr[op];
653 break;
654 }
655 if (!udflt[op])
656 continue;
657 prms[op] = airStrdup(opt[op].dflt);
658 /* fprintf(stderr, "%s: prms[%d] = |%s|\n", me, op, prms[op]); */
659 if (prms[op]) {
660 airMopAdd(mop, prms[op], airFree, airMopAlways);
661 airOneLinify(prms[op]);
662 tmpS = airStrdup(prms[op]);
663 nprm[op] = airStrntok(tmpS, " ");
664 airFree(tmpS);
665 /* printf("!%s: nprm[%d] in default = %u\n", me, op, nprm[op]); */
666 if ((int)opt[op].min < _hestMax(opt[op].max)) { /* HEY scrutinize casts */
667 if (!( AIR_IN_CL((int)opt[op].min, (int)nprm[op], _hestMax(opt[op].max))(((int)opt[op].min) <= ((int)nprm[op]) && ((int)nprm
[op]) <= (_hestMax(opt[op].max)))
/* HEY scrutinize casts */
668 || (airTypeString == opt[op].type
669 && parm->elideMultipleEmptyStringDefault) )) {
670 sprintf(err, "%s# parameters (in default) for %s is %d, "__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%s# parameters (in default) for %s is %d, "
"but need between %d and %d", ((parm && parm->verbosity
) ? me : ""), _hestIdent(ident, opt+op, parm, 1), nprm[op], opt
[op].min, _hestMax(opt[op].max))
671 "but need between %d and %d",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%s# parameters (in default) for %s is %d, "
"but need between %d and %d", ((parm && parm->verbosity
) ? me : ""), _hestIdent(ident, opt+op, parm, 1), nprm[op], opt
[op].min, _hestMax(opt[op].max))
672 ME, _hestIdent(ident, opt+op, parm, AIR_TRUE), nprm[op],__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%s# parameters (in default) for %s is %d, "
"but need between %d and %d", ((parm && parm->verbosity
) ? me : ""), _hestIdent(ident, opt+op, parm, 1), nprm[op], opt
[op].min, _hestMax(opt[op].max))
673 opt[op].min, _hestMax(opt[op].max))__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%s# parameters (in default) for %s is %d, "
"but need between %d and %d", ((parm && parm->verbosity
) ? me : ""), _hestIdent(ident, opt+op, parm, 1), nprm[op], opt
[op].min, _hestMax(opt[op].max))
;
674 return 1;
675 }
676 }
677 }
678 }
679 return 0;
680}
681
682/*
683** this function moved from air/miscAir; the usage below
684** is its only usage in Teem
685*/
686static int
687airIStore(void *v, int t, int i) {
688
689 switch(t) {
690 case airTypeBool: return (*((int*)v) = !!i); break;
691 case airTypeInt: return (*((int*)v) = i); break;
692 case airTypeUInt: return (int)(*((unsigned int*)v) = i); break;
693 case airTypeLongInt:return (int)(*((long int*)v) = i); break;
694 case airTypeULongInt:return (int)(*((unsigned long int*)v) = i); break;
695 case airTypeSize_t: return (int)(*((size_t*)v) = i); break;
696 case airTypeFloat: return (int)(*((float*)v) = (float)(i)); break;
697 case airTypeDouble: return (int)(*((double*)v) = (double)(i)); break;
698 case airTypeChar: return (*((char*)v) = (char)(i)); break;
699 default: return 0; break;
700 }
701}
702
703/*
704** this function moved from air/miscAir; the usage below
705** is its only usage in Teem
706*/
707double
708airDLoad(void *v, int t) {
709
710 switch(t) {
711 case airTypeBool: return AIR_CAST(double,*((int*)v))((double)(*((int*)v))); break;
712 case airTypeInt: return AIR_CAST(double,*((int*)v))((double)(*((int*)v))); break;
713 case airTypeUInt: return AIR_CAST(double,*((unsigned int*)v))((double)(*((unsigned int*)v))); break;
714 case airTypeLongInt:return AIR_CAST(double,*((long int*)v))((double)(*((long int*)v))); break;
715 case airTypeULongInt:return AIR_CAST(double,*((unsigned long int*)v))((double)(*((unsigned long int*)v))); break;
716 case airTypeSize_t: return AIR_CAST(double, *((size_t*)v))((double)(*((size_t*)v))); break;
717 case airTypeFloat: return AIR_CAST(double,*((float*)v))((double)(*((float*)v))); break;
718 case airTypeDouble: return *((double*)v); break;
719 case airTypeChar: return AIR_CAST(double,*((char*)v))((double)(*((char*)v))); break;
720 default: return 0; break;
721 }
722}
723
724
725int
726_hestSetValues(char **prms, int *udflt, unsigned int *nprm, int *appr,
727 hestOpt *opt,
728 char *err, const hestParm *parm, airArray *pmop) {
729 char ident[AIR_STRLEN_HUGE(1024+1)], me[]="_hestSetValues: ",
730 cberr[AIR_STRLEN_HUGE(1024+1)], *tok, *last, *prmsCopy;
731 double tmpD;
732 int op, type, numOpts, p, ret;
733 void *vP;
734 char *cP;
735 size_t size;
736
737 numOpts = _hestNumOpts(opt);
738 for (op=0; op<numOpts; op++) {
1
Assuming 'op' is < 'numOpts'
2
Loop condition is true. Entering loop body
11
Assuming 'op' is < 'numOpts'
12
Loop condition is true. Entering loop body
21
Assuming 'op' is < 'numOpts'
22
Loop condition is true. Entering loop body
31
Assuming 'op' is < 'numOpts'
32
Loop condition is true. Entering loop body
739 _hestIdent(ident, opt+op, parm, AIR_TRUE1);
740 opt[op].source = udflt[op] ? hestSourceDefault : hestSourceUser;
3
'?' condition is false
13
'?' condition is false
23
'?' condition is false
33
'?' condition is false
741 type = opt[op].type;
742 size = (airTypeEnum == type
4
Assuming 'type' is not equal to airTypeEnum
5
'?' condition is false
14
Assuming 'type' is not equal to airTypeEnum
15
'?' condition is false
24
Assuming 'type' is not equal to airTypeEnum
25
'?' condition is false
34
Assuming 'type' is not equal to airTypeEnum
35
'?' condition is false
743 ? (int)sizeof(int) /* HEY scrutinize casts */
744 : (airTypeOther == type
6
Assuming 'type' is not equal to airTypeOther
7
'?' condition is false
16
Assuming 'type' is not equal to airTypeOther
17
'?' condition is false
26
Assuming 'type' is not equal to airTypeOther
27
'?' condition is false
36
Assuming 'type' is equal to airTypeOther
37
'?' condition is true
745 ? (int)opt[op].CB->size /* HEY scrutinize casts */
746 : (int)airTypeSize[type])); /* HEY scrutinize casts */
747 cP = (char *)(vP = opt[op].valueP);
748 if (parm->verbosity) {
8
Taking false branch
18
Taking false branch
28
Taking false branch
38
Taking false branch
749 printf("%s %d of %d: \"%s\": |%s| --> kind=%d, type=%d, size=%d\n",
750 me, op, numOpts-1, prms[op], ident, opt[op].kind, type,
751 (int)size);
752 }
753 /* we may over-write these */
754 opt[op].alloc = 0;
755 if (opt[op].sawP) {
9
Taking false branch
19
Taking false branch
29
Taking false branch
39
Taking false branch
756 *(opt[op].sawP) = 0;
757 }
758 switch(opt[op].kind) {
10
'Default' branch taken. Execution continues on line 738
20
'Default' branch taken. Execution continues on line 738
30
'Default' branch taken. Execution continues on line 738
40
Control jumps to 'case 5:' at line 968
759 case 1:
760 /* -------- parameter-less boolean flags -------- */
761 if (vP)
762 *((int*)vP) = appr[op];
763 break;
764 case 2:
765 /* -------- one required parameter -------- */
766 if (prms[op] && vP) {
767 switch (type) {
768 case airTypeEnum:
769 if (1 != airParseStrE((int *)vP, prms[op], " ", 1, opt[op].enm)) {
770 sprintf(err, "%scouldn\'t parse %s\"%s\" as %s for %s",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%scouldn\'t parse %s\"%s\" as %s for %s", (
(parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) "
: "", prms[op], opt[op].enm->name, ident)
771 ME, udflt[op] ? "(default) " : "", prms[op],__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%scouldn\'t parse %s\"%s\" as %s for %s", (
(parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) "
: "", prms[op], opt[op].enm->name, ident)
772 opt[op].enm->name, ident)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%scouldn\'t parse %s\"%s\" as %s for %s", (
(parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) "
: "", prms[op], opt[op].enm->name, ident)
;
773 return 1;
774 }
775 break;
776 case airTypeOther:
777 strcpy(cberr, "")__builtin___strcpy_chk (cberr, "", __builtin_object_size (cberr
, 2 > 1 ? 1 : 0))
;
778 ret = opt[op].CB->parse(vP, prms[op], cberr);
779 if (ret) {
780 if (strlen(cberr)) {
781 sprintf(err, "%serror parsing \"%s\" as %s for %s:\n%s",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%serror parsing \"%s\" as %s for %s:\n%s",
((parm && parm->verbosity) ? me : ""), prms[op], opt
[op].CB->type, ident, cberr)
782 ME, prms[op], opt[op].CB->type, ident, cberr)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%serror parsing \"%s\" as %s for %s:\n%s",
((parm && parm->verbosity) ? me : ""), prms[op], opt
[op].CB->type, ident, cberr)
;
783 } else {
784 sprintf(err, "%serror parsing \"%s\" as %s for %s: returned %d",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%serror parsing \"%s\" as %s for %s: returned %d"
, ((parm && parm->verbosity) ? me : ""), prms[op],
opt[op].CB->type, ident, ret)
785 ME, prms[op], opt[op].CB->type, ident, ret)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%serror parsing \"%s\" as %s for %s: returned %d"
, ((parm && parm->verbosity) ? me : ""), prms[op],
opt[op].CB->type, ident, ret)
;
786 }
787 return ret;
788 }
789 if (opt[op].CB->destroy) {
790 /* vP is the address of a void*, we manage the void * */
791 opt[op].alloc = 1;
792 airMopAdd(pmop, (void**)vP, (airMopper)airSetNull, airMopOnError);
793 airMopAdd(pmop, *((void**)vP), opt[op].CB->destroy, airMopOnError);
794 }
795 break;
796 case airTypeString:
797 if (1 != airParseStrS((char **)vP, prms[op], " ", 1,
798 parm->greedySingleString)) {
799 sprintf(err, "%scouldn't parse %s\"%s\" as %s for %s",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %s for %s", (
(parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) "
: "", prms[op], airTypeStr[type], ident)
800 ME, udflt[op] ? "(default) " : "", prms[op],__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %s for %s", (
(parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) "
: "", prms[op], airTypeStr[type], ident)
801 airTypeStr[type], ident)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %s for %s", (
(parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) "
: "", prms[op], airTypeStr[type], ident)
;
802 return 1;
803 }
804 /* vP is the address of a char* (a char **), but what we
805 manage with airMop is the char * */
806 opt[op].alloc = 1;
807 airMopMem(pmop, vP, airMopOnError);
808 break;
809 default:
810 /* type isn't string or enum, so no last arg to airParseStr[type] */
811 if (1 != airParseStr[type](vP, prms[op], " ", 1)) {
812 sprintf(err, "%scouldn't parse %s\"%s\" as %s for %s",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %s for %s", (
(parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) "
: "", prms[op], airTypeStr[type], ident)
813 ME, udflt[op] ? "(default) " : "", prms[op],__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %s for %s", (
(parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) "
: "", prms[op], airTypeStr[type], ident)
814 airTypeStr[type], ident)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %s for %s", (
(parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) "
: "", prms[op], airTypeStr[type], ident)
;
815 return 1;
816 }
817 break;
818 }
819 }
820 break;
821 case 3:
822 /* -------- multiple required parameters -------- */
823 if (prms[op] && vP) {
824 switch (type) {
825 case airTypeEnum:
826 if (opt[op].min != /* min == max */
827 airParseStrE((int *)vP, prms[op], " ", opt[op].min, opt[op].enm)) {
828 sprintf(err, "%scouldn't parse %s\"%s\" as %d %s%s for %s",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %d %s%s for %s"
, ((parm && parm->verbosity) ? me : ""), udflt[op]
? "(default) " : "", prms[op], opt[op].min, opt[op].enm->
name, opt[op].min > 1 ? "s" : "", ident)
829 ME, udflt[op] ? "(default) " : "", prms[op],__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %d %s%s for %s"
, ((parm && parm->verbosity) ? me : ""), udflt[op]
? "(default) " : "", prms[op], opt[op].min, opt[op].enm->
name, opt[op].min > 1 ? "s" : "", ident)
830 opt[op].min, opt[op].enm->name,__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %d %s%s for %s"
, ((parm && parm->verbosity) ? me : ""), udflt[op]
? "(default) " : "", prms[op], opt[op].min, opt[op].enm->
name, opt[op].min > 1 ? "s" : "", ident)
831 opt[op].min > 1 ? "s" : "", ident)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %d %s%s for %s"
, ((parm && parm->verbosity) ? me : ""), udflt[op]
? "(default) " : "", prms[op], opt[op].min, opt[op].enm->
name, opt[op].min > 1 ? "s" : "", ident)
;
832 return 1;
833 }
834 break;
835 case airTypeOther:
836 prmsCopy = airStrdup(prms[op]);
837 for (p=0; p<(int)opt[op].min; p++) { /* HEY scrutinize casts */
838 tok = airStrtok(!p ? prmsCopy : NULL((void*)0), " ", &last);
839 strcpy(cberr, "")__builtin___strcpy_chk (cberr, "", __builtin_object_size (cberr
, 2 > 1 ? 1 : 0))
;
840 ret = opt[op].CB->parse(cP + p*size, tok, cberr);
841 if (ret) {
842 if (strlen(cberr))
843 sprintf(err, "%serror parsing \"%s\" (in \"%s\") as %s "__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%serror parsing \"%s\" (in \"%s\") as %s "
"for %s:\n%s", ((parm && parm->verbosity) ? me : ""
), tok, prms[op], opt[op].CB->type, ident, cberr)
844 "for %s:\n%s",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%serror parsing \"%s\" (in \"%s\") as %s "
"for %s:\n%s", ((parm && parm->verbosity) ? me : ""
), tok, prms[op], opt[op].CB->type, ident, cberr)
845 ME, tok, prms[op], opt[op].CB->type, ident, cberr)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%serror parsing \"%s\" (in \"%s\") as %s "
"for %s:\n%s", ((parm && parm->verbosity) ? me : ""
), tok, prms[op], opt[op].CB->type, ident, cberr)
;
846 else
847 sprintf(err, "%serror parsing \"%s\" (in \"%s\") as %s "__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%serror parsing \"%s\" (in \"%s\") as %s "
"for %s: returned %d", ((parm && parm->verbosity)
? me : ""), tok, prms[op], opt[op].CB->type, ident, ret)
848 "for %s: returned %d",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%serror parsing \"%s\" (in \"%s\") as %s "
"for %s: returned %d", ((parm && parm->verbosity)
? me : ""), tok, prms[op], opt[op].CB->type, ident, ret)
849 ME, tok, prms[op], opt[op].CB->type, ident, ret)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%serror parsing \"%s\" (in \"%s\") as %s "
"for %s: returned %d", ((parm && parm->verbosity)
? me : ""), tok, prms[op], opt[op].CB->type, ident, ret)
;
850 free(prmsCopy);
851 return 1;
852 }
853 }
854 free(prmsCopy);
855 if (opt[op].CB->destroy) {
856 /* vP is an array of void*s, we manage the individual void*s */
857 opt[op].alloc = 2;
858 for (p=0; p<(int)opt[op].min; p++) { /* HEY scrutinize casts */
859 airMopAdd(pmop, ((void**)vP)+p, (airMopper)airSetNull,
860 airMopOnError);
861 airMopAdd(pmop, *(((void**)vP)+p), opt[op].CB->destroy,
862 airMopOnError);
863 }
864 }
865 break;
866 case airTypeString:
867 if (opt[op].min != /* min == max */
868 airParseStr[type](vP, prms[op], " ", opt[op].min, AIR_FALSE0)) {
869 sprintf(err, "%scouldn't parse %s\"%s\" as %d %s%s for %s",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %d %s%s for %s"
, ((parm && parm->verbosity) ? me : ""), udflt[op]
? "(default) " : "", prms[op], opt[op].min, airTypeStr[type]
, opt[op].min > 1 ? "s" : "", ident)
870 ME, udflt[op] ? "(default) " : "", prms[op],__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %d %s%s for %s"
, ((parm && parm->verbosity) ? me : ""), udflt[op]
? "(default) " : "", prms[op], opt[op].min, airTypeStr[type]
, opt[op].min > 1 ? "s" : "", ident)
871 opt[op].min, airTypeStr[type],__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %d %s%s for %s"
, ((parm && parm->verbosity) ? me : ""), udflt[op]
? "(default) " : "", prms[op], opt[op].min, airTypeStr[type]
, opt[op].min > 1 ? "s" : "", ident)
872 opt[op].min > 1 ? "s" : "", ident)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %d %s%s for %s"
, ((parm && parm->verbosity) ? me : ""), udflt[op]
? "(default) " : "", prms[op], opt[op].min, airTypeStr[type]
, opt[op].min > 1 ? "s" : "", ident)
;
873 return 1;
874 }
875 /* vP is an array of char*s, (a char**), and what we manage
876 with airMop are the individual vP[p]. */
877 opt[op].alloc = 2;
878 for (p=0; p<(int)opt[op].min; p++) { /* HEY scrutinize casts */
879 airMopMem(pmop, &(((char**)vP)[p]), airMopOnError);
880 }
881 break;
882 default:
883 if (opt[op].min != /* min == max */
884 airParseStr[type](vP, prms[op], " ", opt[op].min)) {
885 sprintf(err, "%scouldn't parse %s\"%s\" as %d %s%s for %s",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %d %s%s for %s"
, ((parm && parm->verbosity) ? me : ""), udflt[op]
? "(default) " : "", prms[op], opt[op].min, airTypeStr[type]
, opt[op].min > 1 ? "s" : "", ident)
886 ME, udflt[op] ? "(default) " : "", prms[op],__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %d %s%s for %s"
, ((parm && parm->verbosity) ? me : ""), udflt[op]
? "(default) " : "", prms[op], opt[op].min, airTypeStr[type]
, opt[op].min > 1 ? "s" : "", ident)
887 opt[op].min, airTypeStr[type],__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %d %s%s for %s"
, ((parm && parm->verbosity) ? me : ""), udflt[op]
? "(default) " : "", prms[op], opt[op].min, airTypeStr[type]
, opt[op].min > 1 ? "s" : "", ident)
888 opt[op].min > 1 ? "s" : "", ident)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %d %s%s for %s"
, ((parm && parm->verbosity) ? me : ""), udflt[op]
? "(default) " : "", prms[op], opt[op].min, airTypeStr[type]
, opt[op].min > 1 ? "s" : "", ident)
;
889 return 1;
890 }
891 break;
892 }
893 }
894 break;
895 case 4:
896 /* -------- optional single variables -------- */
897 if (prms[op] && vP) {
898 switch (type) {
899 case airTypeEnum:
900 if (1 != airParseStrE((int *)vP, prms[op], " ", 1, opt[op].enm)) {
901 sprintf(err, "%scouldn't parse %s\"%s\" as %s for %s",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %s for %s", (
(parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) "
: "", prms[op], opt[op].enm->name, ident)
902 ME, udflt[op] ? "(default) " : "", prms[op],__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %s for %s", (
(parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) "
: "", prms[op], opt[op].enm->name, ident)
903 opt[op].enm->name, ident)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %s for %s", (
(parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) "
: "", prms[op], opt[op].enm->name, ident)
;
904 return 1;
905 }
906 break;
907 case airTypeOther:
908 /* we're parsing an "other". We will not perform the special
909 flagged single variable parameter games as done above, so
910 whether this option is flagged or unflagged, we're going
911 to treat it like an unflagged single variable parameter option:
912 if the parameter didn't appear, we'll parse it from the default,
913 if it did appear, we'll parse it from the command line. Setting
914 up prms[op] thusly has already been done by _hestDefaults() */
915 strcpy(cberr, "")__builtin___strcpy_chk (cberr, "", __builtin_object_size (cberr
, 2 > 1 ? 1 : 0))
;
916 ret = opt[op].CB->parse(vP, prms[op], cberr);
917 if (ret) {
918 if (strlen(cberr))
919 sprintf(err, "%serror parsing \"%s\" as %s for %s:\n%s",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%serror parsing \"%s\" as %s for %s:\n%s",
((parm && parm->verbosity) ? me : ""), prms[op], opt
[op].CB->type, ident, cberr)
920 ME, prms[op], opt[op].CB->type, ident, cberr)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%serror parsing \"%s\" as %s for %s:\n%s",
((parm && parm->verbosity) ? me : ""), prms[op], opt
[op].CB->type, ident, cberr)
;
921 else
922 sprintf(err, "%serror parsing \"%s\" as %s for %s: returned %d",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%serror parsing \"%s\" as %s for %s: returned %d"
, ((parm && parm->verbosity) ? me : ""), prms[op],
opt[op].CB->type, ident, ret)
923 ME, prms[op], opt[op].CB->type, ident, ret)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%serror parsing \"%s\" as %s for %s: returned %d"
, ((parm && parm->verbosity) ? me : ""), prms[op],
opt[op].CB->type, ident, ret)
;
924 return 1;
925 }
926 if (opt[op].CB->destroy) {
927 /* vP is the address of a void*, we manage the void* */
928 opt[op].alloc = 1;
929 airMopAdd(pmop, vP, (airMopper)airSetNull, airMopOnError);
930 airMopAdd(pmop, *((void**)vP), opt[op].CB->destroy, airMopOnError);
931 }
932 break;
933 case airTypeString:
934 if (1 != airParseStr[type](vP, prms[op], " ", 1,
935 parm->greedySingleString)) {
936 sprintf(err, "%scouldn't parse %s\"%s\" as %s for %s",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %s for %s", (
(parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) "
: "", prms[op], airTypeStr[type], ident)
937 ME, udflt[op] ? "(default) " : "", prms[op],__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %s for %s", (
(parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) "
: "", prms[op], airTypeStr[type], ident)
938 airTypeStr[type], ident)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %s for %s", (
(parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) "
: "", prms[op], airTypeStr[type], ident)
;
939 return 1;
940 }
941 opt[op].alloc = 1;
942 if (opt[op].flag && 1 == _hestCase(opt, udflt, nprm, appr, op)) {
943 /* we just parsed the default, but now we want to "invert" it */
944 *((char**)vP) = (char *)airFree(*((char**)vP));
945 opt[op].alloc = 0;
946 }
947 /* vP is the address of a char* (a char**), and what we
948 manage with airMop is the char * */
949 airMopMem(pmop, vP, airMopOnError);
950 break;
951 default:
952 if (1 != airParseStr[type](vP, prms[op], " ", 1)) {
953 sprintf(err, "%scouldn't parse %s\"%s\" as %s for %s",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %s for %s", (
(parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) "
: "", prms[op], airTypeStr[type], ident)
954 ME, udflt[op] ? "(default) " : "", prms[op],__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %s for %s", (
(parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) "
: "", prms[op], airTypeStr[type], ident)
955 airTypeStr[type], ident)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %s for %s", (
(parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) "
: "", prms[op], airTypeStr[type], ident)
;
956 return 1;
957 }
958 opt[op].alloc = 0;
959 if (1 == _hestCase(opt, udflt, nprm, appr, op)) {
960 /* we just parsed the default, but now we want to "invert" it */
961 tmpD = airDLoad(vP, type);
962 airIStore(vP, type, tmpD ? 0 : 1);
963 }
964 break;
965 }
966 }
967 break;
968 case 5:
969 /* -------- multiple optional parameters -------- */
970 /* hammerhead problems in this case;
971 may have been from calloc(0), fixed below */
972 if (prms[op] && vP) {
41
Taking true branch
973 if (1 == _hestCase(opt, udflt, nprm, appr, op)) {
42
Taking false branch
974 *((void**)vP) = NULL((void*)0);
975 /* alloc and sawP set above */
976 } else {
977 if (airTypeString == type) {
43
Taking false branch
978 /* this is sneakiness: we allocate one more element so that
979 the resulting char** is, like argv, NULL-terminated */
980 *((void**)vP) = calloc(nprm[op]+1, size);
981 } else {
982 if (nprm[op]) {
44
Taking true branch
983 /* only allocate if there's something to allocate */
984 *((void**)vP) = calloc(nprm[op], size);
985 } else {
986 *((void**)vP) = NULL((void*)0);
987 }
988 }
989 if (parm->verbosity) {
45
Taking false branch
990 printf("!%s: nprm[%d] = %u\n", me, op, nprm[op]);
991 printf("!%s: new array (size %u*%u) is at 0x%p\n", me,
992 nprm[op], (unsigned int)size, *((void**)vP));
993 }
994 if (*((void**)vP)) {
46
Taking false branch
995 airMopMem(pmop, vP, airMopOnError);
996 }
997 *(opt[op].sawP) = nprm[op];
998 /* so far everything we've done is regardless of type */
999 switch (type) {
47
Control jumps to 'case airTypeOther:' at line 1012
1000 case airTypeEnum:
1001 opt[op].alloc = 1;
1002 if (nprm[op] !=
1003 airParseStrE((int *)(*((void**)vP)), prms[op], " ", nprm[op],
1004 opt[op].enm)) {
1005 sprintf(err, "%scouldn't parse %s\"%s\" as %u %s%s for %s",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %u %s%s for %s"
, ((parm && parm->verbosity) ? me : ""), udflt[op]
? "(default) " : "", prms[op], nprm[op], opt[op].enm->name
, nprm[op] > 1 ? "s" : "", ident)
1006 ME, udflt[op] ? "(default) " : "", prms[op],__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %u %s%s for %s"
, ((parm && parm->verbosity) ? me : ""), udflt[op]
? "(default) " : "", prms[op], nprm[op], opt[op].enm->name
, nprm[op] > 1 ? "s" : "", ident)
1007 nprm[op], opt[op].enm->name,__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %u %s%s for %s"
, ((parm && parm->verbosity) ? me : ""), udflt[op]
? "(default) " : "", prms[op], nprm[op], opt[op].enm->name
, nprm[op] > 1 ? "s" : "", ident)
1008 nprm[op] > 1 ? "s" : "", ident)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %u %s%s for %s"
, ((parm && parm->verbosity) ? me : ""), udflt[op]
? "(default) " : "", prms[op], nprm[op], opt[op].enm->name
, nprm[op] > 1 ? "s" : "", ident)
;
1009 return 1;
1010 }
1011 break;
1012 case airTypeOther:
1013 cP = (char *)(*((void**)vP));
1014 prmsCopy = airStrdup(prms[op]);
1015 opt[op].alloc = (opt[op].CB->destroy ? 3 : 1);
48
'?' condition is true
1016 for (p=0; p<(int)nprm[op]; p++) { /* HEY scrutinize casts */
49
Loop condition is true. Entering loop body
53
Loop condition is false. Execution continues on line 1038
1017 tok = airStrtok(!p ? prmsCopy : NULL((void*)0), " ", &last);
50
'?' condition is true
1018 /* hammerhead problems went away when this line
1019 was replaced by the following one:
1020 strcpy(cberr, "");
1021 */
1022 cberr[0] = 0;
1023 ret = opt[op].CB->parse(cP + p*size, tok, cberr);
1024 if (ret) {
51
Assuming 'ret' is 0
52
Taking false branch
1025 if (strlen(cberr))
1026 sprintf(err,"%serror parsing \"%s\" (in \"%s\") as %s "__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%serror parsing \"%s\" (in \"%s\") as %s "
"for %s:\n%s", ((parm && parm->verbosity) ? me : ""
), tok, prms[op], opt[op].CB->type, ident, cberr)
1027 "for %s:\n%s",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%serror parsing \"%s\" (in \"%s\") as %s "
"for %s:\n%s", ((parm && parm->verbosity) ? me : ""
), tok, prms[op], opt[op].CB->type, ident, cberr)
1028 ME, tok, prms[op], opt[op].CB->type, ident, cberr)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%serror parsing \"%s\" (in \"%s\") as %s "
"for %s:\n%s", ((parm && parm->verbosity) ? me : ""
), tok, prms[op], opt[op].CB->type, ident, cberr)
;
1029
1030 else
1031 sprintf(err, "%serror parsing \"%s\" (in \"%s\") as %s "__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%serror parsing \"%s\" (in \"%s\") as %s "
"for %s: returned %d", ((parm && parm->verbosity)
? me : ""), tok, prms[op], opt[op].CB->type, ident, ret)
1032 "for %s: returned %d",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%serror parsing \"%s\" (in \"%s\") as %s "
"for %s: returned %d", ((parm && parm->verbosity)
? me : ""), tok, prms[op], opt[op].CB->type, ident, ret)
1033 ME, tok, prms[op], opt[op].CB->type, ident, ret)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%serror parsing \"%s\" (in \"%s\") as %s "
"for %s: returned %d", ((parm && parm->verbosity)
? me : ""), tok, prms[op], opt[op].CB->type, ident, ret)
;
1034 free(prmsCopy);
1035 return 1;
1036 }
1037 }
1038 free(prmsCopy);
1039 if (opt[op].CB->destroy) {
54
Taking true branch
1040 for (p=0; p<(int)nprm[op]; p++) { /* HEY scrutinize casts */
55
Loop condition is true. Entering loop body
1041 /* avert your eyes. vP is the address of an array of void*s.
1042 We manage the void*s */
1043 airMopAdd(pmop, (*((void***)vP))+p, (airMopper)airSetNull,
1044 airMopOnError);
1045 airMopAdd(pmop, *((*((void***)vP))+p), opt[op].CB->destroy,
56
Dereference of null pointer
1046 airMopOnError);
1047 }
1048 }
1049 break;
1050 case airTypeString:
1051 opt[op].alloc = 3;
1052 if (nprm[op] !=
1053 airParseStrS((char **)(*((void**)vP)), prms[op], " ", nprm[op],
1054 parm->greedySingleString)) {
1055 sprintf(err, "%scouldn't parse %s\"%s\" as %d %s%s for %s",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %d %s%s for %s"
, ((parm && parm->verbosity) ? me : ""), udflt[op]
? "(default) " : "", prms[op], nprm[op], airTypeStr[type], nprm
[op] > 1 ? "s" : "", ident)
1056 ME, udflt[op] ? "(default) " : "", prms[op],__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %d %s%s for %s"
, ((parm && parm->verbosity) ? me : ""), udflt[op]
? "(default) " : "", prms[op], nprm[op], airTypeStr[type], nprm
[op] > 1 ? "s" : "", ident)
1057 nprm[op], airTypeStr[type],__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %d %s%s for %s"
, ((parm && parm->verbosity) ? me : ""), udflt[op]
? "(default) " : "", prms[op], nprm[op], airTypeStr[type], nprm
[op] > 1 ? "s" : "", ident)
1058 nprm[op] > 1 ? "s" : "", ident)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %d %s%s for %s"
, ((parm && parm->verbosity) ? me : ""), udflt[op]
? "(default) " : "", prms[op], nprm[op], airTypeStr[type], nprm
[op] > 1 ? "s" : "", ident)
;
1059 return 1;
1060 }
1061 /* vP is the address of an array of char*s (a char ***), and
1062 what we manage with airMop is the individual (*vP)[p],
1063 as well as vP itself (above). */
1064 for (p=0; p<(int)nprm[op]; p++) { /* HEY scrutinize casts */
1065 airMopAdd(pmop, (*((char***)vP))[p], airFree, airMopOnError);
1066 }
1067 /* do the NULL-termination described above */
1068 (*((char***)vP))[nprm[op]] = NULL((void*)0);
1069 break;
1070 default:
1071 opt[op].alloc = 1;
1072 if (nprm[op] !=
1073 airParseStr[type](*((void**)vP), prms[op], " ", nprm[op])) {
1074 sprintf(err, "%scouldn't parse %s\"%s\" as %d %s%s for %s",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %d %s%s for %s"
, ((parm && parm->verbosity) ? me : ""), udflt[op]
? "(default) " : "", prms[op], nprm[op], airTypeStr[type], nprm
[op] > 1 ? "s" : "", ident)
1075 ME, udflt[op] ? "(default) " : "", prms[op],__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %d %s%s for %s"
, ((parm && parm->verbosity) ? me : ""), udflt[op]
? "(default) " : "", prms[op], nprm[op], airTypeStr[type], nprm
[op] > 1 ? "s" : "", ident)
1076 nprm[op], airTypeStr[type],__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %d %s%s for %s"
, ((parm && parm->verbosity) ? me : ""), udflt[op]
? "(default) " : "", prms[op], nprm[op], airTypeStr[type], nprm
[op] > 1 ? "s" : "", ident)
1077 nprm[op] > 1 ? "s" : "", ident)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %d %s%s for %s"
, ((parm && parm->verbosity) ? me : ""), udflt[op]
? "(default) " : "", prms[op], nprm[op], airTypeStr[type], nprm
[op] > 1 ? "s" : "", ident)
;
1078 return 1;
1079 }
1080 break;
1081 }
1082 }
1083 }
1084 break;
1085 }
1086 }
1087 return 0;
1088}
1089
1090/*
1091******** hestParse()
1092**
1093** documentation?
1094*/
1095int
1096hestParse(hestOpt *opt, int _argc, const char **_argv,
1097 char **_errP, const hestParm *_parm) {
1098 char me[]="hestParse: ";
1099 char *param, *param_copy;
1100 char **argv, **prms, *err;
1101 int a, argc, argr, *appr, *udflt, nrf, numOpts, big, ret, i;
1102 unsigned int *nprm;
1103 airArray *mop;
1104 hestParm *parm;
1105 size_t start_index, end_index;
1106
1107 numOpts = _hestNumOpts(opt);
1108
1109 /* -------- initialize the mop! */
1110 mop = airMopNew();
1111
1112 /* -------- either copy given _parm, or allocate one */
1113 if (_parm) {
1114 parm = NULL((void*)0);
1115 }
1116 else {
1117 parm = hestParmNew();
1118 airMopAdd(mop, parm, (airMopper)hestParmFree, airMopAlways);
1119 }
1120 /* how to const-correctly use parm or _parm in an expression */
1121#define PARM (_parm ? _parm : parm)
1122
1123 /* -------- allocate the err string. To determine its size with total
1124 ridiculous safety we have to find the biggest things which can appear
1125 in the string. */
1126 big = _hestErrStrlen(opt, _argc, _argv);
1127 if (!( err = AIR_CALLOC(big, char)(char*)(calloc((big), sizeof(char))) )) {
1128 fprintf(stderr__stderrp, "%s PANIC: couldn't allocate error message "
1129 "buffer (size %d)\n", me, big);
1130 /* exit(1); */
1131 }
1132 if (_errP) {
1133 /* if they care about the error string, than it is mopped only
1134 when there _wasn't_ an error */
1135 *_errP = err;
1136 airMopAdd(mop, _errP, (airMopper)airSetNull, airMopOnOkay);
1137 airMopAdd(mop, err, airFree, airMopOnOkay);
1138 }
1139 else {
1140 /* otherwise, we're making the error string just for our own
1141 convenience, and we'll always clean it up on exit */
1142 airMopAdd(mop, err, airFree, airMopAlways);
1143 }
1144
1145 /* -------- check on validity of the hestOpt array */
1146 if (_hestPanic(opt, err, PARM)) {
1147 airMopError(mop); return 1;
1148 }
1149
1150 /* -------- Create all the local arrays used to save state during
1151 the processing of all the different options */
1152 nprm = AIR_CALLOC(numOpts, unsigned int)(unsigned int*)(calloc((numOpts), sizeof(unsigned int)));
1153 airMopMem(mop, &nprm, airMopAlways);
1154 appr = AIR_CALLOC(numOpts, int)(int*)(calloc((numOpts), sizeof(int)));
1155 airMopMem(mop, &appr, airMopAlways);
1156 udflt = AIR_CALLOC(numOpts, int)(int*)(calloc((numOpts), sizeof(int)));
1157 airMopMem(mop, &udflt, airMopAlways);
1158 prms = AIR_CALLOC(numOpts, char *)(char **)(calloc((numOpts), sizeof(char *)));
1159 airMopMem(mop, &prms, airMopAlways);
1160 for (a=0; a<numOpts; a++) {
1161 prms[a] = NULL((void*)0);
1162 }
1163
1164 /* -------- find out how big the argv array needs to be, first
1165 by seeing how many args are in the response files, and then adding
1166 on the args from the actual argv (getting this right the first time
1167 greatly simplifies the problem of eliminating memory leaks) */
1168 if (_hestArgsInResponseFiles(&argr, &nrf, _argv, err, PARM)) {
1169 airMopError(mop); return 1;
1170 }
1171 argc = argr + _argc - nrf;
1172
1173 if (PARM->verbosity) {
1174 printf("!%s: nrf = %d; argr = %d; _argc = %d --> argc = %d\n",
1175 me, nrf, argr, _argc, argc);
1176 }
1177 argv = AIR_CALLOC(argc+1, char *)(char **)(calloc((argc+1), sizeof(char *)));
1178 airMopMem(mop, &argv, airMopAlways);
1179
1180 /* -------- process response files (if any) and set the remaining
1181 elements of argv */
1182 if (PARM->verbosity) printf("%s: #### calling hestResponseFiles\n", me);
1183 if (_hestResponseFiles(argv, _argv, PARM, mop)) {
1184 airMopError(mop); return 1;
1185 }
1186 if (PARM->verbosity) printf("%s: #### hestResponseFiles done!\n", me);
1187 /*
1188 _hestPrintArgv(argc, argv);
1189 */
1190
1191 /* -------- extract flags and their associated parameters from argv */
1192 if (PARM->verbosity) printf("%s: #### calling hestExtractFlagged\n", me);
1193 if (_hestExtractFlagged(prms, nprm, appr,
1194 &argc, argv,
1195 opt,
1196 err, PARM, mop)) {
1197 airMopError(mop); return 1;
1198 }
1199 if (PARM->verbosity) printf("%s: #### hestExtractFlagged done!\n", me);
1200 /*
1201 _hestPrintArgv(argc, argv);
1202 */
1203
1204 /* -------- extract args for unflagged options */
1205 if (PARM->verbosity) printf("%s: #### calling hestExtractUnflagged\n", me);
1206 if (_hestExtractUnflagged(prms, nprm,
1207 &argc, argv,
1208 opt,
1209 err, PARM, mop)) {
1210 airMopError(mop); return 1;
1211 }
1212 if (PARM->verbosity) printf("%s: #### hestExtractUnflagged done!\n", me);
1213
1214 /* currently, any left over arguments indicate error */
1215 if (argc) {
1216 sprintf(err, "%sunexpected arg%s: \"%s\"", ME,__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%sunexpected arg%s: \"%s\"", ((parm &&
parm->verbosity) ? me : ""), ('-' == argv[0][0] ? " (or unrecognized flag)"
: ""), argv[0])
1217 ('-' == argv[0][0]__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%sunexpected arg%s: \"%s\"", ((parm &&
parm->verbosity) ? me : ""), ('-' == argv[0][0] ? " (or unrecognized flag)"
: ""), argv[0])
1218 ? " (or unrecognized flag)"__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%sunexpected arg%s: \"%s\"", ((parm &&
parm->verbosity) ? me : ""), ('-' == argv[0][0] ? " (or unrecognized flag)"
: ""), argv[0])
1219 : ""), argv[0])__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2
> 1 ? 1 : 0), "%sunexpected arg%s: \"%s\"", ((parm &&
parm->verbosity) ? me : ""), ('-' == argv[0][0] ? " (or unrecognized flag)"
: ""), argv[0])
;
1220 airMopError(mop); return 1;
1221 }
1222
1223 /* -------- learn defaults */
1224 if (PARM->verbosity) printf("%s: #### calling hestDefaults\n", me);
1225 if (_hestDefaults(prms, udflt, nprm, appr,
1226 opt,
1227 err, PARM, mop)) {
1228 airMopError(mop); return 1;
1229 }
1230 if (PARM->verbosity) printf("%s: #### hestDefaults done!\n", me);
1231
1232 /* remove quotes from strings
1233 if greedy wasn't turned on for strings, then we have no hope
1234 of capturing filenames with spaces. */
1235 if ( PARM->greedySingleString ) {
1236 for (i=0; i<numOpts; i++) {
1237 param = prms[i];
1238 param_copy = NULL((void*)0);
1239 if (param && strstr(param, " ")) {
1240 start_index = 0;
1241 end_index = strlen(param)-1;
1242 if (param[start_index] == '\"')
1243 start_index++;
1244 if (param[end_index] == '\"')
1245 end_index--;
1246 param_copy = AIR_CALLOC(end_index-start_index+2, char)(char*)(calloc((end_index-start_index+2), sizeof(char)));
1247 strncpy(param_copy,&param[start_index],end_index-start_index+1)__builtin___strncpy_chk (param_copy, &param[start_index],
end_index-start_index+1, __builtin_object_size (param_copy, 2
> 1 ? 1 : 0))
;
1248 param_copy[end_index-start_index+1] = '\0';
1249 strcpy(param,param_copy)__builtin___strcpy_chk (param, param_copy, __builtin_object_size
(param, 2 > 1 ? 1 : 0))
;
1250 free(param_copy);
1251 }
1252 }
1253 }
1254
1255 /* -------- now, the actual parsing of values */
1256 /* hammerhead problems in _hestSetValues */
1257 if (PARM->verbosity) printf("%s: #### calling hestSetValues\n", me);
1258 ret = _hestSetValues(prms, udflt, nprm, appr,
1259 opt,
1260 err, PARM, mop);
1261 if (ret) {
1262 airMopError(mop); return ret;
1263 }
1264
1265 if (PARM->verbosity) printf("%s: #### hestSetValues done!\n", me);
1266#undef PARM
1267
1268 airMopOkay(mop);
1269 return 0;
1270}
1271
1272/*
1273******** hestParseFree()
1274**
1275** free()s whatever was allocated by hestParse()
1276**
1277** returns NULL only to facilitate use with the airMop functions.
1278** You should probably just ignore this quirk.
1279*/
1280void *
1281hestParseFree(hestOpt *opt) {
1282 int op, i, numOpts;
1283 unsigned int ui;
1284 void **vP;
1285 void ***vAP;
1286 char **str;
1287 char ***strP;
1288
1289 numOpts = _hestNumOpts(opt);
1290 for (op=0; op<numOpts; op++) {
1291 /*
1292 printf("!hestParseFree: op = %d/%d -> kind = %d; type = %d; alloc = %d\n",
1293 op, numOpts-1, opt[op].kind, opt[op].type, opt[op].alloc);
1294 */
1295 vP = (void **)opt[op].valueP;
1296 vAP = (void ***)opt[op].valueP;
1297 str = (char **)opt[op].valueP;
1298 strP = (char ***)opt[op].valueP;
1299 switch (opt[op].alloc) {
1300 case 0:
1301 /* nothing was allocated */
1302 break;
1303 case 1:
1304 if (airTypeOther != opt[op].type) {
1305 *vP = airFree(*vP);
1306 }
1307 else {
1308 /* alloc is one either because we parsed one thing, and we have a
1309 destroy callback, or, because we parsed a dynamically-created array
1310 of things, and we don't have a destroy callback */
1311 if (opt[op].CB->destroy) {
1312 *vP = opt[op].CB->destroy(*vP);
1313 }
1314 else {
1315 *vP = airFree(*vP);
1316 }
1317 }
1318 break;
1319 case 2:
1320 if (airTypeString == opt[op].type) {
1321 for (i=0; i<(int)opt[op].min; i++) { /* HEY scrutinize casts */
1322 str[i] = (char *)airFree(str[i]);
1323 }
1324 }
1325 else {
1326 for (i=0; i<(int)opt[op].min; i++) { /* HEY scrutinize casts */
1327 vP[i] = opt[op].CB->destroy(vP[i]);
1328 }
1329 }
1330 break;
1331 case 3:
1332 if (airTypeString == opt[op].type) {
1333 for (ui=0; ui<*(opt[op].sawP); ui++) {
1334 (*strP)[ui] = (char *)airFree((*strP)[ui]);
1335 }
1336 *strP = (char **)airFree(*strP);
1337 }
1338 else {
1339 for (ui=0; ui<*(opt[op].sawP); ui++) {
1340 (*vAP)[ui] = opt[op].CB->destroy((*vAP)[ui]);
1341 }
1342 *vAP = (void **)airFree(*vAP);
1343 }
1344 break;
1345 }
1346 }
1347 return NULL((void*)0);
1348}
1349
1350/*
1351******** hestParseOrDie()
1352**
1353** dumb little function which encapsulate a common usage of hest:
1354** first, make sure hestOpt is valid with hestOptCheck(). Then,
1355** if argc is 0 (and !parm->noArgsIsNoProblem): maybe show
1356** info, usage, and glossary, all according to given flags, then exit(1)
1357** if parsing failed: show error message, and maybe usage and glossary,
1358** again according to boolean flags, then exit(1)
1359** if parsing succeeded: return
1360*/
1361void
1362hestParseOrDie(hestOpt *opt, int argc, const char **argv,
1363 hestParm *parm,
1364 const char *me, const char *info,
1365 int doInfo, int doUsage, int doGlossary) {
1366 int E;
1367 int argcBad;
1368 char *errS;
1369
1370 if (opt) {
1371 if (hestOptCheck(opt, &errS)) {
1372 fprintf(stderr__stderrp, "ERROR in hest usage:\n%s\n", errS); free(errS);
1373 exit(1);
1374 }
1375 E = 0;
1376 /* argc is good if its non-zero, or (else) being zero is ok */
1377 argcBad = !(argc || (parm && parm->noArgsIsNoProblem));
1378 if ( argcBad ||
1379 (E = hestParse(opt, argc, argv, &errS, parm)) ) {
1380 if (E) {
1381 if (argv[0] && !strcmp(argv[0], "--version")) {
1382 /* print version info and bail */
1383 char vbuff[AIR_STRLEN_LARGE(512+1)];
1384 airTeemVersionSprint(vbuff);
1385 printf("%s\n", vbuff);
1386 hestParmFree(parm);
1387 hestOptFree(opt);
1388 exit(0);
1389 } else if (argv[0] && !strcmp(argv[0], "--help")) {
1390 /* actually, not an error, they were asking for help */
1391 E = 0;
1392 } else {
1393 fprintf(stderr__stderrp, "ERROR: %s\n", errS);
1394 }
1395 free(errS);
1396 }
1397 if (!E) {
1398 /* no error, just !argc */
1399 if (doInfo && info) hestInfo(stdout__stdoutp, me?me:"", info, parm);
1400 }
1401 if (doUsage) hestUsage(E ? stderr__stderrp : stdout__stdoutp, opt, me?me:"", parm);
1402 if (doGlossary) hestGlossary(E ? stderr__stderrp : stdout__stdoutp, opt, parm);
1403 hestParmFree(parm);
1404 hestOptFree(opt);
1405 exit(1);
1406 }
1407 }
1408
1409 return;
1410}