wcl.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,055 行 · 第 1/3 页
C
1,055 行
++list;
}
}
}
static char *ScanFName( char *end, int len )
/******************************************/
{
for( ;; ) { /* 15-jan-89: Allow switch char in filenames */
if( *end == '\0' ) break;
if( *end == ' ' ) break;
if( *end == '\t' ) break; /* 16-mar-91 */
Word[ len ] = *end;
++len;
++end;
}
Word[ len ] = NULLCHAR;
return( end );
}
static int FileExtension( char *p, char *ext )
/********************************************/
{
char unquoted[_MAX_PATH];
char *dot;
/* Remove quoted from filename to make it easier to compare extension.
* We are here assuming that filename comes with quotes or doesn't need them.
*/
UnquoteFName( unquoted, sizeof( unquoted ), p );
p = unquoted;
dot = NULL;
while( *p != '\0' ) {
if( *p == '.' ) {
dot = p;
}
++p;
}
if( dot != NULL ) {
if( stricmp( dot, ext ) == 0 ) {
return( 1 ); // indicate file extension matches
}
}
return( 0 ); // indicate no match
}
static void AddDirective( int len )
/*********************************/
{
struct directives *p;
struct directives *p2;
p = MemAlloc( sizeof( struct directives ) );
p->next = NULL;
p->directive = MemAlloc( len + 1 );
UnquoteFName( p->directive, len + 1, Word );
if( Directive_List == NULL ) {
Directive_List = p;
} else {
p2 = Directive_List;
while( p2->next != NULL ) {
p2 = p2->next;
}
p2->next = p;
}
}
static int Parse( char *Cmd )
/***************************/
{
char opt;
char *end;
FILE *atfp;
char buffer[_MAX_PATH];
char unquoted[_MAX_PATH];
int len;
char *p;
int wcc_option;
Conventions = 'r';
/* Cmd will always begin with at least one */
/* non-space character if we get this far */
for( ;; ) {
Cmd = SkipSpaces( Cmd );
if( *Cmd == NULLCHAR ) 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 ] = NULLCHAR;
end = ScanFName( end, len );
if( FileExtension( Word, ".lib" ) ) {
strcat( Libs, Libs[0] != '\0' ? "," : " " );
/* remove quotes and change them to be compatible with wlink */
UnquoteFName( unquoted, sizeof( unquoted ), Word );
BuildQuotedFName( Word, MAX_CMD, "", unquoted, "'" );
strcat( Libs, Word );
} else if( FileExtension( Word, ".res" ) ) {
strcat( Resources, Word );
strcat( Resources, " " );
} else {
strcat( Files, Word );
strcat( Files, " " );
}
} else { /* otherwise, do option */
--len;
strncpy( Word, Cmd + 1, len );
Word[ len ] = NULLCHAR;
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;
SystemName = strdup( Word+3 );
wcc_option = 0;
}
break;
case 'f': /* files option */
end = ScanFName( end, len );
switch( tolower( Word[0] ) ) {
case 'd': /* name of linker directive file */
Link_Name = "__WCL__.LNK";
if( Word[1] == '=' || Word[1] == '#' ) {
/* remove quotes from target linker control filename */
UnquoteFName( unquoted, sizeof( unquoted ), Word + 2 );
MakeName( unquoted, ".lnk" ); /* add extension */
free( Link_Name );
Link_Name = strdup( unquoted );
}
wcc_option = 0;
break;
case 'e': /* name of exe file */
if( Word[1] == '=' || Word[1] == '#' ) {
/* 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 */
break;
case 'm': /* name of map file */
Flags.map_wanted = TRUE;
if( Word[1] == '=' || Word[1] == '#' ) {
/* remove quotes from target map filename */
UnquoteFName( unquoted, sizeof( unquoted ), Word + 2 );
free( Map_Name );
Map_Name = strdup( unquoted );
}
wcc_option = 0;
break;
case 'o': /* name of object file */
/* 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 );
free( Obj_Name );
Obj_Name = strdup( unquoted );
break;
#if defined( WCLI86 ) || defined( WCL386 )
case 'p': /* floating-point option */
if( tolower( Word[1] ) == 'c' ) {
Flags.math_8087 = 0;
}
break;
#endif
default:
break;
}
break;
case 'k': /* stack size option */
if( Word[0] != '\0' ) {
StackSize = strdup( 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;
SystemName = strdup( 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 ) *p = NULLCHAR;
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;
}
/* fall through */
case 'y':
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
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?