/* instructions for compiling and linking this source file lc quit */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* */ /* / Copyright (c) 1989 Paul Klink. All Rights Reserved. */ /* / / This Program must not be distributed or used without the */ /* / / / permission of the authors: */ /* / / / */ /* / / / Paul Klink P.O. Box 169 */ /* / / Woori-Yallock 3139 */ /* Australia */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* */ /* GetNextOpt.c contains the following externally accessable function */ /* which is placed in the pkc.lib library */ /* GetNextOpt() - Gets the next Option and its associated option */ /* string from the command line. */ /* */ /* It is called repeatedly and everytime it is called, it returns the */ /* argument or option, whichever is next. If it returns an option, it */ /* will point to an option string. The option string is the next set of */ /* characters in the command line. It will either be the rest of the */ /* characters in the current parameter or it will point to all the next */ /* parameter. On the next call to GetNextOpt(), the user has to specify */ /* whether or next the previous option required the option string. If */ /* not, these characters are used as the next option or argument. */ /* */ /* The following rules are applied to the command line parameters to */ /* determine which are options and which are arguments. */ /* */ /* - The command line is examined from left to right. */ /* - Each Command line parameter is either an argument, a set of */ /* options or an option string. */ /* - If a parameter starts with a quote (") character, then the */ /* parameter ends when the next quote character is found. All white */ /* space between the quotes is considered as part of that parameter. */ /* If no second quote is found, the task aborts with an error. */ /* Note: This is done by the start up main program. */ /* - A parameter holds a set of options if the first character is a */ /* dash and the second is not a digit. The parameter must have more */ /* than one character within it. */ /* - A parameter holds an option string if the last character in the */ /* preceding parameter was an option (or end of an option) that */ /* required an option string. */ /* - If neither of the above two conditions apply, then the parameter */ /* holds an argument. */ /* - The '-' will be skipped when options are examined. The exception */ /* is if a parameter holds a set of options and ends with the '-' */ /* character. In this case, the final '-' is returned as an option. */ /* - For option strings, if the leading character is an '=' then it is */ /* skipped. If (after possibly removing the '=') the end of the */ /* parameter is detected, then the next parameter is considered the */ /* option string. If no further parameters exist, then the option */ /* string is a NULL string. */ /* */ /* */ /* */ /* The formal parameter 'action' passed to GetNextOpt() has the */ /* following effects. */ /* action = 0 - In this case, the routine will start to examine the */ /* command line from the first parameter (it ignores */ /* the program name). That is it starts a scan of the */ /* Command line. The first time this function is */ /* called, action is not examined as the function */ /* assumes it is 0. */ /* action = 1 - This shows that the previous option string returned */ /* was actually an option string. If the previous call */ /* returned an argument, then action is ignored (as */ /* long as it is not equal to 0). */ /* action = 2 - This shows that the previous option string returned */ /* was NOT used as an option string. If the previous */ /* call returned an argument, then action is ignored */ /* as long as it is not equal to 0). */ /* */ /* */ /* NAME */ /* GetNextOpt() */ /* */ /* SYNOPSIS */ /* #include for function prototype */ /* */ /* option = GetNextOpt(action, str_ptr, OptPrm, argc, argv); */ /* */ /* int action Shows what action function should take. */ /* See above. */ /* char **str_ptr Points to string variable which is set up */ /* point to the option string or to the */ /* argument string if the next element in the */ /* command line is an argument. */ /* int *OptPrm The integer is set to 1 if next element was */ /* an option and the option string was not in */ /* same parameter as that holding the option. */ /* In all other cases it is 0. */ /* int argc Nr of command line arguments. */ /* char *argv[] The string array which holds all the */ /* command line parameters. */ /* */ /* int option See return section below. */ /* */ /* RETURNS */ /* option shows what next element in the command line was. */ /* option = option character if it was an option. (1 to 255) */ /* option = 0 if it was an argument. */ /* option = -1 if no more elements in the command line. */ /* */ /* If the next element was an option, then the variable *str_ptr */ /* will point to what the function interpretted to be the option */ /* string. If the option string is not in the same element as the */ /* option, then the integer pointed to by OptPrm will be set to 1. */ /* Be careful in the next call to GetNextOpt() to specify */ /* whether or not the string pointed to by *strptr was actually an */ /* option string. All the characters in this string will be */ /* skipped in the next call if you specify that it was an option */ /* string. */ /* */ /* If an option was the last character in the command line, then */ /* *str_ptr will point to a Null string. */ /* */ /* If the next element was an argument, the the variable *str_ptr */ /* will point to the argument (string). */ /* */ /* */ /* HISTORY */ /* */ /* Ed. Date Author Comments */ /* --- --------- ----------- ---------------------------------------- */ /* 001 24-Jan-90 Paul Klink Initial Development */ /* */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include "pkc.h" static int initialized = 0; /*= 0 if function called first time. = 1 if thereafter */ /*The Next two variables show where the search*/ /*should continue from if the action formal */ /*parameter specifies that the previous option*/ /*string was used. If the previous element */ /*was an argument, then these two variables & */ /*the next two will be equal so the value of */ /*action will have no effect. In this case, */ /*both of these two sets, will point to the */ /*command line element after the argument */ /*element returned. */ static int YOnextParam = 1; /*Next Cmd line parameter to exam */ static int YOnextPOffs = 0; /*Next offset char in Param to ex */ /*The Next two variables show where the search*/ /*should continue from if the action formal */ /*parameter specifies that the previous option*/ /*string was NOT used. If the previous elemen*/ /*was an argument, then these two variables & */ /*the previous two will be equal so the value */ /*action will have no effect. In this case, */ /*both of these two sets, will point to the */ /*command line element after the argument */ /*element returned. */ static int NOnextParam = 1; /*Next Cmd line parameter to exam */ static int NOnextPOffs = 0; /*Next offset char in Param to ex */ /* Prototypes for functions defined in GetNextOpt.c */ int GetNextOpt(int action, char **str_ptr, int *OptPrm, int argc, char **argv); static int InitCmdLine(int argc, char **argv); static int DoOption(int nextParam, int nextPOffs, int argc, char **argv, char **str_ptr, int *OptPrm); static int DoArg(int nextParam, int nextPOffs, int argc, char **argv, char **str_ptr); /*-------------------------------------*/ int GetNextOpt(int action, char **str_ptr, int *OptPrm, int argc, char *argv[]) { int option; /*holds value to be returned*/ int nextParam, nextPOffs; *OptPrm = 0; /*do this immediately*/ /*First check that there is at least one parameter */ if (argc <= 1) /*at least one parameter?*/ { option = -1; /*no, flag all checked*/ } else { /*Check that command line has been correctly */ /*initialized by function, if not, do so. */ if (!initialized) /*been initialized?*/ { initialized = InitCmdLine(argc, argv); /*no, do so*/ action = 0; /*start from 1st par*/ } /*If action specifies that we are to start at */ /*the start of the command line, reinit the */ /*static ..next.... variables. */ if (action == 0) { YOnextParam = 1; /*start from cmd line param 1*/ NOnextParam = 1; YOnextPOffs = 0; /*start from first char in param*/ NOnextPOffs = 0; } /*Set up the values of the next..... variables */ if (action == 1) /*was previous option str used?*/ { nextParam = YOnextParam; /*yes*/ nextPOffs = YOnextPOffs; } else { nextParam = NOnextParam; /*no*/ nextPOffs = NOnextPOffs; } /*Do not continue if command line completely done */ if (nextParam == -1) /*command line all done?*/ { option = -1; /*yes, flag that & return*/ } else { /*Determine if we are at the start of a cmd line */ /*parameter. */ /*If we are, determine if the parameter holds a */ /*set of options or an argument. It will be a set */ /*of options if the first character is a '-' and */ /*the second character is not a digit and the */ /*string is longer than one character */ /*Otherwise the parameter holds an argument. */ /*If we are not at the start of a parameter, then */ /*the parameter must hold a set of options. */ /*Once this has been determined call the relevant */ /*function. */ if (nextPOffs == 0) /*are we at start of a param?*/ { /*yes, see if it is an set of opt?*/ if ( strlen(argv[nextParam]) > 1 && *argv[nextParam] == '-' && ! isdigit( (int) *(argv[nextParam]+1) ) ) { /*It is a set of options!*/ option = DoOption(nextParam, nextPOffs, argc, argv, str_ptr, OptPrm); } else { /*It is an argument*/ option = DoArg(nextParam, nextPOffs, argc, argv, str_ptr); } } else /*we are not at start of param*/ { /*must be set of options*/ option = DoOption(nextParam, nextPOffs, argc, argv, str_ptr, OptPrm); } } /*if (nextParam==-1)*/ } /*end of if from (argc<=1) */ return(option); } /*-----------------------------------*/ /*InitCmdLine() currently does nothing On Entry: argc the integer that hold the number of command line arguments (ie program name and parameters). argv the argv string array that points to the command line arguments On Exit: 1 Always returns the integer 1 */ #pragma argsused static int InitCmdLine (int argc, char *argv[]) { return(1); } /*----------------------------------*/ /*DoOption() DoOption() extracts the next option and option string out of the command line from the position specified by nextParam and nextPOffs. It will then set up the static ..next.... variables for the next time that GetNextOpt() is called. It will return the option character and set up the pointer *str_ptr to point to the option string. On Entry: nextParam points to command line parameter from which to get option nextPOffs position in parameter from which to get option argc number of command line arguments argv string array pointing to command line arguments str_ptr points to string pointer which is to point to option str OptPrm points to integer that indicates if string in same elem On Exit: option holds option character (0x01 to 0xff) *str_ptr points to option string */ static int DoOption( int nextParam, int nextPOffs, int argc, char *argv[], char **str_ptr, int *OptPrm) { int option; /*Get the option character. Skip over a leading */ /*'-' character if one is present. */ /*It will not skip over a '-' if it is the last */ /*character in a parameter. In this case */ /*option = '-'. */ option = (int) argv[nextParam][nextPOffs++]; /*get option char*/ if (option=='-' && argv[nextParam][nextPOffs]) /*ignore leading '-'*/ { option = (int) argv[nextParam][nextPOffs++]; /*get next option char*/ } /*Set up the pointer to the option string. */ /*The option string will either point to the rest */ /*of the characters in the current parameter or to */ /*the start of the next parameter. */ /*It will specify the next parameter if there are */ /*no more characters in the current parameter. */ /*If there are no more parameters when required, it*/ /*will point to a NULL string. */ /*If it points to characters in the current */ /*parameter, then it will skip one leading '=' if */ /*present. */ *str_ptr = & argv[nextParam][nextPOffs]; /*get option string*/ if (**str_ptr == '=') /*skip any leading equal signs*/ { *str_ptr = & argv[nextParam][++nextPOffs]; /*point to next if so*/ } if (**str_ptr == '\0') /*at end of parameter?*/ { nextParam += 1; /*yes, specify next parameter*/ nextPOffs = 0; /*beginning of next param*/ *OptPrm = 1; /*flag Option string not in same el*/ if (nextParam >= argc) /*are there actually more param?*/ { nextParam = -1; /*no flag so for next time*/ } else /*yes, there are more param*/ { *str_ptr = argv[nextParam]; /*get opt str again*/ } } /*Can now set up the NOnext.... static variables */ /*for the next time GetNextOpt() is called */ NOnextParam = nextParam; NOnextPOffs = nextPOffs; /*Set Up the YOnext.... static variables (option */ /*string was used) for next time. */ if (nextParam != -1) /*run out or parameters already?*/ { nextParam += 1; /*no, specify next one*/ nextPOffs = 0; if (nextParam >= argc) /*are there actually more param?*/ { nextParam = -1; /*no flag so for next time*/ } } YOnextParam = nextParam; YOnextPOffs = nextPOffs; return(option); } /*----------------------------------*/ /*DoArg() DoArg() extracts the next argument string out of the command line from the position specified by nextParam. It will then set up the static ..next.... variables for the next time that GetNextOpt() is called. It will return 0 to show that the next command line element was an argument and set up the pointer *str_ptr to point to the argument string. On Entry: nextParam points to command line parameter from which to get option nextPOffs position in parameter from which to get option argc number of command line arguments argv string array pointing to command line arguments str_ptr points to string pointer which is to point to option str On Exit: option = 0 to show that an argument was found *str_ptr points to the argument string */ #pragma argsused static int DoArg ( int nextParam, int nextPOffs, int argc, char *argv[], char **str_ptr) { int option; *str_ptr = argv[nextParam]; /*make *str_ptr point to argument*/ option = 0; /*flag that next command line element was an argument*/ /*set up the ..next..... static variables*/ nextParam += 1; /*specifiy next parameter*/ if (nextParam >= argc) /*is there a next one?*/ { nextParam = -1; /*no*/ } NOnextParam = nextParam; NOnextPOffs = 0; YOnextParam = nextParam; YOnextPOffs = 0; return(option); } /*======= End of Source file =======*/