|
|
/*++
ENUM.C
Option Enumerated Types
Copyright (C) 1997 Microsoft Corporation, all rights reserved
Created, 7/29/1997 by DavidCHR
--*/
#include "private.h"
BOOL PrintEnumValues( FILE *out, PCHAR header, optEnumStruct *pStringTable ) {
ULONG index;
for( index = 0 ; pStringTable[index].UserField != NULL ; index++ ) {
if ( pStringTable[index].DescriptionField ) { fprintf( stderr, "%hs%10hs : %hs \n", header, pStringTable[index].UserField, pStringTable[index].DescriptionField );
} }
return TRUE;
}
BOOL IsMaskChar( IN CHAR ch ) {
return ( ch == '|' ) || ( ch == ',' ); }
BOOL ResolveEnumFromStrings( ULONG cStrings, PCHAR *strings, // remaining args.
optionStruct *opt, PULONG pcArgsUsed ) {
optEnumStruct *pStringTable; ULONG TableIndex; ULONG StringIndex; ULONG cArgsUsed = 0; BOOL wasFound; BOOL moreComing = TRUE;
pStringTable = ( optEnumStruct *) opt->optData;
#if 1
for ( StringIndex = 0 ; (StringIndex < cStrings) && moreComing ; StringIndex++ ) {
PCHAR theString; // points to the current argument
theString = strings[ StringIndex ];
do {
OPTIONS_DEBUG( "Start of maskable loop. theString = %s\n", theString );
wasFound = FALSE; moreComing = FALSE;
for( TableIndex = 0 ; pStringTable[ TableIndex ].UserField != NULL; TableIndex ++ ) { ULONG StringLength; // set to the string length of the option cmd
StringLength = strlen( pStringTable[ TableIndex ].UserField );
// string-compare up to the StringLength.
if ( STRNCASECMP( pStringTable[ TableIndex ].UserField, theString, StringLength ) != 0 ) {
continue; // this entry doesn't match.
} // else...
// found a partial match! Verify the remainder if there is any.
if ( theString [ StringLength ] != '\0' ) {
if ( opt->flags & OPT_ENUM_IS_MASK ) { if ( IsMaskChar( theString[ StringLength ] ) ) { // more are coming.
moreComing = TRUE;
} else continue; // inexact match.
} else continue; // inexact match.
}
wasFound = TRUE;
if ( cArgsUsed ) { *(POPTU_CAST( *opt )->integer) |= ( ( ULONG )((ULONG_PTR) pStringTable[ TableIndex ]. VariableField ));
} else {
*(POPTU_CAST( *opt )->raw_data) = ( pStringTable[ TableIndex ]. VariableField );
}
if ( theString == strings[ StringIndex ] ) { /* we modify theString if it includes multiple mask values.
So, this way we only increase the number of used arguments ONCE per actual argument. */
cArgsUsed++; } if ( opt->flags & OPT_ENUM_IS_MASK ) {
if ( moreComing ) {
// check to see if the user input "xxx|yyy", or just "xxx|"
ASSERT( StringLength > 0 );
// theString[ StringLength ] == '|' or something.
for ( theString += StringLength+1; // +1 to go past '|'
theString != NULL ; theString ++ ) { if ( *theString == '\0' ) {
OPTIONS_DEBUG( "Mask is of the form 'XXX|'\n" ); // case = xxx| -- no more coming.
theString = NULL; //
break;
}
if ( isspace( *theString ) ) { continue; }
OPTIONS_DEBUG( "nonspace character '%c' hit.\n" "mask component is of the form XXX|YYY.\n", *theString ); break;
}
ASSERT( !theString || ( (*theString != '\0') && !isspace(*theString) ) );
break;
} else { // !moreComing
theString = NULL; // no more args in *this* string.
/* check to see if the mask character is or is in the NEXT
argument: "xxx" "|yyy" or "xxx" "|" "yyy" */ if ( strings[ StringIndex+1 ] ) {
if ( IsMaskChar( strings[ StringIndex+1 ][0] ) ) { moreComing = TRUE; if ( strings[ StringIndex+1 ][1] == '\0' ) {
// xxx | yyy
cArgsUsed++; StringIndex++;
} else {
// xxx |yyy
strings[ StringIndex +1 ]++;
}
}
} // strings[ StringIndex +1 ]
} // !moreComing
break; // found what we wanted. stop checking the table.
} else { // !OPT_ENUM_IS_MASK
// found the only argument we were expecting. Just return.
*pcArgsUsed = cArgsUsed; return TRUE;
} // moreComing check
} // for each table entry
} while ( ( theString != NULL ) && wasFound );
if ( !wasFound ) { // option was not recognized.
fprintf( stderr, "%s: enum value '%s' is not known.\n", opt->cmd, strings[ StringIndex ] ); break; } }
#else
for( index = 0 ; pStringTable[index].UserField != NULL; index++ ) { if ( STRCASECMP( pStringTable[index].UserField, string ) == 0 ) { // found a match!
*(POPTU_CAST( *opt )->raw_data) = pStringTable[index].VariableField;
OPTIONS_DEBUG( "Enum resolves to #%d, \"%s\" = 0x%x \n", index, pStringTable[index].DescriptionField, pStringTable[index].VariableField );
return TRUE; } }
#endif
if ( wasFound ) {
*pcArgsUsed = cArgsUsed;
} else {
fprintf( stderr, "Error: argument for option \"%hs\" must be %s:\n", opt->cmd, ( opt->flags & OPT_ENUM_IS_MASK ) ? "one or more of the\n following, separated by '|' or ','" : "one of the following values" );
PrintEnumValues( stderr, "", pStringTable );
}
return wasFound;
}
|