void HandleArgs( char *cmd ) { char * ptr; bool list_file = FALSE; DFormat |= DFF_PSEUDO | DFF_SYMBOLIC_REG; cmd = skipBlanks( cmd ); if( *cmd == '\0' || *cmd == '?' ) { printUsage( 0 ); } else { while( *cmd ) { if( IS_OPT_DELIM( *cmd ) ) { cmd++; switch( tolower( *cmd ) ) { case 'a': DFormat |= DFF_ASM; if( cmd[1] == 'u' ) { ++cmd; DFormat |= DFF_X86_UNIX; } break; case 'e': Options |= PRINT_EXTERNS; break; case 'i': cmd++; if( *cmd == '=' ) { cmd++; if( !isspace( *cmd ) ) { LabelChar = toupper( *cmd ); } else { printUsage( INVALID_I ); } } else { printUsage( INVALID_I ); } break; case 'l': if( ListFileName ) { printUsage( ONLY_ONE_LISTING ); } list_file = TRUE; cmd++; if( *cmd == '=' ) { cmd++; ptr = cmd; cmd = FindNextWS( cmd ); ListFileName = getFileName( ptr, cmd ); } break; case 'f': switch( cmd[1] ) { case 'p': DFormat ^= DFF_PSEUDO; ++cmd; break; case 'r': DFormat ^= DFF_SYMBOLIC_REG; ++cmd; break; case 'f': Options |= PRINT_FPU_EMU_FIXUP; break; case 'i': DFormat ^= DFF_X86_ALT_INDEXING; ++cmd; break; case 'u': ++cmd; switch( cmd[1] ) { case 'r': DFormat ^= DFF_REG_UP; ++cmd; break; case 'i': DFormat ^= DFF_INS_UP; ++cmd; break; default: DFormat ^= DFF_INS_UP | DFF_REG_UP; } break; } break; case 'm': if( cmd[1] == 'w' ) { Options |= METAWARE_COMPATIBLE; ++cmd; break; } Options |= NODEMANGLE_NAMES; break; case 'p': Options |= PRINT_PUBLICS; break; case 's': if( SourceFileName ) { printUsage( ONLY_ONE_SOURCE ); } source_mix = TRUE; cmd++; if( *cmd == '=' ) { cmd++; ptr = cmd; cmd = FindNextWS( cmd ); SourceFileName = getFileName( ptr, cmd ); } break; default: BufferMsg( INVALID_OPTION ); BufferStore( " -%c\n\n", *cmd ); BufferPrint(); printUsage( 0 ); break; } } else { if( ObjFileName ) { printUsage( ONLY_ONE_OBJECT ); } ptr = cmd; cmd = FindNextWS( cmd ); ObjFileName = getFileName( ptr, cmd ); } cmd = skipToNextArg( cmd ); } } if( !ObjFileName ) { printUsage( NO_OBJECT ); } composeFileNames( list_file ); if( DFormat & DFF_ASM ) { Options &= ~(PRINT_PUBLICS | PRINT_EXTERNS); } }
static int Parse( char *Cmd ) /***************************/ { char opt; char *end; FILE *atfp; char buffer[_MAX_PATH]; char unquoted[_MAX_PATH]; size_t len; char *p; int wcc_option; list *new_item; /* Cmd will always begin with at least one */ /* non-space character if we get this far */ for( ;; ) { Cmd = SkipSpaces( Cmd ); if( *Cmd == '\0' ) break; opt = *Cmd; if( opt == '-' || opt == Switch_Chars[1] ) { Cmd++; } else if( opt != '@' ) { opt = ' '; } end = Cmd; if( *Cmd == '"' ) { end = FindNextWS( end ); } else { end = FindNextWSOrOpt( end, opt, Switch_Chars ); } len = end - Cmd; if( len != 0 ) { if( opt == ' ' ) { /* if filename, add to list */ strncpy( Word, Cmd, len ); Word[len] = '\0'; end = ScanFName( end, len ); UnquoteFName( unquoted, sizeof( unquoted ), Word ); new_item = MemAlloc( sizeof( list ) ); new_item->next = NULL; new_item->item = MemStrDup( unquoted ); if( FileExtension( Word, ".lib" ) ) { ListAppend( &Libs_List, new_item ); } else if( FileExtension( Word, ".res" ) ) { ListAppend( &Res_List, new_item ); } else { ListAppend( &Files_List, new_item ); } } else { /* otherwise, do option */ --len; strncpy( Word, Cmd + 1, len ); Word[len] = '\0'; wcc_option = 1; /* assume it's a wcc option */ switch( tolower( *Cmd ) ) { case 'b': /* possibly -bcl */ if( strnicmp( Word, "cl=", 3 ) == 0 ) { strcat( CC_Opts, " -bt=" ); strcat( CC_Opts, Word+3 ); Flags.link_for_sys = TRUE; MemFree( SystemName ); SystemName = MemStrDup( Word+3 ); wcc_option = 0; } break; case 'f': /* files option */ p = ScanFName( end, len ); switch( tolower( Word[0] ) ) { case 'd': /* name of linker directive file */ if( Word[1] == '=' || Word[1] == '#' ) { end = p; /* remove quotes from target linker control filename */ UnquoteFName( unquoted, sizeof( unquoted ), Word + 2 ); MakeName( unquoted, ".lnk" ); /* add extension */ MemFree( Link_Name ); Link_Name = MemStrDup( unquoted ); } else { MemFree( Link_Name ); Link_Name = MemStrDup( TEMPFILE ); } wcc_option = 0; break; case 'e': /* name of exe file */ if( Word[1] == '=' || Word[1] == '#' ) { end = p; /* remove quotes from target executable filename */ UnquoteFName( unquoted, sizeof( unquoted ), Word + 2 ); strcpy( Exe_Name, unquoted ); } wcc_option = 0; break; case 'i': /* name of forced include file */ end = p; break; case 'm': /* name of map file */ Flags.map_wanted = TRUE; if( Word[1] == '=' || Word[1] == '#' ) { end = p; /* remove quotes from target map filename */ UnquoteFName( unquoted, sizeof( unquoted ), Word + 2 ); MemFree( Map_Name ); Map_Name = MemStrDup( unquoted ); } wcc_option = 0; break; case 'o': /* name of object file */ end = p; /* parse off argument, so we get right filename in linker command file */ p = &Word[1]; if( Word[1] == '=' || Word[1] == '#' ) ++p; /* remove quotes from object name */ UnquoteFName( unquoted, sizeof( unquoted ), p ); MemFree( Obj_Name ); Obj_Name = MemStrDup( unquoted ); break; #if defined( WCLI86 ) || defined( WCL386 ) case 'p': /* floating-point option */ end = p; if( tolower( Word[1] ) == 'c' ) { Flags.math_8087 = 0; } break; #endif default: end = p; break; } break; case 'k': /* stack size option */ if( Word[0] != '\0' ) { MemFree( StackSize ); StackSize = MemStrDup( Word ); } wcc_option = 0; break; case 'l': /* link target option */ switch( (Word[1] << 8) | tolower( Word[0] ) ) { case 'p': Flags.link_for_dos = 0; Flags.link_for_os2 = TRUE; break; case 'r': Flags.link_for_dos = TRUE; Flags.link_for_os2 = 0; break; default: /* 10-jun-91 */ Flags.link_for_sys = TRUE; p = &Word[0]; if( Word[0] == '=' || Word[0] == '#' ) ++p; MemFree( SystemName ); SystemName = MemStrDup( p ); break; } wcc_option = 0; break; case 'x': if( Word[0] == '\0' ) { Flags.two_case = TRUE; wcc_option = 0; } break; case '@': if( Word[0] != '\0' ) { char const * const env = getenv( Word ); if( env != NULL ) { if( handle_environment_variable( env ) ) { return( 1 ); // Recursive call failed } via_environment = TRUE; Cmd = end; continue; } end = ScanFName( end, len ); /* remove quotes from additional linker options file */ UnquoteFName( unquoted, sizeof( unquoted ), Word ); strcpy( Word, unquoted ); MakeName( Word, ".lnk" ); errno = 0; if( (atfp = fopen( Word, "r" )) == NULL ) { PrintMsg( WclMsgs[UNABLE_TO_OPEN_DIRECTIVE_FILE], Word, strerror( errno ) ); return( 1 ); } while( fgets( buffer, sizeof( buffer ), atfp ) != NULL ) { if( strnicmp( buffer, "file ", 5 ) == 0 ) { /* look for names separated by ','s */ p = strchr( buffer, '\n' ); if( p != NULL ) *p = '\0'; AddName( &buffer[5], Fp ); Flags.do_link = TRUE; } else { fputs( buffer, Fp ); } } fclose( atfp ); } wcc_option = 0; break; /* compiler options that affect the linker */ #ifdef WCL386 case '3': case '4': case '5': /* 22-sep-92 */ Conventions = tolower( Word[0] ); break; #endif case 'd': if( DebugFlag == 0 ) { /* not set by -h yet */ if( strcmp( Word, "1" ) == 0 ) { DebugFlag = 1; } else if( strcmp( Word, "1+" ) == 0 ) { /* 02-mar-91 */ DebugFlag = 2; } else if( strcmp( Word, "2" ) == 0 ) { DebugFlag = 2; } else if( strcmp( Word, "2i" ) == 0 ) { DebugFlag = 2; } else if( strcmp( Word, "2s" ) == 0 ) { DebugFlag = 2; } else if( strcmp( Word, "3" ) == 0 ) { DebugFlag = 2; } else if( strcmp( Word, "3i" ) == 0 ) { DebugFlag = 2; } else if( strcmp( Word, "3s" ) == 0 ) { DebugFlag = 2; } } break; case 'h': if( strcmp( Word, "w" ) == 0 ) { DebugFlag = 3; } else if( strcmp( Word, "c" ) == 0 ) { /* 02-mar-91 */ Flags.do_cvpack = 1; DebugFlag = 4; } else if( strcmp( Word, "d" ) == 0 ) { DebugFlag = 5; } break; case 'i': /* include file path */ end = ScanFName( end, len ); break; case 'c': /* compile only */ if( stricmp( Word, "c" ) == 0 ) { Flags.force_c = TRUE; } else if( stricmp( Word, "c++" ) == 0 ) { Flags.force_c_plus = TRUE; } else { Flags.no_link = TRUE; } wcc_option = 0; break; case 'y': if( stricmp( Word, "x" ) == 0 ) { strcat( CC_Opts, " -x" ); wcc_option = 0; } else if( Word[0] == '\0' ) { wcc_option = 0; } break; #if defined( WCLI86 ) || defined( WCL386 ) case 'm': /* memory model */ if( Cmd[1] == 't' || Cmd[1] == 'T' ) { /* tiny model*/ Word[0] = 's'; /* change to small */ Flags.tiny_model = TRUE; } break; #endif case 'p': Flags.no_link = TRUE; break; /* this is a preprocessor option */ case 'q': Flags.be_quiet = TRUE; break; case 'z': /* 12-jan-89 */ switch( tolower( Cmd[1] ) ) { case 's': Flags.no_link = TRUE; break; case 'q': Flags.be_quiet = TRUE; break; #ifdef WCLI86 case 'w': Flags.windows = TRUE; #endif } break; case '"': /* 17-dec-91 */ /* As parameter passing to linker is a special case, we need to pass * whole command instead of first character removed. This allows us * to parse also string literals in AddDirective. */ wcc_option = 0; strncpy( Word, Cmd, ++len ); Word[len] = '\0'; AddDirective( len ); break; } /* don't add linker-specific options */ /* to compiler command line: */ if( wcc_option ) { len = strlen( CC_Opts ); CC_Opts[len++] = ' '; CC_Opts[len++] = opt; CC_Opts[len++] = *Cmd; /* keep original case */ CC_Opts[len] = '\0'; strcat( CC_Opts, Word ); } } Cmd = end; } } return( 0 ); }