// Copyright (C) 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
*******************************************************************************
*
*   Copyright (C) 2000-2015, 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 */
                            option->doesOccur=0;
                            return -i;
                        }
                    }

                    if(option->optionFn!=NULL && option->optionFn(option->context, option)<0) {
                        /* the option function was called and returned an error */
                        option->doesOccur=0;
                        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 */
                            option->doesOccur=0;
                            return -i;
                        }
                    }

                    if(option->optionFn!=NULL && option->optionFn(option->context, option)<0) {
                        /* the option function was called and returned an error */
                        option->doesOccur=0;
                        return -i;
                    }

                    /* get the next option letter */
                    option=NULL;
                    c=*arg++;
                } while(c!=0);
            }

            /* go to next argv[] */
            ++i;
        } else {
            /* move a non-option up in argv[] */
            argv[remaining++]=arg;
            ++i;
        }
    }
    return remaining;
}
