1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
/*
*******************************************************************************
*
* Copyright (C) 2000, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
* file name: uoptions.c
* encoding: US-ASCII
* tab size: 8 (not used)
* indentation:4
*
* created on: 2000apr17
* created by: Markus W. Scherer
*
* This file provides a command line argument parser.
*/
#include "unicode/utypes.h"
#include "cstring.h"
#include "uoptions.h"
U_CAPI int U_EXPORT2
u_parseArgs(int argc, char* argv[],
int optionCount, UOption options[]) {
char *arg;
int i=1, remaining=1;
char c, stopOptions=0;
while(i<argc) {
arg=argv[i];
if(!stopOptions && *arg=='-' && (c=arg[1])!=0) {
/* process an option */
UOption *option=NULL;
arg+=2;
if(c=='-') {
/* process a long option */
if(*arg==0) {
/* stop processing options after "--" */
stopOptions=1;
} else {
/* search for the option string */
int j;
for(j=0; j<optionCount; ++j) {
if(options[j].longName && uprv_strcmp(arg, options[j].longName)==0) {
option=options+j;
break;
}
}
if(option==NULL) {
/* no option matches */
return -i;
}
option->doesOccur=1;
if(option->hasArg!=UOPT_NO_ARG) {
/* parse the argument for the option, if any */
if(i+1<argc && !(argv[i+1][0]=='-' && argv[i+1][1]!=0)) {
/* argument in the next argv[], and there is not an option in there */
option->value=argv[++i];
} else if(option->hasArg==UOPT_REQUIRES_ARG) {
/* there is no argument, but one is required: return with error */
return -i;
}
}
}
} else {
/* process one or more short options */
do {
/* search for the option letter */
int j;
for(j=0; j<optionCount; ++j) {
if(c==options[j].shortName) {
option=options+j;
break;
}
}
if(option==NULL) {
/* no option matches */
return -i;
}
option->doesOccur=1;
if(option->hasArg!=UOPT_NO_ARG) {
/* parse the argument for the option, if any */
if(*arg!=0) {
/* argument following in the same argv[] */
option->value=arg;
/* do not process the rest of this arg as option letters */
break;
} else if(i+1<argc && !(argv[i+1][0]=='-' && argv[i+1][1]!=0)) {
/* argument in the next argv[], and there is not an option in there */
option->value=argv[++i];
/* this break is redundant because we know that *arg==0 */
break;
} else if(option->hasArg==UOPT_REQUIRES_ARG) {
/* there is no argument, but one is required: return with error */
return -i;
}
}
/* get the next option letter */
option=NULL;
c=*arg++;
} while(c!=0);
}
if(option!=0 && option->optionFn!=0 && option->optionFn(option->context, option)<0) {
/* the option function was called and returned an error */
return -i;
}
/* go to next argv[] */
++i;
} else {
/* move a non-option up in argv[] */
argv[remaining++]=arg;
++i;
}
}
return remaining;
}
|