/*++ SUBLIST.C Code for parsing a suboption list DavidCHR 6/6/1997 --*/ #include "private.h" /* ParseSublist: Handler code for parsing a sublist entry. */ BOOL ParseSublist( POPTU Option, PCHAR *argv, int argc, int theIndex, int *argsused, ULONG flags, PBOOL pbDoneParsing, PSAVEQUEUE pQueue ) { PCHAR TheOption; ULONG i; ASSERT( Option != NULL ); ASSERT( argv != NULL ); ASSERT( argc != 0 ); ASSERT( theIndex < argc ); OPTIONS_DEBUG( "ParseSublist: Option = 0x%x, argv=0x%x, " "argc=%d, theIndex=%d", Option, argv, argc, theIndex ); TheOption = argv[ theIndex ]; OPTIONS_DEBUG( "TheOption = [%d] %s... ", theIndex, TheOption ); for ( i = 0 ; TheOption[i] != ':' ; i++ ) { if ( TheOption[i] == '\0' ) { fprintf( stderr, "ParseOptions: %s should be of the form " "%s:option (:option:option...)\n", TheOption, TheOption ); return FALSE; } } ASSERT( TheOption[i] == ':' ); /* algorithm check */ if ( !ISSWITCH( TheOption[0] ) ) { /* The easy side-- just send the argc and argv structure in, MANGLING the first option */ /* we do not deal with pbStopParsing in this branch, because it seems somehow unlikely that deep down in a nested substructure, someone would bury an option like this: opt:foo:bar:baz:terminate to stop the toplevel parser. */ OPTIONS_DEBUG( "ISSWITCH: easy case (%c is not a switch)", TheOption[0] ); ASSERT( argv[ theIndex ][i] == ':' ); argv[ theIndex ] += i+1; ASSERT( argv[ theIndex ][0] != ':' ); return ParseOptionsEx( argc-theIndex, argv+theIndex, Option->optStruct, flags | OPT_FLAG_MEMORYLIST_OK, &pQueue, NULL, NULL ); } else { /* The Hard part-- create a new vector of argv, pointing the first at the local buffer. Since the first buffer PROBABLY won't be used as a string (NOTE: if it's OPT_DEFAULT, it could be), it's safe to use this on the stack. */ PCHAR *newargv; ULONG j; ULONG total; /* total elements in the new list */ CHAR LocalBuffer[ 255 ]; BOOL ret; int tmp; OPTIONS_DEBUG( "Hard case (%c is a switch): ", TheOption[0] ); sprintf( LocalBuffer, "%c%s", TheOption[0], TheOption+i+1 ); OPTIONS_DEBUG( "LocalBuffer = %s\n", LocalBuffer ); total = argc - theIndex ; /* 2? */ newargv = malloc( total * sizeof(PCHAR) ); if (!newargv) { fprintf(stderr, "Failed to allocate memory in ParseOptions\n"); return 0; } newargv[0] = LocalBuffer; for( j = 1 ; j < total ; j++ ) { OPTIONS_DEBUG( "j == %d, total == %d\n", j, total ); ASSERT( argv[j] != NULL ); ASSERT( (int)(j+theIndex) < argc ); newargv[j] = argv[j+theIndex ]; OPTIONS_DEBUG( "assign [%d] %s --> [%d] %s\n", j+theIndex, argv[j+theIndex], j, newargv[j] ); } ret = ParseOneOption( total, newargv, 0 /* parse the first option */, flags, Option->optStruct, argsused, pbDoneParsing, pQueue ); free( newargv ); OPTIONS_DEBUG( "done. returning %d...\n", ret ); return ret; } }