mirror of
https://github.com/ganelson/inform.git
synced 2024-07-05 16:44:21 +03:00
578 lines
64 KiB
HTML
578 lines
64 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<title>6/hdn</title>
|
|
<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="../inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
</head>
|
|
<body>
|
|
<nav role="navigation">
|
|
<h1><a href="../webs.html">Sources</a></h1>
|
|
<ul>
|
|
<li><a href="../compiler.html"><b>compiler</b></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>Compiler Webs</h2>
|
|
<ul>
|
|
<li><a href="../inbuild/index.html">inbuild</a></li>
|
|
<li><a href="../inform7/index.html">inform7</a></li>
|
|
<li><a href="../inter/index.html">inter</a></li>
|
|
</ul>
|
|
<h2>Inbuild Modules</h2>
|
|
<ul>
|
|
<li><a href="../inbuild-module/index.html">inbuild</a></li>
|
|
<li><a href="../arch-module/index.html">arch</a></li>
|
|
<li><a href="../words-module/index.html">words</a></li>
|
|
<li><a href="../syntax-module/index.html">syntax</a></li>
|
|
<li><a href="../html-module/index.html">html</a></li>
|
|
</ul>
|
|
<h2>Inform7 Modules</h2>
|
|
<ul>
|
|
<li><a href="../core-module/index.html">core</a></li>
|
|
<li><a href="../problems-module/index.html">problems</a></li>
|
|
<li><a href="../inflections-module/index.html">inflections</a></li>
|
|
<li><a href="../linguistics-module/index.html">linguistics</a></li>
|
|
<li><a href="../kinds-module/index.html">kinds</a></li>
|
|
<li><a href="../if-module/index.html">if</a></li>
|
|
<li><a href="../multimedia-module/index.html">multimedia</a></li>
|
|
<li><a href="../index-module/index.html">index</a></li>
|
|
</ul>
|
|
<h2>Inter Modules</h2>
|
|
<ul>
|
|
<li><a href="../inter-module/index.html">inter</a></li>
|
|
<li><a href="../building-module/index.html">building</a></li>
|
|
<li><a href="../codegen-module/index.html">codegen</a></li>
|
|
</ul>
|
|
<h2>Foundation</h2>
|
|
<ul>
|
|
<li><a href="../../../inweb/docs/foundation-module/index.html">foundation</a></li>
|
|
</ul>
|
|
|
|
|
|
</nav>
|
|
<main role="main">
|
|
|
|
<!--Weave of '6/inc' generated by 7-->
|
|
<ul class="crumbs"><li><a href="../webs.html">Source</a></li><li><a href="../compiler.html">Compiler Modules</a></li><li><a href="index.html">inbuild</a></li><li><a href="index.html#6">Chapter 6: Handling Inform Source Text</a></li><li><b>Inclusions</b></li></ul><p class="purpose">To fulfill requests to include extensions, adding their material to the parse tree as needed, and removing INCLUDE nodes.</p>
|
|
|
|
<ul class="toc"><li><a href="#SP6">§6. Extension loading</a></li><li><a href="#SP8">§8. Checking the begins here and ends here sentences</a></li></ul><hr class="tocbar">
|
|
|
|
<p class="inwebparagraph"><a id="SP1"></a><b>§1. </b>At this point in the narrative of a typical run of Inform, we have read in the
|
|
source text supplied by the user. The lexer automatically prefaced this with
|
|
"Include Standard Rules by Graham Nelson", and the sentence-breaker
|
|
converted all such sentences to nodes of type <code class="display"><span class="extract">INCLUDE_NT</span></code> which are
|
|
children of the parse tree root. (The eldest child, therefore, is the
|
|
Standard Rules inclusion.)
|
|
</p>
|
|
|
|
<p class="inwebparagraph">We now look through the parse tree in sentence order — something we shall
|
|
do many times, and which we call a "traverse" — and look for INCLUDE
|
|
nodes. Each is replaced with a mass of further nodes for the material in
|
|
whatever new extensions were required. This process is repeated until there
|
|
are no "Include" sentences left. In principle this could go on forever if
|
|
A includes B which includes A, or some such, but we log each extension read
|
|
in to ensure that nothing is read twice.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">At the end of this routine, provided no Problems have been issued, there are
|
|
guaranteed to be no INCLUDE nodes remaining in the parse tree.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">inclusions_errors_to</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Inclusions::traverse</span><span class="plain">(</span><span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">parse_node_tree</span><span class="plain"> *</span><span class="identifier">T</span><span class="plain">) {</span>
|
|
<span class="identifier">inclusions_errors_to</span><span class="plain"> = </span><span class="identifier">C</span><span class="plain">;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">includes_cleared</span><span class="plain">;</span>
|
|
<span class="reserved">do</span><span class="plain"> {</span>
|
|
<span class="identifier">includes_cleared</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_count</span><span class="plain"> > 0) </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="identifier">ParseTree::traverse_ppni</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="functiontext">Inclusions::visit</span><span class="plain">, &</span><span class="identifier">includes_cleared</span><span class="plain">);</span>
|
|
<span class="plain">} </span><span class="reserved">while</span><span class="plain"> (</span><span class="identifier">includes_cleared</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">);</span>
|
|
<span class="identifier">inclusions_errors_to</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">build_vertex</span><span class="plain"> *</span><span class="functiontext">Inclusions::spawned_from_vertex</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">H0</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">H0</span><span class="plain">) {</span>
|
|
<span class="reserved">inform_extension</span><span class="plain"> *</span><span class="identifier">ext</span><span class="plain"> = </span><span class="identifier">ParseTree::get_inclusion_of_extension</span><span class="plain">(</span><span class="identifier">H0</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ext</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">ext</span><span class="plain">-</span><span class="element">>as_copy</span><span class="plain">-</span><span class="element">>vertex</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">inclusions_errors_to</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"no H0 ext or inclusion"</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">inclusions_errors_to</span><span class="plain">-</span><span class="element">>vertex</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Inclusions::visit</span><span class="plain">(</span><span class="identifier">parse_node_tree</span><span class="plain"> *</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">pn</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">last_H0</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> *</span><span class="identifier">includes_cleared</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">) == </span><span class="identifier">INCLUDE_NT</span><span class="plain">) {</span>
|
|
<<span class="cwebmacro">Replace INCLUDE node with sentence nodes for any extensions required</span> <span class="cwebmacronumber">1.1</span>><span class="plain">;</span>
|
|
<span class="plain">*</span><span class="identifier">includes_cleared</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Inclusions::traverse is used in 4/em (<a href="4-em.html#SP9">§9</a>), 5/ps (<a href="5-ps.html#SP4">§4</a>).</p>
|
|
|
|
<p class="endnote">The function Inclusions::spawned_from_vertex is used in <a href="#SP1_1">§1.1</a>, <a href="#SP6_1">§6.1</a>.</p>
|
|
|
|
<p class="endnote">The function Inclusions::visit appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP1_1"></a><b>§1.1. </b>The INCLUDE node becomes an INCLUSION, which in turn contains the extension's code.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Replace INCLUDE node with sentence nodes for any extensions required</span> <span class="cwebmacronumber">1.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (!(<</span><span class="identifier">structural</span><span class="plain">-</span><span class="identifier">sentence</span><span class="plain">>(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">))))</span>
|
|
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"malformed INCLUDE"</span><span class="plain">);</span>
|
|
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">title</span><span class="plain"> = </span><span class="identifier">GET_RW</span><span class="plain">(<</span><span class="identifier">structural</span><span class="plain">-</span><span class="identifier">sentence</span><span class="plain">>, 1);</span>
|
|
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">author</span><span class="plain"> = </span><span class="identifier">GET_RW</span><span class="plain">(<</span><span class="identifier">structural</span><span class="plain">-</span><span class="identifier">sentence</span><span class="plain">>, 2);</span>
|
|
<span class="identifier">ParseTree::set_type</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">, </span><span class="identifier">INCLUSION_NT</span><span class="plain">); </span><span class="identifier">pn</span><span class="plain">-></span><span class="identifier">down</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">l</span><span class="plain"> = </span><span class="identifier">ParseTree::push_attachment_point</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">pn</span><span class="plain">);</span>
|
|
<span class="reserved">inform_extension</span><span class="plain"> *</span><span class="identifier">E</span><span class="plain"> = </span><span class="functiontext">Inclusions::fulfill_request_to_include_extension</span><span class="plain">(</span><span class="identifier">last_H0</span><span class="plain">, </span><span class="identifier">title</span><span class="plain">, </span><span class="identifier">author</span><span class="plain">);</span>
|
|
<span class="identifier">ParseTree::pop_attachment_point</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">l</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">E</span><span class="plain">) {</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">c</span><span class="plain"> = </span><span class="identifier">pn</span><span class="plain">-></span><span class="identifier">down</span><span class="plain">; </span><span class="identifier">c</span><span class="plain">; </span><span class="identifier">c</span><span class="plain"> = </span><span class="identifier">c</span><span class="plain">-</span><span class="element">>next</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">c</span><span class="plain">) == </span><span class="identifier">HEADING_NT</span><span class="plain">)</span>
|
|
<span class="identifier">ParseTree::set_inclusion_of_extension</span><span class="plain">(</span><span class="identifier">c</span><span class="plain">, </span><span class="identifier">E</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">last_H0</span><span class="plain">) && (</span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">last_H0</span><span class="plain">, </span><span class="identifier">implied_heading_ANNOT</span><span class="plain">) != </span><span class="identifier">TRUE</span><span class="plain">)) {</span>
|
|
<span class="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">V</span><span class="plain"> = </span><span class="functiontext">Inclusions::spawned_from_vertex</span><span class="plain">(</span><span class="identifier">last_H0</span><span class="plain">);</span>
|
|
<span class="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">EV</span><span class="plain"> = </span><span class="identifier">E</span><span class="plain">-</span><span class="element">>as_copy</span><span class="plain">-</span><span class="element">>vertex</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">V</span><span class="plain">-</span><span class="element">>buildable_if_copy</span><span class="plain">-</span><span class="element">>edition</span><span class="plain">-</span><span class="element">>work</span><span class="plain">-</span><span class="element">>genre</span><span class="plain"> == </span><span class="identifier">extension_genre</span><span class="plain">)</span>
|
|
<span class="functiontext">Graphs::need_this_to_use</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">, </span><span class="identifier">EV</span><span class="plain">);</span>
|
|
<span class="reserved">else</span>
|
|
<span class="functiontext">Graphs::need_this_to_build</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">, </span><span class="identifier">EV</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP1">§1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP2"></a><b>§2. </b></p>
|
|
|
|
|
|
<pre class="definitions">
|
|
<span class="definitionkeyword">enum</span> <span class="constant">IncludeExtQuoted_SYNERROR</span>
|
|
<span class="definitionkeyword">enum</span> <span class="constant">BogusExtension_SYNERROR</span>
|
|
<span class="definitionkeyword">enum</span> <span class="constant">ExtVersionTooLow_SYNERROR</span>
|
|
<span class="definitionkeyword">enum</span> <span class="constant">ExtVersionMalformed_SYNERROR</span>
|
|
<span class="definitionkeyword">enum</span> <span class="constant">ExtInadequateVM_SYNERROR</span>
|
|
<span class="definitionkeyword">enum</span> <span class="constant">ExtMisidentifiedEnds_SYNERROR</span>
|
|
</pre>
|
|
<p class="inwebparagraph"><a id="SP3"></a><b>§3. </b>Here we parse requests to include extensions.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain"><</span><span class="identifier">extension</span><span class="plain">-</span><span class="identifier">title</span><span class="plain">-</span><span class="identifier">and</span><span class="plain">-</span><span class="identifier">version</span><span class="plain">> ::=</span>
|
|
<span class="identifier">version</span><span class="plain"> <</span><span class="identifier">extension</span><span class="plain">-</span><span class="identifier">version</span><span class="plain">> </span><span class="identifier">of</span><span class="plain"> <</span><span class="identifier">definite</span><span class="plain">-</span><span class="identifier">article</span><span class="plain">> <</span><span class="identifier">extension</span><span class="plain">-</span><span class="identifier">unversioned</span><span class="plain">> | ==> </span><span class="identifier">R</span><span class="plain">[1]</span>
|
|
<span class="identifier">version</span><span class="plain"> <</span><span class="identifier">extension</span><span class="plain">-</span><span class="identifier">version</span><span class="plain">> </span><span class="identifier">of</span><span class="plain"> <</span><span class="identifier">extension</span><span class="plain">-</span><span class="identifier">unversioned</span><span class="plain">> | ==> </span><span class="identifier">R</span><span class="plain">[1]</span>
|
|
<span class="plain"><</span><span class="identifier">definite</span><span class="plain">-</span><span class="identifier">article</span><span class="plain">> <</span><span class="identifier">extension</span><span class="plain">-</span><span class="identifier">unversioned</span><span class="plain">> | ==> -1</span>
|
|
<span class="plain"><</span><span class="identifier">extension</span><span class="plain">-</span><span class="identifier">unversioned</span><span class="plain">> ==> -1</span>
|
|
|
|
<span class="plain"><</span><span class="identifier">extension</span><span class="plain">-</span><span class="identifier">unversioned</span><span class="plain">> ::=</span>
|
|
<span class="plain"><</span><span class="identifier">extension</span><span class="plain">-</span><span class="identifier">unversioned</span><span class="plain">-</span><span class="identifier">inner</span><span class="plain">> ( ... ) | ==> 0</span>
|
|
<span class="plain"><</span><span class="identifier">extension</span><span class="plain">-</span><span class="identifier">unversioned</span><span class="plain">-</span><span class="identifier">inner</span><span class="plain">> ==> 0</span>
|
|
|
|
<span class="plain"><</span><span class="identifier">extension</span><span class="plain">-</span><span class="identifier">unversioned</span><span class="plain">-</span><span class="identifier">inner</span><span class="plain">> ::=</span>
|
|
<span class="plain"><</span><span class="identifier">quoted</span><span class="plain">-</span><span class="identifier">text</span><span class="plain">> *** | ==> </span><<span class="cwebmacro">Issue PM_IncludeExtQuoted problem</span> <span class="cwebmacronumber">3.1</span>>
|
|
<span class="plain">... ==> 0; <<</span><span class="identifier">t1</span><span class="plain">>> = </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">); <<</span><span class="identifier">t2</span><span class="plain">>> = </span><span class="identifier">Wordings::last_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_1"></a><b>§3.1. </b>Quite a popular mistake, this:
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Issue PM_IncludeExtQuoted problem</span> <span class="cwebmacronumber">3.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="plain"><<</span><span class="identifier">t1</span><span class="plain">>> = -1; <<</span><span class="identifier">t2</span><span class="plain">>> = -1;</span>
|
|
<span class="reserved">copy_error</span><span class="plain"> *</span><span class="identifier">CE</span><span class="plain"> = </span><span class="functiontext">Copies::new_error</span><span class="plain">(</span><span class="constant">SYNTAX_CE</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
|
|
<span class="identifier">CE</span><span class="plain">-</span><span class="element">>error_subcategory</span><span class="plain"> = </span><span class="constant">IncludeExtQuoted_SYNERROR</span><span class="plain">;</span>
|
|
<span class="identifier">CE</span><span class="plain">-</span><span class="element">>details_node</span><span class="plain"> = </span><span class="identifier">current_sentence</span><span class="plain">;</span>
|
|
<span class="functiontext">Copies::attach</span><span class="plain">(</span><span class="identifier">inclusions_errors_to</span><span class="plain">, </span><span class="identifier">CE</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP3">§3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP4"></a><b>§4. </b>This internal parses version text such as "12/110410".
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain"><</span><span class="identifier">extension</span><span class="plain">-</span><span class="identifier">version</span><span class="plain">> </span><span class="identifier">internal</span><span class="plain"> 1 {</span>
|
|
<span class="plain">*</span><span class="identifier">X</span><span class="plain"> = </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">); </span> <span class="comment">actually, defer parsing by returning a word number here</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP5"></a><b>§5. </b></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">inform_extension</span><span class="plain"> *</span><span class="functiontext">Inclusions::fulfill_request_to_include_extension</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">last_H0</span><span class="plain">, </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">TW</span><span class="plain">, </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">AW</span><span class="plain">) {</span>
|
|
<span class="reserved">inform_extension</span><span class="plain"> *</span><span class="identifier">E</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="plain"><<</span><span class="identifier">t1</span><span class="plain">>> = -1; <<</span><span class="identifier">t2</span><span class="plain">>> = -1;</span>
|
|
<span class="plain"><</span><span class="identifier">extension</span><span class="plain">-</span><span class="identifier">title</span><span class="plain">-</span><span class="identifier">and</span><span class="plain">-</span><span class="identifier">version</span><span class="plain">>(</span><span class="identifier">TW</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">Wordings::new</span><span class="plain">(<<</span><span class="identifier">t1</span><span class="plain">>>, <<</span><span class="identifier">t2</span><span class="plain">>>);</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">version_word</span><span class="plain"> = <<</span><span class="identifier">r</span><span class="plain">>>;</span>
|
|
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) </span><<span class="cwebmacro">Fulfill request to include a single extension</span> <span class="cwebmacronumber">5.1</span>><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">E</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Inclusions::fulfill_request_to_include_extension is used in <a href="#SP1_1">§1.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP5_1"></a><b>§5.1. </b>A request consists of author, name and version, the latter being optional.
|
|
We obtain the extension file structure corresponding to this: it may have
|
|
no text at all (for instance if Inform could not open the file), or it may be
|
|
one we have seen before, thanks to an earlier inclusion. Only when it
|
|
provided genuinely new text will its <code class="display"><span class="extract">body_text_unbroken</span></code> flag be set,
|
|
and then we call the sentence-breaker to graft the new material on to the
|
|
parse tree.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Fulfill request to include a single extension</span> <span class="cwebmacronumber">5.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">version_word</span><span class="plain"> >= 0)</span>
|
|
<span class="functiontext">Inclusions::parse_version</span><span class="plain">(</span><span class="identifier">version_word</span><span class="plain">); </span> <span class="comment">this checks the formatting of the version number</span>
|
|
|
|
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">exft</span><span class="plain">);</span>
|
|
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">exfa</span><span class="plain">);</span>
|
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">exft</span><span class="plain">, </span><span class="string">"%+W"</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
|
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">exfa</span><span class="plain">, </span><span class="string">"%+W"</span><span class="plain">, </span><span class="identifier">AW</span><span class="plain">);</span>
|
|
<span class="reserved">inbuild_work</span><span class="plain"> *</span><span class="identifier">work</span><span class="plain"> = </span><span class="functiontext">Works::new</span><span class="plain">(</span><span class="identifier">extension_genre</span><span class="plain">, </span><span class="identifier">exft</span><span class="plain">, </span><span class="identifier">exfa</span><span class="plain">);</span>
|
|
<span class="functiontext">Works::add_to_database</span><span class="plain">(</span><span class="identifier">work</span><span class="plain">, </span><span class="constant">LOADED_WDBC</span><span class="plain">);</span>
|
|
<span class="identifier">semantic_version_number</span><span class="plain"> </span><span class="identifier">V</span><span class="plain"> = </span><span class="identifier">VersionNumbers::null</span><span class="plain">();</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">version_word</span><span class="plain"> >= 0) </span><span class="identifier">V</span><span class="plain"> = </span><span class="functiontext">Inclusions::parse_version</span><span class="plain">(</span><span class="identifier">version_word</span><span class="plain">);</span>
|
|
<span class="identifier">semver_range</span><span class="plain"> *</span><span class="identifier">R</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">VersionNumbers::is_null</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">)) </span><span class="identifier">R</span><span class="plain"> = </span><span class="identifier">VersionNumberRanges::any_range</span><span class="plain">();</span>
|
|
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">R</span><span class="plain"> = </span><span class="identifier">VersionNumberRanges::compatibility_range</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">);</span>
|
|
<span class="reserved">inbuild_requirement</span><span class="plain"> *</span><span class="identifier">req</span><span class="plain"> = </span><span class="functiontext">Requirements::new</span><span class="plain">(</span><span class="identifier">work</span><span class="plain">, </span><span class="identifier">R</span><span class="plain">);</span>
|
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">exft</span><span class="plain">);</span>
|
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">exfa</span><span class="plain">);</span>
|
|
|
|
<span class="identifier">E</span><span class="plain"> = </span><span class="functiontext">Inclusions::load</span><span class="plain">(</span><span class="identifier">last_H0</span><span class="plain">, </span><span class="identifier">current_sentence</span><span class="plain">, </span><span class="identifier">req</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. Extension loading. </b>Note that we ignore a request for an extension which has already been
|
|
loaded, except if the new request ups the ante in terms of the minimum
|
|
version permitted: in which case we need to record that the requirement has
|
|
been tightened. That is, if we previously wanted version 2 of Pantomime
|
|
Sausages by Mr Punch, and loaded it, but then read the sentence
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>Include version 3 of Pantomime Sausages by Mr Punch.</p>
|
|
|
|
</blockquote>
|
|
|
|
<p class="inwebparagraph">then we need to note that the version requirement on PS has been raised to 3.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">inform_extension</span><span class="plain"> *</span><span class="functiontext">Inclusions::load</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">last_H0</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">at</span><span class="plain">, </span><span class="reserved">inbuild_requirement</span><span class="plain"> *</span><span class="identifier">req</span><span class="plain">) {</span>
|
|
<span class="reserved">inform_extension</span><span class="plain"> *</span><span class="identifier">E</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">E</span><span class="plain">, </span><span class="reserved">inform_extension</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Requirements::meets</span><span class="plain">(</span><span class="identifier">E</span><span class="plain">-</span><span class="element">>as_copy</span><span class="plain">-</span><span class="element">>edition</span><span class="plain">, </span><span class="identifier">req</span><span class="plain">)) &&</span>
|
|
<span class="plain">(</span><span class="functiontext">Copies::source_text_has_been_read</span><span class="plain">(</span><span class="identifier">E</span><span class="plain">-</span><span class="element">>as_copy</span><span class="plain">))) {</span>
|
|
<span class="functiontext">Extensions::must_satisfy</span><span class="plain">(</span><span class="identifier">E</span><span class="plain">, </span><span class="identifier">req</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">E</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<<span class="cwebmacro">Read the extension file into the lexer, and break it into body and documentation</span> <span class="cwebmacronumber">6.1</span>><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">E</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Inclusions::load is used in <a href="#SP5_1">§5.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP6_1"></a><b>§6.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Read the extension file into the lexer, and break it into body and documentation</span> <span class="cwebmacronumber">6.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">inbuild_search_result</span><span class="plain"> *</span><span class="identifier">search_result</span><span class="plain"> = </span><span class="functiontext">Nests::first_found</span><span class="plain">(</span><span class="identifier">req</span><span class="plain">, </span><span class="functiontext">Inbuild::nest_list</span><span class="plain">());</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">search_result</span><span class="plain">) {</span>
|
|
<span class="identifier">E</span><span class="plain"> = </span><span class="functiontext">ExtensionManager::from_copy</span><span class="plain">(</span><span class="identifier">search_result</span><span class="plain">-</span><span class="element">>copy</span><span class="plain">);</span>
|
|
<span class="functiontext">Extensions::set_inclusion_sentence</span><span class="plain">(</span><span class="identifier">E</span><span class="plain">, </span><span class="identifier">at</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Nests::get_tag</span><span class="plain">(</span><span class="identifier">search_result</span><span class="plain">-</span><span class="element">>nest</span><span class="plain">) == </span><span class="constant">INTERNAL_NEST_TAG</span><span class="plain">)</span>
|
|
<span class="identifier">E</span><span class="plain">-</span><span class="element">>loaded_from_built_in_area</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="identifier">compatibility_specification</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain"> = </span><span class="identifier">E</span><span class="plain">-</span><span class="element">>as_copy</span><span class="plain">-</span><span class="element">>edition</span><span class="plain">-</span><span class="element">>compatibility</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Compatibility::with</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="functiontext">Inbuild::current_vm</span><span class="plain">()) == </span><span class="identifier">FALSE</span><span class="plain">)</span>
|
|
<<span class="cwebmacro">Issue a problem message saying that the VM does not meet requirements</span> <span class="cwebmacronumber">6.1.1</span>><span class="plain">;</span>
|
|
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">LinkedLists::len</span><span class="plain">(</span><span class="identifier">search_result</span><span class="plain">-</span><span class="element">>copy</span><span class="plain">-</span><span class="element">>errors_reading_source_text</span><span class="plain">) == 0) {</span>
|
|
<span class="functiontext">Copies::read_source_text_for</span><span class="plain">(</span><span class="identifier">search_result</span><span class="plain">-</span><span class="element">>copy</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">#</span><span class="identifier">ifndef</span><span class="plain"> </span><span class="identifier">CORE_MODULE</span>
|
|
<span class="functiontext">Copies::list_problems_arising</span><span class="plain">(</span><span class="identifier">STDERR</span><span class="plain">, </span><span class="identifier">search_result</span><span class="plain">-</span><span class="element">>copy</span><span class="plain">);</span>
|
|
<span class="plain">#</span><span class="identifier">endif</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">CORE_MODULE</span>
|
|
<<span class="cwebmacro">Issue a cannot-find problem</span> <span class="cwebmacronumber">6.1.2</span>><span class="plain">;</span>
|
|
<span class="plain">#</span><span class="identifier">endif</span>
|
|
<span class="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">RV</span><span class="plain"> = </span><span class="functiontext">Graphs::req_vertex</span><span class="plain">(</span><span class="identifier">req</span><span class="plain">);</span>
|
|
<span class="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">V</span><span class="plain"> = </span><span class="functiontext">Inclusions::spawned_from_vertex</span><span class="plain">(</span><span class="identifier">last_H0</span><span class="plain">);</span>
|
|
<span class="functiontext">Graphs::need_this_to_build</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">, </span><span class="identifier">RV</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="SP6_1_1"></a><b>§6.1.1. </b>Here the problem is not that the extension is broken in some way: it's
|
|
just not what we can currently use. Therefore the correction should be a
|
|
matter of removing the inclusion, not of altering the extension, so we
|
|
report this problem at the inclusion line.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Issue a problem message saying that the VM does not meet requirements</span> <span class="cwebmacronumber">6.1.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">copy_error</span><span class="plain"> *</span><span class="identifier">CE</span><span class="plain"> = </span><span class="functiontext">Copies::new_error</span><span class="plain">(</span><span class="constant">SYNTAX_CE</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
|
|
<span class="identifier">CE</span><span class="plain">-</span><span class="element">>error_subcategory</span><span class="plain"> = </span><span class="constant">ExtInadequateVM_SYNERROR</span><span class="plain">;</span>
|
|
<span class="identifier">CE</span><span class="plain">-</span><span class="element">>details_node</span><span class="plain"> = </span><span class="functiontext">Extensions::get_inclusion_sentence</span><span class="plain">(</span><span class="identifier">E</span><span class="plain">);</span>
|
|
<span class="identifier">CE</span><span class="plain">-</span><span class="element">>details</span><span class="plain"> = </span><span class="identifier">C</span><span class="plain">-></span><span class="identifier">parsed_from</span><span class="plain">;</span>
|
|
<span class="functiontext">Copies::attach</span><span class="plain">(</span><span class="identifier">inclusions_errors_to</span><span class="plain">, </span><span class="identifier">CE</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP6_1">§6.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP6_1_2"></a><b>§6.1.2. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Issue a cannot-find problem</span> <span class="cwebmacronumber">6.1.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">inbuild_requirement</span><span class="plain"> *</span><span class="identifier">req2</span><span class="plain"> = </span><span class="functiontext">Requirements::any_version_of</span><span class="plain">(</span><span class="identifier">req</span><span class="plain">-</span><span class="element">>work</span><span class="plain">);</span>
|
|
<span class="identifier">linked_list</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain"> = </span><span class="identifier">NEW_LINKED_LIST</span><span class="plain">(</span><span class="reserved">inbuild_search_result</span><span class="plain">);</span>
|
|
<span class="functiontext">Nests::search_for</span><span class="plain">(</span><span class="identifier">req2</span><span class="plain">, </span><span class="functiontext">Inbuild::nest_list</span><span class="plain">(), </span><span class="identifier">L</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">LinkedLists::len</span><span class="plain">(</span><span class="identifier">L</span><span class="plain">) == 0) {</span>
|
|
<span class="reserved">copy_error</span><span class="plain"> *</span><span class="identifier">CE</span><span class="plain"> = </span><span class="functiontext">Copies::new_error</span><span class="plain">(</span><span class="constant">SYNTAX_CE</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
|
|
<span class="identifier">CE</span><span class="plain">-</span><span class="element">>error_subcategory</span><span class="plain"> = </span><span class="constant">BogusExtension_SYNERROR</span><span class="plain">;</span>
|
|
<span class="identifier">CE</span><span class="plain">-</span><span class="element">>details_node</span><span class="plain"> = </span><span class="identifier">current_sentence</span><span class="plain">;</span>
|
|
<span class="functiontext">Copies::attach</span><span class="plain">(</span><span class="identifier">inclusions_errors_to</span><span class="plain">, </span><span class="identifier">CE</span><span class="plain">);</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">versions</span><span class="plain">);</span>
|
|
<span class="reserved">inbuild_search_result</span><span class="plain"> *</span><span class="identifier">search_result</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">search_result</span><span class="plain">, </span><span class="reserved">inbuild_search_result</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">versions</span><span class="plain">) > 0) </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">versions</span><span class="plain">, </span><span class="string">" or "</span><span class="plain">);</span>
|
|
<span class="identifier">semantic_version_number</span><span class="plain"> </span><span class="identifier">V</span><span class="plain"> = </span><span class="identifier">search_result</span><span class="plain">-</span><span class="element">>copy</span><span class="plain">-</span><span class="element">>edition</span><span class="plain">-</span><span class="element">>version</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">VersionNumbers::is_null</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">)) </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">versions</span><span class="plain">, </span><span class="string">"an unnumbered version"</span><span class="plain">);</span>
|
|
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">versions</span><span class="plain">, </span><span class="string">"version %v"</span><span class="plain">, &</span><span class="identifier">V</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">copy_error</span><span class="plain"> *</span><span class="identifier">CE</span><span class="plain"> = </span><span class="functiontext">Copies::new_error</span><span class="plain">(</span><span class="constant">SYNTAX_CE</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
|
|
<span class="identifier">CE</span><span class="plain">-</span><span class="element">>error_subcategory</span><span class="plain"> = </span><span class="constant">ExtVersionTooLow_SYNERROR</span><span class="plain">;</span>
|
|
<span class="identifier">CE</span><span class="plain">-</span><span class="element">>details_node</span><span class="plain"> = </span><span class="identifier">at</span><span class="plain">;</span>
|
|
<span class="identifier">CE</span><span class="plain">-</span><span class="element">>details</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">versions</span><span class="plain">);</span>
|
|
<span class="functiontext">Copies::attach</span><span class="plain">(</span><span class="identifier">inclusions_errors_to</span><span class="plain">, </span><span class="identifier">CE</span><span class="plain">);</span>
|
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">versions</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_1">§6.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP7"></a><b>§7. </b></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">last_PM_ExtVersionMalformed_at</span><span class="plain"> = -1;</span>
|
|
<span class="identifier">semantic_version_number</span><span class="plain"> </span><span class="functiontext">Inclusions::parse_version</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">vwn</span><span class="plain">) {</span>
|
|
<span class="identifier">semantic_version_number</span><span class="plain"> </span><span class="identifier">V</span><span class="plain"> = </span><span class="identifier">VersionNumbers::null</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">Wordings::one_word</span><span class="plain">(</span><span class="identifier">vwn</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (<</span><span class="identifier">version</span><span class="plain">-</span><span class="identifier">number</span><span class="plain">>(</span><span class="identifier">W</span><span class="plain">)) {</span>
|
|
<span class="identifier">semantic_version_number_holder</span><span class="plain"> *</span><span class="identifier">H</span><span class="plain"> = (</span><span class="identifier">semantic_version_number_holder</span><span class="plain"> *) <<</span><span class="identifier">rp</span><span class="plain">>>;</span>
|
|
<span class="identifier">V</span><span class="plain"> = </span><span class="identifier">H</span><span class="plain">-</span><span class="element">>version</span><span class="plain">;</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
|
<<span class="cwebmacro">Issue a problem message for a malformed version number</span> <span class="cwebmacronumber">7.1</span>><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">V</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Inclusions::parse_version is used in <a href="#SP5_1">§5.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP7_1"></a><b>§7.1. </b>Because we tend to call <code class="display"><span class="extract">Inclusions::parse_version</span></code> repeatedly on
|
|
the same word, we want to recover tidily from this problem, and not report it
|
|
over and over. We do this by altering the text to <code class="display"><span class="extract">1</span></code>, the lowest well-formed
|
|
version number text.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Issue a problem message for a malformed version number</span> <span class="cwebmacronumber">7.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">last_PM_ExtVersionMalformed_at</span><span class="plain"> != </span><span class="identifier">vwn</span><span class="plain">) {</span>
|
|
<span class="identifier">last_PM_ExtVersionMalformed_at</span><span class="plain"> = </span><span class="identifier">vwn</span><span class="plain">;</span>
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Offending word number %d <%N>\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">vwn</span><span class="plain">, </span><span class="identifier">vwn</span><span class="plain">);</span>
|
|
<span class="reserved">copy_error</span><span class="plain"> *</span><span class="identifier">CE</span><span class="plain"> = </span><span class="functiontext">Copies::new_error</span><span class="plain">(</span><span class="constant">SYNTAX_CE</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
|
|
<span class="identifier">CE</span><span class="plain">-</span><span class="element">>error_subcategory</span><span class="plain"> = </span><span class="constant">ExtVersionMalformed_SYNERROR</span><span class="plain">;</span>
|
|
<span class="identifier">CE</span><span class="plain">-</span><span class="element">>details_node</span><span class="plain"> = </span><span class="identifier">current_sentence</span><span class="plain">;</span>
|
|
<span class="functiontext">Copies::attach</span><span class="plain">(</span><span class="identifier">inclusions_errors_to</span><span class="plain">, </span><span class="identifier">CE</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP7">§7</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP8"></a><b>§8. Checking the begins here and ends here sentences. </b>When a newly loaded extension is being sentence-broken, problem messages
|
|
will be turned up unless it contains the matching pair of "begins here"
|
|
and "ends here" sentences. Assuming it does, the sentence breaker has no
|
|
objection, but it also calls the two routines below to verify that these
|
|
sentences have the correct format. (The point of this is to catch a malformed
|
|
extension at the earliest possible moment after loading it: it's easy to
|
|
mis-install extensions, especially if doing so by hand, and the resulting
|
|
problem messages could be quite inscrutable if one extension was wrongly
|
|
identified as another.)
|
|
</p>
|
|
|
|
<p class="inwebparagraph">First, we check the "begins here" sentence. We also identify where the
|
|
version number is given (if it is), and check that we are not trying to
|
|
use an extension which is marked as not working on the current VM.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">It is sufficient to try parsing the version number in order to check it:
|
|
we throw away the answer, as we can't use it yet, but this will provoke
|
|
problem messages if it is malformed.
|
|
</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP9"></a><b>§9. </b>This parses the subject noun-phrase in the sentence
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>Version 3 of Pantomime Sausages by Mr Punch begins here.</p>
|
|
|
|
</blockquote>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain"><</span><span class="identifier">begins</span><span class="plain">-</span><span class="identifier">here</span><span class="plain">-</span><span class="identifier">sentence</span><span class="plain">-</span><span class="identifier">subject</span><span class="plain">> ::=</span>
|
|
<span class="plain"><</span><span class="identifier">extension</span><span class="plain">-</span><span class="identifier">title</span><span class="plain">-</span><span class="identifier">and</span><span class="plain">-</span><span class="identifier">version</span><span class="plain">> </span><span class="identifier">by</span><span class="plain"> ... |</span>
|
|
<span class="plain">... ==> </span><<span class="cwebmacro">Issue problem</span> <span class="cwebmacronumber">9.1</span>>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP9_1"></a><b>§9.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Issue problem</span> <span class="cwebmacronumber">9.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">copy_error</span><span class="plain"> *</span><span class="identifier">CE</span><span class="plain"> = </span><span class="functiontext">Copies::new_error</span><span class="plain">(</span><span class="constant">SYNTAX_CE</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
|
|
<span class="identifier">CE</span><span class="plain">-</span><span class="element">>error_subcategory</span><span class="plain"> = </span><span class="identifier">ExtNoBeginsHere_SYNERROR</span><span class="plain">;</span>
|
|
<span class="identifier">CE</span><span class="plain">-</span><span class="element">>details_node</span><span class="plain"> = </span><span class="identifier">current_sentence</span><span class="plain">;</span>
|
|
<span class="functiontext">Copies::attach</span><span class="plain">(</span><span class="identifier">inclusions_errors_to</span><span class="plain">, </span><span class="identifier">CE</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP9">§9</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP10"></a><b>§10. </b></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Inclusions::check_begins_here</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">PN</span><span class="plain">, </span><span class="reserved">inform_extension</span><span class="plain"> *</span><span class="identifier">E</span><span class="plain">) {</span>
|
|
<span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain"> = </span><span class="identifier">inclusions_errors_to</span><span class="plain">;</span>
|
|
<span class="identifier">inclusions_errors_to</span><span class="plain"> = </span><span class="identifier">E</span><span class="plain">-</span><span class="element">>as_copy</span><span class="plain">;</span>
|
|
<span class="plain"><</span><span class="identifier">begins</span><span class="plain">-</span><span class="identifier">here</span><span class="plain">-</span><span class="identifier">sentence</span><span class="plain">-</span><span class="identifier">subject</span><span class="plain">>(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">PN</span><span class="plain">));</span>
|
|
<span class="identifier">inclusions_errors_to</span><span class="plain"> = </span><span class="identifier">S</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Inclusions::check_begins_here is used in 6/st (<a href="6-st.html#SP11">§11</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP11"></a><b>§11. </b>Similarly, we check the "ends here" sentence. Here there are no
|
|
side-effects: we merely verify that the name matches the one quoted in
|
|
the "begins here". We only check this if the problem count is still 0,
|
|
since we don't want to keep on nagging somebody who has already been told
|
|
that the extension isn't the one he thinks it is.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain"><</span><span class="identifier">the</span><span class="plain">-</span><span class="identifier">prefix</span><span class="plain">-</span><span class="reserved">for</span><span class="plain">-</span><span class="identifier">extensions</span><span class="plain">> ::=</span>
|
|
<span class="identifier">the</span><span class="plain"> ...</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Inclusions::check_ends_here</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">PN</span><span class="plain">, </span><span class="reserved">inform_extension</span><span class="plain"> *</span><span class="identifier">E</span><span class="plain">) {</span>
|
|
<span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain"> = </span><span class="identifier">inclusions_errors_to</span><span class="plain">;</span>
|
|
<span class="identifier">inclusions_errors_to</span><span class="plain"> = </span><span class="identifier">E</span><span class="plain">-</span><span class="element">>as_copy</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">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">PN</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (<</span><span class="identifier">the</span><span class="plain">-</span><span class="identifier">prefix</span><span class="plain">-</span><span class="reserved">for</span><span class="plain">-</span><span class="identifier">extensions</span><span class="plain">>(</span><span class="identifier">W</span><span class="plain">)) </span><span class="identifier">W</span><span class="plain"> = </span><span class="identifier">GET_RW</span><span class="plain">(<</span><span class="identifier">the</span><span class="plain">-</span><span class="identifier">prefix</span><span class="plain">-</span><span class="reserved">for</span><span class="plain">-</span><span class="identifier">extensions</span><span class="plain">>, 1);</span>
|
|
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">T</span><span class="plain"> = </span><span class="identifier">Feeds::feed_stream</span><span class="plain">(</span><span class="identifier">E</span><span class="plain">-</span><span class="element">>as_copy</span><span class="plain">-</span><span class="element">>edition</span><span class="plain">-</span><span class="element">>work</span><span class="plain">-</span><span class="element">>title</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">problem_count</span><span class="plain"> == 0) && (</span><span class="identifier">Wordings::match</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">)) {</span>
|
|
<span class="reserved">copy_error</span><span class="plain"> *</span><span class="identifier">CE</span><span class="plain"> = </span><span class="functiontext">Copies::new_error</span><span class="plain">(</span><span class="constant">SYNTAX_CE</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
|
|
<span class="identifier">CE</span><span class="plain">-</span><span class="element">>error_subcategory</span><span class="plain"> = </span><span class="constant">ExtMisidentifiedEnds_SYNERROR</span><span class="plain">;</span>
|
|
<span class="identifier">CE</span><span class="plain">-</span><span class="element">>details_node</span><span class="plain"> = </span><span class="identifier">PN</span><span class="plain">;</span>
|
|
<span class="identifier">CE</span><span class="plain">-</span><span class="element">>details_W</span><span class="plain"> = </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">PN</span><span class="plain">);</span>
|
|
<span class="functiontext">Copies::attach</span><span class="plain">(</span><span class="identifier">inclusions_errors_to</span><span class="plain">, </span><span class="identifier">CE</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">inclusions_errors_to</span><span class="plain"> = </span><span class="identifier">S</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Inclusions::check_ends_here is used in 6/st (<a href="6-st.html#SP11">§11</a>).</p>
|
|
|
|
<hr class="tocbar">
|
|
<ul class="toc"><li><a href="6-hdn.html">Back to 'Headings'</a></li><li><a href="6-cs.html">Continue with 'Control Structures'</a></li></ul><hr class="tocbar">
|
|
<!--End of weave-->
|
|
</main>
|
|
</body>
|
|
</html>
|
|
|