plusplus.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 600 行 · 第 1/2 页

C
600
字号
/****************************************************************************
*
*                            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.
*
****************************************************************************/

#include "plusplus.h"

#include <signal.h>
#include <process.h>
#include <ctype.h>
#include <setjmp.h>
#include <unistd.h>
#include <limits.h>
#include <fcntl.h>
#include <malloc.h>

#include "scan.h"
#include "memmgr.h"
#include "stats.h"
#include "errdefns.h"
#include "iosupp.h"
#include "preproc.h"
#include "fname.h"
#include "yydriver.h"
#include "cmdline.h"
#include "dbg.h"
#include "cgfront.h"
#include "context.h"
#include "srcfile.h"
#include "initdefs.h"
#include "cppdwarf.h"
#include "rtngen.h"
#include "cppexit.h"
#include "pragdefn.h"
#include "cgback.h"
#include "cusage.h"
#include "brinfo.h"
#include "idedrv.h"
#include "autodep.h"
#include "swchar.h"

#ifndef NDEBUG
#include <stdio.h>
#include "pragdefn.h"
#include "enterdb.h"
#endif

enum {
    WPP_WARNINGS        = 0x01,                 /* only if -we is on */
    WPP_ERRORS          = 0x02,
    WPP_FATAL           = 0x04,
    WPP_BATCH_FILES     = 0x08,
    WPP_COMPILE_FAIL    = WPP_WARNINGS
                        | WPP_ERRORS
                        | WPP_FATAL
                        ,
    WPP_SUCCESS         = 0
};

unsigned char _8087;
unsigned char _real87;

static struct {                     // flags:
    unsigned dll_first_time :1;     // - first-time thru
    unsigned batch_cmds     :1;     // - processing batch cmd file
} flags =
{   TRUE                            // - first-time thru
,   FALSE
};


static void CloseFiles( void )
{
    if( CppFile != NULL ) {
        fflush( CppFile );
        if( ferror( CppFile ) ) {
            /* issue message */
        }
        IoSuppCloseFile( &CppFile );
    }
    IoSuppCloseFile( &DefFile );
}


static void resetHandlers( void )
{
    CloseFiles();
}


// open the primary source file, and return pointer to root file name
//
static void MakePgmName(        // MAKE CANONICAL FILE NAME
    char *argv )                // - input name
{
    char buff[ _MAX_PATH2 ];
    char *drv;                  // - drive
    char *dir;                  // - directory
    char *fnm;                  // - file name
    char *ext;                  // - extension

    _splitpath2( argv, buff, &drv, &dir, &fnm, &ext );
    SrcFName = FNameAdd( fnm );
    if( ModuleName == NULL ) {
        ModuleName = strsave( SrcFName );
    }
}


static void OpenPgmFile(        // OPEN PROGRAM FILE
    void )
{
    if( IoSuppOpenSrc( WholeFName, FT_SRC ) ) {
        CompInfo.primary_srcfile = SrcFileCurrent();
        PpStartFile();
    } else {
        CErr2p( ERR_CANT_OPEN_FILE, WholeFName );
        CSuicide();
    }
}


int OpenSrcFile(                // OPEN A SOURCE FILE
    char * filename,            // - file name
    boolean is_lib )            // - TRUE ==> is <file>
{
    boolean     retn;           // - return: TRUE ==> opened ok
    int         save;           // - saved pre-proc status

    if( IoSuppOpenSrc( filename, is_lib ? FT_LIBRARY : FT_HEADER ) ) {
        PpStartFile();
        retn = TRUE;
    } else {
        save = CompFlags.cpp_output;
        if( CompFlags.cpp_output ) {
            PrtChar( PreProcChar );
            PrtString( "include ");
            if( is_lib ) {
                PrtChar( '<' );
            } else {
                PrtChar( '"' );
            }
            PrtString( filename );
            if( is_lib ) {
                PrtChar( '>' );
            } else {
                PrtChar( '"' );
            }
            CompFlags.cpp_output = 0;
        }
        CErr2p( ERR_CANT_OPEN_FILE, filename );
        CompFlags.cpp_output = save;
        retn = FALSE;
    }
    return retn;
}


static boolean parseCmdLine(    // PARSE COMMAND LINE
    char **argv )               // command line vector
{
    char    *p;
    boolean display_only;

    if( argv[0] == NULL ) argv[0] = "";
    p = argv[0];
    while( isspace( *p ) ) ++p;
    if( *p == '?' || *p == '\0' ) {
        CBanner();
        CCusage();
        display_only = TRUE;
    } else {
        GenCOptions( argv );
        if( WholeFName != NULL ) {
            MakePgmName( WholeFName );
        }
        display_only = FALSE;
    }
    return display_only;
}

static int makeExitStatus( int exit_status )
{
    CompFlags.compile_failed = FALSE;
    CompFlags.fatal_error = FALSE;
    if( exit_status & WPP_FATAL ) {
        CompFlags.fatal_error = TRUE;
    }
    if( ErrCount != 0 ) {
        exit_status |= WPP_ERRORS;
    }
    if( CompFlags.warnings_cause_bad_exit && WngCount != 0 ) {
        exit_status |= WPP_WARNINGS;
    }
    if( exit_status & WPP_COMPILE_FAIL ) {
        CompFlags.compile_failed = TRUE;
    }
    return( exit_status );
}

static void openForceIncludeFile( void )
{
    CtxSetContext( CTX_FORCED_INCS );
    if( CompFlags.cpp_output ) {
        PrtChar( '\n' );
    }
    InitialMacroFlag = 0;
    OpenSrcFile( ForceInclude, FALSE );
    CMemFreePtr( &ForceInclude );
}

static void setForceIncludeFromEnv( void )
{
    char *force;

    force = CppGetEnv( "FORCE" );
    if( force != NULL ) {
        force = strsave( force );
    }
    ForceInclude = force;
}

static int doCCompile(          // COMPILE C++ PROGRAM
    char **argv )               // - command line vector
{
    int exit_status;            // - status for exit return code
    boolean gen_code;           // - generate code?
    jmp_buf env;                // - for suicide

    exit_status = WPP_SUCCESS;
    ExitPointAcquire( cpp_front_end );
    Environment = env;
    if( setjmp( env ) ) {   /* if fatal error has occurred */
        exit_status |= WPP_FATAL;
        CtxSetContext( CTX_FINI );
    } else {
        ScanInit();
        setForceIncludeFromEnv();
        if( flags.batch_cmds ) {
            CompFlags.batch_file_processing = TRUE;
            CompFlags.banner_printed = TRUE;
        }
        if( parseCmdLine( argv ) ) {
            exit_status |= WPP_WARNINGS;
        } else if( CompFlags.batch_file_primary
                && ! CompFlags.batch_file_processing ) {
            if( CompFlags.batch_file_eof ) {
                exit_status |= WPP_ERRORS;
            } else {
                exit_status |= WPP_BATCH_FILES;
            }
        } else if( WholeFName == NULL ) {
            CErr1( ERR_FILENAME_REQUIRED );
            CompFlags.cmdline_error = TRUE;
            exit_status |= WPP_ERRORS;
        } else {
            if( ! CompFlags.quiet_mode ) {
                if( CompFlags.batch_file_processing
                 || CompInfo.compfile_max != 1 ) {
                    MsgDisplayLineArgs( "Compiling: "
                                      , WholeFName
                                      , NULL );
                }
            }
            if( 0 < ErrCount ) {
                CompFlags.cmdline_error = TRUE;
            }
            PTypeCheckInit();       /* must come after command line parsing */
            ErrFileOpen();          /* open error file just in case */
            if( CompFlags.cpp_output ) {
                PpOpen();           /* must be before OpenPgmFile() */
            } else {
                BrinfInit( TRUE );  /* must be before OpenPgmFile() */
            }
            OpenPgmFile();

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?