{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}
{Text
Reads successive expressions from file using {fn READ} (with {var FILERDTBL}{index FILERDTBL Var} as readtable)  until the single atom {lisp STOP} is read, or an end of file encountered.  Returns a list of these expressions.
}}


{FnDef {FnName WRITEFILE} {FnArgs X FILE}
{Text
Inverse of {fn READFILE}.  Writes a date expression onto {arg FILE}, followed by successive expressions from {arg X}, using {var FILERDTBL}{index FILERDTBL Var} as a readtable.  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, a {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}