1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-06-26 04:00:43 +03:00

Redrafted Chapter 1 of inbuild module

This commit is contained in:
Graham Nelson 2020-03-29 17:39:17 +01:00
parent 47f29c9e86
commit e76d02da6e
60 changed files with 1936 additions and 1220 deletions

View file

@ -71,7 +71,7 @@ group.
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">CE</span><span class="plain">, </span><span class="identifier">copy_error</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">-&gt;</span><span class="identifier">errors_reading_source_text</span><span class="plain">) {</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">CE</span><span class="plain">-&gt;</span><span class="identifier">error_category</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">OPEN_FAILED_CE</span><span class="plain">:</span>
<span class="identifier">Problems::quote_stream</span><span class="plain">(1, </span><span class="identifier">Filenames::get_leafname</span><span class="plain">(</span><span class="identifier">CE</span><span class="plain">-&gt;</span><span class="identifier">file</span><span class="plain">));</span>
<span class="identifier">Problems::quote_stream</span><span class="plain">(1, </span><span class="identifier">Filenames::get_leafname</span><span class="plain">(</span><span class="identifier">CE</span><span class="plain">-&gt;</span><span class="identifier">details_file</span><span class="plain">));</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</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="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"I can't open the file '%1' of source text. %P"</span>
@ -82,7 +82,7 @@ group.
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">EXT_MISWORDED_CE</span><span class="plain">:</span>
<span class="functiontext">Problems::quote_work</span><span class="plain">(1, </span><span class="identifier">CE</span><span class="plain">-&gt;</span><span class="identifier">copy</span><span class="plain">-&gt;</span><span class="identifier">found_by</span><span class="plain">-&gt;</span><span class="identifier">work</span><span class="plain">);</span>
<span class="identifier">Problems::quote_stream</span><span class="plain">(2, </span><span class="identifier">CE</span><span class="plain">-&gt;</span><span class="identifier">notes</span><span class="plain">);</span>
<span class="identifier">Problems::quote_stream</span><span class="plain">(2, </span><span class="identifier">CE</span><span class="plain">-&gt;</span><span class="identifier">details</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_ExtMiswordedBeginsHere</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"The extension %1, which your source text makes use of, seems to be "</span>
@ -92,7 +92,7 @@ group.
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">KIT_MISWORDED_CE</span><span class="plain">:</span>
<span class="functiontext">Problems::quote_work</span><span class="plain">(1, </span><span class="identifier">CE</span><span class="plain">-&gt;</span><span class="identifier">copy</span><span class="plain">-&gt;</span><span class="identifier">found_by</span><span class="plain">-&gt;</span><span class="identifier">work</span><span class="plain">);</span>
<span class="identifier">Problems::quote_stream</span><span class="plain">(2, </span><span class="identifier">CE</span><span class="plain">-&gt;</span><span class="identifier">notes</span><span class="plain">);</span>
<span class="identifier">Problems::quote_stream</span><span class="plain">(2, </span><span class="identifier">CE</span><span class="plain">-&gt;</span><span class="identifier">details</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</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="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"The kit %1, which your source text makes use of, seems to be "</span>
@ -132,14 +132,14 @@ group.
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">CE</span><span class="plain">-&gt;</span><span class="identifier">error_subcategory</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="functiontext">Task::syntax_tree</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">CE</span><span class="plain">-&gt;</span><span class="identifier">word</span><span class="plain">,</span>
<span class="string">"Too much text in quotation marks"</span><span class="plain">, </span><span class="identifier">CE</span><span class="plain">-&gt;</span><span class="identifier">details_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="functiontext">Task::syntax_tree</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">CE</span><span class="plain">-&gt;</span><span class="identifier">word</span><span class="plain">,</span>
<span class="string">"Word too long"</span><span class="plain">, </span><span class="identifier">CE</span><span class="plain">-&gt;</span><span class="identifier">details_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>
@ -154,7 +154,7 @@ group.
<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="functiontext">Task::syntax_tree</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">CE</span><span class="plain">-&gt;</span><span class="identifier">word</span><span class="plain">,</span>
<span class="string">"Verbatim Inform 6 extract too long"</span><span class="plain">, </span><span class="identifier">CE</span><span class="plain">-&gt;</span><span class="identifier">details_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>

View file

@ -486,7 +486,7 @@ which continues until the client calls <code class="display"><span class="extrac
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">project</span><span class="plain">) {</span>
<span class="functiontext">Inbuild::pass_kit_requests</span><span class="plain">();</span>
<span class="functiontext">Copies::read_source_text_for</span><span class="plain">(</span><span class="identifier">project</span><span class="plain">-</span><span class="element">&gt;as_copy</span><span class="plain">);</span>
<span class="functiontext">Copies::get_source_text</span><span class="plain">(</span><span class="identifier">project</span><span class="plain">-</span><span class="element">&gt;as_copy</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">inbuild_phase</span><span class="plain"> = </span><span class="constant">PROJECTED_INBUILD_PHASE</span><span class="plain">;</span>
@ -646,25 +646,6 @@ used by applications, so <code class="display"><span class="extract">-transient<
Materials folder. For example, in <code class="display"><span class="extract">Jane Eyre.inform</span></code> is a project, then
alongside it is <code class="display"><span class="extract">Jane Eyre.materials</span></code> and this is a nest.
</li></ul>
<p class="inwebparagraph">Nests used by the Inform and Inbuild tools are tagged with the following
comstamts, except that no nest is ever tagged <code class="display"><span class="extract">NOT_A_NEST_TAG</span></code>.
(There used to be quite a good joke here, but refactoring of the
code removed its premiss. Literate programming is like that sometimes.)
</p>
<p class="inwebparagraph">The sequence of the following enumerated values is significant: lower
origins are better than later ones, when choosing the best result of
a search for resources.
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">NOT_A_NEST_TAG</span><span class="definitionkeyword"> from </span><span class="constant">0</span>
<span class="definitionkeyword">enum</span> <span class="constant">MATERIALS_NEST_TAG</span>
<span class="definitionkeyword">enum</span> <span class="constant">EXTERNAL_NEST_TAG</span>
<span class="definitionkeyword">enum</span> <span class="constant">GENERIC_NEST_TAG</span>
<span class="definitionkeyword">enum</span> <span class="constant">INTERNAL_NEST_TAG</span>
</pre>
<p class="inwebparagraph"><a id="SP13"></a><b>&#167;13. </b>Inform customarily has exactly one <code class="display"><span class="extract">-internal</span></code> and one <code class="display"><span class="extract">-external</span></code> nest,
but in fact any number of each are allowed, including none. However, the
first to be declared are used by the compiler as "the" internal and external

View file

@ -0,0 +1,360 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>2/cps</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 tools</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 '2/ce' 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#2">Chapter 2: Conceptual Framework</a></li><li><b>Copy Errors</b></li></ul><p class="purpose">A copy error is attached to a copy when scanning it reveals some malformation.</p>
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. </b>Copies can sometimes exist in a damaged form: for example, they are purportedly
extension files but have a mangled identification line. Each copy structure
therefore has a list attached of errors which occurred in reading it.
</p>
<p class="inwebparagraph">Each copy error has one of the following categories, and some are divided into
subcategories too. Otherwise an error has no real contents: only a ragbag of
contextual data &mdash; exactly what word it is that is too long, where the
sentence is which is mis-punctuated, and such. In every case most of these
fields are blank.
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">OPEN_FAILED_CE</span><span class="definitionkeyword"> from </span><span class="constant">1</span>
<span class="definitionkeyword">enum</span> <span class="constant">KIT_MISWORDED_CE</span>
<span class="definitionkeyword">enum</span> <span class="constant">EXT_MISWORDED_CE</span>
<span class="definitionkeyword">enum</span> <span class="constant">EXT_TITLE_TOO_LONG_CE</span>
<span class="definitionkeyword">enum</span> <span class="constant">EXT_AUTHOR_TOO_LONG_CE</span>
<span class="definitionkeyword">enum</span> <span class="constant">LEXER_CE</span><span class="plain"> </span> <span class="comment">an error generated by the <code class="display"><span class="extract">words</span></code> module</span>
<span class="definitionkeyword">enum</span> <span class="constant">SYNTAX_CE</span><span class="plain"> </span> <span class="comment">an error generated by the <code class="display"><span class="extract">syntax</span></code> module, or by our reading of the tree</span>
</pre>
<pre class="display">
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">copy_error</span><span class="plain"> {</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">copy</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">error_category</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">error_subcategory</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">details</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">filename</span><span class="plain"> *</span><span class="identifier">details_file</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">details_N</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">details_W</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">details_node</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">details_node2</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">inbuild_work</span><span class="plain"> *</span><span class="identifier">details_work</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">inbuild_work</span><span class="plain"> *</span><span class="identifier">details_work2</span><span class="plain">;</span>
<span class="identifier">wchar_t</span><span class="plain"> *</span><span class="identifier">details_word</span><span class="plain">;</span>
<span class="identifier">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">copy_error</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The structure copy_error is accessed in 2/nst, 3/is, 5/kts, 5/ed2, 5/ec, 5/ls, 6/inc and here.</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>And now some creators.
</p>
<pre class="display">
<span class="reserved">copy_error</span><span class="plain"> *</span><span class="functiontext">CopyErrors::new</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">cat</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">subcat</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="identifier">CREATE</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="element">&gt;copy</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">&gt;error_category</span><span class="plain"> = </span><span class="identifier">cat</span><span class="plain">;</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;error_subcategory</span><span class="plain"> = </span><span class="identifier">subcat</span><span class="plain">;</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details</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">&gt;details_file</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">&gt;details_N</span><span class="plain"> = -1;</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details_W</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details_node</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">&gt;details_node2</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">&gt;details_work</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">&gt;details_work2</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">&gt;details_word</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">CE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">copy_error</span><span class="plain"> *</span><span class="functiontext">CopyErrors::new_T</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">cat</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">subcat</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">NB</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">CopyErrors::new</span><span class="plain">(</span><span class="identifier">cat</span><span class="plain">, </span><span class="identifier">subcat</span><span class="plain">);</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">NB</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">CE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">copy_error</span><span class="plain"> *</span><span class="functiontext">CopyErrors::new_N</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">cat</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">subcat</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">N</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">CopyErrors::new</span><span class="plain">(</span><span class="identifier">cat</span><span class="plain">, </span><span class="identifier">subcat</span><span class="plain">);</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details_N</span><span class="plain"> = </span><span class="identifier">N</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">CE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">copy_error</span><span class="plain"> *</span><span class="functiontext">CopyErrors::new_F</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">cat</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">subcat</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="reserved">copy_error</span><span class="plain"> *</span><span class="identifier">CE</span><span class="plain"> = </span><span class="functiontext">CopyErrors::new</span><span class="plain">(</span><span class="identifier">cat</span><span class="plain">, </span><span class="identifier">subcat</span><span class="plain">);</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details_file</span><span class="plain"> = </span><span class="identifier">F</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">CE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">copy_error</span><span class="plain"> *</span><span class="functiontext">CopyErrors::new_WT</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">cat</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">subcat</span><span class="plain">, </span><span class="identifier">wchar_t</span><span class="plain"> *</span><span class="identifier">details_word</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">NB</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">CopyErrors::new</span><span class="plain">(</span><span class="identifier">cat</span><span class="plain">, </span><span class="identifier">subcat</span><span class="plain">);</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details_word</span><span class="plain"> = </span><span class="identifier">details_word</span><span class="plain">;</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">NB</span><span class="plain">);</span>
<span class="reserved">return</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">The function CopyErrors::new is used in 5/ps (<a href="5-ps.html#SP6">&#167;6</a>), 6/st (<a href="6-st.html#SP12">&#167;12</a>), 6/hdn (<a href="6-hdn.html#SP13_1">&#167;13.1</a>, <a href="6-hdn.html#SP13_2">&#167;13.2</a>, <a href="6-hdn.html#SP23_1">&#167;23.1</a>, <a href="6-hdn.html#SP24_1">&#167;24.1</a>, <a href="6-hdn.html#SP23_3">&#167;23.3</a>), 6/inc (<a href="6-inc.html#SP3_1">&#167;3.1</a>, <a href="6-inc.html#SP6_1_2">&#167;6.1.2</a>, <a href="6-inc.html#SP7_1">&#167;7.1</a>, <a href="6-inc.html#SP9_1">&#167;9.1</a>, <a href="6-inc.html#SP11">&#167;11</a>).</p>
<p class="endnote">The function CopyErrors::new_T is used in 5/kts (<a href="5-kts.html#SP1">&#167;1</a>), 5/es (<a href="5-es.html#SP1">&#167;1</a>, <a href="5-es.html#SP1_1">&#167;1.1</a>, <a href="5-es.html#SP1_1_3">&#167;1.1.3</a>, <a href="5-es.html#SP1_1_3_2">&#167;1.1.3.2</a>), 6/hdn (<a href="6-hdn.html#SP23_2">&#167;23.2</a>), 6/inc (<a href="6-inc.html#SP6_1_1">&#167;6.1.1</a>, <a href="6-inc.html#SP6_1_2">&#167;6.1.2</a>).</p>
<p class="endnote">The function CopyErrors::new_N is used in 5/es (<a href="5-es.html#SP1">&#167;1</a>), 6/st (<a href="6-st.html#SP4">&#167;4</a>).</p>
<p class="endnote">The function CopyErrors::new_F is used in 5/es (<a href="5-es.html#SP1_1">&#167;1.1</a>), 6/st (<a href="6-st.html#SP1">&#167;1</a>).</p>
<p class="endnote">The function CopyErrors::new_WT is used in 6/st (<a href="6-st.html#SP2">&#167;2</a>).</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>It becomes tiresome to make creators for every conceivable possibility, so
we also offer these functions to tack extra details on:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CopyErrors::supply_wording</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="identifier">wording</span><span class="plain"> </span><span class="identifier">details_W</span><span class="plain">) {</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details_W</span><span class="plain"> = </span><span class="identifier">details_W</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CopyErrors::supply_work</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="reserved">inbuild_work</span><span class="plain"> *</span><span class="identifier">w</span><span class="plain">) {</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details_work</span><span class="plain"> = </span><span class="identifier">w</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CopyErrors::supply_works</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="reserved">inbuild_work</span><span class="plain"> *</span><span class="identifier">w1</span><span class="plain">, </span><span class="reserved">inbuild_work</span><span class="plain"> *</span><span class="identifier">w2</span><span class="plain">) {</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details_work</span><span class="plain"> = </span><span class="identifier">w1</span><span class="plain">;</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details_work2</span><span class="plain"> = </span><span class="identifier">w2</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CopyErrors::supply_node</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="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">n</span><span class="plain">) {</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details_node</span><span class="plain"> = </span><span class="identifier">n</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CopyErrors::supply_nodes</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="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">n1</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">n2</span><span class="plain">) {</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details_node</span><span class="plain"> = </span><span class="identifier">n1</span><span class="plain">;</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details_node2</span><span class="plain"> = </span><span class="identifier">n2</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function CopyErrors::supply_wording is used in 6/st (<a href="6-st.html#SP4">&#167;4</a>), 6/hdn (<a href="6-hdn.html#SP23_2">&#167;23.2</a>), 6/inc (<a href="6-inc.html#SP11">&#167;11</a>).</p>
<p class="endnote">The function CopyErrors::supply_work is used in 6/hdn (<a href="6-hdn.html#SP23_1">&#167;23.1</a>, <a href="6-hdn.html#SP23_2">&#167;23.2</a>).</p>
<p class="endnote">The function CopyErrors::supply_works is used in 6/hdn (<a href="6-hdn.html#SP24_1">&#167;24.1</a>).</p>
<p class="endnote">The function CopyErrors::supply_node is used in 5/ps (<a href="5-ps.html#SP6">&#167;6</a>), 6/st (<a href="6-st.html#SP12">&#167;12</a>), 6/hdn (<a href="6-hdn.html#SP13_1">&#167;13.1</a>, <a href="6-hdn.html#SP13_2">&#167;13.2</a>, <a href="6-hdn.html#SP23_1">&#167;23.1</a>, <a href="6-hdn.html#SP23_2">&#167;23.2</a>, <a href="6-hdn.html#SP23_3">&#167;23.3</a>), 6/inc (<a href="6-inc.html#SP3_1">&#167;3.1</a>, <a href="6-inc.html#SP6_1_1">&#167;6.1.1</a>, <a href="6-inc.html#SP6_1_2">&#167;6.1.2</a>, <a href="6-inc.html#SP7_1">&#167;7.1</a>, <a href="6-inc.html#SP9_1">&#167;9.1</a>, <a href="6-inc.html#SP11">&#167;11</a>).</p>
<p class="endnote">The function CopyErrors::supply_nodes is used in 6/hdn (<a href="6-hdn.html#SP24_1">&#167;24.1</a>).</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>The following should only be called from Copies.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CopyErrors::supply_attached_copy</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="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain">) {</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;copy</span><span class="plain"> = </span><span class="identifier">C</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function CopyErrors::supply_attached_copy is used in 2/cps (<a href="2-cps.html#SP5">&#167;5</a>).</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b>This produces a textual summary of the issue described. It wouldn't do for
a proper Inform problem message, but it's fine for the Inbuild command line
output.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CopyErrors::write</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</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="reserved">switch</span><span class="plain"> (</span><span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;error_category</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">OPEN_FAILED_CE</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"unable to open file %f"</span><span class="plain">, </span><span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details_file</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="constant">EXT_MISWORDED_CE</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"extension misworded: %S"</span><span class="plain">, </span><span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details</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="constant">KIT_MISWORDED_CE</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"kit has incorrect metadata: %S"</span><span class="plain">, </span><span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details</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="constant">EXT_TITLE_TOO_LONG_CE</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"title too long: %d characters (max is %d)"</span><span class="plain">,</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details_N</span><span class="plain">, </span><span class="constant">MAX_EXTENSION_TITLE_LENGTH</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="constant">EXT_AUTHOR_TOO_LONG_CE</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"author name too long: %d characters (max is %d)"</span><span class="plain">,</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details_N</span><span class="plain">, </span><span class="constant">MAX_EXTENSION_AUTHOR_LENGTH</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="constant">LEXER_CE</span><span class="plain">: </span>&lt;<span class="cwebmacro">Write a lexer error</span> <span class="cwebmacronumber">5.1</span>&gt;<span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">SYNTAX_CE</span><span class="plain">: </span>&lt;<span class="cwebmacro">Write a syntax error</span> <span class="cwebmacronumber">5.2</span>&gt;<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">"an unknown error occurred"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function CopyErrors::write is used in 2/cps (<a href="2-cps.html#SP5">&#167;5</a>), 5/ec (<a href="5-ec.html#SP5">&#167;5</a>).</p>
<p class="inwebparagraph"><a id="SP5_1"></a><b>&#167;5.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Write a lexer error</span> <span class="cwebmacronumber">5.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;error_subcategory</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">WRITE</span><span class="plain">(</span><span class="string">"Too much text in quotation marks: %w"</span><span class="plain">, </span><span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details_word</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">WRITE</span><span class="plain">(</span><span class="string">"Word too long: %w"</span><span class="plain">, </span><span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details_word</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">WRITE</span><span class="plain">(</span><span class="string">"I6 inclusion too long: %w"</span><span class="plain">, </span><span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details_word</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">WRITE</span><span class="plain">(</span><span class="string">"Quoted text never ends: %S"</span><span class="plain">, </span><span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details</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">WRITE</span><span class="plain">(</span><span class="string">"Square-bracketed text never ends: %S"</span><span class="plain">, </span><span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details</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">WRITE</span><span class="plain">(</span><span class="string">"I6 inclusion text never ends: %S"</span><span class="plain">, </span><span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details</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">WRITE</span><span class="plain">(</span><span class="string">"lexer error"</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5">&#167;5</a>.</p>
<p class="inwebparagraph"><a id="SP5_2"></a><b>&#167;5.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Write a syntax error</span> <span class="cwebmacronumber">5.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;error_subcategory</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">UnexpectedSemicolon_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"unexpected semicolon in sentence"</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">ParaEndsInColon_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"paragraph ends with a colon"</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">SentenceEndsInColon_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"paragraph ends with a colon and full stop"</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">SentenceEndsInSemicolon_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"paragraph ends with a semicolon and full stop"</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">SemicolonAfterColon_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"paragraph ends with a colon and semicolon"</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">SemicolonAfterStop_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"paragraph ends with a full stop and semicolon"</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">HeadingOverLine_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"heading contains a line break"</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">HeadingStopsBeforeEndOfLine_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"heading stops before end of line"</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">ExtNoBeginsHere_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"extension has no beginning"</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">ExtNoEndsHere_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"extension has no end"</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">ExtSpuriouslyContinues_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"extension continues after end"</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="constant">ExtMultipleBeginsHere_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"extension has multiple 'begins here' sentences"</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="constant">ExtBeginsAfterEndsHere_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"extension has a 'begins here' after its 'ends here'"</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="constant">ExtEndsWithoutBegins_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"extension has an 'ends here' but no 'begins here'"</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="constant">ExtMultipleEndsHere_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"extension has multiple 'ends here' sentences"</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="constant">BadTitleSentence_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"bibliographic sentence at the start is malformed"</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="constant">UnknownLanguageElement_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"unrecognised stipulation about Inform language elements"</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="constant">UnknownVirtualMachine_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"unrecognised stipulation about virtual machine"</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="constant">UseElementWithdrawn_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"use language element is no longer supported"</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="constant">IncludeExtQuoted_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"extension name should not be double-quoted"</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="constant">BogusExtension_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"can't find this extension"</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="constant">ExtVersionTooLow_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"extension version too low"</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="constant">ExtVersionMalformed_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"extension version is malformed"</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="constant">ExtInadequateVM_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"extension is not compatible with the target virtual machine"</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="constant">ExtMisidentifiedEnds_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"extension has an 'ends here' which doesn't match the 'begins here'"</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="constant">HeadingInPlaceOfUnincluded_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"heading is in place of an extension not included"</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="constant">UnequalHeadingInPlaceOf_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"heading is in place of another heading but of a diffeent level"</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="constant">HeadingInPlaceOfSubordinate_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"heading is in place of another heading subordinate to itself"</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="constant">HeadingInPlaceOfUnknown_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"heading is in place of another heading which doesn't exist'"</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">WRITE</span><span class="plain">(</span><span class="string">"syntax error"</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5">&#167;5</a>.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="2-cps.html">Back to 'Copies'</a></li><li><a href="2-rqr.html">Continue with 'Requirements'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</main>
</body>
</html>

View file

@ -59,70 +59,223 @@
<!--Weave of '2/cps' 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#2">Chapter 2: Conceptual Framework</a></li><li><b>Copies</b></li></ul><p class="purpose">A copy is an instance in the file system of a specific edition of a work.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Copies</a></li><li><a href="#SP2">&#167;2. Errors</a></li></ul><hr class="tocbar">
<ul class="toc"><li><a href="#SP1">&#167;1. Creation</a></li><li><a href="#SP5">&#167;5. List of errors</a></li><li><a href="#SP6">&#167;6. Writing</a></li><li><a href="#SP7">&#167;7. Reading source text</a></li><li><a href="#SP8">&#167;8. Going operational</a></li><li><a href="#SP9">&#167;9. Miscellaneous Inbuild commands</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Copies. </b>A "copy" of a work exists in the file system when we've actually got hold of
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Creation. </b>A "copy" of a work exists in the file system when we've actually got hold of
some edition of it. For some genres, copies will be files; for others,
directories holding a set of files.
</p>
<p class="inwebparagraph">A purist view would be that a copy is simply an edition at a location in the
file system. And so it is. But copies are the main things Inbuild works on,
and we will need to generate data about them, some of which is most usefully
stored here.
</p>
<pre class="display">
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">inbuild_copy</span><span class="plain"> {</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">inbuild_edition</span><span class="plain"> *</span><span class="identifier">edition</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">location_if_path</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">inbuild_edition</span><span class="plain"> *</span><span class="identifier">edition</span><span class="plain">; </span> <span class="comment">what is this a copy of?</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">location_if_path</span><span class="plain">; </span> <span class="comment">exactly one of these must be non-<code class="display"><span class="extract">NULL</span></code></span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">filename</span><span class="plain"> *</span><span class="identifier">location_if_file</span><span class="plain">;</span>
<span class="identifier">general_pointer</span><span class="plain"> </span><span class="identifier">content</span><span class="plain">; </span> <span class="comment">the type of which depends on the work's genre</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">vertex</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">source_text_read</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">source_text</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">linked_list</span><span class="plain"> *</span><span class="identifier">errors_reading_source_text</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">inbuild_requirement</span><span class="plain"> *</span><span class="identifier">found_by</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">vertex</span><span class="plain">; </span> <span class="comment">head vertex of build graph for this copy</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">source_text_read</span><span class="plain">; </span> <span class="comment">have we attempted to read Inform source text from this?</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">source_text</span><span class="plain">; </span> <span class="comment">the source text we read, if so</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">inbuild_requirement</span><span class="plain"> *</span><span class="identifier">found_by</span><span class="plain">; </span> <span class="comment">if this was claimed in a search</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">linked_list</span><span class="plain"> *</span><span class="identifier">errors_reading_source_text</span><span class="plain">; </span> <span class="comment">of <code class="display"><span class="extract">copy_error</span></code></span>
<span class="identifier">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">inbuild_copy</span><span class="plain">;</span>
</pre>
<span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="functiontext">Copies::new_p</span><span class="plain">(</span><span class="reserved">inbuild_edition</span><span class="plain"> *</span><span class="identifier">edition</span><span class="plain">, </span><span class="identifier">general_pointer</span><span class="plain"> </span><span class="identifier">ref</span><span class="plain">) {</span>
<p class="inwebparagraph"></p>
<p class="endnote">The structure inbuild_copy is accessed in 1/ic, 2/nst, 3/bg, 3/bs2, 3/is, 3/is2, 3/is3, 3/is4, 4/km, 4/em, 4/lm, 4/pbm, 4/pfm, 4/tm, 4/pm, 5/kts, 5/es, 5/ed, 5/ed2, 5/ec, 5/ps, 5/ls, 6/hdn, 6/inc and here.</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>Copies are created by the managers for the respective genres, usually when
claiming. If you are a manager, do not call this...
</p>
<pre class="display">
<span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="functiontext">Copies::new_p</span><span class="plain">(</span><span class="reserved">inbuild_edition</span><span class="plain"> *</span><span class="identifier">edition</span><span class="plain">) {</span>
<span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">copy</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">inbuild_copy</span><span class="plain">);</span>
<span class="identifier">copy</span><span class="plain">-</span><span class="element">&gt;edition</span><span class="plain"> = </span><span class="identifier">edition</span><span class="plain">;</span>
<span class="identifier">copy</span><span class="plain">-</span><span class="element">&gt;location_if_path</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">copy</span><span class="plain">-</span><span class="element">&gt;location_if_file</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">copy</span><span class="plain">-</span><span class="element">&gt;content</span><span class="plain"> = </span><span class="identifier">ref</span><span class="plain">;</span>
<span class="identifier">copy</span><span class="plain">-</span><span class="element">&gt;content</span><span class="plain"> = </span><span class="identifier">NULL_GENERAL_POINTER</span><span class="plain">;</span>
<span class="identifier">copy</span><span class="plain">-</span><span class="element">&gt;vertex</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">copy</span><span class="plain">-</span><span class="element">&gt;source_text_read</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">copy</span><span class="plain">-</span><span class="element">&gt;source_text</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="identifier">copy</span><span class="plain">-</span><span class="element">&gt;errors_reading_source_text</span><span class="plain"> = </span><span class="identifier">NEW_LINKED_LIST</span><span class="plain">(</span><span class="reserved">copy_error</span><span class="plain">);</span>
<span class="identifier">copy</span><span class="plain">-</span><span class="element">&gt;found_by</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">copy</span><span class="plain">-</span><span class="element">&gt;errors_reading_source_text</span><span class="plain"> = </span><span class="identifier">NEW_LINKED_LIST</span><span class="plain">(</span><span class="reserved">copy_error</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">copy</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="functiontext">Copies::new_in_file</span><span class="plain">(</span><span class="reserved">inbuild_edition</span><span class="plain"> *</span><span class="identifier">edition</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">general_pointer</span><span class="plain"> </span><span class="identifier">ref</span><span class="plain">) {</span>
<span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">copy</span><span class="plain"> = </span><span class="functiontext">Copies::new_p</span><span class="plain">(</span><span class="identifier">edition</span><span class="plain">, </span><span class="identifier">ref</span><span class="plain">);</span>
<p class="inwebparagraph"></p>
<p class="endnote">The function Copies::new_p is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>...call one of these:
</p>
<pre class="display">
<span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="functiontext">Copies::new_in_file</span><span class="plain">(</span><span class="reserved">inbuild_edition</span><span class="plain"> *</span><span class="identifier">edition</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="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">copy</span><span class="plain"> = </span><span class="functiontext">Copies::new_p</span><span class="plain">(</span><span class="identifier">edition</span><span class="plain">);</span>
<span class="identifier">copy</span><span class="plain">-</span><span class="element">&gt;location_if_file</span><span class="plain"> = </span><span class="identifier">F</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">copy</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="functiontext">Copies::new_in_path</span><span class="plain">(</span><span class="reserved">inbuild_edition</span><span class="plain"> *</span><span class="identifier">edition</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">general_pointer</span><span class="plain"> </span><span class="identifier">ref</span><span class="plain">) {</span>
<span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">copy</span><span class="plain"> = </span><span class="functiontext">Copies::new_p</span><span class="plain">(</span><span class="identifier">edition</span><span class="plain">, </span><span class="identifier">ref</span><span class="plain">);</span>
<span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="functiontext">Copies::new_in_path</span><span class="plain">(</span><span class="reserved">inbuild_edition</span><span class="plain"> *</span><span class="identifier">edition</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="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">copy</span><span class="plain"> = </span><span class="functiontext">Copies::new_p</span><span class="plain">(</span><span class="identifier">edition</span><span class="plain">);</span>
<span class="identifier">copy</span><span class="plain">-</span><span class="element">&gt;location_if_path</span><span class="plain"> = </span><span class="identifier">P</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">copy</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Copies::new_in_file is used in 4/em (<a href="4-em.html#SP5">&#167;5</a>), 4/pfm (<a href="4-pfm.html#SP2">&#167;2</a>), 4/pm (<a href="4-pm.html#SP4">&#167;4</a>).</p>
<p class="endnote">The function Copies::new_in_path is used in 4/km (<a href="4-km.html#SP3">&#167;3</a>), 4/lm (<a href="4-lm.html#SP4">&#167;4</a>), 4/pbm (<a href="4-pbm.html#SP2">&#167;2</a>), 4/tm (<a href="4-tm.html#SP3">&#167;3</a>).</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>And then probably follow up by calling this, to attach a pointer to some
additional data specific to your genre:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Copies::set_content</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">general_pointer</span><span class="plain"> </span><span class="identifier">ref</span><span class="plain">) {</span>
<span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;content</span><span class="plain"> = </span><span class="identifier">ref</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Copies::set_content is used in 4/lm (<a href="4-lm.html#SP4">&#167;4</a>), 4/pbm (<a href="4-pbm.html#SP2">&#167;2</a>), 4/pfm (<a href="4-pfm.html#SP2">&#167;2</a>), 4/tm (<a href="4-tm.html#SP3">&#167;3</a>), 4/pm (<a href="4-pm.html#SP4">&#167;4</a>), 5/kts (<a href="5-kts.html#SP1">&#167;1</a>), 5/es (<a href="5-es.html#SP1">&#167;1</a>).</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. List of errors. </b>When copies are found to be malformed, error messages are attached to them
for later reporting. These are stored in a list.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Copies::attach_error</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="reserved">copy_error</span><span class="plain"> *</span><span class="identifier">CE</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">C</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 copy to attach to"</span><span class="plain">);</span>
<span class="functiontext">CopyErrors::supply_attached_copy</span><span class="plain">(</span><span class="identifier">CE</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">);</span>
<span class="identifier">ADD_TO_LINKED_LIST</span><span class="plain">(</span><span class="identifier">CE</span><span class="plain">, </span><span class="reserved">copy_error</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;errors_reading_source_text</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Copies::list_attached_errors</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</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="reserved">if</span><span class="plain"> (</span><span class="identifier">C</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="reserved">copy_error</span><span class="plain"> *</span><span class="identifier">CE</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">c</span><span class="plain"> = 1;</span>
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">CE</span><span class="plain">, </span><span class="reserved">copy_error</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;errors_reading_source_text</span><span class="plain">) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%d. "</span><span class="plain">, </span><span class="identifier">c</span><span class="plain">++); </span><span class="functiontext">CopyErrors::write</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">CE</span><span class="plain">); </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Copies::attach_error is used in 5/kts (<a href="5-kts.html#SP1">&#167;1</a>), 5/es (<a href="5-es.html#SP1">&#167;1</a>, <a href="5-es.html#SP1_1">&#167;1.1</a>, <a href="5-es.html#SP1_1_3">&#167;1.1.3</a>, <a href="5-es.html#SP1_1_3_2">&#167;1.1.3.2</a>), 5/ps (<a href="5-ps.html#SP6">&#167;6</a>), 6/st (<a href="6-st.html#SP1">&#167;1</a>, <a href="6-st.html#SP2">&#167;2</a>, <a href="6-st.html#SP4">&#167;4</a>, <a href="6-st.html#SP12">&#167;12</a>), 6/hdn (<a href="6-hdn.html#SP13_1">&#167;13.1</a>, <a href="6-hdn.html#SP13_2">&#167;13.2</a>, <a href="6-hdn.html#SP23_1">&#167;23.1</a>, <a href="6-hdn.html#SP24_1">&#167;24.1</a>, <a href="6-hdn.html#SP23_2">&#167;23.2</a>, <a href="6-hdn.html#SP23_3">&#167;23.3</a>), 6/inc (<a href="6-inc.html#SP3_1">&#167;3.1</a>, <a href="6-inc.html#SP6_1_1">&#167;6.1.1</a>, <a href="6-inc.html#SP6_1_2">&#167;6.1.2</a>, <a href="6-inc.html#SP7_1">&#167;7.1</a>, <a href="6-inc.html#SP9_1">&#167;9.1</a>, <a href="6-inc.html#SP11">&#167;11</a>).</p>
<p class="endnote">The function Copies::list_attached_errors is used in <a href="#SP9">&#167;9</a>, 5/ps (<a href="5-ps.html#SP4">&#167;4</a>), 6/inc (<a href="6-inc.html#SP6_1">&#167;6.1</a>).</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. Writing. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Copies::write_copy</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</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="functiontext">Editions::write</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;edition</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Copies::inspect_copy</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</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="functiontext">Editions::inspect</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;edition</span><span class="plain">);</span>
<p class="inwebparagraph"></p>
<p class="endnote">The function Copies::write_copy is used in 3/bg (<a href="3-bg.html#SP1">&#167;1</a>).</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. Reading source text. </b></p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Copies::source_text_has_been_read</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="reserved">if</span><span class="plain"> (</span><span class="identifier">C</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 copy"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;source_text_read</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="functiontext">Copies::get_source_text</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="reserved">if</span><span class="plain"> (</span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;source_text_read</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;source_text_read</span><span class="plain"> = </span><span class="identifier">TRUE</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">VMETHOD_CALL</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;edition</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">-</span><span class="element">&gt;genre</span><span class="plain">, </span><span class="constant">GENRE_READ_SOURCE_TEXT_FOR_MTID</span><span class="plain">, </span><span class="identifier">C</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::end</span><span class="plain">(</span><span class="identifier">id</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="identifier">C</span><span class="plain">-</span><span class="element">&gt;source_text</span><span class="plain"> = </span><span class="identifier">W</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;source_text</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Copies::source_text_has_been_read is used in 6/inc (<a href="6-inc.html#SP6">&#167;6</a>).</p>
<p class="endnote">The function Copies::get_source_text is used in 1/ic (<a href="1-ic.html#SP9">&#167;9</a>), 4/em (<a href="4-em.html#SP9">&#167;9</a>), 5/ed2 (<a href="5-ed2.html#SP3_1">&#167;3.1</a>), 6/inc (<a href="6-inc.html#SP6_1">&#167;6.1</a>).</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. Going operational. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Copies::go_operational</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">VMETHOD_CALL</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;edition</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">-</span><span class="element">&gt;genre</span><span class="plain">, </span><span class="constant">GENRE_GO_OPERATIONAL_MTID</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Copies::go_operational is used in 1/ic (<a href="1-ic.html#SP11">&#167;11</a>).</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. Miscellaneous Inbuild commands. </b>This function implements the command-line instruction to <code class="display"><span class="extract">-inspect</span></code>.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Copies::inspect</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</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">WRITE</span><span class="plain">(</span><span class="string">"%S: "</span><span class="plain">, </span><span class="functiontext">Genres::name</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;edition</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">-</span><span class="element">&gt;genre</span><span class="plain">));</span>
<span class="functiontext">Editions::inspect</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;edition</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;location_if_path</span><span class="plain">) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" at path %p"</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;location_if_path</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;location_if_file</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">Filenames::get_path_to</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;location_if_file</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">P</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" in directory %p"</span><span class="plain">, </span><span class="identifier">P</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">N</span><span class="plain"> = </span><span class="identifier">LinkedLists::len</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;errors_reading_source_text</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">N</span><span class="plain"> &gt; 0) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" - %d error"</span><span class="plain">, </span><span class="identifier">N</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">N</span><span class="plain"> &gt; 1) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"s"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">N</span><span class="plain"> &gt; 0) {</span>
<span class="identifier">INDENT</span><span class="plain">; </span><span class="functiontext">Copies::list_attached_errors</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">); </span><span class="identifier">OUTDENT</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Copies::inspect appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. </b>And here are <code class="display"><span class="extract">-build</span></code> and <code class="display"><span class="extract">-rebuild</span></code>, though note that <code class="display"><span class="extract">Copies::build</span></code>
is also called by the <code class="display"><span class="extract">core</span></code> module of the Inform 7 compiler to perform
its main task: building an Inform project.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Copies::build</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</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="reserved">build_methodology</span><span class="plain"> *</span><span class="identifier">BM</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="identifier">C</span><span class="plain">-</span><span class="element">&gt;vertex</span><span class="plain">;</span>
<span class="identifier">VMETHOD_CALL</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;edition</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">-</span><span class="element">&gt;genre</span><span class="plain">, </span><span class="constant">GENRE_BUILDING_SOON_MTID</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">, &amp;</span><span class="identifier">V</span><span class="plain">);</span>
@ -133,6 +286,20 @@ directories holding a set of files.
<span class="identifier">VMETHOD_CALL</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;edition</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">-</span><span class="element">&gt;genre</span><span class="plain">, </span><span class="constant">GENRE_BUILDING_SOON_MTID</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">, &amp;</span><span class="identifier">V</span><span class="plain">);</span>
<span class="functiontext">Graphs::rebuild</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">, </span><span class="identifier">BM</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Copies::build appears nowhere else.</p>
<p class="endnote">The function Copies::rebuild appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP11"></a><b>&#167;11. </b>Now in quick succession <code class="display"><span class="extract">-graph</span></code>, <code class="display"><span class="extract">-build-needs</span></code>, <code class="display"><span class="extract">-use-needs</span></code>, <code class="display"><span class="extract">-build-missing</span></code>,
<code class="display"><span class="extract">-use-missing</span></code>:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Copies::show_graph</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</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="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">V</span><span class="plain"> = </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;vertex</span><span class="plain">;</span>
<span class="identifier">VMETHOD_CALL</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;edition</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">-</span><span class="element">&gt;genre</span><span class="plain">, </span><span class="constant">GENRE_BUILDING_SOON_MTID</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">, &amp;</span><span class="identifier">V</span><span class="plain">);</span>
@ -149,293 +316,61 @@ directories holding a set of files.
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">N</span><span class="plain"> = </span><span class="functiontext">Graphs::show_missing</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;vertex</span><span class="plain">, </span><span class="identifier">uses_only</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">N</span><span class="plain"> == 0) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"Nothing is missing\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Copies::archive</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</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="reserved">inbuild_nest</span><span class="plain"> *</span><span class="identifier">N</span><span class="plain">, </span><span class="reserved">build_methodology</span><span class="plain"> *</span><span class="identifier">BM</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="identifier">C</span><span class="plain">-</span><span class="element">&gt;vertex</span><span class="plain">;</span>
<span class="identifier">VMETHOD_CALL</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;edition</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">-</span><span class="element">&gt;genre</span><span class="plain">, </span><span class="constant">GENRE_BUILDING_SOON_MTID</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">, &amp;</span><span class="identifier">V</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">NM</span><span class="plain"> = </span><span class="functiontext">Graphs::show_missing</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;vertex</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">NM</span><span class="plain"> &gt; 0) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"Because there are missing resources, -archive is cancelled\</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="reserved">if</span><span class="plain"> (</span><span class="identifier">N</span><span class="plain">) </span><span class="functiontext">Graphs::archive</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;vertex</span><span class="plain">, </span><span class="identifier">N</span><span class="plain">, </span><span class="identifier">BM</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Copies::source_text_has_been_read</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="reserved">if</span><span class="plain"> (</span><span class="identifier">C</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 copy"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;source_text_read</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="functiontext">Copies::read_source_text_for</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="reserved">if</span><span class="plain"> (</span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;source_text_read</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;source_text_read</span><span class="plain"> = </span><span class="identifier">TRUE</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">VMETHOD_CALL</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;edition</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">-</span><span class="element">&gt;genre</span><span class="plain">, </span><span class="constant">GENRE_READ_SOURCE_TEXT_FOR_MTID</span><span class="plain">, </span><span class="identifier">C</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::end</span><span class="plain">(</span><span class="identifier">id</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="identifier">C</span><span class="plain">-</span><span class="element">&gt;source_text</span><span class="plain"> = </span><span class="identifier">W</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;source_text</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="functiontext">Copies::claim</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">arg</span><span class="plain">) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">ext</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">pos</span><span class="plain"> = </span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">) - 1, </span><span class="identifier">dotpos</span><span class="plain"> = -1;</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">pos</span><span class="plain"> &gt;= 0) {</span>
<span class="identifier">wchar_t</span><span class="plain"> </span><span class="identifier">c</span><span class="plain"> = </span><span class="identifier">Str::get_at</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">, </span><span class="identifier">pos</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">c</span><span class="plain"> == </span><span class="identifier">FOLDER_SEPARATOR</span><span class="plain">) </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">c</span><span class="plain"> == </span><span class="character">'.'</span><span class="plain">) </span><span class="identifier">dotpos</span><span class="plain"> = </span><span class="identifier">pos</span><span class="plain">;</span>
<span class="identifier">pos</span><span class="plain">--;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">dotpos</span><span class="plain"> &gt;= 0)</span>
<span class="identifier">Str::substr</span><span class="plain">(</span><span class="identifier">ext</span><span class="plain">, </span><span class="identifier">Str::at</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">, </span><span class="identifier">dotpos</span><span class="plain">+1), </span><span class="identifier">Str::end</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">));</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">directory_status</span><span class="plain"> = </span><span class="identifier">NOT_APPLICABLE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::get_last_char</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">) == </span><span class="identifier">FOLDER_SEPARATOR</span><span class="plain">) {</span>
<span class="identifier">Str::delete_last_character</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">);</span>
<span class="identifier">directory_status</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</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">NULL</span><span class="plain">;</span>
<span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">G</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">G</span><span class="plain">, </span><span class="reserved">inbuild_genre</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">C</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)</span>
<span class="identifier">VMETHOD_CALL</span><span class="plain">(</span><span class="identifier">G</span><span class="plain">, </span><span class="constant">GENRE_CLAIM_AS_COPY_MTID</span><span class="plain">, &amp;</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">arg</span><span class="plain">, </span><span class="identifier">ext</span><span class="plain">, </span><span class="identifier">directory_status</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</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">C</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Copies::inspect</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</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">WRITE</span><span class="plain">(</span><span class="string">"%S: "</span><span class="plain">, </span><span class="functiontext">Genres::name</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;edition</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">-</span><span class="element">&gt;genre</span><span class="plain">));</span>
<span class="functiontext">Copies::inspect_copy</span><span class="plain">(</span><span class="identifier">STDOUT</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;location_if_path</span><span class="plain">) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" at path %p"</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;location_if_path</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;location_if_file</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">Filenames::get_path_to</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;location_if_file</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">P</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" in directory %p"</span><span class="plain">, </span><span class="identifier">P</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">N</span><span class="plain"> = </span><span class="identifier">LinkedLists::len</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;errors_reading_source_text</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">N</span><span class="plain"> &gt; 0) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" - %d error"</span><span class="plain">, </span><span class="identifier">N</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">N</span><span class="plain"> &gt; 1) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"s"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">N</span><span class="plain"> &gt; 0) {</span>
<span class="identifier">INDENT</span><span class="plain">; </span><span class="functiontext">Copies::list_problems_arising</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">); </span><span class="identifier">OUTDENT</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Copies::new_p appears nowhere else.</p>
<p class="endnote">The function Copies::new_in_file is used in 4/em (<a href="4-em.html#SP5">&#167;5</a>), 4/pfm (<a href="4-pfm.html#SP2">&#167;2</a>), 4/pm (<a href="4-pm.html#SP4">&#167;4</a>).</p>
<p class="endnote">The function Copies::new_in_path is used in 4/km (<a href="4-km.html#SP3">&#167;3</a>), 4/lm (<a href="4-lm.html#SP4">&#167;4</a>), 4/pbm (<a href="4-pbm.html#SP2">&#167;2</a>), 4/tm (<a href="4-tm.html#SP3">&#167;3</a>).</p>
<p class="endnote">The function Copies::set_content is used in 5/kts (<a href="5-kts.html#SP1">&#167;1</a>), 5/es (<a href="5-es.html#SP1">&#167;1</a>).</p>
<p class="endnote">The function Copies::write_copy is used in 3/bg (<a href="3-bg.html#SP1">&#167;1</a>).</p>
<p class="endnote">The function Copies::inspect_copy appears nowhere else.</p>
<p class="endnote">The function Copies::go_operational is used in 1/ic (<a href="1-ic.html#SP11">&#167;11</a>).</p>
<p class="endnote">The function Copies::build appears nowhere else.</p>
<p class="endnote">The function Copies::rebuild appears nowhere else.</p>
<p class="endnote">The function Copies::show_graph appears nowhere else.</p>
<p class="endnote">The function Copies::show_needs appears nowhere else.</p>
<p class="endnote">The function Copies::show_missing appears nowhere else.</p>
<p class="endnote">The function Copies::archive appears nowhere else.</p>
<p class="endnote">The function Copies::source_text_has_been_read is used in 6/inc (<a href="6-inc.html#SP6">&#167;6</a>).</p>
<p class="endnote">The function Copies::read_source_text_for is used in 1/ic (<a href="1-ic.html#SP9">&#167;9</a>), 4/em (<a href="4-em.html#SP9">&#167;9</a>), 5/ed2 (<a href="5-ed2.html#SP3_1">&#167;3.1</a>), 6/inc (<a href="6-inc.html#SP6_1">&#167;6.1</a>).</p>
<p class="endnote">The function Copies::claim appears nowhere else.</p>
<p class="endnote">The function Copies::inspect appears nowhere else.</p>
<p class="endnote">The structure inbuild_copy is accessed in 1/ic, 2/nst, 3/bg, 3/bs2, 3/is, 3/is2, 3/is3, 3/is4, 4/km, 4/em, 4/lm, 4/pbm, 4/pfm, 4/tm, 4/pm, 5/kts, 5/es, 5/ed, 5/ed2, 5/ec, 5/ps, 5/ls, 6/hdn, 6/inc and here.</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. Errors. </b>Copies can sometimes exist in a damaged form: for example, they are purportedly
extension files but have a mangled identification line. Each copy structure
therefore has a list attached of errors which occurred in reading it.
<p class="inwebparagraph"><a id="SP12"></a><b>&#167;12. </b>And here is <code class="display"><span class="extract">-archive</span></code> and <code class="display"><span class="extract">-archive-to N</span></code>:
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">OPEN_FAILED_CE</span><span class="definitionkeyword"> from </span><span class="constant">1</span>
<span class="definitionkeyword">enum</span> <span class="constant">KIT_MISWORDED_CE</span>
<span class="definitionkeyword">enum</span> <span class="constant">EXT_MISWORDED_CE</span>
<span class="definitionkeyword">enum</span> <span class="constant">EXT_TITLE_TOO_LONG_CE</span>
<span class="definitionkeyword">enum</span> <span class="constant">EXT_AUTHOR_TOO_LONG_CE</span>
<span class="definitionkeyword">enum</span> <span class="constant">LEXER_CE</span>
<span class="definitionkeyword">enum</span> <span class="constant">SYNTAX_CE</span>
</pre>
<pre class="display">
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">copy_error</span><span class="plain"> {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">error_category</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">error_subcategory</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">copy</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">filename</span><span class="plain"> *</span><span class="identifier">file</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_file_position</span><span class="plain"> </span><span class="identifier">pos</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">notes</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">details</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">details_N</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">details_W</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">details_node</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">details_node2</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">inbuild_work</span><span class="plain"> *</span><span class="identifier">details_work</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">inbuild_work</span><span class="plain"> *</span><span class="identifier">details_work2</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="identifier">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">copy_error</span><span class="plain">;</span>
<span class="reserved">copy_error</span><span class="plain"> *</span><span class="functiontext">Copies::new_error</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">cat</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">NB</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="identifier">CREATE</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="element">&gt;error_category</span><span class="plain"> = </span><span class="identifier">cat</span><span class="plain">;</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;error_subcategory</span><span class="plain"> = -1;</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;file</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">&gt;notes</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">NB</span><span class="plain">);</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details</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">&gt;details_N</span><span class="plain"> = -1;</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details_W</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details_node</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">&gt;details_node2</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">&gt;details_work</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">&gt;details_work2</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">&gt;pos</span><span class="plain"> = </span><span class="identifier">TextFiles::nowhere</span><span class="plain">();</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;copy</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">&gt;word</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">CE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">copy_error</span><span class="plain"> *</span><span class="functiontext">Copies::new_error_N</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">cat</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">N</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="identifier">cat</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">&gt;details_N</span><span class="plain"> = </span><span class="identifier">N</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">CE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">copy_error</span><span class="plain"> *</span><span class="functiontext">Copies::new_error_on_file</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">cat</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="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="identifier">cat</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">&gt;file</span><span class="plain"> = </span><span class="identifier">F</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">CE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Copies::attach</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="reserved">copy_error</span><span class="plain"> *</span><span class="identifier">CE</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">C</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 copy to attach to"</span><span class="plain">);</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;copy</span><span class="plain"> = </span><span class="identifier">C</span><span class="plain">;</span>
<span class="identifier">ADD_TO_LINKED_LIST</span><span class="plain">(</span><span class="identifier">CE</span><span class="plain">, </span><span class="reserved">copy_error</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;errors_reading_source_text</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Copies::list_problems_arising</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</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="reserved">if</span><span class="plain"> (</span><span class="identifier">C</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="reserved">copy_error</span><span class="plain"> *</span><span class="identifier">CE</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">c</span><span class="plain"> = 1;</span>
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">CE</span><span class="plain">, </span><span class="reserved">copy_error</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;errors_reading_source_text</span><span class="plain">) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%d. "</span><span class="plain">, </span><span class="identifier">c</span><span class="plain">++); </span><span class="functiontext">Copies::write_problem</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">CE</span><span class="plain">); </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Copies::write_problem</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</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="reserved">switch</span><span class="plain"> (</span><span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;error_category</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">OPEN_FAILED_CE</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"unable to open file %f"</span><span class="plain">, </span><span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;file</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="constant">EXT_MISWORDED_CE</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"extension misworded: %S"</span><span class="plain">, </span><span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;notes</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="constant">KIT_MISWORDED_CE</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"kit has incorrect metadata: %S"</span><span class="plain">, </span><span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;notes</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="constant">EXT_TITLE_TOO_LONG_CE</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"title too long: %d characters (max is %d)"</span><span class="plain">,</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details_N</span><span class="plain">, </span><span class="constant">MAX_EXTENSION_TITLE_LENGTH</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="constant">EXT_AUTHOR_TOO_LONG_CE</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"author name too long: %d characters (max is %d)"</span><span class="plain">,</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details_N</span><span class="plain">, </span><span class="constant">MAX_EXTENSION_AUTHOR_LENGTH</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="constant">LEXER_CE</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%S"</span><span class="plain">, </span><span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;notes</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="constant">SYNTAX_CE</span><span class="plain">:</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;error_subcategory</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">UnexpectedSemicolon_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"unexpected semicolon in sentence"</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">ParaEndsInColon_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"paragraph ends with a colon"</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">SentenceEndsInColon_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"paragraph ends with a colon and full stop"</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">SentenceEndsInSemicolon_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"paragraph ends with a semicolon and full stop"</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">SemicolonAfterColon_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"paragraph ends with a colon and semicolon"</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">SemicolonAfterStop_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"paragraph ends with a full stop and semicolon"</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">HeadingOverLine_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"heading contains a line break"</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">HeadingStopsBeforeEndOfLine_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"heading stops before end of line"</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">ExtNoBeginsHere_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"extension has no beginning"</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">ExtNoEndsHere_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"extension has no end"</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">ExtSpuriouslyContinues_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"extension continues after end"</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="constant">ExtMultipleBeginsHere_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"extension has multiple 'begins here' sentences"</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="constant">ExtBeginsAfterEndsHere_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"extension has a 'begins here' after its 'ends here'"</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="constant">ExtEndsWithoutBegins_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"extension has an 'ends here' but no 'begins here'"</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="constant">ExtMultipleEndsHere_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"extension has multiple 'ends here' sentences"</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="constant">BadTitleSentence_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"bibliographic sentence at the start is malformed"</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="constant">UnknownLanguageElement_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"unrecognised stipulation about Inform language elements"</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="constant">UnknownVirtualMachine_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"unrecognised stipulation about virtual machine"</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="constant">UseElementWithdrawn_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"use language element is no longer supported"</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="constant">IncludeExtQuoted_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"extension name should not be double-quoted"</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="constant">BogusExtension_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"can't find this extension"</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="constant">ExtVersionTooLow_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"extension version too low"</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="constant">ExtVersionMalformed_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"extension version is malformed"</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="constant">ExtInadequateVM_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"extension is not compatible with the target virtual machine"</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="constant">ExtMisidentifiedEnds_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"extension has an 'ends here' but it does not match the 'begins here'"</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="constant">HeadingInPlaceOfUnincluded_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"heading is in place of an extension not included"</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="constant">UnequalHeadingInPlaceOf_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"heading is in place of another heading but of a diffeent level"</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="constant">HeadingInPlaceOfSubordinate_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"heading is in place of another heading subordinate to itself"</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="constant">HeadingInPlaceOfUnknown_SYNERROR</span><span class="plain">:</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"heading is in place of another heading which doesn't seem to exist'"</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">WRITE</span><span class="plain">(</span><span class="string">"syntax error"</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</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">"an unknown error occurred"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Copies::archive</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</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="reserved">inbuild_nest</span><span class="plain"> *</span><span class="identifier">N</span><span class="plain">, </span><span class="reserved">build_methodology</span><span class="plain"> *</span><span class="identifier">BM</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="identifier">C</span><span class="plain">-</span><span class="element">&gt;vertex</span><span class="plain">;</span>
<span class="identifier">VMETHOD_CALL</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;edition</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">-</span><span class="element">&gt;genre</span><span class="plain">, </span><span class="constant">GENRE_BUILDING_SOON_MTID</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">, &amp;</span><span class="identifier">V</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">NM</span><span class="plain"> = </span><span class="functiontext">Graphs::show_missing</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;vertex</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">NM</span><span class="plain"> &gt; 0) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"Because there are missing resources, -archive is cancelled\</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="reserved">if</span><span class="plain"> (</span><span class="identifier">N</span><span class="plain">) </span><span class="functiontext">Graphs::archive</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;vertex</span><span class="plain">, </span><span class="identifier">N</span><span class="plain">, </span><span class="identifier">BM</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Copies::new_error is used in 5/kts (<a href="5-kts.html#SP1">&#167;1</a>), 5/es (<a href="5-es.html#SP1">&#167;1</a>, <a href="5-es.html#SP1_1">&#167;1.1</a>, <a href="5-es.html#SP1_1_3">&#167;1.1.3</a>, <a href="5-es.html#SP1_1_3_2">&#167;1.1.3.2</a>), 5/ps (<a href="5-ps.html#SP6">&#167;6</a>), 6/st (<a href="6-st.html#SP2">&#167;2</a>, <a href="6-st.html#SP4">&#167;4</a>, <a href="6-st.html#SP12">&#167;12</a>), 6/hdn (<a href="6-hdn.html#SP13_1">&#167;13.1</a>, <a href="6-hdn.html#SP13_2">&#167;13.2</a>, <a href="6-hdn.html#SP23_1">&#167;23.1</a>, <a href="6-hdn.html#SP24_1">&#167;24.1</a>, <a href="6-hdn.html#SP23_2">&#167;23.2</a>, <a href="6-hdn.html#SP23_3">&#167;23.3</a>), 6/inc (<a href="6-inc.html#SP3_1">&#167;3.1</a>, <a href="6-inc.html#SP6_1_1">&#167;6.1.1</a>, <a href="6-inc.html#SP6_1_2">&#167;6.1.2</a>, <a href="6-inc.html#SP7_1">&#167;7.1</a>, <a href="6-inc.html#SP9_1">&#167;9.1</a>, <a href="6-inc.html#SP11">&#167;11</a>).</p>
<p class="endnote">The function Copies::archive appears nowhere else.</p>
<p class="endnote">The function Copies::new_error_N is used in 5/es (<a href="5-es.html#SP1">&#167;1</a>).</p>
<p class="inwebparagraph"><a id="SP13"></a><b>&#167;13. </b>And lastly <code class="display"><span class="extract">-copy-to N</span></code> and <code class="display"><span class="extract">-sync-to N</span></code>:
</p>
<p class="endnote">The function Copies::new_error_on_file is used in 5/es (<a href="5-es.html#SP1_1">&#167;1.1</a>), 6/st (<a href="6-st.html#SP1">&#167;1</a>).</p>
<p class="endnote">The function Copies::attach is used in 5/kts (<a href="5-kts.html#SP1">&#167;1</a>), 5/es (<a href="5-es.html#SP1">&#167;1</a>, <a href="5-es.html#SP1_1">&#167;1.1</a>, <a href="5-es.html#SP1_1_3">&#167;1.1.3</a>, <a href="5-es.html#SP1_1_3_2">&#167;1.1.3.2</a>), 5/ps (<a href="5-ps.html#SP6">&#167;6</a>), 6/st (<a href="6-st.html#SP1">&#167;1</a>, <a href="6-st.html#SP2">&#167;2</a>, <a href="6-st.html#SP4">&#167;4</a>, <a href="6-st.html#SP12">&#167;12</a>), 6/hdn (<a href="6-hdn.html#SP13_1">&#167;13.1</a>, <a href="6-hdn.html#SP13_2">&#167;13.2</a>, <a href="6-hdn.html#SP23_1">&#167;23.1</a>, <a href="6-hdn.html#SP24_1">&#167;24.1</a>, <a href="6-hdn.html#SP23_2">&#167;23.2</a>, <a href="6-hdn.html#SP23_3">&#167;23.3</a>), 6/inc (<a href="6-inc.html#SP3_1">&#167;3.1</a>, <a href="6-inc.html#SP6_1_1">&#167;6.1.1</a>, <a href="6-inc.html#SP6_1_2">&#167;6.1.2</a>, <a href="6-inc.html#SP7_1">&#167;7.1</a>, <a href="6-inc.html#SP9_1">&#167;9.1</a>, <a href="6-inc.html#SP11">&#167;11</a>).</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Copies::copy_to</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="reserved">inbuild_nest</span><span class="plain"> *</span><span class="identifier">destination_nest</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">syncing</span><span class="plain">,</span>
<span class="reserved">build_methodology</span><span class="plain"> *</span><span class="identifier">meth</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">destination_nest</span><span class="plain">)</span>
<span class="identifier">VMETHOD_CALL</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;edition</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">-</span><span class="element">&gt;genre</span><span class="plain">, </span><span class="constant">GENRE_COPY_TO_NEST_MTID</span><span class="plain">,</span>
<span class="identifier">C</span><span class="plain">, </span><span class="identifier">destination_nest</span><span class="plain">, </span><span class="identifier">syncing</span><span class="plain">, </span><span class="identifier">meth</span><span class="plain">);</span>
<span class="plain">}</span>
<p class="endnote">The function Copies::list_problems_arising is used in <a href="#SP1">&#167;1</a>, 5/ps (<a href="5-ps.html#SP4">&#167;4</a>), 6/inc (<a href="6-inc.html#SP6_1">&#167;6.1</a>).</p>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Copies::overwrite_error</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="reserved">inbuild_nest</span><span class="plain"> *</span><span class="identifier">N</span><span class="plain">) {</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">ext</span><span class="plain"> = </span><span class="identifier">Str::new</span><span class="plain">();</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">ext</span><span class="plain">, </span><span class="string">"%X"</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;edition</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">);</span>
<span class="identifier">Errors::with_text</span><span class="plain">(</span><span class="string">"already present (to overwrite, use -sync-to not -copy-to): '%S'"</span><span class="plain">, </span><span class="identifier">ext</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="endnote">The function Copies::write_problem is used in 5/ec (<a href="5-ec.html#SP5">&#167;5</a>).</p>
<p class="inwebparagraph"></p>
<p class="endnote">The structure copy_error is accessed in 2/nst, 3/is, 5/kts, 5/ed2, 5/ec, 5/ps, 5/ls, 6/st, 6/hdn, 6/inc and here.</p>
<p class="endnote">The function Copies::copy_to is used in 3/bg (<a href="3-bg.html#SP1">&#167;1</a>).</p>
<p class="endnote">The function Copies::overwrite_error is used in 4/km (<a href="4-km.html#SP6">&#167;6</a>), 4/em (<a href="4-em.html#SP8">&#167;8</a>), 4/lm (<a href="4-lm.html#SP7">&#167;7</a>), 4/tm (<a href="4-tm.html#SP6">&#167;6</a>), 4/pm (<a href="4-pm.html#SP7">&#167;7</a>).</p>
<hr class="tocbar">
<ul class="toc"><li><a href="2-edt.html">Back to 'Editions'</a></li><li><a href="2-rqr.html">Continue with 'Requirements'</a></li></ul><hr class="tocbar">
<ul class="toc"><li><a href="2-edt.html">Back to 'Editions'</a></li><li><a href="2-ce.html">Continue with 'Copy Errors'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</main>
</body>

View file

@ -57,12 +57,18 @@
<main role="main">
<!--Weave of '2/edt' 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#2">Chapter 2: Conceptual Framework</a></li><li><b>Editions</b></li></ul><p class="purpose">An edition is numbered version of a work.</p>
<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#2">Chapter 2: Conceptual Framework</a></li><li><b>Editions</b></li></ul><p class="purpose">An edition is a numbered version of a work.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Editions</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Editions. </b>An "edition" of a work is a particular version numbered form of it. For
example, release 7 of Bronze by Emily Short would be an edition of Bronze.
example, release 7 of Bronze by Emily Short would be an edition of the
work Bronze by Emily Short.
</p>
<p class="inwebparagraph">It is at this level that we record what works are compatible with which
target virtual machines, because we can imagine that, for example, version 7
might work with all VMs, while version 8 required a 32-bit architecture.
</p>
@ -89,7 +95,24 @@ example, release 7 of Bronze by Emily Short would be an edition of Bronze.
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" v%v"</span><span class="plain">, &amp;</span><span class="identifier">V</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Editions::new is used in 4/km (<a href="4-km.html#SP3">&#167;3</a>), 4/em (<a href="4-em.html#SP5">&#167;5</a>), 4/lm (<a href="4-lm.html#SP4">&#167;4</a>), 4/pbm (<a href="4-pbm.html#SP2">&#167;2</a>), 4/pfm (<a href="4-pfm.html#SP2">&#167;2</a>), 4/tm (<a href="4-tm.html#SP3">&#167;3</a>), 4/pm (<a href="4-pm.html#SP5">&#167;5</a>), 5/es (<a href="5-es.html#SP1">&#167;1</a>).</p>
<p class="endnote">The function Editions::write is used in <a href="#SP3">&#167;3</a>, 2/cps (<a href="2-cps.html#SP6">&#167;6</a>).</p>
<p class="endnote">The structure inbuild_edition is accessed in 2/wrk, 2/cps, 2/rqr, 2/nst, 3/bg, 3/is2, 4/km, 4/em, 4/lm, 4/pbm, 4/pfm, 4/tm, 4/pm, 5/kts, 5/es, 5/ed, 5/ed2, 5/ec, 5/ts, 5/ps, 5/ls, 5/ps2, 6/hdn, 6/inc, 6/vmg and here.</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>When a copy is to be duplicated into a nest <code class="display"><span class="extract">N</span></code>, we need to work out where
to put it. For example, version 2.1 of the extension Marbles by Steve Hogarth
would go into <code class="display"><span class="extract">N/Extensions/Steve Hogarth/Marbles-v2_1.i7x</span></code>. The following
contributes only the un-filename-extended leafname <code class="display"><span class="extract">Marbles-v2_1</span></code>.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Editions::write_canonical_leaf</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">inbuild_edition</span><span class="plain"> *</span><span class="identifier">E</span><span class="plain">) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%S"</span><span class="plain">, </span><span class="identifier">E</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">-</span><span class="element">&gt;title</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">E</span><span class="plain">-</span><span class="element">&gt;version</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
@ -103,7 +126,17 @@ example, release 7 of Bronze by Emily Short would be an edition of Bronze.
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">vn</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Editions::write_canonical_leaf is used in 4/km (<a href="4-km.html#SP6">&#167;6</a>), 4/em (<a href="4-em.html#SP8">&#167;8</a>), 4/lm (<a href="4-lm.html#SP7">&#167;7</a>), 4/tm (<a href="4-tm.html#SP6">&#167;6</a>), 4/pm (<a href="4-pm.html#SP7">&#167;7</a>).</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>The <code class="display"><span class="extract">-inspect</span></code> command of Inbuild uses the following.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Editions::inspect</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">inbuild_edition</span><span class="plain"> *</span><span class="identifier">E</span><span class="plain">) {</span>
<span class="functiontext">Editions::write</span><span class="plain">(</span><span class="identifier">OUT</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">Compatibility::universal</span><span class="plain">(</span><span class="identifier">E</span><span class="plain">-</span><span class="element">&gt;compatibility</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
@ -116,15 +149,7 @@ example, release 7 of Bronze by Emily Short would be an edition of Bronze.
<p class="inwebparagraph"></p>
<p class="endnote">The function Editions::new is used in 4/km (<a href="4-km.html#SP3">&#167;3</a>), 4/em (<a href="4-em.html#SP5">&#167;5</a>), 4/lm (<a href="4-lm.html#SP4">&#167;4</a>), 4/pbm (<a href="4-pbm.html#SP2">&#167;2</a>), 4/pfm (<a href="4-pfm.html#SP2">&#167;2</a>), 4/tm (<a href="4-tm.html#SP3">&#167;3</a>), 4/pm (<a href="4-pm.html#SP5">&#167;5</a>), 5/es (<a href="5-es.html#SP1">&#167;1</a>).</p>
<p class="endnote">The function Editions::write is used in 2/cps (<a href="2-cps.html#SP1">&#167;1</a>).</p>
<p class="endnote">The function Editions::write_canonical_leaf is used in 4/km (<a href="4-km.html#SP6">&#167;6</a>), 4/em (<a href="4-em.html#SP8">&#167;8</a>), 4/lm (<a href="4-lm.html#SP7">&#167;7</a>), 4/tm (<a href="4-tm.html#SP6">&#167;6</a>), 4/pm (<a href="4-pm.html#SP7">&#167;7</a>).</p>
<p class="endnote">The function Editions::inspect is used in 2/cps (<a href="2-cps.html#SP1">&#167;1</a>).</p>
<p class="endnote">The structure inbuild_edition is accessed in 2/wrk, 2/cps, 2/rqr, 2/nst, 3/bg, 3/is2, 4/km, 4/em, 4/lm, 4/pbm, 4/pfm, 4/tm, 4/pm, 5/kts, 5/es, 5/ed, 5/ed2, 5/ec, 5/ts, 5/ps, 5/ls, 5/ps2, 6/hdn, 6/inc, 6/vmg and here.</p>
<p class="endnote">The function Editions::inspect is used in 2/cps (<a href="2-cps.html#SP9">&#167;9</a>).</p>
<hr class="tocbar">
<ul class="toc"><li><a href="2-wrk.html">Back to 'Works'</a></li><li><a href="2-cps.html">Continue with 'Copies'</a></li></ul><hr class="tocbar">

View file

@ -59,7 +59,7 @@
<!--Weave of '2/gnr' 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#2">Chapter 2: Conceptual Framework</a></li><li><b>Genres</b></li></ul><p class="purpose">The different sorts of work managed by inbuild.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Genres</a></li><li><a href="#SP3">&#167;3. Method functions</a></li></ul><hr class="tocbar">
<ul class="toc"><li><a href="#SP1">&#167;1. Genres</a></li><li><a href="#SP4">&#167;4. Method functions</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Genres. </b>Each different genre of work managed by Inbuild is represented by an instance
of the following structure. (At present, then, there are exactly seven
@ -102,7 +102,7 @@ the instance <code class="display"><span class="extract">kit_genre</span></code>
<p class="endnote">The function Genres::new is used in 4/km (<a href="4-km.html#SP1">&#167;1</a>), 4/em (<a href="4-em.html#SP3">&#167;3</a>), 4/lm (<a href="4-lm.html#SP2">&#167;2</a>), 4/pbm (<a href="4-pbm.html#SP1">&#167;1</a>), 4/pfm (<a href="4-pfm.html#SP1">&#167;1</a>), 4/tm (<a href="4-tm.html#SP1">&#167;1</a>), 4/pm (<a href="4-pm.html#SP2">&#167;2</a>).</p>
<p class="endnote">The function Genres::name is used in 2/cps (<a href="2-cps.html#SP1">&#167;1</a>).</p>
<p class="endnote">The function Genres::name is used in 2/cps (<a href="2-cps.html#SP9">&#167;9</a>).</p>
<p class="endnote">The structure inbuild_genre is accessed in 2/rqr, 3/bg and here.</p>
@ -123,7 +123,25 @@ nest depends only on its genre.
<p class="endnote">The function Genres::stored_in_nests is used in 3/bg (<a href="3-bg.html#SP1">&#167;1</a>).</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. Method functions. </b>And here are the method functions which a genre can, optionally, provide.
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>The requirements parser needs to identify genres by name, so:
</p>
<pre class="display">
<span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="functiontext">Genres::by_name</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">name</span><span class="plain">) {</span>
<span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">G</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">G</span><span class="plain">, </span><span class="reserved">inbuild_genre</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::eq_insensitive</span><span class="plain">(</span><span class="identifier">G</span><span class="plain">-</span><span class="element">&gt;genre_name</span><span class="plain">, </span><span class="identifier">name</span><span class="plain">))</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">G</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="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Genres::by_name is used in 2/rqr (<a href="2-rqr.html#SP4_1">&#167;4.1</a>).</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. Method functions. </b>And here are the method functions which a genre can, optionally, provide.
All of these act on a given work, or a given copy of a work, having the
genre in question.
</p>
@ -144,7 +162,7 @@ by Emily Short".
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>This looks at a textual file locator, which might be a pathname or a
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b>This looks at a textual file locator, which might be a pathname or a
filename, to see if it might refer to a copy of a work of the given genre.
If it does, an <code class="display"><span class="extract">inbuild_copy</span></code> is created, and the pointer <code class="display"><span class="extract">*C</span></code> is set to
point to it. If not, no error is issued, and <code class="display"><span class="extract">*C</span></code> is left unchanged.
@ -169,7 +187,7 @@ attached to the copy for later issuing.
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b>This searches the nest <code class="display"><span class="extract">N</span></code> for anything which (a) looks like a copy of a
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. </b>This searches the nest <code class="display"><span class="extract">N</span></code> for anything which (a) looks like a copy of a
work of our genre, and (b) meets the given requirements. If a genre does
not provide this method, then nothing of that genre can ever appear in
<code class="display"><span class="extract">-matching</span></code> search results.
@ -188,7 +206,7 @@ not provide this method, then nothing of that genre can ever appear in
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. </b>Some genres of work involve Inform source text &mdash; Inform projects and
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. </b>Some genres of work involve Inform source text &mdash; Inform projects and
extensions, for example. Reading in source text is fairly fast, but it's not
an instant process, and we don't automatically perform it. (When an extension
is scanned for metadata during claiming, only the opening line is looked at.)
@ -210,7 +228,7 @@ text. It will never be called twice on the same copy.
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. </b>At the Going Operational phase of Inbuild, each copy is offered the chance
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. </b>At the Going Operational phase of Inbuild, each copy is offered the chance
to finalise its internal representation. For example, this may be when its
build graph is constructed, because we can now know for sure that there are
no further unsuspected dependencies.
@ -220,6 +238,10 @@ no further unsuspected dependencies.
provides it) which has been claimed by Inbuild.
</p>
<p class="inwebparagraph">Text should actually be read by feeding it into the lexer. Inbuild will take
of it from there.
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">GENRE_GO_OPERATIONAL_MTID</span>
@ -232,7 +254,7 @@ provides it) which has been claimed by Inbuild.
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. </b>This method is called when a copy is about to be built or have its graph
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. </b>This method is called when a copy is about to be built or have its graph
described, for example by <code class="display"><span class="extract">-graph</span></code>, <code class="display"><span class="extract">-build</span></code> and <code class="display"><span class="extract">-rebuild</span></code>. Nothing actually
needs to be done, but if any work is needed before building can take place,
now's the time; and the vertex to build from can be altered by setting <code class="display"><span class="extract">*V</span></code>.
@ -253,7 +275,7 @@ is ignored for other inspection options such as <code class="display"><span clas
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. </b>This duplicates, or syncs, a copy <code class="display"><span class="extract">C</span></code> of a work in our genre, placing it
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. </b>This duplicates, or syncs, a copy <code class="display"><span class="extract">C</span></code> of a work in our genre, placing it
at a canonical location inside the given nest <code class="display"><span class="extract">N</span></code>. In effect, it implements
the Inbuild command-line options <code class="display"><span class="extract">-copy-to N</span></code> and <code class="display"><span class="extract">-sync-to N</span></code>.
</p>

View file

@ -59,22 +59,21 @@
<!--Weave of '2/nst' 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#2">Chapter 2: Conceptual Framework</a></li><li><b>Nests</b></li></ul><p class="purpose">Nests are repositories of Inform-related resources.</p>
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. </b></p>
<ul class="toc"><li><a href="#SP1">&#167;1. Creation</a></li><li><a href="#SP4">&#167;4. Search list</a></li><li><a href="#SP5">&#167;5. Search results</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Creation. </b>To "create" a nest here does not mean actually altering the file system, for
example by making a directory: nests here are merely notes in memory of
positions in the file system hierarchy which may or may not exist.
</p>
<pre class="display">
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">inbuild_nest</span><span class="plain"> {</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">location</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">read_only</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">tag_value</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">read_only</span><span class="plain">; </span> <span class="comment">files cannot be written into this nest</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">tag_value</span><span class="plain">; </span> <span class="comment">used to indicate whether internal, external, and such</span>
<span class="identifier">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">inbuild_nest</span><span class="plain">;</span>
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">inbuild_search_result</span><span class="plain"> {</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">inbuild_nest</span><span class="plain"> *</span><span class="identifier">nest</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">copy</span><span class="plain">;</span>
<span class="identifier">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">inbuild_search_result</span><span class="plain">;</span>
<span class="reserved">inbuild_nest</span><span class="plain"> *</span><span class="functiontext">Nests::new</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="reserved">inbuild_nest</span><span class="plain"> *</span><span class="identifier">N</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">inbuild_nest</span><span class="plain">);</span>
<span class="identifier">N</span><span class="plain">-</span><span class="element">&gt;location</span><span class="plain"> = </span><span class="identifier">P</span><span class="plain">;</span>
@ -82,7 +81,32 @@
<span class="identifier">N</span><span class="plain">-</span><span class="element">&gt;tag_value</span><span class="plain"> = -1;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">N</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Nests::new is used in 1/ic (<a href="1-ic.html#SP13">&#167;13</a>).</p>
<p class="endnote">The structure inbuild_nest is accessed in 1/ic, 3/bg, 3/is2, 4/km, 4/em, 4/lm, 4/tm, 4/pm, 5/ps and here.</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>Nests used by the Inform and Inbuild tools are tagged with the following
comstamts. (There used to be quite a good joke here, but refactoring of the
code removed its premiss. Literate programming is like that sometimes.)
</p>
<p class="inwebparagraph">The sequence of the following enumerated values is very significant &mdash;
see below for why. Lower-tag-numbered origins are better than later ones.
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">MATERIALS_NEST_TAG</span><span class="definitionkeyword"> from </span><span class="constant">1</span>
<span class="definitionkeyword">enum</span> <span class="constant">EXTERNAL_NEST_TAG</span>
<span class="definitionkeyword">enum</span> <span class="constant">GENERIC_NEST_TAG</span>
<span class="definitionkeyword">enum</span> <span class="constant">INTERNAL_NEST_TAG</span>
</pre>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Nests::get_tag</span><span class="plain">(</span><span class="reserved">inbuild_nest</span><span class="plain"> *</span><span class="identifier">N</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">N</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="reserved">return</span><span class="plain"> </span><span class="identifier">N</span><span class="plain">-</span><span class="element">&gt;tag_value</span><span class="plain">;</span>
@ -92,21 +116,38 @@
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">N</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 nest"</span><span class="plain">);</span>
<span class="identifier">N</span><span class="plain">-</span><span class="element">&gt;tag_value</span><span class="plain"> = </span><span class="identifier">t</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Nests::get_tag is used in <a href="#SP9">&#167;9</a>, 1/ic (<a href="1-ic.html#SP14">&#167;14</a>), 3/is2 (<a href="3-is2.html#SP1">&#167;1</a>), 5/ed2 (<a href="5-ed2.html#SP4">&#167;4</a>), 5/ec (<a href="5-ec.html#SP1">&#167;1</a>, <a href="5-ec.html#SP3_1">&#167;3.1</a>, <a href="5-ec.html#SP3_2">&#167;3.2</a>), 6/inc (<a href="6-inc.html#SP6_1">&#167;6.1</a>).</p>
<p class="endnote">The function Nests::set_tag is used in 1/ic (<a href="1-ic.html#SP13">&#167;13</a>).</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Nests::protect</span><span class="plain">(</span><span class="reserved">inbuild_nest</span><span class="plain"> *</span><span class="identifier">N</span><span class="plain">) {</span>
<span class="identifier">N</span><span class="plain">-</span><span class="element">&gt;read_only</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Nests::add_search_result</span><span class="plain">(</span><span class="identifier">linked_list</span><span class="plain"> *</span><span class="identifier">results</span><span class="plain">, </span><span class="reserved">inbuild_nest</span><span class="plain"> *</span><span class="identifier">N</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="reserved">inbuild_requirement</span><span class="plain"> *</span><span class="identifier">req</span><span class="plain">) {</span>
<span class="reserved">inbuild_search_result</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">inbuild_search_result</span><span class="plain">);</span>
<span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;nest</span><span class="plain"> = </span><span class="identifier">N</span><span class="plain">;</span>
<span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;copy</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">&gt;found_by</span><span class="plain"> = </span><span class="identifier">req</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">req</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">"bad search result"</span><span class="plain">);</span>
<span class="identifier">ADD_TO_LINKED_LIST</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">, </span><span class="reserved">inbuild_search_result</span><span class="plain">, </span><span class="identifier">results</span><span class="plain">);</span>
<span class="plain">}</span>
<p class="inwebparagraph"></p>
<p class="endnote">The function Nests::protect is used in 1/ic (<a href="1-ic.html#SP13">&#167;13</a>).</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. Search list. </b>When we search for copies, we do so by looking through nests in a list. The
following builds such lists, removing duplicates &mdash; where duplicates are
shown up by having the same textual form of pathname. (This is not foolproof
by any means: Unix is replete with ways to describe the same directory, thanks
to simlinks, <code class="display"><span class="extract">~</span></code> and so on. But in the circumstances arising inside Inbuild,
it will do. In any case, having duplicates would not actually matter: it
would just produce search results which were more copious than needed.)
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Nests::add_to_search_sequence</span><span class="plain">(</span><span class="identifier">linked_list</span><span class="plain"> *</span><span class="identifier">search_list</span><span class="plain">, </span><span class="reserved">inbuild_nest</span><span class="plain"> *</span><span class="identifier">N</span><span class="plain">) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">NS</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">NS</span><span class="plain">, </span><span class="string">"%p"</span><span class="plain">, </span><span class="identifier">N</span><span class="plain">-</span><span class="element">&gt;location</span><span class="plain">);</span>
@ -122,8 +163,57 @@
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">already_here</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="identifier">ADD_TO_LINKED_LIST</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">, </span><span class="reserved">inbuild_nest</span><span class="plain">, </span><span class="identifier">search_list</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Nests::search_for</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="identifier">linked_list</span><span class="plain"> *</span><span class="identifier">search_list</span><span class="plain">, </span><span class="identifier">linked_list</span><span class="plain"> *</span><span class="identifier">results</span><span class="plain">) {</span>
<p class="inwebparagraph"></p>
<p class="endnote">The function Nests::add_to_search_sequence appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. Search results. </b>When we search a list of nests for copies satisfying certain requirements,
we create one of these for each hit:
</p>
<pre class="display">
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">inbuild_search_result</span><span class="plain"> {</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">copy</span><span class="plain">; </span> <span class="comment">what was found</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">inbuild_nest</span><span class="plain"> *</span><span class="identifier">nest</span><span class="plain">; </span> <span class="comment">from whence it came</span>
<span class="identifier">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">inbuild_search_result</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The structure inbuild_search_result is accessed in 2/ce, 3/is, 5/kts, 5/ed2, 5/ec, 5/ls, 6/inc and here.</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. </b>These can be created only as entries in a list:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Nests::add_search_result</span><span class="plain">(</span><span class="identifier">linked_list</span><span class="plain"> *</span><span class="identifier">results</span><span class="plain">, </span><span class="reserved">inbuild_nest</span><span class="plain"> *</span><span class="identifier">N</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="reserved">inbuild_requirement</span><span class="plain"> *</span><span class="identifier">req</span><span class="plain">) {</span>
<span class="reserved">inbuild_search_result</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">inbuild_search_result</span><span class="plain">);</span>
<span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;nest</span><span class="plain"> = </span><span class="identifier">N</span><span class="plain">;</span>
<span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;copy</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">&gt;found_by</span><span class="plain"> = </span><span class="identifier">req</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">req</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">"bad search result"</span><span class="plain">);</span>
<span class="identifier">ADD_TO_LINKED_LIST</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">, </span><span class="reserved">inbuild_search_result</span><span class="plain">, </span><span class="identifier">results</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Nests::add_search_result is used in 4/km (<a href="4-km.html#SP5">&#167;5</a>), 4/em (<a href="4-em.html#SP7">&#167;7</a>), 4/lm (<a href="4-lm.html#SP6">&#167;6</a>), 4/tm (<a href="4-tm.html#SP5">&#167;5</a>), 4/pm (<a href="4-pm.html#SP6">&#167;6</a>).</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. </b>And here is our search engine, such as it is. For each nest, we ask each
genre's manager to look for copies of that genre:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Nests::search_for</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="identifier">linked_list</span><span class="plain"> *</span><span class="identifier">search_list</span><span class="plain">, </span><span class="identifier">linked_list</span><span class="plain"> *</span><span class="identifier">results</span><span class="plain">) {</span>
<span class="reserved">inbuild_nest</span><span class="plain"> *</span><span class="identifier">N</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">, </span><span class="reserved">inbuild_nest</span><span class="plain">, </span><span class="identifier">search_list</span><span class="plain">) {</span>
<span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">G</span><span class="plain">;</span>
@ -131,8 +221,20 @@
<span class="identifier">VMETHOD_CALL</span><span class="plain">(</span><span class="identifier">G</span><span class="plain">, </span><span class="constant">GENRE_SEARCH_NEST_FOR_MTID</span><span class="plain">, </span><span class="identifier">N</span><span class="plain">, </span><span class="identifier">req</span><span class="plain">, </span><span class="identifier">results</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<span class="reserved">inbuild_search_result</span><span class="plain"> *</span><span class="functiontext">Nests::first_found</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="identifier">linked_list</span><span class="plain"> *</span><span class="identifier">search_list</span><span class="plain">) {</span>
<p class="inwebparagraph"></p>
<p class="endnote">The function Nests::search_for is used in <a href="#SP8">&#167;8</a>, 1/ic (<a href="1-ic.html#SP9_2">&#167;9.2</a>), 5/ed2 (<a href="5-ed2.html#SP4">&#167;4</a>), 5/ec (<a href="5-ec.html#SP3">&#167;3</a>), 6/inc (<a href="6-inc.html#SP6_1_2">&#167;6.1.2</a>).</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. </b>Oftentimes, we want only the single best result, and won't even look at the
others:
</p>
<pre class="display">
<span class="reserved">inbuild_search_result</span><span class="plain"> *</span><span class="functiontext">Nests::search_for_best</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="identifier">linked_list</span><span class="plain"> *</span><span class="identifier">search_list</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">req</span><span class="plain">, </span><span class="identifier">search_list</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">);</span>
<span class="reserved">inbuild_search_result</span><span class="plain"> *</span><span class="identifier">best</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">search_result</span><span class="plain">;</span>
@ -141,59 +243,45 @@
<span class="identifier">best</span><span class="plain"> = </span><span class="identifier">search_result</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">best</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Nests::search_for_best is used in 3/is (<a href="3-is.html#SP1">&#167;1</a>), 5/kts (<a href="5-kts.html#SP1">&#167;1</a>), 5/ls (<a href="5-ls.html#SP7">&#167;7</a>), 6/inc (<a href="6-inc.html#SP6_1">&#167;6.1</a>).</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. </b>Where "better" is defined as follows. This innocent-looking function is
in fact critical to what Inbuild does. It uses tags on nests to prefer copies
in the Materials folder to those in the external nest, and to prefer those in
turn to copies in the internal nest; and within nests of equal importance,
it chooses the earliest hit among those which have the highest-precedence
semantic version numbers.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Nests::better_result</span><span class="plain">(</span><span class="reserved">inbuild_search_result</span><span class="plain"> *</span><span class="identifier">R1</span><span class="plain">, </span><span class="reserved">inbuild_search_result</span><span class="plain"> *</span><span class="identifier">R2</span><span class="plain">) {</span>
<span class="comment">Something is better than nothing</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">R1</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">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">R2</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">TRUE</span><span class="plain">;</span>
<span class="comment">Otherwise, a more important nest beats a less important nest</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">o1</span><span class="plain"> = </span><span class="functiontext">Nests::get_tag</span><span class="plain">(</span><span class="identifier">R1</span><span class="plain">-</span><span class="element">&gt;nest</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">o2</span><span class="plain"> = </span><span class="functiontext">Nests::get_tag</span><span class="plain">(</span><span class="identifier">R2</span><span class="plain">-</span><span class="element">&gt;nest</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">o1</span><span class="plain"> &lt; </span><span class="identifier">o2</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">if</span><span class="plain"> (</span><span class="identifier">o1</span><span class="plain"> &gt; </span><span class="identifier">o2</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="reserved">if</span><span class="plain"> (</span><span class="identifier">VersionNumbers::gt</span><span class="plain">(</span><span class="identifier">R1</span><span class="plain">-</span><span class="element">&gt;copy</span><span class="plain">-</span><span class="element">&gt;edition</span><span class="plain">-</span><span class="element">&gt;version</span><span class="plain">, </span><span class="identifier">R2</span><span class="plain">-</span><span class="element">&gt;copy</span><span class="plain">-</span><span class="element">&gt;edition</span><span class="plain">-</span><span class="element">&gt;version</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="comment">Otherwise, a higher semantic version number beats a lower</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">VersionNumbers::gt</span><span class="plain">(</span><span class="identifier">R1</span><span class="plain">-</span><span class="element">&gt;copy</span><span class="plain">-</span><span class="element">&gt;edition</span><span class="plain">-</span><span class="element">&gt;version</span><span class="plain">, </span><span class="identifier">R2</span><span class="plain">-</span><span class="element">&gt;copy</span><span class="plain">-</span><span class="element">&gt;edition</span><span class="plain">-</span><span class="element">&gt;version</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="comment">Otherwise, better the devil we know</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Nests::copy_to</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="reserved">inbuild_nest</span><span class="plain"> *</span><span class="identifier">destination_nest</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">syncing</span><span class="plain">,</span>
<span class="reserved">build_methodology</span><span class="plain"> *</span><span class="identifier">meth</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">destination_nest</span><span class="plain">)</span>
<span class="identifier">VMETHOD_CALL</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;edition</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">-</span><span class="element">&gt;genre</span><span class="plain">, </span><span class="constant">GENRE_COPY_TO_NEST_MTID</span><span class="plain">,</span>
<span class="identifier">C</span><span class="plain">, </span><span class="identifier">destination_nest</span><span class="plain">, </span><span class="identifier">syncing</span><span class="plain">, </span><span class="identifier">meth</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Nests::overwrite_error</span><span class="plain">(</span><span class="reserved">inbuild_nest</span><span class="plain"> *</span><span class="identifier">N</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">text_stream</span><span class="plain"> *</span><span class="identifier">ext</span><span class="plain"> = </span><span class="identifier">Str::new</span><span class="plain">();</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">ext</span><span class="plain">, </span><span class="string">"%X"</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;edition</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">);</span>
<span class="identifier">Errors::with_text</span><span class="plain">(</span><span class="string">"already present (to overwrite, use -sync-to not -copy-to): '%S'"</span><span class="plain">, </span><span class="identifier">ext</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Nests::new is used in 1/ic (<a href="1-ic.html#SP13">&#167;13</a>).</p>
<p class="endnote">The function Nests::get_tag is used in 1/ic (<a href="1-ic.html#SP14">&#167;14</a>), 3/is2 (<a href="3-is2.html#SP1">&#167;1</a>), 5/ed2 (<a href="5-ed2.html#SP4">&#167;4</a>), 5/ec (<a href="5-ec.html#SP1">&#167;1</a>, <a href="5-ec.html#SP3_1">&#167;3.1</a>, <a href="5-ec.html#SP3_2">&#167;3.2</a>), 6/inc (<a href="6-inc.html#SP6_1">&#167;6.1</a>).</p>
<p class="endnote">The function Nests::set_tag is used in 1/ic (<a href="1-ic.html#SP13">&#167;13</a>).</p>
<p class="endnote">The function Nests::protect is used in 1/ic (<a href="1-ic.html#SP13">&#167;13</a>).</p>
<p class="endnote">The function Nests::add_search_result is used in 4/km (<a href="4-km.html#SP5">&#167;5</a>), 4/em (<a href="4-em.html#SP7">&#167;7</a>), 4/lm (<a href="4-lm.html#SP6">&#167;6</a>), 4/tm (<a href="4-tm.html#SP5">&#167;5</a>), 4/pm (<a href="4-pm.html#SP6">&#167;6</a>).</p>
<p class="endnote">The function Nests::add_to_search_sequence appears nowhere else.</p>
<p class="endnote">The function Nests::search_for is used in 1/ic (<a href="1-ic.html#SP9_2">&#167;9.2</a>), 5/ed2 (<a href="5-ed2.html#SP4">&#167;4</a>), 5/ec (<a href="5-ec.html#SP3">&#167;3</a>), 6/inc (<a href="6-inc.html#SP6_1_2">&#167;6.1.2</a>).</p>
<p class="endnote">The function Nests::first_found is used in 3/is (<a href="3-is.html#SP1">&#167;1</a>), 5/kts (<a href="5-kts.html#SP1">&#167;1</a>), 5/ls (<a href="5-ls.html#SP7">&#167;7</a>), 6/inc (<a href="6-inc.html#SP6_1">&#167;6.1</a>).</p>
<p class="endnote">The function Nests::better_result appears nowhere else.</p>
<p class="endnote">The function Nests::copy_to is used in 3/bg (<a href="3-bg.html#SP1">&#167;1</a>).</p>
<p class="endnote">The function Nests::overwrite_error is used in 4/km (<a href="4-km.html#SP6">&#167;6</a>), 4/em (<a href="4-em.html#SP8">&#167;8</a>), 4/lm (<a href="4-lm.html#SP7">&#167;7</a>), 4/tm (<a href="4-tm.html#SP6">&#167;6</a>), 4/pm (<a href="4-pm.html#SP7">&#167;7</a>).</p>
<p class="endnote">The structure inbuild_nest is accessed in 1/ic, 3/bg, 3/is2, 4/km, 4/em, 4/lm, 4/tm, 4/pm, 5/ps and here.</p>
<p class="endnote">The structure inbuild_search_result is accessed in 2/cps, 3/is, 5/kts, 5/ed2, 5/ec, 5/ls, 6/inc and here.</p>
<p class="endnote">The function Nests::better_result is used in <a href="#SP8">&#167;8</a>.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="2-rqr.html">Back to 'Requirements'</a></li><li><i>(This section ends Chapter 2: Conceptual Framework.)</i></li></ul><hr class="tocbar">

View file

@ -1,7 +1,7 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>2/cps</title>
<title>2/ce</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">
@ -59,7 +59,12 @@
<!--Weave of '2/rqr' 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#2">Chapter 2: Conceptual Framework</a></li><li><b>Requirements</b></li></ul><p class="purpose">A requirement is a way to specify some subset of works: for example, those with a given title, and/or version number.</p>
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. </b>A null minimum version means "no minimum", a null maximum means "no maximum".
<ul class="toc"><li><a href="#SP1">&#167;1. Creation</a></li><li><a href="#SP6">&#167;6. Writing</a></li><li><a href="#SP7">&#167;7. Meeting requirements</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Creation. </b>A requirement is, in effect, the criteria for performing a search. We can
specify the title, and/or the author name, and/or the genre &mdash; all given
in the <code class="display"><span class="extract">work</span></code> field below, with those unspecified left blank &mdash; and/or
we can give a semantic version number range:
</p>
@ -69,7 +74,17 @@
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">semver_range</span><span class="plain"> *</span><span class="identifier">version_range</span><span class="plain">;</span>
<span class="identifier">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">inbuild_requirement</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The structure inbuild_requirement is accessed in 2/wrk, 2/edt, 2/cps, 3/bg, 3/is2, 4/km, 4/em, 4/lm, 4/pbm, 4/pfm, 4/tm, 4/pm, 5/kts, 5/es, 5/ed, 5/ed2, 5/ec, 5/ps, 5/ls, 6/hdn, 6/inc and here.</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>Here are some creators:
</p>
<pre class="display">
<span class="reserved">inbuild_requirement</span><span class="plain"> *</span><span class="functiontext">Requirements::new</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="identifier">semver_range</span><span class="plain"> *</span><span class="identifier">R</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="identifier">CREATE</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="element">&gt;work</span><span class="plain"> = </span><span class="identifier">work</span><span class="plain">;</span>
@ -88,8 +103,41 @@
<span class="reserved">inbuild_requirement</span><span class="plain"> *</span><span class="functiontext">Requirements::anything</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Requirements::anything_of_genre</span><span class="plain">(</span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<span class="reserved">inbuild_requirement</span><span class="plain"> *</span><span class="functiontext">Requirements::from_text</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">errors</span><span class="plain">) {</span>
<p class="inwebparagraph"></p>
<p class="endnote">The function Requirements::new is used in 6/inc (<a href="6-inc.html#SP5_1">&#167;5.1</a>).</p>
<p class="endnote">The function Requirements::any_version_of is used in 3/is (<a href="3-is.html#SP1">&#167;1</a>), 5/kts (<a href="5-kts.html#SP1">&#167;1</a>), 5/ed2 (<a href="5-ed2.html#SP4">&#167;4</a>), 5/ls (<a href="5-ls.html#SP7">&#167;7</a>), 6/inc (<a href="6-inc.html#SP6_1_2">&#167;6.1.2</a>).</p>
<p class="endnote">The function Requirements::anything_of_genre is used in 1/ic (<a href="1-ic.html#SP9_2">&#167;9.2</a>), 5/ec (<a href="5-ec.html#SP3">&#167;3</a>).</p>
<p class="endnote">The function Requirements::anything is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>The most involved of the creators parses text. An involved example might be:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">genre=extension,author=Emily Short,title=Locksmith,min=6.1-alpha.2,max=17.2</span>
</pre>
<p class="inwebparagraph">We should return a requirement if this is valid, and write an error message if
it is not. (If the text has multiple things wrong with it, we write only the
first error message arising.)
</p>
<p class="inwebparagraph">At the top level, we have a comma-separated list of clauses. Note that the
empty text is legal here, and produces an unlimited requirement.
</p>
<pre class="display">
<span class="reserved">inbuild_requirement</span><span class="plain"> *</span><span class="functiontext">Requirements::from_text</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">T</span><span class="plain">,</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">errors</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::anything</span><span class="plain">();</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">from</span><span class="plain"> = 0;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">at</span><span class="plain"> = 0; </span><span class="identifier">at</span><span class="plain"> &lt; </span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">); </span><span class="identifier">at</span><span class="plain">++) {</span>
@ -110,72 +158,105 @@
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">req</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Requirements::impose_clause</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="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">errors</span><span class="plain">) {</span>
<p class="inwebparagraph"></p>
<p class="endnote">The function Requirements::from_text appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>Each clause must either be <code class="display"><span class="extract">all</span></code> or take the form <code class="display"><span class="extract">term=value</span></code>:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Requirements::impose_clause</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="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">T</span><span class="plain">,</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">errors</span><span class="plain">) {</span>
<span class="identifier">Str::trim_white_space</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::eq</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"all"</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">clause</span><span class="plain">);</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">term</span><span class="plain">);</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">value</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">at</span><span class="plain"> = 0; </span><span class="identifier">at</span><span class="plain"> &lt; </span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">); </span><span class="identifier">at</span><span class="plain">++) {</span>
<span class="identifier">wchar_t</span><span class="plain"> </span><span class="identifier">c</span><span class="plain"> = </span><span class="identifier">Str::get_at</span><span class="plain">(</span><span class="identifier">T</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="identifier">c</span><span class="plain"> == </span><span class="character">'='</span><span class="plain">) {</span>
<span class="identifier">Str::substr</span><span class="plain">(</span><span class="identifier">clause</span><span class="plain">, </span><span class="identifier">Str::start</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">), </span><span class="identifier">Str::at</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">at</span><span class="plain">));</span>
<span class="identifier">Str::substr</span><span class="plain">(</span><span class="identifier">term</span><span class="plain">, </span><span class="identifier">Str::start</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">), </span><span class="identifier">Str::at</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">at</span><span class="plain">));</span>
<span class="identifier">Str::substr</span><span class="plain">(</span><span class="identifier">value</span><span class="plain">, </span><span class="identifier">Str::at</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">at</span><span class="plain">+1), </span><span class="identifier">Str::end</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">));</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="identifier">Str::trim_white_space</span><span class="plain">(</span><span class="identifier">clause</span><span class="plain">);</span>
<span class="identifier">Str::trim_white_space</span><span class="plain">(</span><span class="identifier">term</span><span class="plain">);</span>
<span class="identifier">Str::trim_white_space</span><span class="plain">(</span><span class="identifier">value</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">clause</span><span class="plain">) &gt; 0) &amp;&amp; (</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">value</span><span class="plain">) &gt; 0)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::eq</span><span class="plain">(</span><span class="identifier">clause</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"genre"</span><span class="plain">)) {</span>
<span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">G</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">G</span><span class="plain">, </span><span class="reserved">inbuild_genre</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::eq_insensitive</span><span class="plain">(</span><span class="identifier">G</span><span class="plain">-</span><span class="element">&gt;genre_name</span><span class="plain">, </span><span class="identifier">value</span><span class="plain">)) {</span>
<span class="identifier">req</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">-</span><span class="element">&gt;genre</span><span class="plain"> = </span><span class="identifier">G</span><span class="plain">;</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">req</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">-</span><span class="element">&gt;genre</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">Str::len</span><span class="plain">(</span><span class="identifier">errors</span><span class="plain">) == 0)</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">errors</span><span class="plain">, </span><span class="string">"not a valid genre: '%S'"</span><span class="plain">, </span><span class="identifier">value</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">Str::eq</span><span class="plain">(</span><span class="identifier">clause</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"title"</span><span class="plain">)) </span><span class="identifier">Str::copy</span><span class="plain">(</span><span class="identifier">req</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">-</span><span class="element">&gt;title</span><span class="plain">, </span><span class="identifier">value</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">Str::eq</span><span class="plain">(</span><span class="identifier">clause</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"author"</span><span class="plain">)) </span><span class="identifier">Str::copy</span><span class="plain">(</span><span class="identifier">req</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">-</span><span class="element">&gt;author_name</span><span class="plain">, </span><span class="identifier">value</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">Str::eq</span><span class="plain">(</span><span class="identifier">clause</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"version"</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::from_text</span><span class="plain">(</span><span class="identifier">value</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="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">errors</span><span class="plain">) == 0)</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">errors</span><span class="plain">, </span><span class="string">"not a valid version number: '%S'"</span><span class="plain">, </span><span class="identifier">value</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">req</span><span class="plain">-</span><span class="element">&gt;version_range</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="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::eq</span><span class="plain">(</span><span class="identifier">clause</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"min"</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::from_text</span><span class="plain">(</span><span class="identifier">value</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="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">errors</span><span class="plain">) == 0)</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">errors</span><span class="plain">, </span><span class="string">"not a valid version number: '%S'"</span><span class="plain">, </span><span class="identifier">value</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">req</span><span class="plain">-</span><span class="element">&gt;version_range</span><span class="plain"> = </span><span class="identifier">VersionNumberRanges::at_least_range</span><span class="plain">(</span><span class="identifier">V</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">Str::eq</span><span class="plain">(</span><span class="identifier">clause</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"max"</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::from_text</span><span class="plain">(</span><span class="identifier">value</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="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">errors</span><span class="plain">) == 0)</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">errors</span><span class="plain">, </span><span class="string">"not a valid version number: '%S'"</span><span class="plain">, </span><span class="identifier">value</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">req</span><span class="plain">-</span><span class="element">&gt;version_range</span><span class="plain"> = </span><span class="identifier">VersionNumberRanges::at_most_range</span><span class="plain">(</span><span class="identifier">V</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">Str::len</span><span class="plain">(</span><span class="identifier">errors</span><span class="plain">) == 0)</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">errors</span><span class="plain">, </span><span class="string">"no such term as '%S'"</span><span class="plain">, </span><span class="identifier">clause</span><span class="plain">);</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">term</span><span class="plain">) &gt; 0) &amp;&amp; (</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">value</span><span class="plain">) &gt; 0)) {</span>
&lt;<span class="cwebmacro">Deal with a term-value pair</span> <span class="cwebmacronumber">4.1</span>&gt;<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">Str::len</span><span class="plain">(</span><span class="identifier">errors</span><span class="plain">) == 0)</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">errors</span><span class="plain">, </span><span class="string">"clause not in the form 'term=value': '%S'"</span><span class="plain">, </span><span class="identifier">T</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">clause</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">term</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">value</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Requirements::impose_clause is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP4_1"></a><b>&#167;4.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Deal with a term-value pair</span> <span class="cwebmacronumber">4.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::eq</span><span class="plain">(</span><span class="identifier">term</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"genre"</span><span class="plain">)) {</span>
<span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">G</span><span class="plain"> = </span><span class="functiontext">Genres::by_name</span><span class="plain">(</span><span class="identifier">value</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">G</span><span class="plain">) </span><span class="identifier">req</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">-</span><span class="element">&gt;genre</span><span class="plain"> = </span><span class="identifier">G</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">Str::len</span><span class="plain">(</span><span class="identifier">errors</span><span class="plain">) == 0)</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">errors</span><span class="plain">, </span><span class="string">"not a valid genre: '%S'"</span><span class="plain">, </span><span class="identifier">value</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">Str::eq</span><span class="plain">(</span><span class="identifier">term</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"title"</span><span class="plain">)) {</span>
<span class="identifier">Str::copy</span><span class="plain">(</span><span class="identifier">req</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">-</span><span class="element">&gt;title</span><span class="plain">, </span><span class="identifier">value</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">Str::eq</span><span class="plain">(</span><span class="identifier">term</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"author"</span><span class="plain">)) {</span>
<span class="identifier">Str::copy</span><span class="plain">(</span><span class="identifier">req</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">-</span><span class="element">&gt;author_name</span><span class="plain">, </span><span class="identifier">value</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">Str::eq</span><span class="plain">(</span><span class="identifier">term</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"version"</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="functiontext">Requirements::semver</span><span class="plain">(</span><span class="identifier">value</span><span class="plain">, </span><span class="identifier">errors</span><span class="plain">);</span>
<span class="identifier">req</span><span class="plain">-</span><span class="element">&gt;version_range</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="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::eq</span><span class="plain">(</span><span class="identifier">term</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"min"</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="functiontext">Requirements::semver</span><span class="plain">(</span><span class="identifier">value</span><span class="plain">, </span><span class="identifier">errors</span><span class="plain">);</span>
<span class="identifier">req</span><span class="plain">-</span><span class="element">&gt;version_range</span><span class="plain"> = </span><span class="identifier">VersionNumberRanges::at_least_range</span><span class="plain">(</span><span class="identifier">V</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">Str::eq</span><span class="plain">(</span><span class="identifier">term</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"max"</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="functiontext">Requirements::semver</span><span class="plain">(</span><span class="identifier">value</span><span class="plain">, </span><span class="identifier">errors</span><span class="plain">);</span>
<span class="identifier">req</span><span class="plain">-</span><span class="element">&gt;version_range</span><span class="plain"> = </span><span class="identifier">VersionNumberRanges::at_most_range</span><span class="plain">(</span><span class="identifier">V</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">Str::len</span><span class="plain">(</span><span class="identifier">errors</span><span class="plain">) == 0)</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">errors</span><span class="plain">, </span><span class="string">"no such term as '%S'"</span><span class="plain">, </span><span class="identifier">term</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP4">&#167;4</a>.</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b></p>
<pre class="display">
<span class="identifier">semantic_version_number</span><span class="plain"> </span><span class="functiontext">Requirements::semver</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">value</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">errors</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::from_text</span><span class="plain">(</span><span class="identifier">value</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="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">errors</span><span class="plain">) == 0)</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">errors</span><span class="plain">, </span><span class="string">"not a valid version number: '%S'"</span><span class="plain">, </span><span class="identifier">value</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 Requirements::semver is used in <a href="#SP4_1">&#167;4.1</a>.</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. Writing. </b>This is the inverse of the above function, and uses the same notation.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Requirements::write</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</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">if</span><span class="plain"> (</span><span class="identifier">req</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) { </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&lt;none&gt;"</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">; }</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">claused</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
@ -197,22 +278,35 @@
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">claused</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"all"</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Requirements::write is used in 3/bg (<a href="3-bg.html#SP1">&#167;1</a>).</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. Meeting requirements. </b>Finally, we actually use these intricacies for something. Given an edition,
we return <code class="display"><span class="extract">TRUE</span></code> if it meets the requirements and <code class="display"><span class="extract">FALSE</span></code> if it does not.
</p>
<p class="inwebparagraph">Note that requirements are based on the edition, not on the copy. If one
copy on file of Version 3.2 of Monkey Puzzle Trees by Capability Brown meets
a requirement, then so will all other copies of it.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Requirements::meets</span><span class="plain">(</span><span class="reserved">inbuild_edition</span><span class="plain"> *</span><span class="identifier">edition</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">if</span><span class="plain"> (</span><span class="identifier">req</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">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">req</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">req</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">-</span><span class="element">&gt;genre</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">req</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">-</span><span class="element">&gt;genre</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">req</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">-</span><span class="element">&gt;genre</span><span class="plain"> != </span><span class="identifier">edition</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">-</span><span class="element">&gt;genre</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>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">req</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">-</span><span class="element">&gt;title</span><span class="plain">) &gt; 0) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">req</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">-</span><span class="element">&gt;title</span><span class="plain">) &gt; 0)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::ne_insensitive</span><span class="plain">(</span><span class="identifier">req</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">-</span><span class="element">&gt;title</span><span class="plain">, </span><span class="identifier">edition</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">-</span><span class="element">&gt;title</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>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">req</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">-</span><span class="element">&gt;author_name</span><span class="plain">) &gt; 0) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">req</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">-</span><span class="element">&gt;author_name</span><span class="plain">) &gt; 0)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::ne_insensitive</span><span class="plain">(</span><span class="identifier">req</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">-</span><span class="element">&gt;author_name</span><span class="plain">, </span><span class="identifier">edition</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">-</span><span class="element">&gt;author_name</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>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">VersionNumberRanges::in_range</span><span class="plain">(</span><span class="identifier">edition</span><span class="plain">-</span><span class="element">&gt;version</span><span class="plain">, </span><span class="identifier">req</span><span class="plain">-</span><span class="element">&gt;version_range</span><span class="plain">);</span>
<span class="plain">}</span>
@ -220,26 +314,10 @@
<p class="inwebparagraph"></p>
<p class="endnote">The function Requirements::new is used in 6/inc (<a href="6-inc.html#SP5_1">&#167;5.1</a>).</p>
<p class="endnote">The function Requirements::any_version_of is used in 3/is (<a href="3-is.html#SP1">&#167;1</a>), 5/kts (<a href="5-kts.html#SP1">&#167;1</a>), 5/ed2 (<a href="5-ed2.html#SP4">&#167;4</a>), 5/ls (<a href="5-ls.html#SP7">&#167;7</a>), 6/inc (<a href="6-inc.html#SP6_1_2">&#167;6.1.2</a>).</p>
<p class="endnote">The function Requirements::anything_of_genre is used in 1/ic (<a href="1-ic.html#SP9_2">&#167;9.2</a>), 5/ec (<a href="5-ec.html#SP3">&#167;3</a>).</p>
<p class="endnote">The function Requirements::anything appears nowhere else.</p>
<p class="endnote">The function Requirements::from_text appears nowhere else.</p>
<p class="endnote">The function Requirements::impose_clause appears nowhere else.</p>
<p class="endnote">The function Requirements::write is used in 3/bg (<a href="3-bg.html#SP1">&#167;1</a>).</p>
<p class="endnote">The function Requirements::meets is used in 4/km (<a href="4-km.html#SP5">&#167;5</a>), 4/em (<a href="4-em.html#SP7">&#167;7</a>), 4/lm (<a href="4-lm.html#SP6">&#167;6</a>), 4/tm (<a href="4-tm.html#SP5">&#167;5</a>), 4/pm (<a href="4-pm.html#SP6">&#167;6</a>), 5/kts (<a href="5-kts.html#SP2">&#167;2</a>), 5/es (<a href="5-es.html#SP4">&#167;4</a>), 5/ed2 (<a href="5-ed2.html#SP4">&#167;4</a>), 6/inc (<a href="6-inc.html#SP6">&#167;6</a>).</p>
<p class="endnote">The structure inbuild_requirement is accessed in 2/wrk, 2/edt, 2/cps, 2/nst, 3/bg, 3/is2, 4/km, 4/em, 4/lm, 4/pbm, 4/pfm, 4/tm, 4/pm, 5/kts, 5/es, 5/ed, 5/ed2, 5/ec, 5/ps, 5/ls, 6/hdn, 6/inc and here.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="2-cps.html">Back to 'Copies'</a></li><li><a href="2-nst.html">Continue with 'Nests'</a></li></ul><hr class="tocbar">
<ul class="toc"><li><a href="2-ce.html">Back to 'Copy Errors'</a></li><li><a href="2-nst.html">Continue with 'Nests'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</main>
</body>

View file

@ -59,7 +59,7 @@
<!--Weave of '2/wrk' 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#2">Chapter 2: Conceptual Framework</a></li><li><b>Works</b></li></ul><p class="purpose">To store, hash code and compare title/author pairs used to identify works.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Works</a></li><li><a href="#SP6">&#167;6. The database of known works</a></li><li><a href="#SP10">&#167;10. How casing is normalised</a></li><li><a href="#SP11">&#167;11. Documentation links</a></li></ul><hr class="tocbar">
<ul class="toc"><li><a href="#SP1">&#167;1. Works</a></li><li><a href="#SP5">&#167;5. Printing</a></li><li><a href="#SP8">&#167;8. Identification</a></li><li><a href="#SP11">&#167;11. The database of known works</a></li><li><a href="#SP15">&#167;15. Documentation links</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Works. </b>A "work" is a single artistic or programming creation; for example, the IF
story Bronze by Emily Short might be a work. Mamy versions of this IF story
@ -90,26 +90,10 @@ combination of the textual names and the hash code:
<p class="inwebparagraph"></p>
<p class="endnote">The structure inbuild_work is accessed in 2/edt, 2/cps, 2/rqr, 2/nst, 3/bg, 3/is2, 4/km, 4/em, 4/lm, 4/pbm, 4/pfm, 4/tm, 4/pm, 5/kts, 5/es, 5/ed, 5/ed2, 5/ec, 5/ps, 5/ls, 6/inc and here.</p>
<p class="endnote">The structure inbuild_work is accessed in 2/edt, 2/cps, 2/rqr, 3/bg, 3/is2, 4/km, 4/em, 4/lm, 4/pbm, 4/pfm, 4/tm, 4/pm, 5/kts, 5/es, 5/ed, 5/ed2, 5/ec, 5/ps, 5/ls, 6/inc and here.</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>Each work structure is written only once, and its title and author name are
not subsequently altered. We therefore hash-code on arrival. As when
hashing vocabulary, we apply the X 30011 algorithm, this time with 499
(coprime to 30011) as base, to the text of the Unix-style pathname
<code class="display"><span class="extract">Author/Title</span></code>.
</p>
<p class="inwebparagraph">Though it is probably the case that the author name and title supplied are
already of normalised casing, we do not want to rely on that. Works intending
to represent (e.g.) the same extension but named with different casing
conventions would fail to match: and this could happen if a new build of
Inform were published which made a subtle change to the casing conventions,
but which continued to use an extension dictionary file first written by
previous builds under the previous conventions.
</p>
<p class="inwebparagraph">The hash code is an integer between 0 and the following constant minus 1,
derived from its title and author name.
not subsequently altered.
</p>
@ -124,7 +108,29 @@ derived from its title and author name.
<span class="reserved">inbuild_work</span><span class="plain"> *</span><span class="functiontext">Works::new_raw</span><span class="plain">(</span><span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">genre</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">ti</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">an</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Works::new_inner</span><span class="plain">(</span><span class="identifier">genre</span><span class="plain">, </span><span class="identifier">ti</span><span class="plain">, </span><span class="identifier">an</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 Works::new is used in <a href="#SP10">&#167;10</a>, 2/rqr (<a href="2-rqr.html#SP2">&#167;2</a>), 3/is (<a href="3-is.html#SP1">&#167;1</a>), 4/em (<a href="4-em.html#SP5">&#167;5</a>), 4/lm (<a href="4-lm.html#SP4">&#167;4</a>), 4/pbm (<a href="4-pbm.html#SP2">&#167;2</a>), 4/pfm (<a href="4-pfm.html#SP2">&#167;2</a>), 4/tm (<a href="4-tm.html#SP3">&#167;3</a>), 5/kts (<a href="5-kts.html#SP1">&#167;1</a>), 5/es (<a href="5-es.html#SP1">&#167;1</a>), 5/ed (<a href="5-ed.html#SP10">&#167;10</a>), 5/ls (<a href="5-ls.html#SP7">&#167;7</a>), 6/hdn (<a href="6-hdn.html#SP13_3">&#167;13.3</a>), 6/inc (<a href="6-inc.html#SP5_1">&#167;5.1</a>).</p>
<p class="endnote">The function Works::new_raw is used in 4/km (<a href="4-km.html#SP3">&#167;3</a>), 4/pm (<a href="4-pm.html#SP5">&#167;5</a>).</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>Though it is probably the case that the author name and title supplied are
already of normalised casing, we do not want to rely on that. Works intending
to represent (e.g.) the same extension but named with different casing
conventions would fail to match: and this could happen if a new build of
Inform were published which made a subtle change to the casing conventions,
but which continued to use an extension dictionary file first written by
previous builds under the previous conventions.
</p>
<p class="inwebparagraph">The "raw", i.e., not case-normalised, forms of the title and author name are
preserved for use in text output, but not identification.
</p>
<pre class="display">
<span class="reserved">inbuild_work</span><span class="plain"> *</span><span class="functiontext">Works::new_inner</span><span class="plain">(</span><span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">genre</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">ti</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">an</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">norm</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="identifier">CREATE</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="element">&gt;genre</span><span class="plain"> = </span><span class="identifier">genre</span><span class="plain">;</span>
@ -136,6 +142,30 @@ derived from its title and author name.
<span class="functiontext">Works::normalise_casing</span><span class="plain">(</span><span class="identifier">work</span><span class="plain">-</span><span class="element">&gt;author_name</span><span class="plain">);</span>
<span class="functiontext">Works::normalise_casing</span><span class="plain">(</span><span class="identifier">work</span><span class="plain">-</span><span class="element">&gt;title</span><span class="plain">);</span>
<span class="plain">}</span>
&lt;<span class="cwebmacro">Compute the hash code</span> <span class="cwebmacronumber">3.1</span>&gt;<span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">work</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Works::new_inner is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP3_1"></a><b>&#167;3.1. </b>We hash-code all works on arrival, using the X 30011 algorithm, with 499
(coprime to 30011) as base, to the text of the pseudo-pathname <code class="display"><span class="extract">Author/Title</span></code>.
</p>
<p class="inwebparagraph">The hash code is an integer between 0 and the following constant minus 1,
derived from its title and author name.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Compute the hash code</span> <span class="cwebmacronumber">3.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">unsigned</span><span class="plain"> </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">hc</span><span class="plain"> = 0;</span>
<span class="identifier">LOOP_THROUGH_TEXT</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">, </span><span class="identifier">work</span><span class="plain">-</span><span class="element">&gt;author_name</span><span class="plain">)</span>
<span class="identifier">hc</span><span class="plain"> = </span><span class="identifier">hc</span><span class="plain">*30011 + (</span><span class="reserved">unsigned</span><span class="plain"> </span><span class="reserved">int</span><span class="plain">) </span><span class="identifier">Str::get</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">);</span>
@ -144,14 +174,42 @@ derived from its title and author name.
<span class="identifier">hc</span><span class="plain"> = </span><span class="identifier">hc</span><span class="plain">*30011 + (</span><span class="reserved">unsigned</span><span class="plain"> </span><span class="reserved">int</span><span class="plain">) </span><span class="identifier">Str::get</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">);</span>
<span class="identifier">hc</span><span class="plain"> = </span><span class="identifier">hc</span><span class="plain"> % </span><span class="constant">WORK_HASH_CODING_BASE</span><span class="plain">;</span>
<span class="identifier">work</span><span class="plain">-</span><span class="element">&gt;inbuild_work_hash_code</span><span class="plain"> = (</span><span class="reserved">int</span><span class="plain">) </span><span class="identifier">hc</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">work</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Works::set_raw</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="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">raw_an</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">raw_ti</span><span class="plain">) {</span>
<span class="identifier">work</span><span class="plain">-</span><span class="element">&gt;raw_author_name</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">raw_an</span><span class="plain">);</span>
<span class="identifier">work</span><span class="plain">-</span><span class="element">&gt;raw_title</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">raw_ti</span><span class="plain">);</span>
<span class="plain">}</span>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>Casing is normalised as follows. Every word is capitalised, where a word
begins at the start of the text, after a hyphen, or after a bracket. Thus
"Every Word Counts", "Even Double-Barrelled Ones (And Even Parenthetically)".
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Works::normalise_casing</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">boundary</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">LOOP_THROUGH_TEXT</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">) {</span>
<span class="identifier">wchar_t</span><span class="plain"> </span><span class="identifier">c</span><span class="plain"> = </span><span class="identifier">Str::get</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">boundary</span><span class="plain">) </span><span class="identifier">Str::put</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">, </span><span class="identifier">Characters::toupper</span><span class="plain">(</span><span class="identifier">c</span><span class="plain">));</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">Str::put</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">, </span><span class="identifier">Characters::tolower</span><span class="plain">(</span><span class="identifier">c</span><span class="plain">));</span>
<span class="identifier">boundary</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">c</span><span class="plain"> == </span><span class="character">' '</span><span class="plain">) </span><span class="identifier">boundary</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">c</span><span class="plain"> == </span><span class="character">'-'</span><span class="plain">) </span><span class="identifier">boundary</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">c</span><span class="plain"> == </span><span class="character">'('</span><span class="plain">) </span><span class="identifier">boundary</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Works::normalise_casing is used in <a href="#SP3">&#167;3</a>, 5/es (<a href="5-es.html#SP1_1_1">&#167;1.1.1</a>).</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. Printing. </b>As noted above, the raw forms are used for output.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Works::write</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</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="identifier">VMETHOD_CALL</span><span class="plain">(</span><span class="identifier">work</span><span class="plain">-</span><span class="element">&gt;genre</span><span class="plain">, </span><span class="constant">GENRE_WRITE_WORK_MTID</span><span class="plain">, </span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">work</span><span class="plain">);</span>
<span class="plain">}</span>
@ -163,7 +221,20 @@ derived from its title and author name.
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">fancy</span><span class="plain">) </span><span class="identifier">HTML::end_colour</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%S"</span><span class="plain">, </span><span class="identifier">work</span><span class="plain">-</span><span class="element">&gt;raw_author_name</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Works::write is used in 2/edt (<a href="2-edt.html#SP1">&#167;1</a>), 3/bg (<a href="3-bg.html#SP1">&#167;1</a>).</p>
<p class="endnote">The function Works::write_to_HTML_file is used in <a href="#SP6">&#167;6</a>, 5/ed (<a href="5-ed.html#SP19_2">&#167;19.2</a>), 5/ed2 (<a href="5-ed2.html#SP3_2_1">&#167;3.2.1</a>).</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. </b>The following is only sensible for extensions, and is used when Inform
generates its Extensions index entries.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Works::write_link_to_HTML_file</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</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="identifier">HTML_OPEN_WITH</span><span class="plain">(</span><span class="string">"a"</span><span class="plain">, </span><span class="string">"href='Extensions/%S/%S.html' style=\</span><span class="plain">"</span><span class="string">text-decoration: none\</span><span class="plain">"</span><span class="string">"</span><span class="plain">,</span>
<span class="identifier">work</span><span class="plain">-</span><span class="element">&gt;author_name</span><span class="plain">, </span><span class="identifier">work</span><span class="plain">-</span><span class="element">&gt;title</span><span class="plain">);</span>
@ -173,7 +244,18 @@ derived from its title and author name.
<span class="identifier">HTML::end_colour</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"a"</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Works::write_link_to_HTML_file is used in 5/ed (<a href="5-ed.html#SP20_1">&#167;20.1</a>).</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. </b>The Inbuild module provides the <code class="display"><span class="extract">%X</span></code> escape sequence for printing names of
works. (The X used to stand for Extension.) <code class="display"><span class="extract">%&lt;X</span></code> ptovides an abbreviated form.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Works::writer</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">format_string</span><span class="plain">, </span><span class="reserved">void</span><span class="plain"> *</span><span class="identifier">vE</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="reserved">inbuild_work</span><span class="plain"> *) </span><span class="identifier">vE</span><span class="plain">;</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">format_string</span><span class="plain">[0]) {</span>
@ -181,7 +263,8 @@ derived from its title and author name.
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">work</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"source text"</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%S"</span><span class="plain">, </span><span class="identifier">work</span><span class="plain">-</span><span class="element">&gt;raw_title</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Works::is_standard_rules</span><span class="plain">(</span><span class="identifier">work</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Works::is_standard_rules</span><span class="plain">(</span><span class="identifier">work</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Works::is_basic_inform</span><span class="plain">(</span><span class="identifier">work</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">))</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" by %S"</span><span class="plain">, </span><span class="identifier">work</span><span class="plain">-</span><span class="element">&gt;raw_author_name</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">break</span><span class="plain">;</span>
@ -197,24 +280,10 @@ derived from its title and author name.
<p class="inwebparagraph"></p>
<p class="endnote">The function Works::new is used in <a href="#SP5">&#167;5</a>, 2/rqr (<a href="2-rqr.html#SP1">&#167;1</a>), 3/is (<a href="3-is.html#SP1">&#167;1</a>), 4/em (<a href="4-em.html#SP5">&#167;5</a>), 4/lm (<a href="4-lm.html#SP4">&#167;4</a>), 4/pbm (<a href="4-pbm.html#SP2">&#167;2</a>), 4/pfm (<a href="4-pfm.html#SP2">&#167;2</a>), 4/tm (<a href="4-tm.html#SP3">&#167;3</a>), 5/kts (<a href="5-kts.html#SP1">&#167;1</a>), 5/es (<a href="5-es.html#SP1">&#167;1</a>), 5/ed (<a href="5-ed.html#SP10">&#167;10</a>), 5/ls (<a href="5-ls.html#SP7">&#167;7</a>), 6/hdn (<a href="6-hdn.html#SP13_3">&#167;13.3</a>), 6/inc (<a href="6-inc.html#SP5_1">&#167;5.1</a>).</p>
<p class="endnote">The function Works::new_raw is used in 4/km (<a href="4-km.html#SP3">&#167;3</a>), 4/pm (<a href="4-pm.html#SP5">&#167;5</a>).</p>
<p class="endnote">The function Works::new_inner appears nowhere else.</p>
<p class="endnote">The function Works::set_raw appears nowhere else.</p>
<p class="endnote">The function Works::write is used in 2/edt (<a href="2-edt.html#SP1">&#167;1</a>), 3/bg (<a href="3-bg.html#SP1">&#167;1</a>).</p>
<p class="endnote">The function Works::write_to_HTML_file is used in 5/ed (<a href="5-ed.html#SP19_2">&#167;19.2</a>), 5/ed2 (<a href="5-ed2.html#SP3_2_1">&#167;3.2.1</a>).</p>
<p class="endnote">The function Works::write_link_to_HTML_file is used in 5/ed (<a href="5-ed.html#SP20_1">&#167;20.1</a>).</p>
<p class="endnote">The function Works::writer is used in 1/im (<a href="1-im.html#SP3_3">&#167;3.3</a>).</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>Two works with different hash codes definitely identify different extensions;
if the code is the same, we must use <code class="display"><span class="extract">strcmp</span></code> on the actual title and author
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. Identification. </b>Two works with different hash codes definitely identify different works;
if the code is the same, we must use <code class="display"><span class="extract">Str::eq</span></code> on the actual title and author
name. This is in effect case insensitive, since we normalised casing when
the works were created.
</p>
@ -222,7 +291,7 @@ the works were created.
<p class="inwebparagraph">(Note that this is not a lexicographic function suitable for sorting
works into alphabetical order: it cannot be, since the hash code is not
order-preserving. To emphasise this we return true or false rather than a
<code class="display"><span class="extract">strcmp</span></code>-style delta value. For <code class="display"><span class="extract">Works::compare</span></code>, see below...)
<code class="display"><span class="extract">strcmp</span></code>-style delta value.)
</p>
@ -238,9 +307,10 @@ order-preserving. To emphasise this we return true or false rather than a
<p class="inwebparagraph"></p>
<p class="endnote">The function Works::match is used in <a href="#SP5">&#167;5</a>, <a href="#SP6">&#167;6</a>, <a href="#SP7">&#167;7</a>, <a href="#SP8">&#167;8</a>, 5/ed (<a href="5-ed.html#SP9">&#167;9</a>, <a href="5-ed.html#SP18">&#167;18</a>, <a href="5-ed.html#SP18_2">&#167;18.2</a>), 5/ec (<a href="5-ec.html#SP3_1">&#167;3.1</a>), 6/hdn (<a href="6-hdn.html#SP23">&#167;23</a>, <a href="6-hdn.html#SP23_2">&#167;23.2</a>).</p>
<p class="endnote">The function Works::match is used in <a href="#SP10">&#167;10</a>, <a href="#SP11">&#167;11</a>, <a href="#SP12">&#167;12</a>, <a href="#SP13">&#167;13</a>, 5/ed (<a href="5-ed.html#SP9">&#167;9</a>, <a href="5-ed.html#SP18">&#167;18</a>, <a href="5-ed.html#SP18_2">&#167;18.2</a>), 5/ec (<a href="5-ec.html#SP3_1">&#167;3.1</a>), 6/hdn (<a href="6-hdn.html#SP23">&#167;23</a>, <a href="6-hdn.html#SP23_2">&#167;23.2</a>).</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>These are quite a deal slower, but trichotomous.
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. </b>These are quite a deal slower, but are trichotomous and can be used for
sorting.
</p>
@ -288,9 +358,9 @@ order-preserving. To emphasise this we return true or false rather than a
<p class="endnote">The function Works::compare_by_length is used in 5/ec (<a href="5-ec.html#SP8">&#167;8</a>).</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b>Because the Standard Rules are treated slightly differently by the
documentation, and so forth, it's convenient to provide a single function
testing if a work refers to them.
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. </b>Because Basic Inform and the Standard Rules extensions are treated slightly
differently by the documentation, and so forth, it's convenient to provide a
single function testing if a work refers to them.
</p>
@ -320,11 +390,11 @@ testing if a work refers to them.
<p class="inwebparagraph"></p>
<p class="endnote">The function Works::is_standard_rules is used in <a href="#SP2">&#167;2</a>, 4/em (<a href="4-em.html#SP5">&#167;5</a>), 5/ed2 (<a href="5-ed2.html#SP3_2_1">&#167;3.2.1</a>).</p>
<p class="endnote">The function Works::is_standard_rules is used in <a href="#SP6">&#167;6</a>, <a href="#SP7">&#167;7</a>, 4/em (<a href="4-em.html#SP5">&#167;5</a>), 5/ed2 (<a href="5-ed2.html#SP3_2_1">&#167;3.2.1</a>).</p>
<p class="endnote">The function Works::is_basic_inform appears nowhere else.</p>
<p class="endnote">The function Works::is_basic_inform is used in <a href="#SP7">&#167;7</a>.</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. The database of known works. </b>We will need to be able to give rapid answers to questions like "is there
<p class="inwebparagraph"><a id="SP11"></a><b>&#167;11. The database of known works. </b>We will need to be able to give rapid answers to questions like "is there
an installed extension with this work?" and "does any entry in the dictionary
relate to this work?": there may be many extensions and very many dictionary
entries, so we keep an incidence count of each work and in what context it
@ -394,11 +464,11 @@ indeed, the typical number will be 0 or 1.
<p class="inwebparagraph"></p>
<p class="endnote">The function Works::add_to_database is used in <a href="#SP5">&#167;5</a>, 4/km (<a href="4-km.html#SP4">&#167;4</a>), 4/em (<a href="4-em.html#SP6">&#167;6</a>), 4/lm (<a href="4-lm.html#SP5">&#167;5</a>), 4/pbm (<a href="4-pbm.html#SP3">&#167;3</a>), 4/pfm (<a href="4-pfm.html#SP3">&#167;3</a>), 4/tm (<a href="4-tm.html#SP4">&#167;4</a>), 4/pm (<a href="4-pm.html#SP5">&#167;5</a>), 5/es (<a href="5-es.html#SP1">&#167;1</a>), 5/ed (<a href="5-ed.html#SP10">&#167;10</a>), 5/ec (<a href="5-ec.html#SP3_2">&#167;3.2</a>), 6/hdn (<a href="6-hdn.html#SP13_3">&#167;13.3</a>), 6/inc (<a href="6-inc.html#SP5_1">&#167;5.1</a>).</p>
<p class="endnote">The function Works::add_to_database is used in <a href="#SP10">&#167;10</a>, 4/km (<a href="4-km.html#SP4">&#167;4</a>), 4/em (<a href="4-em.html#SP6">&#167;6</a>), 4/lm (<a href="4-lm.html#SP5">&#167;5</a>), 4/pbm (<a href="4-pbm.html#SP3">&#167;3</a>), 4/pfm (<a href="4-pfm.html#SP3">&#167;3</a>), 4/tm (<a href="4-tm.html#SP4">&#167;4</a>), 4/pm (<a href="4-pm.html#SP5">&#167;5</a>), 5/es (<a href="5-es.html#SP1">&#167;1</a>), 5/ed (<a href="5-ed.html#SP10">&#167;10</a>), 5/ec (<a href="5-ec.html#SP3_2">&#167;3.2</a>), 6/hdn (<a href="6-hdn.html#SP13_3">&#167;13.3</a>), 6/inc (<a href="6-inc.html#SP5_1">&#167;5.1</a>).</p>
<p class="endnote">The structure inbuild_work_database_entry is accessed in 2/edt, 2/cps, 2/rqr, 2/nst, 3/bg, 3/is2, 4/km, 4/em, 4/lm, 4/pbm, 4/pfm, 4/tm, 4/pm, 5/kts, 5/es, 5/ed, 5/ed2, 5/ec, 5/ps, 5/ls, 6/hdn, 6/inc and here.</p>
<p class="endnote">The structure inbuild_work_database_entry is accessed in 2/edt, 2/cps, 2/rqr, 3/bg, 3/is2, 4/km, 4/em, 4/lm, 4/pbm, 4/pfm, 4/tm, 4/pm, 5/kts, 5/es, 5/ed, 5/ed2, 5/ec, 5/ps, 5/ls, 6/hdn, 6/inc and here.</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. </b>This gives us reasonably rapid access to a shared date:
<p class="inwebparagraph"><a id="SP12"></a><b>&#167;12. </b>This gives us reasonably rapid access to a shared date:
</p>
@ -522,11 +592,11 @@ indeed, the typical number will be 0 or 1.
<p class="endnote">The function Works::get_usage_date is used in 5/ec (<a href="5-ec.html#SP6_7_4_4">&#167;6.7.4.4</a>).</p>
<p class="endnote">The function Works::get_sort_date is used in <a href="#SP4">&#167;4</a>.</p>
<p class="endnote">The function Works::get_sort_date is used in <a href="#SP9">&#167;9</a>.</p>
<p class="endnote">The function Works::set_word_count is used in 5/ed (<a href="5-ed.html#SP10">&#167;10</a>).</p>
<p class="endnote">The function Works::get_sort_word_count is used in <a href="#SP4">&#167;4</a>.</p>
<p class="endnote">The function Works::get_sort_word_count is used in <a href="#SP9">&#167;9</a>.</p>
<p class="endnote">The function Works::forgot is used in 5/ec (<a href="5-ec.html#SP6_7_4_4">&#167;6.7.4.4</a>).</p>
@ -534,7 +604,7 @@ indeed, the typical number will be 0 or 1.
<p class="endnote">The function Works::get_word_count is used in 5/ec (<a href="5-ec.html#SP6_7_4_4">&#167;6.7.4.4</a>).</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. </b>The purpose of the hash table is to enable us to reply quickly when asked
<p class="inwebparagraph"><a id="SP13"></a><b>&#167;13. </b>The purpose of the hash table is to enable us to reply quickly when asked
for one of the following usage counts:
</p>
@ -552,7 +622,7 @@ for one of the following usage counts:
<p class="endnote">The function Works::no_times_used_in_context is used in 5/ed (<a href="5-ed.html#SP8">&#167;8</a>), 5/ec (<a href="5-ec.html#SP7">&#167;7</a>), 6/hdn (<a href="6-hdn.html#SP23">&#167;23</a>).</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. </b>The work hash table makes quite interesting reading, so:
<p class="inwebparagraph"><a id="SP14"></a><b>&#167;14. </b>The work hash table makes quite interesting reading, so:
</p>
@ -578,32 +648,7 @@ for one of the following usage counts:
<p class="endnote">The function Works::log_work_hash_table is used in 5/ec (<a href="5-ec.html#SP11">&#167;11</a>).</p>
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. How casing is normalised. </b>Every word is capitalised, where a word begins at the start of the text,
after a hyphen, or after a bracket. Thus "Every Word Counts", "Even
Double-Barrelled Ones (And Even Parenthetically)".
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Works::normalise_casing</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">boundary</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">LOOP_THROUGH_TEXT</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">) {</span>
<span class="identifier">wchar_t</span><span class="plain"> </span><span class="identifier">c</span><span class="plain"> = </span><span class="identifier">Str::get</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">boundary</span><span class="plain">) </span><span class="identifier">Str::put</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">, </span><span class="identifier">Characters::toupper</span><span class="plain">(</span><span class="identifier">c</span><span class="plain">));</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">Str::put</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">, </span><span class="identifier">Characters::tolower</span><span class="plain">(</span><span class="identifier">c</span><span class="plain">));</span>
<span class="identifier">boundary</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">c</span><span class="plain"> == </span><span class="character">' '</span><span class="plain">) </span><span class="identifier">boundary</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">c</span><span class="plain"> == </span><span class="character">'-'</span><span class="plain">) </span><span class="identifier">boundary</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">c</span><span class="plain"> == </span><span class="character">'('</span><span class="plain">) </span><span class="identifier">boundary</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Works::normalise_casing is used in <a href="#SP2">&#167;2</a>, 5/es (<a href="5-es.html#SP1_1_1">&#167;1.1.1</a>).</p>
<p class="inwebparagraph"><a id="SP11"></a><b>&#167;11. Documentation links. </b>This is where HTML links to extension documentation are created; the URL for
<p class="inwebparagraph"><a id="SP15"></a><b>&#167;15. Documentation links. </b>This is where HTML links to extension documentation are created; the URL for
each extension's page is generated from its <code class="display"><span class="extract">inbuild_work</span></code>.
</p>

View file

@ -295,7 +295,7 @@ a different file inside the copy.
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" -- already there\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" -- archiving\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
<span class="functiontext">Nests::copy_to</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">N</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">, </span><span class="identifier">BM</span><span class="plain">);</span>
<span class="functiontext">Copies::copy_to</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">N</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">, </span><span class="identifier">BM</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">nl</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">cl</span><span class="plain">);</span>
@ -369,21 +369,21 @@ a different file inside the copy.
<p class="endnote">The function Graphs::need_this_to_use is used in 5/kts (<a href="5-kts.html#SP2">&#167;2</a>), 5/ps (<a href="5-ps.html#SP3">&#167;3</a>), 6/inc (<a href="6-inc.html#SP1_1">&#167;1.1</a>).</p>
<p class="endnote">The function Graphs::describe is used in <a href="#SP2">&#167;2</a>, 2/cps (<a href="2-cps.html#SP1">&#167;1</a>).</p>
<p class="endnote">The function Graphs::describe is used in <a href="#SP2">&#167;2</a>, 2/cps (<a href="2-cps.html#SP11">&#167;11</a>).</p>
<p class="endnote">The function Graphs::describe_r appears nowhere else.</p>
<p class="endnote">The function Graphs::describe_vertex appears nowhere else.</p>
<p class="endnote">The function Graphs::show_needs is used in 2/cps (<a href="2-cps.html#SP1">&#167;1</a>).</p>
<p class="endnote">The function Graphs::show_needs is used in 2/cps (<a href="2-cps.html#SP11">&#167;11</a>).</p>
<p class="endnote">The function Graphs::show_needs_r appears nowhere else.</p>
<p class="endnote">The function Graphs::show_missing is used in 2/cps (<a href="2-cps.html#SP1">&#167;1</a>).</p>
<p class="endnote">The function Graphs::show_missing is used in 2/cps (<a href="2-cps.html#SP11">&#167;11</a>, <a href="2-cps.html#SP12">&#167;12</a>).</p>
<p class="endnote">The function Graphs::show_missing_r appears nowhere else.</p>
<p class="endnote">The function Graphs::archive is used in 2/cps (<a href="2-cps.html#SP1">&#167;1</a>).</p>
<p class="endnote">The function Graphs::archive is used in 2/cps (<a href="2-cps.html#SP12">&#167;12</a>).</p>
<p class="endnote">The function Graphs::archive_r appears nowhere else.</p>
@ -453,9 +453,9 @@ a different file inside the copy.
<p class="inwebparagraph"></p>
<p class="endnote">The function Graphs::build is used in 2/cps (<a href="2-cps.html#SP1">&#167;1</a>).</p>
<p class="endnote">The function Graphs::build is used in 2/cps (<a href="2-cps.html#SP10">&#167;10</a>).</p>
<p class="endnote">The function Graphs::rebuild is used in 2/cps (<a href="2-cps.html#SP1">&#167;1</a>).</p>
<p class="endnote">The function Graphs::rebuild is used in 2/cps (<a href="2-cps.html#SP10">&#167;10</a>).</p>
<p class="endnote">The function Graphs::build_r appears nowhere else.</p>

View file

@ -95,7 +95,7 @@
<span class="reserved">inbuild_requirement</span><span class="plain"> *</span><span class="identifier">req</span><span class="plain"> =</span>
<span class="functiontext">Requirements::any_version_of</span><span class="plain">(</span><span class="functiontext">Works::new</span><span class="plain">(</span><span class="identifier">pipeline_genre</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"assimilate.interpipeline"</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">));</span>
<span class="reserved">inbuild_search_result</span><span class="plain"> *</span><span class="identifier">R</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">inbuild_search_result</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain"> = </span><span class="functiontext">Nests::search_for_best</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">R</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
<span class="identifier">Errors::nowhere</span><span class="plain">(</span><span class="string">"assimilate pipeline could not be found"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
@ -142,7 +142,7 @@
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">F</span><span class="plain"> == </span><span class="identifier">NULL</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::any_version_of</span><span class="plain">(</span><span class="functiontext">Works::new</span><span class="plain">(</span><span class="identifier">pipeline_genre</span><span class="plain">, </span><span class="identifier">inter_pipeline_name</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">));</span>
<span class="reserved">inbuild_search_result</span><span class="plain"> *</span><span class="identifier">R</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">inbuild_search_result</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain"> = </span><span class="functiontext">Nests::search_for_best</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">R</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
<span class="identifier">Errors::with_text</span><span class="plain">(</span><span class="string">"inter pipeline '%S' could not be found"</span><span class="plain">, </span><span class="identifier">inter_pipeline_name</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>

View file

@ -142,8 +142,10 @@ which stores data about extensions used by the Inform compiler.
<span class="identifier">C</span><span class="plain"> = </span><span class="identifier">Dictionaries::read_value</span><span class="plain">(</span><span class="identifier">ext_copy_cache</span><span class="plain">, </span><span class="identifier">key</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">C</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
<span class="identifier">C</span><span class="plain"> = </span><span class="functiontext">Copies::new_in_file</span><span class="plain">(</span>
<span class="functiontext">Editions::new</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">I</span><span class="string">"Untitled"</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Anonymous"</span><span class="plain">),</span>
<span class="identifier">VersionNumbers::null</span><span class="plain">()), </span><span class="identifier">F</span><span class="plain">, </span><span class="identifier">NULL_GENERAL_POINTER</span><span class="plain">);</span>
<span class="functiontext">Editions::new</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">I</span><span class="string">"Untitled"</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Anonymous"</span><span class="plain">),</span>
<span class="identifier">VersionNumbers::null</span><span class="plain">()),</span>
<span class="identifier">F</span><span class="plain">);</span>
<span class="functiontext">Extensions::scan</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Works::is_standard_rules</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;edition</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">))</span>
<span class="functiontext">Extensions::make_standard</span><span class="plain">(</span><span class="functiontext">ExtensionManager::from_copy</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">));</span>
@ -283,7 +285,7 @@ since an extension is a single file; to sync, we just overwrite.
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">leaf</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">TextFiles::exists</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">syncing</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) { </span><span class="functiontext">Nests::overwrite_error</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">syncing</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) { </span><span class="functiontext">Copies::overwrite_error</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">N</span><span class="plain">); </span><span class="reserved">return</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">meth</span><span class="plain">-</span><span class="element">&gt;methodology</span><span class="plain"> == </span><span class="constant">DRY_RUN_METHODOLOGY</span><span class="plain">) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">);</span>
@ -332,7 +334,7 @@ the current VM settings.
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">ExtensionManager::ensure_graphed</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="functiontext">Copies::read_source_text_for</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">);</span>
<span class="functiontext">Copies::get_source_text</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">);</span>
<span class="functiontext">Inclusions::traverse</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="functiontext">ExtensionManager::from_copy</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">)-</span><span class="element">&gt;syntax_tree</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="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">, </span><span class="reserved">build_vertex</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;vertex</span><span class="plain">-</span><span class="element">&gt;use_edges</span><span class="plain">)</span>

View file

@ -126,7 +126,7 @@ which stores data about extensions used by the Inform compiler.
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">C</span><span class="plain"> == </span><span class="identifier">NULL</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_raw</span><span class="plain">(</span><span class="identifier">kit_genre</span><span class="plain">, </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">), </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="reserved">inbuild_edition</span><span class="plain"> *</span><span class="identifier">edition</span><span class="plain"> = </span><span class="functiontext">Editions::new</span><span class="plain">(</span><span class="identifier">work</span><span class="plain">, </span><span class="identifier">VersionNumbers::null</span><span class="plain">());</span>
<span class="identifier">C</span><span class="plain"> = </span><span class="functiontext">Copies::new_in_path</span><span class="plain">(</span><span class="identifier">edition</span><span class="plain">, </span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">NULL_GENERAL_POINTER</span><span class="plain">);</span>
<span class="identifier">C</span><span class="plain"> = </span><span class="functiontext">Copies::new_in_path</span><span class="plain">(</span><span class="identifier">edition</span><span class="plain">, </span><span class="identifier">P</span><span class="plain">);</span>
<span class="functiontext">Kits::scan</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">);</span>
<span class="identifier">Dictionaries::create</span><span class="plain">(</span><span class="identifier">kit_copy_cache</span><span class="plain">, </span><span class="identifier">key</span><span class="plain">);</span>
<span class="identifier">Dictionaries::write_value</span><span class="plain">(</span><span class="identifier">kit_copy_cache</span><span class="plain">, </span><span class="identifier">key</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">);</span>
@ -237,7 +237,7 @@ we need to <code class="display"><span class="extract">rsync</span></code> it.
<span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">dest_kit</span><span class="plain"> = </span><span class="functiontext">KitManager::pathname_in_nest</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;edition</span><span class="plain">);</span>
<span class="identifier">filename</span><span class="plain"> *</span><span class="identifier">dest_kit_metadata</span><span class="plain"> = </span><span class="identifier">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">dest_kit</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"kit_metadata.txt"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">TextFiles::exists</span><span class="plain">(</span><span class="identifier">dest_kit_metadata</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">syncing</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) { </span><span class="functiontext">Nests::overwrite_error</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">syncing</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) { </span><span class="functiontext">Copies::overwrite_error</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">N</span><span class="plain">); </span><span class="reserved">return</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">meth</span><span class="plain">-</span><span class="element">&gt;methodology</span><span class="plain"> == </span><span class="constant">DRY_RUN_METHODOLOGY</span><span class="plain">) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">);</span>

View file

@ -133,7 +133,8 @@ which stores data about extensions used by the Inform compiler.
<span class="reserved">inform_language</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain"> = </span><span class="functiontext">Languages::new_il</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">, </span><span class="identifier">P</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">language_genre</span><span class="plain">, </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">), </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="reserved">inbuild_edition</span><span class="plain"> *</span><span class="identifier">edition</span><span class="plain"> = </span><span class="functiontext">Editions::new</span><span class="plain">(</span><span class="identifier">work</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">-</span><span class="element">&gt;version</span><span class="plain">);</span>
<span class="identifier">C</span><span class="plain"> = </span><span class="functiontext">Copies::new_in_path</span><span class="plain">(</span><span class="identifier">edition</span><span class="plain">, </span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">STORE_POINTER_inform_language</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">));</span>
<span class="identifier">C</span><span class="plain"> = </span><span class="functiontext">Copies::new_in_path</span><span class="plain">(</span><span class="identifier">edition</span><span class="plain">, </span><span class="identifier">P</span><span class="plain">);</span>
<span class="functiontext">Copies::set_content</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">STORE_POINTER_inform_language</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">));</span>
<span class="identifier">K</span><span class="plain">-</span><span class="element">&gt;as_copy</span><span class="plain"> = </span><span class="identifier">C</span><span class="plain">;</span>
<span class="identifier">Dictionaries::create</span><span class="plain">(</span><span class="identifier">language_copy_cache</span><span class="plain">, </span><span class="identifier">key</span><span class="plain">);</span>
<span class="identifier">Dictionaries::write_value</span><span class="plain">(</span><span class="identifier">language_copy_cache</span><span class="plain">, </span><span class="identifier">key</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">);</span>
@ -248,7 +249,7 @@ we need to <code class="display"><span class="extract">rsync</span></code> it.
<span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">dest_language</span><span class="plain"> = </span><span class="functiontext">LanguageManager::pathname_in_nest</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;edition</span><span class="plain">);</span>
<span class="identifier">filename</span><span class="plain"> *</span><span class="identifier">dest_language_metadata</span><span class="plain"> = </span><span class="identifier">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">dest_language</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"about.txt"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">TextFiles::exists</span><span class="plain">(</span><span class="identifier">dest_language_metadata</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">syncing</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) { </span><span class="functiontext">Nests::overwrite_error</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">syncing</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) { </span><span class="functiontext">Copies::overwrite_error</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">N</span><span class="plain">); </span><span class="reserved">return</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">meth</span><span class="plain">-</span><span class="element">&gt;methodology</span><span class="plain"> == </span><span class="constant">DRY_RUN_METHODOLOGY</span><span class="plain">) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">);</span>

View file

@ -105,7 +105,8 @@ which stores data about extensions used by the Inform compiler.
<span class="reserved">inform_project</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain"> = </span><span class="functiontext">Projects::new_ip</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">P</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">project_bundle_genre</span><span class="plain">, </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">), </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="reserved">inbuild_edition</span><span class="plain"> *</span><span class="identifier">edition</span><span class="plain"> = </span><span class="functiontext">Editions::new</span><span class="plain">(</span><span class="identifier">work</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">-</span><span class="element">&gt;version</span><span class="plain">);</span>
<span class="identifier">K</span><span class="plain">-</span><span class="element">&gt;as_copy</span><span class="plain"> = </span><span class="functiontext">Copies::new_in_path</span><span class="plain">(</span><span class="identifier">edition</span><span class="plain">, </span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">STORE_POINTER_inform_project</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">));</span>
<span class="identifier">K</span><span class="plain">-</span><span class="element">&gt;as_copy</span><span class="plain"> = </span><span class="functiontext">Copies::new_in_path</span><span class="plain">(</span><span class="identifier">edition</span><span class="plain">, </span><span class="identifier">P</span><span class="plain">);</span>
<span class="functiontext">Copies::set_content</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">-</span><span class="element">&gt;as_copy</span><span class="plain">, </span><span class="identifier">STORE_POINTER_inform_project</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">));</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">-</span><span class="element">&gt;as_copy</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>

View file

@ -105,7 +105,8 @@ which stores data about extensions used by the Inform compiler.
<span class="reserved">inform_project</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain"> = </span><span class="functiontext">Projects::new_ip</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">, </span><span class="identifier">F</span><span class="plain">, </span><span class="identifier">NULL</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">project_file_genre</span><span class="plain">, </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">), </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="reserved">inbuild_edition</span><span class="plain"> *</span><span class="identifier">edition</span><span class="plain"> = </span><span class="functiontext">Editions::new</span><span class="plain">(</span><span class="identifier">work</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">-</span><span class="element">&gt;version</span><span class="plain">);</span>
<span class="identifier">K</span><span class="plain">-</span><span class="element">&gt;as_copy</span><span class="plain"> = </span><span class="functiontext">Copies::new_in_file</span><span class="plain">(</span><span class="identifier">edition</span><span class="plain">, </span><span class="identifier">F</span><span class="plain">, </span><span class="identifier">STORE_POINTER_inform_project</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">));</span>
<span class="identifier">K</span><span class="plain">-</span><span class="element">&gt;as_copy</span><span class="plain"> = </span><span class="functiontext">Copies::new_in_file</span><span class="plain">(</span><span class="identifier">edition</span><span class="plain">, </span><span class="identifier">F</span><span class="plain">);</span>
<span class="functiontext">Copies::set_content</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">-</span><span class="element">&gt;as_copy</span><span class="plain">, </span><span class="identifier">STORE_POINTER_inform_project</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">));</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">-</span><span class="element">&gt;as_copy</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>

View file

@ -123,7 +123,8 @@ which stores data about pipelines used by the Inform compiler.
<span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="functiontext">PipelineManager::new_copy</span><span class="plain">(</span><span class="reserved">inbuild_edition</span><span class="plain"> *</span><span class="identifier">edition</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="reserved">inform_pipeline</span><span class="plain"> *</span><span class="identifier">E</span><span class="plain"> = </span><span class="functiontext">Pipelines::new_ip</span><span class="plain">(</span><span class="identifier">edition</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">-</span><span class="element">&gt;title</span><span class="plain">, </span><span class="identifier">F</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="functiontext">Copies::new_in_file</span><span class="plain">(</span><span class="identifier">edition</span><span class="plain">, </span><span class="identifier">F</span><span class="plain">, </span><span class="identifier">STORE_POINTER_inform_pipeline</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">C</span><span class="plain"> = </span><span class="functiontext">Copies::new_in_file</span><span class="plain">(</span><span class="identifier">edition</span><span class="plain">, </span><span class="identifier">F</span><span class="plain">);</span>
<span class="functiontext">Copies::set_content</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">STORE_POINTER_inform_pipeline</span><span class="plain">(</span><span class="identifier">E</span><span class="plain">));</span>
<span class="identifier">E</span><span class="plain">-</span><span class="element">&gt;as_copy</span><span class="plain"> = </span><span class="identifier">C</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">C</span><span class="plain">;</span>
<span class="plain">}</span>
@ -228,7 +229,7 @@ since a pipeline is a single file; to sync, we just overwrite.
<span class="identifier">filename</span><span class="plain"> *</span><span class="identifier">F</span><span class="plain"> = </span><span class="functiontext">PipelineManager::filename_in_nest</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;edition</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">TextFiles::exists</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">syncing</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) { </span><span class="functiontext">Nests::overwrite_error</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">syncing</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) { </span><span class="functiontext">Copies::overwrite_error</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">N</span><span class="plain">); </span><span class="reserved">return</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">meth</span><span class="plain">-</span><span class="element">&gt;methodology</span><span class="plain"> == </span><span class="constant">DRY_RUN_METHODOLOGY</span><span class="plain">) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">);</span>

View file

@ -117,7 +117,8 @@ which stores data about extensions used by the Inform compiler.
<span class="reserved">inform_template</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain"> = </span><span class="functiontext">Templates::new_it</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">, </span><span class="identifier">P</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">template_genre</span><span class="plain">, </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">), </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="reserved">inbuild_edition</span><span class="plain"> *</span><span class="identifier">edition</span><span class="plain"> = </span><span class="functiontext">Editions::new</span><span class="plain">(</span><span class="identifier">work</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">-</span><span class="element">&gt;version</span><span class="plain">);</span>
<span class="identifier">K</span><span class="plain">-</span><span class="element">&gt;as_copy</span><span class="plain"> = </span><span class="functiontext">Copies::new_in_path</span><span class="plain">(</span><span class="identifier">edition</span><span class="plain">, </span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">STORE_POINTER_inform_template</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">));</span>
<span class="identifier">K</span><span class="plain">-</span><span class="element">&gt;as_copy</span><span class="plain"> = </span><span class="functiontext">Copies::new_in_path</span><span class="plain">(</span><span class="identifier">edition</span><span class="plain">, </span><span class="identifier">P</span><span class="plain">);</span>
<span class="functiontext">Copies::set_content</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">-</span><span class="element">&gt;as_copy</span><span class="plain">, </span><span class="identifier">STORE_POINTER_inform_template</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">));</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">-</span><span class="element">&gt;as_copy</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
@ -220,7 +221,7 @@ a folder, we need to <code class="display"><span class="extract">rsync</span></c
<span class="identifier">filename</span><span class="plain"> *</span><span class="identifier">canary1</span><span class="plain"> = </span><span class="identifier">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"(manifest).txt"</span><span class="plain">);</span>
<span class="identifier">filename</span><span class="plain"> *</span><span class="identifier">canary2</span><span class="plain"> = </span><span class="identifier">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"index.html"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">TextFiles::exists</span><span class="plain">(</span><span class="identifier">canary1</span><span class="plain">)) || (</span><span class="identifier">TextFiles::exists</span><span class="plain">(</span><span class="identifier">canary2</span><span class="plain">))) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">syncing</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) { </span><span class="functiontext">Nests::overwrite_error</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">syncing</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) { </span><span class="functiontext">Copies::overwrite_error</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">N</span><span class="plain">); </span><span class="reserved">return</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">meth</span><span class="plain">-</span><span class="element">&gt;methodology</span><span class="plain"> == </span><span class="constant">DRY_RUN_METHODOLOGY</span><span class="plain">) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">);</span>

View file

@ -275,7 +275,7 @@ invisible unless the user scrolls a long way:
<span class="identifier">HTML_OPEN</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">);</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&lt;b&gt;%X&lt;/b&gt; - "</span><span class="plain">, </span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;copy</span><span class="plain">-</span><span class="element">&gt;edition</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">);</span>
<span class="functiontext">Copies::write_problem</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">CE</span><span class="plain">);</span>
<span class="functiontext">CopyErrors::write</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">CE</span><span class="plain">);</span>
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>

View file

@ -233,7 +233,7 @@ calls.
<span class="identifier">Feeds::feed_text</span><span class="plain">(</span><span class="identifier">L</span><span class="string">"This sentence provides a firebreak, no more. "</span><span class="plain">);</span>
<span class="identifier">E</span><span class="plain"> = </span><span class="functiontext">Extensions::Documentation::load</span><span class="plain">(</span><span class="identifier">work</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="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> 0; </span> <span class="comment">shouldn't happen: it was there only moments ago</span>
<span class="functiontext">Copies::read_source_text_for</span><span class="plain">(</span><span class="identifier">E</span><span class="plain">-</span><span class="element">&gt;as_copy</span><span class="plain">);</span>
<span class="functiontext">Copies::get_source_text</span><span class="plain">(</span><span class="identifier">E</span><span class="plain">-</span><span class="element">&gt;as_copy</span><span class="plain">);</span>
<span class="functiontext">Extensions::Documentation::write_extension_documentation</span><span class="plain">(</span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">E</span><span class="plain">, </span><span class="identifier">census_mode</span><span class="plain">);</span>
</pre>

View file

@ -106,10 +106,10 @@
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">claimed_title</span><span class="plain">) == 0) { </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">claimed_title</span><span class="plain">, </span><span class="string">"Unknown"</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">claimed_author_name</span><span class="plain">) == 0) { </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">claimed_author_name</span><span class="plain">, </span><span class="string">"Anonymous"</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">claimed_title</span><span class="plain">) &gt; </span><span class="constant">MAX_EXTENSION_TITLE_LENGTH</span><span class="plain">) {</span>
<span class="functiontext">Copies::attach</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="functiontext">Copies::new_error_N</span><span class="plain">(</span><span class="constant">EXT_TITLE_TOO_LONG_CE</span><span class="plain">, </span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">claimed_title</span><span class="plain">)));</span>
<span class="functiontext">Copies::attach_error</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="functiontext">CopyErrors::new_N</span><span class="plain">(</span><span class="constant">EXT_TITLE_TOO_LONG_CE</span><span class="plain">, -1, </span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">claimed_title</span><span class="plain">)));</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">claimed_author_name</span><span class="plain">) &gt; </span><span class="constant">MAX_EXTENSION_AUTHOR_LENGTH</span><span class="plain">) {</span>
<span class="functiontext">Copies::attach</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="functiontext">Copies::new_error_N</span><span class="plain">(</span><span class="constant">EXT_AUTHOR_TOO_LONG_CE</span><span class="plain">, </span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">claimed_author_name</span><span class="plain">)));</span>
<span class="functiontext">Copies::attach_error</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="functiontext">CopyErrors::new_N</span><span class="plain">(</span><span class="constant">EXT_AUTHOR_TOO_LONG_CE</span><span class="plain">, -1, </span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">claimed_author_name</span><span class="plain">)));</span>
<span class="plain">}</span>
<span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;edition</span><span class="plain"> = </span><span class="functiontext">Editions::new</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">claimed_title</span><span class="plain">, </span><span class="identifier">claimed_author_name</span><span class="plain">), </span><span class="identifier">V</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">reqs</span><span class="plain">) &gt; 0) {</span>
@ -118,7 +118,7 @@
<span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">err</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">err</span><span class="plain">, </span><span class="string">"cannot read compatibility '%S'"</span><span class="plain">, </span><span class="identifier">reqs</span><span class="plain">);</span>
<span class="functiontext">Copies::attach</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="functiontext">Copies::new_error</span><span class="plain">(</span><span class="constant">EXT_MISWORDED_CE</span><span class="plain">, </span><span class="identifier">err</span><span class="plain">));</span>
<span class="functiontext">Copies::attach_error</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="functiontext">CopyErrors::new_T</span><span class="plain">(</span><span class="constant">EXT_MISWORDED_CE</span><span class="plain">, -1, </span><span class="identifier">err</span><span class="plain">));</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">err</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
@ -151,7 +151,7 @@ alone, and the version number is returned.
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">version_text</span><span class="plain">);</span>
<span class="reserved">FILE</span><span class="plain"> *</span><span class="identifier">EXTF</span><span class="plain"> = </span><span class="identifier">Filenames::fopen_caseless</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="reserved">if</span><span class="plain"> (</span><span class="identifier">EXTF</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
<span class="functiontext">Copies::attach</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="functiontext">Copies::new_error_on_file</span><span class="plain">(</span><span class="constant">OPEN_FAILED_CE</span><span class="plain">, </span><span class="identifier">F</span><span class="plain">));</span>
<span class="functiontext">Copies::attach_error</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="functiontext">CopyErrors::new_F</span><span class="plain">(</span><span class="constant">OPEN_FAILED_CE</span><span class="plain">, -1, </span><span class="identifier">F</span><span class="plain">));</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
&lt;<span class="cwebmacro">Read the titling line of the extension and normalise its casing</span> <span class="cwebmacronumber">1.1.1</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Read the rubric text, if any is present</span> <span class="cwebmacronumber">1.1.2</span>&gt;<span class="plain">;</span>
@ -162,7 +162,7 @@ alone, and the version number is returned.
<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">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">error_text</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">error_text</span><span class="plain">, </span><span class="string">"the version number '%S' is malformed"</span><span class="plain">, </span><span class="identifier">version_text</span><span class="plain">);</span>
<span class="functiontext">Copies::attach</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="functiontext">Copies::new_error</span><span class="plain">(</span><span class="constant">EXT_MISWORDED_CE</span><span class="plain">, </span><span class="identifier">error_text</span><span class="plain">));</span>
<span class="functiontext">Copies::attach_error</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="functiontext">CopyErrors::new_T</span><span class="plain">(</span><span class="constant">EXT_MISWORDED_CE</span><span class="plain">, -1, </span><span class="identifier">error_text</span><span class="plain">));</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">error_text</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
@ -262,7 +262,7 @@ load the entire file.
<span class="plain">(</span><span class="identifier">Regexp::match</span><span class="plain">(&amp;</span><span class="identifier">mr</span><span class="plain">, </span><span class="identifier">titling_line</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"(%c*) Starts Here"</span><span class="plain">))) {</span>
<span class="identifier">Str::copy</span><span class="plain">(</span><span class="identifier">titling_line</span><span class="plain">, </span><span class="identifier">mr</span><span class="plain">.</span><span class="identifier">exp</span><span class="plain">[0]);</span>
<span class="plain">}</span>
<span class="functiontext">Copies::attach</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="functiontext">Copies::new_error</span><span class="plain">(</span><span class="constant">EXT_MISWORDED_CE</span><span class="plain">,</span>
<span class="functiontext">Copies::attach_error</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="functiontext">CopyErrors::new_T</span><span class="plain">(</span><span class="constant">EXT_MISWORDED_CE</span><span class="plain">, -1,</span>
<span class="identifier">I</span><span class="string">"the opening line does not end 'begin(s) here'"</span><span class="plain">));</span>
<span class="plain">}</span>
&lt;<span class="cwebmacro">Scan the version text, if any, and advance to the position past Version... Of</span> <span class="cwebmacronumber">1.1.3.1</span>&gt;<span class="plain">;</span>
@ -316,7 +316,7 @@ not a situation we need to contend with.
<span class="identifier">Str::copy</span><span class="plain">(</span><span class="identifier">claimed_author_name</span><span class="plain">, </span><span class="identifier">mr</span><span class="plain">.</span><span class="identifier">exp</span><span class="plain">[1]);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Str::copy</span><span class="plain">(</span><span class="identifier">claimed_title</span><span class="plain">, </span><span class="identifier">titling_line</span><span class="plain">);</span>
<span class="functiontext">Copies::attach</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="functiontext">Copies::new_error</span><span class="plain">(</span><span class="constant">EXT_MISWORDED_CE</span><span class="plain">,</span>
<span class="functiontext">Copies::attach_error</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="functiontext">CopyErrors::new_T</span><span class="plain">(</span><span class="constant">EXT_MISWORDED_CE</span><span class="plain">, -1,</span>
<span class="identifier">I</span><span class="string">"the titling line does not give both author and title"</span><span class="plain">));</span>
<span class="plain">}</span>
</pre>

View file

@ -131,7 +131,7 @@
<span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">err</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">err</span><span class="plain">, </span><span class="string">"cannot read compatibility '%S'"</span><span class="plain">, </span><span class="identifier">mr</span><span class="plain">.</span><span class="identifier">exp</span><span class="plain">[0]);</span>
<span class="functiontext">Copies::attach</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="functiontext">Copies::new_error</span><span class="plain">(</span><span class="constant">KIT_MISWORDED_CE</span><span class="plain">, </span><span class="identifier">err</span><span class="plain">));</span>
<span class="functiontext">Copies::attach_error</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="functiontext">CopyErrors::new_T</span><span class="plain">(</span><span class="constant">KIT_MISWORDED_CE</span><span class="plain">, -1, </span><span class="identifier">err</span><span class="plain">));</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">err</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">Regexp::match</span><span class="plain">(&amp;</span><span class="identifier">mr</span><span class="plain">, </span><span class="identifier">text</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"defines Main: yes"</span><span class="plain">)) {</span>
@ -166,7 +166,7 @@
<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">err</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">err</span><span class="plain">, </span><span class="string">"unreadable instruction '%S'"</span><span class="plain">, </span><span class="identifier">text</span><span class="plain">);</span>
<span class="functiontext">Copies::attach</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="functiontext">Copies::new_error</span><span class="plain">(</span><span class="constant">KIT_MISWORDED_CE</span><span class="plain">, </span><span class="identifier">err</span><span class="plain">));</span>
<span class="functiontext">Copies::attach_error</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="functiontext">CopyErrors::new_T</span><span class="plain">(</span><span class="constant">KIT_MISWORDED_CE</span><span class="plain">, -1, </span><span class="identifier">err</span><span class="plain">));</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">err</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">Regexp::dispose_of</span><span class="plain">(&amp;</span><span class="identifier">mr</span><span class="plain">);</span>
@ -175,7 +175,7 @@
<span class="reserved">inform_kit</span><span class="plain"> *</span><span class="functiontext">Kits::load</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">name</span><span class="plain">, </span><span class="identifier">linked_list</span><span class="plain"> *</span><span class="identifier">nest_list</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::any_version_of</span><span class="plain">(</span><span class="functiontext">Works::new</span><span class="plain">(</span><span class="identifier">kit_genre</span><span class="plain">, </span><span class="identifier">name</span><span class="plain">, </span><span class="identifier">I</span><span class="string">""</span><span class="plain">));</span>
<span class="reserved">inbuild_search_result</span><span class="plain"> *</span><span class="identifier">R</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="identifier">nest_list</span><span class="plain">);</span>
<span class="reserved">inbuild_search_result</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain"> = </span><span class="functiontext">Nests::search_for_best</span><span class="plain">(</span><span class="identifier">req</span><span class="plain">, </span><span class="identifier">nest_list</span><span class="plain">);</span>
<span class="reserved">if</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="identifier">Errors::fatal_with_text</span><span class="plain">(</span><span class="string">"cannot find kit"</span><span class="plain">, </span><span class="identifier">name</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">R</span><span class="plain">-</span><span class="element">&gt;copy</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;vertex</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="functiontext">KitManager::build_vertex</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">);</span>

View file

@ -269,7 +269,7 @@ insensitively.
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">I</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_nest</span><span class="plain">);</span>
<span class="identifier">ADD_TO_LINKED_LIST</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">, </span><span class="reserved">inbuild_nest</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">);</span>
<span class="reserved">inbuild_search_result</span><span class="plain"> *</span><span class="identifier">R</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="identifier">L</span><span class="plain">);</span>
<span class="reserved">inbuild_search_result</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain"> = </span><span class="functiontext">Nests::search_for_best</span><span class="plain">(</span><span class="identifier">req</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">R</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="functiontext">LanguageManager::from_copy</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;copy</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>

View file

@ -552,7 +552,7 @@ may be multiple sentences, which we need to count up.
<span class="functiontext">Headings::satisfy_dependencies</span><span class="plain">(</span><span class="identifier">project</span><span class="plain">-</span><span class="element">&gt;syntax_tree</span><span class="plain">, </span><span class="identifier">project</span><span class="plain">-</span><span class="element">&gt;as_copy</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">project</span><span class="plain">-</span><span class="element">&gt;as_copy</span><span class="plain">);</span>
<span class="functiontext">Copies::list_attached_errors</span><span class="plain">(</span><span class="identifier">STDERR</span><span class="plain">, </span><span class="identifier">project</span><span class="plain">-</span><span class="element">&gt;as_copy</span><span class="plain">);</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="plain">}</span>
</pre>
@ -589,10 +589,9 @@ it happens during the call to <code class="display"><span class="extract">Senten
&lt;<span class="cwebmacro">Extract title and author name wording</span> <span class="cwebmacronumber">6.2</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Dequote the title and, perhaps, author name</span> <span class="cwebmacronumber">6.3</span>&gt;<span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</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">&gt;error_subcategory</span><span class="plain"> = </span><span class="constant">BadTitleSentence_SYNERROR</span><span class="plain">;</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details_node</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">project</span><span class="plain">-</span><span class="element">&gt;as_copy</span><span class="plain">, </span><span class="identifier">CE</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">CopyErrors::new</span><span class="plain">(</span><span class="constant">SYNTAX_CE</span><span class="plain">, </span><span class="constant">BadTitleSentence_SYNERROR</span><span class="plain">);</span>
<span class="functiontext">CopyErrors::supply_node</span><span class="plain">(</span><span class="identifier">CE</span><span class="plain">, </span><span class="identifier">PN</span><span class="plain">);</span>
<span class="functiontext">Copies::attach_error</span><span class="plain">(</span><span class="identifier">project</span><span class="plain">-</span><span class="element">&gt;as_copy</span><span class="plain">, </span><span class="identifier">CE</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>

View file

@ -520,10 +520,9 @@ allowed; they should probably be withdrawn.
<pre class="displaydefn">
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">CORE_MODULE</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">&gt;error_subcategory</span><span class="plain"> = </span><span class="constant">UnknownLanguageElement_SYNERROR</span><span class="plain">;</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;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">sfsm_copy</span><span class="plain">, </span><span class="identifier">CE</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">CopyErrors::new</span><span class="plain">(</span><span class="constant">SYNTAX_CE</span><span class="plain">, </span><span class="constant">UnknownLanguageElement_SYNERROR</span><span class="plain">);</span>
<span class="functiontext">CopyErrors::supply_node</span><span class="plain">(</span><span class="identifier">CE</span><span class="plain">, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="functiontext">Copies::attach_error</span><span class="plain">(</span><span class="identifier">sfsm_copy</span><span class="plain">, </span><span class="identifier">CE</span><span class="plain">);</span>
<span class="plain">#</span><span class="identifier">endif</span>
</pre>
@ -537,10 +536,9 @@ allowed; they should probably be withdrawn.
<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">&gt;error_subcategory</span><span class="plain"> = </span><span class="constant">UnknownVirtualMachine_SYNERROR</span><span class="plain">;</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;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">sfsm_copy</span><span class="plain">, </span><span class="identifier">CE</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">CopyErrors::new</span><span class="plain">(</span><span class="constant">SYNTAX_CE</span><span class="plain">, </span><span class="constant">UnknownVirtualMachine_SYNERROR</span><span class="plain">);</span>
<span class="functiontext">CopyErrors::supply_node</span><span class="plain">(</span><span class="identifier">CE</span><span class="plain">, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="functiontext">Copies::attach_error</span><span class="plain">(</span><span class="identifier">sfsm_copy</span><span class="plain">, </span><span class="identifier">CE</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
@ -998,11 +996,10 @@ the parse tree on quite a large scale, and that's just what we do.
<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">&gt;error_subcategory</span><span class="plain"> = </span><span class="constant">HeadingInPlaceOfUnincluded_SYNERROR</span><span class="plain">;</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details_node</span><span class="plain"> = </span><span class="identifier">h</span><span class="plain">-</span><span class="element">&gt;sentence_declaring</span><span class="plain">;</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details_work</span><span class="plain"> = </span><span class="identifier">h</span><span class="plain">-</span><span class="element">&gt;for_use_with</span><span class="plain">;</span>
<span class="functiontext">Copies::attach</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">CE</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">CopyErrors::new</span><span class="plain">(</span><span class="constant">SYNTAX_CE</span><span class="plain">, </span><span class="constant">HeadingInPlaceOfUnincluded_SYNERROR</span><span class="plain">);</span>
<span class="functiontext">CopyErrors::supply_node</span><span class="plain">(</span><span class="identifier">CE</span><span class="plain">, </span><span class="identifier">h</span><span class="plain">-</span><span class="element">&gt;sentence_declaring</span><span class="plain">);</span>
<span class="functiontext">CopyErrors::supply_work</span><span class="plain">(</span><span class="identifier">CE</span><span class="plain">, </span><span class="identifier">h</span><span class="plain">-</span><span class="element">&gt;for_use_with</span><span class="plain">);</span>
<span class="functiontext">Copies::attach_error</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">CE</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
@ -1072,13 +1069,10 @@ elsewhere).
<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">&gt;error_subcategory</span><span class="plain"> = </span><span class="constant">HeadingInPlaceOfSubordinate_SYNERROR</span><span class="plain">;</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details_node</span><span class="plain"> = </span><span class="identifier">h2</span><span class="plain">-</span><span class="element">&gt;sentence_declaring</span><span class="plain">;</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details_work</span><span class="plain"> = </span><span class="identifier">h2</span><span class="plain">-</span><span class="element">&gt;for_use_with</span><span class="plain">;</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details_work2</span><span class="plain"> = </span><span class="identifier">h</span><span class="plain">-</span><span class="element">&gt;for_use_with</span><span class="plain">;</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details_node2</span><span class="plain"> = </span><span class="identifier">h</span><span class="plain">-</span><span class="element">&gt;sentence_declaring</span><span class="plain">;</span>
<span class="functiontext">Copies::attach</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">CE</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">CopyErrors::new</span><span class="plain">(</span><span class="constant">SYNTAX_CE</span><span class="plain">, </span><span class="constant">HeadingInPlaceOfSubordinate_SYNERROR</span><span class="plain">);</span>
<span class="functiontext">CopyErrors::supply_works</span><span class="plain">(</span><span class="identifier">CE</span><span class="plain">, </span><span class="identifier">h2</span><span class="plain">-</span><span class="element">&gt;for_use_with</span><span class="plain">, </span><span class="identifier">h</span><span class="plain">-</span><span class="element">&gt;for_use_with</span><span class="plain">);</span>
<span class="functiontext">CopyErrors::supply_nodes</span><span class="plain">(</span><span class="identifier">CE</span><span class="plain">, </span><span class="identifier">h2</span><span class="plain">-</span><span class="element">&gt;sentence_declaring</span><span class="plain">, </span><span class="identifier">h</span><span class="plain">-</span><span class="element">&gt;sentence_declaring</span><span class="plain">);</span>
<span class="functiontext">Copies::attach_error</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">CE</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
@ -1099,13 +1093,11 @@ elsewhere).
<span class="identifier">Str::clear</span><span class="plain">(</span><span class="identifier">vt</span><span class="plain">);</span>
<span class="identifier">VersionNumbers::to_text</span><span class="plain">(</span><span class="identifier">vt</span><span class="plain">, </span><span class="identifier">E</span><span class="plain">-</span><span class="element">&gt;as_copy</span><span class="plain">-</span><span class="element">&gt;edition</span><span class="plain">-</span><span class="element">&gt;version</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">&gt;error_subcategory</span><span class="plain"> = </span><span class="constant">HeadingInPlaceOfUnknown_SYNERROR</span><span class="plain">;</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details_node</span><span class="plain"> = </span><span class="identifier">h</span><span class="plain">-</span><span class="element">&gt;sentence_declaring</span><span class="plain">;</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details_work</span><span class="plain"> = </span><span class="identifier">h</span><span class="plain">-</span><span class="element">&gt;for_use_with</span><span class="plain">;</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details_W</span><span class="plain"> = </span><span class="identifier">h</span><span class="plain">-</span><span class="element">&gt;in_place_of_text</span><span class="plain">;</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">vt</span><span class="plain">);</span>
<span class="functiontext">Copies::attach</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">CE</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">CopyErrors::new_T</span><span class="plain">(</span><span class="constant">SYNTAX_CE</span><span class="plain">, </span><span class="constant">HeadingInPlaceOfUnknown_SYNERROR</span><span class="plain">, </span><span class="identifier">vt</span><span class="plain">);</span>
<span class="functiontext">CopyErrors::supply_node</span><span class="plain">(</span><span class="identifier">CE</span><span class="plain">, </span><span class="identifier">h</span><span class="plain">-</span><span class="element">&gt;sentence_declaring</span><span class="plain">);</span>
<span class="functiontext">CopyErrors::supply_work</span><span class="plain">(</span><span class="identifier">CE</span><span class="plain">, </span><span class="identifier">h</span><span class="plain">-</span><span class="element">&gt;for_use_with</span><span class="plain">);</span>
<span class="functiontext">CopyErrors::supply_wording</span><span class="plain">(</span><span class="identifier">CE</span><span class="plain">, </span><span class="identifier">h</span><span class="plain">-</span><span class="element">&gt;in_place_of_text</span><span class="plain">);</span>
<span class="functiontext">Copies::attach_error</span><span class="plain">(</span><span class="identifier">C</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">vt</span><span class="plain">);</span>
</pre>
@ -1119,10 +1111,9 @@ elsewhere).
<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">&gt;error_subcategory</span><span class="plain"> = </span><span class="constant">UnequalHeadingInPlaceOf_SYNERROR</span><span class="plain">;</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details_node</span><span class="plain"> = </span><span class="identifier">h</span><span class="plain">-</span><span class="element">&gt;sentence_declaring</span><span class="plain">;</span>
<span class="functiontext">Copies::attach</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">CE</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">CopyErrors::new</span><span class="plain">(</span><span class="constant">SYNTAX_CE</span><span class="plain">, </span><span class="constant">UnequalHeadingInPlaceOf_SYNERROR</span><span class="plain">);</span>
<span class="functiontext">CopyErrors::supply_node</span><span class="plain">(</span><span class="identifier">CE</span><span class="plain">, </span><span class="identifier">h</span><span class="plain">-</span><span class="element">&gt;sentence_declaring</span><span class="plain">);</span>
<span class="functiontext">Copies::attach_error</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">CE</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>

View file

@ -202,10 +202,9 @@ guaranteed to be no INCLUDE nodes remaining in the parse tree.
<pre class="displaydefn">
<span class="plain">&lt;&lt;</span><span class="identifier">t1</span><span class="plain">&gt;&gt; = -1; &lt;&lt;</span><span class="identifier">t2</span><span class="plain">&gt;&gt; = -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">&gt;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">&gt;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="reserved">copy_error</span><span class="plain"> *</span><span class="identifier">CE</span><span class="plain"> = </span><span class="functiontext">CopyErrors::new</span><span class="plain">(</span><span class="constant">SYNTAX_CE</span><span class="plain">, </span><span class="constant">IncludeExtQuoted_SYNERROR</span><span class="plain">);</span>
<span class="functiontext">CopyErrors::supply_node</span><span class="plain">(</span><span class="identifier">CE</span><span class="plain">, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="functiontext">Copies::attach_error</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>
@ -326,7 +325,7 @@ Sausages by Mr Punch, and loaded it, but then read the sentence
<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">inbuild_search_result</span><span class="plain"> *</span><span class="identifier">search_result</span><span class="plain"> = </span><span class="functiontext">Nests::search_for_best</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">&gt;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>
@ -337,10 +336,10 @@ Sausages by Mr Punch, and loaded it, but then read the sentence
&lt;<span class="cwebmacro">Issue a problem message saying that the VM does not meet requirements</span> <span class="cwebmacronumber">6.1.1</span>&gt;<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">&gt;copy</span><span class="plain">-</span><span class="element">&gt;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">&gt;copy</span><span class="plain">);</span>
<span class="functiontext">Copies::get_source_text</span><span class="plain">(</span><span class="identifier">search_result</span><span class="plain">-</span><span class="element">&gt;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">&gt;copy</span><span class="plain">);</span>
<span class="functiontext">Copies::list_attached_errors</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">&gt;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>
@ -369,11 +368,9 @@ report this problem at the inclusion line.
<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">&gt;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">&gt;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">&gt;details</span><span class="plain"> = </span><span class="identifier">C</span><span class="plain">-&gt;</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>
<span class="reserved">copy_error</span><span class="plain"> *</span><span class="identifier">CE</span><span class="plain"> = </span><span class="functiontext">CopyErrors::new_T</span><span class="plain">(</span><span class="constant">SYNTAX_CE</span><span class="plain">, </span><span class="constant">ExtInadequateVM_SYNERROR</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">-&gt;</span><span class="identifier">parsed_from</span><span class="plain">);</span>
<span class="functiontext">CopyErrors::supply_node</span><span class="plain">(</span><span class="identifier">CE</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="functiontext">Copies::attach_error</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>
@ -390,10 +387,9 @@ report this problem at the inclusion line.
<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">&gt;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">&gt;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="reserved">copy_error</span><span class="plain"> *</span><span class="identifier">CE</span><span class="plain"> = </span><span class="functiontext">CopyErrors::new</span><span class="plain">(</span><span class="constant">SYNTAX_CE</span><span class="plain">, </span><span class="constant">BogusExtension_SYNERROR</span><span class="plain">);</span>
<span class="functiontext">CopyErrors::supply_node</span><span class="plain">(</span><span class="identifier">CE</span><span class="plain">, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="functiontext">Copies::attach_error</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>
@ -403,11 +399,9 @@ report this problem at the inclusion line.
<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">, &amp;</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">&gt;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">&gt;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">&gt;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="reserved">copy_error</span><span class="plain"> *</span><span class="identifier">CE</span><span class="plain"> = </span><span class="functiontext">CopyErrors::new_T</span><span class="plain">(</span><span class="constant">SYNTAX_CE</span><span class="plain">, </span><span class="constant">ExtVersionTooLow_SYNERROR</span><span class="plain">, </span><span class="identifier">versions</span><span class="plain">);</span>
<span class="functiontext">CopyErrors::supply_node</span><span class="plain">(</span><span class="identifier">CE</span><span class="plain">, </span><span class="identifier">at</span><span class="plain">);</span>
<span class="functiontext">Copies::attach_error</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>
@ -454,10 +448,9 @@ version number text.
<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 &lt;%N&gt;\</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">&gt;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">&gt;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="reserved">copy_error</span><span class="plain"> *</span><span class="identifier">CE</span><span class="plain"> = </span><span class="functiontext">CopyErrors::new</span><span class="plain">(</span><span class="constant">SYNTAX_CE</span><span class="plain">, </span><span class="constant">ExtVersionMalformed_SYNERROR</span><span class="plain">);</span>
<span class="functiontext">CopyErrors::supply_node</span><span class="plain">(</span><span class="identifier">CE</span><span class="plain">, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="functiontext">Copies::attach_error</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>
@ -509,10 +502,9 @@ problem messages if it is malformed.
<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">&gt;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">&gt;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="reserved">copy_error</span><span class="plain"> *</span><span class="identifier">CE</span><span class="plain"> = </span><span class="functiontext">CopyErrors::new</span><span class="plain">(</span><span class="constant">SYNTAX_CE</span><span class="plain">, </span><span class="identifier">ExtNoBeginsHere_SYNERROR</span><span class="plain">);</span>
<span class="functiontext">CopyErrors::supply_node</span><span class="plain">(</span><span class="identifier">CE</span><span class="plain">, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="functiontext">Copies::attach_error</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>
@ -554,11 +546,10 @@ that the extension isn't the one he thinks it is.
<span class="reserved">if</span><span class="plain"> (&lt;</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">&gt;(</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">(&lt;</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">&gt;, 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">&gt;as_copy</span><span class="plain">-</span><span class="element">&gt;edition</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">-</span><span class="element">&gt;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) &amp;&amp; (</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">&gt;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">&gt;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">&gt;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="reserved">copy_error</span><span class="plain"> *</span><span class="identifier">CE</span><span class="plain"> = </span><span class="functiontext">CopyErrors::new</span><span class="plain">(</span><span class="constant">SYNTAX_CE</span><span class="plain">, </span><span class="constant">ExtMisidentifiedEnds_SYNERROR</span><span class="plain">);</span>
<span class="functiontext">CopyErrors::supply_node</span><span class="plain">(</span><span class="identifier">CE</span><span class="plain">, </span><span class="identifier">PN</span><span class="plain">);</span>
<span class="functiontext">CopyErrors::supply_wording</span><span class="plain">(</span><span class="identifier">CE</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_error</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>

View file

@ -83,7 +83,7 @@ from multiple files and indeed from elsewhere.
<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">F</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="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="functiontext">Copies::attach</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="functiontext">Copies::new_error_on_file</span><span class="plain">(</span><span class="constant">OPEN_FAILED_CE</span><span class="plain">, </span><span class="identifier">F</span><span class="plain">));</span>
<span class="functiontext">Copies::attach_error</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="functiontext">CopyErrors::new_F</span><span class="plain">(</span><span class="constant">OPEN_FAILED_CE</span><span class="plain">, -1, </span><span class="identifier">F</span><span class="plain">));</span>
<span class="plain">} </span><span class="reserved">else</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="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">CORE_MODULE</span>
@ -149,37 +149,10 @@ application.
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">SourceText::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">desc</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">if</span><span class="plain"> (</span><span class="identifier">err</span><span class="plain"> == </span><span class="identifier">MEMORY_OUT_LEXERERROR</span><span class="plain">)</span>
<span class="identifier">Errors::fatal</span><span class="plain">(</span><span class="string">"Out of memory: unable to create lexer workspace"</span><span class="plain">);</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">erm</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">STRING_TOO_LONG_LEXERERROR</span><span class="plain">:</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">erm</span><span class="plain">, </span><span class="string">"Too much text in quotation marks: %w"</span><span class="plain">, </span><span class="identifier">word</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">WRITE_TO</span><span class="plain">(</span><span class="identifier">erm</span><span class="plain">, </span><span class="string">"Word too long: %w"</span><span class="plain">, </span><span class="identifier">word</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">WRITE_TO</span><span class="plain">(</span><span class="identifier">erm</span><span class="plain">, </span><span class="string">"I6 inclusion too long: %w"</span><span class="plain">, </span><span class="identifier">word</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">WRITE_TO</span><span class="plain">(</span><span class="identifier">erm</span><span class="plain">, </span><span class="string">"Quoted text never ends: %S"</span><span class="plain">, </span><span class="identifier">desc</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">WRITE_TO</span><span class="plain">(</span><span class="identifier">erm</span><span class="plain">, </span><span class="string">"Square-bracketed text never ends: %S"</span><span class="plain">, </span><span class="identifier">desc</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">WRITE_TO</span><span class="plain">(</span><span class="identifier">erm</span><span class="plain">, </span><span class="string">"I6 inclusion text never ends: %S"</span><span class="plain">, </span><span class="identifier">desc</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="reserved">if</span><span class="plain"> (</span><span class="identifier">currently_lexing_into</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">LEXER_CE</span><span class="plain">, </span><span class="identifier">erm</span><span class="plain">);</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;error_subcategory</span><span class="plain"> = </span><span class="identifier">err</span><span class="plain">;</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">desc</span><span class="plain">);</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;word</span><span class="plain"> = </span><span class="identifier">word</span><span class="plain">;</span>
<span class="functiontext">Copies::attach</span><span class="plain">(</span><span class="identifier">currently_lexing_into</span><span class="plain">, </span><span class="identifier">CE</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">CopyErrors::new_WT</span><span class="plain">(</span><span class="constant">LEXER_CE</span><span class="plain">, </span><span class="identifier">err</span><span class="plain">, </span><span class="identifier">word</span><span class="plain">, </span><span class="identifier">desc</span><span class="plain">);</span>
<span class="functiontext">Copies::attach_error</span><span class="plain">(</span><span class="identifier">currently_lexing_into</span><span class="plain">, </span><span class="identifier">CE</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">erm</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
@ -203,11 +176,9 @@ application.
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">SourceText::syntax_problem_handler</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">err_no</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">void</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">k</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="reserved">inbuild_copy</span><span class="plain"> *) </span><span class="identifier">ref</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">&gt;error_subcategory</span><span class="plain"> = </span><span class="identifier">err_no</span><span class="plain">;</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details_W</span><span class="plain"> = </span><span class="identifier">W</span><span class="plain">;</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details_N</span><span class="plain"> = </span><span class="identifier">k</span><span class="plain">;</span>
<span class="functiontext">Copies::attach</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">CE</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">CopyErrors::new_N</span><span class="plain">(</span><span class="constant">SYNTAX_CE</span><span class="plain">, </span><span class="identifier">err_no</span><span class="plain">, </span><span class="identifier">k</span><span class="plain">);</span>
<span class="functiontext">CopyErrors::supply_wording</span><span class="plain">(</span><span class="identifier">CE</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
<span class="functiontext">Copies::attach_error</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">CE</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
@ -475,10 +446,9 @@ saved up to be parsed later, so we will use the following:
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">SourceText::new_language</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">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">&gt;error_subcategory</span><span class="plain"> = </span><span class="constant">UseElementWithdrawn_SYNERROR</span><span class="plain">;</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;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">sfsm_copy</span><span class="plain">, </span><span class="identifier">CE</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">CopyErrors::new</span><span class="plain">(</span><span class="constant">SYNTAX_CE</span><span class="plain">, </span><span class="constant">UseElementWithdrawn_SYNERROR</span><span class="plain">);</span>
<span class="functiontext">CopyErrors::supply_node</span><span class="plain">(</span><span class="identifier">CE</span><span class="plain">, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="functiontext">Copies::attach_error</span><span class="plain">(</span><span class="identifier">sfsm_copy</span><span class="plain">, </span><span class="identifier">CE</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>

View file

@ -86,12 +86,16 @@
</li>
<li>
<p><a href="2-edt.html"><spon class="sectiontitle">Editions</span></a> -
<span class="purpose">An edition is numbered version of a work.</span></p>
<span class="purpose">An edition is a numbered version of a work.</span></p>
</li>
<li>
<p><a href="2-cps.html"><spon class="sectiontitle">Copies</span></a> -
<span class="purpose">A copy is an instance in the file system of a specific edition of a work.</span></p>
</li>
<li>
<p><a href="2-ce.html"><spon class="sectiontitle">Copy Errors</span></a> -
<span class="purpose">A copy error is attached to a copy when scanning it reveals some malformation.</span></p>
</li>
<li>
<p><a href="2-rqr.html"><spon class="sectiontitle">Requirements</span></a> -
<span class="purpose">A requirement is a way to specify some subset of works: for example, those with a given title, and/or version number.</span></p>

View file

@ -245,8 +245,8 @@ utility functions in the <code class="display"><span class="extract">inbuild</sp
<span class="reserved">case</span><span class="plain"> </span><span class="constant">BUILD_MISSING_TTASK</span><span class="plain">: </span><span class="functiontext">Copies::show_missing</span><span class="plain">(</span><span class="constant">STDOUT</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">, </span><span class="constant">FALSE</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="constant">BUILD_TTASK</span><span class="plain">: </span><span class="functiontext">Copies::build</span><span class="plain">(</span><span class="constant">STDOUT</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">BM</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="constant">REBUILD_TTASK</span><span class="plain">: </span><span class="functiontext">Copies::rebuild</span><span class="plain">(</span><span class="constant">STDOUT</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">BM</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="constant">COPY_TO_TTASK</span><span class="plain">: </span><span class="functiontext">Nests::copy_to</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">destination_nest</span><span class="plain">, </span><span class="constant">FALSE</span><span class="plain">, </span><span class="identifier">BM</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="constant">SYNC_TO_TTASK</span><span class="plain">: </span><span class="functiontext">Nests::copy_to</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">destination_nest</span><span class="plain">, </span><span class="constant">TRUE</span><span class="plain">, </span><span class="identifier">BM</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="constant">COPY_TO_TTASK</span><span class="plain">: </span><span class="functiontext">Copies::copy_to</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">destination_nest</span><span class="plain">, </span><span class="constant">FALSE</span><span class="plain">, </span><span class="identifier">BM</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="constant">SYNC_TO_TTASK</span><span class="plain">: </span><span class="functiontext">Copies::copy_to</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">destination_nest</span><span class="plain">, </span><span class="constant">TRUE</span><span class="plain">, </span><span class="identifier">BM</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
@ -349,7 +349,27 @@ Inbuild this number is never likely to be more than about 100 at a time.
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Main::add_file_or_path_as_target</span><span class="plain">(</span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">arg</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">throwing_error</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="functiontext">Copies::claim</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">);</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">ext</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">pos</span><span class="plain"> = </span><span class="functiontext">Str::len</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">) - 1, </span><span class="identifier">dotpos</span><span class="plain"> = -1;</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">pos</span><span class="plain"> &gt;= 0) {</span>
<span class="identifier">wchar_t</span><span class="plain"> </span><span class="identifier">c</span><span class="plain"> = </span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">, </span><span class="identifier">pos</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">c</span><span class="plain"> == </span><span class="constant">FOLDER_SEPARATOR</span><span class="plain">) </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">c</span><span class="plain"> == </span><span class="character">'.'</span><span class="plain">) </span><span class="identifier">dotpos</span><span class="plain"> = </span><span class="identifier">pos</span><span class="plain">;</span>
<span class="identifier">pos</span><span class="plain">--;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">dotpos</span><span class="plain"> &gt;= 0)</span>
<span class="functiontext">Str::substr</span><span class="plain">(</span><span class="identifier">ext</span><span class="plain">, </span><span class="functiontext">Str::at</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">, </span><span class="identifier">dotpos</span><span class="plain">+1), </span><span class="functiontext">Str::end</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">));</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">directory_status</span><span class="plain"> = </span><span class="constant">NOT_APPLICABLE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Str::get_last_char</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">) == </span><span class="constant">FOLDER_SEPARATOR</span><span class="plain">) {</span>
<span class="functiontext">Str::delete_last_character</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">);</span>
<span class="identifier">directory_status</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">;</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">NULL</span><span class="plain">;</span>
<span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">G</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">G</span><span class="plain">, </span><span class="reserved">inbuild_genre</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">C</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)</span>
<span class="identifier">VMETHOD_CALL</span><span class="plain">(</span><span class="identifier">G</span><span class="plain">, </span><span class="constant">GENRE_CLAIM_AS_COPY_MTID</span><span class="plain">, &amp;</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">arg</span><span class="plain">, </span><span class="identifier">ext</span><span class="plain">, </span><span class="identifier">directory_status</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">ext</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">C</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">throwing_error</span><span class="plain">) </span><span class="functiontext">Errors::with_text</span><span class="plain">(</span><span class="string">"unable to identify '%S'"</span><span class="plain">, </span><span class="identifier">arg</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>

View file

@ -526,7 +526,7 @@ and minimum version number, use <code class="display"><span class="extract">max<
<pre class="display">
<span class="plain">-matching 'genre=extension,author=Emily Short,title=Locksmith,min=6.1-alpha.2,max=17.2</span>
<span class="plain">-matching 'genre=extension,author=Emily Short,title=Locksmith,min=6.1-alpha.2,max=17.2'</span>
</pre>
<p class="inwebparagraph"></p>

View file

@ -133,8 +133,8 @@ utility functions in the |inbuild| module, which we call.
case BUILD_MISSING_TTASK: Copies::show_missing(STDOUT, C, FALSE); break;
case BUILD_TTASK: Copies::build(STDOUT, C, BM); break;
case REBUILD_TTASK: Copies::rebuild(STDOUT, C, BM); break;
case COPY_TO_TTASK: Nests::copy_to(C, destination_nest, FALSE, BM); break;
case SYNC_TO_TTASK: Nests::copy_to(C, destination_nest, TRUE, BM); break;
case COPY_TO_TTASK: Copies::copy_to(C, destination_nest, FALSE, BM); break;
case SYNC_TO_TTASK: Copies::copy_to(C, destination_nest, TRUE, BM); break;
}
@<Shut down the modules@> =
@ -214,7 +214,27 @@ void Main::add_directory_contents_targets(pathname *P) {
}
void Main::add_file_or_path_as_target(text_stream *arg, int throwing_error) {
inbuild_copy *C = Copies::claim(arg);
TEMPORARY_TEXT(ext);
int pos = Str::len(arg) - 1, dotpos = -1;
while (pos >= 0) {
wchar_t c = Str::get_at(arg, pos);
if (c == FOLDER_SEPARATOR) break;
if (c == '.') dotpos = pos;
pos--;
}
if (dotpos >= 0)
Str::substr(ext, Str::at(arg, dotpos+1), Str::end(arg));
int directory_status = NOT_APPLICABLE;
if (Str::get_last_char(arg) == FOLDER_SEPARATOR) {
Str::delete_last_character(arg);
directory_status = TRUE;
}
inbuild_copy *C = NULL;
inbuild_genre *G;
LOOP_OVER(G, inbuild_genre)
if (C == NULL)
VMETHOD_CALL(G, GENRE_CLAIM_AS_COPY_MTID, &C, arg, ext, directory_status);
DISCARD_TEXT(ext);
if (C == NULL) {
if (throwing_error) Errors::with_text("unable to identify '%S'", arg);
return;

View file

@ -317,7 +317,7 @@ would match version numbers 5.1.1, 5.1.2, 5.2.0, etc., but not 6 or above:
again, this is following semver conventions. To specify an explicit maximum
and minimum version number, use |max| and |min|. For example:
|-matching 'genre=extension,author=Emily Short,title=Locksmith,min=6.1-alpha.2,max=17.2|
|-matching 'genre=extension,author=Emily Short,title=Locksmith,min=6.1-alpha.2,max=17.2'|
@h Nests and searches.
When searching with |-matching R|, or indeed when running Inform and needing

View file

@ -302,7 +302,7 @@ inbuild_copy *Inbuild::optioneering_complete(inbuild_copy *C, int compile_only,
if (project) {
Inbuild::pass_kit_requests();
Copies::read_source_text_for(project->as_copy);
Copies::get_source_text(project->as_copy);
}
inbuild_phase = PROJECTED_INBUILD_PHASE;
@ -411,21 +411,6 @@ used by applications, so |-transient| can be used to divert these.
Materials folder. For example, in |Jane Eyre.inform| is a project, then
alongside it is |Jane Eyre.materials| and this is a nest.
Nests used by the Inform and Inbuild tools are tagged with the following
comstamts, except that no nest is ever tagged |NOT_A_NEST_TAG|.
(There used to be quite a good joke here, but refactoring of the
code removed its premiss. Literate programming is like that sometimes.)
The sequence of the following enumerated values is significant: lower
origins are better than later ones, when choosing the best result of
a search for resources.
@e NOT_A_NEST_TAG from 0
@e MATERIALS_NEST_TAG
@e EXTERNAL_NEST_TAG
@e GENERIC_NEST_TAG
@e INTERNAL_NEST_TAG
@ Inform customarily has exactly one |-internal| and one |-external| nest,
but in fact any number of each are allowed, including none. However, the
first to be declared are used by the compiler as "the" internal and external

View file

@ -2,67 +2,155 @@
A copy is an instance in the file system of a specific edition of a work.
@h Copies.
@h Creation.
A "copy" of a work exists in the file system when we've actually got hold of
some edition of it. For some genres, copies will be files; for others,
directories holding a set of files.
A purist view would be that a copy is simply an edition at a location in the
file system. And so it is. But copies are the main things Inbuild works on,
and we will need to generate data about them, some of which is most usefully
stored here.
=
typedef struct inbuild_copy {
struct inbuild_edition *edition;
struct pathname *location_if_path;
struct inbuild_edition *edition; /* what is this a copy of? */
struct pathname *location_if_path; /* exactly one of these must be non-|NULL| */
struct filename *location_if_file;
general_pointer content; /* the type of which depends on the work's genre */
struct build_vertex *vertex;
int source_text_read;
struct wording source_text;
struct linked_list *errors_reading_source_text;
struct inbuild_requirement *found_by;
struct build_vertex *vertex; /* head vertex of build graph for this copy */
int source_text_read; /* have we attempted to read Inform source text from this? */
struct wording source_text; /* the source text we read, if so */
struct inbuild_requirement *found_by; /* if this was claimed in a search */
struct linked_list *errors_reading_source_text; /* of |copy_error| */
MEMORY_MANAGEMENT
} inbuild_copy;
inbuild_copy *Copies::new_p(inbuild_edition *edition, general_pointer ref) {
@ Copies are created by the managers for the respective genres, usually when
claiming. If you are a manager, do not call this...
=
inbuild_copy *Copies::new_p(inbuild_edition *edition) {
inbuild_copy *copy = CREATE(inbuild_copy);
copy->edition = edition;
copy->location_if_path = NULL;
copy->location_if_file = NULL;
copy->content = ref;
copy->content = NULL_GENERAL_POINTER;
copy->vertex = NULL;
copy->source_text_read = FALSE;
copy->source_text = EMPTY_WORDING;
copy->errors_reading_source_text = NEW_LINKED_LIST(copy_error);
copy->found_by = NULL;
copy->errors_reading_source_text = NEW_LINKED_LIST(copy_error);
return copy;
}
inbuild_copy *Copies::new_in_file(inbuild_edition *edition, filename *F, general_pointer ref) {
inbuild_copy *copy = Copies::new_p(edition, ref);
@ ...call one of these:
=
inbuild_copy *Copies::new_in_file(inbuild_edition *edition, filename *F) {
inbuild_copy *copy = Copies::new_p(edition);
copy->location_if_file = F;
return copy;
}
inbuild_copy *Copies::new_in_path(inbuild_edition *edition, pathname *P, general_pointer ref) {
inbuild_copy *copy = Copies::new_p(edition, ref);
inbuild_copy *Copies::new_in_path(inbuild_edition *edition, pathname *P) {
inbuild_copy *copy = Copies::new_p(edition);
copy->location_if_path = P;
return copy;
}
@ And then probably follow up by calling this, to attach a pointer to some
additional data specific to your genre:
=
void Copies::set_content(inbuild_copy *C, general_pointer ref) {
C->content = ref;
}
@h List of errors.
When copies are found to be malformed, error messages are attached to them
for later reporting. These are stored in a list.
=
void Copies::attach_error(inbuild_copy *C, copy_error *CE) {
if (C == NULL) internal_error("no copy to attach to");
CopyErrors::supply_attached_copy(CE, C);
ADD_TO_LINKED_LIST(CE, copy_error, C->errors_reading_source_text);
}
void Copies::list_attached_errors(OUTPUT_STREAM, inbuild_copy *C) {
if (C == NULL) return;
copy_error *CE;
int c = 1;
LOOP_OVER_LINKED_LIST(CE, copy_error, C->errors_reading_source_text) {
WRITE("%d. ", c++); CopyErrors::write(OUT, CE); WRITE("\n");
}
}
@h Writing.
=
void Copies::write_copy(OUTPUT_STREAM, inbuild_copy *C) {
Editions::write(OUT, C->edition);
}
void Copies::inspect_copy(OUTPUT_STREAM, inbuild_copy *C) {
Editions::inspect(OUT, C->edition);
@h Reading source text.
=
int Copies::source_text_has_been_read(inbuild_copy *C) {
if (C == NULL) internal_error("no copy");
return C->source_text_read;
}
wording Copies::get_source_text(inbuild_copy *C) {
if (C->source_text_read == FALSE) {
C->source_text_read = TRUE;
feed_t id = Feeds::begin();
VMETHOD_CALL(C->edition->work->genre, GENRE_READ_SOURCE_TEXT_FOR_MTID, C);
wording W = Feeds::end(id);
if (Wordings::nonempty(W)) C->source_text = W;
}
return C->source_text;
}
@h Going operational.
=
void Copies::go_operational(inbuild_copy *C) {
VMETHOD_CALL(C->edition->work->genre, GENRE_GO_OPERATIONAL_MTID, C);
}
@h Miscellaneous Inbuild commands.
This function implements the command-line instruction to |-inspect|.
=
void Copies::inspect(OUTPUT_STREAM, inbuild_copy *C) {
WRITE("%S: ", Genres::name(C->edition->work->genre));
Editions::inspect(OUT, C->edition);
if (C->location_if_path) {
WRITE(" at path %p", C->location_if_path);
}
if (C->location_if_file) {
pathname *P = Filenames::get_path_to(C->location_if_file);
if (P) WRITE(" in directory %p", P);
}
int N = LinkedLists::len(C->errors_reading_source_text);
if (N > 0) {
WRITE(" - %d error", N);
if (N > 1) WRITE("s");
}
WRITE("\n");
if (N > 0) {
INDENT; Copies::list_attached_errors(OUT, C); OUTDENT;
}
}
@ And here are |-build| and |-rebuild|, though note that |Copies::build|
is also called by the |core| module of the Inform 7 compiler to perform
its main task: building an Inform project.
=
void Copies::build(OUTPUT_STREAM, inbuild_copy *C, build_methodology *BM) {
build_vertex *V = C->vertex;
VMETHOD_CALL(C->edition->work->genre, GENRE_BUILDING_SOON_MTID, C, &V);
@ -73,6 +161,11 @@ void Copies::rebuild(OUTPUT_STREAM, inbuild_copy *C, build_methodology *BM) {
VMETHOD_CALL(C->edition->work->genre, GENRE_BUILDING_SOON_MTID, C, &V);
Graphs::rebuild(OUT, V, BM);
}
@ Now in quick succession |-graph|, |-build-needs|, |-use-needs|, |-build-missing|,
|-use-missing|:
=
void Copies::show_graph(OUTPUT_STREAM, inbuild_copy *C) {
build_vertex *V = C->vertex;
VMETHOD_CALL(C->edition->work->genre, GENRE_BUILDING_SOON_MTID, C, &V);
@ -89,6 +182,10 @@ void Copies::show_missing(OUTPUT_STREAM, inbuild_copy *C, int uses_only) {
int N = Graphs::show_missing(OUT, C->vertex, uses_only);
if (N == 0) WRITE("Nothing is missing\n");
}
@ And here is |-archive| and |-archive-to N|:
=
void Copies::archive(OUTPUT_STREAM, inbuild_copy *C, inbuild_nest *N, build_methodology *BM) {
build_vertex *V = C->vertex;
VMETHOD_CALL(C->edition->work->genre, GENRE_BUILDING_SOON_MTID, C, &V);
@ -97,220 +194,18 @@ void Copies::archive(OUTPUT_STREAM, inbuild_copy *C, inbuild_nest *N, build_meth
else if (N) Graphs::archive(OUT, C->vertex, N, BM);
}
int Copies::source_text_has_been_read(inbuild_copy *C) {
if (C == NULL) internal_error("no copy");
return C->source_text_read;
}
wording Copies::read_source_text_for(inbuild_copy *C) {
if (C->source_text_read == FALSE) {
C->source_text_read = TRUE;
feed_t id = Feeds::begin();
VMETHOD_CALL(C->edition->work->genre, GENRE_READ_SOURCE_TEXT_FOR_MTID, C);
wording W = Feeds::end(id);
if (Wordings::nonempty(W)) C->source_text = W;
}
return C->source_text;
}
inbuild_copy *Copies::claim(text_stream *arg) {
TEMPORARY_TEXT(ext);
int pos = Str::len(arg) - 1, dotpos = -1;
while (pos >= 0) {
wchar_t c = Str::get_at(arg, pos);
if (c == FOLDER_SEPARATOR) break;
if (c == '.') dotpos = pos;
pos--;
}
if (dotpos >= 0)
Str::substr(ext, Str::at(arg, dotpos+1), Str::end(arg));
int directory_status = NOT_APPLICABLE;
if (Str::get_last_char(arg) == FOLDER_SEPARATOR) {
Str::delete_last_character(arg);
directory_status = TRUE;
}
inbuild_copy *C = NULL;
inbuild_genre *G;
LOOP_OVER(G, inbuild_genre)
if (C == NULL)
VMETHOD_CALL(G, GENRE_CLAIM_AS_COPY_MTID, &C, arg, ext, directory_status);
DISCARD_TEXT(ext);
return C;
}
void Copies::inspect(OUTPUT_STREAM, inbuild_copy *C) {
WRITE("%S: ", Genres::name(C->edition->work->genre));
Copies::inspect_copy(STDOUT, C);
if (C->location_if_path) {
WRITE(" at path %p", C->location_if_path);
}
if (C->location_if_file) {
pathname *P = Filenames::get_path_to(C->location_if_file);
if (P) WRITE(" in directory %p", P);
}
int N = LinkedLists::len(C->errors_reading_source_text);
if (N > 0) {
WRITE(" - %d error", N);
if (N > 1) WRITE("s");
}
WRITE("\n");
if (N > 0) {
INDENT; Copies::list_problems_arising(OUT, C); OUTDENT;
}
}
@h Errors.
Copies can sometimes exist in a damaged form: for example, they are purportedly
extension files but have a mangled identification line. Each copy structure
therefore has a list attached of errors which occurred in reading it.
@e OPEN_FAILED_CE from 1
@e KIT_MISWORDED_CE
@e EXT_MISWORDED_CE
@e EXT_TITLE_TOO_LONG_CE
@e EXT_AUTHOR_TOO_LONG_CE
@e LEXER_CE
@e SYNTAX_CE
@ And lastly |-copy-to N| and |-sync-to N|:
=
typedef struct copy_error {
int error_category;
int error_subcategory;
struct inbuild_copy *copy;
struct filename *file;
struct text_file_position pos;
struct text_stream *notes;
struct text_stream *details;
int details_N;
struct wording details_W;
struct parse_node *details_node;
struct parse_node *details_node2;
struct inbuild_work *details_work;
struct inbuild_work *details_work2;
wchar_t *word;
MEMORY_MANAGEMENT
} copy_error;
copy_error *Copies::new_error(int cat, text_stream *NB) {
copy_error *CE = CREATE(copy_error);
CE->error_category = cat;
CE->error_subcategory = -1;
CE->file = NULL;
CE->notes = Str::duplicate(NB);
CE->details = NULL;
CE->details_N = -1;
CE->details_W = EMPTY_WORDING;
CE->details_node = NULL;
CE->details_node2 = NULL;
CE->details_work = NULL;
CE->details_work2 = NULL;
CE->pos = TextFiles::nowhere();
CE->copy = NULL;
CE->word = NULL;
return CE;
void Copies::copy_to(inbuild_copy *C, inbuild_nest *destination_nest, int syncing,
build_methodology *meth) {
if (destination_nest)
VMETHOD_CALL(C->edition->work->genre, GENRE_COPY_TO_NEST_MTID,
C, destination_nest, syncing, meth);
}
copy_error *Copies::new_error_N(int cat, int N) {
copy_error *CE = Copies::new_error(cat, NULL);
CE->details_N = N;
return CE;
}
copy_error *Copies::new_error_on_file(int cat, filename *F) {
copy_error *CE = Copies::new_error(cat, NULL);
CE->file = F;
return CE;
}
void Copies::attach(inbuild_copy *C, copy_error *CE) {
if (C == NULL) internal_error("no copy to attach to");
CE->copy = C;
ADD_TO_LINKED_LIST(CE, copy_error, C->errors_reading_source_text);
}
void Copies::list_problems_arising(OUTPUT_STREAM, inbuild_copy *C) {
if (C == NULL) return;
copy_error *CE;
int c = 1;
LOOP_OVER_LINKED_LIST(CE, copy_error, C->errors_reading_source_text) {
WRITE("%d. ", c++); Copies::write_problem(OUT, CE); WRITE("\n");
}
}
void Copies::write_problem(OUTPUT_STREAM, copy_error *CE) {
switch (CE->error_category) {
case OPEN_FAILED_CE: WRITE("unable to open file %f", CE->file); break;
case EXT_MISWORDED_CE: WRITE("extension misworded: %S", CE->notes); break;
case KIT_MISWORDED_CE: WRITE("kit has incorrect metadata: %S", CE->notes); break;
case EXT_TITLE_TOO_LONG_CE: WRITE("title too long: %d characters (max is %d)",
CE->details_N, MAX_EXTENSION_TITLE_LENGTH); break;
case EXT_AUTHOR_TOO_LONG_CE: WRITE("author name too long: %d characters (max is %d)",
CE->details_N, MAX_EXTENSION_AUTHOR_LENGTH); break;
case LEXER_CE: WRITE("%S", CE->notes); break;
case SYNTAX_CE:
switch (CE->error_subcategory) {
case UnexpectedSemicolon_SYNERROR:
WRITE("unexpected semicolon in sentence"); break;
case ParaEndsInColon_SYNERROR:
WRITE("paragraph ends with a colon"); break;
case SentenceEndsInColon_SYNERROR:
WRITE("paragraph ends with a colon and full stop"); break;
case SentenceEndsInSemicolon_SYNERROR:
WRITE("paragraph ends with a semicolon and full stop"); break;
case SemicolonAfterColon_SYNERROR:
WRITE("paragraph ends with a colon and semicolon"); break;
case SemicolonAfterStop_SYNERROR:
WRITE("paragraph ends with a full stop and semicolon"); break;
case HeadingOverLine_SYNERROR:
WRITE("heading contains a line break"); break;
case HeadingStopsBeforeEndOfLine_SYNERROR:
WRITE("heading stops before end of line"); break;
case ExtNoBeginsHere_SYNERROR:
WRITE("extension has no beginning"); break;
case ExtNoEndsHere_SYNERROR:
WRITE("extension has no end"); break;
case ExtSpuriouslyContinues_SYNERROR:
WRITE("extension continues after end"); break;
case ExtMultipleBeginsHere_SYNERROR:
WRITE("extension has multiple 'begins here' sentences"); break;
case ExtBeginsAfterEndsHere_SYNERROR:
WRITE("extension has a 'begins here' after its 'ends here'"); break;
case ExtEndsWithoutBegins_SYNERROR:
WRITE("extension has an 'ends here' but no 'begins here'"); break;
case ExtMultipleEndsHere_SYNERROR:
WRITE("extension has multiple 'ends here' sentences"); break;
case BadTitleSentence_SYNERROR:
WRITE("bibliographic sentence at the start is malformed"); break;
case UnknownLanguageElement_SYNERROR:
WRITE("unrecognised stipulation about Inform language elements"); break;
case UnknownVirtualMachine_SYNERROR:
WRITE("unrecognised stipulation about virtual machine"); break;
case UseElementWithdrawn_SYNERROR:
WRITE("use language element is no longer supported"); break;
case IncludeExtQuoted_SYNERROR:
WRITE("extension name should not be double-quoted"); break;
case BogusExtension_SYNERROR:
WRITE("can't find this extension"); break;
case ExtVersionTooLow_SYNERROR:
WRITE("extension version too low"); break;
case ExtVersionMalformed_SYNERROR:
WRITE("extension version is malformed"); break;
case ExtInadequateVM_SYNERROR:
WRITE("extension is not compatible with the target virtual machine"); break;
case ExtMisidentifiedEnds_SYNERROR:
WRITE("extension has an 'ends here' but it does not match the 'begins here'"); break;
case HeadingInPlaceOfUnincluded_SYNERROR:
WRITE("heading is in place of an extension not included"); break;
case UnequalHeadingInPlaceOf_SYNERROR:
WRITE("heading is in place of another heading but of a diffeent level"); break;
case HeadingInPlaceOfSubordinate_SYNERROR:
WRITE("heading is in place of another heading subordinate to itself"); break;
case HeadingInPlaceOfUnknown_SYNERROR:
WRITE("heading is in place of another heading which doesn't seem to exist'"); break;
default:
WRITE("syntax error"); break;
}
break;
default: internal_error("an unknown error occurred");
}
void Copies::overwrite_error(inbuild_copy *C, inbuild_nest *N) {
text_stream *ext = Str::new();
WRITE_TO(ext, "%X", C->edition->work);
Errors::with_text("already present (to overwrite, use -sync-to not -copy-to): '%S'", ext);
}

View file

@ -0,0 +1,221 @@
[CopyErrors::] Copy Errors.
A copy error is attached to a copy when scanning it reveals some malformation.
@ Copies can sometimes exist in a damaged form: for example, they are purportedly
extension files but have a mangled identification line. Each copy structure
therefore has a list attached of errors which occurred in reading it.
Each copy error has one of the following categories, and some are divided into
subcategories too. Otherwise an error has no real contents: only a ragbag of
contextual data -- exactly what word it is that is too long, where the
sentence is which is mis-punctuated, and such. In every case most of these
fields are blank.
@e OPEN_FAILED_CE from 1
@e KIT_MISWORDED_CE
@e EXT_MISWORDED_CE
@e EXT_TITLE_TOO_LONG_CE
@e EXT_AUTHOR_TOO_LONG_CE
@e LEXER_CE /* an error generated by the |words| module */
@e SYNTAX_CE /* an error generated by the |syntax| module, or by our reading of the tree */
=
typedef struct copy_error {
struct inbuild_copy *copy;
int error_category;
int error_subcategory;
struct text_stream *details;
struct filename *details_file;
int details_N;
struct wording details_W;
struct parse_node *details_node;
struct parse_node *details_node2;
struct inbuild_work *details_work;
struct inbuild_work *details_work2;
wchar_t *details_word;
MEMORY_MANAGEMENT
} copy_error;
@ And now some creators.
=
copy_error *CopyErrors::new(int cat, int subcat) {
copy_error *CE = CREATE(copy_error);
CE->copy = NULL;
CE->error_category = cat;
CE->error_subcategory = subcat;
CE->details = NULL;
CE->details_file = NULL;
CE->details_N = -1;
CE->details_W = EMPTY_WORDING;
CE->details_node = NULL;
CE->details_node2 = NULL;
CE->details_work = NULL;
CE->details_work2 = NULL;
CE->details_word = NULL;
return CE;
}
copy_error *CopyErrors::new_T(int cat, int subcat, text_stream *NB) {
copy_error *CE = CopyErrors::new(cat, subcat);
CE->details = Str::duplicate(NB);
return CE;
}
copy_error *CopyErrors::new_N(int cat, int subcat, int N) {
copy_error *CE = CopyErrors::new(cat, subcat);
CE->details_N = N;
return CE;
}
copy_error *CopyErrors::new_F(int cat, int subcat, filename *F) {
copy_error *CE = CopyErrors::new(cat, subcat);
CE->details_file = F;
return CE;
}
copy_error *CopyErrors::new_WT(int cat, int subcat, wchar_t *details_word, text_stream *NB) {
copy_error *CE = CopyErrors::new(cat, subcat);
CE->details_word = details_word;
CE->details = Str::duplicate(NB);
return CE;
}
@ It becomes tiresome to make creators for every conceivable possibility, so
we also offer these functions to tack extra details on:
=
void CopyErrors::supply_wording(copy_error *CE, wording details_W) {
CE->details_W = details_W;
}
void CopyErrors::supply_work(copy_error *CE, inbuild_work *w) {
CE->details_work = w;
}
void CopyErrors::supply_works(copy_error *CE, inbuild_work *w1, inbuild_work *w2) {
CE->details_work = w1;
CE->details_work2 = w2;
}
void CopyErrors::supply_node(copy_error *CE, parse_node *n) {
CE->details_node = n;
}
void CopyErrors::supply_nodes(copy_error *CE, parse_node *n1, parse_node *n2) {
CE->details_node = n1;
CE->details_node2 = n2;
}
@ The following should only be called from Copies.
=
void CopyErrors::supply_attached_copy(copy_error *CE, inbuild_copy *C) {
CE->copy = C;
}
@ This produces a textual summary of the issue described. It wouldn't do for
a proper Inform problem message, but it's fine for the Inbuild command line
output.
=
void CopyErrors::write(OUTPUT_STREAM, copy_error *CE) {
switch (CE->error_category) {
case OPEN_FAILED_CE: WRITE("unable to open file %f", CE->details_file); break;
case EXT_MISWORDED_CE: WRITE("extension misworded: %S", CE->details); break;
case KIT_MISWORDED_CE: WRITE("kit has incorrect metadata: %S", CE->details); break;
case EXT_TITLE_TOO_LONG_CE: WRITE("title too long: %d characters (max is %d)",
CE->details_N, MAX_EXTENSION_TITLE_LENGTH); break;
case EXT_AUTHOR_TOO_LONG_CE: WRITE("author name too long: %d characters (max is %d)",
CE->details_N, MAX_EXTENSION_AUTHOR_LENGTH); break;
case LEXER_CE: @<Write a lexer error@>; break;
case SYNTAX_CE: @<Write a syntax error@>; break;
default: internal_error("an unknown error occurred");
}
}
@<Write a lexer error@> =
switch (CE->error_subcategory) {
case STRING_TOO_LONG_LEXERERROR:
WRITE("Too much text in quotation marks: %w", CE->details_word); break;
case WORD_TOO_LONG_LEXERERROR:
WRITE("Word too long: %w", CE->details_word); break;
case I6_TOO_LONG_LEXERERROR:
WRITE("I6 inclusion too long: %w", CE->details_word); break;
case STRING_NEVER_ENDS_LEXERERROR:
WRITE("Quoted text never ends: %S", CE->details); break;
case COMMENT_NEVER_ENDS_LEXERERROR:
WRITE("Square-bracketed text never ends: %S", CE->details); break;
case I6_NEVER_ENDS_LEXERERROR:
WRITE("I6 inclusion text never ends: %S", CE->details); break;
default:
WRITE("lexer error"); break;
}
@<Write a syntax error@> =
switch (CE->error_subcategory) {
case UnexpectedSemicolon_SYNERROR:
WRITE("unexpected semicolon in sentence"); break;
case ParaEndsInColon_SYNERROR:
WRITE("paragraph ends with a colon"); break;
case SentenceEndsInColon_SYNERROR:
WRITE("paragraph ends with a colon and full stop"); break;
case SentenceEndsInSemicolon_SYNERROR:
WRITE("paragraph ends with a semicolon and full stop"); break;
case SemicolonAfterColon_SYNERROR:
WRITE("paragraph ends with a colon and semicolon"); break;
case SemicolonAfterStop_SYNERROR:
WRITE("paragraph ends with a full stop and semicolon"); break;
case HeadingOverLine_SYNERROR:
WRITE("heading contains a line break"); break;
case HeadingStopsBeforeEndOfLine_SYNERROR:
WRITE("heading stops before end of line"); break;
case ExtNoBeginsHere_SYNERROR:
WRITE("extension has no beginning"); break;
case ExtNoEndsHere_SYNERROR:
WRITE("extension has no end"); break;
case ExtSpuriouslyContinues_SYNERROR:
WRITE("extension continues after end"); break;
case ExtMultipleBeginsHere_SYNERROR:
WRITE("extension has multiple 'begins here' sentences"); break;
case ExtBeginsAfterEndsHere_SYNERROR:
WRITE("extension has a 'begins here' after its 'ends here'"); break;
case ExtEndsWithoutBegins_SYNERROR:
WRITE("extension has an 'ends here' but no 'begins here'"); break;
case ExtMultipleEndsHere_SYNERROR:
WRITE("extension has multiple 'ends here' sentences"); break;
case BadTitleSentence_SYNERROR:
WRITE("bibliographic sentence at the start is malformed"); break;
case UnknownLanguageElement_SYNERROR:
WRITE("unrecognised stipulation about Inform language elements"); break;
case UnknownVirtualMachine_SYNERROR:
WRITE("unrecognised stipulation about virtual machine"); break;
case UseElementWithdrawn_SYNERROR:
WRITE("use language element is no longer supported"); break;
case IncludeExtQuoted_SYNERROR:
WRITE("extension name should not be double-quoted"); break;
case BogusExtension_SYNERROR:
WRITE("can't find this extension"); break;
case ExtVersionTooLow_SYNERROR:
WRITE("extension version too low"); break;
case ExtVersionMalformed_SYNERROR:
WRITE("extension version is malformed"); break;
case ExtInadequateVM_SYNERROR:
WRITE("extension is not compatible with the target virtual machine"); break;
case ExtMisidentifiedEnds_SYNERROR:
WRITE("extension has an 'ends here' which doesn't match the 'begins here'"); break;
case HeadingInPlaceOfUnincluded_SYNERROR:
WRITE("heading is in place of an extension not included"); break;
case UnequalHeadingInPlaceOf_SYNERROR:
WRITE("heading is in place of another heading but of a diffeent level"); break;
case HeadingInPlaceOfSubordinate_SYNERROR:
WRITE("heading is in place of another heading subordinate to itself"); break;
case HeadingInPlaceOfUnknown_SYNERROR:
WRITE("heading is in place of another heading which doesn't exist'"); break;
default:
WRITE("syntax error"); break;
}

View file

@ -1,10 +1,15 @@
[Editions::] Editions.
An edition is numbered version of a work.
An edition is a numbered version of a work.
@h Editions.
An "edition" of a work is a particular version numbered form of it. For
example, release 7 of Bronze by Emily Short would be an edition of Bronze.
example, release 7 of Bronze by Emily Short would be an edition of the
work Bronze by Emily Short.
It is at this level that we record what works are compatible with which
target virtual machines, because we can imagine that, for example, version 7
might work with all VMs, while version 8 required a 32-bit architecture.
=
typedef struct inbuild_edition {
@ -30,6 +35,12 @@ void Editions::write(OUTPUT_STREAM, inbuild_edition *E) {
}
}
@ When a copy is to be duplicated into a nest |N|, we need to work out where
to put it. For example, version 2.1 of the extension Marbles by Steve Hogarth
would go into |N/Extensions/Steve Hogarth/Marbles-v2_1.i7x|. The following
contributes only the un-filename-extended leafname |Marbles-v2_1|.
=
void Editions::write_canonical_leaf(OUTPUT_STREAM, inbuild_edition *E) {
WRITE("%S", E->work->title);
if (VersionNumbers::is_null(E->version) == FALSE) {
@ -44,6 +55,9 @@ void Editions::write_canonical_leaf(OUTPUT_STREAM, inbuild_edition *E) {
}
}
@ The |-inspect| command of Inbuild uses the following.
=
void Editions::inspect(OUTPUT_STREAM, inbuild_edition *E) {
Editions::write(OUT, E);
if (Compatibility::universal(E->compatibility) == FALSE) {

View file

@ -46,6 +46,17 @@ int Genres::stored_in_nests(inbuild_genre *G) {
return G->stored_in_nests;
}
@ The requirements parser needs to identify genres by name, so:
=
inbuild_genre *Genres::by_name(text_stream *name) {
inbuild_genre *G;
LOOP_OVER(G, inbuild_genre)
if (Str::eq_insensitive(G->genre_name, name))
return G;
return NULL;
}
@h Method functions.
And here are the method functions which a genre can, optionally, provide.
All of these act on a given work, or a given copy of a work, having the
@ -111,6 +122,9 @@ no further unsuspected dependencies.
This method is optional, and is called exactly once on every copy (whose genre
provides it) which has been claimed by Inbuild.
Text should actually be read by feeding it into the lexer. Inbuild will take
of it from there.
@e GENRE_GO_OPERATIONAL_MTID
=

View file

@ -2,22 +2,19 @@
Nests are repositories of Inform-related resources.
@
@h Creation.
To "create" a nest here does not mean actually altering the file system, for
example by making a directory: nests here are merely notes in memory of
positions in the file system hierarchy which may or may not exist.
=
typedef struct inbuild_nest {
struct pathname *location;
int read_only;
int tag_value;
int read_only; /* files cannot be written into this nest */
int tag_value; /* used to indicate whether internal, external, and such */
MEMORY_MANAGEMENT
} inbuild_nest;
typedef struct inbuild_search_result {
struct inbuild_nest *nest;
struct inbuild_copy *copy;
MEMORY_MANAGEMENT
} inbuild_search_result;
=
inbuild_nest *Nests::new(pathname *P) {
inbuild_nest *N = CREATE(inbuild_nest);
@ -27,6 +24,19 @@ inbuild_nest *Nests::new(pathname *P) {
return N;
}
@ Nests used by the Inform and Inbuild tools are tagged with the following
comstamts. (There used to be quite a good joke here, but refactoring of the
code removed its premiss. Literate programming is like that sometimes.)
The sequence of the following enumerated values is very significant --
see below for why. Lower-tag-numbered origins are better than later ones.
@e MATERIALS_NEST_TAG from 1
@e EXTERNAL_NEST_TAG
@e GENERIC_NEST_TAG
@e INTERNAL_NEST_TAG
=
int Nests::get_tag(inbuild_nest *N) {
if (N == NULL) return -1;
return N->tag_value;
@ -37,20 +47,21 @@ void Nests::set_tag(inbuild_nest *N, int t) {
N->tag_value = t;
}
@ =
void Nests::protect(inbuild_nest *N) {
N->read_only = TRUE;
}
void Nests::add_search_result(linked_list *results, inbuild_nest *N, inbuild_copy *C,
inbuild_requirement *req) {
inbuild_search_result *R = CREATE(inbuild_search_result);
R->nest = N;
R->copy = C;
C->found_by = req;
if (req == NULL) internal_error("bad search result");
ADD_TO_LINKED_LIST(R, inbuild_search_result, results);
}
@h Search list.
When we search for copies, we do so by looking through nests in a list. The
following builds such lists, removing duplicates -- where duplicates are
shown up by having the same textual form of pathname. (This is not foolproof
by any means: Unix is replete with ways to describe the same directory, thanks
to simlinks, |~| and so on. But in the circumstances arising inside Inbuild,
it will do. In any case, having duplicates would not actually matter: it
would just produce search results which were more copious than needed.)
=
void Nests::add_to_search_sequence(linked_list *search_list, inbuild_nest *N) {
TEMPORARY_TEXT(NS);
WRITE_TO(NS, "%p", N->location);
@ -67,7 +78,36 @@ void Nests::add_to_search_sequence(linked_list *search_list, inbuild_nest *N) {
ADD_TO_LINKED_LIST(N, inbuild_nest, search_list);
}
void Nests::search_for(inbuild_requirement *req, linked_list *search_list, linked_list *results) {
@h Search results.
When we search a list of nests for copies satisfying certain requirements,
we create one of these for each hit:
=
typedef struct inbuild_search_result {
struct inbuild_copy *copy; /* what was found */
struct inbuild_nest *nest; /* from whence it came */
MEMORY_MANAGEMENT
} inbuild_search_result;
@ These can be created only as entries in a list:
=
void Nests::add_search_result(linked_list *results, inbuild_nest *N, inbuild_copy *C,
inbuild_requirement *req) {
inbuild_search_result *R = CREATE(inbuild_search_result);
R->nest = N;
R->copy = C;
C->found_by = req;
if (req == NULL) internal_error("bad search result");
ADD_TO_LINKED_LIST(R, inbuild_search_result, results);
}
@ And here is our search engine, such as it is. For each nest, we ask each
genre's manager to look for copies of that genre:
=
void Nests::search_for(inbuild_requirement *req,
linked_list *search_list, linked_list *results) {
inbuild_nest *N;
LOOP_OVER_LINKED_LIST(N, inbuild_nest, search_list) {
inbuild_genre *G;
@ -76,7 +116,12 @@ void Nests::search_for(inbuild_requirement *req, linked_list *search_list, linke
}
}
inbuild_search_result *Nests::first_found(inbuild_requirement *req, linked_list *search_list) {
@ Oftentimes, we want only the single best result, and won't even look at the
others:
=
inbuild_search_result *Nests::search_for_best(inbuild_requirement *req,
linked_list *search_list) {
linked_list *L = NEW_LINKED_LIST(inbuild_search_result);
Nests::search_for(req, search_list, L);
inbuild_search_result *best = NULL, *search_result;
@ -86,26 +131,29 @@ inbuild_search_result *Nests::first_found(inbuild_requirement *req, linked_list
return best;
}
@ Where "better" is defined as follows. This innocent-looking function is
in fact critical to what Inbuild does. It uses tags on nests to prefer copies
in the Materials folder to those in the external nest, and to prefer those in
turn to copies in the internal nest; and within nests of equal importance,
it chooses the earliest hit among those which have the highest-precedence
semantic version numbers.
=
int Nests::better_result(inbuild_search_result *R1, inbuild_search_result *R2) {
/* Something is better than nothing */
if (R1 == NULL) return FALSE;
if (R2 == NULL) return TRUE;
/* Otherwise, a more important nest beats a less important nest */
int o1 = Nests::get_tag(R1->nest);
int o2 = Nests::get_tag(R2->nest);
if (o1 < o2) return TRUE;
if (o1 > o2) return FALSE;
if (VersionNumbers::gt(R1->copy->edition->version, R2->copy->edition->version)) return TRUE;
/* Otherwise, a higher semantic version number beats a lower */
if (VersionNumbers::gt(R1->copy->edition->version, R2->copy->edition->version))
return TRUE;
/* Otherwise, better the devil we know */
return FALSE;
}
void Nests::copy_to(inbuild_copy *C, inbuild_nest *destination_nest, int syncing,
build_methodology *meth) {
if (destination_nest)
VMETHOD_CALL(C->edition->work->genre, GENRE_COPY_TO_NEST_MTID,
C, destination_nest, syncing, meth);
}
void Nests::overwrite_error(inbuild_nest *N, inbuild_copy *C) {
text_stream *ext = Str::new();
WRITE_TO(ext, "%X", C->edition->work);
Errors::with_text("already present (to overwrite, use -sync-to not -copy-to): '%S'", ext);
}

View file

@ -3,7 +3,11 @@
A requirement is a way to specify some subset of works: for example, those
with a given title, and/or version number.
@ A null minimum version means "no minimum", a null maximum means "no maximum".
@h Creation.
A requirement is, in effect, the criteria for performing a search. We can
specify the title, and/or the author name, and/or the genre -- all given
in the |work| field below, with those unspecified left blank -- and/or
we can give a semantic version number range:
=
typedef struct inbuild_requirement {
@ -12,6 +16,9 @@ typedef struct inbuild_requirement {
MEMORY_MANAGEMENT
} inbuild_requirement;
@ Here are some creators:
=
inbuild_requirement *Requirements::new(inbuild_work *work, semver_range *R) {
inbuild_requirement *req = CREATE(inbuild_requirement);
req->work = work;
@ -31,7 +38,20 @@ inbuild_requirement *Requirements::anything(void) {
return Requirements::anything_of_genre(NULL);
}
inbuild_requirement *Requirements::from_text(text_stream *T, text_stream *errors) {
@ The most involved of the creators parses text. An involved example might be:
|genre=extension,author=Emily Short,title=Locksmith,min=6.1-alpha.2,max=17.2|
We should return a requirement if this is valid, and write an error message if
it is not. (If the text has multiple things wrong with it, we write only the
first error message arising.)
At the top level, we have a comma-separated list of clauses. Note that the
empty text is legal here, and produces an unlimited requirement.
=
inbuild_requirement *Requirements::from_text(text_stream *T,
text_stream *errors) {
inbuild_requirement *req = Requirements::anything();
int from = 0;
for (int at = 0; at < Str::len(T); at++) {
@ -53,71 +73,73 @@ inbuild_requirement *Requirements::from_text(text_stream *T, text_stream *errors
return req;
}
void Requirements::impose_clause(inbuild_requirement *req, text_stream *T, text_stream *errors) {
@ Each clause must either be |all| or take the form |term=value|:
=
void Requirements::impose_clause(inbuild_requirement *req, text_stream *T,
text_stream *errors) {
Str::trim_white_space(T);
if (Str::eq(T, I"all")) return;
TEMPORARY_TEXT(clause);
TEMPORARY_TEXT(term);
TEMPORARY_TEXT(value);
for (int at = 0; at < Str::len(T); at++) {
wchar_t c = Str::get_at(T, at);
if (c == '=') {
Str::substr(clause, Str::start(T), Str::at(T, at));
Str::substr(term, Str::start(T), Str::at(T, at));
Str::substr(value, Str::at(T, at+1), Str::end(T));
break;
}
}
Str::trim_white_space(clause);
Str::trim_white_space(term);
Str::trim_white_space(value);
if ((Str::len(clause) > 0) && (Str::len(value) > 0)) {
if (Str::eq(clause, I"genre")) {
inbuild_genre *G;
LOOP_OVER(G, inbuild_genre)
if (Str::eq_insensitive(G->genre_name, value)) {
req->work->genre = G;
break;
}
if (req->work->genre == NULL) {
if (Str::len(errors) == 0)
WRITE_TO(errors, "not a valid genre: '%S'", value);
}
} else if (Str::eq(clause, I"title")) Str::copy(req->work->title, value);
else if (Str::eq(clause, I"author")) Str::copy(req->work->author_name, value);
else if (Str::eq(clause, I"version")) {
semantic_version_number V = VersionNumbers::from_text(value);
if (VersionNumbers::is_null(V)) {
if (Str::len(errors) == 0)
WRITE_TO(errors, "not a valid version number: '%S'", value);
}
req->version_range = VersionNumberRanges::compatibility_range(V);
} else if (Str::eq(clause, I"min")) {
semantic_version_number V = VersionNumbers::from_text(value);
if (VersionNumbers::is_null(V)) {
if (Str::len(errors) == 0)
WRITE_TO(errors, "not a valid version number: '%S'", value);
}
req->version_range = VersionNumberRanges::at_least_range(V);
} else if (Str::eq(clause, I"max")) {
semantic_version_number V = VersionNumbers::from_text(value);
if (VersionNumbers::is_null(V)) {
if (Str::len(errors) == 0)
WRITE_TO(errors, "not a valid version number: '%S'", value);
}
req->version_range = VersionNumberRanges::at_most_range(V);
} else {
if (Str::len(errors) == 0)
WRITE_TO(errors, "no such term as '%S'", clause);
}
if ((Str::len(term) > 0) && (Str::len(value) > 0)) {
@<Deal with a term-value pair@>;
} else {
if (Str::len(errors) == 0)
WRITE_TO(errors, "clause not in the form 'term=value': '%S'", T);
}
DISCARD_TEXT(clause);
DISCARD_TEXT(term);
DISCARD_TEXT(value);
}
@<Deal with a term-value pair@> =
if (Str::eq(term, I"genre")) {
inbuild_genre *G = Genres::by_name(value);
if (G) req->work->genre = G;
else if (Str::len(errors) == 0)
WRITE_TO(errors, "not a valid genre: '%S'", value);
} else if (Str::eq(term, I"title")) {
Str::copy(req->work->title, value);
} else if (Str::eq(term, I"author")) {
Str::copy(req->work->author_name, value);
} else if (Str::eq(term, I"version")) {
semantic_version_number V = Requirements::semver(value, errors);
req->version_range = VersionNumberRanges::compatibility_range(V);
} else if (Str::eq(term, I"min")) {
semantic_version_number V = Requirements::semver(value, errors);
req->version_range = VersionNumberRanges::at_least_range(V);
} else if (Str::eq(term, I"max")) {
semantic_version_number V = Requirements::semver(value, errors);
req->version_range = VersionNumberRanges::at_most_range(V);
} else {
if (Str::len(errors) == 0)
WRITE_TO(errors, "no such term as '%S'", term);
}
@ =
semantic_version_number Requirements::semver(text_stream *value, text_stream *errors) {
semantic_version_number V = VersionNumbers::from_text(value);
if (VersionNumbers::is_null(V))
if (Str::len(errors) == 0)
WRITE_TO(errors, "not a valid version number: '%S'", value);
return V;
}
@h Writing.
This is the inverse of the above function, and uses the same notation.
=
void Requirements::write(OUTPUT_STREAM, inbuild_requirement *req) {
if (req == NULL) { WRITE("<none>"); return; }
int claused = FALSE;
@ -140,21 +162,27 @@ void Requirements::write(OUTPUT_STREAM, inbuild_requirement *req) {
if (claused == FALSE) WRITE("all");
}
@h Meeting requirements.
Finally, we actually use these intricacies for something. Given an edition,
we return |TRUE| if it meets the requirements and |FALSE| if it does not.
Note that requirements are based on the edition, not on the copy. If one
copy on file of Version 3.2 of Monkey Puzzle Trees by Capability Brown meets
a requirement, then so will all other copies of it.
=
int Requirements::meets(inbuild_edition *edition, inbuild_requirement *req) {
if (req == NULL) return TRUE;
if (req->work) {
if (req->work->genre) {
if (req->work->genre)
if (req->work->genre != edition->work->genre)
return FALSE;
}
if (Str::len(req->work->title) > 0) {
if (Str::len(req->work->title) > 0)
if (Str::ne_insensitive(req->work->title, edition->work->title))
return FALSE;
}
if (Str::len(req->work->author_name) > 0) {
if (Str::len(req->work->author_name) > 0)
if (Str::ne_insensitive(req->work->author_name, edition->work->author_name))
return FALSE;
}
}
return VersionNumberRanges::in_range(edition->version, req->version_range);
}

View file

@ -27,21 +27,7 @@ typedef struct inbuild_work {
} inbuild_work;
@ Each work structure is written only once, and its title and author name are
not subsequently altered. We therefore hash-code on arrival. As when
hashing vocabulary, we apply the X 30011 algorithm, this time with 499
(coprime to 30011) as base, to the text of the Unix-style pathname
|Author/Title|.
Though it is probably the case that the author name and title supplied are
already of normalised casing, we do not want to rely on that. Works intending
to represent (e.g.) the same extension but named with different casing
conventions would fail to match: and this could happen if a new build of
Inform were published which made a subtle change to the casing conventions,
but which continued to use an extension dictionary file first written by
previous builds under the previous conventions.
The hash code is an integer between 0 and the following constant minus 1,
derived from its title and author name.
not subsequently altered.
@d WORK_HASH_CODING_BASE 499
@ -53,6 +39,18 @@ inbuild_work *Works::new_raw(inbuild_genre *genre, text_stream *ti, text_stream
return Works::new_inner(genre, ti, an, FALSE);
}
@ Though it is probably the case that the author name and title supplied are
already of normalised casing, we do not want to rely on that. Works intending
to represent (e.g.) the same extension but named with different casing
conventions would fail to match: and this could happen if a new build of
Inform were published which made a subtle change to the casing conventions,
but which continued to use an extension dictionary file first written by
previous builds under the previous conventions.
The "raw", i.e., not case-normalised, forms of the title and author name are
preserved for use in text output, but not identification.
=
inbuild_work *Works::new_inner(inbuild_genre *genre, text_stream *ti, text_stream *an, int norm) {
inbuild_work *work = CREATE(inbuild_work);
work->genre = genre;
@ -64,6 +62,17 @@ inbuild_work *Works::new_inner(inbuild_genre *genre, text_stream *ti, text_strea
Works::normalise_casing(work->author_name);
Works::normalise_casing(work->title);
}
@<Compute the hash code@>;
return work;
}
@ We hash-code all works on arrival, using the X 30011 algorithm, with 499
(coprime to 30011) as base, to the text of the pseudo-pathname |Author/Title|.
The hash code is an integer between 0 and the following constant minus 1,
derived from its title and author name.
@<Compute the hash code@> =
unsigned int hc = 0;
LOOP_THROUGH_TEXT(pos, work->author_name)
hc = hc*30011 + (unsigned int) Str::get(pos);
@ -72,14 +81,29 @@ inbuild_work *Works::new_inner(inbuild_genre *genre, text_stream *ti, text_strea
hc = hc*30011 + (unsigned int) Str::get(pos);
hc = hc % WORK_HASH_CODING_BASE;
work->inbuild_work_hash_code = (int) hc;
return work;
@ Casing is normalised as follows. Every word is capitalised, where a word
begins at the start of the text, after a hyphen, or after a bracket. Thus
"Every Word Counts", "Even Double-Barrelled Ones (And Even Parenthetically)".
=
void Works::normalise_casing(text_stream *p) {
int boundary = TRUE;
LOOP_THROUGH_TEXT(pos, p) {
wchar_t c = Str::get(pos);
if (boundary) Str::put(pos, Characters::toupper(c));
else Str::put(pos, Characters::tolower(c));
boundary = FALSE;
if (c == ' ') boundary = TRUE;
if (c == '-') boundary = TRUE;
if (c == '(') boundary = TRUE;
}
}
void Works::set_raw(inbuild_work *work, text_stream *raw_an, text_stream *raw_ti) {
work->raw_author_name = Str::duplicate(raw_an);
work->raw_title = Str::duplicate(raw_ti);
}
@h Printing.
As noted above, the raw forms are used for output.
=
void Works::write(OUTPUT_STREAM, inbuild_work *work) {
VMETHOD_CALL(work->genre, GENRE_WRITE_WORK_MTID, OUT, work);
}
@ -92,6 +116,10 @@ void Works::write_to_HTML_file(OUTPUT_STREAM, inbuild_work *work, int fancy) {
WRITE("%S", work->raw_author_name);
}
@ The following is only sensible for extensions, and is used when Inform
generates its Extensions index entries.
=
void Works::write_link_to_HTML_file(OUTPUT_STREAM, inbuild_work *work) {
HTML_OPEN_WITH("a", "href='Extensions/%S/%S.html' style=\"text-decoration: none\"",
work->author_name, work->title);
@ -102,6 +130,10 @@ void Works::write_link_to_HTML_file(OUTPUT_STREAM, inbuild_work *work) {
HTML_CLOSE("a");
}
@ The Inbuild module provides the |%X| escape sequence for printing names of
works. (The X used to stand for Extension.) |%<X| ptovides an abbreviated form.
=
void Works::writer(OUTPUT_STREAM, char *format_string, void *vE) {
inbuild_work *work = (inbuild_work *) vE;
switch (format_string[0]) {
@ -109,7 +141,8 @@ void Works::writer(OUTPUT_STREAM, char *format_string, void *vE) {
if (work == NULL) WRITE("source text");
else {
WRITE("%S", work->raw_title);
if (Works::is_standard_rules(work) == FALSE)
if ((Works::is_standard_rules(work) == FALSE) &&
(Works::is_basic_inform(work) == FALSE))
WRITE(" by %S", work->raw_author_name);
}
break;
@ -122,15 +155,16 @@ void Works::writer(OUTPUT_STREAM, char *format_string, void *vE) {
}
}
@ Two works with different hash codes definitely identify different extensions;
if the code is the same, we must use |strcmp| on the actual title and author
@h Identification.
Two works with different hash codes definitely identify different works;
if the code is the same, we must use |Str::eq| on the actual title and author
name. This is in effect case insensitive, since we normalised casing when
the works were created.
(Note that this is not a lexicographic function suitable for sorting
works into alphabetical order: it cannot be, since the hash code is not
order-preserving. To emphasise this we return true or false rather than a
|strcmp|-style delta value. For |Works::compare|, see below...)
|strcmp|-style delta value.)
=
int Works::match(inbuild_work *eid1, inbuild_work *eid2) {
@ -141,7 +175,8 @@ int Works::match(inbuild_work *eid1, inbuild_work *eid2) {
return TRUE;
}
@ These are quite a deal slower, but trichotomous.
@ These are quite a deal slower, but are trichotomous and can be used for
sorting.
=
int Works::compare(inbuild_work *eid1, inbuild_work *eid2) {
@ -176,9 +211,9 @@ int Works::compare_by_length(inbuild_work *eid1, inbuild_work *eid2) {
return Str::cmp(eid1->author_name, eid2->author_name);
}
@ Because the Standard Rules are treated slightly differently by the
documentation, and so forth, it's convenient to provide a single function
testing if a work refers to them.
@ Because Basic Inform and the Standard Rules extensions are treated slightly
differently by the documentation, and so forth, it's convenient to provide a
single function testing if a work refers to them.
=
inbuild_work *a_work_for_standard_rules = NULL;
@ -408,25 +443,6 @@ void Works::log_work_hash_table(void) {
LOG("%d entries in all\n", total);
}
@h How casing is normalised.
Every word is capitalised, where a word begins at the start of the text,
after a hyphen, or after a bracket. Thus "Every Word Counts", "Even
Double-Barrelled Ones (And Even Parenthetically)".
=
void Works::normalise_casing(text_stream *p) {
int boundary = TRUE;
LOOP_THROUGH_TEXT(pos, p) {
wchar_t c = Str::get(pos);
if (boundary) Str::put(pos, Characters::toupper(c));
else Str::put(pos, Characters::tolower(c));
boundary = FALSE;
if (c == ' ') boundary = TRUE;
if (c == '-') boundary = TRUE;
if (c == '(') boundary = TRUE;
}
}
@h Documentation links.
This is where HTML links to extension documentation are created; the URL for
each extension's page is generated from its |inbuild_work|.

View file

@ -233,7 +233,7 @@ void Graphs::archive_r(OUTPUT_STREAM, build_vertex *V, int true_depth, inbuild_n
WRITE(" -- already there\n");
} else {
WRITE(" -- archiving\n");
Nests::copy_to(C, N, TRUE, BM);
Copies::copy_to(C, N, TRUE, BM);
}
DISCARD_TEXT(nl);
DISCARD_TEXT(cl);

View file

@ -35,7 +35,7 @@ int InterSkill::assimilate_internally(build_skill *skill, build_step *S, build_m
inbuild_requirement *req =
Requirements::any_version_of(Works::new(pipeline_genre, I"assimilate.interpipeline", NULL));
inbuild_search_result *R = Nests::first_found(req, Inbuild::nest_list());
inbuild_search_result *R = Nests::search_for_best(req, Inbuild::nest_list());
if (R == NULL) {
Errors::nowhere("assimilate pipeline could not be found");
return FALSE;
@ -82,7 +82,7 @@ int InterSkill::code_generate_internally(build_skill *skill, build_step *S, buil
if (F == NULL) {
inbuild_requirement *req =
Requirements::any_version_of(Works::new(pipeline_genre, inter_pipeline_name, NULL));
inbuild_search_result *R = Nests::first_found(req, Inbuild::nest_list());
inbuild_search_result *R = Nests::search_for_best(req, Inbuild::nest_list());
if (R == NULL) {
Errors::with_text("inter pipeline '%S' could not be found", inter_pipeline_name);
return FALSE;

View file

@ -57,8 +57,10 @@ inbuild_copy *ExtensionManager::new_copy(filename *F) {
C = Dictionaries::read_value(ext_copy_cache, key);
if (C == NULL) {
C = Copies::new_in_file(
Editions::new(Works::new(extension_genre, I"Untitled", I"Anonymous"),
VersionNumbers::null()), F, NULL_GENERAL_POINTER);
Editions::new(
Works::new(extension_genre, I"Untitled", I"Anonymous"),
VersionNumbers::null()),
F);
Extensions::scan(C);
if (Works::is_standard_rules(C->edition->work))
Extensions::make_standard(ExtensionManager::from_copy(C));
@ -169,7 +171,7 @@ void ExtensionManager::copy_to_nest(inbuild_genre *gen, inbuild_copy *C, inbuild
DISCARD_TEXT(leaf);
if (TextFiles::exists(F)) {
if (syncing == FALSE) { Nests::overwrite_error(N, C); return; }
if (syncing == FALSE) { Copies::overwrite_error(C, N); return; }
} else {
if (meth->methodology == DRY_RUN_METHODOLOGY) {
TEMPORARY_TEXT(command);
@ -211,7 +213,7 @@ void ExtensionManager::building_soon(inbuild_genre *gen, inbuild_copy *C, build_
}
void ExtensionManager::ensure_graphed(inbuild_copy *C) {
Copies::read_source_text_for(C);
Copies::get_source_text(C);
Inclusions::traverse(C, ExtensionManager::from_copy(C)->syntax_tree);
build_vertex *V;
LOOP_OVER_LINKED_LIST(V, build_vertex, C->vertex->use_edges)

View file

@ -50,7 +50,7 @@ inbuild_copy *KitManager::new_copy(text_stream *name, pathname *P) {
if (C == NULL) {
inbuild_work *work = Works::new_raw(kit_genre, Str::duplicate(name), NULL);
inbuild_edition *edition = Editions::new(work, VersionNumbers::null());
C = Copies::new_in_path(edition, P, NULL_GENERAL_POINTER);
C = Copies::new_in_path(edition, P);
Kits::scan(C);
Dictionaries::create(kit_copy_cache, key);
Dictionaries::write_value(kit_copy_cache, key, C);
@ -138,7 +138,7 @@ void KitManager::copy_to_nest(inbuild_genre *gen, inbuild_copy *C, inbuild_nest
pathname *dest_kit = KitManager::pathname_in_nest(N, C->edition);
filename *dest_kit_metadata = Filenames::in_folder(dest_kit, I"kit_metadata.txt");
if (TextFiles::exists(dest_kit_metadata)) {
if (syncing == FALSE) { Nests::overwrite_error(N, C); return; }
if (syncing == FALSE) { Copies::overwrite_error(C, N); return; }
} else {
if (meth->methodology == DRY_RUN_METHODOLOGY) {
TEMPORARY_TEXT(command);

View file

@ -51,7 +51,8 @@ inbuild_copy *LanguageManager::new_copy(text_stream *name, pathname *P) {
inform_language *K = Languages::new_il(name, P);
inbuild_work *work = Works::new(language_genre, Str::duplicate(name), NULL);
inbuild_edition *edition = Editions::new(work, K->version);
C = Copies::new_in_path(edition, P, STORE_POINTER_inform_language(K));
C = Copies::new_in_path(edition, P);
Copies::set_content(C, STORE_POINTER_inform_language(K));
K->as_copy = C;
Dictionaries::create(language_copy_cache, key);
Dictionaries::write_value(language_copy_cache, key, C);
@ -143,7 +144,7 @@ void LanguageManager::copy_to_nest(inbuild_genre *gen, inbuild_copy *C, inbuild_
pathname *dest_language = LanguageManager::pathname_in_nest(N, C->edition);
filename *dest_language_metadata = Filenames::in_folder(dest_language, I"about.txt");
if (TextFiles::exists(dest_language_metadata)) {
if (syncing == FALSE) { Nests::overwrite_error(N, C); return; }
if (syncing == FALSE) { Copies::overwrite_error(C, N); return; }
} else {
if (meth->methodology == DRY_RUN_METHODOLOGY) {
TEMPORARY_TEXT(command);

View file

@ -41,7 +41,8 @@ inform_pipeline *PipelineManager::from_copy(inbuild_copy *C) {
inbuild_copy *PipelineManager::new_copy(inbuild_edition *edition, filename *F) {
inform_pipeline *E = Pipelines::new_ip(edition->work->title, F);
inbuild_copy *C = Copies::new_in_file(edition, F, STORE_POINTER_inform_pipeline(E));
inbuild_copy *C = Copies::new_in_file(edition, F);
Copies::set_content(C, STORE_POINTER_inform_pipeline(E));
E->as_copy = C;
return C;
}
@ -123,7 +124,7 @@ void PipelineManager::copy_to_nest(inbuild_genre *gen, inbuild_copy *C, inbuild_
filename *F = PipelineManager::filename_in_nest(N, C->edition);
if (TextFiles::exists(F)) {
if (syncing == FALSE) { Nests::overwrite_error(N, C); return; }
if (syncing == FALSE) { Copies::overwrite_error(C, N); return; }
} else {
if (meth->methodology == DRY_RUN_METHODOLOGY) {
TEMPORARY_TEXT(command);

View file

@ -36,7 +36,8 @@ inbuild_copy *ProjectBundleManager::new_copy(text_stream *name, pathname *P) {
inform_project *K = Projects::new_ip(name, NULL, P);
inbuild_work *work = Works::new(project_bundle_genre, Str::duplicate(name), NULL);
inbuild_edition *edition = Editions::new(work, K->version);
K->as_copy = Copies::new_in_path(edition, P, STORE_POINTER_inform_project(K));
K->as_copy = Copies::new_in_path(edition, P);
Copies::set_content(K->as_copy, STORE_POINTER_inform_project(K));
return K->as_copy;
}

View file

@ -36,7 +36,8 @@ inbuild_copy *ProjectFileManager::new_copy(text_stream *name, filename *F) {
inform_project *K = Projects::new_ip(name, F, NULL);
inbuild_work *work = Works::new(project_file_genre, Str::duplicate(name), NULL);
inbuild_edition *edition = Editions::new(work, K->version);
K->as_copy = Copies::new_in_file(edition, F, STORE_POINTER_inform_project(K));
K->as_copy = Copies::new_in_file(edition, F);
Copies::set_content(K->as_copy, STORE_POINTER_inform_project(K));
return K->as_copy;
}

View file

@ -41,7 +41,8 @@ inbuild_copy *TemplateManager::new_copy(text_stream *name, pathname *P) {
inform_template *K = Templates::new_it(name, P);
inbuild_work *work = Works::new(template_genre, Str::duplicate(name), NULL);
inbuild_edition *edition = Editions::new(work, K->version);
K->as_copy = Copies::new_in_path(edition, P, STORE_POINTER_inform_template(K));
K->as_copy = Copies::new_in_path(edition, P);
Copies::set_content(K->as_copy, STORE_POINTER_inform_template(K));
return K->as_copy;
}
@ -121,7 +122,7 @@ void TemplateManager::copy_to_nest(inbuild_genre *gen, inbuild_copy *C, inbuild_
filename *canary1 = Filenames::in_folder(P, I"(manifest).txt");
filename *canary2 = Filenames::in_folder(P, I"index.html");
if ((TextFiles::exists(canary1)) || (TextFiles::exists(canary2))) {
if (syncing == FALSE) { Nests::overwrite_error(N, C); return; }
if (syncing == FALSE) { Copies::overwrite_error(C, N); return; }
} else {
if (meth->methodology == DRY_RUN_METHODOLOGY) {
TEMPORARY_TEXT(command);

View file

@ -154,7 +154,7 @@ void Extensions::Census::transcribe_census_errors(OUTPUT_STREAM, extension_censu
HTML_OPEN("p");
#endif
WRITE("<b>%X</b> - ", R->copy->edition->work);
Copies::write_problem(OUT, CE);
CopyErrors::write(OUT, CE);
HTML_CLOSE("p");
}
}

View file

@ -135,7 +135,7 @@ calls.
Feeds::feed_text(L"This sentence provides a firebreak, no more. ");
E = Extensions::Documentation::load(work);
if (E == NULL) return 0; /* shouldn't happen: it was there only moments ago */
Copies::read_source_text_for(E->as_copy);
Copies::get_source_text(E->as_copy);
Extensions::Documentation::write_extension_documentation(NULL, E, census_mode);
@ We now make much the same "paste into the gap in the template" copying

View file

@ -48,10 +48,10 @@ void Extensions::scan(inbuild_copy *C) {
if (Str::len(claimed_title) == 0) { WRITE_TO(claimed_title, "Unknown"); }
if (Str::len(claimed_author_name) == 0) { WRITE_TO(claimed_author_name, "Anonymous"); }
if (Str::len(claimed_title) > MAX_EXTENSION_TITLE_LENGTH) {
Copies::attach(C, Copies::new_error_N(EXT_TITLE_TOO_LONG_CE, Str::len(claimed_title)));
Copies::attach_error(C, CopyErrors::new_N(EXT_TITLE_TOO_LONG_CE, -1, Str::len(claimed_title)));
}
if (Str::len(claimed_author_name) > MAX_EXTENSION_AUTHOR_LENGTH) {
Copies::attach(C, Copies::new_error_N(EXT_AUTHOR_TOO_LONG_CE, Str::len(claimed_author_name)));
Copies::attach_error(C, CopyErrors::new_N(EXT_AUTHOR_TOO_LONG_CE, -1, Str::len(claimed_author_name)));
}
C->edition = Editions::new(Works::new(extension_genre, claimed_title, claimed_author_name), V);
if (Str::len(reqs) > 0) {
@ -60,7 +60,7 @@ void Extensions::scan(inbuild_copy *C) {
else {
TEMPORARY_TEXT(err);
WRITE_TO(err, "cannot read compatibility '%S'", reqs);
Copies::attach(C, Copies::new_error(EXT_MISWORDED_CE, err));
Copies::attach_error(C, CopyErrors::new_T(EXT_MISWORDED_CE, -1, err));
DISCARD_TEXT(err);
}
}
@ -80,7 +80,7 @@ alone, and the version number is returned.
TEMPORARY_TEXT(version_text);
FILE *EXTF = Filenames::fopen_caseless(F, "r");
if (EXTF == NULL) {
Copies::attach(C, Copies::new_error_on_file(OPEN_FAILED_CE, F));
Copies::attach_error(C, CopyErrors::new_F(OPEN_FAILED_CE, -1, F));
} else {
@<Read the titling line of the extension and normalise its casing@>;
@<Read the rubric text, if any is present@>;
@ -91,7 +91,7 @@ alone, and the version number is returned.
if (VersionNumbers::is_null(V)) {
TEMPORARY_TEXT(error_text);
WRITE_TO(error_text, "the version number '%S' is malformed", version_text);
Copies::attach(C, Copies::new_error(EXT_MISWORDED_CE, error_text));
Copies::attach_error(C, CopyErrors::new_T(EXT_MISWORDED_CE, -1, error_text));
DISCARD_TEXT(error_text);
}
}
@ -151,7 +151,7 @@ load the entire file.
(Regexp::match(&mr, titling_line, L"(%c*) Starts Here"))) {
Str::copy(titling_line, mr.exp[0]);
}
Copies::attach(C, Copies::new_error(EXT_MISWORDED_CE,
Copies::attach_error(C, CopyErrors::new_T(EXT_MISWORDED_CE, -1,
I"the opening line does not end 'begin(s) here'"));
}
@<Scan the version text, if any, and advance to the position past Version... Of@>;
@ -181,7 +181,7 @@ not a situation we need to contend with.
Str::copy(claimed_author_name, mr.exp[1]);
} else {
Str::copy(claimed_title, titling_line);
Copies::attach(C, Copies::new_error(EXT_MISWORDED_CE,
Copies::attach_error(C, CopyErrors::new_T(EXT_MISWORDED_CE, -1,
I"the titling line does not give both author and title"));
}

View file

@ -71,7 +71,7 @@ void Kits::read_metadata(text_stream *text, text_file_position *tfp, void *state
else {
TEMPORARY_TEXT(err);
WRITE_TO(err, "cannot read compatibility '%S'", mr.exp[0]);
Copies::attach(C, Copies::new_error(KIT_MISWORDED_CE, err));
Copies::attach_error(C, CopyErrors::new_T(KIT_MISWORDED_CE, -1, err));
DISCARD_TEXT(err);
}
} else if (Regexp::match(&mr, text, L"defines Main: yes")) {
@ -106,7 +106,7 @@ void Kits::read_metadata(text_stream *text, text_file_position *tfp, void *state
} else {
TEMPORARY_TEXT(err);
WRITE_TO(err, "unreadable instruction '%S'", text);
Copies::attach(C, Copies::new_error(KIT_MISWORDED_CE, err));
Copies::attach_error(C, CopyErrors::new_T(KIT_MISWORDED_CE, -1, err));
DISCARD_TEXT(err);
}
Regexp::dispose_of(&mr);
@ -115,7 +115,7 @@ void Kits::read_metadata(text_stream *text, text_file_position *tfp, void *state
inform_kit *Kits::load(text_stream *name, linked_list *nest_list) {
inbuild_requirement *req =
Requirements::any_version_of(Works::new(kit_genre, name, I""));
inbuild_search_result *R = Nests::first_found(req, nest_list);
inbuild_search_result *R = Nests::search_for_best(req, nest_list);
if (R == NULL) Errors::fatal_with_text("cannot find kit", name);
inbuild_copy *C = R->copy;
if (C->vertex == NULL) KitManager::build_vertex(C);

View file

@ -149,7 +149,7 @@ inform_language *Languages::internal_English(void) {
if (I) {
linked_list *L = NEW_LINKED_LIST(inbuild_nest);
ADD_TO_LINKED_LIST(I, inbuild_nest, L);
inbuild_search_result *R = Nests::first_found(req, L);
inbuild_search_result *R = Nests::search_for_best(req, L);
if (R) return LanguageManager::from_copy(R->copy);
}
return NULL;

View file

@ -405,7 +405,7 @@ void Projects::read_source_text_for(inform_project *project) {
Headings::satisfy_dependencies(project->syntax_tree, project->as_copy);
#ifndef CORE_MODULE
Copies::list_problems_arising(STDERR, project->as_copy);
Copies::list_attached_errors(STDERR, project->as_copy);
#endif
}
@ -433,10 +433,9 @@ void Projects::notify_of_bibliographic_sentence(inform_project *project, parse_n
@<Extract title and author name wording@>;
@<Dequote the title and, perhaps, author name@>;
} else {
copy_error *CE = Copies::new_error(SYNTAX_CE, NULL);
CE->error_subcategory = BadTitleSentence_SYNERROR;
CE->details_node = PN;
Copies::attach(project->as_copy, CE);
copy_error *CE = CopyErrors::new(SYNTAX_CE, BadTitleSentence_SYNERROR);
CopyErrors::supply_node(CE, PN);
Copies::attach_error(project->as_copy, CE);
}
}

View file

@ -330,17 +330,15 @@ allowed; they should probably be withdrawn.
@<Issue PM_UnknownLanguageElement problem@> =
#ifdef CORE_MODULE
copy_error *CE = Copies::new_error(SYNTAX_CE, NULL);
CE->error_subcategory = UnknownLanguageElement_SYNERROR;
CE->details_node = current_sentence;
Copies::attach(sfsm_copy, CE);
copy_error *CE = CopyErrors::new(SYNTAX_CE, UnknownLanguageElement_SYNERROR);
CopyErrors::supply_node(CE, current_sentence);
Copies::attach_error(sfsm_copy, CE);
#endif
@<Issue PM_UnknownVirtualMachine problem@> =
copy_error *CE = Copies::new_error(SYNTAX_CE, NULL);
CE->error_subcategory = UnknownVirtualMachine_SYNERROR;
CE->details_node = current_sentence;
Copies::attach(sfsm_copy, CE);
copy_error *CE = CopyErrors::new(SYNTAX_CE, UnknownVirtualMachine_SYNERROR);
CopyErrors::supply_node(CE, current_sentence);
Copies::attach_error(sfsm_copy, CE);
@<Set for-use-with extension identifier@> =
*X = R[0] + 4;
@ -638,11 +636,10 @@ void Headings::satisfy_individual_heading_dependency(parse_node_tree *T, inbuild
}
@<Can't replace heading in an unincluded extension@> =
copy_error *CE = Copies::new_error(SYNTAX_CE, NULL);
CE->error_subcategory = HeadingInPlaceOfUnincluded_SYNERROR;
CE->details_node = h->sentence_declaring;
CE->details_work = h->for_use_with;
Copies::attach(C, CE);
copy_error *CE = CopyErrors::new(SYNTAX_CE, HeadingInPlaceOfUnincluded_SYNERROR);
CopyErrors::supply_node(CE, h->sentence_declaring);
CopyErrors::supply_work(CE, h->for_use_with);
Copies::attach_error(C, CE);
@ To excise, we simply prune the heading's contents from the parse tree,
though optionally grafting them to another node rather than discarding them
@ -690,13 +687,10 @@ void Headings::suppress_dependencies(parse_node *pn) {
}
@<Can't replace heading subordinate to another replaced heading@> =
copy_error *CE = Copies::new_error(SYNTAX_CE, NULL);
CE->error_subcategory = HeadingInPlaceOfSubordinate_SYNERROR;
CE->details_node = h2->sentence_declaring;
CE->details_work = h2->for_use_with;
CE->details_work2 = h->for_use_with;
CE->details_node2 = h->sentence_declaring;
Copies::attach(C, CE);
copy_error *CE = CopyErrors::new(SYNTAX_CE, HeadingInPlaceOfSubordinate_SYNERROR);
CopyErrors::supply_works(CE, h2->for_use_with, h->for_use_with);
CopyErrors::supply_nodes(CE, h2->sentence_declaring, h->sentence_declaring);
Copies::attach_error(C, CE);
@<Can't find heading in the given extension@> =
TEMPORARY_TEXT(vt);
@ -707,17 +701,14 @@ void Headings::suppress_dependencies(parse_node *pn) {
Str::clear(vt);
VersionNumbers::to_text(vt, E->as_copy->edition->version);
}
copy_error *CE = Copies::new_error(SYNTAX_CE, NULL);
CE->error_subcategory = HeadingInPlaceOfUnknown_SYNERROR;
CE->details_node = h->sentence_declaring;
CE->details_work = h->for_use_with;
CE->details_W = h->in_place_of_text;
CE->details = Str::duplicate(vt);
Copies::attach(C, CE);
copy_error *CE = CopyErrors::new_T(SYNTAX_CE, HeadingInPlaceOfUnknown_SYNERROR, vt);
CopyErrors::supply_node(CE, h->sentence_declaring);
CopyErrors::supply_work(CE, h->for_use_with);
CopyErrors::supply_wording(CE, h->in_place_of_text);
Copies::attach_error(C, CE);
DISCARD_TEXT(vt);
@<Can't replace heading unless level matches@> =
copy_error *CE = Copies::new_error(SYNTAX_CE, NULL);
CE->error_subcategory = UnequalHeadingInPlaceOf_SYNERROR;
CE->details_node = h->sentence_declaring;
Copies::attach(C, CE);
copy_error *CE = CopyErrors::new(SYNTAX_CE, UnequalHeadingInPlaceOf_SYNERROR);
CopyErrors::supply_node(CE, h->sentence_declaring);
Copies::attach_error(C, CE);

View file

@ -105,10 +105,9 @@ void Inclusions::visit(parse_node_tree *T, parse_node *pn, parse_node *last_H0,
@<Issue PM_IncludeExtQuoted problem@> =
<<t1>> = -1; <<t2>> = -1;
copy_error *CE = Copies::new_error(SYNTAX_CE, NULL);
CE->error_subcategory = IncludeExtQuoted_SYNERROR;
CE->details_node = current_sentence;
Copies::attach(inclusions_errors_to, CE);
copy_error *CE = CopyErrors::new(SYNTAX_CE, IncludeExtQuoted_SYNERROR);
CopyErrors::supply_node(CE, current_sentence);
Copies::attach_error(inclusions_errors_to, CE);
@ This internal parses version text such as "12/110410".
@ -184,7 +183,7 @@ inform_extension *Inclusions::load(parse_node *last_H0, parse_node *at, inbuild_
}
@<Read the extension file into the lexer, and break it into body and documentation@> =
inbuild_search_result *search_result = Nests::first_found(req, Inbuild::nest_list());
inbuild_search_result *search_result = Nests::search_for_best(req, Inbuild::nest_list());
if (search_result) {
E = ExtensionManager::from_copy(search_result->copy);
Extensions::set_inclusion_sentence(E, at);
@ -195,10 +194,10 @@ inform_extension *Inclusions::load(parse_node *last_H0, parse_node *at, inbuild_
@<Issue a problem message saying that the VM does not meet requirements@>;
if (LinkedLists::len(search_result->copy->errors_reading_source_text) == 0) {
Copies::read_source_text_for(search_result->copy);
Copies::get_source_text(search_result->copy);
}
#ifndef CORE_MODULE
Copies::list_problems_arising(STDERR, search_result->copy);
Copies::list_attached_errors(STDERR, search_result->copy);
#endif
} else {
#ifdef CORE_MODULE
@ -215,21 +214,18 @@ matter of removing the inclusion, not of altering the extension, so we
report this problem at the inclusion line.
@<Issue a problem message saying that the VM does not meet requirements@> =
copy_error *CE = Copies::new_error(SYNTAX_CE, NULL);
CE->error_subcategory = ExtInadequateVM_SYNERROR;
CE->details_node = Extensions::get_inclusion_sentence(E);
CE->details = C->parsed_from;
Copies::attach(inclusions_errors_to, CE);
copy_error *CE = CopyErrors::new_T(SYNTAX_CE, ExtInadequateVM_SYNERROR, C->parsed_from);
CopyErrors::supply_node(CE, Extensions::get_inclusion_sentence(E));
Copies::attach_error(inclusions_errors_to, CE);
@<Issue a cannot-find problem@> =
inbuild_requirement *req2 = Requirements::any_version_of(req->work);
linked_list *L = NEW_LINKED_LIST(inbuild_search_result);
Nests::search_for(req2, Inbuild::nest_list(), L);
if (LinkedLists::len(L) == 0) {
copy_error *CE = Copies::new_error(SYNTAX_CE, NULL);
CE->error_subcategory = BogusExtension_SYNERROR;
CE->details_node = current_sentence;
Copies::attach(inclusions_errors_to, CE);
copy_error *CE = CopyErrors::new(SYNTAX_CE, BogusExtension_SYNERROR);
CopyErrors::supply_node(CE, current_sentence);
Copies::attach_error(inclusions_errors_to, CE);
} else {
TEMPORARY_TEXT(versions);
inbuild_search_result *search_result;
@ -239,11 +235,9 @@ report this problem at the inclusion line.
if (VersionNumbers::is_null(V)) WRITE_TO(versions, "an unnumbered version");
else WRITE_TO(versions, "version %v", &V);
}
copy_error *CE = Copies::new_error(SYNTAX_CE, NULL);
CE->error_subcategory = ExtVersionTooLow_SYNERROR;
CE->details_node = at;
CE->details = Str::duplicate(versions);
Copies::attach(inclusions_errors_to, CE);
copy_error *CE = CopyErrors::new_T(SYNTAX_CE, ExtVersionTooLow_SYNERROR, versions);
CopyErrors::supply_node(CE, at);
Copies::attach_error(inclusions_errors_to, CE);
DISCARD_TEXT(versions);
}
@ -270,10 +264,9 @@ version number text.
if (last_PM_ExtVersionMalformed_at != vwn) {
last_PM_ExtVersionMalformed_at = vwn;
LOG("Offending word number %d <%N>\n", vwn, vwn);
copy_error *CE = Copies::new_error(SYNTAX_CE, NULL);
CE->error_subcategory = ExtVersionMalformed_SYNERROR;
CE->details_node = current_sentence;
Copies::attach(inclusions_errors_to, CE);
copy_error *CE = CopyErrors::new(SYNTAX_CE, ExtVersionMalformed_SYNERROR);
CopyErrors::supply_node(CE, current_sentence);
Copies::attach_error(inclusions_errors_to, CE);
}
@h Checking the begins here and ends here sentences.
@ -305,10 +298,9 @@ problem messages if it is malformed.
... ==> @<Issue problem@>
@<Issue problem@> =
copy_error *CE = Copies::new_error(SYNTAX_CE, NULL);
CE->error_subcategory = ExtNoBeginsHere_SYNERROR;
CE->details_node = current_sentence;
Copies::attach(inclusions_errors_to, CE);
copy_error *CE = CopyErrors::new(SYNTAX_CE, ExtNoBeginsHere_SYNERROR);
CopyErrors::supply_node(CE, current_sentence);
Copies::attach_error(inclusions_errors_to, CE);
@ =
void Inclusions::check_begins_here(parse_node *PN, inform_extension *E) {
@ -335,11 +327,10 @@ void Inclusions::check_ends_here(parse_node *PN, inform_extension *E) {
if (<the-prefix-for-extensions>(W)) W = GET_RW(<the-prefix-for-extensions>, 1);
wording T = Feeds::feed_stream(E->as_copy->edition->work->title);
if ((problem_count == 0) && (Wordings::match(T, W) == FALSE)) {
copy_error *CE = Copies::new_error(SYNTAX_CE, NULL);
CE->error_subcategory = ExtMisidentifiedEnds_SYNERROR;
CE->details_node = PN;
CE->details_W = ParseTree::get_text(PN);
Copies::attach(inclusions_errors_to, CE);
copy_error *CE = CopyErrors::new(SYNTAX_CE, ExtMisidentifiedEnds_SYNERROR);
CopyErrors::supply_node(CE, PN);
CopyErrors::supply_wording(CE, ParseTree::get_text(PN));
Copies::attach_error(inclusions_errors_to, CE);
}
inclusions_errors_to = S;
}

View file

@ -23,7 +23,7 @@ source_file *SourceText::read_file(inbuild_copy *C, filename *F, text_stream *sy
sf = TextFromFiles::feed_open_file_into_lexer(F, handle,
leaf, documentation_only, ref);
if (sf == NULL) {
Copies::attach(C, Copies::new_error_on_file(OPEN_FAILED_CE, F));
Copies::attach_error(C, CopyErrors::new_F(OPEN_FAILED_CE, -1, F));
} else {
fclose(handle);
#ifdef CORE_MODULE
@ -63,37 +63,10 @@ application.
void SourceText::lexer_problem_handler(int err, text_stream *desc, wchar_t *word) {
if (err == MEMORY_OUT_LEXERERROR)
Errors::fatal("Out of memory: unable to create lexer workspace");
TEMPORARY_TEXT(erm);
switch (err) {
case STRING_TOO_LONG_LEXERERROR:
WRITE_TO(erm, "Too much text in quotation marks: %w", word);
break;
case WORD_TOO_LONG_LEXERERROR:
WRITE_TO(erm, "Word too long: %w", word);
break;
case I6_TOO_LONG_LEXERERROR:
WRITE_TO(erm, "I6 inclusion too long: %w", word);
break;
case STRING_NEVER_ENDS_LEXERERROR:
WRITE_TO(erm, "Quoted text never ends: %S", desc);
break;
case COMMENT_NEVER_ENDS_LEXERERROR:
WRITE_TO(erm, "Square-bracketed text never ends: %S", desc);
break;
case I6_NEVER_ENDS_LEXERERROR:
WRITE_TO(erm, "I6 inclusion text never ends: %S", desc);
break;
default:
internal_error("unknown lexer error");
}
if (currently_lexing_into) {
copy_error *CE = Copies::new_error(LEXER_CE, erm);
CE->error_subcategory = err;
CE->details = Str::duplicate(desc);
CE->word = word;
Copies::attach(currently_lexing_into, CE);
copy_error *CE = CopyErrors::new_WT(LEXER_CE, err, word, desc);
Copies::attach_error(currently_lexing_into, CE);
}
DISCARD_TEXT(erm);
}
@
@ -107,11 +80,9 @@ void SourceText::lexer_problem_handler(int err, text_stream *desc, wchar_t *word
=
void SourceText::syntax_problem_handler(int err_no, wording W, void *ref, int k) {
inbuild_copy *C = (inbuild_copy *) ref;
copy_error *CE = Copies::new_error(SYNTAX_CE, NULL);
CE->error_subcategory = err_no;
CE->details_W = W;
CE->details_N = k;
Copies::attach(C, CE);
copy_error *CE = CopyErrors::new_N(SYNTAX_CE, err_no, k);
CopyErrors::supply_wording(CE, W);
Copies::attach_error(C, CE);
}
@ Sentences in the source text are of five categories: dividing sentences,
@ -278,8 +249,7 @@ void SourceText::new_beginend(parse_node *new, inbuild_copy *C) {
=
void SourceText::new_language(wording W) {
copy_error *CE = Copies::new_error(SYNTAX_CE, NULL);
CE->error_subcategory = UseElementWithdrawn_SYNERROR;
CE->details_node = current_sentence;
Copies::attach(sfsm_copy, CE);
copy_error *CE = CopyErrors::new(SYNTAX_CE, UseElementWithdrawn_SYNERROR);
CopyErrors::supply_node(CE, current_sentence);
Copies::attach_error(sfsm_copy, CE);
}

View file

@ -13,6 +13,7 @@ Chapter 2: Conceptual Framework
Works
Editions
Copies
Copy Errors
Requirements
Nests

View file

@ -14,7 +14,7 @@ void SourceProblems::issue_problems_arising(inbuild_copy *C) {
LOOP_OVER_LINKED_LIST(CE, copy_error, C->errors_reading_source_text) {
switch (CE->error_category) {
case OPEN_FAILED_CE:
Problems::quote_stream(1, Filenames::get_leafname(CE->file));
Problems::quote_stream(1, Filenames::get_leafname(CE->details_file));
Problems::Issue::handmade_problem(Task::syntax_tree(), _p_(Untestable));
Problems::issue_problem_segment(
"I can't open the file '%1' of source text. %P"
@ -25,7 +25,7 @@ void SourceProblems::issue_problems_arising(inbuild_copy *C) {
break;
case EXT_MISWORDED_CE:
Problems::quote_work(1, CE->copy->found_by->work);
Problems::quote_stream(2, CE->notes);
Problems::quote_stream(2, CE->details);
Problems::Issue::handmade_problem(Task::syntax_tree(), _p_(PM_ExtMiswordedBeginsHere));
Problems::issue_problem_segment(
"The extension %1, which your source text makes use of, seems to be "
@ -35,7 +35,7 @@ void SourceProblems::issue_problems_arising(inbuild_copy *C) {
break;
case KIT_MISWORDED_CE:
Problems::quote_work(1, CE->copy->found_by->work);
Problems::quote_stream(2, CE->notes);
Problems::quote_stream(2, CE->details);
Problems::Issue::handmade_problem(Task::syntax_tree(), _p_(Untestable));
Problems::issue_problem_segment(
"The kit %1, which your source text makes use of, seems to be "
@ -75,14 +75,14 @@ void SourceProblems::issue_problems_arising(inbuild_copy *C) {
switch (CE->error_subcategory) {
case STRING_TOO_LONG_LEXERERROR:
Problems::Issue::lexical_problem(Task::syntax_tree(), _p_(PM_TooMuchQuotedText),
"Too much text in quotation marks", CE->word,
"Too much text in quotation marks", CE->details_word,
"...\" The maximum length is very high, so this is more "
"likely to be because a close quotation mark was "
"forgotten.");
break;
case WORD_TOO_LONG_LEXERERROR:
Problems::Issue::lexical_problem(Task::syntax_tree(), _p_(PM_WordTooLong),
"Word too long", CE->word,
"Word too long", CE->details_word,
"(Individual words of unquoted text can run up to "
"128 letters long, which ought to be plenty. The longest "
"recognised place name in the English speaking world is "
@ -97,7 +97,7 @@ void SourceProblems::issue_problems_arising(inbuild_copy *C) {
break;
case I6_TOO_LONG_LEXERERROR:
Problems::Issue::lexical_problem(Task::syntax_tree(), _p_(Untestable), /* well, not at all conveniently */
"Verbatim Inform 6 extract too long", CE->word,
"Verbatim Inform 6 extract too long", CE->details_word,
"... -). The maximum length is quite high, so this "
"may be because a '-)' was forgotten. Still, if "
"you do need to paste a huge I6 program in, try "