/*++ UTEST.C Test program for the options subsystem. Must compile under NT and UNIX Created, 5/24/1997 by DavidCHR --*/ #include "private.h" optEnumStruct enums[] = { { "one", (PVOID) 1, "should end up 1" }, { "two", (PVOID) 2, "should end up 2" }, { "beef", (PVOID)(UINT_PTR)(UINT) 0xdeadbeef, "should be 0xdeadbeef" }, { "beefs", (PVOID)(UINT_PTR)(UINT) 0xbadf00d, "should be 0xbadf00d" }, { "secret", (PVOID) 60, }, // shouldn't show in help TERMINATE_ARRAY }; ULONG enumTestVariable=0; PCHAR SubString = NULL; optionStruct substructOptions[] = { { "h", NULL, OPT_HELP }, { "substr", &SubString, OPT_STRING, "Substring option" }, TERMINATE_ARRAY }; PCHAR FuncString1 = NULL; PCHAR FuncString2 = NULL; PCHAR StringOption = NULL; int IntegerOption = 0L; BOOL BooleanOption = FALSE; float FloatOption = 0.0; PCHAR UndocumentedString = NULL; PWCHAR WideCharOption = NULL; UNICODE_STRING UnicodeStringOption = { 0 }; int MyOptFunc( IN int argc, IN PCHAR *argv ); BOOL MyOptFunc2( IN BOOL fHelp, IN POPT_FUNC_PARAMETER_DATA pData ); optionStruct sampleOptions[ ] = { { "help", NULL, OPT_HELP }, { "?", NULL, OPT_HELP }, { NULL, NULL, OPT_DUMMY, "-----------------------------" }, { NULL, NULL, OPT_CONTINUE, "These are the useful options:" }, { NULL, NULL, OPT_DUMMY, "-----------------------------" }, { "enum", &enumTestVariable, OPT_ENUMERATED, "Test enumerated type", enums }, { "mask", &enumTestVariable, OPT_ENUMERATED | OPT_ENUM_IS_MASK, "Test enumerated type with OPT_ENUM_IS_MASK", enums }, { "substruct", substructOptions, OPT_SUBOPTION | OPT_RECURSE, "substruct:help for help" }, { "recurse", sampleOptions, OPT_SUBOPTION, "recurse:help for help" }, { "string", &StringOption, OPT_STRING | OPT_ENVIRONMENT, "String Option", "StringOption" }, { NULL, NULL, OPT_CONTINUE, "Use this option to request a string" }, { "int", &IntegerOption, OPT_INT | OPT_ENVIRONMENT, "integer option", "IntegerOption" }, { NULL, NULL, OPT_CONTINUE, "Use this option to request an integer" }, { "func", MyOptFunc, OPT_FUNC, "function option" }, { NULL, NULL, OPT_CONTINUE, "Use this option to request two strings" }, { "func2", &IntegerOption, OPT_FUNC2, "FUNC2 option", MyOptFunc2 }, { "bool", &BooleanOption, OPT_BOOL, "boolean option" }, { NULL, NULL, OPT_CONTINUE, "Use this option to request a boolean" }, { "float", &FloatOption, OPT_FLOAT, "floating point option" }, { NULL, NULL, OPT_CONTINUE, "Use this option to request a float" }, { "wstring",&WideCharOption, OPT_WSTRING | OPT_ENVIRONMENT, "Wide Char String option", "WideCharOption" }, { "ustring",&UnicodeStringOption, OPT_USTRING | OPT_ENVIRONMENT, "Unicode String Option", "UnicodeStringOption" }, { "hidden", &UndocumentedString, OPT_STRING | OPT_HIDDEN, "you should never see this line. This option is OPT_HIDDEN" }, { "stop", NULL, OPT_STOP_PARSING, "halts parsing of the command line." }, { NULL, NULL, OPT_DUMMY | OPT_NOHEADER, "" }, { NULL, NULL, OPT_DUMMY | OPT_NOHEADER, "Example: utest /string \"foo bar baz\" /int 0x15 +bool /float 3.14" }, { NULL, NULL, OPT_PAUSE }, TERMINATE_ARRAY }; int MyOptFunc( int argc, PCHAR *argv ) { if ( ( argv == NULL ) || (argc < 3 ) ) { /* this means the user requested help */ fprintf( stderr, "func [string1] [string2]\n" ); return 0; } printf( "MyOptFunc was called. argc=%d.\n", argc ); FuncString1 = argv[1]; FuncString2 = argv[2]; return 3; /* number of arguments eaten-- -func argv[1] argv[2] == 3 options */ } VOID DumpArgs( int argc, PCHAR argv[] ) { int i; for ( i = 0 ; i < argc ; i++ ) { fprintf( stderr, "arg %d = %s\n", i, argv[i] ); } } BOOL MyOptFunc2( IN BOOL fHelp, IN POPT_FUNC_PARAMETER_DATA pData ) { #if OPT_FUNC_PARAMETER_VERSION != 1 #error "OptFuncParameterVersion has changed. Update this function." #endif optionStruct OptFunc2Options[] = { { "help", NULL, OPT_HELP }, { "FuncString1", &FuncString1, OPT_INT }, { "FuncString2", &FuncString2, OPT_INT }, { "recurse", sampleOptions, OPT_SUBOPTION, "points back to the toplevel structure. Very amusing. :-)" }, { "STOP", NULL, OPT_STOP_PARSING, "halts parsing within the Func2." }, TERMINATE_ARRAY }; if ( fHelp ) { CHAR buffer[ 255 ]; PrintUsageEntry( stderr, "[-/+]", // switch characters pData->argv[0], // command GUARANTEED TO EXIST "->", // separator "Exercises the OPT_FUNC2 interface. Options follow", FALSE ); // FALSE--> do not repeat switch. sprintf( buffer, "-> options %s takes ", pData->argv[0] ); PrintUsageEntry( stderr, NULL, NULL, "-=", // the NULLs will fill with this string. buffer, TRUE ); sprintf( buffer, "(%s) ", pData->argv[0] ); PrintUsage( stderr, 0L, // flags OptFunc2Options, buffer ); PrintUsageEntry( stderr, NULL, NULL, "-*", "-> (end of OPT_FUNC2 options)", TRUE ); return TRUE; } else { if ( pData->optionVersion != OPT_FUNC_PARAMETER_VERSION ) { fprintf( stderr, "WARNING: option library out of sync with header\n" ); } fprintf( stderr, "MyOptFunc2 called. Data follows:\n" "pData->optionVersion = %d\n" "pData->dataField = 0x%p\n" "pData->argc = %d\n" "pData->argv = 0x%p\n" "pData->optionFlags = 0x%x\n" "pData->pSaveQueue = 0x%p\n", pData->optionVersion, pData->dataFieldPointer, pData->argc, pData->argv, pData->optionFlags, pData->pSaveQueue ); fprintf( stderr, "%s arguments are:\n", pData->argv[0] ); DumpArgs( pData->argc, pData->argv ); if ( ParseOptionsEx( pData->argc-1, pData->argv+1, OptFunc2Options, pData->optionFlags, &pData->pSaveQueue, &pData->argsused, &pData->argv ) ) { fprintf( stderr, "pData->argsused IN = %d\n", pData->argsused ); pData->argsused = pData->argc - pData->argsused; fprintf( stderr, "pData->argsused OUT = %d\n", pData->argsused ); } else return FALSE; } fprintf( stderr, "\n Leaving OPT_FUNC2. \n\n" ); return TRUE; } int __cdecl main( int argc, char *argv[] ) { BOOL foo; PVOID pCleanup = NULL; optEnumStruct parserOptions[] = { { "skip", (PVOID) OPT_FLAG_SKIP_UNKNOWNS, "OPT_FLAG_SKIP_UNKNOWNS" }, { "reassemble", (PVOID) OPT_FLAG_REASSEMBLE, "OPT_FLAG_REASSEMBLE" }, { "terminate", (PVOID) OPT_FLAG_TERMINATE, "OPT_FLAG_TERMINATE" }, TERMINATE_ARRAY }; ULONG ParserFlag = OPT_FLAG_REASSEMBLE; #ifndef DEBUG_OPTIONS BOOL DebugFlag = 0; // will be ignored... just here for convenience #endif optionStruct singleOption[] = { { "utestHelp", NULL, OPT_HELP }, { "parserFlag", &ParserFlag, OPT_ENUMERATED, "flags to pass to ParseOptionsEx", parserOptions }, { "headerlength", &OptMaxHeaderLength, OPT_INT, "OptMaxHeaderLength value (formatting)" }, { "commandLength", &OptMaxCommandLength, OPT_INT, "OptMaxCommandLength value (formatting)" }, { "separatorLength", &OptMaxSeparatorLength, OPT_INT, "OptMaxSeparatorLength value (formatting)" }, { "descriptionLength", &OptMaxDescriptionLength, OPT_INT, "OptMaxDescriptionLength value (formatting)" }, { "debug", &DebugFlag, OPT_INT, "Debugger status" }, TERMINATE_ARRAY }; DebugFlag |= OPTION_DEBUGGING_LEVEL; foo = ParseOptionsEx( argc-1, argv+1, singleOption, 0, &pCleanup, &argc, &argv ); ParserFlag |= OPT_FLAG_MEMORYLIST_OK; fprintf( stderr, "first ParseOptionsEx returned 0x%x \n" " saveQueue 0x%p \n" " passing in flags 0x%x \n", foo, pCleanup, ParserFlag ); if ( argc ) { ULONG i; fprintf( stderr, "%d new options: \n", argc ); DumpArgs( argc, argv ); fprintf( stderr, "\n" ); } foo = ParseOptionsEx( argc, argv, sampleOptions, ParserFlag, &pCleanup, &argc, &argv ); fprintf( stderr, "ParseOptionsEx returns %d\n" " new argv = 0x%p\n" " new argc = %d \n", foo, argv, argc ); DumpArgs( argc, argv ); printf( "Formatting values were:\n" "\tOptMaxHeaderLength = %d\n" "\tOptMaxCommandLength = %d\n" "\tOptMaxSeparatorLength = %d\n" "\tOptMaxDescriptionLength = %d\n", OptMaxHeaderLength, OptMaxCommandLength, OptMaxSeparatorLength, OptMaxDescriptionLength ); printf( "\nOptions used:\n" "\tstring = \"%hs\"\n" "\tint = %d \n" "\tBool = 0x%x \n" /* "Float = %f \n" */ "\twstring = L\"%ws\"\n" "\tustring = (unicode string) %wZ \n" "\thidden = \"%hs\"\n" "\tsubstruct:substr = \"%hs\"\n" "\tfuncString1 = \"%hs\"\n" "\tfuncString2 = \"%hs\"\n" "\tenum = %d (0x%x)\n", StringOption, IntegerOption, BooleanOption, /* FloatOption, */ /* floating point not loaded? What does that mean?! */ WideCharOption, &UnicodeStringOption, UndocumentedString, SubString, FuncString1, FuncString2, enumTestVariable, enumTestVariable ); CleanupOptionDataEx( pCleanup ); return foo; }