exopen.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 393 行
C
393 行
/****************************************************************************
*
* 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: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
*
****************************************************************************/
//
// EXOPEN : Run-time OPEN statement processor
//
#include "ftnstd.h"
#include "errcod.h"
#include "rundat.h"
#include "rtenv.h"
extern bool FindFtnFile(void);
extern void GetFileInfo(void);
extern void F_Connect(void);
extern void DoOpen(void);
extern void ChkUnitId(void);
extern void DiscoFile(ftnfile *);
extern void IOErr(int,...);
extern bool SameFile(char *,char *);
extern bool Scrtched(ftnfile *);
extern void CloseFile(ftnfile *);
extern void SysCreateFile(ftnfile *);
extern int FindKWord(char **,int,int,string PGM *);
extern int IOMain(void (*)( void ));
extern bool IsDevice(ftnfile *);
extern bool __DevicesCC(void);
//
// AccModTab - access mode table
//
char *AccModTab[] = {
"sequential",
"direct",
"append",
NULL };
//
// FormTab - formatted or unformatted table
//
char *FormTab[] = {
"formatted",
"unformatted",
NULL };
//
// OpStatTab - open status table
//
char *OpStatTab[] = {
"unknown",
"old",
"new",
"scratch",
NULL };
//
// BlnkTab - blank table
//
char *BlnkTab[] = {
"null",
"zero",
NULL };
//
// RecFmTab - record format table
//
char *RecFmTab[] = {
"fixed",
"variable",
"text",
NULL };
//
// CCtrlTab - carriage control table
//
char *CCtrlTab[] = {
"yes",
"no",
NULL };
//
// ActionTab - action table
//
char *ActionTab[] = {
"read",
"write",
"readwrite",
NULL };
//
// ShareTab - share table
//
char *ShareTab[] = {
"compat",
"denyrw",
"denywr",
"denyrd",
"denynone",
NULL };
extern char *SpecId[];
static void ExOpen( void ) {
//========================
ftnfile *fcb;
byte accmode;
byte form;
byte status;
byte blanks;
byte recfm;
byte cctrl;
byte action;
byte share;
bool log;
bool connected;
void *temp;
ChkUnitId();
FindFtnFile();
fcb = IOCB->fileinfo;
status = FindKWord( OpStatTab, STAT_SPEC, STATUS_UNKNOWN,
( IOCB->set_flags & SET_STATPTR ) ? IOCB->statptr : NULL );
accmode = FindKWord( AccModTab, ACC_SPEC, ACCM_DEFAULT,
( IOCB->set_flags & SET_ACCPTR ) ? IOCB->accptr : NULL );
form = FindKWord( FormTab, FORM_SPEC, FORMATTED_DFLT,
( IOCB->set_flags & SET_FORMPTR ) ? IOCB->formptr : NULL );
blanks = FindKWord( BlnkTab, BLNK_SPEC, BLANK_DEFAULT,
( IOCB->set_flags & SET_BLNKPTR ) ? IOCB->blnkptr : NULL );
recfm = FindKWord( RecFmTab, RECFM_SPEC, RECFM_DEFAULT,
( IOCB->set_flags & SET_RECFMPTR ) ? IOCB->recfmptr : NULL );
cctrl = FindKWord( CCtrlTab, CCTRL_SPEC, CC_DEFAULT,
( IOCB->set_flags & SET_CCTRLPTR ) ? IOCB->cctrlptr : NULL );
action = FindKWord( ActionTab, ACTION_SPEC, ACT_DEFAULT,
( IOCB->set_flags & SET_ACTPTR ) ? IOCB->actptr : NULL );
share = FindKWord( ShareTab, SHARE_SPEC, SHARE_DEFAULT,
( IOCB->set_flags & SET_SHARE ) ? IOCB->shareptr : NULL );
if( IOCB->flags & BAD_RECL ) {
IOErr( IO_IRECL );
}
if( IOCB->flags & BAD_BLOCKSIZE ) {
IOErr( IO_IBLOCKSIZE );
}
if( (status != STATUS_SCRATCH) || !(IOCB->set_flags & SET_FILENAME) ) {
if( (status == STATUS_OLD) || (status == STATUS_NEW) ) {
if( !(IOCB->set_flags & SET_FILENAME) ) {
IOErr( IO_SNAME );
}
}
} else {
IOErr( IO_SNAME );
}
if( !(IOCB->set_flags & SET_RECL) ) {
if( accmode == ACCM_DIRECT ) {
IOErr( IO_RACCM );
}
}
F_Connect();
// Set the status since VAX/VMS needs the information to create a new
// version of the file.
IOCB->fileinfo->status = status;
GetFileInfo();
log = FALSE;
connected = FALSE;
if( fcb == NULL ) {
// file not connected
fcb = IOCB->fileinfo;
} else {
connected = TRUE;
log = (fcb->flags & FTN_LOG_IO) != 0;
if( fcb->accmode == ACCM_DEFAULT ) {
// OPEN of a preconnected file
if( IOCB->set_flags & SET_FILENAME ) {
// use the given name
DiscoFile( fcb );
fcb = IOCB->fileinfo;
} else {
// use the pre-connected name
DiscoFile( IOCB->fileinfo );
IOCB->fileinfo = fcb;
}
} else if( (IOCB->set_flags & SET_FILENAME) &&
!SameFile( IOCB->fileinfo->filename, fcb->filename ) ) {
// if OPENing a new file, close the old one
temp = IOCB->fileinfo;
IOCB->fileinfo = fcb;
CloseFile( fcb );
if( (fcb->status == STATUS_SCRATCH) &&
(fcb->flags & FTN_FSEXIST) && !Scrtched( fcb ) ) {
DiscoFile( fcb );
IOErr( IO_FILE_PROBLEM );
}
DiscoFile( fcb );
fcb = temp;
IOCB->fileinfo = temp;
} else {
// OPENing an open file, check only BLANK= has changed
DiscoFile( IOCB->fileinfo );
if( status == STATUS_UNKNOWN ) {
status = fcb->status;
}
if( accmode == ACCM_DEFAULT ) {
accmode = fcb->accmode;
}
if( form == FORMATTED_DFLT ) {
form = fcb->formatted;
}
if( !(IOCB->set_flags & SET_RECL) ) {
IOCB->recl = fcb->bufflen;
IOCB->set_flags |= SET_RECL;
}
if( !(IOCB->set_flags & SET_BLOCKSIZE) ) {
IOCB->blocksize = fcb->blocksize;
IOCB->set_flags |= SET_BLOCKSIZE;
}
if( blanks == BLANK_DEFAULT ) {
blanks = fcb->blanks;
}
if( recfm == RECFM_DEFAULT ) {
recfm = fcb->recfm;
}
if( cctrl == CC_DEFAULT ) {
cctrl = fcb->cctrl;
}
if( action == ACT_DEFAULT ) {
action = fcb->action;
}
if( share == SHARE_DEFAULT ) {
share = fcb->share;
}
if( status != fcb->status ) {
IOErr( IO_SUBSEQUENT_OPEN, SpecId[ STAT_SPEC ] );
} else if( accmode != fcb->accmode ) {
IOErr( IO_SUBSEQUENT_OPEN, SpecId[ ACC_SPEC ] );
} else if( form != fcb->formatted ) {
IOErr( IO_SUBSEQUENT_OPEN, SpecId[ FORM_SPEC ] );
} else if( IOCB->recl != fcb->bufflen ) {
IOErr( IO_SUBSEQUENT_OPEN, SpecId[ RECL_SPEC ] );
} else if( IOCB->blocksize != fcb->blocksize ) {
IOErr( IO_SUBSEQUENT_OPEN, SpecId[ BLOCKSIZE_SPEC ] );
} else if( recfm != fcb->recfm ) {
IOErr( IO_SUBSEQUENT_OPEN, SpecId[ RECFM_SPEC ] );
} else if( cctrl != fcb->cctrl ) {
IOErr( IO_SUBSEQUENT_OPEN, SpecId[ CCTRL_SPEC ] );
} else if( action != fcb->action ) {
IOErr( IO_SUBSEQUENT_OPEN, SpecId[ ACTION_SPEC ] );
} else if( share != fcb->share ) {
IOErr( IO_SUBSEQUENT_OPEN, SpecId[ SHARE_SPEC ] );
}
fcb->blanks = blanks;
IOCB->fileinfo = fcb;
if( fcb->fileptr == NULL ) {
DoOpen();
}
return;
}
}
// set up defaults for new file
if( blanks == BLANK_DEFAULT ) {
blanks = BLANK_NULL;
}
if( accmode == ACCM_DEFAULT ) {
accmode = ACCM_SEQUENTIAL;
}
if( form == FORMATTED_DFLT ) {
if( accmode == ACCM_DIRECT ) {
form = UNFORMATTED_IO;
} else {
form = FORMATTED_IO;
}
}
if( form == UNFORMATTED_IO ) {
if( IOCB->set_flags & SET_BLNKPTR ) {
if( !connected ) {
DiscoFile( fcb );
}
IOErr( IO_BLNK_FMT );
} else if( IOCB->set_flags & SET_CCTRLPTR ) {
if( !connected ) {
DiscoFile( fcb );
}
IOErr( IO_CC_FORM );
}
}
if( cctrl == CC_DEFAULT ) {
if( IsDevice( fcb ) && __DevicesCC() ) {
cctrl = CC_YES;
} else {
cctrl = CC_NO;
}
}
if( action == ACT_DEFAULT ) {
action = ACTION_RW;
}
if( share == SHARE_DEFAULT ) {
share = SHARE_COMPAT;
}
// check for status/file existence errors
if( ((status == STATUS_OLD) && !(fcb->flags & FTN_FSEXIST)) ||
((status == STATUS_NEW) && (fcb->flags & FTN_FSEXIST)) ) {
if( !connected ) {
DiscoFile( fcb );
}
IOErr( IO_SFILE );
}
// if record length was given, use it
if( IOCB->set_flags & SET_RECL ) {
fcb->bufflen = IOCB->recl;
}
// if block size was given, use it
if( IOCB->set_flags & SET_BLOCKSIZE ) {
fcb->blocksize = IOCB->blocksize;
}
// if action was given or the file does not exist, use it
// if the file exists, fcb->action will have been set by GetSysFileInfo()
if( ( IOCB->set_flags & SET_ACTPTR ) || !(fcb->flags & FTN_FSEXIST) ) {
fcb->action = action;
}
// Set up the new ftnfile structure - must be done before SysCreateFile()
// as VAX/VMS needs to know the access mode to create the file.
fcb->formatted = form;
fcb->accmode = accmode;
fcb->blanks = blanks;
fcb->flags |= FTN_EXIST;
if( log ) {
fcb->flags |= FTN_LOG_IO;
}
fcb->recfm = recfm;
fcb->cctrl = cctrl;
fcb->share = share;
// if the status is NEW, create the file and set status to OLD
if( status == STATUS_NEW ) {
SysCreateFile( fcb );
status = STATUS_OLD;
}
fcb->status = status;
// _NoRecordOrganization() assumes all fields have been set
if( _NoRecordOrganization( fcb ) ) {
fcb->recnum = 0;
} else {
fcb->recnum = 1;
}
if( fcb->fileptr == NULL ) {
DoOpen();
}
}
int IOOpen( void ) {
//================
IOCB->iostmt = IO_OPEN;
return( IOMain( &ExOpen ) );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?