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