Skip to content

Commit a38eed1

Browse files
jacobmealeybagder
authored andcommitted
trurl: errorf improvements
Closes #235
1 parent 364006d commit a38eed1

File tree

1 file changed

+73
-61
lines changed

1 file changed

+73
-61
lines changed

trurl.c

Lines changed: 73 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -147,17 +147,6 @@ static void warnf(char *fmt, ...)
147147
va_end(ap);
148148
}
149149

150-
static void errorf(int exit_code, char *fmt, ...)
151-
{
152-
va_list ap;
153-
va_start(ap, fmt);
154-
fputs(ERROR_PREFIX, stderr);
155-
vfprintf(stderr, fmt, ap);
156-
fputs("\n" ERROR_PREFIX "Try " PROGNAME " -h for help\n", stderr);
157-
va_end(ap);
158-
exit(exit_code);
159-
}
160-
161150
#define VERIFY(o, exit_code, ...) \
162151
do { \
163152
if(!o->verify) \
@@ -166,7 +155,7 @@ static void errorf(int exit_code, char *fmt, ...)
166155
/* make sure to terminate the JSON array */ \
167156
if(o->jsonout) \
168157
printf("%s]\n", o->urls ? "\n" : ""); \
169-
errorf(exit_code, __VA_ARGS__); \
158+
errorf(o, exit_code, __VA_ARGS__); \
170159
} \
171160
} while(0)
172161

@@ -301,12 +290,27 @@ int nqpairs; /* how many is stored */
301290

302291
static void trurl_cleanup_options(struct option *o)
303292
{
304-
curl_slist_free_all(o->url_list);
305-
curl_slist_free_all(o->set_list);
306-
curl_slist_free_all(o->iter_list);
307-
curl_slist_free_all(o->append_query);
308-
curl_slist_free_all(o->trim_list);
309-
curl_slist_free_all(o->append_path);
293+
if(!o)
294+
return;
295+
curl_slist_free_all(o->url_list);
296+
curl_slist_free_all(o->set_list);
297+
curl_slist_free_all(o->iter_list);
298+
curl_slist_free_all(o->append_query);
299+
curl_slist_free_all(o->trim_list);
300+
curl_slist_free_all(o->append_path);
301+
}
302+
303+
static void errorf(struct option *o, int exit_code, char *fmt, ...)
304+
{
305+
va_list ap;
306+
va_start(ap, fmt);
307+
fputs(ERROR_PREFIX, stderr);
308+
vfprintf(stderr, fmt, ap);
309+
fputs("\n" ERROR_PREFIX "Try " PROGNAME " -h for help\n", stderr);
310+
va_end(ap);
311+
trurl_cleanup_options(o);
312+
curl_global_cleanup();
313+
exit(exit_code);
310314
}
311315

312316
static char *strurldecode(const char *url, int inlength, int *outlength)
@@ -329,11 +333,11 @@ static void urlfile(struct option *o, const char *file)
329333
{
330334
FILE *f;
331335
if(o->url)
332-
errorf(ERROR_FLAG, "only one --url-file is supported");
336+
errorf(o, ERROR_FLAG, "only one --url-file is supported");
333337
if(strcmp("-", file)) {
334338
f = fopen(file, "rt");
335339
if(!f)
336-
errorf(ERROR_FILE, "--url-file %s not found", file);
340+
errorf(o, ERROR_FILE, "--url-file %s not found", file);
337341
o->urlopen = true;
338342
}
339343
else
@@ -386,7 +390,7 @@ static void appendadd(struct option *o,
386390
else if(!strncmp("query=", arg, 6))
387391
queryadd(o, arg + 6);
388392
else
389-
errorf(ERROR_APPEND, "--append unsupported component: %s", arg);
393+
errorf(o, ERROR_APPEND, "--append unsupported component: %s", arg);
390394
}
391395

392396
static void setadd(struct option *o,
@@ -416,13 +420,13 @@ static void trimadd(struct option *o,
416420
o->trim_list = n;
417421
}
418422

419-
static bool checkoptarg(const char *str,
423+
static bool checkoptarg(struct option *o, const char *str,
420424
const char *given,
421425
const char *arg)
422426
{
423427
if(!strcmp(str, given)) {
424428
if(!arg)
425-
errorf(ERROR_ARG, "Missing argument for %s", str);
429+
errorf(o, ERROR_ARG, "Missing argument for %s", str);
426430
return true;
427431
}
428432
return false;
@@ -441,56 +445,61 @@ static int getarg(struct option *o,
441445
show_version();
442446
else if(!strcmp("-h", flag) || !strcmp("--help", flag))
443447
help();
444-
else if(checkoptarg("--url", flag, arg)) {
448+
else if(checkoptarg(o, "--url", flag, arg)) {
445449
urladd(o, arg);
446450
*usedarg = true;
447451
}
448-
else if(checkoptarg("-f", flag, arg) ||
449-
checkoptarg("--url-file", flag, arg)) {
452+
else if(checkoptarg(o, "-f", flag, arg) ||
453+
checkoptarg(o, "--url-file", flag, arg)) {
450454
urlfile(o, arg);
451455
*usedarg = true;
452456
}
453-
else if(checkoptarg("-a", flag, arg) || checkoptarg("--append", flag, arg)) {
457+
else if(checkoptarg(o, "-a", flag, arg) ||
458+
checkoptarg(o, "--append", flag, arg)) {
454459
appendadd(o, arg);
455460
*usedarg = true;
456461
}
457-
else if(checkoptarg("-s", flag, arg) || checkoptarg("--set", flag, arg)) {
462+
else if(checkoptarg(o, "-s", flag, arg) ||
463+
checkoptarg(o, "--set", flag, arg)) {
458464
setadd(o, arg);
459465
*usedarg = true;
460466
}
461-
else if(checkoptarg("--iterate", flag, arg)) {
467+
else if(checkoptarg(o, "--iterate", flag, arg)) {
462468
iteradd(o, arg);
463469
*usedarg = true;
464470
}
465-
else if(checkoptarg("--redirect", flag, arg)) {
471+
else if(checkoptarg(o, "--redirect", flag, arg)) {
466472
if(o->redirect)
467-
errorf(ERROR_FLAG, "only one --redirect is supported");
473+
errorf(o, ERROR_FLAG, "only one --redirect is supported");
468474
o->redirect = arg;
469475
*usedarg = true;
470476
}
471-
else if(checkoptarg("--query-separator", flag, arg)) {
477+
else if(checkoptarg(o, "--query-separator", flag, arg)) {
472478
if(o->qsep)
473-
errorf(ERROR_FLAG, "only one --query-separator is supported");
479+
errorf(o, ERROR_FLAG, "only one --query-separator is supported");
474480
if(strlen(arg) != 1)
475-
errorf(ERROR_FLAG, "only single-letter query separators are supported");
481+
errorf(o, ERROR_FLAG,
482+
"only single-letter query separators are supported");
476483
o->qsep = arg;
477484
*usedarg = true;
478485
}
479-
else if(checkoptarg("--trim", flag, arg)) {
486+
else if(checkoptarg(o, "--trim", flag, arg)) {
480487
trimadd(o, arg);
481488
*usedarg = true;
482489
}
483-
else if(checkoptarg("-g", flag, arg) || checkoptarg("--get", flag, arg)) {
490+
else if(checkoptarg(o, "-g", flag, arg) ||
491+
checkoptarg(o, "--get", flag, arg)) {
484492
if(o->format)
485-
errorf(ERROR_FLAG, "only one --get is supported");
493+
errorf(o, ERROR_FLAG, "only one --get is supported");
486494
if(o->jsonout)
487-
errorf(ERROR_FLAG, "--get is mututally exclusive with --json");
495+
errorf(o, ERROR_FLAG,
496+
"--get is mututally exclusive with --json");
488497
o->format = arg;
489498
*usedarg = true;
490499
}
491500
else if(!strcmp("--json", flag)) {
492501
if(o->format)
493-
errorf(ERROR_FLAG, "--json is mututally exclusive with --get");
502+
errorf(o, ERROR_FLAG, "--json is mututally exclusive with --get");
494503
o->jsonout = true;
495504
}
496505
else if(!strcmp("--verify", flag))
@@ -511,12 +520,12 @@ static int getarg(struct option *o,
511520
o->keep_port = true;
512521
else if(!strcmp("--punycode", flag)) {
513522
if(o->puny2idn)
514-
errorf(ERROR_FLAG, "--punycode is mutually exclusive with --as-idn");
523+
errorf(o, ERROR_FLAG, "--punycode is mutually exclusive with --as-idn");
515524
o->punycode = true;
516525
}
517526
else if(!strcmp("--as-idn", flag)) {
518527
if(o->punycode)
519-
errorf(ERROR_FLAG, "--as-idn is mutually exclusive with --punycode");
528+
errorf(o, ERROR_FLAG, "--as-idn is mutually exclusive with --punycode");
520529
o->puny2idn = true;
521530
}
522531
else if(!strcmp("--no-guess-scheme", flag))
@@ -670,13 +679,13 @@ static void get(struct option *o, CURLU *uh)
670679
mods |= VARMODIFIER_DEFAULT;
671680
else if(!strncmp(ptr, "puny:", cl - ptr + 1)) {
672681
if(mods & VARMODIFIER_PUNY2IDN)
673-
errorf(ERROR_GET,
682+
errorf(o, ERROR_GET,
674683
"puny modifier is mutually exclusive with idn");
675684
mods |= VARMODIFIER_PUNY;
676685
}
677686
else if(!strncmp(ptr, "idn:", cl - ptr + 1)) {
678687
if(mods & VARMODIFIER_PUNY)
679-
errorf(ERROR_GET,
688+
errorf(o, ERROR_GET,
680689
"idn modifier is mutually exclusive with puny");
681690
mods |= VARMODIFIER_PUNY2IDN;
682691
}
@@ -706,7 +715,7 @@ static void get(struct option *o, CURLU *uh)
706715
queryall);
707716
}
708717
else if(!vlen)
709-
errorf(ERROR_GET, "Bad --get syntax: %s", start);
718+
errorf(o, ERROR_GET, "Bad --get syntax: %s", start);
710719
else if(!strncmp(ptr, "url", vlen))
711720
showurl(stream, o, mods, uh);
712721
else {
@@ -777,7 +786,7 @@ static void get(struct option *o, CURLU *uh)
777786
}
778787

779788
static const struct var *setone(CURLU *uh, const char *setline,
780-
const struct option *o)
789+
struct option *o)
781790
{
782791
char *ptr = strchr(setline, '=');
783792
const struct var *v = NULL;
@@ -800,10 +809,11 @@ static const struct var *setone(CURLU *uh, const char *setline,
800809
found = true;
801810
}
802811
if(!found)
803-
errorf(ERROR_SET, "unknown component: %.*s", (int)vlen, setline);
812+
errorf(o, ERROR_SET,
813+
"unknown component: %.*s", (int)vlen, setline);
804814
}
805815
else
806-
errorf(ERROR_SET, "invalid --set syntax: %s", setline);
816+
errorf(o, ERROR_SET, "invalid --set syntax: %s", setline);
807817
return v;
808818
}
809819

@@ -818,7 +828,8 @@ static unsigned int set(CURLU *uh,
818828
v = setone(uh, setline, o);
819829
if(v) {
820830
if(mask & (1 << v->part))
821-
errorf(ERROR_SET, "duplicate --set for component %s", v->name);
831+
errorf(o, ERROR_SET,
832+
"duplicate --set for component %s", v->name);
822833
mask |= (1 << v->part);
823834
}
824835
}
@@ -934,7 +945,7 @@ static void trim(struct option *o)
934945
char *instr = node->data;
935946
if(strncmp(instr, "query", 5))
936947
/* for now we can only trim query components */
937-
errorf(ERROR_TRIM, "Unsupported trim component: %s", instr);
948+
errorf(o, ERROR_TRIM, "Unsupported trim component: %s", instr);
938949
char *ptr = strchr(instr, '=');
939950
if(ptr && (ptr > instr)) {
940951
/* 'ptr' should be a fixed string or a pattern ending with an
@@ -1193,7 +1204,7 @@ static void singleurl(struct option *o,
11931204
if(!uh) {
11941205
uh = curl_url();
11951206
if(!uh)
1196-
errorf(ERROR_MEM, "out of memory");
1207+
errorf(o, ERROR_MEM, "out of memory");
11971208
if(url) {
11981209
CURLUcode rc = seturl(o, uh, url);
11991210
if(rc) {
@@ -1235,7 +1246,7 @@ static void singleurl(struct option *o,
12351246
part = iter->data;
12361247
sep = strchr(part, '=');
12371248
if(!sep)
1238-
errorf(ERROR_ITER, "wrong iterate syntax");
1249+
errorf(o, ERROR_ITER, "wrong iterate syntax");
12391250
plen = sep - part;
12401251
if(sep[-1] == ':') {
12411252
urlencode = false;
@@ -1247,19 +1258,18 @@ static void singleurl(struct option *o,
12471258
iinfo->plen = plen;
12481259
v = comp2var(part, plen);
12491260
if(!v) {
1250-
trurl_cleanup_options(o);
12511261
curl_url_cleanup(uh);
1252-
errorf(ERROR_ITER, "bad component for iterate");
1262+
errorf(o, ERROR_ITER, "bad component for iterate");
12531263
}
12541264
if(iinfo->varmask & (1<<v->part)) {
1255-
trurl_cleanup_options(o);
12561265
curl_url_cleanup(uh);
1257-
errorf(ERROR_ITER, "duplicate component for iterate: %s", v->name);
1266+
errorf(o, ERROR_ITER,
1267+
"duplicate component for iterate: %s", v->name);
12581268
}
12591269
if(setmask & (1 << v->part)) {
1260-
trurl_cleanup_options(o);
12611270
curl_url_cleanup(uh);
1262-
errorf(ERROR_ITER, "duplicate --iterate and --set for component %s",
1271+
errorf(o, ERROR_ITER,
1272+
"duplicate --iterate and --set for component %s",
12631273
v->name);
12641274
}
12651275
}
@@ -1338,16 +1348,16 @@ static void singleurl(struct option *o,
13381348
char *ourl = NULL;
13391349
CURLUcode rc = curl_url_get(uh, CURLUPART_URL, &ourl, 0);
13401350
if(rc) {
1341-
if(o->verify) {
1351+
if(o->verify) /* only clean up if we're exiting */
13421352
curl_url_cleanup(uh);
1343-
trurl_cleanup_options(o);
1344-
}
13451353
VERIFY(o, ERROR_URL, "not enough input for a URL");
13461354
url_is_invalid = true;
13471355
}
13481356
else {
13491357
rc = seturl(o, uh, ourl);
13501358
if(rc) {
1359+
if(o->verify) /* only clean up if we're exiting */
1360+
curl_url_cleanup(uh);
13511361
VERIFY(o, ERROR_BADURL, "%s [%s]", curl_url_strerror(rc),
13521362
ourl);
13531363
url_is_invalid = true;
@@ -1358,6 +1368,8 @@ static void singleurl(struct option *o,
13581368
if(!rc)
13591369
curl_free(nurl);
13601370
else {
1371+
if(o->verify) /* only clean up if we're exiting */
1372+
curl_url_cleanup(uh);
13611373
VERIFY(o, ERROR_BADURL, "url became invalid");
13621374
url_is_invalid = true;
13631375
}
@@ -1411,7 +1423,7 @@ int main(int argc, const char **argv)
14111423
if(!o.end_of_options && argv[0][0] == '-') {
14121424
/* dash-dash prefixed */
14131425
if(getarg(&o, argv[0], argv[1], &usedarg))
1414-
errorf(ERROR_FLAG, "unknown option: %s", argv[0]);
1426+
errorf(&o, ERROR_FLAG, "unknown option: %s", argv[0]);
14151427
}
14161428
else {
14171429
/* this is a URL */

0 commit comments

Comments
 (0)