diff options
Diffstat (limited to 'board/MAI/bios_emulator/scitech/src/common/cmdline.c')
| -rw-r--r-- | board/MAI/bios_emulator/scitech/src/common/cmdline.c | 428 | 
1 files changed, 428 insertions, 0 deletions
| diff --git a/board/MAI/bios_emulator/scitech/src/common/cmdline.c b/board/MAI/bios_emulator/scitech/src/common/cmdline.c new file mode 100644 index 000000000..872fae919 --- /dev/null +++ b/board/MAI/bios_emulator/scitech/src/common/cmdline.c @@ -0,0 +1,428 @@ +/**************************************************************************** +* +*  ======================================================================== +* +*    The contents of this file are subject to the SciTech MGL Public +*    License Version 1.0 (the "License"); you may not use this file +*    except in compliance with the License. You may obtain a copy of +*    the License at http://www.scitechsoft.com/mgl-license.txt +* +*    Software distributed under the License is distributed on an +*    "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +*    implied. See the License for the specific language governing +*    rights and limitations under the License. +* +*    The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc. +* +*    The Initial Developer of the Original Code is SciTech Software, Inc. +*    All Rights Reserved. +* +*  ======================================================================== +* +* Language:     ANSI C +* Environment:  any +* +* Description:  This module contains code to parse the command line, +*               extracting options and parameters in standard System V +*               style. +* +****************************************************************************/ + +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include "cmdline.h" + +/*------------------------- Global variables ------------------------------*/ + +int     nextargv    =   1;          /* Index into argv array            */ +char    *nextchar   =   NULL;       /* Pointer to next character        */ + +/*-------------------------- Implementation -------------------------------*/ + +#define IS_SWITCH_CHAR(c)       ((c) == '-') +#define IS_NOT_SWITCH_CHAR(c)   ((c) != '-') + +/**************************************************************************** +DESCRIPTION: +Parse the command line for specific options + +HEADER: +cmdline.h + +PARAMETERS: +argc        - Value passed to program through argc variable +argv        - Pointer to the argv array passed to the program +format      - A string representing the expected format of the command line +argument    - Pointer to optional argument on command line + +RETURNS: +Character code representing the next option parsed from the command line by +getcmdopt. Returns ALLDONE (-1) when there are no more parameters to be parsed +on the command line, PARAMETER (-2) when the argument being parsed is a +parameter and not an option switch and lastly INVALID (-3) if an error +occured while parsing the command line. + +REMARKS: +Function to parse the command line option switches in UNIX System V style. +When getcmdopt is called, it returns the character code of the next valid +option that is parsed from the command line as specified by the Format +string. The format string should be in the following form: + +    "abcd:e:f:" + +where a,b and c represent single switch style options and the character +code returned by getcmdopt is the only value returned. Also d, e and f +represent options that expect arguments immediately after them on the +command line. The argument that follows the option on the command line is +returned via a reference in the pointer argument. Thus a valid command line +for this format string might be: + +    myprogram -adlines -b -f format infile outfile + +where a and b will be returned as single character options with no argument, +while d is returned with the argument lines and f is returned with the +argument format. + +When getcmdopt returns with PARAMETER (we attempted to parse a paramter, not +an option), the global variable NextArgv will hold an index in the argv +array to the argument on the command line AFTER the options, ie in the +above example the string 'infile'. If the parameter is successfully used, +NextArgv should be incremented and getcmdopt can be called again to parse any +more options. Thus you can also have options interspersed throught the +command line. eg: + +    myprogram -adlines infile -b outfile -f format + +can be made to be a valid form of the above command line. +****************************************************************************/ +int getcmdopt( +    int argc, +    char **argv, +    char *format, +    char **argument) +{ +    char    ch; +    char    *formatchar; + +    if (argc > nextargv) { +        if (nextchar == NULL) { +            nextchar = argv[nextargv];      /* Index next argument      */ +            if (nextchar == NULL) { +                nextargv++; +                return ALLDONE;             /* No more options          */ +                } +            if (IS_NOT_SWITCH_CHAR(*nextchar)) { +                nextchar = NULL; +                return PARAMETER;           /* We have a parameter      */ +                } +            nextchar++;                     /* Move past switch operator */ +            if (IS_SWITCH_CHAR(*nextchar)) { +                nextchar = NULL; +                return INVALID;             /* Ignore rest of line      */ +                } +            } +        if ((ch = *(nextchar++)) == 0) { +            nextchar = NULL; +            return INVALID;                 /* No options on line       */ +            } + +        if (ch == ':' ||  (formatchar = strchr(format, ch)) == NULL) +            return INVALID; + +        if (*(++formatchar) == ':') {   /* Expect an argument after option */ +            nextargv++; +            if (*nextchar == 0) { +                if (argc <= nextargv) +                    return INVALID; +                nextchar = argv[nextargv++]; +                } +            *argument = nextchar; +            nextchar = NULL; +            } +        else {                      /* We have a switch style option    */ +            if (*nextchar == 0) { +                nextargv++; +                nextchar = NULL; +                } +            *argument = NULL; +            } +        return ch;                  /* return the option specifier      */ +        } +    nextchar = NULL; +    nextargv++; +    return ALLDONE;                 /* no arguments on command line     */ +} + +/**************************************************************************** +PARAMETERS: +optarr      - Description for the option we are parsing +argument    - String to parse + +RETURNS: +INVALID on error, ALLDONE on success. + +REMARKS: +Parses the argument string depending on the type of argument that is +expected, filling in the argument for that option. Note that to parse a +string, we simply return a pointer to argument. +****************************************************************************/ +static int parse_option( +    Option *optarr, +    char *argument) +{ +    int     num_read; + +    switch ((int)(optarr->type)) { +        case OPT_INTEGER: +            num_read = sscanf(argument,"%d",(int*)optarr->arg); +            break; +        case OPT_HEX: +            num_read = sscanf(argument,"%x",(int*)optarr->arg); +            break; +        case OPT_OCTAL: +            num_read = sscanf(argument,"%o",(int*)optarr->arg); +            break; +        case OPT_UNSIGNED: +            num_read = sscanf(argument,"%u",(uint*)optarr->arg); +            break; +        case OPT_LINTEGER: +            num_read = sscanf(argument,"%ld",(long*)optarr->arg); +            break; +        case OPT_LHEX: +            num_read = sscanf(argument,"%lx",(long*)optarr->arg); +            break; +        case OPT_LOCTAL: +            num_read = sscanf(argument,"%lo",(long*)optarr->arg); +            break; +        case OPT_LUNSIGNED: +            num_read = sscanf(argument,"%lu",(ulong*)optarr->arg); +            break; +        case OPT_FLOAT: +            num_read = sscanf(argument,"%f",(float*)optarr->arg); +            break; +        case OPT_DOUBLE: +            num_read = sscanf(argument,"%lf",(double*)optarr->arg); +            break; +        case OPT_LDOUBLE: +            num_read = sscanf(argument,"%Lf",(long double*)optarr->arg); +            break; +        case OPT_STRING: +            num_read = 1;           /* This always works    */ +            *((char**)optarr->arg) = argument; +            break; +        default: +            return INVALID; +        } + +    if (num_read == 0) +        return INVALID; +    else +        return ALLDONE; +} + +/**************************************************************************** +HEADER: +cmdline.h + +PARAMETERS: +argc        - Number of arguments on command line +argv        - Array of command line arguments +num_opt     - Number of options in option array +optarr      - Array to specify how to parse the command line +do_param    - Routine to handle a command line parameter + +RETURNS: +ALLDONE, INVALID or HELP + +REMARKS: +Function to parse the command line according to a table of options. This +routine calls getcmdopt above to parse each individual option and attempts +to parse each option into a variable of the specified type. The routine +can parse integers and long integers in either decimal, octal, hexadecimal +notation, unsigned integers and unsigned longs, strings and option switches. +Option switches are simply boolean variables that get turned on if the +switch was parsed. + +Parameters are extracted from the command line by calling a user supplied +routine do_param() to handle each parameter as it is encountered. The +routine do_param() should accept a pointer to the parameter on the command +line and an integer representing how many parameters have been encountered +(ie: 1 if this is the first parameter, 10 if it is the 10th etc), and return +ALLDONE upon successfully parsing it or INVALID if the parameter was invalid. + +We return either ALLDONE if all the options were successfully parsed, +INVALID if an invalid option was encountered or HELP if any of -h, -H or +-? were present on the command line. +****************************************************************************/ +int getargs( +    int argc, +    char *argv[], +    int num_opt, +    Option optarr[], +    int (*do_param)( +        char *param, +        int num)) +{ +    int     i,opt; +    char    *argument; +    int     param_num = 1; +    char    cmdstr[MAXARG*2 + 4]; + +    /* Build the command string from the array of options   */ + +    strcpy(cmdstr,"hH?"); +    for (i = 0,opt = 3; i < num_opt; i++,opt++) { +        cmdstr[opt] = optarr[i].opt; +        if (optarr[i].type != OPT_SWITCH) { +            cmdstr[++opt] = ':'; +            } +        } +    cmdstr[opt] = '\0'; + +    for (;;) { +        opt = getcmdopt(argc,argv,cmdstr,&argument); +        switch (opt) { +            case 'H': +            case 'h': +            case '?': +                return HELP; +            case ALLDONE: +                return ALLDONE; +            case INVALID: +                return INVALID; +            case PARAMETER: +                if (do_param == NULL) +                    return INVALID; +                if (do_param(argv[nextargv],param_num) == INVALID) +                    return INVALID; +                nextargv++; +                param_num++; +                break; +            default: + +                /* Search for the option in the option array. We are +                 * guaranteed to find it. +                 */ + +                for (i = 0; i < num_opt; i++) { +                    if (optarr[i].opt == opt) +                        break; +                    } +                if (optarr[i].type == OPT_SWITCH) +                    *((ibool*)optarr[i].arg) = true; +                else { +                    if (parse_option(&optarr[i],argument) == INVALID) +                        return INVALID; +                    } +                break; +            } +        } +} + +/**************************************************************************** +HEADER: +cmdline.h + +PARAMETERS: +num_opt - Number of options in the table +optarr  - Table of option descriptions + +REMARKS: +Prints the description of each option in a standard format to the standard +output device. The description for each option is obtained from the table +of options. +****************************************************************************/ +void print_desc( +    int num_opt, +    Option optarr[]) +{ +    int     i; + +    for (i = 0; i < num_opt; i++) { +        if (optarr[i].type == OPT_SWITCH) +            printf("  -%c       %s\n",optarr[i].opt,optarr[i].desc); +        else +            printf("  -%c<arg>  %s\n",optarr[i].opt,optarr[i].desc); +        } +} + +/**************************************************************************** +HEADER: +cmdline.h + +PARAMETERS: +moduleName  - Module name for program +cmdLine     - Command line to parse +pargc       - Pointer to 'argc' parameter +pargv       - Pointer to 'argv' parameter +maxArgc     - Maximum argv array index + +REMARKS: +Parses a command line from a single string into the C style 'argc' and +'argv' format. Most useful for Windows programs where the command line +is passed in verbatim. +****************************************************************************/ +int parse_commandline( +    char *moduleName, +    char *cmdLine, +    int *pargc, +    char *argv[], +    int maxArgv) +{ +    static char str[512]; +    static char filename[260]; +    char        *prevWord = NULL; +    ibool        inQuote = FALSE; +    ibool        noStrip = FALSE; +    int         argc; + +    argc = 0; +    strcpy(filename,moduleName); +    argv[argc++] = filename; +    cmdLine = strncpy(str, cmdLine, sizeof(str)-1); +    while (*cmdLine) { +        switch (*cmdLine) { +            case '"' : +                if (prevWord != NULL) { +                    if (inQuote) { +                        if (!noStrip) +                            *cmdLine = '\0'; +                        argv [argc++] = prevWord; +                        prevWord = NULL; +                        } +                    else +                        noStrip = TRUE; +                    } +                inQuote = !inQuote; +                break; +            case ' ' : +            case '\t' : +                if (!inQuote) { +                    if (prevWord != NULL) { +                        *cmdLine = '\0'; +                        argv [argc++] = prevWord; +                        prevWord = NULL; +                        noStrip = FALSE; +                        } +                    } +                break; +            default : +                if (prevWord == NULL) +                    prevWord = cmdLine; +                break; +                } +        if (argc >= maxArgv - 1) +            break; +        cmdLine++; +        } + +    if ((prevWord != NULL || (inQuote && prevWord != NULL)) && argc < maxArgv - 1) { +        *cmdLine = '\0'; +        argv [argc++] = prevWord; +        } +    argv[argc] = NULL; + +    /* Return updated parameters */ +    return (*pargc = argc); +} |