Mercurial > hg > th-libs
annotate th_args.c @ 39:0d55592e0e01
Cosmetic cleanups.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Sun, 02 Oct 2011 23:57:09 +0300 |
parents | a25f5d22483e |
children | e031a062b731 |
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 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
4 * (C) Copyright 2002-2008 Tecnic Software productions (TNSP) |
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) |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
65 effects the argument processing if bailOut argument of th_args_process() |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
66 is TRUE! |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
67 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
68 If bailOut is TRUE, any error/failure in argument processing (including |
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 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
72 If bailOut is FALSE, most errors are "ignored", but FALSE is still returned |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
73 if any errors occured. |
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 optional argument |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
96 { 2, 'f', "foobar", "Use foobar, with optional string", OPT_ARGOPT }, |
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 // This option is required to be given, though without other flags |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
99 // it may not make much sense. |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
100 { 4, 'S', "stupid", "You must give this option", OPT_REQUIRED }, |
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 // The flags can be combined with OR operator: this option is both |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
103 // required to be specified, and also requires argument (the filename) |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
104 { 5, 'i', "input", "Input file name", OPT_REQUIRED | OPT_ARGREQ }, |
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 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
107 // Option with only long form |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
108 { 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
|
109 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
110 // Option with only short form |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
111 { 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
|
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 |
2 | 115 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
|
116 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
117 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
118 */ |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
119 #ifdef HAVE_CONFIG_H |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
120 #include "config.h" |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
121 #endif |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
122 #include "th_util.h" |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
123 #include "th_args.h" |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
124 #include "th_string.h" |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
125 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
126 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
127 /* 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
|
128 */ |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
129 static BOOL th_args_check_arg(optarg_t *o, char *optArg) |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
130 { |
39 | 131 if ((o->optFlags & OPT_ARGMASK) == OPT_ARGREQ && optArg == NULL) |
132 { | |
133 if (o->optShort != 0 && o->optLong != NULL) | |
134 { | |
10 | 135 THERR("Option '-%c ARG' (--%s=ARG) requires an argument!\n", |
39 | 136 o->optShort, o->optLong); |
137 } | |
138 else if (o->optShort != 0) | |
139 { | |
10 | 140 THERR("Option '-%c ARG' requires an argument!\n", o->optShort); |
39 | 141 } |
142 else if (o->optLong != NULL) | |
143 { | |
10 | 144 THERR("Option --%s=ARG requires an argument!\n", o->optLong); |
145 } | |
39 | 146 |
10 | 147 return FALSE; |
39 | 148 } |
149 else | |
10 | 150 return TRUE; |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
151 } |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
152 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
153 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
154 /* Handle short options |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
155 */ |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
156 static BOOL th_args_process_short(char *currArg, int *newArgIndex, |
10 | 157 BOOL *wasGiven, int argc, char *argv[], |
158 optarg_t optList[], int optListN, | |
159 BOOL (*handleOpt)(int, char *, char *)) | |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
160 { |
10 | 161 char *tmpArg = currArg, *optArg; |
162 int optN; | |
163 BOOL isFound; | |
39 | 164 |
10 | 165 /* Short options can be combined: -a -b -c == -abc */ |
39 | 166 while (*tmpArg) |
167 { | |
10 | 168 for (optN = 0, isFound = FALSE; (optN < optListN) && !isFound; optN++) |
39 | 169 if (*tmpArg == optList[optN].optShort) |
170 { | |
171 /* Get possible option argument, if needed */ | |
172 if ((optList[optN].optFlags & OPT_ARGMASK) != 0 | |
173 && (++(*newArgIndex) < argc)) | |
174 optArg = argv[*newArgIndex]; | |
175 else | |
176 optArg = NULL; | |
177 | |
178 /* Check if option argument is required */ | |
179 if (!th_args_check_arg(&optList[optN], optArg)) | |
180 return FALSE; | |
181 else | |
182 { | |
183 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
|
184 |
39 | 185 /* Option was given succesfully, try to handle it */ |
186 wasGiven[optN] = TRUE; | |
187 | |
188 tmpStr[0] = *tmpArg; | |
189 | |
190 if (!handleOpt(optList[optN].optID, optArg, tmpStr)) | |
191 return FALSE; | |
192 } | |
193 | |
194 isFound = TRUE; | |
10 | 195 } |
39 | 196 |
197 if (!isFound) | |
198 { | |
10 | 199 THERR("Unknown short option '%c' in argument '-%s'\n", |
39 | 200 *tmpArg, currArg); |
10 | 201 return FALSE; |
202 } | |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
203 |
10 | 204 tmpArg++; |
205 } | |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
206 |
10 | 207 return TRUE; |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
208 } |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
209 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
210 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
211 /* Handle long options |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
212 */ |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
213 static BOOL th_args_process_long(char *currArg, int *newArgIndex, |
10 | 214 BOOL *wasGiven, int argc, char *argv[], |
215 optarg_t optList[], int optListN, | |
216 BOOL (*handleOpt)(int, char *, char *)) | |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
217 { |
10 | 218 int optN, optLen, i; |
219 char *optArg; | |
39 | 220 |
221 (void) argc; | |
222 (void) argv; | |
223 (void) newArgIndex; | |
224 | |
10 | 225 /* Long option */ |
226 for (optN = -1, optLen = i = 0; (i < optListN) && (optN < 0); i++) | |
39 | 227 if (optList[i].optLong) |
228 { | |
229 optLen = strlen(optList[i].optLong); | |
230 if (strncmp(currArg, optList[i].optLong, optLen) == 0) | |
231 optN = i; | |
232 } | |
233 | |
10 | 234 /* Get possible option argument, if needed */ |
39 | 235 if (optN >= 0) |
236 { | |
237 if ((optList[optN].optFlags & OPT_ARGMASK) != 0) | |
238 { | |
10 | 239 if (currArg[optLen] == '=') |
240 optArg = &currArg[optLen + 1]; | |
241 else | |
242 optArg = NULL; | |
39 | 243 } |
244 else | |
10 | 245 optArg = NULL; |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
246 |
10 | 247 /* Check if option argument is required */ |
248 if (!th_args_check_arg(&optList[optN], optArg)) | |
39 | 249 return FALSE; |
250 else | |
251 { | |
10 | 252 /* Option was given succesfully, try to handle it */ |
253 wasGiven[optN] = TRUE; | |
254 if (!handleOpt(optList[optN].optID, optArg, currArg)) | |
255 return FALSE; | |
256 } | |
39 | 257 } |
258 else | |
259 { | |
10 | 260 THERR("Unknown long option '--%s'\n", currArg); |
261 return FALSE; | |
262 } | |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
263 |
10 | 264 return TRUE; |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
265 } |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
266 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
267 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
268 /* 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
|
269 * calling the given callback functions. |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
270 */ |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
271 BOOL th_args_process(int argc, char *argv[], |
39 | 272 optarg_t optList[], int optListN, |
273 BOOL(*handleOpt) (int, char *, char *), | |
274 BOOL(*handleNonOption) (char *), BOOL bailOut) | |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
275 { |
10 | 276 BOOL endOptions, optionsOK; |
277 int argIndex, newArgIndex, i; | |
278 char *currArg; | |
279 BOOL *wasGiven; | |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
280 |
10 | 281 /* Allocate wasGiven */ |
282 wasGiven = (BOOL *) th_calloc(optListN, sizeof(BOOL)); | |
39 | 283 if (!wasGiven) |
284 { | |
285 THERR | |
286 ("FATAL ERROR! Could not allocate wasGiven in th_args_process()!\n"); | |
10 | 287 exit(128); |
288 } | |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
289 |
10 | 290 /* Parse arguments */ |
291 argIndex = 1; | |
292 optionsOK = TRUE; | |
293 endOptions = FALSE; | |
39 | 294 while (argIndex < argc) |
295 { | |
10 | 296 currArg = argv[argIndex]; |
39 | 297 if ((currArg[0] == '-') && !endOptions) |
298 { | |
10 | 299 newArgIndex = argIndex; |
300 currArg++; | |
39 | 301 if (*currArg == '-') |
302 { | |
10 | 303 /* Check for "--", which ends the options-list */ |
304 currArg++; | |
39 | 305 if (*currArg == 0) |
306 { | |
10 | 307 endOptions = TRUE; |
308 continue; | |
309 } | |
39 | 310 |
10 | 311 /* Long options */ |
312 if (!th_args_process_long(currArg, &newArgIndex, | |
39 | 313 wasGiven, argc, argv, optList, |
314 optListN, handleOpt)) | |
10 | 315 optionsOK = FALSE; |
39 | 316 } |
317 else | |
318 { | |
10 | 319 /* Short options */ |
320 if (!th_args_process_short(currArg, &newArgIndex, | |
39 | 321 wasGiven, argc, argv, optList, |
322 optListN, handleOpt)) | |
10 | 323 optionsOK = FALSE; |
324 } | |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
325 |
10 | 326 argIndex = newArgIndex; |
39 | 327 } |
328 else | |
329 { | |
10 | 330 /* Was not option argument */ |
39 | 331 if (handleNonOption == NULL |
332 || (handleNonOption != NULL && !handleNonOption(currArg))) | |
333 { | |
10 | 334 THERR("Invalid argument '%s'\n", currArg); |
335 optionsOK = FALSE; | |
336 } | |
337 } | |
39 | 338 |
10 | 339 /* Check if we bail out on invalid argument */ |
39 | 340 if (!optionsOK && bailOut) |
341 { | |
10 | 342 th_free(wasGiven); |
343 return FALSE; | |
344 } | |
39 | 345 |
10 | 346 argIndex++; |
347 } | |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
348 |
10 | 349 /* Check wasGiven by isRequired */ |
350 for (i = 0; i < optListN; i++) | |
39 | 351 if ((optList[i].optFlags & OPT_REQUIRED) != 0 && !wasGiven[i]) |
352 { | |
353 THERR("Option -%s (--%s) is required.\n", | |
354 optList[i].optShort, optList[i].optLong); | |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
355 |
39 | 356 optionsOK = FALSE; |
357 if (bailOut) | |
358 break; | |
359 } | |
360 | |
10 | 361 th_free(wasGiven); |
362 return optionsOK; | |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
363 } |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
364 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
365 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
366 /* 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
|
367 */ |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
368 void th_args_help(FILE * outFile, |
39 | 369 optarg_t optList[], int optListN, |
370 char *progName, char *progUsage) | |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
371 { |
10 | 372 int i, nrequired; |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
373 |
10 | 374 fprintf(outFile, |
39 | 375 "\n%s v%s (%s)\n" |
376 "%s\n" | |
377 "%s\n" | |
378 "Usage: %s %s\n", | |
379 th_prog_name, th_prog_version, th_prog_fullname, | |
380 th_prog_author, th_prog_license, progName, progUsage); | |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
381 |
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
382 |
39 | 383 for (i = nrequired = 0; i < optListN; i++) |
384 { | |
10 | 385 optarg_t *o = &optList[i]; |
39 | 386 |
10 | 387 /* Print short option */ |
388 if (o->optShort != 0) | |
389 fprintf(outFile, " -%c, ", o->optShort); | |
390 else | |
391 fprintf(outFile, " "); | |
39 | 392 |
10 | 393 /* Print long option */ |
39 | 394 if (o->optLong) |
395 { | |
10 | 396 char tmpStr[64], *p; |
39 | 397 |
398 if ((o->optFlags & OPT_ARGMASK) == OPT_ARGOPT) | |
399 { | |
400 snprintf(tmpStr, sizeof(tmpStr), "%s[=ARG]", | |
401 optList[i].optLong); | |
10 | 402 p = tmpStr; |
39 | 403 } |
404 else if ((o->optFlags & OPT_ARGMASK) == OPT_ARGREQ) | |
405 { | |
406 snprintf(tmpStr, sizeof(tmpStr), "%s=ARG", | |
407 optList[i].optLong); | |
10 | 408 p = tmpStr; |
39 | 409 } |
410 else | |
10 | 411 p = o->optLong; |
39 | 412 |
10 | 413 fprintf(outFile, "--%-15s", p); |
39 | 414 } |
415 else | |
10 | 416 fprintf(outFile, " "); |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
417 |
10 | 418 fprintf(outFile, " %s.", optList[i].optDesc); |
39 | 419 |
420 if (o->optFlags & OPT_REQUIRED) | |
421 { | |
10 | 422 fprintf(outFile, " [*]\n"); |
423 nrequired++; | |
39 | 424 } |
425 else | |
10 | 426 fprintf(outFile, "\n"); |
427 } | |
39 | 428 |
10 | 429 if (nrequired > 0) |
430 fprintf(outFile, "(Options marked with [*] are required)\n"); | |
0
bd61a80a6c54
Initial import into Mercurial repository. Discarding old cvs/svn history
Matti Hamalainen <ccr@tnsp.org>
parents:
diff
changeset
|
431 } |