{Begin SubSec READFILE and WRITEFILE}
{Title READFILE and WRITEFILE}
{Text
For those applications where the user simply wants to simply read all of the expressions on a file, and not evaluate them, the function {fn READFILE} is available:
{FnDef {FnName READFILE} {FnArgs FILE RDTBL ENDTOKEN}
{Type NOSPREAD}
{Text
Reads successive expressions from file using {fn READ} (with read table {arg RDTBL}) until the single litatom {arg ENDTOKEN} is read, or an end of file encountered. Returns a list of these expressions.
If {arg RDTBL} is not specified, it defaults to {var FILERDTBL}{index FILERDTBL Var}. If {arg ENDTOKEN} is not specified, it defaults to the litatom {lisp STOP}.
}}
{FnDef {FnName WRITEFILE} {FnArgs X FILE}
{Text
Writes a date expression onto {arg FILE}, followed by successive expressions from {arg X}, using {var FILERDTBL}{index FILERDTBL Var} as a read table. If {arg X} is atomic, its value is used. If {arg FILE} is not open, it is opened. If {arg FILE} is a list, {lisp (CAR {arg FILE})} is used and the file is left opened. Otherwise, when {arg X} is finished, the litatom {lisp STOP}{index STOP (at the end of a file)} is printed on {arg FILE} and it is closed. Returns {arg FILE}.
{note Why write the date expression into FILE? This makes it a non-inverse of READFILE.}
{note Moby kludge: checking if FILE is a list to determine if the file should be closed (w/ STOP written) or not. Why not have a third CLOSEFLG argument. Indeed, with ENDFILE below, why do you even need this option? How is this normally used?}
{Note I agree with both complaints: the date expression makes it a noninverse (and, in fact, has kept me from using WRITEFILE in some of the cases where I might have used it), and the LISTP check is a crock. WRITEFILE is rarely used, especially now that we have MAKEFILE in all its glory. --bvm}
}}
{FnDef {FnName ENDFILE} {FnArgs FILE}
{Text
Prints {lisp STOP}{index STOP (at the end of a file)} on {arg FILE} and closes it.
}}
}{End SubSec READFILE and WRITEFILE}