diff options
author | Rutger Broekhoff | 2024-05-02 20:27:40 +0200 |
---|---|---|
committer | Rutger Broekhoff | 2024-05-02 20:27:40 +0200 |
commit | 17a3ea880402338420699e03bcb24181e4ff3924 (patch) | |
tree | da666ef91e0b60d20aa0b01529644c136fd1f4ab /src/querykv1/cliopts.cpp | |
download | oeuf-17a3ea880402338420699e03bcb24181e4ff3924.tar.gz oeuf-17a3ea880402338420699e03bcb24181e4ff3924.zip |
Initial commit
Based on dc4ba6a
Diffstat (limited to 'src/querykv1/cliopts.cpp')
-rw-r--r-- | src/querykv1/cliopts.cpp | 456 |
1 files changed, 456 insertions, 0 deletions
diff --git a/src/querykv1/cliopts.cpp b/src/querykv1/cliopts.cpp new file mode 100644 index 0000000..bef7a98 --- /dev/null +++ b/src/querykv1/cliopts.cpp | |||
@@ -0,0 +1,456 @@ | |||
1 | // vim:set sw=2 ts=2 sts et: | ||
2 | |||
3 | #include <cstdlib> | ||
4 | #include <cstdio> | ||
5 | #include <string> | ||
6 | #include <string_view> | ||
7 | |||
8 | #include <getopt.h> | ||
9 | |||
10 | #include "cliopts.hpp" | ||
11 | |||
12 | using namespace std::string_view_literals; | ||
13 | |||
14 | const char *opt_set = ""; | ||
15 | const char *opt_unset = nullptr; | ||
16 | |||
17 | const char help[] = R"(Usage: %1$s [OPTIONS] <COMMAND> | ||
18 | |||
19 | Global Options: | ||
20 | --kv1 <PATH> Path to file containing all KV1 data, '-' for stdin | ||
21 | -h, --help Print this help | ||
22 | |||
23 | Commands: | ||
24 | joparoute Generate CSV for journey pattern route | ||
25 | journeyinfo Print some information on a journey | ||
26 | journeyroute Generate CSV for journey route | ||
27 | journeys List journeys of a specific line going from stop A to B | ||
28 | schedule Generate schedule | ||
29 | )"; | ||
30 | |||
31 | const char joparoute_help[] = R"(Usage: %1$s joparoute --line <NUMBER> --jopa <CODE> [OPTIONS] | ||
32 | |||
33 | Options: | ||
34 | --line <NUMBER> Line planning number as in schedule | ||
35 | --jopa <CODE> Journey pattern code as in KV1 data | ||
36 | -o <PATH> Path of file to write to, '-' for stdout | ||
37 | |||
38 | Global Options: | ||
39 | --kv1 <PATH> Path to file containing all KV1 data, '-' for stdin | ||
40 | -h, --help Print this help | ||
41 | )"; | ||
42 | |||
43 | const char journeyroute_help[] = R"(Usage: %1$s journeyroute --line <NUMBER> [OPTIONS] | ||
44 | |||
45 | Options: | ||
46 | --line <NUMBER> Line planning number as in KV1 data | ||
47 | --journey <NUMBER> Journey number as in KV1 data | ||
48 | -o <PATH> Path of file to write to, '-' for stdout | ||
49 | |||
50 | Global Options: | ||
51 | --kv1 <PATH> Path to file containing all KV1 data, '-' for stdin | ||
52 | -h, --help Print this help | ||
53 | )"; | ||
54 | |||
55 | const char journeys_help[] = R"(Usage: %1$s journeys --line <NUMBER> --begin <STOP> --end <STOP> [OPTIONS] | ||
56 | |||
57 | For the --begin and --end arguments, use the following format: | ||
58 | --begin/--end stop:<USRSTOP CODE> | ||
59 | --begin/--end star:<USRSTAR CODE> | ||
60 | |||
61 | Options: | ||
62 | --begin <STOP> User stop code/area of stop the journey should begin at | ||
63 | --end <STOP> User stop code/area of stop the journey should end at | ||
64 | --line <NUMBER> Line planning number to filter on | ||
65 | -o <PATH> Path of file to write to, '-' for stdout | ||
66 | |||
67 | Global Options: | ||
68 | --kv1 <PATH> Path to file containing all KV1 data, '-' for stdin | ||
69 | -h, --help Print this help | ||
70 | )"; | ||
71 | |||
72 | const char journeyinfo_help[] = R"(Usage: %1$s journeyinfo --line <NUMBER> --journey <NUMBER> [OPTIONS] | ||
73 | |||
74 | Options: | ||
75 | --line <NUMBER> Line planning number to filter on | ||
76 | --journey <NUMBER> Journey number as in schedule | ||
77 | |||
78 | Global Options: | ||
79 | --kv1 <PATH> Path to file containing all KV1 data, '-' for stdin | ||
80 | -h, --help Print this help | ||
81 | )"; | ||
82 | |||
83 | const char schedule_help[] = R"(Usage: %1$s schedule --line <NUMBER> [OPTIONS] | ||
84 | |||
85 | Options: | ||
86 | --line <NUMBER> Line planning number to generate schedule for | ||
87 | -o <PATH> Path of file to write to, '-' for stdout | ||
88 | |||
89 | Global Options: | ||
90 | --kv1 <PATH> Path to file containing all KV1 data, '-' for stdin | ||
91 | -h, --help Print this help | ||
92 | )"; | ||
93 | |||
94 | void journeyRouteValidateOptions(const char *progname, Options *options) { | ||
95 | #define X(name, argument, long_, short_) \ | ||
96 | if (#name != "kv1_file_path"sv && #name != "line_planning_number"sv \ | ||
97 | && #name != "journey_number"sv && #name != "help"sv && #name != "output_file_path"sv) \ | ||
98 | if (options->name) { \ | ||
99 | if (long_) { \ | ||
100 | if (short_) fprintf(stderr, "%s: unexpected flag --%s (-%c) for journeyroute subcommand\n\n", progname, static_cast<const char *>(long_), short_); \ | ||
101 | else fprintf(stderr, "%s: unexpected flag --%s for journeyroute subcommand\n\n", progname, static_cast<const char *>(long_)); \ | ||
102 | } else if (short_) fprintf(stderr, "%s: unexpected flag -%c for journeyroute subcommand\n\n", progname, short_); \ | ||
103 | fprintf(stderr, journeyroute_help, progname); \ | ||
104 | exit(1); \ | ||
105 | } | ||
106 | LONG_OPTIONS | ||
107 | SHORT_OPTIONS | ||
108 | #undef X | ||
109 | |||
110 | if (options->positional.size() > 0) { | ||
111 | fprintf(stderr, "%s: unexpected positional argument(s) for journeyroute subcommand\n\n", progname); | ||
112 | for (auto pos : options->positional) fprintf(stderr, "opt: %s\n", pos); | ||
113 | fprintf(stderr, journeyroute_help, progname); | ||
114 | exit(1); | ||
115 | } | ||
116 | |||
117 | if (!options->kv1_file_path) | ||
118 | options->kv1_file_path = "-"; | ||
119 | if (!options->output_file_path) | ||
120 | options->output_file_path = "-"; | ||
121 | if (options->kv1_file_path == ""sv) { | ||
122 | fprintf(stderr, "%s: KV1 file path cannot be empty\n\n", progname); | ||
123 | fprintf(stderr, journeyroute_help, progname); | ||
124 | exit(1); | ||
125 | } | ||
126 | if (options->output_file_path == ""sv) { | ||
127 | fprintf(stderr, "%s: output file path cannot be empty\n\n", progname); | ||
128 | fprintf(stderr, journeyroute_help, progname); | ||
129 | exit(1); | ||
130 | } | ||
131 | if (!options->journey_number || options->journey_number == ""sv) { | ||
132 | fprintf(stderr, "%s: journey number must be provided\n\n", progname); | ||
133 | fprintf(stderr, journeyroute_help, progname); | ||
134 | exit(1); | ||
135 | } | ||
136 | if (!options->line_planning_number || options->line_planning_number == ""sv) { | ||
137 | fprintf(stderr, "%s: line planning number must be provided\n\n", progname); | ||
138 | fprintf(stderr, journeyroute_help, progname); | ||
139 | exit(1); | ||
140 | } | ||
141 | } | ||
142 | |||
143 | void scheduleValidateOptions(const char *progname, Options *options) { | ||
144 | #define X(name, argument, long_, short_) \ | ||
145 | if (#name != "kv1_file_path"sv && #name != "help"sv \ | ||
146 | && #name != "line_planning_number"sv && #name != "output_file_path"sv) \ | ||
147 | if (options->name) { \ | ||
148 | if (long_) { \ | ||
149 | if (short_) fprintf(stderr, "%s: unexpected flag --%s (-%c) for schedule subcommand\n\n", progname, static_cast<const char *>(long_), short_); \ | ||
150 | else fprintf(stderr, "%s: unexpected flag --%s for schedule subcommand\n\n", progname, static_cast<const char *>(long_)); \ | ||
151 | } else if (short_) fprintf(stderr, "%s: unexpected flag -%c for schedule subcommand\n\n", progname, short_); \ | ||
152 | fprintf(stderr, schedule_help, progname); \ | ||
153 | exit(1); \ | ||
154 | } | ||
155 | LONG_OPTIONS | ||
156 | SHORT_OPTIONS | ||
157 | #undef X | ||
158 | |||
159 | if (options->positional.size() > 0) { | ||
160 | fprintf(stderr, "%s: unexpected positional argument(s) for schedule subcommand\n\n", progname); | ||
161 | for (auto pos : options->positional) fprintf(stderr, "opt: %s\n", pos); | ||
162 | fprintf(stderr, schedule_help, progname); | ||
163 | exit(1); | ||
164 | } | ||
165 | |||
166 | if (!options->kv1_file_path) | ||
167 | options->kv1_file_path = "-"; | ||
168 | if (!options->output_file_path) | ||
169 | options->output_file_path = "-"; | ||
170 | if (options->kv1_file_path == ""sv) { | ||
171 | fprintf(stderr, "%s: KV1 file path cannot be empty\n\n", progname); | ||
172 | fprintf(stderr, schedule_help, progname); | ||
173 | exit(1); | ||
174 | } | ||
175 | if (options->output_file_path == ""sv) { | ||
176 | fprintf(stderr, "%s: output file path cannot be empty\n\n", progname); | ||
177 | fprintf(stderr, schedule_help, progname); | ||
178 | exit(1); | ||
179 | } | ||
180 | if (!options->line_planning_number || options->line_planning_number == ""sv) { | ||
181 | fprintf(stderr, "%s: line planning number must be provided\n\n", progname); | ||
182 | fprintf(stderr, schedule_help, progname); | ||
183 | exit(1); | ||
184 | } | ||
185 | } | ||
186 | |||
187 | void journeysValidateOptions(const char *progname, Options *options) { | ||
188 | #define X(name, argument, long_, short_) \ | ||
189 | if (#name != "kv1_file_path"sv && #name != "help"sv \ | ||
190 | && #name != "line_planning_number"sv && #name != "output_file_path"sv \ | ||
191 | && #name != "begin_stop_code"sv && #name != "end_stop_code"sv) \ | ||
192 | if (options->name) { \ | ||
193 | if (long_) { \ | ||
194 | if (short_) fprintf(stderr, "%s: unexpected flag --%s (-%c) for journeys subcommand\n\n", progname, static_cast<const char *>(long_), short_); \ | ||
195 | else fprintf(stderr, "%s: unexpected flag --%s for journeys subcommand\n\n", progname, static_cast<const char *>(long_)); \ | ||
196 | } else if (short_) fprintf(stderr, "%s: unexpected flag -%c for journeys subcommand\n\n", progname, short_); \ | ||
197 | fprintf(stderr, journeys_help, progname); \ | ||
198 | exit(1); \ | ||
199 | } | ||
200 | LONG_OPTIONS | ||
201 | SHORT_OPTIONS | ||
202 | #undef X | ||
203 | |||
204 | if (options->positional.size() > 0) { | ||
205 | fprintf(stderr, "%s: unexpected positional argument(s) for journeys subcommand\n\n", progname); | ||
206 | for (auto pos : options->positional) fprintf(stderr, "opt: %s\n", pos); | ||
207 | fprintf(stderr, journeys_help, progname); | ||
208 | exit(1); | ||
209 | } | ||
210 | |||
211 | if (!options->kv1_file_path) | ||
212 | options->kv1_file_path = "-"; | ||
213 | if (!options->output_file_path) | ||
214 | options->output_file_path = "-"; | ||
215 | if (options->kv1_file_path == ""sv) { | ||
216 | fprintf(stderr, "%s: KV1 file path cannot be empty\n\n", progname); | ||
217 | fprintf(stderr, journeys_help, progname); | ||
218 | exit(1); | ||
219 | } | ||
220 | if (options->output_file_path == ""sv) { | ||
221 | fprintf(stderr, "%s: output file path cannot be empty\n\n", progname); | ||
222 | fprintf(stderr, journeys_help, progname); | ||
223 | exit(1); | ||
224 | } | ||
225 | if (!options->line_planning_number || options->line_planning_number == ""sv) { | ||
226 | fprintf(stderr, "%s: line planning number must be provided\n\n", progname); | ||
227 | fprintf(stderr, journeys_help, progname); | ||
228 | exit(1); | ||
229 | } | ||
230 | if (!options->begin_stop_code || options->begin_stop_code == ""sv) { | ||
231 | fprintf(stderr, "%s: start user stop code must be provided\n\n", progname); | ||
232 | fprintf(stderr, journeys_help, progname); | ||
233 | exit(1); | ||
234 | } | ||
235 | if (!options->end_stop_code || options->end_stop_code == ""sv) { | ||
236 | fprintf(stderr, "%s: end user stop code must be provided\n\n", progname); | ||
237 | fprintf(stderr, journeys_help, progname); | ||
238 | exit(1); | ||
239 | } | ||
240 | if (!std::string_view(options->begin_stop_code).starts_with("star:") | ||
241 | && !std::string_view(options->begin_stop_code).starts_with("stop:")) { | ||
242 | fprintf(stderr, "%s: begin user stop code must be prefixed with star:/stop:\n\n", progname); | ||
243 | fprintf(stderr, journeys_help, progname); | ||
244 | exit(1); | ||
245 | } | ||
246 | if (!std::string_view(options->end_stop_code).starts_with("star:") | ||
247 | && !std::string_view(options->end_stop_code).starts_with("stop:")) { | ||
248 | fprintf(stderr, "%s: end user stop code must be prefixed with star:/stop:\n\n", progname); | ||
249 | fprintf(stderr, journeys_help, progname); | ||
250 | exit(1); | ||
251 | } | ||
252 | } | ||
253 | |||
254 | void journeyInfoValidateOptions(const char *progname, Options *options) { | ||
255 | #define X(name, argument, long_, short_) \ | ||
256 | if (#name != "kv1_file_path"sv && #name != "line_planning_number"sv \ | ||
257 | && #name != "journey_number"sv && #name != "help"sv) \ | ||
258 | if (options->name) { \ | ||
259 | if (long_) { \ | ||
260 | if (short_) fprintf(stderr, "%s: unexpected flag --%s (-%c) for journeyinfo subcommand\n\n", progname, static_cast<const char *>(long_), short_); \ | ||
261 | else fprintf(stderr, "%s: unexpected flag --%s for journeyinfo subcommand\n\n", progname, static_cast<const char *>(long_)); \ | ||
262 | } else if (short_) fprintf(stderr, "%s: unexpected flag -%c for journeyinfo subcommand\n\n", progname, short_); \ | ||
263 | fprintf(stderr, journeyinfo_help, progname); \ | ||
264 | exit(1); \ | ||
265 | } | ||
266 | LONG_OPTIONS | ||
267 | SHORT_OPTIONS | ||
268 | #undef X | ||
269 | |||
270 | if (options->positional.size() > 0) { | ||
271 | fprintf(stderr, "%s: unexpected positional argument(s) for journeyinfo subcommand\n\n", progname); | ||
272 | for (auto pos : options->positional) fprintf(stderr, "opt: %s\n", pos); | ||
273 | fprintf(stderr, journeyinfo_help, progname); | ||
274 | exit(1); | ||
275 | } | ||
276 | |||
277 | if (!options->kv1_file_path) | ||
278 | options->kv1_file_path = "-"; | ||
279 | if (options->kv1_file_path == ""sv) { | ||
280 | fprintf(stderr, "%s: KV1 file path cannot be empty\n\n", progname); | ||
281 | fprintf(stderr, journeyinfo_help, progname); | ||
282 | exit(1); | ||
283 | } | ||
284 | if (!options->journey_number || options->journey_number == ""sv) { | ||
285 | fprintf(stderr, "%s: journey number must be provided\n\n", progname); | ||
286 | fprintf(stderr, journeyinfo_help, progname); | ||
287 | exit(1); | ||
288 | } | ||
289 | if (!options->line_planning_number || options->line_planning_number == ""sv) { | ||
290 | fprintf(stderr, "%s: line planning number must be provided\n\n", progname); | ||
291 | fprintf(stderr, journeyinfo_help, progname); | ||
292 | exit(1); | ||
293 | } | ||
294 | } | ||
295 | |||
296 | void jopaRouteValidateOptions(const char *progname, Options *options) { | ||
297 | #define X(name, argument, long_, short_) \ | ||
298 | if (#name != "kv1_file_path"sv && #name != "line_planning_number"sv \ | ||
299 | && #name != "journey_pattern_code"sv && #name != "help"sv && #name != "output_file_path"sv) \ | ||
300 | if (options->name) { \ | ||
301 | if (long_) { \ | ||
302 | if (short_) fprintf(stderr, "%s: unexpected flag --%s (-%c) for joparoute subcommand\n\n", progname, static_cast<const char *>(long_), short_); \ | ||
303 | else fprintf(stderr, "%s: unexpected flag --%s for joparoute subcommand\n\n", progname, static_cast<const char *>(long_)); \ | ||
304 | } else if (short_) fprintf(stderr, "%s: unexpected flag -%c for joparoute subcommand\n\n", progname, short_); \ | ||
305 | fprintf(stderr, joparoute_help, progname); \ | ||
306 | exit(1); \ | ||
307 | } | ||
308 | LONG_OPTIONS | ||
309 | SHORT_OPTIONS | ||
310 | #undef X | ||
311 | |||
312 | if (options->positional.size() > 0) { | ||
313 | fprintf(stderr, "%s: unexpected positional argument(s) for joparoute subcommand\n\n", progname); | ||
314 | for (auto pos : options->positional) fprintf(stderr, "opt: %s\n", pos); | ||
315 | fprintf(stderr, joparoute_help, progname); | ||
316 | exit(1); | ||
317 | } | ||
318 | |||
319 | if (!options->kv1_file_path) | ||
320 | options->kv1_file_path = "-"; | ||
321 | if (!options->output_file_path) | ||
322 | options->output_file_path = "-"; | ||
323 | if (options->kv1_file_path == ""sv) { | ||
324 | fprintf(stderr, "%s: KV1 file path cannot be empty\n\n", progname); | ||
325 | fprintf(stderr, joparoute_help, progname); | ||
326 | exit(1); | ||
327 | } | ||
328 | if (options->output_file_path == ""sv) { | ||
329 | fprintf(stderr, "%s: output file path cannot be empty\n\n", progname); | ||
330 | fprintf(stderr, joparoute_help, progname); | ||
331 | exit(1); | ||
332 | } | ||
333 | if (!options->journey_pattern_code || options->journey_pattern_code == ""sv) { | ||
334 | fprintf(stderr, "%s: journey pattern code must be provided\n\n", progname); | ||
335 | fprintf(stderr, joparoute_help, progname); | ||
336 | exit(1); | ||
337 | } | ||
338 | if (!options->line_planning_number || options->line_planning_number == ""sv) { | ||
339 | fprintf(stderr, "%s: line planning number must be provided\n\n", progname); | ||
340 | fprintf(stderr, joparoute_help, progname); | ||
341 | exit(1); | ||
342 | } | ||
343 | } | ||
344 | |||
345 | struct ShortFlag { | ||
346 | int has_arg; | ||
347 | int c; | ||
348 | }; | ||
349 | |||
350 | template<ShortFlag ...flags> | ||
351 | const std::string mkargarr = | ||
352 | (std::string() | ||
353 | + ... | ||
354 | + (flags.c == 0 | ||
355 | ? "" | ||
356 | : std::string((const char[]){ flags.c, '\0' }) | ||
357 | + (flags.has_arg == required_argument | ||
358 | ? ":" | ||
359 | : flags.has_arg == optional_argument | ||
360 | ? "::" | ||
361 | : ""))); | ||
362 | |||
363 | #define X(name, has_arg, long_, short_) ShortFlag(has_arg, short_), | ||
364 | const std::string argarr = mkargarr<SHORT_OPTIONS LONG_OPTIONS ShortFlag(no_argument, 0)>; | ||
365 | #undef X | ||
366 | |||
367 | Options parseOptions(int argc, char *argv[]) { | ||
368 | const char *progname = argv[0]; | ||
369 | |||
370 | // Struct with options for augmentkv6. | ||
371 | Options options; | ||
372 | |||
373 | static option long_options[] = { | ||
374 | #define X(name, argument, long_, short_) { long_, argument, nullptr, short_ }, | ||
375 | LONG_OPTIONS | ||
376 | #undef X | ||
377 | { 0 }, | ||
378 | }; | ||
379 | |||
380 | int c; | ||
381 | int option_index = 0; | ||
382 | bool error = false; | ||
383 | while ((c = getopt_long(argc, argv, argarr.c_str(), long_options, &option_index)) != -1) { | ||
384 | // If a long option was used, c corresponds with val. We have val = 0 for | ||
385 | // options which have no short alternative, so checking for c = 0 gives us | ||
386 | // whether a long option with no short alternative was used. | ||
387 | // Below, we check for c = 'h', which corresponds with the long option | ||
388 | // '--help', for which val = 'h'. | ||
389 | if (c == 0) { | ||
390 | const char *name = long_options[option_index].name; | ||
391 | #define X(opt_name, opt_has_arg, opt_long, opt_short) \ | ||
392 | if (name == opt_long ## sv) { options.opt_name = optarg; continue; } | ||
393 | LONG_OPTIONS | ||
394 | #undef X | ||
395 | error = true; | ||
396 | } | ||
397 | #define X(opt_name, opt_has_arg, opt_long, opt_short) \ | ||
398 | if (c == opt_short) { options.opt_name = optarg ? optarg : opt_set; continue; } | ||
399 | LONG_OPTIONS | ||
400 | SHORT_OPTIONS | ||
401 | #undef X | ||
402 | error = true; | ||
403 | } | ||
404 | |||
405 | if (optind < argc) | ||
406 | options.subcommand = argv[optind++]; | ||
407 | while (optind < argc) | ||
408 | options.positional.push_back(argv[optind++]); | ||
409 | |||
410 | if (options.subcommand | ||
411 | && options.subcommand != "schedule"sv | ||
412 | && options.subcommand != "joparoute"sv | ||
413 | && options.subcommand != "journeyinfo"sv | ||
414 | && options.subcommand != "journeyroute"sv | ||
415 | && options.subcommand != "journeys"sv) { | ||
416 | fprintf(stderr, "%s: unknown subcommand '%s'\n\n", progname, options.subcommand); | ||
417 | fprintf(stderr, help, progname); | ||
418 | exit(1); | ||
419 | } | ||
420 | if (options.subcommand && error) { | ||
421 | fputc('\n', stderr); | ||
422 | if (options.subcommand == "joparoute"sv) fprintf(stderr, joparoute_help, progname); | ||
423 | if (options.subcommand == "journeyinfo"sv) fprintf(stderr, journeyinfo_help, progname); | ||
424 | if (options.subcommand == "journeyroute"sv) fprintf(stderr, journeyroute_help, progname); | ||
425 | if (options.subcommand == "journeys"sv) fprintf(stderr, journeys_help, progname); | ||
426 | if (options.subcommand == "schedule"sv) fprintf(stderr, schedule_help, progname); | ||
427 | exit(1); | ||
428 | } | ||
429 | if (error || !options.subcommand) { | ||
430 | if (!options.subcommand) fprintf(stderr, "%s: no subcommand provided\n", progname); | ||
431 | fputc('\n', stderr); | ||
432 | fprintf(stderr, help, progname); | ||
433 | exit(1); | ||
434 | } | ||
435 | if (options.help) { | ||
436 | if (options.subcommand == "joparoute"sv) fprintf(stderr, joparoute_help, progname); | ||
437 | if (options.subcommand == "journeyinfo"sv) fprintf(stderr, journeyinfo_help, progname); | ||
438 | if (options.subcommand == "journeyroute"sv) fprintf(stderr, journeyroute_help, progname); | ||
439 | if (options.subcommand == "journeys"sv) fprintf(stderr, journeys_help, progname); | ||
440 | if (options.subcommand == "schedule"sv) fprintf(stderr, schedule_help, progname); | ||
441 | exit(0); | ||
442 | } | ||
443 | |||
444 | if (options.subcommand == "joparoute"sv) | ||
445 | jopaRouteValidateOptions(progname, &options); | ||
446 | if (options.subcommand == "journeyinfo"sv) | ||
447 | journeyInfoValidateOptions(progname, &options); | ||
448 | if (options.subcommand == "journeyroute"sv) | ||
449 | journeyRouteValidateOptions(progname, &options); | ||
450 | if (options.subcommand == "journeys"sv) | ||
451 | journeysValidateOptions(progname, &options); | ||
452 | if (options.subcommand == "schedule"sv) | ||
453 | scheduleValidateOptions(progname, &options); | ||
454 | |||
455 | return options; | ||
456 | } | ||