OLD | NEW |
(Empty) | |
| 1 /* |
| 2 ******************************************************************************* |
| 3 * |
| 4 * Copyright (C) 2000, International Business Machines |
| 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 |
| 23 U_CAPI int U_EXPORT2 |
| 24 u_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].lo
ngName)==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 */ |
| 63 return -i; |
| 64 } |
| 65 } |
| 66 } |
| 67 } else { |
| 68 /* process one or more short options */ |
| 69 do { |
| 70 /* search for the option letter */ |
| 71 int j; |
| 72 for(j=0; j<optionCount; ++j) { |
| 73 if(c==options[j].shortName) { |
| 74 option=options+j; |
| 75 break; |
| 76 } |
| 77 } |
| 78 if(option==NULL) { |
| 79 /* no option matches */ |
| 80 return -i; |
| 81 } |
| 82 option->doesOccur=1; |
| 83 |
| 84 if(option->hasArg!=UOPT_NO_ARG) { |
| 85 /* parse the argument for the option, if any */ |
| 86 if(*arg!=0) { |
| 87 /* argument following in the same argv[] */ |
| 88 option->value=arg; |
| 89 /* do not process the rest of this arg as option let
ters */ |
| 90 break; |
| 91 } else if(i+1<argc && !(argv[i+1][0]=='-' && argv[i+1][1
]!=0)) { |
| 92 /* argument in the next argv[], and there is not an
option in there */ |
| 93 option->value=argv[++i]; |
| 94 /* this break is redundant because we know that *arg
==0 */ |
| 95 break; |
| 96 } else if(option->hasArg==UOPT_REQUIRES_ARG) { |
| 97 /* there is no argument, but one is required: return
with error */ |
| 98 return -i; |
| 99 } |
| 100 } |
| 101 |
| 102 /* get the next option letter */ |
| 103 option=NULL; |
| 104 c=*arg++; |
| 105 } while(c!=0); |
| 106 } |
| 107 |
| 108 if(option!=0 && option->optionFn!=0 && option->optionFn(option->cont
ext, option)<0) { |
| 109 /* the option function was called and returned an error */ |
| 110 return -i; |
| 111 } |
| 112 |
| 113 /* go to next argv[] */ |
| 114 ++i; |
| 115 } else { |
| 116 /* move a non-option up in argv[] */ |
| 117 argv[remaining++]=arg; |
| 118 ++i; |
| 119 } |
| 120 } |
| 121 return remaining; |
| 122 } |
OLD | NEW |