tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

uoptions.cpp (5115B)


      1 // © 2016 and later: Unicode, Inc. and others.
      2 // License & terms of use: http://www.unicode.org/copyright.html
      3 /*
      4 *******************************************************************************
      5 *
      6 *   Copyright (C) 2000-2015, International Business Machines
      7 *   Corporation and others.  All Rights Reserved.
      8 *
      9 *******************************************************************************
     10 *   file name:  uoptions.c
     11 *   encoding:   UTF-8
     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 
     25 U_CAPI int U_EXPORT2
     26 u_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=nullptr;
     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==nullptr) {
     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 */
     65                            option->doesOccur=0;
     66                            return -i;
     67                        }
     68                    }
     69 
     70                    if(option->optionFn!=nullptr && option->optionFn(option->context, option)<0) {
     71                        /* the option function was called and returned an error */
     72                        option->doesOccur=0;
     73                        return -i;
     74                    }
     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==nullptr) {
     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 */
    107                            option->doesOccur=0;
    108                            return -i;
    109                        }
    110                    }
    111 
    112                    if(option->optionFn!=nullptr && 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 
    118                    /* get the next option letter */
    119                    option=nullptr;
    120                    c=*arg++;
    121                } while(c!=0);
    122            }
    123 
    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 }