iosupp.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 977 行 · 第 1/2 页
C
977 行
/****************************************************************************
*
* 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: I/O support routines.
*
****************************************************************************/
#include "plusplus.h"
#include <stdio.h>
#include <fcntl.h>
#include <stdarg.h>
#include <unistd.h>
#include "preproc.h"
#include "errdefns.h"
#include "memmgr.h"
#include "iosupp.h"
#include "cgdata.h"
#include "fname.h"
#include "hfile.h"
#include "initdefs.h"
#include "stats.h"
#include "pcheader.h"
#include "ring.h"
#include "brinfo.h"
#include "autodept.h"
#if defined(__UNIX__)
#include <dirent.h>
#else
#include <direct.h>
#endif
typedef struct buf_alloc BUF_ALLOC;
struct buf_alloc { // BUF_ALLOC -- allocated buffer
BUF_ALLOC* next; // - next buffer allocation
FILE* file; // - file in question
void* buffer; // - allocated buffer
};
static carve_t carve_buf; // carver: BUF_ALLOC
static BUF_ALLOC* buffers; // allocated buffers
static int temphandle; // handle for temp file
static char *tempname; // name of temp file
static DISK_ADDR tempBlock; // next available block in temp file
static unsigned outFileChecked; // mask for checking output files
static char workFile[] = // template for work file
"__wrk0__";
#if defined(__OS2__) || defined(__DOS__) || defined(__NT__)
static char* pathSrc[] = // paths for source file
{ "..\\cpp"
, "..\\c"
, NULL
};
static char* pathHdr[] = // paths for header files
{ "..\\h"
, "..\\include"
, NULL
};
static char* pathCmd[] = // paths for command files
{ "..\\occ"
, NULL
};
static char* extsHdr[] = // extensions for header files
{ ".hpp"
, ".h"
, NULL
};
static char* extsSrc[] = // extensions for source files
{ ".cpp"
, ".cc"
, ".c"
, NULL
};
static char* extsCmd[] = // extensions for command files
{ ".occ"
, NULL
};
static char* extsOut[] = // extensions for output files
{ ".obj"
, ".i"
, ".err"
, ".mbr"
, ".def"
#ifdef OPT_BR
, ".brm"
#endif
, ".d"
, ".obj"
};
#define IS_DIR_SEP( c ) ((c)=='/'||(c)=='\\')
#define IS_PATH_SEP( c ) ((c)==':'||IS_DIR_SEP(c))
#define PATH_SEP '\\'
#define INC_PATH_SEP ';'
#elif defined(__UNIX__)
static char* pathSrc[] = // paths for source file
{ "../C"
, "../cpp"
, "../c"
, NULL
};
static char* pathHdr[] = // paths for header files
{ "../H"
, "../h"
, NULL
};
static char* pathCmd[] = // paths for command files
{ "../occ"
, NULL
};
static char* extsHdr[] = // extensions for header files
{ ".H"
, ".hpp"
, ".h"
, NULL
};
static char* extsSrc[] = // extensions for source files
{ ".C"
, ".cpp"
, ".cc"
, ".c"
, NULL
};
static char* extsCmd[] = // extensions for command files
{ ".occ"
, NULL
};
static char* extsOut[] = // extensions for output files
{ ".o"
, ".i"
, ".err"
, ".mbr"
, ".def"
#ifdef OPT_BR
, ".brm"
#endif
, ".d"
, ".o"
};
#define IS_DIR_SEP( c ) ((c)=='/')
#define IS_PATH_SEP( c ) IS_DIR_SEP( c )
#define PATH_SEP '/'
#define INC_PATH_SEP ':'
#else
#error IOSUPP not configured for OS
#endif
char *IoSuppOutFileName( // BUILD AN OUTPUT NAME FROM SOURCE NAME
enum out_file_type typ ) // - extension
{
char *drive;
char *dir;
char *fname;
char *ext;
char *extsrc;
char *path;
int use_defaults;
unsigned mask;
FILE *try_create;
auto char buff[ _MAX_PATH2 ];
use_defaults = FALSE;
switch( typ ) {
case OFT_DEF:
#ifdef OPT_BR
case OFT_BRI:
#endif
path = WholeFName;
use_defaults = TRUE;
break;
case OFT_DEP:
path = DependFileName;
if( path == NULL ) {
use_defaults = TRUE;
path = WholeFName;
}
break;
case OFT_ERR:
if( ErrorFileName == NULL ) return( NULL );
path = ErrorFileName;
break;
case OFT_SRCDEP:
outFileChecked |= 1 << typ;
if( !(path = SrcDepFileName ) ) {
path = WholeFName;
}
else
{
auto char buff[ _MAX_PATH2 ];
char *drive;
char *dir;
char *fname;
_splitpath2( WholeFName, buff, &drive, &dir, &fname, &extsrc );
}
break;
case OFT_TRG:
outFileChecked |= 1 << typ; // don't create a file. it's just a name.
if( path = TargetFileName ) break;
case OFT_PPO:
case OFT_OBJ:
case OFT_MBR:
path = ObjectFileName;
if( path == NULL ) {
use_defaults = TRUE;
path = WholeFName;
}
break;
}
_splitpath2( path, buff, &drive, &dir, &fname, &ext );
switch( typ ) {
case OFT_MBR:
ext = ""; // don't override extension
break;
case OFT_SRCDEP:
if( !ext || !ext[0] )
ext = extsrc;
break;
}
if( use_defaults || ext[0] == '\0' ) {
ext = extsOut[ typ ];
}
if( fname[0] == '\0' || fname[0] == '*' ) {
fname = ModuleName;
}
if( use_defaults ) {
drive = "";
dir = "";
}
_makepath( Buffer, drive, dir, fname, ext );
mask = 1 << typ;
if(( outFileChecked & mask ) == 0 ) {
outFileChecked |= mask;
try_create = fopen( Buffer, "w" );
if( try_create != NULL ) {
fclose( try_create );
} else {
CErr2p( ERR_CANNOT_CREATE_OUTPUT_FILE, Buffer );
}
}
return( Buffer );
}
static void set_buffering( // SET BUFFERING FOR AN OPEN FILE
FILE *fp, // - opened file
size_t buf_size, // - buffer size
int mode ) // - buffering mode
{
BUF_ALLOC* ba = RingCarveAlloc( carve_buf, &buffers );
ba->file = fp;
ba->buffer = CMemAlloc( buf_size );
setvbuf( fp, ba->buffer, mode, buf_size );
}
void IoSuppSetBuffering( // SET FULL BUFFERING FOR AN OPEN FILE
FILE *fp, // - opened file
size_t buf_size ) // - buffer size
{
set_buffering( fp, buf_size, _IOFBF );
}
void IoSuppSetLineBuffering( // SET LINE BUFFERING FOR AN OPEN FILE
FILE *fp, // - opened file
size_t buf_size ) // - buffer size
{
set_buffering( fp, buf_size, _IOLBF );
}
static void freeBuffer( // FREE A BUFFER
BUF_ALLOC* ba ) // - allocated buffer
{
CMemFree( ba->buffer );
RingPrune( &buffers, ba );
CarveFree( carve_buf, ba );
}
boolean IoSuppCloseFile( // CLOSE FILE IF OPENED
FILE **file_ptr ) // - addr( file pointer )
{
boolean retn; // - return: TRUE ==> was open
BUF_ALLOC* ba; // - current allocated buffer
if( *file_ptr == NULL ) {
retn = FALSE;
} else {
RingIterBegSafe( buffers, ba ) {
if( *file_ptr == ba->buffer ) {
freeBuffer( ba );
break;
}
} RingIterEndSafe( ba );
SrcFileFClose( *file_ptr );
*file_ptr = NULL;
retn = TRUE;
}
return( retn );
}
struct path_descr // path description
{ char buffer[ _MAX_PATH2 ]; // - buffer
char *drv; // - drive
char *dir; // - directory
char *fnm; // - file name
char *ext; // - extension
};
static void splitFileName( // SPLIT APART PATH/FILENAME
char *name, // - name to be split
struct path_descr *descr ) // - descriptor
{
_splitpath2( name
, descr->buffer
, &descr->drv
, &descr->dir
, &descr->fnm
, &descr->ext );
}
static void makeDirName( // MAKE FILE NAME (WITHOUT DRIVE)
char *pp, // - target location
struct path_descr *nd ) // - name descriptor
{
_makepath( pp, NULL, nd->dir, nd->fnm, nd->ext );
}
static boolean openSrc( // ATTEMPT TO OPEN FILE
char *name, // - file name
enum file_type typ ) // - type of file being opened
{
pch_status pch_OK; // - pre-compiled header load status
FILE *fp; // - file pointer
boolean might_browse; // - true ==> might browse, if right file type
if( SrcFileProcessOnce( name ) ) {
SrcFileOpen( NULL, name );
return( TRUE );
}
fp = SrcFileFOpen( name, SFO_SOURCE_FILE );
if( fp == NULL ) {
return( FALSE );
}
might_browse = FALSE;
if( CompFlags.watch_for_pcheader ) {
CompFlags.watch_for_pcheader = FALSE;
pch_OK = PCHeaderAbsorb( name );
if( pch_OK != PCHA_OK ) {
SrcFileSetCreatePCHeader();
SrcFileOpen( fp, name );
might_browse = TRUE;
} else {
SrcFileOpen( NULL, name );
fclose( fp );
}
} else {
SrcFileOpen( fp, name );
if( typ == FT_SRC ) {
SetSrcFilePrimary();
}
might_browse = TRUE;
}
#ifdef OPT_BR
if( might_browse ) switch( typ ) {
case FT_SRC :
case FT_LIBRARY :
case FT_HEADER :
BrinfOpenSource( SrcFileCurrent() );
break;
}
#endif
return( TRUE );
}
static char *openExt( // ATTEMPT TO OPEN FILE (EXT. TO BE APPENDED)
char *ext, // - extension
struct path_descr *nd, // - name descriptor
enum file_type typ ) // - type of file being opened
{
char *ret; // - ret
char name[ _MAX_PATH ]; // - buffer for file name
_makepath( name, nd->drv, nd->dir, nd->fnm, ext );
/* so we can tell if the open worked */
ret = (ext != NULL) ? ext : "";
if( ! openSrc( name, typ ) ) {
ret = NULL;
}
return ret;
}
static char *openSrcExts( // ATTEMPT TO OPEN FILE (EXT.S TO BE APPENDED)
char **exts, // - extensions
struct path_descr *nd, // - name descriptor
enum file_type typ ) // - type of file being opened
{
char *ext; // - current extension
if( nd->ext[0] == '\0' ) {
int doSrc = (!(CompFlags.dont_autogen_ext_src) && (FT_SRC == typ));
int doInc = (!(CompFlags.dont_autogen_ext_inc) && ((FT_HEADER == typ)||(FT_LIBRARY == typ)));
int doExt = (doSrc || doInc);
ext = openExt( NULL, nd, typ );
if(( ext == NULL ) && (doExt)) {
for( ; ; ) {
ext = *exts++;
if( ext == NULL ) break;
ext = openExt( ext, nd, typ );
if( ext != NULL ) break;
}
}
} else {
ext = openExt( nd->ext, nd, typ );
}
return ext;
}
static char *concSep( // CONCATENATE PATH SEPARATOR AS REQUIRED
char *pp, // - pointer into buffer
char *buffer ) // - buffer
{
char *pred; // - preceding char in buffer
if( pp > buffer ) {
pred = pp - 1;
if( !IS_PATH_SEP( *pred ) ) {
*pp++ = PATH_SEP;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?