wmacpi: fix multiple definitions of two global variables.
[dockapps.git] / libdockapp / src / daargs.c
blob99a8f73e9a55a2b4df43af0c94e886949636aa91
1 /*
2 * Copyright (c) 1999-2005 Alfredo K. Kojima, Alban G. Hertroys
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 #include <assert.h>
24 #include <string.h>
26 #include "daargs.h"
27 #include "dautil.h"
29 #define DEFAULT_OPTION_COUNT 3
31 extern struct DAContext *_daContext;
34 * Prototypes
37 static void _daContextAddDefaultOptions(void);
38 static void _daContextAddOptions(DAProgramOption *options, int count);
39 static void printHelp(char *description);
41 int contains(char *needle, char *haystack);
42 int parseOption(DAProgramOption *option, int i, int argc, char **argv);
43 int readIntOption(int index, char **argv);
46 * Public functions
49 void
50 DAParseArguments(
51 int argc,
52 char **argv,
53 DAProgramOption *options,
54 int count,
55 char *programDescription,
56 char *versionDescription)
58 int i, j, size;
59 int found = 0;
61 _daContext = DAContextInit(argc, argv);
63 size = (count + DEFAULT_OPTION_COUNT) * sizeof(DAProgramOption *);
64 _daContext->options = malloc(size);
65 memset(_daContext->options, 0, size);
67 _daContextAddDefaultOptions();
68 _daContextAddOptions(options, count);
70 for (i = 1; i < argc; i++) {
71 char *optStr = argv[i];
73 /* Handle default options */
74 if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0)
75 printHelp(programDescription), exit(0);
77 if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--version") == 0)
78 puts(versionDescription), exit(0);
80 if (strcmp(argv[i], "-w") == 0 || strcmp(argv[i], "--windowed") == 0) {
81 _daContext->windowed = 1;
82 continue;
85 found = 0;
86 /* options with a one-to-one mapping */
87 for (j = 0; j < count; j++) {
88 DAProgramOption *option = &options[j];
90 if ((option->longForm && strcmp(option->longForm, optStr) == 0)
91 || (option->shortForm && strcmp(option->shortForm, optStr) == 0)) {
93 found = 1;
94 i = parseOption(option, i, argc, argv);
98 /* mixed options */
99 if (!found)
100 /* XXX: Parsing all options again... */
101 for (j = 0; j < count; j++) {
102 DAProgramOption *option = &options[j];
104 if (option->shortForm && contains(option->shortForm, optStr)) {
105 found = 1;
106 i = parseOption(option, i, argc, argv);
110 if (!found) {
111 printf("%s: unrecognized option '%s'\n", argv[0], argv[i]);
112 printHelp(programDescription), exit(1);
118 contains(char *needle, char *haystack)
120 char *pos = NULL;
122 if (strlen(needle) == 2 && needle[0] == '-') {
123 pos = strchr(haystack, needle[1]);
126 return (pos != NULL);
130 parseOption(DAProgramOption *option, int i, int argc, char **argv)
132 option->used = True;
134 if (option->type == DONone)
135 return i;
137 i++;
138 if (i >= argc)
139 printf("%s: missing argument for option '%s'\n",
140 argv[0],
141 argv[i-1]),
142 exit(1);
144 switch (option->type) {
145 case DOInteger:
146 *option->value.integer = readIntOption(i, argv);
148 break;
150 case DONatural:
151 *option->value.integer = readIntOption(i, argv);
153 if (*option->value.integer < 0)
154 printf("%s: argument %s must be >= 0\n",
155 argv[0],
156 argv[i-1]),
157 exit(1);
158 break;
160 case DOString:
161 *option->value.string = argv[i];
162 break;
165 return i;
169 readIntOption(int index, char **argv)
171 int integer;
173 if (sscanf(argv[index], "%i", &integer) != 1)
174 DAError("error parsing argument for option %s\n", argv[index-1]),
175 exit(1);
177 return integer;
181 DAGetArgC()
183 return _daContext->argc;
186 char **
187 DAGetArgV()
189 return _daContext->argv;
192 char *
193 DAGetProgramName()
195 return _daContext->programName;
200 * Local functions
203 struct DAContext *
204 DAContextInit(int argc, char **argv)
206 struct DAContext *context = malloc(sizeof(struct DAContext));
208 memset(context, 0, sizeof(struct DAContext));
210 context->argc = argc;
211 context->argv = argv;
212 context->programName = argv[0];
214 return context;
217 void
218 DAFreeContext(void)
220 if (_daContext->optionCount > 0) {
221 int i;
223 for (i = 0; i < _daContext->optionCount; i++)
224 free(_daContext->options[i]);
226 free(_daContext->options);
229 free(_daContext);
232 static void
233 _daContextAddOption(DAProgramOption *option)
235 /* If the buffer is full, double its size */
236 if (sizeof(_daContext->options) == _daContext->optionCount * sizeof(DAProgramOption)) {
237 DAProgramOption **options;
239 options = (DAProgramOption **)realloc(
240 (DAProgramOption **)_daContext->options,
241 2 * sizeof(_daContext->options));
243 if (options == NULL)
244 DAError("Out of memory");
246 _daContext->options = options;
249 _daContext->options[_daContext->optionCount] = option;
250 _daContext->optionCount++;
253 static void
254 _daContextAddOptionData(char *shortForm, char *longForm,
255 char *description, short type)
257 DAProgramOption *option = malloc(sizeof(DAProgramOption));
259 option->shortForm = shortForm;
260 option->longForm = longForm;
261 option->description = description;
262 option->type = type;
263 option->used = False;
264 option->value.ptr = NULL;
266 _daContextAddOption(option);
269 static void
270 _daContextAddDefaultOptions(void)
272 _daContextAddOptionData("-h", "--help", "show this help text and exit", DONone);
273 _daContextAddOptionData("-v", "--version", "show program version and exit", DONone);
274 _daContextAddOptionData("-w", "--windowed", "run the application in windowed mode", DONone);
277 static void
278 _daContextAddOptions(DAProgramOption *options, int count)
280 int i;
282 for (i = 0; i < count; i++)
283 _daContextAddOptionData(
284 options[i].shortForm,
285 options[i].longForm,
286 options[i].description,
287 options[i].type);
290 static void
291 printHelp(char *description)
293 int i;
294 DAProgramOption **options = _daContext->options;
295 int count = _daContext->optionCount;
297 printf("Usage: %s [OPTIONS]\n", _daContext->programName);
298 if (description)
299 puts(description);
301 for (i = 0; i < count; i++) {
302 char blank[30];
303 int c;
305 if (options[i]->shortForm && options[i]->longForm)
306 c = printf(" %s, %s", options[i]->shortForm, options[i]->longForm);
307 else if (options[i]->shortForm)
308 c = printf(" %s", options[i]->shortForm);
309 else if (options[i]->longForm)
310 c = printf(" %s", options[i]->longForm);
311 else
312 continue;
314 if (options[i]->type != DONone) {
315 switch (options[i]->type) {
316 case DOInteger:
317 c += printf(" <integer>");
318 break;
319 case DOString:
320 c += printf(" <string>");
321 break;
322 case DONatural:
323 c += printf(" <number>");
324 break;
328 memset(blank, ' ', 30);
329 if (c > 29)
330 c = 1;
331 blank[30-c] = 0;
332 printf("%s %s\n", blank, options[i]->description);