1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-03 07:24:58 +03:00
inform7/docs/BasicInformKit/S-fl.html
2021-02-20 15:45:46 +00:00

468 lines
95 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>FileIO Template</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
<meta name="viewport" content="width=device-width initial-scale=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body class="commentary-font">
<nav role="navigation">
<h1><a href="../index.html">
<img src="../docs-assets/Inform.png" height=72">
</a></h1>
<ul><li><a href="../compiler.html">compiler tools</a></li>
<li><a href="../other.html">other tools</a></li>
<li><a href="../extensions.html">extensions and kits</a></li>
<li><a href="../units.html">unit test tools</a></li>
</ul><h2>Extensions</h2><ul>
<li><a href="../basic_inform/index.html">basic_inform</a></li>
<li><a href="../standard_rules/index.html">standard_rules</a></li>
</ul><h2>Kits</h2><ul>
<li><a href="index.html"><span class="selectedlink">BasicInformKit</span></a></li>
<li><a href="../BasicInformExtrasKit/index.html">BasicInformExtrasKit</a></li>
<li><a href="../CommandParserKit/index.html">CommandParserKit</a></li>
<li><a href="../EnglishLanguageKit/index.html">EnglishLanguageKit</a></li>
<li><a href="../WorldModelKit/index.html">WorldModelKit</a></li>
</ul>
</nav>
<main role="main">
<!--Weave of 'FileIO Template' generated by Inweb-->
<div class="breadcrumbs">
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../extensions.html">Kits</a></li><li><a href="index.html">BasicInformKit</a></li><li><b>FileIO Template</b></li></ul></div>
<p class="purpose">Reading and writing external files, in the Glulx virtual machine only.</p>
<ul class="toc"><li><a href="S-fl.html#SP1">&#167;1. Language</a></li><li><a href="S-fl.html#SP2">&#167;2. Structure</a></li><li><a href="S-fl.html#SP3">&#167;3. Instances</a></li><li><a href="S-fl.html#SP4">&#167;4. Errors</a></li><li><a href="S-fl.html#SP5">&#167;5. Glulx Material</a></li><li><a href="S-fl.html#SP6">&#167;6. Existence</a></li><li><a href="S-fl.html#SP7">&#167;7. Readiness</a></li><li><a href="S-fl.html#SP8">&#167;8. Open File</a></li><li><a href="S-fl.html#SP9">&#167;9. Close File</a></li><li><a href="S-fl.html#SP10">&#167;10. Get Character</a></li><li><a href="S-fl.html#SP11">&#167;11. Put Character</a></li><li><a href="S-fl.html#SP12">&#167;12. Print Line</a></li><li><a href="S-fl.html#SP13">&#167;13. Print Contents</a></li><li><a href="S-fl.html#SP14">&#167;14. Print Text</a></li><li><a href="S-fl.html#SP15">&#167;15. Serialising Tables</a></li><li><a href="S-fl.html#SP16">&#167;16. Z-Machine Stubs</a></li><li><a href="S-fl.html#SP17">&#167;17. Back To Core</a></li></ul><hr class="tocbar">
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. Language. </b>This whole template contains material used only if the "Glulx external files"
element is part of Inform's current definition, so:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">#</span><span class="identifier-syntax">IFDEF</span><span class="plain-syntax"> </span><span class="identifier-syntax">FILES_PLUGIN</span><span class="plain-syntax">;</span>
</pre>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. Structure. </b>The I7 kind of value "auxiliary-file" is an <span class="extract"><span class="extract-syntax">--&gt;</span></span> array, holding a memory
structure containing information about external files. The following
constants specify memory offsets and values. Note the safety value stored
as the first word of the structure: this helps protect the routines below
from accidents. (16339, besides being prime, is a number interesting to the
author of Inform since it was the examination board identifying number of
his school, and so had to be filled in on all of the many papers he sat
during his formative years.)
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">AUXF_MAGIC</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="comment-syntax">First word holds a safety constant</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">AUXF_MAGIC_VALUE</span><span class="plain-syntax"> = </span><span class="constant-syntax">16339</span><span class="plain-syntax">; </span><span class="comment-syntax">Should be first word of any valid file structure</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">AUXF_STATUS</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">; </span><span class="comment-syntax">One of the following:</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">AUXF_STATUS_IS_CLOSED</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">; </span><span class="comment-syntax">Currently closed, or perhaps doesn't exist</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">AUXF_STATUS_IS_OPEN_FOR_READ</span><span class="plain-syntax"> = </span><span class="constant-syntax">2</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">AUXF_STATUS_IS_OPEN_FOR_WRITE</span><span class="plain-syntax"> = </span><span class="constant-syntax">3</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">AUXF_STATUS_IS_OPEN_FOR_APPEND</span><span class="plain-syntax"> = </span><span class="constant-syntax">4</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">AUXF_BINARY</span><span class="plain-syntax"> = </span><span class="constant-syntax">2</span><span class="plain-syntax">; </span><span class="comment-syntax">False for text files (I7 default), true for binary</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">AUXF_STREAM</span><span class="plain-syntax"> = </span><span class="constant-syntax">3</span><span class="plain-syntax">; </span><span class="comment-syntax">Stream for an open file (meaningless otherwise)</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">AUXF_FILENAME</span><span class="plain-syntax"> = </span><span class="constant-syntax">4</span><span class="plain-syntax">; </span><span class="comment-syntax">Packed address of constant string</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">AUXF_IFID_OF_OWNER</span><span class="plain-syntax"> = </span><span class="constant-syntax">5</span><span class="plain-syntax">; </span><span class="comment-syntax">UUID_ARRAY if owned by this project, or</span>
<span class="plain-syntax"> </span><span class="comment-syntax">string array of IFID of owner, or NULL to leave open</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. Instances. </b>These structures are not dynamically created: they are precompiled by the Inform
compiler, already filled in with the necessary values. The following command
generates them.
</p>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. Errors. </b>This is used for I/O errors of all kinds: it isn't within the Glulx-only
code because one of the errors is to try to use these routines on the
Z-machine.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax"> </span><span class="identifier-syntax">extf</span><span class="plain-syntax"> </span><span class="identifier-syntax">err_text</span><span class="plain-syntax"> </span><span class="identifier-syntax">struc</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">NO_EXTERNAL_FILES</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"^*** Error on unknown file: "</span><span class="plain-syntax">, (</span><span class="reserved-syntax">string</span><span class="plain-syntax">) </span><span class="identifier-syntax">err_text</span><span class="plain-syntax">, </span><span class="string-syntax">" ***^"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">struc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TableOfExternalFiles</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">extf</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"^*** Error on file '"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> (</span><span class="reserved-syntax">string</span><span class="plain-syntax">) </span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_FILENAME</span><span class="plain-syntax">, </span><span class="string-syntax">"': "</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> (</span><span class="reserved-syntax">string</span><span class="plain-syntax">) </span><span class="identifier-syntax">err_text</span><span class="plain-syntax">, </span><span class="string-syntax">" ***^"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">RunTimeProblem</span><span class="plain-syntax">(</span><span class="identifier-syntax">RTP_FILEIOERROR</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. Glulx Material. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">#</span><span class="identifier-syntax">IFDEF</span><span class="plain-syntax"> </span><span class="identifier-syntax">TARGET_GLULX</span><span class="plain-syntax">;</span>
</pre>
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>&#167;6. Existence. </b>Determine whether a file exists on disc. Note that we have no concept of
directories, or the file system structure on the host machine: indeed, it
is entirely up to the Glulx VM what it does when asked to look for a file.
By convention, though, files for a project are stored in the same folder
as the story file when out in the wild; when a project is developed within
the Inform user interface, they are either (for preference) stored in a
<span class="extract"><span class="extract-syntax">Files</span></span> subfolder of the <span class="extract"><span class="extract-syntax">Materials</span></span> folder for a project, or else stored
alongside the Inform project file.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">FileIO_Exists</span><span class="plain-syntax"> </span><span class="identifier-syntax">extf</span><span class="plain-syntax"> </span><span class="identifier-syntax">fref</span><span class="plain-syntax"> </span><span class="identifier-syntax">struc</span><span class="plain-syntax"> </span><span class="identifier-syntax">rv</span><span class="plain-syntax"> </span><span class="identifier-syntax">usage</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">NO_EXTERNAL_FILES</span><span class="plain-syntax">)) </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">struc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TableOfExternalFiles</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">extf</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">struc</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_MAGIC</span><span class="plain-syntax"> ~= </span><span class="identifier-syntax">AUXF_MAGIC_VALUE</span><span class="plain-syntax">)) </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_BINARY</span><span class="plain-syntax">) </span><span class="identifier-syntax">usage</span><span class="plain-syntax"> = </span><span class="identifier-syntax">fileusage_BinaryMode</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">usage</span><span class="plain-syntax"> = </span><span class="identifier-syntax">fileusage_TextMode</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">fref</span><span class="plain-syntax"> = </span><span class="identifier-syntax">glk_fileref_create_by_name</span><span class="plain-syntax">(</span><span class="identifier-syntax">fileusage_Data</span><span class="plain-syntax"> + </span><span class="identifier-syntax">usage</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Glulx_ChangeAnyToCString</span><span class="plain-syntax">(</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_FILENAME</span><span class="plain-syntax">), </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">rv</span><span class="plain-syntax"> = </span><span class="identifier-syntax">glk_fileref_does_file_exist</span><span class="plain-syntax">(</span><span class="identifier-syntax">fref</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">glk_fileref_destroy</span><span class="plain-syntax">(</span><span class="identifier-syntax">fref</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">rv</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>&#167;7. Readiness. </b>One of our problems is that a file might be being used by another application:
perhaps even by another story file running in a second incarnation of Glulx,
like a parallel world of which we can know nothing. We actually want to
allow for this sort of thing, because one use for external files in I7
is as a sort of communications conduit for assisting applications.
</p>
<p class="commentary">Most operating systems solve this problem by means of locking a file, or
by creating a second lock-file, the existence of which indicates ownership
of the original. We haven't got much access to the file-system, though:
what we do is to set the first character of the file to an asterisk to
mark it as complete and ready for reading, or to a hyphen to mark it as
a work in progress.
</p>
<p class="commentary"><span class="extract"><span class="extract-syntax">FileIO_Ready</span></span> determines whether or not a file is ready to be read
from: it has to exist on disc, and to be openable, and also to be ready
in having this marker asterisk.
</p>
<p class="commentary"><span class="extract"><span class="extract-syntax">FileIO_MarkReady</span></span> changes the readiness state of a file, writing the
asterisk or hyphen into the initial character as needed.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">FileIO_Ready</span><span class="plain-syntax"> </span><span class="identifier-syntax">extf</span><span class="plain-syntax"> </span><span class="identifier-syntax">struc</span><span class="plain-syntax"> </span><span class="identifier-syntax">fref</span><span class="plain-syntax"> </span><span class="identifier-syntax">usage</span><span class="plain-syntax"> </span><span class="identifier-syntax">str</span><span class="plain-syntax"> </span><span class="identifier-syntax">ch</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">NO_EXTERNAL_FILES</span><span class="plain-syntax">)) </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">struc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TableOfExternalFiles</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">extf</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">struc</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_MAGIC</span><span class="plain-syntax"> ~= </span><span class="identifier-syntax">AUXF_MAGIC_VALUE</span><span class="plain-syntax">)) </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_BINARY</span><span class="plain-syntax">) </span><span class="identifier-syntax">usage</span><span class="plain-syntax"> = </span><span class="identifier-syntax">fileusage_BinaryMode</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">usage</span><span class="plain-syntax"> = </span><span class="identifier-syntax">fileusage_TextMode</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">fref</span><span class="plain-syntax"> = </span><span class="identifier-syntax">glk_fileref_create_by_name</span><span class="plain-syntax">(</span><span class="identifier-syntax">fileusage_Data</span><span class="plain-syntax"> + </span><span class="identifier-syntax">usage</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Glulx_ChangeAnyToCString</span><span class="plain-syntax">(</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_FILENAME</span><span class="plain-syntax">), </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">glk_fileref_does_file_exist</span><span class="plain-syntax">(</span><span class="identifier-syntax">fref</span><span class="plain-syntax">) == </span><span class="reserved-syntax">false</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">glk_fileref_destroy</span><span class="plain-syntax">(</span><span class="identifier-syntax">fref</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">str</span><span class="plain-syntax"> = </span><span class="identifier-syntax">glk_stream_open_file</span><span class="plain-syntax">(</span><span class="identifier-syntax">fref</span><span class="plain-syntax">, </span><span class="identifier-syntax">filemode_Read</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ch</span><span class="plain-syntax"> = </span><span class="identifier-syntax">glk_get_char_stream</span><span class="plain-syntax">(</span><span class="identifier-syntax">str</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">glk_stream_close</span><span class="plain-syntax">(</span><span class="identifier-syntax">str</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">glk_fileref_destroy</span><span class="plain-syntax">(</span><span class="identifier-syntax">fref</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ch</span><span class="plain-syntax"> ~= </span><span class="character-syntax">'*'</span><span class="plain-syntax">) </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">rtrue</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>
<span class="plain-syntax">[ </span><span class="identifier-syntax">FileIO_MarkReady</span><span class="plain-syntax"> </span><span class="identifier-syntax">extf</span><span class="plain-syntax"> </span><span class="identifier-syntax">readiness</span><span class="plain-syntax"> </span><span class="identifier-syntax">struc</span><span class="plain-syntax"> </span><span class="identifier-syntax">fref</span><span class="plain-syntax"> </span><span class="identifier-syntax">str</span><span class="plain-syntax"> </span><span class="identifier-syntax">ch</span><span class="plain-syntax"> </span><span class="identifier-syntax">usage</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">NO_EXTERNAL_FILES</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="string-syntax">"tried to open a non-file"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">struc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TableOfExternalFiles</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">extf</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">struc</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_MAGIC</span><span class="plain-syntax"> ~= </span><span class="identifier-syntax">AUXF_MAGIC_VALUE</span><span class="plain-syntax">)) </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_BINARY</span><span class="plain-syntax">) </span><span class="identifier-syntax">usage</span><span class="plain-syntax"> = </span><span class="identifier-syntax">fileusage_BinaryMode</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">usage</span><span class="plain-syntax"> = </span><span class="identifier-syntax">fileusage_TextMode</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">fref</span><span class="plain-syntax"> = </span><span class="identifier-syntax">glk_fileref_create_by_name</span><span class="plain-syntax">(</span><span class="identifier-syntax">fileusage_Data</span><span class="plain-syntax"> + </span><span class="identifier-syntax">usage</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Glulx_ChangeAnyToCString</span><span class="plain-syntax">(</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_FILENAME</span><span class="plain-syntax">), </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">glk_fileref_does_file_exist</span><span class="plain-syntax">(</span><span class="identifier-syntax">fref</span><span class="plain-syntax">) == </span><span class="reserved-syntax">false</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">glk_fileref_destroy</span><span class="plain-syntax">(</span><span class="identifier-syntax">fref</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="string-syntax">"only existing files can be marked"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STATUS</span><span class="plain-syntax"> ~= </span><span class="identifier-syntax">AUXF_STATUS_IS_CLOSED</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">glk_fileref_destroy</span><span class="plain-syntax">(</span><span class="identifier-syntax">fref</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="string-syntax">"only closed files can be marked"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">str</span><span class="plain-syntax"> = </span><span class="identifier-syntax">glk_stream_open_file</span><span class="plain-syntax">(</span><span class="identifier-syntax">fref</span><span class="plain-syntax">, </span><span class="identifier-syntax">filemode_ReadWrite</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">glk_stream_set_position</span><span class="plain-syntax">(</span><span class="identifier-syntax">str</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">); </span><span class="comment-syntax">seek start</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">readiness</span><span class="plain-syntax">) </span><span class="identifier-syntax">ch</span><span class="plain-syntax"> = </span><span class="character-syntax">'*'</span><span class="plain-syntax">; </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">ch</span><span class="plain-syntax"> = </span><span class="character-syntax">'-'</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">glk_put_char_stream</span><span class="plain-syntax">(</span><span class="identifier-syntax">str</span><span class="plain-syntax">, </span><span class="identifier-syntax">ch</span><span class="plain-syntax">); </span><span class="comment-syntax">mark as complete</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">glk_stream_close</span><span class="plain-syntax">(</span><span class="identifier-syntax">str</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">glk_fileref_destroy</span><span class="plain-syntax">(</span><span class="identifier-syntax">fref</span><span class="plain-syntax">);</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>&#167;8. Open File. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">FileIO_Open</span><span class="plain-syntax"> </span><span class="identifier-syntax">extf</span><span class="plain-syntax"> </span><span class="identifier-syntax">write_flag</span><span class="plain-syntax"> </span><span class="identifier-syntax">append_flag</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">struc</span><span class="plain-syntax"> </span><span class="identifier-syntax">fref</span><span class="plain-syntax"> </span><span class="identifier-syntax">str</span><span class="plain-syntax"> </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> </span><span class="identifier-syntax">ix</span><span class="plain-syntax"> </span><span class="identifier-syntax">ch</span><span class="plain-syntax"> </span><span class="identifier-syntax">not_this_ifid</span><span class="plain-syntax"> </span><span class="identifier-syntax">owner</span><span class="plain-syntax"> </span><span class="identifier-syntax">force_header</span><span class="plain-syntax"> </span><span class="identifier-syntax">usage</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">NO_EXTERNAL_FILES</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="string-syntax">"tried to open a non-file"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">struc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TableOfExternalFiles</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">extf</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">struc</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_MAGIC</span><span class="plain-syntax"> ~= </span><span class="identifier-syntax">AUXF_MAGIC_VALUE</span><span class="plain-syntax">)) </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STATUS</span><span class="plain-syntax"> ~= </span><span class="identifier-syntax">AUXF_STATUS_IS_CLOSED</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="string-syntax">"tried to open a file already open"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_BINARY</span><span class="plain-syntax">) </span><span class="identifier-syntax">usage</span><span class="plain-syntax"> = </span><span class="identifier-syntax">fileusage_BinaryMode</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">usage</span><span class="plain-syntax"> = </span><span class="identifier-syntax">fileusage_TextMode</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">fref</span><span class="plain-syntax"> = </span><span class="identifier-syntax">glk_fileref_create_by_name</span><span class="plain-syntax">(</span><span class="identifier-syntax">fileusage_Data</span><span class="plain-syntax"> + </span><span class="identifier-syntax">usage</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Glulx_ChangeAnyToCString</span><span class="plain-syntax">(</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_FILENAME</span><span class="plain-syntax">), </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">write_flag</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">append_flag</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">filemode_WriteAppend</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">glk_fileref_does_file_exist</span><span class="plain-syntax">(</span><span class="identifier-syntax">fref</span><span class="plain-syntax">) == </span><span class="reserved-syntax">false</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">force_header</span><span class="plain-syntax"> = </span><span class="reserved-syntax">true</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">filemode_Write</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">filemode_Read</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">glk_fileref_does_file_exist</span><span class="plain-syntax">(</span><span class="identifier-syntax">fref</span><span class="plain-syntax">) == </span><span class="reserved-syntax">false</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">glk_fileref_destroy</span><span class="plain-syntax">(</span><span class="identifier-syntax">fref</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="string-syntax">"tried to open a file which does not exist"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">str</span><span class="plain-syntax"> = </span><span class="identifier-syntax">glk_stream_open_file</span><span class="plain-syntax">(</span><span class="identifier-syntax">fref</span><span class="plain-syntax">, </span><span class="identifier-syntax">mode</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">glk_fileref_destroy</span><span class="plain-syntax">(</span><span class="identifier-syntax">fref</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">str</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="string-syntax">"tried to open a file but failed"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STREAM</span><span class="plain-syntax"> = </span><span class="identifier-syntax">str</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">write_flag</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">append_flag</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STATUS</span><span class="plain-syntax"> = </span><span class="identifier-syntax">AUXF_STATUS_IS_OPEN_FOR_APPEND</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STATUS</span><span class="plain-syntax"> = </span><span class="identifier-syntax">AUXF_STATUS_IS_OPEN_FOR_WRITE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">glk_stream_set_current</span><span class="plain-syntax">(</span><span class="identifier-syntax">str</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">append_flag</span><span class="plain-syntax"> == </span><span class="reserved-syntax">false</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">force_header</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"- "</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ix</span><span class="plain-syntax">=6: </span><span class="identifier-syntax">ix</span><span class="plain-syntax"> &lt;= </span><span class="identifier-syntax">UUID_ARRAY</span><span class="plain-syntax">-&gt;0: </span><span class="identifier-syntax">ix</span><span class="plain-syntax">++) </span><span class="reserved-syntax">print</span><span class="plain-syntax"> (</span><span class="identifier-syntax">char</span><span class="plain-syntax">) </span><span class="identifier-syntax">UUID_ARRAY</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">ix</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">" "</span><span class="plain-syntax">, (</span><span class="reserved-syntax">string</span><span class="plain-syntax">) </span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_FILENAME</span><span class="plain-syntax">, </span><span class="string-syntax">"^"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STATUS</span><span class="plain-syntax"> = </span><span class="identifier-syntax">AUXF_STATUS_IS_OPEN_FOR_READ</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ch</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FileIO_GetC</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ch</span><span class="plain-syntax"> ~= </span><span class="character-syntax">'-'</span><span class="plain-syntax"> </span><span class="reserved-syntax">or</span><span class="plain-syntax"> </span><span class="character-syntax">'*'</span><span class="plain-syntax">) { </span><span class="reserved-syntax">jump</span><span class="plain-syntax"> </span><span class="identifier-syntax">BadFile</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ch</span><span class="plain-syntax"> == </span><span class="character-syntax">'-'</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="string-syntax">"tried to open a file which was incomplete"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ch</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FileIO_GetC</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ch</span><span class="plain-syntax"> ~= </span><span class="character-syntax">' '</span><span class="plain-syntax">) { </span><span class="reserved-syntax">jump</span><span class="plain-syntax"> </span><span class="identifier-syntax">BadFile</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ch</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FileIO_GetC</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ch</span><span class="plain-syntax"> ~= </span><span class="character-syntax">'/'</span><span class="plain-syntax">) { </span><span class="reserved-syntax">jump</span><span class="plain-syntax"> </span><span class="identifier-syntax">BadFile</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ch</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FileIO_GetC</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ch</span><span class="plain-syntax"> ~= </span><span class="character-syntax">'/'</span><span class="plain-syntax">) { </span><span class="reserved-syntax">jump</span><span class="plain-syntax"> </span><span class="identifier-syntax">BadFile</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">owner</span><span class="plain-syntax"> = </span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_IFID_OF_OWNER</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ix</span><span class="plain-syntax"> = </span><span class="constant-syntax">3</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">owner</span><span class="plain-syntax"> == </span><span class="identifier-syntax">UUID_ARRAY</span><span class="plain-syntax">) </span><span class="identifier-syntax">ix</span><span class="plain-syntax"> = </span><span class="constant-syntax">8</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">owner</span><span class="plain-syntax"> ~= </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (: </span><span class="identifier-syntax">ix</span><span class="plain-syntax"> &lt;= </span><span class="identifier-syntax">owner</span><span class="plain-syntax">-&gt;0: </span><span class="identifier-syntax">ix</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ch</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FileIO_GetC</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ch</span><span class="plain-syntax"> == -1) { </span><span class="reserved-syntax">jump</span><span class="plain-syntax"> </span><span class="identifier-syntax">BadFile</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ch</span><span class="plain-syntax"> ~= </span><span class="identifier-syntax">owner</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">ix</span><span class="plain-syntax">) </span><span class="identifier-syntax">not_this_ifid</span><span class="plain-syntax"> = </span><span class="reserved-syntax">true</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ch</span><span class="plain-syntax"> == </span><span class="character-syntax">' '</span><span class="plain-syntax">) </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">not_this_ifid</span><span class="plain-syntax"> == </span><span class="reserved-syntax">false</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ch</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FileIO_GetC</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ch</span><span class="plain-syntax"> ~= </span><span class="character-syntax">' '</span><span class="plain-syntax">) { </span><span class="reserved-syntax">jump</span><span class="plain-syntax"> </span><span class="identifier-syntax">BadFile</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ch</span><span class="plain-syntax"> ~= -1) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ch</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FileIO_GetC</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ch</span><span class="plain-syntax"> == </span><span class="constant-syntax">10</span><span class="plain-syntax"> </span><span class="reserved-syntax">or</span><span class="plain-syntax"> </span><span class="constant-syntax">13</span><span class="plain-syntax">) </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">not_this_ifid</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STATUS</span><span class="plain-syntax"> = </span><span class="identifier-syntax">AUXF_STATUS_IS_CLOSED</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">glk_stream_close</span><span class="plain-syntax">(</span><span class="identifier-syntax">str</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"tried to open a file owned by another project"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STREAM</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> .</span><span class="identifier-syntax">BadFile</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STATUS</span><span class="plain-syntax"> = </span><span class="identifier-syntax">AUXF_STATUS_IS_CLOSED</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">glk_stream_close</span><span class="plain-syntax">(</span><span class="identifier-syntax">str</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="string-syntax">"tried to open a file which seems to be malformed"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>&#167;9. Close File. </b>Note that a call to the following, in write mode, must be followed by a
<span class="extract"><span class="extract-syntax">glk_stream_set_current()</span></span>, or else the next print statement will run into
Glk errors.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">FileIO_Close</span><span class="plain-syntax"> </span><span class="identifier-syntax">extf</span><span class="plain-syntax"> </span><span class="identifier-syntax">struc</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">NO_EXTERNAL_FILES</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="string-syntax">"tried to open a non-file"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">struc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TableOfExternalFiles</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">extf</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STATUS</span><span class="plain-syntax"> ~=</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">AUXF_STATUS_IS_OPEN_FOR_READ</span><span class="plain-syntax"> </span><span class="reserved-syntax">or</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">AUXF_STATUS_IS_OPEN_FOR_WRITE</span><span class="plain-syntax"> </span><span class="reserved-syntax">or</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">AUXF_STATUS_IS_OPEN_FOR_APPEND</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="string-syntax">"tried to close a file which is not open"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STATUS</span><span class="plain-syntax"> ==</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">AUXF_STATUS_IS_OPEN_FOR_WRITE</span><span class="plain-syntax"> </span><span class="reserved-syntax">or</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">AUXF_STATUS_IS_OPEN_FOR_APPEND</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">glk_stream_set_position</span><span class="plain-syntax">(</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STREAM</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">); </span><span class="comment-syntax">seek start</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">glk_put_char_stream</span><span class="plain-syntax">(</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STREAM</span><span class="plain-syntax">, </span><span class="character-syntax">'*'</span><span class="plain-syntax">); </span><span class="comment-syntax">mark as complete</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">glk_stream_close</span><span class="plain-syntax">(</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STREAM</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STATUS</span><span class="plain-syntax"> = </span><span class="identifier-syntax">AUXF_STATUS_IS_CLOSED</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>&#167;10. Get Character. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">FileIO_GetC</span><span class="plain-syntax"> </span><span class="identifier-syntax">extf</span><span class="plain-syntax"> </span><span class="identifier-syntax">struc</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">NO_EXTERNAL_FILES</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> -1;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">struc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TableOfExternalFiles</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">extf</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STATUS</span><span class="plain-syntax"> ~= </span><span class="identifier-syntax">AUXF_STATUS_IS_OPEN_FOR_READ</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> -1;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">glk_get_char_stream</span><span class="plain-syntax">(</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STREAM</span><span class="plain-syntax">);</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>&#167;11. Put Character. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">FileIO_PutC</span><span class="plain-syntax"> </span><span class="identifier-syntax">extf</span><span class="plain-syntax"> </span><span class="identifier-syntax">char</span><span class="plain-syntax"> </span><span class="identifier-syntax">struc</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">NO_EXTERNAL_FILES</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> -1;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="string-syntax">"tried to write to a non-file"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">struc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TableOfExternalFiles</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">extf</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STATUS</span><span class="plain-syntax"> ~=</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">AUXF_STATUS_IS_OPEN_FOR_WRITE</span><span class="plain-syntax"> </span><span class="reserved-syntax">or</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">AUXF_STATUS_IS_OPEN_FOR_APPEND</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"tried to write to a file which is not open for writing"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">glk_put_char_stream</span><span class="plain-syntax">(</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_STREAM</span><span class="plain-syntax">, </span><span class="identifier-syntax">char</span><span class="plain-syntax">);</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>&#167;12. Print Line. </b>We read characters from the supplied file until the next newline
character. (We allow for that to be encoded as either a single <span class="extract"><span class="extract-syntax">0a</span></span> or a
single <span class="extract"><span class="extract-syntax">0d</span></span>.) Each character is printed, and at the end we print a newline.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">FileIO_PrintLine</span><span class="plain-syntax"> </span><span class="identifier-syntax">extf</span><span class="plain-syntax"> </span><span class="identifier-syntax">ch</span><span class="plain-syntax"> </span><span class="identifier-syntax">struc</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">NO_EXTERNAL_FILES</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="string-syntax">"tried to write to a non-file"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">struc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TableOfExternalFiles</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">extf</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (::) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ch</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FileIO_GetC</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ch</span><span class="plain-syntax"> == -1) </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ch</span><span class="plain-syntax"> == </span><span class="constant-syntax">10</span><span class="plain-syntax"> </span><span class="reserved-syntax">or</span><span class="plain-syntax"> </span><span class="constant-syntax">13</span><span class="plain-syntax">) { </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"^"</span><span class="plain-syntax">; </span><span class="reserved-syntax">rtrue</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">print</span><span class="plain-syntax"> (</span><span class="identifier-syntax">char</span><span class="plain-syntax">) </span><span class="identifier-syntax">ch</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP13" class="paragraph-anchor"></a><b>&#167;13. Print Contents. </b>Repeating this until the file runs out is equivalent to the Unix command
<span class="extract"><span class="extract-syntax">cat</span></span>, that is, it copies the stream of characters from the file to the
output stream. (This might well be another file, just as with <span class="extract"><span class="extract-syntax">cat</span></span>, in
which case we have a copy utility.)
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">FileIO_PrintContents</span><span class="plain-syntax"> </span><span class="identifier-syntax">extf</span><span class="plain-syntax"> </span><span class="identifier-syntax">tab</span><span class="plain-syntax"> </span><span class="identifier-syntax">struc</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">NO_EXTERNAL_FILES</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="string-syntax">"tried to access a non-file"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">struc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TableOfExternalFiles</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">extf</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_BINARY</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="string-syntax">"printing text will not work with binary files"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">FileIO_Open</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="reserved-syntax">false</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">FileIO_PrintLine</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">)) ;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Close</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">rtrue</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP14" class="paragraph-anchor"></a><b>&#167;14. Print Text. </b>The following writes a given piece of text as the new content of the file,
either as the whole file (if <span class="extract"><span class="extract-syntax">append_flag</span></span> is false) or adding only to the
end (if true).
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">FileIO_PutContents</span><span class="plain-syntax"> </span><span class="identifier-syntax">extf</span><span class="plain-syntax"> </span><span class="identifier-syntax">text</span><span class="plain-syntax"> </span><span class="identifier-syntax">append_flag</span><span class="plain-syntax"> </span><span class="identifier-syntax">struc</span><span class="plain-syntax"> </span><span class="identifier-syntax">str</span><span class="plain-syntax"> </span><span class="identifier-syntax">ch</span><span class="plain-syntax"> </span><span class="identifier-syntax">oldstream</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">NO_EXTERNAL_FILES</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="string-syntax">"tried to access a non-file"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">struc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TableOfExternalFiles</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">extf</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_BINARY</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="string-syntax">"writing text will not work with binary files"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">oldstream</span><span class="plain-syntax"> = </span><span class="identifier-syntax">glk_stream_get_current</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">str</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FileIO_Open</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="reserved-syntax">true</span><span class="plain-syntax">, </span><span class="identifier-syntax">append_flag</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">str</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> @</span><span class="identifier-syntax">push</span><span class="plain-syntax"> </span><span class="identifier-syntax">say__p</span><span class="plain-syntax">; @</span><span class="identifier-syntax">push</span><span class="plain-syntax"> </span><span class="identifier-syntax">say__pc</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ClearParagraphing</span><span class="plain-syntax">(19);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEXT_TY_Say</span><span class="plain-syntax">(</span><span class="identifier-syntax">text</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Close</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">oldstream</span><span class="plain-syntax">) </span><span class="identifier-syntax">glk_stream_set_current</span><span class="plain-syntax">(</span><span class="identifier-syntax">oldstream</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> @</span><span class="identifier-syntax">pull</span><span class="plain-syntax"> </span><span class="identifier-syntax">say__pc</span><span class="plain-syntax">; @</span><span class="identifier-syntax">pull</span><span class="plain-syntax"> </span><span class="identifier-syntax">say__p</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP15" class="paragraph-anchor"></a><b>&#167;15. Serialising Tables. </b>The most important data structures to "serialise" &mdash; that is, to convert
from their binary representations in memory into text representations in an
external file &mdash; are Tables. Here we only carry out the file-handling; the
actual translations are in "Tables.i6t".
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">FileIO_PutTable</span><span class="plain-syntax"> </span><span class="identifier-syntax">extf</span><span class="plain-syntax"> </span><span class="identifier-syntax">tab</span><span class="plain-syntax"> </span><span class="identifier-syntax">rv</span><span class="plain-syntax"> </span><span class="identifier-syntax">struc</span><span class="plain-syntax"> </span><span class="identifier-syntax">oldstream</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">NO_EXTERNAL_FILES</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="string-syntax">"tried to write table to a non-file"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">struc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TableOfExternalFiles</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">extf</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_BINARY</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="string-syntax">"writing a table will not work with binary files"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">oldstream</span><span class="plain-syntax"> = </span><span class="identifier-syntax">glk_stream_get_current</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">FileIO_Open</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="reserved-syntax">true</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">rv</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TablePrint</span><span class="plain-syntax">(</span><span class="identifier-syntax">tab</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Close</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">oldstream</span><span class="plain-syntax">) </span><span class="identifier-syntax">glk_stream_set_current</span><span class="plain-syntax">(</span><span class="identifier-syntax">oldstream</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">rv</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">RunTimeProblem</span><span class="plain-syntax">(</span><span class="identifier-syntax">RTP_TABLE_CANTSAVE</span><span class="plain-syntax">, </span><span class="identifier-syntax">tab</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">rtrue</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>
<span class="plain-syntax">[ </span><span class="identifier-syntax">FileIO_GetTable</span><span class="plain-syntax"> </span><span class="identifier-syntax">extf</span><span class="plain-syntax"> </span><span class="identifier-syntax">tab</span><span class="plain-syntax"> </span><span class="identifier-syntax">struc</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">extf</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">NO_EXTERNAL_FILES</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="string-syntax">"tried to read table from a non-file"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">struc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TableOfExternalFiles</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">extf</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">struc</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">AUXF_BINARY</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="string-syntax">"reading a table will not work with binary files"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">FileIO_Open</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="reserved-syntax">false</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TableRead</span><span class="plain-syntax">(</span><span class="identifier-syntax">tab</span><span class="plain-syntax">, </span><span class="identifier-syntax">extf</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Close</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">rtrue</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP16" class="paragraph-anchor"></a><b>&#167;16. Z-Machine Stubs. </b>These routines do the minimum possible, but equally, they only generate a
run-time problem when there is no alternative.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">#</span><span class="identifier-syntax">IFNOT</span><span class="plain-syntax">; </span><span class="comment-syntax">TARGET_GLULX</span>
<span class="plain-syntax">[ </span><span class="identifier-syntax">FileIO_Exists</span><span class="plain-syntax"> </span><span class="identifier-syntax">extf</span><span class="plain-syntax">; </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">; ];</span>
<span class="plain-syntax">[ </span><span class="identifier-syntax">FileIO_Ready</span><span class="plain-syntax"> </span><span class="identifier-syntax">extf</span><span class="plain-syntax">; </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">; ];</span>
<span class="plain-syntax">[ </span><span class="identifier-syntax">FileIO_GetC</span><span class="plain-syntax"> </span><span class="identifier-syntax">extf</span><span class="plain-syntax">; </span><span class="reserved-syntax">return</span><span class="plain-syntax"> -1; ];</span>
<span class="plain-syntax">[ </span><span class="identifier-syntax">FileIO_PutTable</span><span class="plain-syntax"> </span><span class="identifier-syntax">extf</span><span class="plain-syntax"> </span><span class="identifier-syntax">tab</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FileIO_Error</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">, </span><span class="string-syntax">"external files can only be used under Glulx"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">];</span>
<span class="plain-syntax">[ </span><span class="identifier-syntax">FileIO_MarkReady</span><span class="plain-syntax"> </span><span class="identifier-syntax">extf</span><span class="plain-syntax"> </span><span class="identifier-syntax">status</span><span class="plain-syntax">; </span><span class="identifier-syntax">FileIO_PutTable</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">); ];</span>
<span class="plain-syntax">[ </span><span class="identifier-syntax">FileIO_GetTable</span><span class="plain-syntax"> </span><span class="identifier-syntax">extf</span><span class="plain-syntax"> </span><span class="identifier-syntax">tab</span><span class="plain-syntax">; </span><span class="identifier-syntax">FileIO_PutTable</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">); ];</span>
<span class="plain-syntax">[ </span><span class="identifier-syntax">FileIO_PrintContents</span><span class="plain-syntax"> </span><span class="identifier-syntax">extf</span><span class="plain-syntax">; </span><span class="identifier-syntax">FileIO_PutTable</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">); ];</span>
<span class="plain-syntax">[ </span><span class="identifier-syntax">FileIO_PutContents</span><span class="plain-syntax"> </span><span class="identifier-syntax">extf</span><span class="plain-syntax">; </span><span class="identifier-syntax">FileIO_PutTable</span><span class="plain-syntax">(</span><span class="identifier-syntax">extf</span><span class="plain-syntax">); ];</span>
<span class="plain-syntax">#</span><span class="identifier-syntax">ENDIF</span><span class="plain-syntax">; </span><span class="comment-syntax">TARGET_GLULX</span>
</pre>
<p class="commentary firstcommentary"><a id="SP17" class="paragraph-anchor"></a><b>&#167;17. Back To Core. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">#</span><span class="identifier-syntax">IFNOT</span><span class="plain-syntax">; </span><span class="comment-syntax">FILES_PLUGIN</span>
<span class="plain-syntax">[ </span><span class="identifier-syntax">FileIO_GetC</span><span class="plain-syntax"> </span><span class="identifier-syntax">extf</span><span class="plain-syntax">; </span><span class="reserved-syntax">return</span><span class="plain-syntax"> -1; ];</span>
<span class="plain-syntax">#</span><span class="identifier-syntax">ENDIF</span><span class="plain-syntax">; </span><span class="comment-syntax">FILES_PLUGIN</span>
</pre>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="S-mth.html">&#10094;</a></li><li class="progresssection"><a href="S-dfn.html">dfn</a></li><li class="progresssection"><a href="S-utl.html">utl</a></li><li class="progresssection"><a href="S-gll.html">gll</a></li><li class="progresssection"><a href="S-zmc.html">zmc</a></li><li class="progresssection"><a href="S-prg.html">prg</a></li><li class="progresssection"><a href="S-mth.html">mth</a></li><li class="progresscurrent">fl</li><li class="progresssection"><a href="S-srt.html">srt</a></li><li class="progresssection"><a href="S-tbl.html">tbl</a></li><li class="progresssection"><a href="S-mst.html">mst</a></li><li class="progresssection"><a href="S-rlb.html">rlb</a></li><li class="progresssection"><a href="S-flx.html">flx</a></li><li class="progresssection"><a href="S-blc.html">blc</a></li><li class="progresssection"><a href="S-txt.html">txt</a></li><li class="progresssection"><a href="S-unc.html">unc</a></li><li class="progresssection"><a href="S-chr.html">chr</a></li><li class="progresssection"><a href="S-rgx.html">rgx</a></li><li class="progresssection"><a href="S-lst.html">lst</a></li><li class="progresssection"><a href="S-cmb.html">cmb</a></li><li class="progresssection"><a href="S-rlt.html">rlt</a></li><li class="progresssection"><a href="S-rlt2.html">rlt2</a></li><li class="progresssection"><a href="S-rtp.html">rtp</a></li><li class="progressnext"><a href="S-srt.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>
</body>
</html>