1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
#include "Cli/Cli.h"
#include "Logger/Logger.h"
#include "Version/Version.h"
#include <getopt.h>
#include <stdio.h>
void cli_print_usage(const char *program_name) {
fprintf(
stderr,
"Usage:\n"
" %s FILE [-o OUTPUT]\n"
" %s -d DIRECTORY [-o OUTPUT] [-f]\n\n"
"Options:\n"
" -d, --directory DIRECTORY Process a directory recursively\n"
" -o, --output OUTPUT Set the output path\n"
" -f, --overwrite Overwrite an existing output directory\n"
" -l, --log-level LEVEL error, warning, info, debug, or silent\n"
" -v, --version Show the program version\n"
" -h, --help Show this help\n",
program_name, program_name);
}
static void cli_print_version(void) { printf("yapssg %s\n", yapssg_version); }
static const char *strip_optional_equals(const char *value) {
return value != NULL && value[0] == '=' ? value + 1 : value;
}
CliParseResult cli_parse(int argc, char **argv, CliOptions *options) {
static const struct option long_options[] = {
{"directory", required_argument, NULL, 'd'},
{"output", required_argument, NULL, 'o'},
{"overwrite", no_argument, NULL, 'f'},
{"force", no_argument, NULL, 'f'},
{"log-level", required_argument, NULL, 'l'},
{"version", no_argument, NULL, 'v'},
{"help", no_argument, NULL, 'h'},
{NULL, 0, NULL, 0}};
const char *directory = NULL;
int option;
options->input_type = INPUT_TYPE_NONE;
options->input_path = NULL;
options->output_path = NULL;
options->overwrite_output = 0;
options->log_level = LOG_LEVEL_INFO;
while ((option = getopt_long(argc, argv, "d:o:fl:vh", long_options, NULL)) !=
-1) {
switch (option) {
case 'd':
directory = strip_optional_equals(optarg);
break;
case 'o':
options->output_path = strip_optional_equals(optarg);
break;
case 'f':
options->overwrite_output = 1;
break;
case 'l':
if (logger_parse_level(optarg, &options->log_level) != 0) {
logger_error("unknown log level '%s'", optarg);
return CLI_PARSE_ERROR;
}
break;
case 'v':
cli_print_version();
return CLI_PARSE_VERSION;
case 'h':
cli_print_usage(argv[0]);
return CLI_PARSE_HELP;
default:
cli_print_usage(argv[0]);
return CLI_PARSE_ERROR;
}
}
if (directory != NULL) {
if (optind != argc || directory[0] == '\0') {
logger_error("a directory cannot be combined with a file");
return CLI_PARSE_ERROR;
}
options->input_type = INPUT_TYPE_DIRECTORY;
options->input_path = directory;
} else {
if (optind + 1 != argc) {
cli_print_usage(argv[0]);
return CLI_PARSE_ERROR;
}
options->input_type = INPUT_TYPE_FILE;
options->input_path = argv[optind];
}
if (options->output_path != NULL && options->output_path[0] == '\0') {
logger_error("output path cannot be empty");
return CLI_PARSE_ERROR;
}
return CLI_PARSE_OK;
}
|