Skip to content

Commit 2caa3ed

Browse files
committed
Improve CLI niceness:
- Print help etc. to stdout unless in error state - Print usage if no args given
1 parent 5951a0c commit 2caa3ed

File tree

1 file changed

+67
-66
lines changed

1 file changed

+67
-66
lines changed

src/main.c

Lines changed: 67 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -28,70 +28,70 @@
2828
#include <getopt.h>
2929

3030
static void
31-
print_version(void)
31+
print_version(FILE *stream)
3232
{
33-
fprintf(stderr, "AXE Version %s\n", AXE_VERSION);
33+
fprintf(stream, "AXE Version %s\n", AXE_VERSION);
3434
}
3535

3636
static void
37-
print_help(void)
37+
print_help(FILE *stream)
3838
{
39-
fprintf(stderr, "All mandatory short options are mandatory in their\n");
40-
fprintf(stderr, "long option form. Likewise, all short options that take\n");
41-
fprintf(stderr, "an argument must be given an argument in their long form\n");
42-
fprintf(stderr, "\n");
43-
fprintf(stderr, "If a forward read input is given, a forward read output\n");
44-
fprintf(stderr, "must be. Likewise for a reverse/interleaved input. If either\n");
45-
fprintf(stderr, "forward and/or reverse reads are given, interleaved input\n");
46-
fprintf(stderr, "cannot be. However, one can input interleaved paired reads\n");
47-
fprintf(stderr, "and output separate forwards and reverse reads, and vice versa.\n");
48-
fprintf(stderr, "\n");
49-
fprintf(stderr, "The barcode file is a tab-separated tabular file with an\n");
50-
fprintf(stderr, "optional header, and has two alternative formats. The standard\n");
51-
fprintf(stderr, "form (see below) is expected unless --combinatorial is given.\n");
52-
fprintf(stderr, "\n");
53-
fprintf(stderr, "The standard format is:\n");
54-
fprintf(stderr, "Barcode\tID\n");
55-
fprintf(stderr, "ACTA\tA1\n");
56-
fprintf(stderr, "CCTC\tA2\n");
57-
fprintf(stderr, "...\n");
58-
fprintf(stderr, "\n");
59-
fprintf(stderr, "The combinatorial format is:\n");
60-
fprintf(stderr, "Barcode1\tBarcode2\tID\n");
61-
fprintf(stderr, "ACTA\tACGC\tA1\n");
62-
fprintf(stderr, "CCTC\tTCTA\tA2\n");
63-
fprintf(stderr, "...\n");
64-
fprintf(stderr, "\n");
39+
fprintf(stream, "All mandatory short options are mandatory in their\n");
40+
fprintf(stream, "long option form. Likewise, all short options that take\n");
41+
fprintf(stream, "an argument must be given an argument in their long form\n");
42+
fprintf(stream, "\n");
43+
fprintf(stream, "If a forward read input is given, a forward read output\n");
44+
fprintf(stream, "must be. Likewise for a reverse/interleaved input. If either\n");
45+
fprintf(stream, "forward and/or reverse reads are given, interleaved input\n");
46+
fprintf(stream, "cannot be. However, one can input interleaved paired reads\n");
47+
fprintf(stream, "and output separate forwards and reverse reads, and vice versa.\n");
48+
fprintf(stream, "\n");
49+
fprintf(stream, "The barcode file is a tab-separated tabular file with an\n");
50+
fprintf(stream, "optional header, and has two alternative formats. The standard\n");
51+
fprintf(stream, "form (see below) is expected unless --combinatorial is given.\n");
52+
fprintf(stream, "\n");
53+
fprintf(stream, "The standard format is:\n");
54+
fprintf(stream, "Barcode\tID\n");
55+
fprintf(stream, "ACTA\tA1\n");
56+
fprintf(stream, "CCTC\tA2\n");
57+
fprintf(stream, "...\n");
58+
fprintf(stream, "\n");
59+
fprintf(stream, "The combinatorial format is:\n");
60+
fprintf(stream, "Barcode1\tBarcode2\tID\n");
61+
fprintf(stream, "ACTA\tACGC\tA1\n");
62+
fprintf(stream, "CCTC\tTCTA\tA2\n");
63+
fprintf(stream, "...\n");
64+
fprintf(stream, "\n");
6565
}
6666

6767
static void
68-
print_usage(void)
68+
print_usage(FILE *stream)
6969
{
70-
print_version();
71-
fprintf(stderr, "\nUSAGE:\n");
72-
fprintf(stderr, "axe-demux [-mzc2pt] -b (-f [-r] | -i) (-F [-R] | -I)\n");
73-
fprintf(stderr, "axe-demux -h\n");
74-
fprintf(stderr, "axe-demux -v\n\n");
75-
fprintf(stderr, "OPTIONS:\n");
76-
fprintf(stderr, " -m, --mismatch\tMaximum hamming distance mismatch. [int, default 1]\n");
77-
fprintf(stderr, " -z, --ziplevel\tGzip compression level, or 0 for plain text [int, default 0]\n");
78-
fprintf(stderr, " -c, --combinatorial\tUse combinatorial barcode matching. [flag, default OFF]\n");
79-
fprintf(stderr, " -p, --permissive\tDon't error on barcode mismatch confict, matching only\n");
80-
fprintf(stderr, " \texactly for conficting barcodes. [flag, default OFF]\n");
81-
fprintf(stderr, " -2, --trim-r2\tTrim barcode from R2 read as well as R1. [flag, default OFF]\n");
82-
fprintf(stderr, " -b, --barcodes\tBarcode file. See --help for example. [file]\n");
83-
fprintf(stderr, " -f, --fwd-in\tInput forward read. [file]\n");
84-
fprintf(stderr, " -F, --fwd-out\tOutput forward read prefix. [file]\n");
85-
fprintf(stderr, " -r, --rev-in\tInput reverse read. [file]\n");
86-
fprintf(stderr, " -R, --rev-out\tOutput reverse read prefix. [file]\n");
87-
fprintf(stderr, " -i, --ilfq-in\tInput interleaved paired reads. [file]\n");
88-
fprintf(stderr, " -I, --ilfq-out\tOutput interleaved paired reads prefix. [file]\n");
89-
fprintf(stderr, " -t, --table-file\tOutput a summary table of demultiplexing statistics to file. [file]\n");
90-
fprintf(stderr, " -h, --help\t\tPrint this usage plus additional help.\n");
91-
fprintf(stderr, " -V, --version\tPrint version string.\n");
92-
fprintf(stderr, " -v, --verbose\tBe more verbose. Additive, -vv is more vebose than -v.\n");
93-
fprintf(stderr, " -q, --quiet\t\tBe very quiet.\n");
94-
fprintf(stderr, "\n");
70+
print_version(stream);
71+
fprintf(stream, "\nUSAGE:\n");
72+
fprintf(stream, "axe-demux [-mzc2pt] -b (-f [-r] | -i) (-F [-R] | -I)\n");
73+
fprintf(stream, "axe-demux -h\n");
74+
fprintf(stream, "axe-demux -v\n\n");
75+
fprintf(stream, "OPTIONS:\n");
76+
fprintf(stream, " -m, --mismatch\tMaximum hamming distance mismatch. [int, default 1]\n");
77+
fprintf(stream, " -z, --ziplevel\tGzip compression level, or 0 for plain text [int, default 0]\n");
78+
fprintf(stream, " -c, --combinatorial\tUse combinatorial barcode matching. [flag, default OFF]\n");
79+
fprintf(stream, " -p, --permissive\tDon't error on barcode mismatch confict, matching only\n");
80+
fprintf(stream, " \texactly for conficting barcodes. [flag, default OFF]\n");
81+
fprintf(stream, " -2, --trim-r2\tTrim barcode from R2 read as well as R1. [flag, default OFF]\n");
82+
fprintf(stream, " -b, --barcodes\tBarcode file. See --help for example. [file]\n");
83+
fprintf(stream, " -f, --fwd-in\tInput forward read. [file]\n");
84+
fprintf(stream, " -F, --fwd-out\tOutput forward read prefix. [file]\n");
85+
fprintf(stream, " -r, --rev-in\tInput reverse read. [file]\n");
86+
fprintf(stream, " -R, --rev-out\tOutput reverse read prefix. [file]\n");
87+
fprintf(stream, " -i, --ilfq-in\tInput interleaved paired reads. [file]\n");
88+
fprintf(stream, " -I, --ilfq-out\tOutput interleaved paired reads prefix. [file]\n");
89+
fprintf(stream, " -t, --table-file\tOutput a summary table of demultiplexing statistics to file. [file]\n");
90+
fprintf(stream, " -h, --help\t\tPrint this usage plus additional help.\n");
91+
fprintf(stream, " -V, --version\tPrint version string.\n");
92+
fprintf(stream, " -v, --verbose\tBe more verbose. Additive, -vv is more vebose than -v.\n");
93+
fprintf(stream, " -q, --quiet\t\tBe very quiet.\n");
94+
fprintf(stream, "\n");
9595
}
9696

9797
static const char *axe_opts = "m:z:c2pb:f:F:r:R:i:I:t:hVvqd";
@@ -121,11 +121,12 @@ parse_args(struct axe_config *config, int argc, char * const *argv)
121121
{
122122
int c = 0;
123123
int optind = 0;
124+
bool fullhelp = false;
124125

125126
if (argc < 2 ) {
126-
return 1;
127+
goto printhelp;
127128
}
128-
if (!axe_config_ok(config) || argc < 1 || argv == NULL) {
129+
if (!axe_config_ok(config) || argv == NULL) {
129130
goto error;
130131
}
131132
/* Set some sane defaults */
@@ -193,7 +194,8 @@ parse_args(struct axe_config *config, int argc, char * const *argv)
193194
config->table_file = strdup(optarg);
194195
break;
195196
case 'h':
196-
goto help;
197+
fullhelp = true;
198+
goto printhelp;
197199
case 'V':
198200
goto version;
199201
case 'v':
@@ -339,11 +341,13 @@ parse_args(struct axe_config *config, int argc, char * const *argv)
339341
"Axe failed due to bad CLI flags. Consult the usage below please!\n\n");
340342
config->have_cli_opts = false;
341343
return 1;
342-
help:
343-
config->have_cli_opts = false;
344-
return 2;
344+
printhelp:
345+
print_usage(stdout);
346+
if (fullhelp) print_help(stdout);
347+
axe_config_destroy(config);
348+
exit(0);
345349
version:
346-
print_version();
350+
print_version(stdout);
347351
axe_config_destroy(config);
348352
exit(0);
349353
}
@@ -360,10 +364,7 @@ main (int argc, char * const *argv)
360364
}
361365
ret = parse_args(config, argc, argv);
362366
if (ret != 0) {
363-
print_usage();
364-
if (ret == 2) {
365-
print_help();
366-
}
367+
print_usage(stderr);
367368
goto end;
368369
}
369370
ret = axe_read_barcodes(config);

0 commit comments

Comments
 (0)