/* argcheck Interface to routines for checking argument strings in command lines. Usage: #include arg_check (argument) char *argument; The argument string Description: Each argument string is compared against a list of valid arguments contained in an argument list (the global variable arg_list is this array; see below). The comparison is made by a matching function (the global variable arg_match points to this function; see below). When a match occurs (the arg_match function returns TRUE) the corresponding argument handler is called and passed the argument string, and its return value is returned to the user. The argument handler is refered to by a function pointer paired with the matched argument string in the arg_list. When the global variable arg_do_no is TRUE, a check is made for a "NO[_]" prefix to the argument string. When this prefix is encountered the global variable arg_positive is set to FALSE (0), and the pointer to the argument string is moved forward (on the stack, not affecting the user's value) past the prefix. The new argument string, effectively stripped of the negating prefix, is used to scan the argument list of keywords for a match. When an argument function handler is called, it may use arg_positive as appropriate. Since arg_positive is TRUE when the negating prefix is not present, the typical use of this variable in an argument handler would be to set the value of a logical flag. If the scan of the argument list fails to produce a match, arg_check returns with the value FAILURE (0); otherwise, the value returned by the argument handler is returned to the user. The argument list is a an array of structures of type ARG_HANDLE: typedef struct { char *keyword; The argument keyword to be matched int (*function)(); The argument handler function } ARG_HANDLE; >>> CAUTION <<< The user MUST create an initial argument list with the global name user_arguments. The arg_list pointer is initialized with this external variable. >>> CAUTION <<< The argument list MUST be terminated with a null entry. Example: extern first_function(); extern second_function(); ... extern last_function(); ARG_HANDLE user_arguments[] = { "FIRST_WORD", first_function, "SECOND_WORD", second_function, ... "LAST_WORD", last_function, 0, 0 } >>> WARNING <<< The argument handler function is called with this syntax: (*handle->function) (argument string); where handle - is a pointer to the current ARG_HANDLE structure in the argument list pointed to by arg_list. - is the argument string the matched the keyword corrsponding to the function in the argument list. The function that is used to match argument strings to argument list words is pointed to by arg_match. The default function (strmatch) compares the strings without regard to case. If the argument keyword ends before the argument string ends (i.e. the keyword matches the beginning of the argument), a successful match has occured. Checking for a string match fails when corresponding characters are not the same, or the argument string ends (i.e. the keyword is the minimal string that must be matched). >>> CAUTION <<< The string comparison function MUST return TRUE if a match (by whatever definition) exits between the keyword string and the argument string. It must return FALSE otherwise. >>> WARNING <<< The matching function is called with this syntax: (*arg_match) (handle->keyword, argument); ******************************************************************************/ #include #define _ARG_CHECK_ #include IMPORTED ARG_HANDLE user_arguments[]; ARG_HANDLE *arg_list = user_arguments; IMPORTED INTEGER strmatch (); INTFUNC arg_match = strmatch; LOGICAL arg_do_no = TRUE; LOGICAL arg_positive = TRUE; INTEGER arg_check (argument) STRING argument; { REGISTER ARG_HANDLE *handle; #ifdef DEBUG printf ("arg_check: %s\n", argument); #endif arg_positive = TRUE; if (arg_do_no) { /* NO[_] prefix check: */ if (toupper (*argument) == 'N' && toupper (*argument + 1) == 'O') { arg_positive = FALSE; #ifdef DEBUG printf ("\tNO prefix ...\n"); #endif /* Allow for optional '_' separator between NO and argument */ argument = &argument[(argument[2] == '_') ? 3 : 2]; } } /* Scan the argument list looking for a keyword match: */ for (handle = arg_list; handle->function; handle++) if ((*arg_match) (handle->keyword, argument)) { #ifdef DEBUG printf ("\tMatch with keyword %s\n", handle->keyword); #endif return ((*handle->function) (argument)); } #ifdef DEBUG printf ("\tNo keyword match.\n"); #endif return (FAILURE); /* unknown */ }