ccmain.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,314 行 · 第 1/3 页
C
1,314 行
/****************************************************************************
*
* 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: C compiler top level driver module and file I/O.
*
****************************************************************************/
#include "cvars.h"
#include "iopath.h"
#include "scan.h"
#include "autodept.h"
#include <stdarg.h>
#include <stdio.h>
#ifdef __OSI__
#include "ostype.h"
#endif
#define BY_CLI
#include "feprotos.h"
#include "swchar.h"
#ifndef _MAX_PATH
#define _MAX_PATH (PATH_MAX + 1)
#endif
#ifndef _MAX_PATH2
#define _MAX_PATH2 (PATH_MAX + 4)
#endif
#if defined( __UNIX__ )
#define IS_PATH_SEP( ch ) ((ch) == '/')
#else
#define IS_PATH_SEP( ch ) ((ch) == '/' || (ch) == '\\')
#endif
#define MAX_INC_DEPTH 255
extern char CharSet[];
static char IsStdIn;
static int IncFileDepth;
int PrintWhiteSpace; // also refered from cmac2.c
// local function prototypes
static void DoCCompile( char **cmdline );
static void DelErrFile( void );
static void MakePgmName( void );
static int OpenFCB( FILE *fp, char *filename );
static bool IsFNameOnce( char const *filename );
static int TryOpen( char *prefix, char *separator, char *filename, char *suffix );
static void ParseInit( void );
static void CPP_Parse( void );
static int FCB_Alloc( FILE *fp, char *filename );
local void Parse( void );
static int OpenPgmFile( void );
static void DelDepFile( void );
void FrontEndInit( bool reuse )
//***************************//
// Do the once only things //
//***************************//
{
GlobalCompFlags.cc_reuse = reuse;
GlobalCompFlags.cc_first_use = TRUE;
}
void FrontEndFini( void )
//********************//
// Fini the once only //
//********************//
{
GlobalCompFlags.cc_reuse = FALSE;
GlobalCompFlags.cc_first_use = TRUE;
}
void ClearGlobals( void )
{
InitStats();
IsStdIn = 0;
FNames = NULL;
RDirNames = NULL;
SrcFile = NULL;
ErrFile = NULL;
DefFile = NULL;
CppFile = NULL;
DepFile = NULL;
SymLoc = NULL;
HFileList = NULL;
IncFileDepth = MAX_INC_DEPTH;
SegmentNum = FIRST_PRIVATE_SEGMENT;
BufSize = BUF_SIZE;
Buffer = CMemAlloc( BufSize );
TokenBuf = CMemAlloc( BufSize );
}
unsigned char _8087; /* 27-may-91 */
unsigned char _real87;
int FrontEnd( char **cmdline )
{
_real87 = _8087 = 0;/* set to 0 in case 8087 is present; 27-may-91 */
InitGlobalVars();
CMemInit();
InitMsg();
InitPurge();
SwitchChar = _dos_switch_char();
ClearGlobals();
DoCCompile( cmdline );
PurgeMemory();
FiniMsg();
CMemFini();
GlobalCompFlags.cc_first_use = FALSE;
return( ErrCount );
}
void CloseFiles( void )
{
if( CppFile != NULL ) {
fflush( CppFile );
if( ferror( CppFile ) ) {
char msgtxt[80];
char msgbuf[MAX_MSG_LEN];
/* issue message */
CGetMsg( msgtxt, ERR_FATAL_ERROR );
sprintf( msgbuf, msgtxt, strerror( errno ) );
NoteMsg( msgbuf );
}
fclose( CppFile );
CppFile = NULL;
}
if( ErrFile != NULL ) {
fclose( ErrFile );
ErrFile = NULL;
if( ! CompFlags.errfile_written ) {
DelErrFile();
}
}
if( DefFile != NULL ) {
fclose( DefFile );
DefFile = NULL;
}
if( ErrFile != NULL ) {
fclose( ErrFile );
ErrFile = NULL;
}
}
static bool ParseCmdLine( char **cmdline )
{
char *cmd;
cmd = (cmdline == NULL) ? "" : cmdline[0]; // from cpp.c
if( cmd == NULL ) { // argv == 1
cmd = "";
}
while( *cmd == ' ' ) ++cmd; /* 13-mar-90 */
if( *cmd == '?' || *cmd == '\0' ) {
CBanner();
CCusage();
return( FALSE );
}
GenCOptions( cmdline );
FESetCurInc();
if( WholeFName != NULL ) {
MakePgmName( );
OpenPgmFile();
MainSrcFile = SrcFile; /* 05-jan-94 */
}
return( TRUE );
}
void OpenDepFile( void )
{
char *name;
if( CompFlags.generate_auto_depend ) { /* 15-dec-88 */
name = DepFileName();
if( name != NULL ) {
DepFile = fopen( name, "w" );
if( DepFile != NULL ) {
setvbuf( DepFile, CPermAlloc( 1024 ), _IOFBF, 1024 );
}
}
}
}
char *ForceSlash( char *name, char slash )
{
char *save = name;
if( !slash || !save )
return( name );
while( name[0] )
{
if( name[0] == '\\' || name[0] == '/' )
name[0] = slash;
name++;
}
return( save );
}
void DumpDepFile( void )
{
FNAMEPTR curr;
if( CompFlags.generate_auto_depend && FNames ) {
curr = FNames;
if( !DepFile ) {
return;
}
fprintf( DepFile, "%s :"
, ForceSlash( CreateFileName( DependTarget, OBJ_EXT, FALSE )
, DependForceSlash ) );
if( curr )
if( curr->rwflag && !SrcFileInRDir( curr ) )
fprintf( DepFile, " %s"
, ForceSlash( GetSourceDepName()
, DependForceSlash ) );
curr = curr->next;
for( ; curr; curr = curr->next ) {
if( curr->rwflag && !SrcFileInRDir( curr ) )
fprintf( DepFile, " %s", ForceSlash( curr->name, DependForceSlash ) );
}
fprintf( DepFile, "\n" );
/*
for( curr = FNames; curr; curr = curr->next )
{
if( curr->rwflag && !SrcFileInRDir( curr ) )
continue;
//fprintf( DepFile, "#Skipped file...%s\n", curr->name );
}
*/
}
}
static void DoCCompile( char **cmdline )
/**************************************/
{
jmp_buf env;
Environment = &env;
if( setjmp( env ) ) { /* if fatal error has occurred */
EmitAbort(); /* abort code generator */
PragmaFini();
CloseFiles();
FreeFNames();
FreeRDir();
ErrCount = 1;
MyExit( 1 );
}
ParseInit();
ForceInclude = FEGetEnv( "FORCE" );
if( ParseCmdLine( cmdline ) ) {
if( WholeFName == NULL ) {
CErr1( ERR_FILENAME_REQUIRED );
return;
}
DelErrFile(); /* delete old error file */
OpenErrFile(); /* open error file just in case */
OpenDepFile();
MergeInclude(); /* merge INCLUDE= with HFileList */
CPragmaInit(); /* memory model is known now */
#if _CPU == 370
ParseAuxFile();
#endif
if( CompFlags.cpp_output ) {
CPP_Parse();
if( !CompFlags.quiet_mode ) {
PrintStats();
}
} else {
MacroAddComp(); // Add any compile time only macros
Parse();
if( !CompFlags.quiet_mode ) {
PrintStats();
}
if( ( ErrCount == 0 ) && ( !CompFlags.check_syntax ) ) {
if( CompFlags.emit_browser_info ) {
DwarfBrowseEmit();
}
FreeMacroSegments();
DoCompile();
} else {
FreeMacroSegments();
}
}
if( ErrCount == 0 && DepFile ) {
DumpDepFile();
fclose( DepFile );
}
else {
if( DepFile ) {
fclose( DepFile );
}
DelDepFile();
}
DepFile = NULL;
SymFini();
PragmaFini();
} else {
ErrCount = 1;
}
CloseFiles();
FreeFNames();
FreeRDir();
}
/* open the primary source file, and return pointer to root file name */
#define STDIN_NAME "stdin"
static void MakePgmName( void )
{
// Get fname, if file name has no extension whack ".c" on
// if stdin a "." then replace with "stdin" don't whack ".c"
// If no module name make the same as fname
int len;
char *ptr;
char buff[ _MAX_PATH2 ];
char *fname;
char *ext;
ptr = WholeFName;
if( ptr[0] == '.' && ptr[1] == '\0' ) {
IsStdIn = 1;
CMemFree( WholeFName );
len = strlen( STDIN_NAME );
WholeFName = CMemAlloc( len + sizeof( char ) );
strcpy( WholeFName, STDIN_NAME );
fname = WholeFName;
} else {
_splitpath2( ptr, buff, NULL, NULL, &fname, &ext );
if( *ext == '\0' ) { // no extension
char *new;
len = strlen( WholeFName );
len += sizeof( C_EXT ); /* for the ".c\0" */
new = CMemAlloc( len );
strcpy( new, WholeFName );
strcat( new, C_EXT );
CMemFree( WholeFName );
WholeFName = new;
}
}
len = strlen( fname );
SrcFName = CMemAlloc( len + sizeof( char ) );
strcpy( SrcFName, fname );
if( ModuleName == NULL ) ModuleName = SrcFName;
}
local void CantOpenFile( char *name )
{
char msgtxt[80];
char msgbuf[MAX_MSG_LEN];
CGetMsg( msgtxt, ERR_CANT_OPEN_FILE );
sprintf( msgbuf, msgtxt, name );
BannerMsg( msgbuf );
}
static int OpenPgmFile( void )
{
if( IsStdIn ) {
return( OpenFCB( stdin, "stdin" ) );
}
if( TryOpen( "", "", WholeFName, "" ) == 0 ) {
if( TryOpen( C_PATH, PATH_SEP, WholeFName, "" ) == 0 ) {
CantOpenFile( WholeFName );
CSuicide();
return( 0 );
}
}
#if _CPU == 370
SrcFile->colum = Column;
SrcFile->trunc = Trunc;
#endif
return( 1 );
}
char *CreateFileName( char *template, char *extension, bool forceext )
{
#if !defined( __CMS__ )
char buff[ _MAX_PATH2 ];
char *drive;
char *dir;
char *fname;
char *ext;
char *path;
path = (template == NULL) ? WholeFName : template;
_splitpath2( path, buff, &drive, &dir, &fname, &ext );
if( forceext || template == NULL || ext[0] == '\0' ) {
ext = extension;
}
if( fname[0] == '\0' || fname[0] == '*' ) {
fname = ModuleName;
}
if( template == NULL ) {
/* default object file goes in current directory */
drive = "";
dir = "";
}
_makepath( Buffer, drive, dir, fname, ext );
#else
char *p;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?