/**
* FILE --- Optional File-Access Word Set
*
* Copyright (C) Tektronix, Inc. 1998 - 2001. All rights reserved.
*
* @see GNU LGPL
* @author Tektronix CTE @(#) %derived_by: guidod %
* @version %version: bln_mpt1!5.8 %
* (%date_modified: Tue Sep 10 13:28:57 2002 %)
*
* @description
* The Optional File-Access Word Set and
* File-Access Extension Words.
* These words imply some kind of file-system unlike
* the BLOCK wordset.
*
*//*@{*/
/**BIN( access-mode -- access-mode' )
* modify the give file access-mode to be a binary-mode
*/FCode (p4_bin)
{
*SP += FMODE_BIN;
}
/**CLOSE-FILE( file -- code )
* close the file and return the status-code
*/FCode (p4_close_file)
{
File *fid = (File *) SP[0];
if (_is_nullfile(fid)) goto nullfile;
SP[0] = p4_close_file (fid) ? errno : 0;
return;
nullfile:
SP[0] = EINVAL;
P4_warn ("close on NULL file");
}
/**CREATE-FILE( str-adr str-len mode -- file code )
* create the file with the given name and open
* it - returns the file id and a status code.
* A code of zero means success. An existing file
* of the same name is truncated upon open.
*/FCode (p4_create_file)
{
char *fn = (char *) SP[2]; /* c-addr, name */
p4ucell u = SP[1]; /* length of name */
p4cell fam = SP[0]; /* file access mode */
File *fid = p4_create_file (fn, u, fam);
SP += 1;
SP[1] = (p4cell) fid;
SP[0] = fid ? 0 : errno;
}
/**DELETE-FILE( str-adr str-len -- code )
* delete the named file and return a status code
*/FCode (p4_delete_file)
{
char* fnz = p4_pocket_filename ((char*)SP[1], SP[0]) ; /* as asciiz */
SP += 1;
SP[0] = _pfe_remove (fnz) ? errno : 0;
}
/**FILE-POSITION( file -- p.pos code )
* return the current position in the file and
* return a status code. A code of zero means success.
*/FCode (p4_file_position)
{
File *fid = (File *) SP[0]; /* file-id */
long pos;
p4udcell ud;
if (_is_nullfile(fid)) goto nullfile;
pos = ftell (fid->f);
SP -= 2;
if (pos != -1)
{
UL2UDC (pos, ud);
SP[0] = 0; /* ior */
}else{
ud.lo = ud.hi = UCELL_MAX;
SP[0] = errno; /* ior */
}
*(p4udcell *) &SP[1] = ud; /* ud */
return;
nullfile:
ud.lo = ud.hi = 0;
*(p4udcell *) &SP[1] = ud;
SP[0] = EINVAL;
P4_warn ("trying seek on NULL file");
}
/**FILE-SIZE( file -- s.size code )
* return the current size of the file and
* return a status code. A code of zero means success.
*/FCode (p4_file_size)
{
File *fid = (File *) SP[0]; /* fileid */
long size;
p4udcell ud;
if (_is_nullfile(fid)) goto nullfile;
size = fsize (fid->f);
SP -= 2;
if (size != -1)
{
UL2UDC (size, ud);
SP[0] = 0; /* ior */
}else{
ud.lo = ud.hi = UCELL_MAX;
SP[0] = errno; /* ior */
}
*(p4udcell *) &SP[1] = ud; /* ud */
return;
nullfile:
ud.lo = ud.hi = 0;
*(p4udcell *) &SP[1] = ud;
SP[0] = EINVAL;
P4_warn ("trying seek on NULL file");
}
/**INCLUDE-FILE( file -- )
* INTERPRET the given file
*/FCode (p4_include_file)
{
p4_include_file ((File *) *SP++);
}
/**INCLUDED( str-adr str-len -- )
* open the named file and then INCLUDE-FILE
* see also the interactive INCLUDE
*/FCode (p4_included)
{
char *fn = (char *) SP[1]; /* c-addr, name */
p4ucell u = SP[0]; /* length of name */
SP += 2;
p4_included (fn, u);
}
/**OPEN-FILE( str-adr str-len mode -- file code )
* open the named file with mode. returns the
* file id and a status code. A code of zero
* means success.
*/FCode (p4_open_file)
{
char *fn = (char *) SP[2]; /* c-addr, name */
p4ucell u = SP[1]; /* length of name */
p4cell fam = SP[0]; /* file access mode */
File *fid = p4_open_file (fn, u, fam);
SP += 1;
SP[1] = (p4cell) fid;
SP[0] = fid ? 0 : errno;
}
/**READ-FILE( str-adr str-len file -- count code )
* fill the given string buffer with characters
* from the buffer. A status code of zero means
* success and the returned count gives the
* number of bytes actually read. If an error
* occurs the number of already transferred bytes
* is returned.
*/FCode (p4_read_file)
{
char *c_addr = (char *) SP[2];
p4ucell u = SP[1];
File *fid = (File *) SP[0];
SP += 1;
if (_is_nullfile(fid)) goto nullfile;
SP[0] = p4_read_file (c_addr, &u, fid);
SP[1] = u;
return;
nullfile:
SP[0] = EINVAL;
SP[1] = 0;
P4_fail ("trying read from NULL file" CHECKFILE);
}
/**READ-LINE( str-adr str-len file -- count flag code )
* fill the given string buffer with one line
* from the file. A line termination character
* (or character sequence under WIN/DOS) may
* also be placed in the buffer but is not
* included in the final count. In other respects
* this function performs a READ-FILE
*/FCode (p4_read_line)
{
char *c_addr = (char *) SP[2];
p4ucell u = SP[1];
File *fid = (File *) SP[0];
p4cell ior;
if (_is_nullfile(fid)) goto nullfile;
SP[1] = p4_read_line (c_addr, &u, fid, &ior);
SP[2] = u;
SP[0] = ior;
return;
nullfile:
SP[0] = EINVAL;
SP[1] = EINVAL;
SP[2] = 0;
P4_fail ("trying read from NULL file" CHECKFILE);
}
/**REPOSITION-FILE( o.offset file -- code )
* reposition the file offset - the next FILE-POSITION
* would return o.offset then. returns a status code.
*/FCode (p4_reposition_file)
{
File *fid = (File *) SP[0];
long pos = UDC2UL (SP[1], SP[2]);
if (_is_nullfile(fid)) goto nullfile;
SP += 2;
SP[0] = p4_reposition_file (fid, pos);
return;
nullfile:
SP[0] = EINVAL;
P4_warn ("trying seek on NULL file");
}
/**RESIZE-FILE( s.size file -- code )
* resize the give file, returns a status code.
*/FCode (p4_resize_file)
{
File *fid = (File *) SP[0];
long size = UDC2UL (SP[1], SP[2]);
if (_is_nullfile(fid)) goto nullfile;
SP += 2;
if (p4_resize_file (fid, size) != 0)
*SP = errno;
else
*SP = 0, fid->size = (p4ucell) (size / BPBUF);
return;
nullfile:
SP[0] = EINVAL;
P4_fail ("trying seek on NULL file" CHECKFILE);
}
/**WRITE-FILE( str-adr str-len file -- code )
* write characters from the string buffer to a file,
* returns a status code.
*/FCode (p4_write_file)
{
char *c_addr = (char *) SP[2];
p4ucell u = SP[1];
File *fid = (File *) SP[0];
SP += 2;
if (_is_nullfile(fid)) goto nullfile;
SP[0] = p4_write_file (c_addr, u, fid);
return;
nullfile:
SP[0] = EINVAL;
P4_fail ("trying write to NULL file" CHECKFILE);
}
/**WRITE-LINE( str-adr str-len file -- code )
* write characters from the string buffer to a file,
* and add the line-terminator to the end of it.
* returns a status code.
*/FCode (p4_write_line)
{
char *c_addr = (char *) SP[2];
p4ucell u = SP[1];
File *fid = (File *) SP[0];
SP += 2;
if (_is_nullfile(fid)) goto nullfile;
if ((SP[0] = p4_write_file (c_addr, u, fid)) == 0)
putc ('\n', fid->f);
return;
nullfile:
SP[0] = EINVAL;
P4_fail ("trying write to NULL file" CHECKFILE);
}
/**FILE-STATUS( str-adr str-len -- sub-code code )
* check the named file - if it exists
* the status code is zero. The sub-code
* is implementation-specific.
*/FCode (p4_file_status)
{
int mode = p4_file_access ((char *) SP[1], SP[0]);
if (mode == -1)
{
SP[1] = 0;
SP[0] = errno;
}else{
SP[1] = mode;
SP[0] = 0;
}
}
/**FLUSH-FILE( file -- code )
* flush all unsaved buffers of the file to disk.
* A status code of zero means success.
*/FCode (p4_flush_file)
{
File *fid = (File *) SP[0];
if (_is_nullfile(fid)) goto nullfile;
if (BLOCK_FILE == fid)
{
FX (p4_save_buffers);
SP[0] = 0;
}else{
if (fflush (fid->f))
SP[0] = errno;
else
SP[0] = 0;
}
return;
nullfile:
SP[0] = EINVAL;
P4_warn ("trying flush on NULL file");
}
/**RENAME-FILE( str-adr1 str-len1 str-adr2 str-len2 -- code )
* rename the file named by string1 to the name of string2.
* returns a status-code
*/FCode (p4_rename_file)
{
char* oldnm;
char* newnm;
oldnm = p4_pocket_filename ((char *) SP[3], SP[2]);
newnm = p4_pocket_filename ((char *) SP[1], SP[0]);
SP += 3;
*SP = _P4_rename (oldnm, newnm) ? errno : 0;
}
/**R/O( -- bitmask )
* a bitmask for OPEN-FILE ( R/OR/WW/OBIN )
*/
/**W/O( -- bitmask )
* a bitmask for OPEN-FILE or CREATE-FILE ( R/OR/WW/OBIN )
*/
/**R/W( -- bitmask )
* a bitmask for OPEN-FILE or CREATE-FILE ( R/OR/WW/OBIN )
*/
/**ENVIRONMENT MAX-FILES( -- number )
* the number of opened file-ids allowed during compilation.
* portable programs can check this with ENVIRONMENT?
*/