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