mirror of
https://github.com/ganelson/inform.git
synced 2024-07-08 18:14:21 +03:00
392 lines
44 KiB
HTML
392 lines
44 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<title>2/si</title>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
<meta http-equiv="Content-Language" content="en-gb">
|
|
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
</head>
|
|
<body>
|
|
|
|
<!--Weave of '3/rst' generated by 7-->
|
|
<ul class="crumbs"><li><a href="../webs.html">★</a></li><li><a href="index.html">core</a></li><li><a href="index.html#3">Chapter 3: Bridge to Words Module</a></li><li><b>Read Source Text</b></li></ul><p class="purpose">This is where source text is read in, whether from extension files or from the main source text file, and fed into the lexer.</p>
|
|
|
|
<ul class="toc"><li><a href="#SP1">§1. Definitions</a></li></ul><hr class="tocbar">
|
|
|
|
<p class="inwebparagraph"><a id="SP1"></a><b>§1. Definitions. </b></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP2"></a><b>§2. </b>The source text is drawn almost entirely from the primary source file and
|
|
the extensions, but Inform does also inject small amounts of source text of
|
|
its own (for instance, when a new kind is created, the kind interpreter
|
|
does this).
|
|
</p>
|
|
|
|
<p class="inwebparagraph">In particular, every source text read into Inform is automatically prefixed by
|
|
the following eight words — if Inform were a computer, this would be the BIOS
|
|
which boots up its operating system. (In that the rest of the creation of the
|
|
I7 world model is handled by source text in the Standard Rules.)
|
|
</p>
|
|
|
|
<p class="inwebparagraph">Because of this mandatory insertion, one extension, the Standard Rules, is
|
|
compulsorily included in every run. So there will certainly be at least two
|
|
files of source text to be read, and quite possibly more.
|
|
</p>
|
|
|
|
|
|
<pre class="definitions">
|
|
<span class="definitionkeyword">define</span> <span class="constant">MANDATORY_INSERTED_TEXT</span><span class="plain"> </span><span class="identifier">L</span><span class="string">"Include Basic Inform by Graham Nelson. Include the Standard Rules by Graham Nelson.\</span><span class="plain">n</span><span class="string">\</span><span class="plain">n</span><span class="string">"</span>
|
|
</pre>
|
|
|
|
<pre class="display">
|
|
<span class="identifier">source_file</span><span class="plain"> *</span><span class="identifier">primary_source_file</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span> <span class="comment">first to be opened</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3"></a><b>§3. </b>There is no real difference between the loading of the primary source text
|
|
and the loading of an extension's text, except for the descriptions we
|
|
supply in case of any problem messages which might need to be issued,
|
|
and for the fact that the mandatory insertion text is loaded before the
|
|
primary source text.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">SourceFiles::read_extension_source_text</span><span class="plain">(</span><span class="reserved">extension_file</span><span class="plain"> *</span><span class="identifier">EF</span><span class="plain">,</span>
|
|
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">synopsis</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">documentation_only</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain"> = </span><span class="functiontext">SourceFiles::read_file</span><span class="plain">(</span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">synopsis</span><span class="plain">, </span><span class="identifier">EF</span><span class="plain">, </span><span class="identifier">documentation_only</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Log::aspect_switched_on</span><span class="plain">(</span><span class="identifier">LEXICAL_OUTPUT_DA</span><span class="plain">)) </span><span class="identifier">Word::log_lexer_output</span><span class="plain">();</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">SourceFiles::read_primary_source_text</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="identifier">Feeds::feed_text</span><span class="plain">(</span><span class="constant">MANDATORY_INSERTED_TEXT</span><span class="plain">);</span>
|
|
<span class="functiontext">SourceFiles::read_further_mandatory_text</span><span class="plain">();</span>
|
|
<span class="functiontext">SourceFiles::read_file</span><span class="plain">(</span><span class="identifier">filename_of_i7_source</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"your source text"</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function SourceFiles::read_extension_source_text is used in 8/ie (<a href="8-ie.html#SP5_2">§5.2</a>).</p>
|
|
|
|
<p class="endnote">The function SourceFiles::read_primary_source_text is used in 1/mr (<a href="1-mr.html#SP4_8">§4.8</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP4"></a><b>§4. </b>The following reads in the text of the optional file of use options, if
|
|
this has been created, producing no problem message if it hasn't.
|
|
</p>
|
|
|
|
|
|
<pre class="definitions">
|
|
<span class="definitionkeyword">define</span> <span class="constant">SENTENCE_COUNT_MONITOR</span><span class="plain"> </span><span class="functiontext">SourceFiles::increase_sentence_count</span>
|
|
</pre>
|
|
|
|
<pre class="display">
|
|
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">options_file_wording</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING_INIT</span><span class="plain">;</span>
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">SourceFiles::read_further_mandatory_text</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="identifier">feed_t</span><span class="plain"> </span><span class="identifier">id</span><span class="plain"> = </span><span class="identifier">Feeds::begin</span><span class="plain">();</span>
|
|
<span class="identifier">TextFiles::read</span><span class="plain">(</span><span class="identifier">filename_of_options</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">,</span>
|
|
<span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="functiontext">SourceFiles::read_further_mandatory_text_helper</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
|
|
<span class="identifier">options_file_wording</span><span class="plain"> = </span><span class="identifier">Feeds::end</span><span class="plain">(</span><span class="identifier">id</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">SourceFiles::read_further_mandatory_text_helper</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">line</span><span class="plain">,</span>
|
|
<span class="identifier">text_file_position</span><span class="plain"> *</span><span class="identifier">tfp</span><span class="plain">, </span><span class="reserved">void</span><span class="plain"> *</span><span class="identifier">unused_state</span><span class="plain">) {</span>
|
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">line</span><span class="plain">, </span><span class="string">"\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
|
|
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain"> = </span><span class="identifier">Feeds::feed_stream</span><span class="plain">(</span><span class="identifier">line</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (<</span><span class="identifier">use</span><span class="plain">-</span><span class="identifier">option</span><span class="plain">-</span><span class="identifier">sentence</span><span class="plain">-</span><span class="identifier">shape</span><span class="plain">>(</span><span class="identifier">W</span><span class="plain">)) </span><span class="functiontext">UseOptions::set_immediate_option_flags</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">SourceFiles::increase_sentence_count</span><span class="plain">(</span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::within</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">options_file_wording</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function SourceFiles::read_further_mandatory_text is used in <a href="#SP3">§3</a>.</p>
|
|
|
|
<p class="endnote">The function SourceFiles::read_further_mandatory_text_helper appears nowhere else.</p>
|
|
|
|
<p class="endnote">The function SourceFiles::increase_sentence_count appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP5"></a><b>§5. </b>Either way, we use the following code. The <code class="display"><span class="extract">SourceFiles::read_file</span></code> function returns
|
|
one of the following values to indicate the source of the source: the value
|
|
only really tells us something we didn't know in the case of extensions,
|
|
but in that event the Extensions.w routines do indeed want to know this.
|
|
(Area 51 is reserved for extensions of alien origin, but the relevant
|
|
source code is classified.)
|
|
</p>
|
|
|
|
|
|
<pre class="definitions">
|
|
<span class="definitionkeyword">define</span> <span class="constant">ORIGIN_WAS_PRIMARY_SOURCE</span><span class="plain"> 0</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">ORIGIN_WAS_MATERIALS_EXTENSIONS_AREA</span><span class="plain"> 1 </span> <span class="comment">must match <code class="display"><span class="extract">*_FS_AREA</span></code> numbers plus 1</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">ORIGIN_WAS_USER_EXTENSIONS_AREA</span><span class="plain"> 2</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">ORIGIN_WAS_BUILT_IN_EXTENSIONS_AREA</span><span class="plain"> 3</span>
|
|
</pre>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">SourceFiles::read_file</span><span class="plain">(</span><span class="identifier">filename</span><span class="plain"> *</span><span class="identifier">F</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">synopsis</span><span class="plain">, </span><span class="reserved">extension_file</span><span class="plain"> *</span><span class="identifier">EF</span><span class="plain">,</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">documentation_only</span><span class="plain">) {</span>
|
|
<span class="identifier">source_file</span><span class="plain"> *</span><span class="identifier">sf</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">area</span><span class="plain"> = -1;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">EF</span><span class="plain">)</span>
|
|
<span class="identifier">area</span><span class="plain"> = </span><span class="functiontext">SourceFiles::read_file_inner</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">, </span><span class="identifier">synopsis</span><span class="plain">,</span>
|
|
<span class="identifier">pathname_of_extensions</span><span class="plain">, </span><span class="constant">NO_FS_AREAS</span><span class="plain"> + 1, </span><span class="identifier">documentation_only</span><span class="plain">, &</span><span class="identifier">sf</span><span class="plain">,</span>
|
|
<span class="identifier">STORE_POINTER_extension_file</span><span class="plain">(</span><span class="identifier">EF</span><span class="plain">), </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="identifier">EF</span><span class="plain">);</span>
|
|
<span class="reserved">else</span>
|
|
<span class="identifier">area</span><span class="plain"> = </span><span class="functiontext">SourceFiles::read_file_inner</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">, </span><span class="identifier">synopsis</span><span class="plain">,</span>
|
|
<span class="identifier">NULL</span><span class="plain">, 0, </span><span class="identifier">documentation_only</span><span class="plain">, &</span><span class="identifier">sf</span><span class="plain">,</span>
|
|
<span class="identifier">STORE_POINTER_extension_file</span><span class="plain">(</span><span class="identifier">NULL</span><span class="plain">), </span><span class="identifier">TRUE</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">area</span><span class="plain"> == -1) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">EF</span><span class="plain">) {</span>
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Author: %W\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">EF</span><span class="plain">-</span><span class="element">>author_text</span><span class="plain">);</span>
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Title: %W\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">EF</span><span class="plain">-</span><span class="element">>title_text</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::quote_stream</span><span class="plain">(2, </span><span class="identifier">synopsis</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_BogusExtension</span><span class="plain">));</span>
|
|
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
|
|
<span class="string">"I can't find the extension '%2', which seems not to be installed, "</span>
|
|
<span class="string">"but was requested by: %1. %P"</span>
|
|
<span class="string">"You can get hold of extensions which people have made public at "</span>
|
|
<span class="string">"the Inform website, www.inform7.com, or by using the Public "</span>
|
|
<span class="string">"Library in the Extensions panel."</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="identifier">Problems::Fatal::filename_related</span><span class="plain">(</span>
|
|
<span class="string">"Error: can't open source text file"</span><span class="plain">, </span><span class="identifier">F</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">EF</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">primary_source_file</span><span class="plain"> = </span><span class="identifier">sf</span><span class="plain">;</span>
|
|
<span class="reserved">else</span><span class="plain"> </span><span class="functiontext">Extensions::Files::set_corresponding_source_file</span><span class="plain">(</span><span class="identifier">EF</span><span class="plain">, </span><span class="identifier">sf</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">documentation_only</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) </span><<span class="cwebmacro">Tell console output about the file</span> <span class="cwebmacronumber">5.1</span>><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">area</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function SourceFiles::read_file is used in <a href="#SP3">§3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP5_1"></a><b>§5.1. </b>This is where messages like
|
|
</p>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain">I've also read Standard Rules by Graham Nelson, which is 27204 words long.</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph">are printed to <code class="display"><span class="extract">stdout</span></code> (not <code class="display"><span class="extract">stderr</span></code>), in something of an affectionate nod
|
|
to TeX's traditional console output, though occasionally I think silence is
|
|
golden and that the messages could go. It's a moot point for almost all users,
|
|
though, because the console output is concealed from them by the Inform
|
|
application.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Tell console output about the file</span> <span class="cwebmacronumber">5.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">wc</span><span class="plain">;</span>
|
|
<span class="reserved">char</span><span class="plain"> *</span><span class="identifier">message</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">EF</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">message</span><span class="plain"> = </span><span class="string">"I've now read %S, which is %d words long.\</span><span class="plain">n</span><span class="string">"</span><span class="plain">;</span>
|
|
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">message</span><span class="plain"> = </span><span class="string">"I've also read %S, which is %d words long.\</span><span class="plain">n</span><span class="string">"</span><span class="plain">;</span>
|
|
<span class="identifier">wc</span><span class="plain"> = </span><span class="identifier">TextFromFiles::total_word_count</span><span class="plain">(</span><span class="identifier">sf</span><span class="plain">);</span>
|
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">STDOUT</span><span class="plain">, </span><span class="identifier">message</span><span class="plain">, </span><span class="identifier">synopsis</span><span class="plain">, </span><span class="identifier">wc</span><span class="plain">);</span>
|
|
<span class="identifier">STREAM_FLUSH</span><span class="plain">(</span><span class="identifier">STDOUT</span><span class="plain">);</span>
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="identifier">message</span><span class="plain">, </span><span class="identifier">synopsis</span><span class="plain">, </span><span class="identifier">wc</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP5">§5</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP6"></a><b>§6. </b></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">SourceFiles::read_file_inner</span><span class="plain">(</span><span class="identifier">filename</span><span class="plain"> *</span><span class="identifier">F</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">synopsis</span><span class="plain">,</span>
|
|
<span class="identifier">pathname</span><span class="plain"> **</span><span class="identifier">list</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">list_len</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">documentation_only</span><span class="plain">, </span><span class="identifier">source_file</span><span class="plain"> **</span><span class="identifier">S</span><span class="plain">,</span>
|
|
<span class="identifier">general_pointer</span><span class="plain"> </span><span class="identifier">ref</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">primary</span><span class="plain">, </span><span class="reserved">extension_file</span><span class="plain"> *</span><span class="identifier">EF</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">origin_tried</span><span class="plain"> = 1;</span>
|
|
|
|
<span class="reserved">FILE</span><span class="plain"> *</span><span class="identifier">handle</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span><span class="identifier">filename</span><span class="plain"> *</span><span class="identifier">eventual</span><span class="plain"> = </span><span class="identifier">F</span><span class="plain">;</span>
|
|
<<span class="cwebmacro">Set pathname and filename, and open file</span> <span class="cwebmacronumber">6.1</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">handle</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> -1;</span>
|
|
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">leaf</span><span class="plain"> = </span><span class="identifier">Filenames::get_leafname</span><span class="plain">(</span><span class="identifier">eventual</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">primary</span><span class="plain">) </span><span class="identifier">leaf</span><span class="plain"> = </span><span class="identifier">I</span><span class="string">"main source text"</span><span class="plain">;</span>
|
|
<span class="identifier">source_file</span><span class="plain"> *</span><span class="identifier">sf</span><span class="plain"> = </span><span class="identifier">TextFromFiles::feed_open_file_into_lexer</span><span class="plain">(</span><span class="identifier">eventual</span><span class="plain">, </span><span class="identifier">handle</span><span class="plain">,</span>
|
|
<span class="identifier">leaf</span><span class="plain">, </span><span class="identifier">documentation_only</span><span class="plain">, </span><span class="identifier">ref</span><span class="plain">);</span>
|
|
<span class="identifier">fclose</span><span class="plain">(</span><span class="identifier">handle</span><span class="plain">);</span>
|
|
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">S</span><span class="plain">) *</span><span class="identifier">S</span><span class="plain"> = </span><span class="identifier">sf</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">origin_tried</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function SourceFiles::read_file_inner is used in <a href="#SP5">§5</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP6_1"></a><b>§6.1. </b>The primary source text must be found where we expect it, or a fatal
|
|
error is issued. An extension, however, can be in one of two places: the
|
|
user's own repository of installed extensions, or the built-in stock. We
|
|
must try each possibility — in that order, so that the user can supplant
|
|
the built-in extensions by installing hacked versions of her own — and in
|
|
the event of failing, we issue only a standard Inform problem message and
|
|
continue. While meaningful compilation is unlikely to succeed now, this is
|
|
not a fatal error, because fatality would cause the user interface
|
|
application to communicate the problem badly.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Set pathname and filename, and open file</span> <span class="cwebmacronumber">6.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">handle</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">list</span><span class="plain">) {</span>
|
|
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">author_name</span><span class="plain">);</span>
|
|
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">title</span><span class="plain">);</span>
|
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">author_name</span><span class="plain">, </span><span class="string">"%W"</span><span class="plain">, </span><span class="identifier">EF</span><span class="plain">-</span><span class="element">>author_text</span><span class="plain">);</span>
|
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">title</span><span class="plain">, </span><span class="string">"%W"</span><span class="plain">, </span><span class="identifier">EF</span><span class="plain">-</span><span class="element">>title_text</span><span class="plain">);</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">area</span><span class="plain">=0; </span><span class="identifier">area</span><span class="plain"><</span><span class="identifier">list_len</span><span class="plain">; </span><span class="identifier">area</span><span class="plain">++)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">handle</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
|
|
<span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain"> = </span><span class="identifier">list</span><span class="plain">[</span><span class="identifier">area</span><span class="plain">];</span>
|
|
<span class="identifier">origin_tried</span><span class="plain"> = </span><span class="identifier">area</span><span class="plain"> + 1;</span>
|
|
<span class="identifier">eventual</span><span class="plain"> = </span><span class="functiontext">Locations::of_extension</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">title</span><span class="plain">, </span><span class="identifier">author_name</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
|
|
<span class="identifier">handle</span><span class="plain"> = </span><span class="identifier">Filenames::fopen_caseless</span><span class="plain">(</span><span class="identifier">eventual</span><span class="plain">, </span><span class="string">"r"</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">handle</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
|
|
<span class="identifier">eventual</span><span class="plain"> = </span><span class="functiontext">Locations::of_extension</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">title</span><span class="plain">, </span><span class="identifier">author_name</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
|
|
<span class="identifier">handle</span><span class="plain"> = </span><span class="identifier">Filenames::fopen_caseless</span><span class="plain">(</span><span class="identifier">eventual</span><span class="plain">, </span><span class="string">"r"</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">author_name</span><span class="plain">);</span>
|
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">title</span><span class="plain">);</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="identifier">handle</span><span class="plain"> = </span><span class="identifier">Filenames::fopen</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">, </span><span class="string">"r"</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP6">§6</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP7"></a><b>§7. </b></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">extension_file</span><span class="plain"> *</span><span class="functiontext">SourceFiles::get_extension_corresponding</span><span class="plain">(</span><span class="identifier">source_file</span><span class="plain"> *</span><span class="identifier">sf</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sf</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">RETRIEVE_POINTER_extension_file</span><span class="plain">(</span><span class="identifier">sf</span><span class="plain">-></span><span class="identifier">your_ref</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function SourceFiles::get_extension_corresponding is used in 4/am (<a href="4-am.html#SP26_1">§26.1</a>), 6/nv (<a href="6-nv.html#SP14_1">§14.1</a>), 7/hdn (<a href="7-hdn.html#SP16">§16</a>, <a href="7-hdn.html#SP33_1_1">§33.1.1</a>), 8/ef (<a href="8-ef.html#SP21">§21</a>), 9/tfa (<a href="9-tfa.html#SP11_1">§11.1</a>), 17/rs (<a href="17-rs.html#SP7_3_1">§7.3.1</a>), 21/rl2 (<a href="21-rl2.html#SP23_10_1">§23.10.1</a>, <a href="21-rl2.html#SP24">§24</a>), 25/ci (<a href="25-ci.html#SP3_2_3_6">§3.2.3.6</a>), 26/uo (<a href="26-uo.html#SP11_1">§11.1</a>, <a href="26-uo.html#SP13_1">§13.1</a>, <a href="26-uo.html#SP16">§16</a>), 27/cm (<a href="27-cm.html#SP2">§2</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP8"></a><b>§8. </b>And the following converts lexer error conditions into I7 problem messages.
|
|
</p>
|
|
|
|
|
|
<pre class="definitions">
|
|
<span class="definitionkeyword">define</span> <span class="constant">LEXER_PROBLEM_HANDLER</span><span class="plain"> </span><span class="functiontext">SourceFiles::lexer_problem_handler</span>
|
|
</pre>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">SourceFiles::lexer_problem_handler</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">err</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">problem_source_description</span><span class="plain">, </span><span class="identifier">wchar_t</span><span class="plain"> *</span><span class="identifier">word</span><span class="plain">) {</span>
|
|
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">err</span><span class="plain">) {</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">MEMORY_OUT_LEXERERROR</span><span class="plain">:</span>
|
|
<span class="identifier">Problems::Fatal::issue</span><span class="plain">(</span><span class="string">"Out of memory: unable to create lexer workspace"</span><span class="plain">);</span>
|
|
<span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">STRING_TOO_LONG_LEXERERROR</span><span class="plain">:</span>
|
|
<span class="identifier">Problems::Issue::lexical_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_TooMuchQuotedText</span><span class="plain">),</span>
|
|
<span class="string">"Too much text in quotation marks"</span><span class="plain">, </span><span class="identifier">word</span><span class="plain">,</span>
|
|
<span class="string">"...\</span><span class="plain">"</span><span class="string"> The maximum length is very high, so this is more "</span>
|
|
<span class="string">"likely to be because a close quotation mark was "</span>
|
|
<span class="string">"forgotten."</span><span class="plain">);</span>
|
|
<span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">WORD_TOO_LONG_LEXERERROR</span><span class="plain">:</span>
|
|
<span class="identifier">Problems::Issue::lexical_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_WordTooLong</span><span class="plain">),</span>
|
|
<span class="string">"Word too long"</span><span class="plain">, </span><span class="identifier">word</span><span class="plain">,</span>
|
|
<span class="string">"(Individual words of unquoted text can run up to "</span>
|
|
<span class="string">"128 letters long, which ought to be plenty. The longest "</span>
|
|
<span class="string">"recognised place name in the English speaking world is "</span>
|
|
<span class="string">"a hill in New Zealand called Taumatawhakatang-"</span>
|
|
<span class="string">"ihangakoauauot-amateaturipukaka-pikimaunga-"</span>
|
|
<span class="string">"horonuku-pokaiwhenuak-itanatahu. (You say tomato, "</span>
|
|
<span class="string">"I say taumatawhakatang-...) The longest word found in a "</span>
|
|
<span class="string">"classic novel is bababadalgharaghtakamminarronnkonnbronntonn"</span>
|
|
<span class="string">"erronntuonnthunntrovarrhounawnskawntoohoohoordenenthurnuk, "</span>
|
|
<span class="string">"creation's thunderclap from Finnegan's Wake. And both of those "</span>
|
|
<span class="string">"words are fine.)"</span><span class="plain">);</span>
|
|
<span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">I6_TOO_LONG_LEXERERROR</span><span class="plain">:</span>
|
|
<span class="identifier">Problems::Issue::lexical_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">Untestable</span><span class="plain">), </span> <span class="comment">well, not at all conveniently</span>
|
|
<span class="string">"Verbatim Inform 6 extract too long"</span><span class="plain">, </span><span class="identifier">word</span><span class="plain">,</span>
|
|
<span class="string">"... -). The maximum length is quite high, so this "</span>
|
|
<span class="string">"may be because a '-)' was forgotten. Still, if "</span>
|
|
<span class="string">"you do need to paste a huge I6 program in, try "</span>
|
|
<span class="string">"using several verbatim inclusions in a row."</span><span class="plain">);</span>
|
|
<span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">STRING_NEVER_ENDS_LEXERERROR</span><span class="plain">:</span>
|
|
<span class="identifier">Problems::Issue::lexical_problem_S</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_UnendingQuote</span><span class="plain">),</span>
|
|
<span class="string">"Some source text ended in the middle of quoted text"</span><span class="plain">,</span>
|
|
<span class="identifier">problem_source_description</span><span class="plain">,</span>
|
|
<span class="string">"This probably means that a quotation mark is missing "</span>
|
|
<span class="string">"somewhere. If you are using Inform with syntax colouring, "</span>
|
|
<span class="string">"look for where the quoted-text colour starts. (Sometimes "</span>
|
|
<span class="string">"this problem turns up because a piece of quoted text contains "</span>
|
|
<span class="string">"a text substitution in square brackets which in turn contains "</span>
|
|
<span class="string">"another piece of quoted text - this is not allowed, and causes "</span>
|
|
<span class="string">"me to lose track.)"</span><span class="plain">);</span>
|
|
<span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">COMMENT_NEVER_ENDS_LEXERERROR</span><span class="plain">:</span>
|
|
<span class="identifier">Problems::Issue::lexical_problem_S</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_UnendingComment</span><span class="plain">),</span>
|
|
<span class="string">"Some source text ended in the middle of a comment"</span><span class="plain">,</span>
|
|
<span class="identifier">problem_source_description</span><span class="plain">,</span>
|
|
<span class="string">"This probably means that a ']' is missing somewhere. "</span>
|
|
<span class="string">"(If you are using Inform with syntax colouring, look for "</span>
|
|
<span class="string">"where the comment colour starts.) Inform's convention on "</span>
|
|
<span class="string">"'nested comments' is that each '[' in a comment must be "</span>
|
|
<span class="string">"matched by a corresponding ']': so for instance '[This "</span>
|
|
<span class="string">"[even nested like so] acts as a comment]' is a single "</span>
|
|
<span class="string">"comment - the first ']' character matches the second '[' "</span>
|
|
<span class="string">"and so doesn't end the comment: only the second ']' ends "</span>
|
|
<span class="string">"the comment."</span><span class="plain">);</span>
|
|
<span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">I6_NEVER_ENDS_LEXERERROR</span><span class="plain">:</span>
|
|
<span class="identifier">Problems::Issue::lexical_problem_S</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_UnendingI6</span><span class="plain">),</span>
|
|
<span class="string">"Some source text ended in the middle of a verbatim passage "</span>
|
|
<span class="string">"of Inform 6 code"</span><span class="plain">,</span>
|
|
<span class="identifier">problem_source_description</span><span class="plain">,</span>
|
|
<span class="string">"This probably means that a '-)' is missing."</span><span class="plain">);</span>
|
|
<span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">default</span><span class="plain">:</span>
|
|
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"unknown lexer error"</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function SourceFiles::lexer_problem_handler appears nowhere else.</p>
|
|
|
|
<hr class="tocbar">
|
|
<ul class="toc"><li><i>(This section begins Chapter 3: Bridge to Words Module.)</i></li><li><a href="3-nl.html">Continue with 'Natural Languages'</a></li></ul><hr class="tocbar">
|
|
<!--End of weave-->
|
|
</body>
|
|
</html>
|
|
|