main.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,316 行 · 第 1/3 页
C
1,316 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: WASM top level module + command line parser
*
****************************************************************************/
#include "asmglob.h"
#include <fcntl.h>
#include <unistd.h>
#ifdef __WATCOMC__
#include <process.h>
#endif
#include <ctype.h>
#include "asmalloc.h"
#include "asmins.h"
#include "fatal.h"
#include "asmdefs.h"
#include "asmexpnd.h"
#include "objprs.h"
#include "genmsomf.h"
#include "directiv.h"
#include "womputil.h"
#include "swchar.h"
#include "asminput.h"
#include "asmerr.h"
#ifdef __OSI__
#include "ostype.h"
#endif
extern void Fatal( unsigned msg, ... );
extern void ObjRecInit( void );
extern void DelErrFile( void );
extern void PrintfUsage( int first_ln );
extern void MsgPrintf1( int resourceid, char *token );
extern const char *FingerMsg[];
File_Info AsmFiles; // files information
pobj_state pobjState; // object file information for WOMP
struct option {
char *option;
unsigned value;
void (*function)( void );
};
static struct SWData {
bool register_conventions;
bool protect_mode;
int cpu;
int fpu;
} SWData = {
TRUE, // register conventions
FALSE, // real mode CPU instructions set
0, // default CPU 8086
-1 // unspecified FPU
};
#define MAX_NESTING 15
#define BUF_SIZE 512
static char ParamBuf[ BUF_SIZE ];
static unsigned char SwitchChar;
static unsigned OptValue;
static char *OptScanPtr;
static char *OptParm;
static char *ForceInclude = NULL;
global_options Options = {
/* sign_value */ FALSE,
/* stop_at_end */ FALSE,
/* quiet */ FALSE,
/* banner_printed */ FALSE,
/* debug_flag */ FALSE,
/* naming_convention*/ ADD_USCORES,
/* floating_point */ DO_FP_EMULATION,
/* output_comment_data_in_code_records */ TRUE,
/* error_count */ 0,
/* warning_count */ 0,
/* error_limit */ 20,
/* warning_level */ 2,
/* warning_error */ FALSE,
/* build_target */ NULL,
/* code_class */ NULL,
/* data_seg */ NULL,
/* text_seg */ NULL,
/* module_name */ NULL,
#ifdef DEBUG_OUT
/* debug */ FALSE,
#endif
/* default_name_mangler */ NULL,
/* allow_c_octals */ FALSE,
/* emit_dependencies */ TRUE,
/* Watcom C name mangler */ TRUE,
/* stdcall at number */ TRUE,
/* mangle stdcall */ TRUE
};
static char *CopyOfParm( void )
/*****************************/
{
unsigned len;
len = OptScanPtr - OptParm;
memcpy( ParamBuf, OptParm, len );
ParamBuf[ len ] = '\0';
return( ParamBuf );
}
static void StripQuotes( char *fname )
/************************************/
{
char *s;
char *d;
if( *fname == '"' ) {
// string will shrink so we can reduce in place
d = fname;
for( s = d + 1; *s && *s != '"'; ++s ) {
// collapse double backslashes, only then look for escaped quotes
if( s[0] == '\\' && s[1] == '\\' ) {
++s;
} else if( s[0] == '\\' && s[1] == '"' ) {
++s;
}
*d++ = *s;
}
*d = '\0';
}
}
static char *GetAFileName( void )
/*******************************/
{
char *fname;
fname = CopyOfParm();
StripQuotes( fname );
return( fname );
}
static void SetTargName( char *name, unsigned len )
/*************************************************/
{
char *p;
if( Options.build_target != NULL ) {
AsmFree( Options.build_target );
Options.build_target = NULL;
}
if( name == NULL || len == 0 )
return;
Options.build_target = AsmAlloc( len + 1 );
p = Options.build_target;
while( len != 0 ) {
*p++ = toupper( *name++ );
--len;
}
*p++ = '\0';
}
static void SetCPUPMC( void )
/***************************/
{
char *tmp;
for( tmp=OptParm; tmp < OptScanPtr; tmp++ ) {
if( *tmp == 'p' ) {
if( SWData.cpu >= 2 ) { // set protected mode
SWData.protect_mode = TRUE;
} else {
MsgPrintf1( MSG_CPU_OPTION_INVALID, CopyOfParm() );
}
} else if( *tmp == 'r' ) {
if( SWData.cpu >= 3 ) { // set register calling convention
SWData.register_conventions = TRUE;
} else {
MsgPrintf1( MSG_CPU_OPTION_INVALID, CopyOfParm() );
}
} else if( *tmp == 's' ) {
if( SWData.cpu >= 3 ) { // set stack calling convention
SWData.register_conventions = FALSE;
} else {
MsgPrintf1( MSG_CPU_OPTION_INVALID, CopyOfParm() );
}
} else if( *tmp == '"' ) { // set default mangler
char *dest;
tmp++;
dest = strchr(tmp, '"');
if( Options.default_name_mangler != NULL ) {
AsmFree( Options.default_name_mangler );
}
Options.default_name_mangler = AsmAlloc( dest - tmp + 1 );
dest = Options.default_name_mangler;
for( ; *tmp != '"'; dest++, tmp++ ) {
*dest = *tmp;
}
*dest = NULLC;
} else {
MsgPrintf1( MSG_UNKNOWN_OPTION, CopyOfParm() );
exit( 1 );
}
}
if( SWData.cpu < 2 ) {
SWData.protect_mode = FALSE;
SWData.register_conventions = TRUE;
} else if( SWData.cpu < 3 ) {
SWData.register_conventions = TRUE;
}
}
static void SetCPU( void )
/************************/
{
SWData.cpu = OptValue;
SetCPUPMC();
}
static void SetFPU( void )
/************************/
{
switch( OptValue ) {
case 'i':
Options.floating_point = DO_FP_EMULATION;
break;
case '7':
Options.floating_point = NO_FP_EMULATION;
break;
case 'c':
Options.floating_point = NO_FP_ALLOWED;
break;
case 0:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
SWData.fpu = OptValue;
break;
}
}
static char memory_model = 0;
static void SetMM( void )
/***********************/
{
char buffer[20];
switch( OptValue ) {
case 'c':
case 'f':
case 'h':
case 'l':
case 'm':
case 's':
case 't':
break;
default:
strcpy( buffer, "/m" );
strcat( buffer, (char *)&OptValue );
MsgPrintf1( MSG_UNKNOWN_OPTION, buffer );
exit( 1 );
}
memory_model = OptValue;
}
static void SetMemoryModel( void )
/********************************/
{
char buffer[20];
char *model;
switch( memory_model ) {
case 'c':
model = "COMPACT";
break;
case 'f':
model = "FLAT";
break;
case 'h':
model = "HUGE";
break;
case 'l':
model = "LARGE";
break;
case 'm':
model = "MEDIUM";
break;
case 's':
model = "SMALL";
break;
case 't':
model = "TINY";
break;
default:
return;
}
strcpy( buffer, ".MODEL " );
strcat( buffer, model );
InputQueueLine( buffer );
}
static int isvalidident( char *id )
/*********************************/
{
char *s;
char lwr_char;
if( isdigit( *id ) )
return( ERROR ); /* can't start with a number */
for( s = id; *s != '\0'; s++ ) {
lwr_char = tolower( *s );
if( !( lwr_char == '_' || lwr_char == '.' || lwr_char == '$'
|| lwr_char == '@' || lwr_char == '?'
|| isdigit( lwr_char )
|| islower( lwr_char ) ) ) {
return( ERROR );
}
}
return( NOT_ERROR );
}
static void add_constant( char *string )
/**************************************/
{
char *tmp;
char *one = "1";
tmp = strchr( string, '=' );
if( tmp == NULL ) {
tmp = strchr( string, '#' );
if( tmp == NULL ) {
tmp = one;
} else {
*tmp = '\0';
tmp++;
}
} else {
*tmp = '\0';
tmp++;
}
if( isvalidident( string ) == ERROR ) {
AsmError( SYNTAX_ERROR ); // fixme
return;
}
StoreConstant( string, tmp, FALSE ); // don't allow it to be redef'd
}
static void get_fname( char *token, int type )
/********************************************/
/*
* figure out the source file name & store it in AsmFiles
* fill in default object file name if it is null
*/
{
char *def_drive, *def_dir, *def_fname, *def_ext;
char *drive, *dir, *fname, *ext;
char buffer[ _MAX_PATH2 ];
char buffer2[ _MAX_PATH2 ];
char name [ _MAX_PATH ];
char msgbuf[80];
/* get filename for source file */
if( type == ASM ) {
if( token == NULL ) {
MsgGet( SOURCE_FILE, msgbuf );
Fatal( MSG_CANNOT_OPEN_FILE, msgbuf );
}
if( AsmFiles.fname[ASM] != NULL ) {
Fatal( MSG_TOO_MANY_FILES );
}
_splitpath2( token, buffer, &drive, &dir, &fname, &ext );
if( *ext == '\0' ) {
ext = ASM_EXT;
}
_makepath( name, drive, dir, fname, ext );
AsmFiles.fname[ASM] = AsmAlloc( strlen( name ) + 1 );
strcpy( AsmFiles.fname[ASM], name );
_makepath( name, drive, dir, NULL, NULL );
/* add the source path to the include path */
AddStringToIncludePath( name );
if( AsmFiles.fname[OBJ] == NULL ) {
/* set up default object and error filename */
ext = OBJ_EXT;
_makepath( name, NULL, NULL, fname, ext );
} else {
_splitpath2( AsmFiles.fname[OBJ], buffer2, &def_drive,
&def_dir, &def_fname, &def_ext );
if( *def_fname == NULLC )
def_fname = fname;
if( *def_ext == NULLC )
def_ext = OBJ_EXT;
_makepath( name, def_drive, def_dir, def_fname, def_ext );
AsmFree( AsmFiles.fname[OBJ] );
}
AsmFiles.fname[OBJ] = AsmAlloc( strlen( name ) + 1 );
strcpy( AsmFiles.fname[OBJ], name );
if( AsmFiles.fname[ERR] == NULL ) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?