📄 ccmain.c
字号:
/****************************************************************************
*
* 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 "standard.h"
#include "cg.h"
#include "cgdefs.h"
#include "cgswitch.h"
#include "cgprotos.h"
#include "autodept.h"
#include <stdarg.h>
#include <signal.h>
#include <ctype.h>
#if _OS == _CMS
#include <file.h>
#include <errno.h>
#include <setup.h>
#include <depsets.h>
#define FEGetEnv EnvVar
/* plist format to be passed to main */
int const _parms = UNTOKENIZED;
int const _staksize = (100*1024);/* stack size */
#elif _OS == _QNX
#include <stdio.h>
#ifdef __WATCOMC__
#include <i86.h>
#endif
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#elif _OS == _LINUX
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#else
#include "dos.h"
#include <io.h>
#include <fcntl.h>
#include <process.h>
#endif
#ifdef __OSI__
#include "ostype.h"
#endif
#ifndef _MAX_PATH
#define _MAX_PATH (PATH_MAX+1)
#endif
#ifndef _MAX_PATH2
#define _MAX_PATH2 (PATH_MAX+4)
#endif
#ifndef O_TEMP
#define O_TEMP 0
#endif
#ifdef __WATCOMC__
#include <conio.h>
#endif
#if defined(__QNX__) || defined(__LINUX__)
#define IS_PATH_SEP( ch ) ((ch) == '/')
#else
#define IS_PATH_SEP( ch ) ((ch) == '/' || (ch) == '\\')
#endif
extern char CharSet[];
static char IsStdIn;
static int IncFileDepth;
int PrintWhiteSpace; // also refered from cmac2.c
// local functions definition
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 = 255;
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 */
#if _HOST == 386 && defined(__WATCOMC__)
_amblksiz = 16;
#endif
InitGlobalVars();
CMemInit();
InitMsg();
InitPurge();
SwitchChar = _dos_switch_char();
ClearGlobals();
#if _OS == _CMS
setxedit( 1 ); /* mjc */
#endif
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()
{
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( 32 ), _IOFBF, 32 );
}
}
}
}
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 )
/******************************/
{
auto 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"
// extern char FindIt[10] = "cgtype";
static void MakePgmName( void )
{
// Get fname, if file name has no extension wack ".c" on
// if stdin a "." then replace with "stdin" don't wack ".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 ) );
// if( strcmp( fname, FindIt ) == 0 ) {
// printf( "here\n" );
// }
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 )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -