Mercurial > hg > th-libs
annotate th_args.c @ 139:4ca0af6dbcf8
Another fix in the option handling.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Fri, 26 Sep 2014 01:52:14 +0300 |
parents | dab546dfb9b4 |
children | 3d555015ada4 |
rev | line source |
---|---|
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
1 /* |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
2 * Simple commandline argument processing |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
3 * Programmed and designed by Matti 'ccr' Hamalainen |
128 | 4 * (C) Copyright 2002-2008 Tecnic Software productions (TNSP) |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
5 * |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
6 * Please read file 'COPYING' for information on license and distribution. |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
7 */ |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
8 /* |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
9 Description |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
10 =========== |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
11 Structures and functions for simple commandline argument processing, |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
12 option argument handling (short and long forms supported). |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
13 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
14 Output function for printing out short on-line help for said options |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
15 and program commandline usage. |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
16 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
17 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
18 Format for typical commandline: |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
19 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
20 $ program -a -b -c --long-d -e argument-for-e --long-f="argument for f" |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
21 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
22 where -a, -b and -c are short options without required arguments; |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
23 --long-d is a long option without argument; -e is short option with |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
24 argument and finally --long-f is long option with argument. |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
25 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
26 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
27 Introduction |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
28 ============ |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
29 Handling of commandline options in th_args_process() has various |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
30 options, which effect how an option is handled. Also the error |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
31 situations (unknown option/no required argument) can be handled |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
32 in different ways. |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
33 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
34 Typically th_args_process() is called as follows: |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
35 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
36 BOOL optionHandlerCallback(int optionNumber, char *optionArgument, char *optionName) |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
37 { |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
38 if (option is OK) |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
39 return TRUE; |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
40 else |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
41 return FALSE; |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
42 } |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
43 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
44 BOOL nonoptionHandlerCallback(char *argumentString) |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
45 { |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
46 // return value same as in optionHandlerCallback |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
47 } |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
48 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
49 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
50 int main(int argc, char *argv[]) |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
51 { |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
52 if (th_args_process(argc, argv, optList, optListN, |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
53 optionHandlerCallback, nonoptionHandlerCallback)) { |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
54 ... arguments OK ... |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
55 } else { |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
56 ... arguments invalid or required arguments missing ... |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
57 } |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
58 } |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
59 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
60 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
61 NOTICE! |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
62 ------- |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
63 The return value from handler callbacks affects the return value of |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
64 th_args_process(). Additionally, a failure in callback (returns FALSE) |
137
0f43a94516f4
Improve argument handling module.
Matti Hamalainen <ccr@tnsp.org>
parents:
136
diff
changeset
|
65 effects the argument processing if OPTH_BAILOUT flag for th_args_process() |
0f43a94516f4
Improve argument handling module.
Matti Hamalainen <ccr@tnsp.org>
parents:
136
diff
changeset
|
66 is set. |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
67 |
137
0f43a94516f4
Improve argument handling module.
Matti Hamalainen <ccr@tnsp.org>
parents:
136
diff
changeset
|
68 If OPTH_BAILOUT is set, any error/failure in argument processing (including |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
69 callbacks) immediately stops the argument processing and FALSE is |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
70 returned from th_args_process(). |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
71 |
137
0f43a94516f4
Improve argument handling module.
Matti Hamalainen <ccr@tnsp.org>
parents:
136
diff
changeset
|
72 If OPTH_BAILOUT is NOT set, most errors are "ignored", but FALSE is still |
0f43a94516f4
Improve argument handling module.
Matti Hamalainen <ccr@tnsp.org>
parents:
136
diff
changeset
|
73 returned if any errors occured. |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
74 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
75 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
76 NOTICE #2! |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
77 ---------- |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
78 A small temporary buffer of N*sizeof(BOOL) (where N is number of |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
79 options in optList[]) is allocated for processing required options. |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
80 If this allocation fails, the program is immediately exited with |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
81 code 128. |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
82 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
83 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
84 Examples |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
85 ======== |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
86 Example of different options, in a fictional optionlist struct: |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
87 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
88 optarg_t optList[] = { |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
89 // Option without arguments |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
90 { 0, '?', "help", "Show this help", OPT_NONE }, |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
91 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
92 // Option with a required argument |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
93 { 1, 'o', "output", "Output file name", OPT_ARGREQ }, |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
94 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
95 // Option with only long form |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
96 { 0, 0, "only-long", "Long option", OPT_NONE }, |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
97 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
98 // Option with only short form |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
99 { 0, 's', NULL, "Short option", OPT_NONE }, |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
100 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
101 }; |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
102 |
2 | 103 const int optListN = (sizeof(optList) / sizeof(optarg_t)); |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
104 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
105 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
106 */ |
50 | 107 #ifndef TH_EXTERNAL |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
108 #include "th_util.h" |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
109 #include "th_args.h" |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
110 #include "th_string.h" |
49
598609fb49b0
Change how "config.h" is included, etc.
Matti Hamalainen <ccr@tnsp.org>
parents:
47
diff
changeset
|
111 #endif |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
112 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
113 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
114 /* Check if option requires an argument |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
115 */ |
47 | 116 static BOOL th_args_check_arg(const optarg_t *o, const char *optArg) |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
117 { |
46
5f73c8cd333a
Change some structure member names in optarg_t.
Matti Hamalainen <ccr@tnsp.org>
parents:
45
diff
changeset
|
118 if ((o->flags & OPT_ARGMASK) == OPT_ARGREQ && optArg == NULL) |
39 | 119 { |
120 if (o->optShort != 0 && o->optLong != NULL) | |
121 { | |
10 | 122 THERR("Option '-%c ARG' (--%s=ARG) requires an argument!\n", |
39 | 123 o->optShort, o->optLong); |
124 } | |
125 else if (o->optShort != 0) | |
126 { | |
10 | 127 THERR("Option '-%c ARG' requires an argument!\n", o->optShort); |
39 | 128 } |
129 else if (o->optLong != NULL) | |
130 { | |
10 | 131 THERR("Option --%s=ARG requires an argument!\n", o->optLong); |
132 } | |
39 | 133 |
10 | 134 return FALSE; |
39 | 135 } |
136 else | |
10 | 137 return TRUE; |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
138 } |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
139 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
140 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
141 /* Handle short options |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
142 */ |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
143 static BOOL th_args_process_short(char *currArg, int *newArgIndex, |
136 | 144 int argc, char *argv[], |
10 | 145 optarg_t optList[], int optListN, |
139
4ca0af6dbcf8
Another fix in the option handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
138
diff
changeset
|
146 BOOL (*handleOpt)(int, char *, char *), BOOL process) |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
147 { |
10 | 148 char *tmpArg = currArg, *optArg; |
149 int optN; | |
150 BOOL isFound; | |
39 | 151 |
128 | 152 // Short options can be combined: -a -b -c == -abc |
39 | 153 while (*tmpArg) |
154 { | |
10 | 155 for (optN = 0, isFound = FALSE; (optN < optListN) && !isFound; optN++) |
39 | 156 if (*tmpArg == optList[optN].optShort) |
157 { | |
128 | 158 // Get possible option argument, if needed |
46
5f73c8cd333a
Change some structure member names in optarg_t.
Matti Hamalainen <ccr@tnsp.org>
parents:
45
diff
changeset
|
159 if ((optList[optN].flags & OPT_ARGMASK) != 0 |
39 | 160 && (++(*newArgIndex) < argc)) |
161 optArg = argv[*newArgIndex]; | |
162 else | |
163 optArg = NULL; | |
164 | |
128 | 165 // Check if option argument is required |
39 | 166 if (!th_args_check_arg(&optList[optN], optArg)) |
167 return FALSE; | |
168 else | |
139
4ca0af6dbcf8
Another fix in the option handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
138
diff
changeset
|
169 if (process) |
39 | 170 { |
171 char tmpStr[2] = { 0, 0 }; | |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
172 |
128 | 173 // Option was given succesfully, try to handle it |
39 | 174 tmpStr[0] = *tmpArg; |
175 | |
46
5f73c8cd333a
Change some structure member names in optarg_t.
Matti Hamalainen <ccr@tnsp.org>
parents:
45
diff
changeset
|
176 if (!handleOpt(optList[optN].id, optArg, tmpStr)) |
39 | 177 return FALSE; |
178 } | |
179 | |
180 isFound = TRUE; | |
10 | 181 } |
39 | 182 |
183 if (!isFound) | |
184 { | |
10 | 185 THERR("Unknown short option '%c' in argument '-%s'\n", |
39 | 186 *tmpArg, currArg); |
10 | 187 return FALSE; |
188 } | |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
189 |
10 | 190 tmpArg++; |
191 } | |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
192 |
10 | 193 return TRUE; |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
194 } |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
195 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
196 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
197 /* Handle long options |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
198 */ |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
199 static BOOL th_args_process_long(char *currArg, int *newArgIndex, |
136 | 200 int argc, char *argv[], |
10 | 201 optarg_t optList[], int optListN, |
139
4ca0af6dbcf8
Another fix in the option handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
138
diff
changeset
|
202 BOOL (*handleOpt)(int, char *, char *), BOOL process) |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
203 { |
10 | 204 int optN, optLen, i; |
205 char *optArg; | |
39 | 206 |
207 (void) argc; | |
208 (void) argv; | |
209 (void) newArgIndex; | |
210 | |
128 | 211 // Long option |
212 for (optN = -1, optLen = i = 0; i < optListN && optN < 0; i++) | |
136 | 213 { |
214 optarg_t *opt = &optList[i]; | |
215 if (opt->optLong) | |
39 | 216 { |
136 | 217 optLen = strlen(opt->optLong); |
218 if (strncmp(currArg, opt->optLong, optLen) == 0) | |
39 | 219 optN = i; |
220 } | |
136 | 221 } |
39 | 222 |
128 | 223 // Get possible option argument, if needed |
39 | 224 if (optN >= 0) |
225 { | |
46
5f73c8cd333a
Change some structure member names in optarg_t.
Matti Hamalainen <ccr@tnsp.org>
parents:
45
diff
changeset
|
226 if ((optList[optN].flags & OPT_ARGMASK) != 0) |
127
37bf3d8766b7
Fix long option parsing. I wonder how long that has been broken.
Matti Hamalainen <ccr@tnsp.org>
parents:
73
diff
changeset
|
227 optArg = (currArg[optLen] == '=') ? &currArg[optLen + 1] : NULL; |
39 | 228 else |
10 | 229 optArg = NULL; |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
230 |
128 | 231 // Check if option argument is required |
10 | 232 if (!th_args_check_arg(&optList[optN], optArg)) |
39 | 233 return FALSE; |
234 else | |
136 | 235 // Option was given succesfully, try to handle it |
139
4ca0af6dbcf8
Another fix in the option handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
138
diff
changeset
|
236 if (process && !handleOpt(optList[optN].id, optArg, currArg)) |
136 | 237 return FALSE; |
39 | 238 } |
239 else | |
240 { | |
10 | 241 THERR("Unknown long option '--%s'\n", currArg); |
242 return FALSE; | |
243 } | |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
244 |
10 | 245 return TRUE; |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
246 } |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
247 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
248 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
249 /* Process arguments, handling short and long options by |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
250 * calling the given callback functions. |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
251 */ |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
252 BOOL th_args_process(int argc, char *argv[], |
39 | 253 optarg_t optList[], int optListN, |
254 BOOL(*handleOpt) (int, char *, char *), | |
137
0f43a94516f4
Improve argument handling module.
Matti Hamalainen <ccr@tnsp.org>
parents:
136
diff
changeset
|
255 BOOL(*handleNonOption) (char *), int flags) |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
256 { |
139
4ca0af6dbcf8
Another fix in the option handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
138
diff
changeset
|
257 int handle = flags & OPTH_ONLY_MASK, |
4ca0af6dbcf8
Another fix in the option handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
138
diff
changeset
|
258 argIndex = 1; |
4ca0af6dbcf8
Another fix in the option handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
138
diff
changeset
|
259 BOOL optionsOK = TRUE, |
4ca0af6dbcf8
Another fix in the option handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
138
diff
changeset
|
260 endOptions = FALSE; |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
261 |
39 | 262 while (argIndex < argc) |
263 { | |
137
0f43a94516f4
Improve argument handling module.
Matti Hamalainen <ccr@tnsp.org>
parents:
136
diff
changeset
|
264 char *currArg = argv[argIndex]; |
138
dab546dfb9b4
Oops, fix the new option handling options.
Matti Hamalainen <ccr@tnsp.org>
parents:
137
diff
changeset
|
265 if (*currArg == '-' && !endOptions) |
39 | 266 { |
139
4ca0af6dbcf8
Another fix in the option handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
138
diff
changeset
|
267 BOOL process = (handle & OPTH_ONLY_OPTS) || handle == 0; |
4ca0af6dbcf8
Another fix in the option handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
138
diff
changeset
|
268 int newArgIndex = argIndex; |
4ca0af6dbcf8
Another fix in the option handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
138
diff
changeset
|
269 currArg++; |
4ca0af6dbcf8
Another fix in the option handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
138
diff
changeset
|
270 if (*currArg == '-') |
39 | 271 { |
139
4ca0af6dbcf8
Another fix in the option handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
138
diff
changeset
|
272 // Check for "--", which ends the options-list |
10 | 273 currArg++; |
139
4ca0af6dbcf8
Another fix in the option handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
138
diff
changeset
|
274 if (*currArg == 0) |
39 | 275 { |
139
4ca0af6dbcf8
Another fix in the option handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
138
diff
changeset
|
276 endOptions = TRUE; |
4ca0af6dbcf8
Another fix in the option handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
138
diff
changeset
|
277 continue; |
10 | 278 } |
39 | 279 |
139
4ca0af6dbcf8
Another fix in the option handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
138
diff
changeset
|
280 // Long options |
4ca0af6dbcf8
Another fix in the option handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
138
diff
changeset
|
281 if (!th_args_process_long(currArg, &newArgIndex, |
4ca0af6dbcf8
Another fix in the option handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
138
diff
changeset
|
282 argc, argv, optList, |
4ca0af6dbcf8
Another fix in the option handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
138
diff
changeset
|
283 optListN, handleOpt, process)) |
4ca0af6dbcf8
Another fix in the option handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
138
diff
changeset
|
284 optionsOK = FALSE; |
39 | 285 } |
139
4ca0af6dbcf8
Another fix in the option handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
138
diff
changeset
|
286 else |
4ca0af6dbcf8
Another fix in the option handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
138
diff
changeset
|
287 { |
4ca0af6dbcf8
Another fix in the option handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
138
diff
changeset
|
288 // Short options |
4ca0af6dbcf8
Another fix in the option handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
138
diff
changeset
|
289 if (!th_args_process_short(currArg, &newArgIndex, |
4ca0af6dbcf8
Another fix in the option handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
138
diff
changeset
|
290 argc, argv, optList, |
4ca0af6dbcf8
Another fix in the option handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
138
diff
changeset
|
291 optListN, handleOpt, process)) |
4ca0af6dbcf8
Another fix in the option handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
138
diff
changeset
|
292 optionsOK = FALSE; |
4ca0af6dbcf8
Another fix in the option handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
138
diff
changeset
|
293 } |
4ca0af6dbcf8
Another fix in the option handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
138
diff
changeset
|
294 |
4ca0af6dbcf8
Another fix in the option handling.
Matti Hamalainen <ccr@tnsp.org>
parents:
138
diff
changeset
|
295 argIndex = newArgIndex; |
39 | 296 } |
297 else | |
137
0f43a94516f4
Improve argument handling module.
Matti Hamalainen <ccr@tnsp.org>
parents:
136
diff
changeset
|
298 if (handle == OPTH_ONLY_OTHER || handle == 0) |
39 | 299 { |
128 | 300 // Was not option argument |
39 | 301 if (handleNonOption == NULL |
302 || (handleNonOption != NULL && !handleNonOption(currArg))) | |
303 { | |
10 | 304 THERR("Invalid argument '%s'\n", currArg); |
305 optionsOK = FALSE; | |
306 } | |
307 } | |
39 | 308 |
128 | 309 // Check if we bail out on invalid argument |
137
0f43a94516f4
Improve argument handling module.
Matti Hamalainen <ccr@tnsp.org>
parents:
136
diff
changeset
|
310 if (!optionsOK && (flags & OPTH_BAILOUT)) |
10 | 311 return FALSE; |
39 | 312 |
10 | 313 argIndex++; |
314 } | |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
315 |
10 | 316 return optionsOK; |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
317 } |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
318 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
319 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
320 /* Print help for commandline arguments/options |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
321 */ |
50 | 322 void th_args_help(FILE *outFile, optarg_t optList[], int optListN) |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
323 { |
136 | 324 int index; |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
325 |
136 | 326 for (index = 0; index < optListN; index++) |
39 | 327 { |
136 | 328 optarg_t *opt = &optList[index]; |
39 | 329 |
128 | 330 // Print short option |
136 | 331 if (opt->optShort != 0) |
332 fprintf(outFile, " -%c, ", opt->optShort); | |
10 | 333 else |
334 fprintf(outFile, " "); | |
39 | 335 |
128 | 336 // Print long option |
136 | 337 if (opt->optLong) |
39 | 338 { |
10 | 339 char tmpStr[64], *p; |
39 | 340 |
136 | 341 if ((opt->flags & OPT_ARGMASK) == OPT_ARGREQ) |
39 | 342 { |
343 snprintf(tmpStr, sizeof(tmpStr), "%s=ARG", | |
136 | 344 opt->optLong); |
10 | 345 p = tmpStr; |
39 | 346 } |
347 else | |
136 | 348 p = opt->optLong; |
39 | 349 |
10 | 350 fprintf(outFile, "--%-15s", p); |
39 | 351 } |
352 else | |
10 | 353 fprintf(outFile, " "); |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
354 |
136 | 355 fprintf(outFile, " %s.\n", opt->desc); |
10 | 356 } |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
357 } |