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

📄 rcio.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 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:  WRC I/O routines.
*
****************************************************************************/


#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdarg.h>
#include <time.h>
#ifndef __UNIX__
    #include <process.h>
#endif
#include "watcom.h"
#include "wresall.h"
#include "global.h"
#include "pass2.h"
#include "semstr.h"
#include "rcmem.h"
#include "rctypes.h"
#include "errors.h"
#include "exeutil.h"
#include "rcio.h"
#include "preproc.h"
#include "reserr.h"
#include "tmpctl.h"
#include "autodep.h"
#include "errprt.h"
#include "util.h"
#include "rcldstr.h"
#include "iortns.h"
#include <banner.h>

#ifdef _BANEXTRA
#undef  _BANEXTRA
#define _BANEXTRA _BANEXSHORT
#endif

#ifdef __UNIX__
#define PATH_SEP '/'
#define PATH_SPLIT ':'
#else
#define PATH_SEP '\\'
#define PATH_SPLIT ';'
#endif

#ifdef __OSI__
 extern char    *_Copyright;
#endif

#if !defined( DLL_COMPILE )
extern char *RcGetEnv( const char *name )
/****************************************/
{
    return( getenv( name ) );
}
#endif

static void MakeTmpInSameDir( const char * dirfile, char * outfile, char * ext )
/******************************************************************************/
{
    char    drive[ _MAX_DRIVE ];
    char    dir[ _MAX_DIR ];
#ifdef __UNIX__
    char    fname[ 32 ];
#else
    char    *fname = "__TMP__";
#endif

    _splitpath( dirfile, drive, dir, NULL, NULL );
#ifdef __UNIX__
    // Must be able to run several "rc" executables simultaneously
    // in the same directory
    sprintf( fname, "__RCTMP%lu__", (unsigned long)getpid() );
#endif
    _makepath( outfile, drive, dir, fname, ext );
} /* MakeTmpInSameDir */

static int Pass1InitRes( void )
/*****************************/
{
    WResID        null_id;
    ResMemFlags   null_memflags;
    ResLocation   null_loc;

    /* put the temporary file in the same location as the output file */
    CurrResFile.filename = CurrResFile.namebuf;
#ifdef USE_TEMPFILE
    MakeTmpInSameDir( CmdLineParms.OutResFileName, CurrResFile.filename,
                    "res" );
#else
    strcpy( CurrResFile.filename, CmdLineParms.OutResFileName );
#endif

    /* initialize the directory */
    CurrResFile.dir = WResInitDir();
    if( CurrResFile.dir == NULL ) {
        RcError( ERR_OUT_OF_MEMORY );
        CurrResFile.IsOpen = false;
        return( TRUE );
    }

    if( CmdLineParms.TargetOS == RC_TARGET_OS_WIN16 ) {
        WResSetTargetOS( CurrResFile.dir, WRES_OS_WIN16 );
    } else if( CmdLineParms.TargetOS == RC_TARGET_OS_WIN32 ) {
        WResSetTargetOS( CurrResFile.dir, WRES_OS_WIN32 );
    } else {
        WResSetTargetOS( CurrResFile.dir, WRES_OS_OS2 );
    }

    /* open the tempory file */
    if (CmdLineParms.MSResFormat) {
        CurrResFile.IsWatcomRes = FALSE;
        CurrResFile.handle = MResOpenNewFile( CurrResFile.filename );

    /* write null header here if it is win32 */
        if( CmdLineParms.TargetOS == RC_TARGET_OS_WIN32 &&
                                     CmdLineParms.MSResFormat ) {
            null_loc.start = SemStartResource();
            null_loc.len = SemEndResource( null_loc.start );
            null_id.IsName = FALSE;
            null_id.ID.Num = 0;
            null_memflags = 0;
            SemAddResource( &null_id, &null_id, null_memflags, null_loc );
        }
    } else {
        CurrResFile.IsWatcomRes = TRUE;
        CurrResFile.handle = WResOpenNewFile( CurrResFile.filename );
    }
    if( CurrResFile.handle == -1 ) {
        RcError( ERR_OPENING_TMP, CurrResFile.filename, LastWresErrStr() );
        CurrResFile.IsOpen = false;
        return( TRUE );
    }
    RegisterTmpFile( CurrResFile.filename );

    CurrResFile.IsOpen = true;
    CurrResFile.StringTable = NULL;
    CurrResFile.ErrorTable = NULL;
    CurrResFile.FontDir = NULL;
    CurrResFile.NextCurOrIcon = 1;
    return( FALSE );
} /* Pass1InitRes */

extern void RcFindResource( char *name, char *fullpath ) {

    char        *src;
    char        *dst;
    char        end;
    char        drive[_MAX_DRIVE];
    char        dir[_MAX_DIR];

    fullpath[0] = '\0';
    //if the filename has a drive or is an absolute path then ignore
    //the include path and just look at the specified location
    _splitpath( name, drive, dir, NULL, NULL );
    if( drive[0] != '\0' || dir[0] ==PATH_SEP ) {
        if( access( name, F_OK ) == 0 ) {
            strcpy( fullpath, name );
        }
        return;
    }
    if( !CmdLineParms.IgnoreCWD && access( name, F_OK ) == 0 ) {
        strcpy( fullpath, name );
        return;
    }
    if( NewIncludeDirs != NULL ) {
        src = NewIncludeDirs;
        end = *NewIncludeDirs;
        while( end != '\0' ) {
            dst = fullpath;
            while( *src != ';' && *src != PATH_SPLIT && *src != '\0' ) {
                *dst = *src;
                dst ++;
                src ++;
            }
            end = *src;
            src ++;
            if( *( dst - 1 ) != PATH_SEP ) {
                *dst = PATH_SEP;
                dst++;
            }
            strcpy( dst, name );
            if( access( fullpath, F_OK ) == 0 ) return;
        }
    }
    fullpath[0] = '\0';
}

extern void RcTmpFileName( char * tmpfilename )
/*********************************************/
/* uses the TMP env. var. if it is set and puts the result into tmpfilename */
/* which is assumed to be a buffer of at least _MAX_PATH characters */
{
    char *  nextchar;
    char *  tmpdir;

    tmpdir = RcGetEnv( "TMP" );
    if( tmpdir != NULL ) {
        /* leave room for the '\' and the filename */
        strncpy( tmpfilename, tmpdir, _MAX_PATH - L_tmpnam - 1 );
        nextchar = tmpfilename + strlen( tmpfilename ) - 1;
        /* tack a '\' onto the end if it is not there already */
        if( *nextchar != PATH_SEP ) {
            nextchar++;
            *nextchar = PATH_SEP;
        }
        nextchar++;
    } else {
        nextchar = tmpfilename;
    }

    tmpnam( nextchar );
}

static int PreprocessInputFile( void )
/************************************/
{
    unsigned    flags;
    char        rcdefine[13];
    char      **cppargs;
    char       *p;
    int         rc;

    // We have already merged INCLUDE path with /i paths
    flags = PPFLAG_IGNORE_INCLUDE;
    if( CmdLineParms.IgnoreCWD ) {
        flags |= PPFLAG_IGNORE_CWD;
    }
    rc = PP_Init2( CmdLineParms.InFileName, flags, NewIncludeDirs, CharSet );
    if( rc != 0 ) {
        RcError( ERR_CANT_OPEN_FILE, CmdLineParms.InFileName, strerror(errno) );
        return( TRUE );
    }
    strcpy( rcdefine, "RC_INVOKED 1" );
    PP_Define( rcdefine );
    if( CmdLineParms.TargetOS == RC_TARGET_OS_WIN16 ) {
        strcpy( rcdefine, "__WINDOWS__" );
        PP_Define( rcdefine );
    } else if( CmdLineParms.TargetOS == RC_TARGET_OS_WIN32 ) {
        strcpy( rcdefine, "__NT__" );
        PP_Define( rcdefine );
        strcpy( rcdefine, "_WIN32" );
        PP_Define( rcdefine );
    } else if( CmdLineParms.TargetOS == RC_TARGET_OS_OS2 ) {
        strcpy( rcdefine, "__OS2__" );
        PP_Define( rcdefine );
    }
    cppargs = CmdLineParms.CPPArgs;
    if( cppargs != NULL ) {
        ++cppargs;
        for(;;) {
            p = *cppargs;
            if( p == NULL ) break;
            for(;;) {
                if( *p == '\0' ) break;
                if( *p == '=' ) {
                    *p = ' ';
                    break;
                }
                ++p;
            }
            p = *cppargs;
            PP_Define( p + 2 );         // skip over -d
            ++cppargs;
        }
    }
    return( FALSE );                    // indicate no error
}

extern int RcPass1IoInit( void )
/******************************/
/* Open the two files for input and output. The input stream starts at the */
/* top   infilename   and continues as the directives in the file indicate */
/* Returns false if there is a problem opening one of the files. */
{
    int         error;
    char       *includepath = NULL;

    if( !CmdLineParms.IgnoreINCLUDE ) {
        if( CmdLineParms.TargetOS == RC_TARGET_OS_WIN16 ) {
            includepath = RcGetEnv( "WINDOWS_INCLUDE" );
        } else if( CmdLineParms.TargetOS == RC_TARGET_OS_WIN32 ) {
            includepath = RcGetEnv( "NT_INCLUDE" );
        } else if( CmdLineParms.TargetOS == RC_TARGET_OS_OS2 ) {
            includepath = RcGetEnv( "OS2_INCLUDE" );
        }
    }
    if( includepath != NULL ) {
        AddNewIncludeDirs( includepath );
    }
    if( CmdLineParms.NoPreprocess ) {
        RcIoTextInputInit();
        error = RcIoPushInputFile( CmdLineParms.InFileName );
    } else {
        error = PreprocessInputFile();
        if( error ) return( FALSE );
        RcIoTextInputInit();
        error = RcIoPushInputFile( CmdLineParms.InFileName );
    }
    if( error ) return( FALSE );

    if( !CmdLineParms.PreprocessOnly ) {
        error = Pass1InitRes();
    }
    if( error )  {
        PP_Fini();
        RcIoTextInputShutdown();
        return( FALSE );
    }

    return( TRUE );
}

static int ChangeTmpToOutFile( const char * tmpfile, const char * outfile )
/**************************************************************************/
{
    int     fileerror;      /* error while deleting or renaming */

    /* remove the old copy of the output file */
    fileerror = remove( outfile );
    if( fileerror ) {
        if( errno == ENOENT ) {
            /* ignore the error if it says that the file doesn't exist */
            errno = 0;
        } else {
            RcError( ERR_RENAMEING_TMP_FILE, tmpfile, outfile,
                        strerror( errno ) );
            remove( tmpfile );
            UnregisterTmpFile( tmpfile );
            return( TRUE );
        }
    }
    /* rename the temp file to the output file */
    fileerror = rename( tmpfile, outfile );
    if( fileerror ) {
        RcError( ERR_RENAMEING_TMP_FILE, tmpfile, outfile,
                        strerror( errno ) );
        remove( tmpfile );
        UnregisterTmpFile( tmpfile );
        return( TRUE );
    }

    return( FALSE );
} /* ChangeTmpToOutFile */

static int RemoveCurrResFile( void )
/**********************************/
{
    int     fileerror;

    fileerror = remove( CurrResFile.filename );
    UnregisterTmpFile( CurrResFile.filename );
    if( fileerror ) {

⌨️ 快捷键说明

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