Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

275 lines
5.7 KiB

  1. /*++
  2. ENUM.C
  3. Option Enumerated Types
  4. Copyright (C) 1997 Microsoft Corporation, all rights reserved
  5. Created, 7/29/1997 by DavidCHR
  6. --*/
  7. #include "private.h"
  8. BOOL
  9. PrintEnumValues( FILE *out,
  10. PCHAR header,
  11. optEnumStruct *pStringTable ) {
  12. ULONG index;
  13. for( index = 0 ; pStringTable[index].UserField != NULL ; index++ ) {
  14. if ( pStringTable[index].DescriptionField ) {
  15. fprintf( stderr, "%hs%10hs : %hs \n",
  16. header,
  17. pStringTable[index].UserField,
  18. pStringTable[index].DescriptionField );
  19. }
  20. }
  21. return TRUE;
  22. }
  23. BOOL
  24. IsMaskChar( IN CHAR ch ) {
  25. return ( ch == '|' ) || ( ch == ',' );
  26. }
  27. BOOL
  28. ResolveEnumFromStrings( ULONG cStrings,
  29. PCHAR *strings, // remaining args.
  30. optionStruct *opt,
  31. PULONG pcArgsUsed ) {
  32. optEnumStruct *pStringTable;
  33. ULONG TableIndex;
  34. ULONG StringIndex;
  35. ULONG cArgsUsed = 0;
  36. BOOL wasFound = FALSE;
  37. BOOL moreComing = TRUE;
  38. pStringTable = ( optEnumStruct *) opt->optData;
  39. #if 1
  40. for ( StringIndex = 0 ;
  41. (StringIndex < cStrings) && moreComing ;
  42. StringIndex++ ) {
  43. PCHAR theString; // points to the current argument
  44. theString = strings[ StringIndex ];
  45. do {
  46. OPTIONS_DEBUG( "Start of maskable loop. theString = %s\n",
  47. theString );
  48. wasFound = FALSE;
  49. moreComing = FALSE;
  50. for( TableIndex = 0 ;
  51. pStringTable[ TableIndex ].UserField != NULL;
  52. TableIndex ++ ) {
  53. ULONG StringLength; // set to the string length of the option cmd
  54. StringLength = strlen( pStringTable[ TableIndex ].UserField );
  55. // string-compare up to the StringLength.
  56. if ( STRNCASECMP( pStringTable[ TableIndex ].UserField,
  57. theString, StringLength ) != 0 ) {
  58. continue; // this entry doesn't match.
  59. } // else...
  60. // found a partial match! Verify the remainder if there is any.
  61. if ( theString [ StringLength ] != '\0' ) {
  62. if ( opt->flags & OPT_ENUM_IS_MASK ) {
  63. if ( IsMaskChar( theString[ StringLength ] ) ) {
  64. // more are coming.
  65. moreComing = TRUE;
  66. } else continue; // inexact match.
  67. } else continue; // inexact match.
  68. }
  69. wasFound = TRUE;
  70. if ( cArgsUsed ) {
  71. *(POPTU_CAST( *opt )->integer) |= ( ( ULONG )((ULONG_PTR)
  72. pStringTable[ TableIndex ].
  73. VariableField ));
  74. } else {
  75. *(POPTU_CAST( *opt )->raw_data) = ( pStringTable[ TableIndex ].
  76. VariableField );
  77. }
  78. if ( theString == strings[ StringIndex ] ) {
  79. /* we modify theString if it includes multiple mask values.
  80. So, this way we only increase the number of used arguments
  81. ONCE per actual argument. */
  82. cArgsUsed++;
  83. }
  84. if ( opt->flags & OPT_ENUM_IS_MASK ) {
  85. if ( moreComing ) {
  86. // check to see if the user input "xxx|yyy", or just "xxx|"
  87. ASSERT( StringLength > 0 );
  88. // theString[ StringLength ] == '|' or something.
  89. for ( theString += StringLength+1; // +1 to go past '|'
  90. theString != NULL ;
  91. theString ++ ) {
  92. if ( *theString == '\0' ) {
  93. OPTIONS_DEBUG( "Mask is of the form 'XXX|'\n" );
  94. // case = xxx| -- no more coming.
  95. theString = NULL; //
  96. break;
  97. }
  98. if ( isspace( *theString ) ) {
  99. continue;
  100. }
  101. OPTIONS_DEBUG( "nonspace character '%c' hit.\n"
  102. "mask component is of the form XXX|YYY.\n",
  103. *theString );
  104. break;
  105. }
  106. ASSERT( !theString || ( (*theString != '\0') &&
  107. !isspace(*theString) ) );
  108. break;
  109. } else { // !moreComing
  110. theString = NULL; // no more args in *this* string.
  111. /* check to see if the mask character is or is in the NEXT
  112. argument: "xxx" "|yyy" or "xxx" "|" "yyy" */
  113. if ( strings[ StringIndex+1 ] ) {
  114. if ( IsMaskChar( strings[ StringIndex+1 ][0] ) ) {
  115. moreComing = TRUE;
  116. if ( strings[ StringIndex+1 ][1] == '\0' ) {
  117. // xxx | yyy
  118. cArgsUsed++;
  119. StringIndex++;
  120. } else {
  121. // xxx |yyy
  122. strings[ StringIndex +1 ]++;
  123. }
  124. }
  125. } // strings[ StringIndex +1 ]
  126. } // !moreComing
  127. break; // found what we wanted. stop checking the table.
  128. } else { // !OPT_ENUM_IS_MASK
  129. // found the only argument we were expecting. Just return.
  130. *pcArgsUsed = cArgsUsed;
  131. return TRUE;
  132. } // moreComing check
  133. } // for each table entry
  134. } while ( ( theString != NULL ) && wasFound );
  135. if ( !wasFound ) { // option was not recognized.
  136. fprintf( stderr,
  137. "%s: enum value '%s' is not known.\n",
  138. opt->cmd, strings[ StringIndex ] );
  139. break;
  140. }
  141. }
  142. #else
  143. for( index = 0 ; pStringTable[index].UserField != NULL; index++ ) {
  144. if ( STRCASECMP( pStringTable[index].UserField, string ) == 0 ) {
  145. // found a match!
  146. *(POPTU_CAST( *opt )->raw_data) = pStringTable[index].VariableField;
  147. OPTIONS_DEBUG( "Enum resolves to #%d, \"%s\" = 0x%x \n",
  148. index,
  149. pStringTable[index].DescriptionField,
  150. pStringTable[index].VariableField );
  151. return TRUE;
  152. }
  153. }
  154. #endif
  155. if ( wasFound ) {
  156. *pcArgsUsed = cArgsUsed;
  157. } else {
  158. fprintf( stderr, "Error: argument for option \"%hs\" must be %s:\n",
  159. opt->cmd,
  160. ( opt->flags & OPT_ENUM_IS_MASK ) ?
  161. "one or more of the\n following, separated by '|' or ','" :
  162. "one of the following values" );
  163. PrintEnumValues( stderr, "", pStringTable );
  164. }
  165. return wasFound;
  166. }