windows-nt/Source/XPSP1/NT/ds/security/tools/keytab2/opt/enum.c
2020-09-26 16:20:57 +08:00

276 lines
5.4 KiB
C

/*++
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;
}