⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ccmain.c

📁 Open Watcom 的 C 编译器源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************************************************************************
*
*                            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 + -