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

Catching up on the woven form

This commit is contained in:
Graham Nelson 2020-02-27 11:18:25 +00:00
parent 0b70407916
commit 35978b0026
129 changed files with 14569 additions and 807 deletions

View file

@ -101,6 +101,7 @@ This repository is where development is done on the following executables:
* their unit test executables [★ words-test](docs/words-test/index.html), [★ inflections-test](docs/inflections-test/index.html), [★ syntax-test](docs/syntax-test/index.html), [★ problems-test](docs/problems-test/index.html), [★ linguistics-test](docs/linguistics-test/index.html), [★ kinds-test](docs/kinds-test/index.html)
* inblorb - The packaging stage of the Inform 7 system, which releases a story file in the blorbed format. - __version 4 'Duralumin'__ - [★ Web](docs/inblorb/index.html) - [▶ Documentation](docs/inblorb/P-ui.html)
* inbuild - A simple build and package manager for the Inform tools. - __version 1 'Avignon'__ - [★ Web](docs/inbuild/index.html) - [▶ Documentation](docs/inbuild/P-ui.html)
* its modules [★ inbuild](docs/inbuild-module/index.html), [★ arch](docs/arch-module/index.html), [★ html](docs/html-module/index.html)
* indoc - The documentation-formatter for the Inform 7 system. - __version 4 'Didache'__ - [★ Web](docs/indoc/index.html) - [▶ Documentation](docs/indoc/P-iti.html)
* inpolicy - A lint-like tool to check up on various policies used in Inform source code. - __version 1 'Plan A'__ - [★ Web](docs/inpolicy/index.html) - [▶ Documentation](docs/inpolicy/P-ui.html)
* inrtps - A generator of HTML pages to show for run-time problem messages in Inform. - __version 2 'Benefactive'__ - [★ Web](docs/inrtps/index.html) - [▶ Documentation](docs/inrtps/P-ui.html)

143
docs/arch-module/1-am.html Normal file
View file

@ -0,0 +1,143 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Booklet Title</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<!--Weave of '1/am' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">arch</a></li><li><a href="index.html#1">Chapter 1: Setting Up</a></li><li><b>Arch Module</b></li></ul><p class="purpose">Setting up the use of this module.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Introduction</a></li><li><a href="#SP3">&#167;3. The beginning</a></li><li><a href="#SP4">&#167;4. The end</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Introduction. </b></p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">ARCH_MODULE</span><span class="plain"> </span><span class="identifier">TRUE</span>
</pre>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>To begin with, this module needs to allocate memory:
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">inter_architecture_MT</span>
<span class="definitionkeyword">enum</span> <span class="constant">target_vm_MT</span>
<span class="definitionkeyword">enum</span> <span class="constant">compatibility_specification_MT</span>
<span class="definitionkeyword">enum</span> <span class="constant">semantic_version_number_holder_MT</span>
</pre>
<pre class="display">
<span class="identifier">ALLOCATE_INDIVIDUALLY</span><span class="plain">(</span><span class="reserved">inter_architecture</span><span class="plain">)</span>
<span class="identifier">ALLOCATE_INDIVIDUALLY</span><span class="plain">(</span><span class="reserved">target_vm</span><span class="plain">)</span>
<span class="identifier">ALLOCATE_INDIVIDUALLY</span><span class="plain">(</span><span class="reserved">compatibility_specification</span><span class="plain">)</span>
<span class="identifier">ALLOCATE_INDIVIDUALLY</span><span class="plain">(</span><span class="reserved">semantic_version_number_holder</span><span class="plain">)</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. The beginning. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">ArchModule::start</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
&lt;<span class="cwebmacro">Register this module's memory allocation reasons</span> <span class="cwebmacronumber">3.1</span>&gt;<span class="character">;</span>
&lt;<span class="cwebmacro">Register this module's stream writers</span> <span class="cwebmacronumber">3.2</span>&gt;<span class="character">;</span>
&lt;<span class="cwebmacro">Register this module's debugging log aspects</span> <span class="cwebmacronumber">3.3</span>&gt;<span class="character">;</span>
&lt;<span class="cwebmacro">Register this module's debugging log writers</span> <span class="cwebmacronumber">3.4</span>&gt;<span class="character">;</span>
&lt;<span class="cwebmacro">Register this module's command line switches</span> <span class="cwebmacronumber">3.5</span>&gt;<span class="character">;</span>
<span class="functiontext">Architectures::create</span><span class="plain">();</span>
<span class="functiontext">TargetVMs::create</span><span class="plain">();</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function ArchModule::start appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP3_1"></a><b>&#167;3.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Register this module's memory allocation reasons</span> <span class="cwebmacronumber">3.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP3_2"></a><b>&#167;3.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Register this module's stream writers</span> <span class="cwebmacronumber">3.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP3_3"></a><b>&#167;3.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">Register this module's debugging log aspects</span> <span class="cwebmacronumber">3.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP3_4"></a><b>&#167;3.4. </b><code class="display">
&lt;<span class="cwebmacrodefn">Register this module's debugging log writers</span> <span class="cwebmacronumber">3.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP3_5"></a><b>&#167;3.5. </b><code class="display">
&lt;<span class="cwebmacrodefn">Register this module's command line switches</span> <span class="cwebmacronumber">3.5</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="plain">;</span>
</pre>
<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. The end. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">ArchModule::end</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function ArchModule::end appears nowhere else.</p>
<hr class="tocbar">
<ul class="toc"><li><i>(This section begins Chapter 1: Setting Up.)</i></li><li><i>(This section ends Chapter 1: Setting Up.)</i></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>

108
docs/arch-module/2-arc.html Normal file
View file

@ -0,0 +1,108 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>2/vn</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<!--Weave of '2/arc' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">arch</a></li><li><a href="index.html#2">Chapter 2: Architectures</a></li><li><b>Architectures</b></li></ul><p class="purpose">To deal with multiple inter architectures.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Architectures</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Architectures. </b></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">inter_architecture</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">shorthand</span><span class="plain">; </span> <span class="comment">such as <code class="display"><span class="extract">32d</span></code></span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">sixteen_bit</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">debug_enabled</span><span class="plain">;</span>
<span class="identifier">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">inter_architecture</span><span class="plain">;</span>
<span class="reserved">inter_architecture</span><span class="plain"> *</span><span class="functiontext">Architectures::new</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">code</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">s</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">d</span><span class="plain">) {</span>
<span class="reserved">inter_architecture</span><span class="plain"> *</span><span class="identifier">A</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">inter_architecture</span><span class="plain">);</span>
<span class="identifier">A</span><span class="plain">-</span><span class="element">&gt;shorthand</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">code</span><span class="plain">);</span>
<span class="identifier">A</span><span class="plain">-</span><span class="element">&gt;sixteen_bit</span><span class="plain"> = </span><span class="identifier">s</span><span class="plain">;</span>
<span class="identifier">A</span><span class="plain">-</span><span class="element">&gt;debug_enabled</span><span class="plain"> = </span><span class="identifier">d</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">A</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Architectures::create</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="functiontext">Architectures::new</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"16"</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="functiontext">Architectures::new</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"16d"</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
<span class="functiontext">Architectures::new</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"32"</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="functiontext">Architectures::new</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"32d"</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">filename</span><span class="plain"> *</span><span class="functiontext">Architectures::canonical_binary</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">inter_architecture</span><span class="plain"> *</span><span class="identifier">A</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">A</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 arch"</span><span class="plain">);</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">leafname</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">leafname</span><span class="plain">, </span><span class="string">"arch-%S.interb"</span><span class="plain">, </span><span class="identifier">A</span><span class="plain">-</span><span class="element">&gt;shorthand</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">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">leafname</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">leafname</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">F</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">filename</span><span class="plain"> *</span><span class="functiontext">Architectures::canonical_textual</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">inter_architecture</span><span class="plain"> *</span><span class="identifier">A</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">A</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 arch"</span><span class="plain">);</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">leafname</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">leafname</span><span class="plain">, </span><span class="string">"arch-%S.intert"</span><span class="plain">, </span><span class="identifier">A</span><span class="plain">-</span><span class="element">&gt;shorthand</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">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">leafname</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">leafname</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">F</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="functiontext">Architectures::to_codename</span><span class="plain">(</span><span class="reserved">inter_architecture</span><span class="plain"> *</span><span class="identifier">A</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">A</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">A</span><span class="plain">-</span><span class="element">&gt;shorthand</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">inter_architecture</span><span class="plain"> *</span><span class="functiontext">Architectures::from_codename</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">inter_architecture</span><span class="plain"> *</span><span class="identifier">A</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">A</span><span class="plain">, </span><span class="reserved">inter_architecture</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">A</span><span class="plain">-</span><span class="element">&gt;shorthand</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">A</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>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Architectures::is_16_bit</span><span class="plain">(</span><span class="reserved">inter_architecture</span><span class="plain"> *</span><span class="identifier">A</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">A</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 arch"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">A</span><span class="plain">-</span><span class="element">&gt;sixteen_bit</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Architectures::debug_enabled</span><span class="plain">(</span><span class="reserved">inter_architecture</span><span class="plain"> *</span><span class="identifier">A</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">A</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 arch"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">A</span><span class="plain">-</span><span class="element">&gt;debug_enabled</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Architectures::new appears nowhere else.</p>
<p class="endnote">The function Architectures::create is used in 1/am (<a href="1-am.html#SP3">&#167;3</a>).</p>
<p class="endnote">The function Architectures::canonical_binary appears nowhere else.</p>
<p class="endnote">The function Architectures::canonical_textual appears nowhere else.</p>
<p class="endnote">The function Architectures::to_codename appears nowhere else.</p>
<p class="endnote">The function Architectures::from_codename is used in 2/tvm (<a href="2-tvm.html#SP1">&#167;1</a>).</p>
<p class="endnote">The function Architectures::is_16_bit is used in 2/tvm (<a href="2-tvm.html#SP1">&#167;1</a>).</p>
<p class="endnote">The function Architectures::debug_enabled is used in 2/tvm (<a href="2-tvm.html#SP1">&#167;1</a>).</p>
<p class="endnote">The structure inter_architecture is private to this section.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="2-vn.html">Back to 'Version Numbers'</a></li><li><a href="2-tvm.html">Continue with 'Target Virtual Machines'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>

334
docs/arch-module/2-cmp.html Normal file
View file

@ -0,0 +1,334 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>2/tvm</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<!--Weave of '2/cmp' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">arch</a></li><li><a href="index.html#2">Chapter 2: Architectures</a></li><li><b>Compatibility</b></li></ul><p class="purpose">To manage compatibility lists: what can be compiled to what format.</p>
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. </b></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">compatibility_specification</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">parsed_from</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">default_allows</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">exceptions</span><span class="plain">; </span> <span class="comment">of <code class="display"><span class="extract">target_vm</span></code></span>
<span class="identifier">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">compatibility_specification</span><span class="plain">;</span>
<span class="reserved">compatibility_specification</span><span class="plain"> *</span><span class="functiontext">Compatibility::all</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="reserved">compatibility_specification</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">compatibility_specification</span><span class="plain">);</span>
<span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;parsed_from</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="element">&gt;default_allows</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;exceptions</span><span class="plain"> = </span><span class="identifier">NEW_LINKED_LIST</span><span class="plain">(</span><span class="reserved">target_vm</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">int</span><span class="plain"> </span><span class="functiontext">Compatibility::universal</span><span class="plain">(</span><span class="reserved">compatibility_specification</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="identifier">FALSE</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">C</span><span class="plain">-</span><span class="element">&gt;exceptions</span><span class="plain">) &gt; 0) </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">C</span><span class="plain">-</span><span class="element">&gt;default_allows</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Compatibility::write</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">compatibility_specification</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">WRITE</span><span class="plain">(</span><span class="string">"for none"</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">x</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;exceptions</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">x</span><span class="plain"> == 0) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;default_allows</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"for all"</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">"for none"</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">C</span><span class="plain">-</span><span class="element">&gt;default_allows</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"not "</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"for "</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">n</span><span class="plain"> = 0;</span>
<span class="reserved">target_vm</span><span class="plain"> *</span><span class="identifier">VM</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">VM</span><span class="plain">, </span><span class="reserved">target_vm</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;exceptions</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) &amp;&amp; (</span><span class="identifier">n</span><span class="plain"> &lt; </span><span class="identifier">x</span><span class="plain">)) </span><span class="identifier">WRITE</span><span class="plain">(</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; 1) &amp;&amp; (</span><span class="identifier">n</span><span class="plain"> == </span><span class="identifier">x</span><span class="plain">)) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" or "</span><span class="plain">);</span>
<span class="functiontext">TargetVMs::write</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">VM</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">compatibility_specification</span><span class="plain"> *</span><span class="functiontext">Compatibility::from_text</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">text</span><span class="plain">) {</span>
<span class="reserved">compatibility_specification</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain"> = </span><span class="functiontext">Compatibility::all</span><span class="plain">();</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">incorrect</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">Str::len</span><span class="plain">(</span><span class="identifier">text</span><span class="plain">) == 0) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">C</span><span class="plain">;</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">parse</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">parse</span><span class="plain">, </span><span class="string">"%S"</span><span class="plain">, </span><span class="identifier">text</span><span class="plain">);</span>
<span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;parsed_from</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">parse</span><span class="plain">);</span>
<span class="identifier">Str::trim_white_space</span><span class="plain">(</span><span class="identifier">parse</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Str::get_first_char</span><span class="plain">(</span><span class="identifier">parse</span><span class="plain">) == </span><span class="character">'('</span><span class="plain">) &amp;&amp; (</span><span class="identifier">Str::get_last_char</span><span class="plain">(</span><span class="identifier">parse</span><span class="plain">) == </span><span class="character">')'</span><span class="plain">)) {</span>
<span class="identifier">Str::delete_first_character</span><span class="plain">(</span><span class="identifier">parse</span><span class="plain">);</span>
<span class="identifier">Str::delete_last_character</span><span class="plain">(</span><span class="identifier">parse</span><span class="plain">);</span>
<span class="identifier">Str::trim_white_space</span><span class="plain">(</span><span class="identifier">parse</span><span class="plain">);</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">parse</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">Str::get</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">)));</span>
<span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;default_allows</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">match_results</span><span class="plain"> </span><span class="identifier">mr</span><span class="plain"> = </span><span class="identifier">Regexp::create_mr</span><span class="plain">();</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">negated</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">Regexp::match</span><span class="plain">(&amp;</span><span class="identifier">mr</span><span class="plain">, </span><span class="identifier">parse</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"not (%c+)"</span><span class="plain">)) {</span>
<span class="identifier">Str::clear</span><span class="plain">(</span><span class="identifier">parse</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">parse</span><span class="plain">, </span><span class="string">"%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="identifier">Str::trim_white_space</span><span class="plain">(</span><span class="identifier">parse</span><span class="plain">);</span>
<span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;default_allows</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">negated</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</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">parse</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"for (%c+)"</span><span class="plain">)) {</span>
<span class="identifier">Str::clear</span><span class="plain">(</span><span class="identifier">parse</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">parse</span><span class="plain">, </span><span class="string">"%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="identifier">Str::trim_white_space</span><span class="plain">(</span><span class="identifier">parse</span><span class="plain">);</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">parse</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"(%c+) only"</span><span class="plain">)) {</span>
<span class="identifier">Str::clear</span><span class="plain">(</span><span class="identifier">parse</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">parse</span><span class="plain">, </span><span class="string">"%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="identifier">Str::trim_white_space</span><span class="plain">(</span><span class="identifier">parse</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">negated</span><span class="plain">) </span><span class="identifier">incorrect</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">; </span> <span class="comment">"not for 32d only"</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">parse</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"all"</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">negated</span><span class="plain">) </span><span class="identifier">incorrect</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">; </span> <span class="comment">"not for all"</span>
<span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;default_allows</span><span class="plain"> = </span><span class="identifier">TRUE</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">parse</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"none"</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">negated</span><span class="plain">) </span><span class="identifier">incorrect</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">; </span> <span class="comment">"not for none"</span>
<span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;default_allows</span><span class="plain"> = </span><span class="identifier">FALSE</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="functiontext">Compatibility::clause</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">parse</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">)</span>
<span class="identifier">incorrect</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">parse</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>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">incorrect</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="identifier">C</span><span class="plain">;</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">compat_parser_state</span><span class="plain"> {</span>
<span class="reserved">compatibility_specification</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">current_family</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">version_allowed</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">version_required</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">family_used</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">compat_parser_state</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Compatibility::clause</span><span class="plain">(</span><span class="reserved">compatibility_specification</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">text</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">correct</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">match_results</span><span class="plain"> </span><span class="identifier">mr</span><span class="plain"> = </span><span class="identifier">Regexp::create_mr</span><span class="plain">();</span>
<span class="reserved">compat_parser_state</span><span class="plain"> </span><span class="identifier">cps</span><span class="plain">;</span>
<span class="identifier">cps</span><span class="element">.C</span><span class="plain"> = </span><span class="identifier">C</span><span class="plain">; </span><span class="identifier">cps</span><span class="element">.version_allowed</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">; </span><span class="identifier">cps</span><span class="element">.version_required</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">cps</span><span class="element">.current_family</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span><span class="identifier">cps</span><span class="element">.family_used</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">while</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">"(%C+) (%c+)"</span><span class="plain">)) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">comma</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">Str::get_last_char</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="character">','</span><span class="plain">) {</span>
<span class="identifier">comma</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">Str::delete_last_character</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="identifier">Str::trim_white_space</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="reserved">int</span><span class="plain"> </span><span class="identifier">with</span><span class="plain"> = </span><span class="identifier">NOT_APPLICABLE</span><span class="plain">;</span>
<span class="identifier">match_results</span><span class="plain"> </span><span class="identifier">mr2</span><span class="plain"> = </span><span class="identifier">Regexp::create_mr</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">mr2</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="identifier">L</span><span class="string">"with debugging,* *(%c*)"</span><span class="plain">)) {</span>
<span class="identifier">Str::clear</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="identifier">Str::copy</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="identifier">mr2</span><span class="plain">.</span><span class="identifier">exp</span><span class="plain">[0]);</span>
<span class="identifier">with</span><span class="plain"> = </span><span class="identifier">TRUE</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">mr2</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="identifier">L</span><span class="string">"without debugging,* *(%c*)"</span><span class="plain">)) {</span>
<span class="identifier">Str::clear</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="identifier">Str::copy</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="identifier">mr2</span><span class="plain">.</span><span class="identifier">exp</span><span class="plain">[0]);</span>
<span class="identifier">with</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">Regexp::dispose_of</span><span class="plain">(&amp;</span><span class="identifier">mr2</span><span class="plain">);</span>
<span class="identifier">correct</span><span class="plain"> = (</span><span class="identifier">correct</span><span class="plain"> &amp;&amp; </span><span class="functiontext">Compatibility::word</span><span class="plain">(&amp;</span><span class="identifier">cps</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="identifier">with</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">comma</span><span class="plain">) </span><span class="identifier">correct</span><span class="plain"> = (</span><span class="identifier">correct</span><span class="plain"> &amp;&amp; </span><span class="functiontext">Compatibility::word</span><span class="plain">(&amp;</span><span class="identifier">cps</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"or"</span><span class="plain">, </span><span class="identifier">with</span><span class="plain">));</span>
<span class="identifier">Str::clear</span><span class="plain">(</span><span class="identifier">text</span><span class="plain">); </span><span class="identifier">Str::copy</span><span class="plain">(</span><span class="identifier">text</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">if</span><span class="plain"> (</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">text</span><span class="plain">) &gt; 0)</span>
<span class="identifier">correct</span><span class="plain"> = (</span><span class="identifier">correct</span><span class="plain"> &amp;&amp; </span><span class="functiontext">Compatibility::word</span><span class="plain">(&amp;</span><span class="identifier">cps</span><span class="plain">, </span><span class="identifier">text</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">correct</span><span class="plain">) &amp;&amp; (</span><span class="identifier">cps</span><span class="element">.family_used</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) &amp;&amp; (</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">cps</span><span class="element">.current_family</span><span class="plain">) &gt; 0)) {</span>
<span class="reserved">target_vm</span><span class="plain"> *</span><span class="identifier">VM</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">VM</span><span class="plain">, </span><span class="reserved">target_vm</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">cps</span><span class="element">.current_family</span><span class="plain">, </span><span class="identifier">VM</span><span class="plain">-</span><span class="element">&gt;family_name</span><span class="plain">))</span>
<span class="functiontext">Compatibility::add</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">VM</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>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">correct</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Compatibility::word</span><span class="plain">(</span><span class="reserved">compat_parser_state</span><span class="plain"> *</span><span class="identifier">cps</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">word</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">with</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">cps</span><span class="plain">-</span><span class="element">&gt;version_allowed</span><span class="plain">) {</span>
<span class="reserved">semantic_version_number</span><span class="plain"> </span><span class="identifier">V</span><span class="plain"> = </span><span class="functiontext">VersionNumbers::from_text</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="functiontext">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">cps</span><span class="plain">-</span><span class="element">&gt;version_required</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">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">cps</span><span class="plain">-</span><span class="element">&gt;current_family</span><span class="plain">) == 0) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">cps</span><span class="plain">-</span><span class="element">&gt;family_used</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">target_vm</span><span class="plain"> *</span><span class="identifier">VM</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">seen</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">VM</span><span class="plain">, </span><span class="reserved">target_vm</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">VM</span><span class="plain">-</span><span class="element">&gt;family_name</span><span class="plain">, </span><span class="identifier">cps</span><span class="plain">-</span><span class="element">&gt;current_family</span><span class="plain">)) {</span>
<span class="identifier">seen</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="functiontext">VersionNumbers::eq</span><span class="plain">(</span><span class="identifier">VM</span><span class="plain">-</span><span class="element">&gt;version</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">((</span><span class="identifier">with</span><span class="plain"> == </span><span class="identifier">NOT_APPLICABLE</span><span class="plain">) || (</span><span class="functiontext">TargetVMs::debug_enabled</span><span class="plain">(</span><span class="identifier">VM</span><span class="plain">) == </span><span class="identifier">with</span><span class="plain">)))</span>
<span class="functiontext">Compatibility::add</span><span class="plain">(</span><span class="identifier">cps</span><span class="plain">-</span><span class="element">&gt;C</span><span class="plain">, </span><span class="identifier">VM</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">cps</span><span class="plain">-</span><span class="element">&gt;version_required</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">seen</span><span class="plain">;</span>
<span class="plain">}</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">word</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"or"</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">with</span><span class="plain"> != </span><span class="identifier">NOT_APPLICABLE</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">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</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">word</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"version"</span><span class="plain">)) ||</span>
<span class="plain">(</span><span class="identifier">Str::eq_insensitive</span><span class="plain">(</span><span class="identifier">word</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"versions"</span><span class="plain">))) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">with</span><span class="plain"> != </span><span class="identifier">NOT_APPLICABLE</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="identifier">cps</span><span class="plain">-</span><span class="element">&gt;version_required</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">cps</span><span class="plain">-</span><span class="element">&gt;version_allowed</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">cps</span><span class="plain">-</span><span class="element">&gt;version_required</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">cps</span><span class="plain">-</span><span class="element">&gt;version_allowed</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">bits</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::eq_insensitive</span><span class="plain">(</span><span class="identifier">word</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"16-bit"</span><span class="plain">)) </span><span class="identifier">bits</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">Str::eq_insensitive</span><span class="plain">(</span><span class="identifier">word</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"32-bit"</span><span class="plain">)) </span><span class="identifier">bits</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">bits</span><span class="plain"> != </span><span class="identifier">NOT_APPLICABLE</span><span class="plain">) {</span>
<span class="reserved">target_vm</span><span class="plain"> *</span><span class="identifier">VM</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">VM</span><span class="plain">, </span><span class="reserved">target_vm</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">TargetVMs::is_16_bit</span><span class="plain">(</span><span class="identifier">VM</span><span class="plain">) == </span><span class="identifier">bits</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">with</span><span class="plain"> == </span><span class="identifier">NOT_APPLICABLE</span><span class="plain">) || (</span><span class="functiontext">TargetVMs::debug_enabled</span><span class="plain">(</span><span class="identifier">VM</span><span class="plain">) == </span><span class="identifier">with</span><span class="plain">))</span>
<span class="functiontext">Compatibility::add</span><span class="plain">(</span><span class="identifier">cps</span><span class="plain">-</span><span class="element">&gt;C</span><span class="plain">, </span><span class="identifier">VM</span><span class="plain">);</span>
<span class="identifier">cps</span><span class="plain">-</span><span class="element">&gt;current_family</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">cps</span><span class="plain">-</span><span class="element">&gt;family_used</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">with</span><span class="plain"> != </span><span class="identifier">NOT_APPLICABLE</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">seen</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">target_vm</span><span class="plain"> *</span><span class="identifier">VM</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">VM</span><span class="plain">, </span><span class="reserved">target_vm</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">VM</span><span class="plain">-</span><span class="element">&gt;family_name</span><span class="plain">, </span><span class="identifier">word</span><span class="plain">)) {</span>
<span class="identifier">seen</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="functiontext">TargetVMs::debug_enabled</span><span class="plain">(</span><span class="identifier">VM</span><span class="plain">) == </span><span class="identifier">with</span><span class="plain">)</span>
<span class="functiontext">Compatibility::add</span><span class="plain">(</span><span class="identifier">cps</span><span class="plain">-</span><span class="element">&gt;C</span><span class="plain">, </span><span class="identifier">VM</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">cps</span><span class="plain">-</span><span class="element">&gt;current_family</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">cps</span><span class="plain">-</span><span class="element">&gt;family_used</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">seen</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">target_vm</span><span class="plain"> *</span><span class="identifier">VM</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">VM</span><span class="plain">, </span><span class="reserved">target_vm</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">VM</span><span class="plain">-</span><span class="element">&gt;family_name</span><span class="plain">, </span><span class="identifier">word</span><span class="plain">)) {</span>
<span class="identifier">cps</span><span class="plain">-</span><span class="element">&gt;current_family</span><span class="plain"> = </span><span class="identifier">VM</span><span class="plain">-</span><span class="element">&gt;family_name</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="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">int</span><span class="plain"> </span><span class="functiontext">Compatibility::add</span><span class="plain">(</span><span class="reserved">compatibility_specification</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain">, </span><span class="reserved">target_vm</span><span class="plain"> *</span><span class="identifier">VM</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">already_there</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">target_vm</span><span class="plain"> *</span><span class="identifier">X</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">X</span><span class="plain">, </span><span class="reserved">target_vm</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;exceptions</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">VM</span><span class="plain"> == </span><span class="identifier">X</span><span class="plain">)</span>
<span class="identifier">already_there</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">already_there</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">)</span>
<span class="identifier">ADD_TO_LINKED_LIST</span><span class="plain">(</span><span class="identifier">VM</span><span class="plain">, </span><span class="reserved">target_vm</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;exceptions</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">already_there</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Compatibility::with</span><span class="plain">(</span><span class="reserved">compatibility_specification</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain">, </span><span class="reserved">target_vm</span><span class="plain"> *</span><span class="identifier">VM</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="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">decision</span><span class="plain"> = </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;default_allows</span><span class="plain">;</span>
<span class="reserved">target_vm</span><span class="plain"> *</span><span class="identifier">X</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">X</span><span class="plain">, </span><span class="reserved">target_vm</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;exceptions</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">VM</span><span class="plain"> == </span><span class="identifier">X</span><span class="plain">)</span>
<span class="identifier">decision</span><span class="plain"> = </span><span class="identifier">decision</span><span class="plain">?</span><span class="identifier">FALSE</span><span class="plain">:</span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">decision</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Compatibility::test</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">) {</span>
<span class="functiontext">Compatibility::test_one</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"for all"</span><span class="plain">);</span>
<span class="functiontext">Compatibility::test_one</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"all"</span><span class="plain">);</span>
<span class="functiontext">Compatibility::test_one</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"not for all"</span><span class="plain">);</span>
<span class="functiontext">Compatibility::test_one</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"not all"</span><span class="plain">);</span>
<span class="functiontext">Compatibility::test_one</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"for none"</span><span class="plain">);</span>
<span class="functiontext">Compatibility::test_one</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"none"</span><span class="plain">);</span>
<span class="functiontext">Compatibility::test_one</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"not for none"</span><span class="plain">);</span>
<span class="functiontext">Compatibility::test_one</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"not none"</span><span class="plain">);</span>
<span class="functiontext">Compatibility::test_one</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"for 16-bit with debugging"</span><span class="plain">);</span>
<span class="functiontext">Compatibility::test_one</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"not for 32-bit"</span><span class="plain">);</span>
<span class="functiontext">Compatibility::test_one</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"for 16-bit with debugging or 32-bit with debugging"</span><span class="plain">);</span>
<span class="functiontext">Compatibility::test_one</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"not for 32-bit or 16-bit"</span><span class="plain">);</span>
<span class="functiontext">Compatibility::test_one</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"for 16-bit with debugging, 32-bit with debugging or 32-bit"</span><span class="plain">);</span>
<span class="functiontext">Compatibility::test_one</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"not for 16-bit with debugging, 32-bit with debugging or 32-bit"</span><span class="plain">);</span>
<span class="functiontext">Compatibility::test_one</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"for glulx"</span><span class="plain">);</span>
<span class="functiontext">Compatibility::test_one</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"for glulx or z-machine version 8"</span><span class="plain">);</span>
<span class="functiontext">Compatibility::test_one</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"for glulx without debugging"</span><span class="plain">);</span>
<span class="functiontext">Compatibility::test_one</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"for z-machine version 8"</span><span class="plain">);</span>
<span class="functiontext">Compatibility::test_one</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"for z-machine version 5 with debugging"</span><span class="plain">);</span>
<span class="functiontext">Compatibility::test_one</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"for z-machine version 8, or Glulx without debugging"</span><span class="plain">);</span>
<span class="functiontext">Compatibility::test_one</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"for z-machine version 5 or 8"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Compatibility::test_one</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">test</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">test</span><span class="plain">);</span>
<span class="reserved">compatibility_specification</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain"> = </span><span class="functiontext">Compatibility::from_text</span><span class="plain">(</span><span class="identifier">test</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">WRITE</span><span class="plain">(</span><span class="string">"not a valid compatibility specification\</span><span class="plain">n</span><span class="string">\</span><span class="plain">n</span><span class="string">"</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">; }</span>
<span class="functiontext">Compatibility::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="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="identifier">INDENT</span><span class="plain">;</span>
<span class="reserved">target_vm</span><span class="plain"> *</span><span class="identifier">VM</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">VM</span><span class="plain">, </span><span class="reserved">target_vm</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Compatibility::with</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">VM</span><span class="plain">)) {</span>
<span class="functiontext">TargetVMs::write</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">VM</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="identifier">OUTDENT</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>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Compatibility::all appears nowhere else.</p>
<p class="endnote">The function Compatibility::universal appears nowhere else.</p>
<p class="endnote">The function Compatibility::write appears nowhere else.</p>
<p class="endnote">The function Compatibility::from_text appears nowhere else.</p>
<p class="endnote">The function Compatibility::clause appears nowhere else.</p>
<p class="endnote">The function Compatibility::word appears nowhere else.</p>
<p class="endnote">The function Compatibility::add appears nowhere else.</p>
<p class="endnote">The function Compatibility::with appears nowhere else.</p>
<p class="endnote">The function Compatibility::test appears nowhere else.</p>
<p class="endnote">The function Compatibility::test_one appears nowhere else.</p>
<p class="endnote">The structure compatibility_specification is private to this section.</p>
<p class="endnote">The structure compat_parser_state is private to this section.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="2-tvm.html">Back to 'Target Virtual Machines'</a></li><li><i>(This section ends Chapter 2: Architectures.)</i></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>

232
docs/arch-module/2-tvm.html Normal file
View file

@ -0,0 +1,232 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>2/arc</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<!--Weave of '2/tvm' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">arch</a></li><li><a href="index.html#2">Chapter 2: Architectures</a></li><li><b>Target Virtual Machines</b></li></ul><p class="purpose">To deal with multiple inter architectures.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Architectures</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Architectures. </b></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">target_vm</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">family_name</span><span class="plain">; </span> <span class="comment">such as <code class="display"><span class="extract">Glulx</span></code></span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">with_debugging_enabled</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">inter_architecture</span><span class="plain"> *</span><span class="identifier">architecture</span><span class="plain">; </span> <span class="comment">such as 32d</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">semantic_version_number</span><span class="plain"> </span><span class="identifier">version</span><span class="plain">; </span> <span class="comment">such as 0.8.7</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">VM_extension</span><span class="plain">; </span> <span class="comment">canonical filename extension</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">VM_unblorbed_extension</span><span class="plain">; </span> <span class="comment">such as <code class="display"><span class="extract">z8</span></code></span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">VM_blorbed_extension</span><span class="plain">; </span> <span class="comment">when blorbed up</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">VM_image</span><span class="plain">; </span> <span class="comment">filename of image for icon denoting VM</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">max_locals</span><span class="plain">; </span> <span class="comment">upper limit on local variables per stack frame</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">default_browser_interpreter</span><span class="plain">; </span> <span class="comment">e.g., "Parchment"</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">iFiction_format_name</span><span class="plain">; </span> <span class="comment">e.g., "zcode": see the Treaty of Babel</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">supports_floating_point</span><span class="plain">;</span>
<span class="identifier">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">target_vm</span><span class="plain">;</span>
<span class="reserved">target_vm</span><span class="plain"> *</span><span class="functiontext">TargetVMs::new</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">code</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">nick</span><span class="plain">, </span><span class="reserved">semantic_version_number</span><span class="plain"> </span><span class="identifier">V</span><span class="plain">,</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">image</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">interpreter</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">blorbed</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">arch</span><span class="plain">,</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">debug</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">max_locals</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">iFiction</span><span class="plain">) {</span>
<span class="reserved">target_vm</span><span class="plain"> *</span><span class="identifier">VM</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">target_vm</span><span class="plain">);</span>
<span class="identifier">VM</span><span class="plain">-</span><span class="element">&gt;family_name</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">code</span><span class="plain">);</span>
<span class="identifier">VM</span><span class="plain">-</span><span class="element">&gt;version</span><span class="plain"> = </span><span class="identifier">V</span><span class="plain">;</span>
<span class="identifier">VM</span><span class="plain">-</span><span class="element">&gt;VM_extension</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">nick</span><span class="plain">);</span>
<span class="identifier">VM</span><span class="plain">-</span><span class="element">&gt;VM_unblorbed_extension</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">nick</span><span class="plain">);</span>
<span class="identifier">VM</span><span class="plain">-</span><span class="element">&gt;VM_blorbed_extension</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">blorbed</span><span class="plain">);</span>
<span class="identifier">VM</span><span class="plain">-</span><span class="element">&gt;VM_image</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">image</span><span class="plain">);</span>
<span class="identifier">VM</span><span class="plain">-</span><span class="element">&gt;max_locals</span><span class="plain"> = </span><span class="identifier">max_locals</span><span class="plain">;</span>
<span class="identifier">VM</span><span class="plain">-</span><span class="element">&gt;default_browser_interpreter</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">interpreter</span><span class="plain">);</span>
<span class="identifier">VM</span><span class="plain">-</span><span class="element">&gt;architecture</span><span class="plain"> = </span><span class="functiontext">Architectures::from_codename</span><span class="plain">(</span><span class="identifier">arch</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">VM</span><span class="plain">-</span><span class="element">&gt;architecture</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 such architecture"</span><span class="plain">);</span>
<span class="identifier">VM</span><span class="plain">-</span><span class="element">&gt;with_debugging_enabled</span><span class="plain"> = </span><span class="identifier">debug</span><span class="plain">;</span>
<span class="identifier">VM</span><span class="plain">-</span><span class="element">&gt;supports_floating_point</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="functiontext">Architectures::is_16_bit</span><span class="plain">(</span><span class="identifier">VM</span><span class="plain">-</span><span class="element">&gt;architecture</span><span class="plain">)) </span><span class="identifier">VM</span><span class="plain">-</span><span class="element">&gt;supports_floating_point</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">VM</span><span class="plain">-</span><span class="element">&gt;iFiction_format_name</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">iFiction</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">VM</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">TargetVMs::write</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">target_vm</span><span class="plain"> *</span><span class="identifier">VM</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">VM</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">"none"</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">VM</span><span class="plain">-</span><span class="element">&gt;family_name</span><span class="plain">);</span>
<span class="reserved">semantic_version_number</span><span class="plain"> </span><span class="identifier">V</span><span class="plain"> = </span><span class="identifier">VM</span><span class="plain">-</span><span class="element">&gt;version</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">VersionNumbers::is_null</span><span class="plain">(</span><span class="identifier">V</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">" version %v"</span><span class="plain">, &amp;</span><span class="identifier">V</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">VM</span><span class="plain">-</span><span class="element">&gt;with_debugging_enabled</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" with debugging"</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">TargetVMs::create</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="comment">hat tip: Joel Berez and Marc Blank, 1979, and later hands</span>
<span class="functiontext">TargetVMs::new</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"Z-Machine"</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"z5"</span><span class="plain">, </span><span class="functiontext">VersionNumbers::from_text</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"5"</span><span class="plain">),</span>
<span class="identifier">I</span><span class="string">"vm_z5.png"</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Parchment"</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"zblorb"</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"16"</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, 15, </span><span class="identifier">I</span><span class="string">"zcode"</span><span class="plain">);</span>
<span class="functiontext">TargetVMs::new</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"Z-Machine"</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"z5"</span><span class="plain">, </span><span class="functiontext">VersionNumbers::from_text</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"5"</span><span class="plain">),</span>
<span class="identifier">I</span><span class="string">"vm_z5.png"</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Parchment"</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"zblorb"</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"16d"</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">, 15, </span><span class="identifier">I</span><span class="string">"zcode"</span><span class="plain">);</span>
<span class="functiontext">TargetVMs::new</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"Z-Machine"</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"z8"</span><span class="plain">, </span><span class="functiontext">VersionNumbers::from_text</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"8"</span><span class="plain">),</span>
<span class="identifier">I</span><span class="string">"vm_z8.png"</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Parchment"</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"zblorb"</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"16"</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, 15, </span><span class="identifier">I</span><span class="string">"zcode"</span><span class="plain">);</span>
<span class="functiontext">TargetVMs::new</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"Z-Machine"</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"z8"</span><span class="plain">, </span><span class="functiontext">VersionNumbers::from_text</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"8"</span><span class="plain">),</span>
<span class="identifier">I</span><span class="string">"vm_z8.png"</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Parchment"</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"zblorb"</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"16d"</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">, 15, </span><span class="identifier">I</span><span class="string">"zcode"</span><span class="plain">);</span>
<span class="comment">hat tip: Andrew Plotkin, 2000</span>
<span class="functiontext">TargetVMs::new</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"Glulx"</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"ulx"</span><span class="plain">, </span><span class="functiontext">VersionNumbers::from_text</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"3.1.2"</span><span class="plain">),</span>
<span class="identifier">I</span><span class="string">"vm_glulx.png"</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Quixe"</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"gblorb"</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"32"</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, 256, </span><span class="identifier">I</span><span class="string">"glulx"</span><span class="plain">);</span>
<span class="functiontext">TargetVMs::new</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"Glulx"</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"ulx"</span><span class="plain">, </span><span class="functiontext">VersionNumbers::from_text</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"3.1.2"</span><span class="plain">),</span>
<span class="identifier">I</span><span class="string">"vm_glulx.png"</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Quixe"</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"gblorb"</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"32d"</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">, 256, </span><span class="identifier">I</span><span class="string">"glulx"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">target_vm</span><span class="plain"> *</span><span class="functiontext">TargetVMs::find</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="reserved">int</span><span class="plain"> </span><span class="identifier">debug</span><span class="plain">) {</span>
<span class="reserved">target_vm</span><span class="plain"> *</span><span class="identifier">result</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">ext</span><span class="plain">) == 0) </span><span class="identifier">ext</span><span class="plain"> = </span><span class="identifier">I</span><span class="string">"ulx"</span><span class="plain">;</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">file_extension</span><span class="plain">);</span>
<span class="identifier">Str::copy</span><span class="plain">(</span><span class="identifier">file_extension</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">Str::get_first_char</span><span class="plain">(</span><span class="identifier">file_extension</span><span class="plain">) == </span><span class="character">'.'</span><span class="plain">) </span><span class="identifier">Str::delete_first_character</span><span class="plain">(</span><span class="identifier">file_extension</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">file_extension</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">Str::get</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">)));</span>
<span class="reserved">target_vm</span><span class="plain"> *</span><span class="identifier">VM</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">VM</span><span class="plain">, </span><span class="reserved">target_vm</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">VM</span><span class="plain">-</span><span class="element">&gt;VM_unblorbed_extension</span><span class="plain">, </span><span class="identifier">ext</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">VM</span><span class="plain">-</span><span class="element">&gt;with_debugging_enabled</span><span class="plain"> == </span><span class="identifier">debug</span><span class="plain">))</span>
<span class="identifier">result</span><span class="plain"> = </span><span class="identifier">VM</span><span class="plain">;</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">file_extension</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">result</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">target_vm</span><span class="plain"> *</span><span class="functiontext">TargetVMs::find_in_family</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">family</span><span class="plain">, </span><span class="reserved">semantic_version_number</span><span class="plain"> </span><span class="identifier">V</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">debug</span><span class="plain">) {</span>
<span class="reserved">target_vm</span><span class="plain"> *</span><span class="identifier">VM</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">VM</span><span class="plain">, </span><span class="reserved">target_vm</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">VM</span><span class="plain">-</span><span class="element">&gt;family_name</span><span class="plain">, </span><span class="identifier">family</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">VersionNumbers::eq</span><span class="plain">(</span><span class="identifier">VM</span><span class="plain">-</span><span class="element">&gt;version</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">((</span><span class="identifier">debug</span><span class="plain"> == </span><span class="identifier">NOT_APPLICABLE</span><span class="plain">) || (</span><span class="identifier">debug</span><span class="plain"> == </span><span class="identifier">VM</span><span class="plain">-</span><span class="element">&gt;with_debugging_enabled</span><span class="plain">)))</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">VM</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>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">TargetVMs::is_16_bit</span><span class="plain">(</span><span class="reserved">target_vm</span><span class="plain"> *</span><span class="identifier">VM</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">VM</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 VM"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Architectures::is_16_bit</span><span class="plain">(</span><span class="identifier">VM</span><span class="plain">-</span><span class="element">&gt;architecture</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">TargetVMs::debug_enabled</span><span class="plain">(</span><span class="reserved">target_vm</span><span class="plain"> *</span><span class="identifier">VM</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">VM</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 VM"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Architectures::debug_enabled</span><span class="plain">(</span><span class="identifier">VM</span><span class="plain">-</span><span class="element">&gt;architecture</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">TargetVMs::supports_floating_point</span><span class="plain">(</span><span class="reserved">target_vm</span><span class="plain"> *</span><span class="identifier">VM</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">VM</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 VM"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">VM</span><span class="plain">-</span><span class="element">&gt;supports_floating_point</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function TargetVMs::new appears nowhere else.</p>
<p class="endnote">The function TargetVMs::write is used in 2/cmp (<a href="2-cmp.html#SP1">&#167;1</a>).</p>
<p class="endnote">The function TargetVMs::create is used in 1/am (<a href="1-am.html#SP3">&#167;3</a>).</p>
<p class="endnote">The function TargetVMs::find appears nowhere else.</p>
<p class="endnote">The function TargetVMs::find_in_family appears nowhere else.</p>
<p class="endnote">The function TargetVMs::is_16_bit is used in 2/cmp (<a href="2-cmp.html#SP1">&#167;1</a>).</p>
<p class="endnote">The function TargetVMs::debug_enabled is used in 2/cmp (<a href="2-cmp.html#SP1">&#167;1</a>).</p>
<p class="endnote">The function TargetVMs::supports_floating_point appears nowhere else.</p>
<p class="endnote">The structure target_vm is accessed in 2/cmp and here.</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>The limits are different on each platform. On Z, the maximum is fixed
at 15, but Glulx allows it to be set with an I6 memory setting.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">TargetVMs::allow_this_many_locals</span><span class="plain">(</span><span class="reserved">target_vm</span><span class="plain"> *</span><span class="identifier">VM</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">if</span><span class="plain"> (</span><span class="identifier">VM</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 VM"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">VM</span><span class="plain">-</span><span class="element">&gt;max_locals</span><span class="plain"> &gt;= 0) &amp;&amp; (</span><span class="identifier">VM</span><span class="plain">-</span><span class="element">&gt;max_locals</span><span class="plain"> &lt; </span><span class="identifier">N</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">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">TargetVMs::allow_MAX_LOCAL_VARIABLES</span><span class="plain">(</span><span class="reserved">target_vm</span><span class="plain"> *</span><span class="identifier">VM</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">VM</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 VM"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">VM</span><span class="plain">-</span><span class="element">&gt;max_locals</span><span class="plain"> &gt; 15) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function TargetVMs::allow_this_many_locals appears nowhere else.</p>
<p class="endnote">The function TargetVMs::allow_MAX_LOCAL_VARIABLES appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>When releasing a blorbed story file, the file extension depends on the
story file wrapped inside. (This is a dubious idea, in the opinion of
the author of Inform &mdash; should not blorb be one unified wrapper? &mdash; but
interpreter writers disagree.)
</p>
<pre class="display">
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="functiontext">TargetVMs::get_unblorbed_extension</span><span class="plain">(</span><span class="reserved">target_vm</span><span class="plain"> *</span><span class="identifier">VM</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">VM</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 VM"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">VM</span><span class="plain">-</span><span class="element">&gt;VM_unblorbed_extension</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="functiontext">TargetVMs::get_blorbed_extension</span><span class="plain">(</span><span class="reserved">target_vm</span><span class="plain"> *</span><span class="identifier">VM</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">VM</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 VM"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">VM</span><span class="plain">-</span><span class="element">&gt;VM_blorbed_extension</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="functiontext">TargetVMs::get_iFiction_format</span><span class="plain">(</span><span class="reserved">target_vm</span><span class="plain"> *</span><span class="identifier">VM</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">VM</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 VM"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">VM</span><span class="plain">-</span><span class="element">&gt;iFiction_format_name</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">inter_architecture</span><span class="plain"> *</span><span class="functiontext">TargetVMs::get_architecture</span><span class="plain">(</span><span class="reserved">target_vm</span><span class="plain"> *</span><span class="identifier">VM</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">VM</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 VM"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">VM</span><span class="plain">-</span><span class="element">&gt;architecture</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function TargetVMs::get_unblorbed_extension appears nowhere else.</p>
<p class="endnote">The function TargetVMs::get_blorbed_extension appears nowhere else.</p>
<p class="endnote">The function TargetVMs::get_iFiction_format appears nowhere else.</p>
<p class="endnote">The function TargetVMs::get_architecture appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>Different VMs have different in-browser interpreters, which means that
Inblorb needs to be given different release instructions for them. If the
user doesn't specify any particular interpreter, he gets:
</p>
<pre class="display">
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="functiontext">TargetVMs::get_default_interpreter</span><span class="plain">(</span><span class="reserved">target_vm</span><span class="plain"> *</span><span class="identifier">VM</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">VM</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 VM"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">VM</span><span class="plain">-</span><span class="element">&gt;default_browser_interpreter</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function TargetVMs::get_default_interpreter appears nowhere else.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="2-arc.html">Back to 'Architectures'</a></li><li><a href="2-cmp.html">Continue with 'Compatibility'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>

249
docs/arch-module/2-vn.html Normal file
View file

@ -0,0 +1,249 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>1/am</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<!--Weave of '2/vn' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">arch</a></li><li><a href="index.html#2">Chapter 2: Architectures</a></li><li><b>Version Numbers</b></li></ul><p class="purpose">Semantic version numbers such as 3.7.1.</p>
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. </b>Traditional semantic version numbers look like dot-divided runs of
non-negative integers: for example, 4, 7.1, and 0.2.3. Up to <code class="display"><span class="extract">VERSION_NUMBER_DEPTH</span></code>
components can be given. The tail of the array should be padded with <code class="display"><span class="extract">-1</span></code> values;
otherwise, components should all be non-negative integers.
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">VERSION_NUMBER_DEPTH</span><span class="plain"> 4</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">semantic_version_number</span><span class="plain"> {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">version_numbers</span><span class="plain">[</span><span class="constant">VERSION_NUMBER_DEPTH</span><span class="plain">];</span>
<span class="plain">} </span><span class="reserved">semantic_version_number</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">semantic_version_number_holder</span><span class="plain"> {</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">semantic_version_number</span><span class="plain"> </span><span class="identifier">version</span><span class="plain">;</span>
<span class="identifier">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">semantic_version_number_holder</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The structure semantic_version_number is private to this section.</p>
<p class="endnote">The structure semantic_version_number_holder is accessed in 2/tvm, 2/cmp.</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>However, Inform 7 extensions have for many years allowed two forms of
version number: either just <code class="display"><span class="extract">N</span></code>, which clearly fits the scheme above, or
<code class="display"><span class="extract">N/DDDDDD</span></code>, which does not. This is a format which was chosen for sentimental
reasons: IF enthusiasts know it well from the banner text of the Infocom
titles of the 1980s. This story file, for instance, was compiled at the
time of the Reykjavik summit between Presidents Gorbachev and Reagan:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">Moonmist</span>
<span class="plain">Infocom interactive fiction - a mystery story</span>
<span class="plain">Copyright (c) 1986 by Infocom, Inc. All rights reserved.</span>
<span class="plain">Moonmist is a trademark of Infocom, Inc.</span>
<span class="plain">Release number 9 / Serial number 861022</span>
</pre>
<p class="inwebparagraph">Story file collectors customarily abbreviate this in catalogues to <code class="display"><span class="extract">9/861022</span></code>.
</p>
<p class="inwebparagraph">We will therefore allow this notation, and convert it silently each way.
<code class="display"><span class="extract">N/DDDDDD</span></code> is equivalent to <code class="display"><span class="extract">N.DDDDDD</span></code>.
</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>All invalid strings of numbers &mdash; i.e., breaking the above rules &mdash; are
called "null" versions, and can never be valid as the version of anything.
Instead they are used to represent the absence of a version number.
(In particular, a string of <code class="display"><span class="extract">-1</span></code>s is null.)
</p>
<pre class="display">
<span class="reserved">semantic_version_number</span><span class="plain"> </span><span class="functiontext">VersionNumbers::null</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="plain">#</span><span class="identifier">pragma</span><span class="plain"> </span><span class="identifier">clang</span><span class="plain"> </span><span class="identifier">diagnostic</span><span class="plain"> </span><span class="identifier">push</span>
<span class="plain">#</span><span class="identifier">pragma</span><span class="plain"> </span><span class="identifier">clang</span><span class="plain"> </span><span class="identifier">diagnostic</span><span class="plain"> </span><span class="identifier">ignored</span><span class="plain"> </span><span class="string">"-Wconditional-uninitialized"</span>
<span class="reserved">semantic_version_number</span><span class="plain"> </span><span class="identifier">V</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">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="constant">VERSION_NUMBER_DEPTH</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">V</span><span class="element">.version_numbers</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] = -1;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">V</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">pragma</span><span class="plain"> </span><span class="identifier">clang</span><span class="plain"> </span><span class="identifier">diagnostic</span><span class="plain"> </span><span class="identifier">pop</span>
<span class="plain">}</span>
<span class="reserved">semantic_version_number</span><span class="plain"> </span><span class="functiontext">VersionNumbers::from_major</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">major</span><span class="plain">) {</span>
<span class="reserved">semantic_version_number</span><span class="plain"> </span><span class="identifier">V</span><span class="plain"> = </span><span class="functiontext">VersionNumbers::null</span><span class="plain">();</span>
<span class="identifier">V</span><span class="element">.version_numbers</span><span class="plain">[0] = </span><span class="identifier">major</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>
<span class="reserved">semantic_version_number</span><span class="plain"> </span><span class="functiontext">VersionNumbers::from_pair</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">major</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">minor</span><span class="plain">) {</span>
<span class="reserved">semantic_version_number</span><span class="plain"> </span><span class="identifier">V</span><span class="plain"> = </span><span class="functiontext">VersionNumbers::null</span><span class="plain">();</span>
<span class="identifier">V</span><span class="element">.version_numbers</span><span class="plain">[0] = </span><span class="identifier">major</span><span class="plain">;</span>
<span class="identifier">V</span><span class="element">.version_numbers</span><span class="plain">[1] = </span><span class="identifier">minor</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>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">VersionNumbers::is_null</span><span class="plain">(</span><span class="reserved">semantic_version_number</span><span class="plain"> </span><span class="identifier">V</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">i</span><span class="plain">=0, </span><span class="identifier">allow</span><span class="plain">=</span><span class="identifier">TRUE</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="constant">VERSION_NUMBER_DEPTH</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">V</span><span class="element">.version_numbers</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] &lt; -1)</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">V</span><span class="element">.version_numbers</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] == -1)</span>
<span class="identifier">allow</span><span class="plain"> = </span><span class="identifier">FALSE</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">allow</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">V</span><span class="element">.version_numbers</span><span class="plain">[0] &lt; 0) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function VersionNumbers::null is used in <a href="#SP4">&#167;4</a>.</p>
<p class="endnote">The function VersionNumbers::from_major appears nowhere else.</p>
<p class="endnote">The function VersionNumbers::from_pair appears nowhere else.</p>
<p class="endnote">The function VersionNumbers::is_null is used in <a href="#SP4">&#167;4</a>, <a href="#SP5">&#167;5</a>, 2/tvm (<a href="2-tvm.html#SP1">&#167;1</a>), 2/cmp (<a href="2-cmp.html#SP1">&#167;1</a>).</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>Here we print and parse:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">VersionNumbers::to_text</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">semantic_version_number</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="functiontext">VersionNumbers::is_null</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">)) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"null"</span><span class="plain">);</span>
<span class="reserved">else</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; (</span><span class="identifier">i</span><span class="plain">&lt;</span><span class="constant">VERSION_NUMBER_DEPTH</span><span class="plain">) &amp;&amp; (</span><span class="identifier">V</span><span class="element">.version_numbers</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] &gt;= 0); </span><span class="identifier">i</span><span class="plain">++) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">&gt;0) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"."</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">V</span><span class="element">.version_numbers</span><span class="plain">[</span><span class="identifier">i</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">VersionNumbers::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">semantic_version_number</span><span class="plain"> *</span><span class="identifier">V</span><span class="plain"> = (</span><span class="reserved">semantic_version_number</span><span class="plain"> *) </span><span class="identifier">vE</span><span class="plain">;</span>
<span class="functiontext">VersionNumbers::to_text</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="plain">}</span>
<span class="reserved">semantic_version_number</span><span class="plain"> </span><span class="functiontext">VersionNumbers::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="reserved">semantic_version_number</span><span class="plain"> </span><span class="identifier">V</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">component</span><span class="plain"> = 0, </span><span class="identifier">val</span><span class="plain"> = -1, </span><span class="identifier">dots_used</span><span class="plain"> = 0, </span><span class="identifier">slashes_used</span><span class="plain"> = 0, </span><span class="identifier">count</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">T</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">c</span><span class="plain"> == </span><span class="character">'.'</span><span class="plain">) </span><span class="identifier">dots_used</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">slashes_used</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">c</span><span class="plain"> == </span><span class="character">'/'</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">val</span><span class="plain"> == -1) </span><span class="reserved">return</span><span class="plain"> </span><span class="functiontext">VersionNumbers::null</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">component</span><span class="plain"> &gt;= </span><span class="constant">VERSION_NUMBER_DEPTH</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="functiontext">VersionNumbers::null</span><span class="plain">();</span>
<span class="identifier">V</span><span class="element">.version_numbers</span><span class="plain">[</span><span class="identifier">component</span><span class="plain">] = </span><span class="identifier">val</span><span class="plain">;</span>
<span class="identifier">component</span><span class="plain">++; </span><span class="identifier">val</span><span class="plain"> = -1; </span><span class="identifier">count</span><span class="plain"> = 0;</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">Characters::isdigit</span><span class="plain">(</span><span class="identifier">c</span><span class="plain">)) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">digit</span><span class="plain"> = </span><span class="identifier">c</span><span class="plain"> - </span><span class="character">'0'</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">val</span><span class="plain"> == 0) &amp;&amp; (</span><span class="identifier">slashes_used</span><span class="plain"> == 0))</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">VersionNumbers::null</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">val</span><span class="plain"> &lt; 0) </span><span class="identifier">val</span><span class="plain"> = </span><span class="identifier">digit</span><span class="plain">; </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">val</span><span class="plain"> = 10*</span><span class="identifier">val</span><span class="plain"> + </span><span class="identifier">digit</span><span class="plain">;</span>
<span class="identifier">count</span><span class="plain">++;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="functiontext">VersionNumbers::null</span><span class="plain">();</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">val</span><span class="plain"> == -1) </span><span class="reserved">return</span><span class="plain"> </span><span class="functiontext">VersionNumbers::null</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">dots_used</span><span class="plain"> &gt; 0) &amp;&amp; (</span><span class="identifier">slashes_used</span><span class="plain"> &gt; 0)) </span><span class="reserved">return</span><span class="plain"> </span><span class="functiontext">VersionNumbers::null</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">slashes_used</span><span class="plain"> &gt; 0) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">component</span><span class="plain"> &gt; 1) </span><span class="reserved">return</span><span class="plain"> </span><span class="functiontext">VersionNumbers::null</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">count</span><span class="plain"> != 6) </span><span class="reserved">return</span><span class="plain"> </span><span class="functiontext">VersionNumbers::null</span><span class="plain">();</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">component</span><span class="plain"> &gt;= </span><span class="constant">VERSION_NUMBER_DEPTH</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="functiontext">VersionNumbers::null</span><span class="plain">();</span>
<span class="identifier">V</span><span class="element">.version_numbers</span><span class="plain">[</span><span class="identifier">component</span><span class="plain">] = </span><span class="identifier">val</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">i</span><span class="plain">=</span><span class="identifier">component</span><span class="plain">+1; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="constant">VERSION_NUMBER_DEPTH</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">V</span><span class="element">.version_numbers</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] = -1;</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 VersionNumbers::to_text appears nowhere else.</p>
<p class="endnote">The function VersionNumbers::writer appears nowhere else.</p>
<p class="endnote">The function VersionNumbers::from_text is used in 2/tvm (<a href="2-tvm.html#SP1">&#167;1</a>), 2/cmp (<a href="2-cmp.html#SP1">&#167;1</a>).</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b>And now comparison operators. Note that all null versions are equal, and
are always both <code class="display"><span class="extract">&lt;=</span></code> and <code class="display"><span class="extract">&gt;=</span></code> all versions. This means our ordering is not
trichotomous (though it is on the set of non-null versions), but this
ensures that null versions can be used to mean "unlimited" in either direction.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">VersionNumbers::eq</span><span class="plain">(</span><span class="reserved">semantic_version_number</span><span class="plain"> </span><span class="identifier">V1</span><span class="plain">, </span><span class="reserved">semantic_version_number</span><span class="plain"> </span><span class="identifier">V2</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">VersionNumbers::is_null</span><span class="plain">(</span><span class="identifier">V1</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="functiontext">VersionNumbers::is_null</span><span class="plain">(</span><span class="identifier">V2</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">VersionNumbers::is_null</span><span class="plain">(</span><span class="identifier">V2</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">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="constant">VERSION_NUMBER_DEPTH</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">V1</span><span class="element">.version_numbers</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] != </span><span class="identifier">V2</span><span class="element">.version_numbers</span><span class="plain">[</span><span class="identifier">i</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">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">VersionNumbers::ne</span><span class="plain">(</span><span class="reserved">semantic_version_number</span><span class="plain"> </span><span class="identifier">V1</span><span class="plain">, </span><span class="reserved">semantic_version_number</span><span class="plain"> </span><span class="identifier">V2</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> (</span><span class="functiontext">VersionNumbers::eq</span><span class="plain">(</span><span class="identifier">V1</span><span class="plain">, </span><span class="identifier">V2</span><span class="plain">))?</span><span class="identifier">FALSE</span><span class="plain">:</span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">VersionNumbers::le</span><span class="plain">(</span><span class="reserved">semantic_version_number</span><span class="plain"> </span><span class="identifier">V1</span><span class="plain">, </span><span class="reserved">semantic_version_number</span><span class="plain"> </span><span class="identifier">V2</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">VersionNumbers::is_null</span><span class="plain">(</span><span class="identifier">V1</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="functiontext">VersionNumbers::is_null</span><span class="plain">(</span><span class="identifier">V2</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">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="constant">VERSION_NUMBER_DEPTH</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">V1</span><span class="element">.version_numbers</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] &gt; </span><span class="identifier">V2</span><span class="element">.version_numbers</span><span class="plain">[</span><span class="identifier">i</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">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">VersionNumbers::gt</span><span class="plain">(</span><span class="reserved">semantic_version_number</span><span class="plain"> </span><span class="identifier">V1</span><span class="plain">, </span><span class="reserved">semantic_version_number</span><span class="plain"> </span><span class="identifier">V2</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> (</span><span class="functiontext">VersionNumbers::le</span><span class="plain">(</span><span class="identifier">V1</span><span class="plain">, </span><span class="identifier">V2</span><span class="plain">))?</span><span class="identifier">FALSE</span><span class="plain">:</span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">VersionNumbers::ge</span><span class="plain">(</span><span class="reserved">semantic_version_number</span><span class="plain"> </span><span class="identifier">V1</span><span class="plain">, </span><span class="reserved">semantic_version_number</span><span class="plain"> </span><span class="identifier">V2</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">VersionNumbers::is_null</span><span class="plain">(</span><span class="identifier">V1</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="functiontext">VersionNumbers::is_null</span><span class="plain">(</span><span class="identifier">V2</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">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="constant">VERSION_NUMBER_DEPTH</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">V1</span><span class="element">.version_numbers</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] &lt; </span><span class="identifier">V2</span><span class="element">.version_numbers</span><span class="plain">[</span><span class="identifier">i</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">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">VersionNumbers::lt</span><span class="plain">(</span><span class="reserved">semantic_version_number</span><span class="plain"> </span><span class="identifier">V1</span><span class="plain">, </span><span class="reserved">semantic_version_number</span><span class="plain"> </span><span class="identifier">V2</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> (</span><span class="functiontext">VersionNumbers::ge</span><span class="plain">(</span><span class="identifier">V1</span><span class="plain">, </span><span class="identifier">V2</span><span class="plain">))?</span><span class="identifier">FALSE</span><span class="plain">:</span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function VersionNumbers::eq is used in 2/tvm (<a href="2-tvm.html#SP1">&#167;1</a>), 2/cmp (<a href="2-cmp.html#SP1">&#167;1</a>).</p>
<p class="endnote">The function VersionNumbers::ne appears nowhere else.</p>
<p class="endnote">The function VersionNumbers::le appears nowhere else.</p>
<p class="endnote">The function VersionNumbers::gt appears nowhere else.</p>
<p class="endnote">The function VersionNumbers::ge appears nowhere else.</p>
<p class="endnote">The function VersionNumbers::lt appears nowhere else.</p>
<hr class="tocbar">
<ul class="toc"><li><i>(This section begins Chapter 2: Architectures.)</i></li><li><a href="2-arc.html">Continue with 'Architectures'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>

BIN
docs/arch-module/crumbs.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View file

@ -0,0 +1,51 @@
<html>
<head>
<title>arch </title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><b>arch </b></li></ul>
<p class="purpose">Definitions of Inter and final VM architectures.</p>
<hr>
<ul class="chapterlist">
<li>
<p><a name="1"></a><spon class="chaptertitle">Chapter 1: Setting Up</span></p>
<p><span class="purpose"></span></p>
<ul class="sectionlist">
<li>
<p><a href="1-am.html"><spon class="sectiontitle">Arch Module</span></a> -
<span class="purpose">Setting up the use of this module.</span></p>
</li>
</ul>
</li>
<li>
<p><a name="2"></a><spon class="chaptertitle">Chapter 2: Architectures</span></p>
<p><span class="purpose"></span></p>
<ul class="sectionlist">
<li>
<p><a href="2-vn.html"><spon class="sectiontitle">Version Numbers</span></a> -
<span class="purpose">Semantic version numbers such as 3.7.1.</span></p>
</li>
<li>
<p><a href="2-arc.html"><spon class="sectiontitle">Architectures</span></a> -
<span class="purpose">To deal with multiple inter architectures.</span></p>
</li>
<li>
<p><a href="2-tvm.html"><spon class="sectiontitle">Target Virtual Machines</span></a> -
<span class="purpose">To deal with multiple inter architectures.</span></p>
</li>
<li>
<p><a href="2-cmp.html"><spon class="sectiontitle">Compatibility</span></a> -
<span class="purpose">To manage compatibility lists: what can be compiled to what format.</span></p>
</li>
</ul>
</li>
</ul>
<hr>
</body>
</html>

288
docs/arch-module/inweb.css Normal file
View file

@ -0,0 +1,288 @@
/* This is a CSS file for pages woven by the literate programming tool inweb */
/* We'll start with syntax colouring, since everyone likes to toy with this: */
.cwebmacrotext { color: #000000; font-weight: bold; } /* The name of a web macro */
.functiontext { color: #C00000; } /* When a C function is being defined */
.string { color: #408040; } /* A double-quoted C literal string */
.character { color: #204020; } /* A single-quoted C literal character */
.constant { color: #204020; } /* A named constant */
.element { color: #40407f; } /* A C structure element */
.identifier { color: #4040ff; } /* An identifier */
.reserved { color: #600000; } /* A reserved word */
/* Comments at the end of lines are rendered like so: */
.comment {
font: "Lucida Grande", "Lucida Sans Unicode", Helvetica, Arial, Verdana, sans-serif;
color: #404040;
font-style:italic;
}
/* The name of a web macro when being used: */
.cwebmacro {
font-family: "Lucida Grande", "Lucida Sans Unicode", Helvetica, Arial, Verdana, sans-serif;
text-decoration: none;
color: #000000; font-weight: bold;
}
.cwebmacronumber {
font-family: "Lucida Grande", "Lucida Sans Unicode", Helvetica, Arial, Verdana, sans-serif;
font-size: 80%;
text-decoration: none;
color: #000000;
}
/* And when being defined: */
.cwebmacrodefn {
font-family: "Lucida Grande", "Lucida Sans Unicode", Helvetica, Arial, Verdana, sans-serif;
text-decoration: none;
color: #000000; font-weight: bold;
font-weight:bold;
}
/* Now some generalities: */
body {
background-color: #ffffff;
margin: 8px;
font-family: "Lucida Grande", "Lucida Sans Unicode", Helvetica, Arial, Verdana, sans-serif;
font-size: 16px;
line-height: 24px;
background-color: transparent;
-webkit-font-smoothing: antialiased;
}
/* Forms of paragraph: */
p {
margin: 0;
padding-top: 5px;
padding-bottom: 5px;
clear: both;
}
/* Where an inweb paragraph begins: */
p.inwebparagraph {
width: 60em;
line-height: 150%;
padding-top: 15px;
padding-bottom: 5px;
}
/* If a web macro definition begins in its own paragraph, this is it: */
p.macrodefinition {
padding-top: 0px;
padding-bottom: 0px;
margin-left: 30px;
}
/* The endnotes at the foot of code: "The function foo_bar is used in ..." */
p.endnote {
font-size: 0.8em;
padding-top: 0px;
padding-bottom: 0px;
margin-left: 30px;
text-decoration:none;
color: #000000;
}
/* The Purpose slug: */
p.purpose {
width: 60em;
line-height: 150%;
font-size: 1em;
font-style:italic;
margin-left: 15px;
}
/* Blocks of code appear in these */
pre {
font-family: Monaco, monospace;
}
pre.display {
padding: 3px;
margin-top: 5px;
margin-bottom: 5px;
margin-left: 30px;
margin-right: 10px;
background: #f8f8f8;
border-width: 1px;
border-style: solid solid solid solid;
border-color: #ccc;
word-wrap: break-word;
white-space: pre-wrap;
}
pre.displaydefn {
padding: 3px;
margin-top: 0px;
margin-bottom: 0px;
margin-left: 0px;
margin-right: 10px;
background: #f8f8f8;
border-width: 1px;
border-style: solid solid solid solid;
border-color: #ccc;
word-wrap: break-word;
white-space: pre-wrap;
}
pre.definitions {
padding-top: 0px;
margin-top: 0px;
margin-left: 0px;
margin-right: 10px;
word-wrap: break-word;
white-space: pre-wrap;
}
/* The following are for breadcrumbs of links: */
ul, li {
list-style-type:none;
padding:0;
margin:0;
}
.crumbs {
border:1px solid #dedede;
height:3.45em;
}
.crumbs li {
float:left;
line-height:2.3em;
padding-left:.75em;
color:#333;
font-size: 1.5em;
}
.crumbs li a {
display:block;
padding:0 15px 0 0;
background:url(crumbs.gif) no-repeat right center;
}
.crumbs li a:link, #crumbs li a:visited {
text-decoration:none;
color:#333;
}
.crumbs li a:hover, #crumbs li a:focus {
color:#dd2c0d;
}
/* This is for items in lists from inweb source: */
ul.items {
margin-top: 3px;
margin-bottom: 3px;
}
ul.items li {
margin-top: 1px;
margin-bottom: 1px;
margin-left: 15px;
}
/* And this is for each section's table of contents: */
ul.toc {
margin-top: 3px;
margin-bottom: 3px;
}
ul.toc li {
float:left;
margin-left: 15px;
color:#000;
}
ul.toc li a {
display:block;
}
ul.toc li a:link, ul.toc li a:visited {
text-decoration:none;
color:#000;
}
ul.toc li a:hover, ul.toc li a:focus {
color:#dd2c0d;
}
hr.tocbar {
clear: both;
margin-top:3px;
margin-bottom:3px;
color:#333;
border:0
background-color:#333;
}
/* This is for cross-reference links ("This code is used in ...") */
p.endnote:link, p.endnote:visited, p.endnote:hover, p.endnote:focus {
text-decoration:none;
color:#000;
}
p.endnote a:link, p.endnote a:visited {
text-decoration:none;
color:#000;
}
p.endnote a:hover, p.endnote a:focus {
text-decoration:none;
color:#dd2c0d;
}
/* Now for the index page */
p.heading {
margin-top: 2px;
margin-bottom: 2px;
font-size: 20
}
p.chapter {
font-size: 14
}
p.tight {
font-size: 12
}
p.tightin {
padding-left: 25px;
font-size: 12
}
.chapterlist li {
padding-top: 8px;
padding-left: 16px;
}
.chaptertitle {
font-weight: bold;
}
.chapterlist .sectionlist li {
padding-left: 48px;
}
span.definitionkeyword {
color:#801010;
font-weight:bold;
}
span.extract {
font-size: 15px;
border: 1px solid #e8e8e8;
border-radius: 3px;
background-color: #eef;
width: 100%;
padding: 3px;
}

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>1/mr</title>
<title>Booklet Title</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
@ -11,9 +11,15 @@
<!--Weave of '1/cm' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">core</a></li><li><a href="index.html#1">Chapter 1: Configuration and Control</a></li><li><b>Core Module</b></li></ul><p class="purpose">Setting up the use of this module.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Introduction</a></li><li><a href="#SP2">&#167;2. Setting up the memory manager</a></li><li><a href="#SP5">&#167;5. The beginning</a></li><li><a href="#SP8">&#167;8. The end</a></li></ul><hr class="tocbar">
<ul class="toc"><li><a href="#SP2">&#167;2. Setting up the memory manager</a></li><li><a href="#SP5">&#167;5. The beginning</a></li><li><a href="#SP8">&#167;8. The end</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Introduction. </b></p>
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. </b>There is no interesting code in this section: all Intools modules open with
a section like this one, configuring the memory management and debugging log
features we will use from <code class="display"><span class="extract">foundation</span></code>.
</p>
<p class="inwebparagraph">The following symbol is defined in every tool incorporating this module:
</p>
<pre class="definitions">
@ -509,7 +515,7 @@ we need to use the equivalent of traditional <code class="display"><span class="
<p class="endnote">The function CoreModule::end appears nowhere else.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="1-mr.html">Back to 'Main Routine'</a></li><li><a href="1-pp.html">Continue with 'Progress Percentages'</a></li></ul><hr class="tocbar">
<ul class="toc"><li><i>(This section begins Chapter 1: Configuration and Control.)</i></li><li><a href="1-mr.html">Continue with 'Main Routine'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>

View file

@ -9,17 +9,30 @@
<body>
<!--Weave of '1/htc' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">core</a></li><li><a href="index.html#1">Chapter 1: Configuration and Control</a></li><li><b>How To Compile</b></li></ul><p class="purpose">To configure the many locations used in the host filing system.</p>
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">core</a></li><li><a href="index.html#1">Chapter 1: Configuration and Control</a></li><li><b>How To Compile</b></li></ul><p class="purpose">The long production line on which products of Inform are built, one step at a time.</p>
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. </b>We run through the following stages in sequence:
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. </b>Having seen the top management of the factory, we now reach the factory
floor, which is one long production line: around 150 steps must be performed
in sequence to finish making the product. We can picture each of these
steps as carried out by a worker function: each does its work and passes
on to the next.
</p>
<p class="inwebparagraph">150 is a great many, so we group the stages into 16 departments, which are,
in order of when they work:
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">STARTED_CSEQ</span><span class="definitionkeyword"> from </span><span class="constant">1</span>
<span class="definitionkeyword">enum</span> <span class="constant">STARTED_CSEQ</span><span class="definitionkeyword"> from </span><span class="constant">0</span>
<span class="definitionkeyword">enum</span> <span class="constant">LEXICAL_CSEQ</span>
<span class="definitionkeyword">enum</span> <span class="constant">SEMANTIC_CSEQ</span>
<span class="definitionkeyword">enum</span> <span class="constant">ASSERTIONS_CSEQ</span>
<span class="definitionkeyword">enum</span> <span class="constant">SEMANTIC_IA_CSEQ</span>
<span class="definitionkeyword">enum</span> <span class="constant">SEMANTIC_LANGUAGE_CSEQ</span>
<span class="definitionkeyword">enum</span> <span class="constant">SEMANTIC_IB_CSEQ</span>
<span class="definitionkeyword">enum</span> <span class="constant">SEMANTIC_II_CSEQ</span>
<span class="definitionkeyword">enum</span> <span class="constant">SEMANTIC_III_CSEQ</span>
<span class="definitionkeyword">enum</span> <span class="constant">ASSERTIONS_PASS_1_CSEQ</span>
<span class="definitionkeyword">enum</span> <span class="constant">ASSERTIONS_PASS_2_CSEQ</span>
<span class="definitionkeyword">enum</span> <span class="constant">MODEL_CSEQ</span>
<span class="definitionkeyword">enum</span> <span class="constant">MODEL_COMPLETE_CSEQ</span>
<span class="definitionkeyword">enum</span> <span class="constant">TABLES_CSEQ</span>
@ -34,27 +47,37 @@
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b></p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>The aim of this section is to contain as little logic as possible. However,
a few of the steps are carried out only if debugging features are enabled,
or disabled; or only if certain elements of the Inform language are enabled.
For example, a Basic Inform source text is not allowed to contain command
parser grammar in the way that an IF source text would, so the steps to do
with building that grammar are skipped unless the relevant language element
is active.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">no_compile_tasks_carried_out</span><span class="plain"> = 0;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">compiler_booted_up</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Sequence::carry_out</span><span class="plain">(</span><span class="reserved">compile_task_data</span><span class="plain"> *</span><span class="identifier">ctd</span><span class="plain">) {</span>
<span class="functiontext">Task::advance_stage_to</span><span class="plain">(</span><span class="constant">STARTED_CSEQ</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">no_compile_tasks_carried_out</span><span class="plain"> == 0) </span>&lt;<span class="cwebmacro">Boot up the compiler</span> <span class="cwebmacronumber">2.1</span>&gt;<span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Sequence::carry_out</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">debugging</span><span class="plain">) {</span>
<span class="identifier">clock_t</span><span class="plain"> </span><span class="identifier">start</span><span class="plain"> = </span><span class="identifier">clock</span><span class="plain">();</span>
&lt;<span class="cwebmacro">Perform lexical analysis</span> <span class="cwebmacronumber">2.2</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Perform semantic analysis</span> <span class="cwebmacronumber">2.3</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Read the assertions in two passes</span> <span class="cwebmacronumber">2.4</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Make the model world</span> <span class="cwebmacronumber">2.5</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Tables and grammar</span> <span class="cwebmacronumber">2.6</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Phrases and rules</span> <span class="cwebmacronumber">2.7</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Generate inter</span> <span class="cwebmacronumber">2.8</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Generate index and bibliographic file</span> <span class="cwebmacronumber">2.9</span>&gt;<span class="plain">;</span>
<span class="functiontext">Task::advance_stage_to</span><span class="plain">(</span><span class="constant">STARTED_CSEQ</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Starting"</span><span class="plain">, -1);</span>
<span class="functiontext">Task::advance_stage_to</span><span class="plain">(</span><span class="constant">FINISHED_CSEQ</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">compiler_booted_up</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
&lt;<span class="cwebmacro">Boot up the compiler</span> <span class="cwebmacronumber">2.2</span>&gt;<span class="plain">;</span>
<span class="identifier">compiler_booted_up</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
&lt;<span class="cwebmacro">Perform lexical analysis</span> <span class="cwebmacronumber">2.3</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Perform semantic analysis</span> <span class="cwebmacronumber">2.4</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Read the assertions in two passes</span> <span class="cwebmacronumber">2.5</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Make the model world</span> <span class="cwebmacronumber">2.6</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Tables and grammar</span> <span class="cwebmacronumber">2.7</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Phrases and rules</span> <span class="cwebmacronumber">2.8</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Generate inter</span> <span class="cwebmacronumber">2.9</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Generate index and bibliographic file</span> <span class="cwebmacronumber">2.10</span>&gt;<span class="plain">;</span>
<span class="functiontext">Task::advance_stage_to</span><span class="plain">(</span><span class="constant">FINISHED_CSEQ</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Ccmplete"</span><span class="plain">, -1);</span>
<span class="identifier">clock_t</span><span class="plain"> </span><span class="identifier">end</span><span class="plain"> = </span><span class="identifier">clock</span><span class="plain">();</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">cpu_time_used</span><span class="plain"> = ((</span><span class="reserved">int</span><span class="plain">) (</span><span class="identifier">end</span><span class="plain"> - </span><span class="identifier">start</span><span class="plain">)) / (</span><span class="identifier">CLOCKS_PER_SEC</span><span class="plain">/100);</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Compile CPU time: %d centiseconds\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">cpu_time_used</span><span class="plain">);</span>
@ -67,11 +90,25 @@
<p class="endnote">The function Sequence::carry_out is used in 1/wtc (<a href="1-wtc.html#SP2">&#167;2</a>).</p>
<p class="inwebparagraph"><a id="SP2_1"></a><b>&#167;2.1. </b></p>
<p class="inwebparagraph"><a id="SP2_1"></a><b>&#167;2.1. </b>Here are macros for the unconditional and conditional steps, respectively,
taking place at what we think of as benches in the production line. Continuing
the analogy, there is an ongoing time and motion study: any step which takes
more than 1 centisecond of CPU time is reported to the debugging log. That
isn't necessarily a sign of something wrong: a few of these steps are always
going to take serious computation. But we want to know which ones.
</p>
<p class="inwebparagraph">As soon as any step generates problem messages, all subsequent steps are
skipped, so that each of the worker functions can assume that the
part-assembled state they receive is correct so far. This greatly simplifies
error recovery, prevents small errors in the source text leading to
cascades of problem messages, and ensures that we report problems as quickly
as possible.
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="identifier">routine</span><span class="plain">, </span><span class="identifier">mark</span><span class="plain">) {</span>
<span class="definitionkeyword">define</span> <span class="identifier">BENCH</span><span class="plain">(</span><span class="identifier">routine</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_count</span><span class="plain"> == 0) {</span>
<span class="identifier">clock_t</span><span class="plain"> </span><span class="identifier">now</span><span class="plain"> = </span><span class="identifier">clock</span><span class="plain">();</span>
<span class="identifier">routine</span><span class="plain">();</span>
@ -79,7 +116,7 @@
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">cs</span><span class="plain"> &gt; 0) </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">".... "</span><span class="plain"> #</span><span class="identifier">routine</span><span class="plain"> </span><span class="string">"() took %dcs\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">cs</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="definitionkeyword">define</span> <span class="identifier">COMPILATION_STEP_IF</span><span class="plain">(</span><span class="reserved">plugin</span><span class="plain">, </span><span class="identifier">routine</span><span class="plain">, </span><span class="identifier">mark</span><span class="plain">) {</span>
<span class="definitionkeyword">define</span> <span class="identifier">BENCH_IF</span><span class="plain">(</span><span class="reserved">plugin</span><span class="plain">, </span><span class="identifier">routine</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="functiontext">Plugins::Manage::plugged_in</span><span class="plain">(</span><span class="reserved">plugin</span><span class="plain">))) {</span>
<span class="identifier">clock_t</span><span class="plain"> </span><span class="identifier">now</span><span class="plain"> = </span><span class="identifier">clock</span><span class="plain">();</span>
<span class="identifier">routine</span><span class="plain">();</span>
@ -87,337 +124,299 @@
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">cs</span><span class="plain"> &gt; 0) </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">".... "</span><span class="plain"> #</span><span class="identifier">routine</span><span class="plain"> </span><span class="string">"() took %dcs\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">cs</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Boot up the compiler</span> <span class="cwebmacronumber">2.1</span>&gt; =
</code></p>
</pre>
<p class="inwebparagraph"><a id="SP2_2"></a><b>&#167;2.2. </b>Here, then, are the steps in the production line, presented without
commentary. For what they do, see the relevant sections. Note that although
most of these worker functions are in the <code class="display"><span class="extract">core</span></code> module, some are not.
</p>
<pre class="displaydefn">
<span class="functiontext">Emit::begin</span><span class="plain">();</span>
<span class="functiontext">Semantics::read_preform</span><span class="plain">();</span>
<span class="functiontext">Plugins::Manage::start</span><span class="plain">();</span>
<span class="functiontext">InferenceSubjects::begin</span><span class="plain">();</span>
<span class="identifier">Index::DocReferences::read_xrefs</span><span class="plain">();</span>
<span class="identifier">doc_references_top</span><span class="plain"> = </span><span class="identifier">lexer_wordcount</span><span class="plain"> - 1;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP2_2"></a><b>&#167;2.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Perform lexical analysis</span> <span class="cwebmacronumber">2.2</span>&gt; =
</code></p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Boot up the compiler</span> <span class="cwebmacronumber">2.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="functiontext">Task::advance_stage_to</span><span class="plain">(</span><span class="constant">LEXICAL_CSEQ</span><span class="plain">);</span>
<span class="functiontext">ProgressBar::update_progress_bar</span><span class="plain">(0, 0);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_count</span><span class="plain"> == 0) </span><span class="functiontext">Sequence::go_to_log_phase</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"Lexical analysis"</span><span class="plain">);</span>
<span class="functiontext">SourceFiles::read</span><span class="plain">(</span><span class="functiontext">Task::project</span><span class="plain">()-&gt;</span><span class="identifier">as_copy</span><span class="plain">);</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Sentences::RuleSubtrees::create_standard_csps</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Sentences::RuleSubtrees::create_standard_csps"</span><span class="plain">)</span>
</pre>
<pre class="displaydefn">
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Emit::begin</span><span class="plain">);</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Semantics::read_preform</span><span class="plain">);</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Plugins::Manage::start</span><span class="plain">);</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">InferenceSubjects::begin</span><span class="plain">);</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="identifier">Index::DocReferences::read_xrefs</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP2">&#167;2</a>.</p>
<p class="endnote">This code is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP2_3"></a><b>&#167;2.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">Perform semantic analysis</span> <span class="cwebmacronumber">2.3</span>&gt; =
</code></p>
<p class="inwebparagraph"><a id="SP2_3"></a><b>&#167;2.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">Perform lexical analysis</span> <span class="cwebmacronumber">2.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="functiontext">Task::advance_stage_to</span><span class="plain">(</span><span class="constant">SEMANTIC_CSEQ</span><span class="plain">);</span>
<span class="functiontext">ProgressBar::update_progress_bar</span><span class="plain">(1, 0);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_count</span><span class="plain"> == 0) </span><span class="functiontext">Sequence::go_to_log_phase</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"Semantic analysis Ia"</span><span class="plain">);</span>
<span class="identifier">Projects::activate_plugins</span><span class="plain">(</span><span class="functiontext">Task::project</span><span class="plain">());</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">ParseTreeUsage::plant_parse_tree</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"ParseTreeUsage::plant_parse_tree"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">StructuralSentences::break_source</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"StructuralSentences::break_source"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Extensions::Inclusion::traverse</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Extensions::Inclusion::traverse"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Sentences::Headings::satisfy_dependencies</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Sentences::Headings::satisfy_dependencies"</span><span class="plain">)</span>
<pre class="displaydefn">
<span class="functiontext">Task::advance_stage_to</span><span class="plain">(</span><span class="constant">LEXICAL_CSEQ</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Lexical analysis"</span><span class="plain">, 0);</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Task::read_source_text</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Sentences::RuleSubtrees::create_standard_csps</span><span class="plain">)</span>
</pre>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_count</span><span class="plain"> == 0) </span><span class="functiontext">Sequence::go_to_log_phase</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"Initialise language semantics"</span><span class="plain">);</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Plugins::Manage::start_plugins</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Plugins::Manage::start_plugins"</span><span class="plain">);</span>
<span class="identifier">Projects::load_types</span><span class="plain">(</span><span class="functiontext">Task::project</span><span class="plain">());</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">BinaryPredicates::make_built_in</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"BinaryPredicates::make_built_in"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">NewVerbs::add_inequalities</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"NewVerbs::add_inequalities"</span><span class="plain">)</span>
<p class="inwebparagraph"></p>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_count</span><span class="plain"> == 0) </span><span class="functiontext">Sequence::go_to_log_phase</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"Semantic analysis Ib"</span><span class="plain">);</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Sentences::VPs::traverse</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Sentences::VPs::traverse"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Sentences::Rearrangement::tidy_up_ofs_and_froms</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Sentences::Rearrangement::tidy_up_ofs_and_froms"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Sentences::RuleSubtrees::register_recently_lexed_phrases</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Sentences::RuleSubtrees::register_recently_lexed_phrases"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">StructuralSentences::declare_source_loaded</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"StructuralSentences::declare_source_loaded"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="identifier">Kinds::Interpreter::include_templates_for_kinds</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Kinds::Interpreter::include_templates_for_kinds"</span><span class="plain">)</span>
<p class="endnote">This code is used in <a href="#SP2">&#167;2</a>.</p>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_count</span><span class="plain"> == 0) </span><span class="functiontext">Sequence::go_to_log_phase</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"Semantic analysis II"</span><span class="plain">);</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">ParseTreeUsage::verify</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"ParseTreeUsage::verify"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Extensions::Files::check_versions</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Extensions::Files::check_versions"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Sentences::Headings::make_tree</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Sentences::Headings::make_tree"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Sentences::Headings::write_as_xml</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Sentences::Headings::write_as_xml"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Sentences::Headings::write_as_xml</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Sentences::Headings::write_as_xml"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Modules::traverse_to_define</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Modules::traverse_to_define"</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_count</span><span class="plain"> == 0) </span><span class="functiontext">Sequence::go_to_log_phase</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"Semantic analysis III"</span><span class="plain">);</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Phrases::Adjectives::traverse</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Phrases::Adjectives::traverse"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Equations::traverse_to_create</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Equations::traverse_to_create"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Tables::traverse_to_create</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Tables::traverse_to_create"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Phrases::Manager::traverse_for_names</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Phrases::Manager::traverse_for_names"</span><span class="plain">)</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP2_4"></a><b>&#167;2.4. </b><code class="display">
&lt;<span class="cwebmacrodefn">Read the assertions in two passes</span> <span class="cwebmacronumber">2.4</span>&gt; =
</code></p>
<p class="inwebparagraph"><a id="SP2_4"></a><b>&#167;2.4. </b><code class="display">
&lt;<span class="cwebmacrodefn">Perform semantic analysis</span> <span class="cwebmacronumber">2.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="functiontext">Task::advance_stage_to</span><span class="plain">(</span><span class="constant">ASSERTIONS_CSEQ</span><span class="plain">);</span>
<span class="functiontext">ProgressBar::update_progress_bar</span><span class="plain">(2, 0);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_count</span><span class="plain"> == 0) </span><span class="functiontext">Sequence::go_to_log_phase</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"First pass through assertions"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_count</span><span class="plain"> == 0) </span><span class="functiontext">Assertions::Traverse::traverse</span><span class="plain">(1);</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Tables::traverse_to_stock</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Tables::traverse_to_stock"</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_count</span><span class="plain"> == 0) </span><span class="functiontext">Sequence::go_to_log_phase</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"Second pass through assertions"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_count</span><span class="plain"> == 0) </span><span class="functiontext">Assertions::Traverse::traverse</span><span class="plain">(2);</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Kinds::RunTime::kind_declarations</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Kinds::RunTime::kind_declarations"</span><span class="plain">)</span>
</pre>
<pre class="displaydefn">
<span class="functiontext">Task::advance_stage_to</span><span class="plain">(</span><span class="constant">SEMANTIC_IA_CSEQ</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Semantic analysis Ia"</span><span class="plain">, 1);</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Task::activate_language_elements</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">ParseTreeUsage::plant_parse_tree</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">StructuralSentences::break_source</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Extensions::Inclusion::traverse</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Sentences::Headings::satisfy_dependencies</span><span class="plain">)</span>
<p class="inwebparagraph"></p>
<span class="functiontext">Task::advance_stage_to</span><span class="plain">(</span><span class="constant">SEMANTIC_LANGUAGE_CSEQ</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Initialise language semantics"</span><span class="plain">, -1);</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Plugins::Manage::start_plugins</span><span class="plain">);</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Task::load_types</span><span class="plain">);</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">BinaryPredicates::make_built_in</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">NewVerbs::add_inequalities</span><span class="plain">)</span>
<p class="endnote">This code is used in <a href="#SP2">&#167;2</a>.</p>
<span class="functiontext">Task::advance_stage_to</span><span class="plain">(</span><span class="constant">SEMANTIC_IB_CSEQ</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Semantic analysis Ib"</span><span class="plain">, -1);</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Sentences::VPs::traverse</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Sentences::Rearrangement::tidy_up_ofs_and_froms</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Sentences::RuleSubtrees::register_recently_lexed_phrases</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">StructuralSentences::declare_source_loaded</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="identifier">Kinds::Interpreter::include_templates_for_kinds</span><span class="plain">)</span>
<p class="inwebparagraph"><a id="SP2_5"></a><b>&#167;2.5. </b><code class="display">
&lt;<span class="cwebmacrodefn">Make the model world</span> <span class="cwebmacronumber">2.5</span>&gt; =
</code></p>
<span class="functiontext">Task::advance_stage_to</span><span class="plain">(</span><span class="constant">SEMANTIC_II_CSEQ</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Semantic analysis II"</span><span class="plain">, -1);</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">ParseTreeUsage::verify</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Extensions::Files::check_versions</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Sentences::Headings::make_tree</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Sentences::Headings::write_as_xml</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Sentences::Headings::write_as_xml</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Modules::traverse_to_define</span><span class="plain">)</span>
<span class="functiontext">Task::advance_stage_to</span><span class="plain">(</span><span class="constant">SEMANTIC_III_CSEQ</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Semantic analysis III"</span><span class="plain">, -1);</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Phrases::Adjectives::traverse</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Equations::traverse_to_create</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Tables::traverse_to_create</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Phrases::Manager::traverse_for_names</span><span class="plain">)</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP2_5"></a><b>&#167;2.5. </b><code class="display">
&lt;<span class="cwebmacrodefn">Read the assertions in two passes</span> <span class="cwebmacronumber">2.5</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="functiontext">Task::advance_stage_to</span><span class="plain">(</span><span class="constant">MODEL_CSEQ</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_count</span><span class="plain"> == 0) </span><span class="functiontext">Sequence::go_to_log_phase</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"Making the model world"</span><span class="plain">);</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">UseOptions::compile</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"UseOptions::compile"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Properties::emit</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Properties::emit"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Properties::Emit::allocate_attributes</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Properties::Emit::allocate_attributes"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="identifier">PL::Actions::name_all</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"PL::Actions::name_all"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">UseNouns::name_all</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"UseNouns::name_all"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Instances::place_objects_in_definition_sequence</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Instances::place_objects_in_definition_sequence"</span><span class="plain">)</span>
<span class="functiontext">Task::advance_stage_to</span><span class="plain">(</span><span class="constant">MODEL_COMPLETE_CSEQ</span><span class="plain">);</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">World::complete</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"World::complete"</span><span class="plain">)</span>
</pre>
<pre class="displaydefn">
<span class="functiontext">Task::advance_stage_to</span><span class="plain">(</span><span class="constant">ASSERTIONS_PASS_1_CSEQ</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"First pass through assertions"</span><span class="plain">, 2);</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Assertions::Traverse::traverse1</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Tables::traverse_to_stock</span><span class="plain">)</span>
<span class="functiontext">Task::advance_stage_to</span><span class="plain">(</span><span class="constant">ASSERTIONS_PASS_2_CSEQ</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Second pass through assertions"</span><span class="plain">, -1);</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Assertions::Traverse::traverse2</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Kinds::RunTime::kind_declarations</span><span class="plain">)</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP2">&#167;2</a>.</p>
<p class="endnote">This code is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP2_6"></a><b>&#167;2.6. </b><code class="display">
&lt;<span class="cwebmacrodefn">Tables and grammar</span> <span class="cwebmacronumber">2.6</span>&gt; =
</code></p>
<p class="inwebparagraph"><a id="SP2_6"></a><b>&#167;2.6. </b><code class="display">
&lt;<span class="cwebmacrodefn">Make the model world</span> <span class="cwebmacronumber">2.6</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="functiontext">Task::advance_stage_to</span><span class="plain">(</span><span class="constant">TABLES_CSEQ</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_count</span><span class="plain"> == 0) </span><span class="functiontext">Sequence::go_to_log_phase</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"Tables and grammar"</span><span class="plain">);</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Properties::Measurement::validate_definitions</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Properties::Measurement::validate_definitions"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">BinaryPredicates::make_built_in_further</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"BinaryPredicates::make_built_in_further"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="identifier">PL::Bibliographic::IFID::define_UUID</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"PL::Bibliographic::IFID::define_UUID"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="identifier">PL::Figures::compile_ResourceIDsOfFigures_array</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"PL::Figures::compile_ResourceIDsOfFigures_array"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="identifier">PL::Sounds::compile_ResourceIDsOfSounds_array</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"PL::Sounds::compile_ResourceIDsOfSounds_array"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="identifier">PL::Player::InitialSituation</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"PL::Player::InitialSituation"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Tables::check_tables_for_kind_clashes</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Tables::check_tables_for_kind_clashes"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Tables::Support::compile_print_table_names</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Tables::Support::compile_print_table_names"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="identifier">PL::Parsing::traverse</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"PL::Parsing::traverse"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">World::complete_additions</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"World::complete_additions"</span><span class="plain">)</span>
</pre>
<pre class="displaydefn">
<span class="functiontext">Task::advance_stage_to</span><span class="plain">(</span><span class="constant">MODEL_CSEQ</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Making the model world"</span><span class="plain">, -1);</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">UseOptions::compile</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Properties::emit</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Properties::Emit::allocate_attributes</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="identifier">PL::Actions::name_all</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">UseNouns::name_all</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Instances::place_objects_in_definition_sequence</span><span class="plain">)</span>
<span class="functiontext">Task::advance_stage_to</span><span class="plain">(</span><span class="constant">MODEL_COMPLETE_CSEQ</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Completing the model world"</span><span class="plain">, -1);</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">World::complete</span><span class="plain">)</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP2">&#167;2</a>.</p>
<p class="endnote">This code is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP2_7"></a><b>&#167;2.7. </b><code class="display">
&lt;<span class="cwebmacrodefn">Phrases and rules</span> <span class="cwebmacronumber">2.7</span>&gt; =
</code></p>
<p class="inwebparagraph"><a id="SP2_7"></a><b>&#167;2.7. </b><code class="display">
&lt;<span class="cwebmacrodefn">Tables and grammar</span> <span class="cwebmacronumber">2.7</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="functiontext">Task::advance_stage_to</span><span class="plain">(</span><span class="constant">PHRASES_CSEQ</span><span class="plain">);</span>
<span class="functiontext">ProgressBar::update_progress_bar</span><span class="plain">(3, 0);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_count</span><span class="plain"> == 0) </span><span class="functiontext">Sequence::go_to_log_phase</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"Phrases and rules"</span><span class="plain">);</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">LiteralPatterns::define_named_phrases</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"LiteralPatterns::define_named_phrases"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Phrases::Manager::traverse</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Phrases::Manager::traverse"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Phrases::Manager::register_meanings</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Phrases::Manager::register_meanings"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Phrases::Manager::parse_rule_parameters</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Phrases::Manager::parse_rule_parameters"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Phrases::Manager::add_rules_to_rulebooks</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Phrases::Manager::add_rules_to_rulebooks"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Phrases::Manager::parse_rule_placements</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Phrases::Manager::parse_rule_placements"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Equations::traverse_to_stock</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Equations::traverse_to_stock"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Tables::traverse_to_stock</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Tables::traverse_to_stock"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Properties::annotate_attributes</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Properties::annotate_attributes"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Rulebooks::Outcomes::RulebookOutcomePrintingRule</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Rulebooks::Outcomes::RulebookOutcomePrintingRule"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Kinds::RunTime::compile_instance_counts</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Kinds::RunTime::compile_instance_counts"</span><span class="plain">)</span>
</pre>
<pre class="displaydefn">
<span class="functiontext">Task::advance_stage_to</span><span class="plain">(</span><span class="constant">TABLES_CSEQ</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Tables and grammar"</span><span class="plain">, -1);</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Properties::Measurement::validate_definitions</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">BinaryPredicates::make_built_in_further</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="identifier">PL::Bibliographic::IFID::define_UUID</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="identifier">PL::Figures::compile_ResourceIDsOfFigures_array</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="identifier">PL::Sounds::compile_ResourceIDsOfSounds_array</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="identifier">PL::Player::InitialSituation</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Tables::check_tables_for_kind_clashes</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Tables::Support::compile_print_table_names</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="identifier">PL::Parsing::traverse</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">World::complete_additions</span><span class="plain">)</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP2">&#167;2</a>.</p>
<p class="endnote">This code is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP2_8"></a><b>&#167;2.8. </b>This is where we hand over to regular template files &mdash; containing code
passed through as I6 source, as well as a few further commands &mdash; starting
with "Output.i6t".
</p>
<p class="inwebparagraph"><a id="SP2_8"></a><b>&#167;2.8. </b><code class="display">
&lt;<span class="cwebmacrodefn">Phrases and rules</span> <span class="cwebmacronumber">2.8</span>&gt; =
</code></p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Generate inter</span> <span class="cwebmacronumber">2.8</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="functiontext">Task::advance_stage_to</span><span class="plain">(</span><span class="constant">PHRASES_CSEQ</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Phrases and rules"</span><span class="plain">, 3);</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">LiteralPatterns::define_named_phrases</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Phrases::Manager::traverse</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Phrases::Manager::register_meanings</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Phrases::Manager::parse_rule_parameters</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Phrases::Manager::add_rules_to_rulebooks</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Phrases::Manager::parse_rule_placements</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Equations::traverse_to_stock</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Tables::traverse_to_stock</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Properties::annotate_attributes</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Rulebooks::Outcomes::RulebookOutcomePrintingRule</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Kinds::RunTime::compile_instance_counts</span><span class="plain">)</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP2_9"></a><b>&#167;2.9. </b><code class="display">
&lt;<span class="cwebmacrodefn">Generate inter</span> <span class="cwebmacronumber">2.9</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="functiontext">Task::advance_stage_to</span><span class="plain">(</span><span class="constant">INTER_CSEQ</span><span class="plain">);</span>
<span class="functiontext">ProgressBar::update_progress_bar</span><span class="plain">(4, 0);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_count</span><span class="plain"> == 0) </span><span class="functiontext">Sequence::go_to_log_phase</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"Generating inter"</span><span class="plain">);</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">UseOptions::compile_icl_commands</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"UseOptions::compile_icl_commands"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">FundamentalConstants::emit_build_number</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"FundamentalConstants::emit_build_number"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="identifier">PL::Bibliographic::compile_constants</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"PL::Bibliographic::compile_constants"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Extensions::Files::ShowExtensionVersions_routine</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Extensions::Files::ShowExtensionVersions_routine"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="identifier">Kinds::Constructors::compile_I6_constants</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Kinds::Constructors::compile_I6_constants"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP_IF</span><span class="plain">(</span><span class="identifier">scoring_plugin</span><span class="plain">, </span><span class="identifier">PL::Score::compile_max_score</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"PL::Score::compile_max_score"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">UseOptions::TestUseOption_routine</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"UseOptions::TestUseOption_routine"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Activities::compile_activity_constants</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Activities::compile_activity_constants"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Activities::Activity_before_rulebooks_array</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Activities::Activity_before_rulebooks_array"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Activities::Activity_for_rulebooks_array</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Activities::Activity_for_rulebooks_array"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Activities::Activity_after_rulebooks_array</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Activities::Activity_after_rulebooks_array"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Activities::Activity_atb_rulebooks_array</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Activities::Activity_atb_rulebooks_array"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Relations::compile_defined_relation_constants</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Relations::compile_defined_relation_constants"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Kinds::RunTime::compile_data_type_support_routines</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Kinds::RunTime::compile_data_type_support_routines"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Kinds::RunTime::I7_Kind_Name_routine</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Kinds::RunTime::I7_Kind_Name_routine"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">World::Compile::compile</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"World::Compile::compile"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP_IF</span><span class="plain">(</span><span class="identifier">backdrops_plugin</span><span class="plain">, </span><span class="identifier">PL::Backdrops::write_found_in_routines</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"PL::Backdrops::write_found_in_routines"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP_IF</span><span class="plain">(</span><span class="identifier">map_plugin</span><span class="plain">, </span><span class="identifier">PL::Map::write_door_dir_routines</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"PL::Map::write_door_dir_routines"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP_IF</span><span class="plain">(</span><span class="identifier">map_plugin</span><span class="plain">, </span><span class="identifier">PL::Map::write_door_to_routines</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"PL::Map::write_door_to_routines"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP_IF</span><span class="plain">(</span><span class="identifier">parsing_plugin</span><span class="plain">, </span><span class="identifier">PL::Parsing::Tokens::General::write_parse_name_routines</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"PL::Parsing::Tokens::General::write_parse_name_routines"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP_IF</span><span class="plain">(</span><span class="identifier">regions_plugin</span><span class="plain">, </span><span class="identifier">PL::Regions::write_regional_found_in_routines</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"PL::Regions::write_regional_found_in_routines"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Tables::complete</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Tables::complete"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Tables::Support::compile</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Tables::Support::compile"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Equations::compile</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Equations::compile"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP_IF</span><span class="plain">(</span><span class="identifier">actions_plugin</span><span class="plain">, </span><span class="identifier">PL::Actions::Patterns::Named::compile</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"PL::Actions::Patterns::Named::compile"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP_IF</span><span class="plain">(</span><span class="identifier">actions_plugin</span><span class="plain">, </span><span class="identifier">PL::Actions::ActionData</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"PL::Actions::ActionData"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP_IF</span><span class="plain">(</span><span class="identifier">actions_plugin</span><span class="plain">, </span><span class="identifier">PL::Actions::ActionCoding_array</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"PL::Actions::ActionCoding_array"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP_IF</span><span class="plain">(</span><span class="identifier">actions_plugin</span><span class="plain">, </span><span class="identifier">PL::Actions::ActionHappened</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"PL::Actions::ActionHappened"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP_IF</span><span class="plain">(</span><span class="identifier">actions_plugin</span><span class="plain">, </span><span class="identifier">PL::Actions::compile_action_routines</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"PL::Actions::compile_action_routines"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP_IF</span><span class="plain">(</span><span class="identifier">parsing_plugin</span><span class="plain">, </span><span class="identifier">PL::Parsing::Lines::MistakeActionSub_routine</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"PL::Parsing::Lines::MistakeActionSub_routine"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Phrases::Manager::compile_first_block</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Phrases::Manager::compile_first_block"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Phrases::Manager::compile_rulebooks</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Phrases::Manager::compile_rulebooks"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Phrases::Manager::rulebooks_array</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Phrases::Manager::rulebooks_array"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP_IF</span><span class="plain">(</span><span class="identifier">scenes_plugin</span><span class="plain">, </span><span class="identifier">PL::Scenes::DetectSceneChange_routine</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"PL::Scenes::DetectSceneChange_routine"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP_IF</span><span class="plain">(</span><span class="identifier">scenes_plugin</span><span class="plain">, </span><span class="identifier">PL::Scenes::ShowSceneStatus_routine</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"PL::Scenes::ShowSceneStatus_routine"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="identifier">PL::Files::arrays</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"PL::Files::arrays"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Rulebooks::rulebook_var_creators</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Rulebooks::rulebook_var_creators"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Activities::activity_var_creators</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Activities::activity_var_creators"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Relations::IterateRelations</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Relations::IterateRelations"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Phrases::Manager::RulebookNames_array</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Phrases::Manager::RulebookNames_array"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Phrases::Manager::RulePrintingRule_routine</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Phrases::Manager::RulePrintingRule_routine"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP_IF</span><span class="plain">(</span><span class="identifier">parsing_plugin</span><span class="plain">, </span><span class="identifier">PL::Parsing::Verbs::prepare</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"PL::Parsing::Verbs::prepare"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP_IF</span><span class="plain">(</span><span class="identifier">parsing_plugin</span><span class="plain">, </span><span class="identifier">PL::Parsing::Verbs::compile_conditions</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"PL::Parsing::Verbs::compile_conditions"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP_IF</span><span class="plain">(</span><span class="identifier">parsing_plugin</span><span class="plain">, </span><span class="identifier">PL::Parsing::Tokens::Values::number</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"PL::Parsing::Tokens::Values::number"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP_IF</span><span class="plain">(</span><span class="identifier">parsing_plugin</span><span class="plain">, </span><span class="identifier">PL::Parsing::Tokens::Values::truth_state</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"PL::Parsing::Tokens::Values::truth_state"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP_IF</span><span class="plain">(</span><span class="identifier">parsing_plugin</span><span class="plain">, </span><span class="identifier">PL::Parsing::Tokens::Values::time</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"PL::Parsing::Tokens::Values::time"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP_IF</span><span class="plain">(</span><span class="identifier">parsing_plugin</span><span class="plain">, </span><span class="identifier">PL::Parsing::Tokens::Values::compile_type_gprs</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"PL::Parsing::Tokens::Values::compile_type_gprs"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">NewVerbs::ConjugateVerb</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"NewVerbs::ConjugateVerb"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Adjectives::Meanings::agreements</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Adjectives::Meanings::agreements"</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">TargetVMs::debug_enabled</span><span class="plain">(</span><span class="functiontext">Task::vm</span><span class="plain">())) {</span>
<span class="identifier">COMPILATION_STEP_IF</span><span class="plain">(</span><span class="identifier">parsing_plugin</span><span class="plain">, </span><span class="functiontext">PL::Parsing::TestScripts::write_text</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"PL::Parsing::TestScripts::write_text"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP_IF</span><span class="plain">(</span><span class="identifier">parsing_plugin</span><span class="plain">, </span><span class="functiontext">PL::Parsing::TestScripts::TestScriptSub_routine</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"PL::Parsing::TestScripts::TestScriptSub_routine"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP_IF</span><span class="plain">(</span><span class="identifier">parsing_plugin</span><span class="plain">, </span><span class="functiontext">PL::Parsing::TestScripts::InternalTestCases_routine</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"PL::Parsing::TestScripts::InternalTestCases_routine"</span><span class="plain">)</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">COMPILATION_STEP_IF</span><span class="plain">(</span><span class="identifier">parsing_plugin</span><span class="plain">, </span><span class="functiontext">PL::Parsing::TestScripts::TestScriptSub_stub_routine</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"PL::Parsing::TestScripts::TestScriptSub_stub_routine"</span><span class="plain">)</span>
<span class="plain">}</span>
<pre class="displaydefn">
<span class="functiontext">Task::advance_stage_to</span><span class="plain">(</span><span class="constant">INTER_CSEQ</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Generating inter"</span><span class="plain">, 4);</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">UseOptions::compile_icl_commands</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">FundamentalConstants::emit_build_number</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="identifier">PL::Bibliographic::compile_constants</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Extensions::Files::ShowExtensionVersions_routine</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="identifier">Kinds::Constructors::compile_I6_constants</span><span class="plain">)</span>
<span class="identifier">BENCH_IF</span><span class="plain">(</span><span class="identifier">scoring_plugin</span><span class="plain">, </span><span class="identifier">PL::Score::compile_max_score</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">UseOptions::TestUseOption_routine</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Activities::compile_activity_constants</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Activities::Activity_before_rulebooks_array</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Activities::Activity_for_rulebooks_array</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Activities::Activity_after_rulebooks_array</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Activities::Activity_atb_rulebooks_array</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Relations::compile_defined_relation_constants</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Kinds::RunTime::compile_data_type_support_routines</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Kinds::RunTime::I7_Kind_Name_routine</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">World::Compile::compile</span><span class="plain">)</span>
<span class="identifier">BENCH_IF</span><span class="plain">(</span><span class="identifier">backdrops_plugin</span><span class="plain">, </span><span class="identifier">PL::Backdrops::write_found_in_routines</span><span class="plain">)</span>
<span class="identifier">BENCH_IF</span><span class="plain">(</span><span class="identifier">map_plugin</span><span class="plain">, </span><span class="identifier">PL::Map::write_door_dir_routines</span><span class="plain">)</span>
<span class="identifier">BENCH_IF</span><span class="plain">(</span><span class="identifier">map_plugin</span><span class="plain">, </span><span class="identifier">PL::Map::write_door_to_routines</span><span class="plain">)</span>
<span class="identifier">BENCH_IF</span><span class="plain">(</span><span class="identifier">parsing_plugin</span><span class="plain">, </span><span class="identifier">PL::Parsing::Tokens::General::write_parse_name_routines</span><span class="plain">)</span>
<span class="identifier">BENCH_IF</span><span class="plain">(</span><span class="identifier">regions_plugin</span><span class="plain">, </span><span class="identifier">PL::Regions::write_regional_found_in_routines</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Tables::complete</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Tables::Support::compile</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Equations::compile</span><span class="plain">)</span>
<span class="identifier">BENCH_IF</span><span class="plain">(</span><span class="identifier">actions_plugin</span><span class="plain">, </span><span class="identifier">PL::Actions::Patterns::Named::compile</span><span class="plain">)</span>
<span class="identifier">BENCH_IF</span><span class="plain">(</span><span class="identifier">actions_plugin</span><span class="plain">, </span><span class="identifier">PL::Actions::ActionData</span><span class="plain">)</span>
<span class="identifier">BENCH_IF</span><span class="plain">(</span><span class="identifier">actions_plugin</span><span class="plain">, </span><span class="identifier">PL::Actions::ActionCoding_array</span><span class="plain">)</span>
<span class="identifier">BENCH_IF</span><span class="plain">(</span><span class="identifier">actions_plugin</span><span class="plain">, </span><span class="identifier">PL::Actions::ActionHappened</span><span class="plain">)</span>
<span class="identifier">BENCH_IF</span><span class="plain">(</span><span class="identifier">actions_plugin</span><span class="plain">, </span><span class="identifier">PL::Actions::compile_action_routines</span><span class="plain">)</span>
<span class="identifier">BENCH_IF</span><span class="plain">(</span><span class="identifier">parsing_plugin</span><span class="plain">, </span><span class="identifier">PL::Parsing::Lines::MistakeActionSub_routine</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Phrases::Manager::compile_first_block</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Phrases::Manager::compile_rulebooks</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Phrases::Manager::rulebooks_array</span><span class="plain">)</span>
<span class="identifier">BENCH_IF</span><span class="plain">(</span><span class="identifier">scenes_plugin</span><span class="plain">, </span><span class="identifier">PL::Scenes::DetectSceneChange_routine</span><span class="plain">)</span>
<span class="identifier">BENCH_IF</span><span class="plain">(</span><span class="identifier">scenes_plugin</span><span class="plain">, </span><span class="identifier">PL::Scenes::ShowSceneStatus_routine</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="identifier">PL::Files::arrays</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Rulebooks::rulebook_var_creators</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Activities::activity_var_creators</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Relations::IterateRelations</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Phrases::Manager::RulebookNames_array</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Phrases::Manager::RulePrintingRule_routine</span><span class="plain">)</span>
<span class="identifier">BENCH_IF</span><span class="plain">(</span><span class="identifier">parsing_plugin</span><span class="plain">, </span><span class="identifier">PL::Parsing::Verbs::prepare</span><span class="plain">)</span>
<span class="identifier">BENCH_IF</span><span class="plain">(</span><span class="identifier">parsing_plugin</span><span class="plain">, </span><span class="identifier">PL::Parsing::Verbs::compile_conditions</span><span class="plain">)</span>
<span class="identifier">BENCH_IF</span><span class="plain">(</span><span class="identifier">parsing_plugin</span><span class="plain">, </span><span class="identifier">PL::Parsing::Tokens::Values::number</span><span class="plain">)</span>
<span class="identifier">BENCH_IF</span><span class="plain">(</span><span class="identifier">parsing_plugin</span><span class="plain">, </span><span class="identifier">PL::Parsing::Tokens::Values::truth_state</span><span class="plain">)</span>
<span class="identifier">BENCH_IF</span><span class="plain">(</span><span class="identifier">parsing_plugin</span><span class="plain">, </span><span class="identifier">PL::Parsing::Tokens::Values::time</span><span class="plain">)</span>
<span class="identifier">BENCH_IF</span><span class="plain">(</span><span class="identifier">parsing_plugin</span><span class="plain">, </span><span class="identifier">PL::Parsing::Tokens::Values::compile_type_gprs</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">NewVerbs::ConjugateVerb</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Adjectives::Meanings::agreements</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Lists::check</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Lists::check"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Lists::compile</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Lists::compile"</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Projects::Main_defined</span><span class="plain">(</span><span class="functiontext">Task::project</span><span class="plain">()) == </span><span class="identifier">FALSE</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Phrases::invoke_to_begin</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Phrases::invoke_to_begin"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Phrases::Manager::compile_as_needed</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Phrases::Manager::compile_as_needed"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Strings::compile_responses</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Strings::compile_responses"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Lists::check</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Lists::check"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Lists::compile</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Lists::compile"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Relations::compile_defined_relations</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Relations::compile_defined_relations"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Phrases::Manager::compile_as_needed</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Phrases::Manager::compile_as_needed"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Strings::TextSubstitutions::allow_no_further_text_subs</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Strings::TextSubstitutions::allow_no_further_text_subs"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP_IF</span><span class="plain">(</span><span class="identifier">parsing_plugin</span><span class="plain">, </span><span class="identifier">PL::Parsing::Tokens::Filters::compile</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"PL::Parsing::Tokens::Filters::compile"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP_IF</span><span class="plain">(</span><span class="identifier">actions_plugin</span><span class="plain">, </span><span class="functiontext">Chronology::past_actions_i6_routines</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Chronology::past_actions_i6_routines"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP_IF</span><span class="plain">(</span><span class="identifier">chronology_plugin</span><span class="plain">, </span><span class="functiontext">Chronology::chronology_extents_i6_escape</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Chronology::chronology_extents_i6_escape"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP_IF</span><span class="plain">(</span><span class="identifier">chronology_plugin</span><span class="plain">, </span><span class="functiontext">Chronology::past_tenses_i6_escape</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Chronology::past_tenses_i6_escape"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP_IF</span><span class="plain">(</span><span class="identifier">chronology_plugin</span><span class="plain">, </span><span class="functiontext">Chronology::allow_no_further_past_tenses</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Chronology::allow_no_further_past_tenses"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP_IF</span><span class="plain">(</span><span class="identifier">parsing_plugin</span><span class="plain">, </span><span class="identifier">PL::Parsing::Verbs::compile_all</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"PL::Parsing::Verbs::compile_all"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP_IF</span><span class="plain">(</span><span class="identifier">parsing_plugin</span><span class="plain">, </span><span class="identifier">PL::Parsing::Tokens::Filters::compile</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"PL::Parsing::Tokens::Filters::compile"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Properties::Measurement::compile_MADJ_routines</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Properties::Measurement::compile_MADJ_routines"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Calculus::Propositions::Deferred::compile_remaining_deferred</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Calculus::Propositions::Deferred::compile_remaining_deferred"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Calculus::Deferrals::allow_no_further_deferrals</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Calculus::Deferrals::allow_no_further_deferrals"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Lists::check</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Lists::check"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Lists::compile</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Lists::compile"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Strings::TextLiterals::compile</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Strings::TextLiterals::compile"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">JumpLabels::compile_necessary_storage</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"JumpLabels::compile_necessary_storage"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Kinds::RunTime::compile_heap_allocator</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Kinds::RunTime::compile_heap_allocator"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Phrases::Constants::compile_closures</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Phrases::Constants::compile_closures"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Kinds::RunTime::compile_structures</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Kinds::RunTime::compile_structures"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Rules::check_response_usages</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Rules::check_response_usages"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Phrases::Timed::check_for_unused</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Phrases::Timed::check_for_unused"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="identifier">PL::Showme::compile_SHOWME_details</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"PL::Showme::compile_SHOWME_details"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Phrases::Timed::TimedEventsTable</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Phrases::Timed::TimedEventsTable"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">Phrases::Timed::TimedEventTimesTable</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Phrases::Timed::TimedEventTimesTable"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="identifier">PL::Naming::compile_cap_short_name</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"PL::Naming::compile_cap_short_name"</span><span class="plain">)</span>
<span class="identifier">COMPILATION_STEP</span><span class="plain">(</span><span class="functiontext">UseOptions::configure_template</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"UseOptions::configure_template"</span><span class="plain">)</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP2_9"></a><b>&#167;2.9. </b>Metadata.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Generate index and bibliographic file</span> <span class="cwebmacronumber">2.9</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="functiontext">Task::advance_stage_to</span><span class="plain">(</span><span class="constant">BIBLIOGRAPHIC_CSEQ</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Plugins::Manage::plugged_in</span><span class="plain">(</span><span class="identifier">bibliographic_plugin</span><span class="plain">))</span>
<span class="identifier">PL::Bibliographic::Release::write_ifiction_and_blurb</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_count</span><span class="plain"> == 0)</span>
<span class="functiontext">NaturalLanguages::produce_index</span><span class="plain">();</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b></p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">no_log_phases</span><span class="plain"> = 0;</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Sequence::go_to_log_phase</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">argument</span><span class="plain">) {</span>
<span class="reserved">char</span><span class="plain"> *</span><span class="identifier">phase_names</span><span class="plain">[] = {</span>
<span class="string">"I"</span><span class="plain">, </span><span class="string">"II"</span><span class="plain">, </span><span class="string">"III"</span><span class="plain">, </span><span class="string">"IV"</span><span class="plain">, </span><span class="string">"V"</span><span class="plain">, </span><span class="string">"VI"</span><span class="plain">, </span><span class="string">"VII"</span><span class="plain">, </span><span class="string">"VIII"</span><span class="plain">, </span><span class="string">"IX"</span><span class="plain">, </span><span class="string">"X"</span><span class="plain">,</span>
<span class="string">"XI"</span><span class="plain">, </span><span class="string">"XII"</span><span class="plain">, </span><span class="string">"XIII"</span><span class="plain">, </span><span class="string">"XIV"</span><span class="plain">, </span><span class="string">"XV"</span><span class="plain">, </span><span class="string">"XVI"</span><span class="plain">, </span><span class="string">"XVII"</span><span class="plain">, </span><span class="string">"XVIII"</span><span class="plain">, </span><span class="string">"XIX"</span><span class="plain">, </span><span class="string">"XX"</span><span class="plain">, </span><span class="string">"XXI"</span><span class="plain">, </span><span class="string">"XXII"</span><span class="plain"> };</span>
<span class="identifier">Log::new_phase</span><span class="plain">(</span><span class="identifier">phase_names</span><span class="plain">[</span><span class="identifier">no_log_phases</span><span class="plain">], </span><span class="identifier">argument</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">no_log_phases</span><span class="plain"> &lt; 21) </span><span class="identifier">no_log_phases</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">debugging</span><span class="plain">) {</span>
<span class="identifier">BENCH_IF</span><span class="plain">(</span><span class="identifier">parsing_plugin</span><span class="plain">, </span><span class="functiontext">PL::Parsing::TestScripts::write_text</span><span class="plain">)</span>
<span class="identifier">BENCH_IF</span><span class="plain">(</span><span class="identifier">parsing_plugin</span><span class="plain">, </span><span class="functiontext">PL::Parsing::TestScripts::TestScriptSub_routine</span><span class="plain">)</span>
<span class="identifier">BENCH_IF</span><span class="plain">(</span><span class="identifier">parsing_plugin</span><span class="plain">, </span><span class="functiontext">PL::Parsing::TestScripts::InternalTestCases_routine</span><span class="plain">)</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">BENCH_IF</span><span class="plain">(</span><span class="identifier">parsing_plugin</span><span class="plain">, </span><span class="functiontext">PL::Parsing::TestScripts::TestScriptSub_stub_routine</span><span class="plain">)</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Lists::check</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Lists::compile</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Phrases::invoke_to_begin</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Phrases::Manager::compile_as_needed</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Strings::compile_responses</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Lists::check</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Lists::compile</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Relations::compile_defined_relations</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Phrases::Manager::compile_as_needed</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Strings::TextSubstitutions::allow_no_further_text_subs</span><span class="plain">)</span>
<span class="identifier">BENCH_IF</span><span class="plain">(</span><span class="identifier">parsing_plugin</span><span class="plain">, </span><span class="identifier">PL::Parsing::Tokens::Filters::compile</span><span class="plain">)</span>
<span class="identifier">BENCH_IF</span><span class="plain">(</span><span class="identifier">actions_plugin</span><span class="plain">, </span><span class="functiontext">Chronology::past_actions_i6_routines</span><span class="plain">)</span>
<span class="identifier">BENCH_IF</span><span class="plain">(</span><span class="identifier">chronology_plugin</span><span class="plain">, </span><span class="functiontext">Chronology::chronology_extents_i6_escape</span><span class="plain">)</span>
<span class="identifier">BENCH_IF</span><span class="plain">(</span><span class="identifier">chronology_plugin</span><span class="plain">, </span><span class="functiontext">Chronology::past_tenses_i6_escape</span><span class="plain">)</span>
<span class="identifier">BENCH_IF</span><span class="plain">(</span><span class="identifier">chronology_plugin</span><span class="plain">, </span><span class="functiontext">Chronology::allow_no_further_past_tenses</span><span class="plain">)</span>
<span class="identifier">BENCH_IF</span><span class="plain">(</span><span class="identifier">parsing_plugin</span><span class="plain">, </span><span class="identifier">PL::Parsing::Verbs::compile_all</span><span class="plain">)</span>
<span class="identifier">BENCH_IF</span><span class="plain">(</span><span class="identifier">parsing_plugin</span><span class="plain">, </span><span class="identifier">PL::Parsing::Tokens::Filters::compile</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Properties::Measurement::compile_MADJ_routines</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Calculus::Propositions::Deferred::compile_remaining_deferred</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Calculus::Deferrals::allow_no_further_deferrals</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Lists::check</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Lists::compile</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Strings::TextLiterals::compile</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">JumpLabels::compile_necessary_storage</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Kinds::RunTime::compile_heap_allocator</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Phrases::Constants::compile_closures</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Kinds::RunTime::compile_structures</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Rules::check_response_usages</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Phrases::Timed::check_for_unused</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="identifier">PL::Showme::compile_SHOWME_details</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Phrases::Timed::TimedEventsTable</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">Phrases::Timed::TimedEventTimesTable</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="identifier">PL::Naming::compile_cap_short_name</span><span class="plain">)</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">UseOptions::configure_template</span><span class="plain">)</span>
</pre>
<p class="endnote">The function Sequence::go_to_log_phase is used in <a href="#SP2_2">&#167;2.2</a>, <a href="#SP2_3">&#167;2.3</a>, <a href="#SP2_4">&#167;2.4</a>, <a href="#SP2_5">&#167;2.5</a>, <a href="#SP2_6">&#167;2.6</a>, <a href="#SP2_7">&#167;2.7</a>, <a href="#SP2_8">&#167;2.8</a>.</p>
<p class="inwebparagraph"></p>
<hr class="tocbar">
<ul class="toc"><li><a href="1-wtc.html">Back to 'What To Compile'</a></li><li><i>(This section ends Chapter 1: Configuration and Control.)</i></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>
<p class="endnote">This code is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP2_10"></a><b>&#167;2.10. </b><code class="display">
&lt;<span class="cwebmacrodefn">Generate index and bibliographic file</span> <span class="cwebmacronumber">2.10</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="functiontext">Task::advance_stage_to</span><span class="plain">(</span><span class="constant">BIBLIOGRAPHIC_CSEQ</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Bibliographic work"</span><span class="plain">, -1);</span>
<span class="identifier">BENCH_IF</span><span class="plain">(</span><span class="identifier">bibliographic_plugin</span><span class="plain">, </span><span class="identifier">PL::Bibliographic::Release::write_ifiction_and_blurb</span><span class="plain">);</span>
<span class="identifier">BENCH</span><span class="plain">(</span><span class="functiontext">NaturalLanguages::produce_index</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP2">&#167;2</a>.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="1-wtc.html">Back to 'What To Compile'</a></li><li><a href="1-pp.html">Continue with 'Progress Percentages'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>

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>Booklet Title</title>
<title>1/cm</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
@ -16,9 +16,7 @@
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. The Management. </b>All C programs begin execution in <code class="display"><span class="extract">main</span></code>, but the function below is not it.
This is because the compiler proper is a tiny wrapper around a collection of
modules, of which <code class="display"><span class="extract">core</span></code> is only one. <code class="display"><span class="extract">main</span></code> is found in that wrapper. On the
other hand, all it does is to start up the modules (making it safe to use
the memory manager, and so on) and then hand over the command line to
<code class="display"><span class="extract">CoreMain::main</span></code> below.
other hand, <code class="display"><span class="extract">main</span></code> simply starts up the modules and hands straight over to us.
</p>
<p class="inwebparagraph">So the <code class="display"><span class="extract">CoreMain::main</span></code> function certainly has the opportunity to be head
@ -148,11 +146,11 @@ it to go ahead and build that project.
</p>
<p class="inwebparagraph">But the art of leadership is delegation and what <code class="display"><span class="extract">inbuild</span></code> then does is to
call <code class="display"><span class="extract">core</span></code> back again: see the What To Compile section for the function it
calls. That sounds like an unnecessary round trip, but in fact it's not,
because <code class="display"><span class="extract">inbuild</span></code> also incrementally builds some of the resources we will
be using. That business is helpfully invisible to us: so it turns out that
CEOs do something, after all.
call <code class="display"><span class="extract">core</span></code> back again to do the actual work: see the What To Compile section.
That sounds like an unnecessary round trip, but in fact it's not, because
<code class="display"><span class="extract">inbuild</span></code> also incrementally builds some of the resources we will be using.
That business is helpfully invisible to us: so it turns out that CEOs do
something, after all.
</p>
@ -165,7 +163,7 @@ CEOs do something, after all.
<span class="identifier">inform_project</span><span class="plain"> *</span><span class="identifier">project</span><span class="plain"> = </span><span class="identifier">Inbuild::go_operational</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">project</span><span class="plain">)</span>
<span class="identifier">Copies::build</span><span class="plain">(</span><span class="identifier">STDOUT</span><span class="plain">, </span><span class="identifier">project</span><span class="plain">-&gt;</span><span class="identifier">as_copy</span><span class="plain">,</span>
<span class="identifier">BuildMethodology::new</span><span class="plain">(</span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="identifier">INTERNAL_METHODOLOGY</span><span class="plain">));</span>
<span class="identifier">BuildMethodology::stay_in_current_process</span><span class="plain">());</span>
</pre>
<p class="inwebparagraph"></p>
@ -215,15 +213,18 @@ gargantuan debugging logs if enabled.
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. Command line processing. </b>The bulk of the command-line options are both registered and processed by
<code class="display"><span class="extract">inbuild</span></code> rather than here: in particular, every switch ever used by the
Inform UI apps is really a command to <code class="display"><span class="extract">inbuild</span></code> not to <code class="display"><span class="extract">inform7</span></code>. What
remains here are just some eldritch options for testing the <code class="display"><span class="extract">inform7</span></code>
compiler via Delia scripts in <code class="display"><span class="extract">intest</span></code>.
Inform UI apps is really a command to <code class="display"><span class="extract">inbuild</span></code> not to <code class="display"><span class="extract">inform7</span></code>.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">CoreMain::read_command_line</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">argc</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">argv</span><span class="plain">[]) {</span>
<span class="identifier">CommandLine::declare_heading</span><span class="plain">(</span>
<span class="identifier">L</span><span class="string">"inform7: a compiler from source text to Inter code\</span><span class="plain">n</span><span class="string">\</span><span class="plain">n</span><span class="string">"</span>
<span class="identifier">L</span><span class="string">"Usage: inform7 [OPTIONS]\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Register command-line arguments</span> <span class="cwebmacronumber">2.2</span>&gt;<span class="plain">;</span>
<span class="identifier">Inbuild::declare_options</span><span class="plain">();</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">proceed</span><span class="plain"> = </span><span class="identifier">CommandLine::read</span><span class="plain">(</span><span class="identifier">argc</span><span class="plain">, </span><span class="identifier">argv</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, &amp;</span><span class="functiontext">CoreMain::switch</span><span class="plain">, &amp;</span><span class="functiontext">CoreMain::bareword</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">proceed</span><span class="plain">) {</span>
<span class="identifier">path_to_inform7</span><span class="plain"> = </span><span class="identifier">Pathnames::installation_path</span><span class="plain">(</span><span class="string">"INFORM7_PATH"</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"inform7"</span><span class="plain">);</span>
@ -237,9 +238,8 @@ compiler via Delia scripts in <code class="display"><span class="extract">intest
<p class="endnote">The function CoreMain::read_command_line is used in <a href="#SP1">&#167;1</a>.</p>
<p class="inwebparagraph"><a id="SP2_1"></a><b>&#167;2.1. </b>Note that the locations manager is also allowed to process command-line
arguments in order to set certain pathnames or filenames, so the following
list is not exhaustive.
<p class="inwebparagraph"><a id="SP2_1"></a><b>&#167;2.1. </b>What remains here are just some eldritch options for testing the <code class="display"><span class="extract">inform7</span></code>
compiler via Delia scripts in <code class="display"><span class="extract">intest</span></code>.
</p>
@ -257,10 +257,6 @@ list is not exhaustive.
<pre class="displaydefn">
<span class="identifier">CommandLine::declare_heading</span><span class="plain">(</span>
<span class="identifier">L</span><span class="string">"inform7: a compiler from source text to Inform 6 code\</span><span class="plain">n</span><span class="string">\</span><span class="plain">n</span><span class="string">"</span>
<span class="identifier">L</span><span class="string">"Usage: inform7 [OPTIONS] [SOURCETEXT]\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
<span class="identifier">CommandLine::begin_group</span><span class="plain">(</span><span class="constant">INFORM_TESTING_CLSG</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"for testing and debugging inform7"</span><span class="plain">);</span>
<span class="identifier">CommandLine::declare_boolean_switch</span><span class="plain">(</span><span class="constant">CRASHALL_CLSW</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"crash-all"</span><span class="plain">, 1,</span>
<span class="identifier">L</span><span class="string">"intentionally crash on Problem messages, for debugger backtracing"</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
@ -273,14 +269,15 @@ list is not exhaustive.
<span class="identifier">CommandLine::declare_switch</span><span class="plain">(</span><span class="constant">REQUIRE_PROBLEM_CLSW</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"require-problem"</span><span class="plain">, 2,</span>
<span class="identifier">L</span><span class="string">"return 0 unless exactly this Problem message is generated"</span><span class="plain">);</span>
<span class="identifier">CommandLine::end_group</span><span class="plain">();</span>
<span class="identifier">Inbuild::declare_options</span><span class="plain">();</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b></p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>Three of the five options here actually configure the <code class="display"><span class="extract">problems</span></code> module
rather than <code class="display"><span class="extract">core</span></code>.
</p>
<pre class="display">
@ -311,7 +308,7 @@ list is not exhaustive.
<p class="endnote">The function CoreMain::bareword is used in <a href="#SP2">&#167;2</a>.</p>
<hr class="tocbar">
<ul class="toc"><li><i>(This section begins Chapter 1: Configuration and Control.)</i></li><li><a href="1-cm.html">Continue with 'Core Module'</a></li></ul><hr class="tocbar">
<ul class="toc"><li><a href="1-cm.html">Back to 'Core Module'</a></li><li><a href="1-wtc.html">Continue with 'What To Compile'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>

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>1/cm</title>
<title>1/htc</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
@ -9,7 +9,7 @@
<body>
<!--Weave of '1/pp' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">core</a></li><li><a href="index.html#1">Chapter 1: Configuration and Control</a></li><li><b>Progress Percentages</b></li></ul><p class="purpose">This tiny section, the Lichtenstein of Inform, prints percentage of completion estimates onto |stderr| so that the host application can intercept them and update its graphical progress bar.</p>
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">core</a></li><li><a href="index.html#1">Chapter 1: Configuration and Control</a></li><li><b>Progress Percentages</b></li></ul><p class="purpose">This tiny section, the Lichtenstein of Inform, prints percentage of completion estimates so that the host application can intercept them and update its graphical progress bar.</p>
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. </b>Clearly we can only estimate how far Inform has progressed. While we could in
principle measure the number of CPU-seconds it has run for, we don't know
@ -44,7 +44,7 @@ progress bar with a rubric beneath it.
<span class="string">"Generating code"</span>
<span class="plain">};</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">ProgressBar::update_progress_bar</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">stage</span><span class="plain">, </span><span class="reserved">float</span><span class="plain"> </span><span class="identifier">proportion</span><span class="plain">) {</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">ProgressBar::update</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">stage</span><span class="plain">, </span><span class="reserved">float</span><span class="plain"> </span><span class="identifier">proportion</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">r1</span><span class="plain"> = </span><span class="identifier">progress_stage_from</span><span class="plain">[</span><span class="identifier">stage</span><span class="plain">], </span><span class="identifier">r2</span><span class="plain"> = </span><span class="identifier">progress_stage_from</span><span class="plain">[</span><span class="identifier">stage</span><span class="plain">+1];</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">pc</span><span class="plain"> = </span><span class="identifier">r1</span><span class="plain"> + ((</span><span class="reserved">int</span><span class="plain">) (</span><span class="identifier">proportion</span><span class="plain">*(</span><span class="identifier">r2</span><span class="plain">-</span><span class="identifier">r1</span><span class="plain">)));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">show_progress_indicator</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
@ -64,7 +64,7 @@ progress bar with a rubric beneath it.
<p class="inwebparagraph"></p>
<p class="endnote">The function ProgressBar::update_progress_bar is used in 1/htc (<a href="1-htc.html#SP2_2">&#167;2.2</a>, <a href="1-htc.html#SP2_3">&#167;2.3</a>, <a href="1-htc.html#SP2_4">&#167;2.4</a>, <a href="1-htc.html#SP2_7">&#167;2.7</a>, <a href="1-htc.html#SP2_8">&#167;2.8</a>), 22/cs (<a href="22-cs.html#SP4">&#167;4</a>), 22/ph (<a href="22-ph.html#SP12_1">&#167;12.1</a>).</p>
<p class="endnote">The function ProgressBar::update is used in 1/wtc (<a href="1-wtc.html#SP3">&#167;3</a>), 22/cs (<a href="22-cs.html#SP4">&#167;4</a>), 22/ph (<a href="22-ph.html#SP12_1">&#167;12.1</a>).</p>
<p class="endnote">The function ProgressBar::final_state_of_progress_bar is used in 2/up (<a href="2-up.html#SP2_3">&#167;2.3</a>).</p>
@ -94,7 +94,7 @@ a final status indicator.
<p class="endnote">The function ProgressBar::end_outcome is used in 2/up (<a href="2-up.html#SP2_2">&#167;2.2</a>, <a href="2-up.html#SP2_3">&#167;2.3</a>).</p>
<hr class="tocbar">
<ul class="toc"><li><a href="1-cm.html">Back to 'Core Module'</a></li><li><a href="1-wtc.html">Continue with 'What To Compile'</a></li></ul><hr class="tocbar">
<ul class="toc"><li><a href="1-htc.html">Back to 'How To Compile'</a></li><li><i>(This section ends Chapter 1: Configuration and Control.)</i></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>

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>1/pp</title>
<title>1/mr</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
@ -11,7 +11,7 @@
<!--Weave of '1/wtc' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">core</a></li><li><a href="index.html#1">Chapter 1: Configuration and Control</a></li><li><b>What To Compile</b></li></ul><p class="purpose">To receive an instruction to compile something from Inbuild, and then to sort out the many locations then used in the host filing system.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Task data</a></li><li><a href="#SP7">&#167;7. Project-related files and file paths</a></li></ul><hr class="tocbar">
<ul class="toc"><li><a href="#SP1">&#167;1. Task data</a></li><li><a href="#SP8">&#167;8. Project-related files and file paths</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Task data. </b>When Inbuild (a copy of which is included in the Inform 7 executable) decides
that an Inform source text must be compiled, it calls <code class="display"><span class="extract">Task::carry_out</span></code>. By
@ -81,7 +81,7 @@ thing which is being compiled when it is.
<span class="identifier">Projects::set_language_of_index</span><span class="plain">(</span><span class="identifier">project</span><span class="plain">, </span><span class="identifier">E</span><span class="plain">);</span>
<span class="identifier">Projects::set_language_of_play</span><span class="plain">(</span><span class="identifier">project</span><span class="plain">, </span><span class="identifier">E</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain"> = </span><span class="functiontext">Sequence::carry_out</span><span class="plain">(</span><span class="identifier">inform7_task</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain"> = </span><span class="functiontext">Sequence::carry_out</span><span class="plain">(</span><span class="identifier">TargetVMs::debug_enabled</span><span class="plain">(</span><span class="identifier">inform7_task</span><span class="plain">-</span><span class="element">&gt;task</span><span class="plain">-&gt;</span><span class="identifier">for_vm</span><span class="plain">));</span>
<span class="identifier">inform7_task</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">rv</span><span class="plain">;</span>
<span class="plain">}</span>
@ -92,14 +92,22 @@ thing which is being compiled when it is.
<p class="endnote">The function Task::carry_out appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>We will keep track of how far along the process has advanced, in very
rough terms.
rough stages. Twenty is plenty.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Task::advance_stage_to</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">stage</span><span class="plain">) {</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Task::advance_stage_to</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">stage</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">int</span><span class="plain"> </span><span class="identifier">X</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">inform7_task</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">"there is no current task"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">stage</span><span class="plain"> &lt;= </span><span class="identifier">inform7_task</span><span class="plain">-</span><span class="element">&gt;stage_of_compilation</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"not an advance"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">stage</span><span class="plain"> &gt;= 20) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"went too far"</span><span class="plain">);</span>
<span class="reserved">char</span><span class="plain"> *</span><span class="identifier">roman</span><span class="plain">[] = {</span>
<span class="string">"I"</span><span class="plain">, </span><span class="string">"II"</span><span class="plain">, </span><span class="string">"III"</span><span class="plain">, </span><span class="string">"IV"</span><span class="plain">, </span><span class="string">"V"</span><span class="plain">, </span><span class="string">"VI"</span><span class="plain">, </span><span class="string">"VII"</span><span class="plain">, </span><span class="string">"VIII"</span><span class="plain">, </span><span class="string">"IX"</span><span class="plain">, </span><span class="string">"X"</span><span class="plain">,</span>
<span class="string">"XI"</span><span class="plain">, </span><span class="string">"XII"</span><span class="plain">, </span><span class="string">"XIII"</span><span class="plain">, </span><span class="string">"XIV"</span><span class="plain">, </span><span class="string">"XV"</span><span class="plain">, </span><span class="string">"XVI"</span><span class="plain">, </span><span class="string">"XVII"</span><span class="plain">, </span><span class="string">"XVIII"</span><span class="plain">, </span><span class="string">"XIX"</span><span class="plain">, </span><span class="string">"XX"</span><span class="plain"> };</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_count</span><span class="plain"> == 0) {</span>
<span class="identifier">Log::new_phase</span><span class="plain">(</span><span class="identifier">roman</span><span class="plain">[</span><span class="identifier">stage</span><span class="plain">], </span><span class="identifier">name</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">X</span><span class="plain"> &gt;= 0) </span><span class="functiontext">ProgressBar::update</span><span class="plain">(</span><span class="identifier">X</span><span class="plain">, 0);</span>
<span class="plain">}</span>
<span class="identifier">inform7_task</span><span class="plain">-</span><span class="element">&gt;stage_of_compilation</span><span class="plain"> = </span><span class="identifier">stage</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Task::is_before_stage</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">stage</span><span class="plain">) {</span>
@ -121,7 +129,7 @@ rough terms.
<p class="inwebparagraph"></p>
<p class="endnote">The function Task::advance_stage_to is used in 1/htc (<a href="1-htc.html#SP2">&#167;2</a>, <a href="1-htc.html#SP2_2">&#167;2.2</a>, <a href="1-htc.html#SP2_3">&#167;2.3</a>, <a href="1-htc.html#SP2_4">&#167;2.4</a>, <a href="1-htc.html#SP2_5">&#167;2.5</a>, <a href="1-htc.html#SP2_6">&#167;2.6</a>, <a href="1-htc.html#SP2_7">&#167;2.7</a>, <a href="1-htc.html#SP2_8">&#167;2.8</a>, <a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="endnote">The function Task::advance_stage_to is used in 1/htc (<a href="1-htc.html#SP2">&#167;2</a>, <a href="1-htc.html#SP2_3">&#167;2.3</a>, <a href="1-htc.html#SP2_4">&#167;2.4</a>, <a href="1-htc.html#SP2_5">&#167;2.5</a>, <a href="1-htc.html#SP2_6">&#167;2.6</a>, <a href="1-htc.html#SP2_7">&#167;2.7</a>, <a href="1-htc.html#SP2_8">&#167;2.8</a>, <a href="1-htc.html#SP2_9">&#167;2.9</a>, <a href="1-htc.html#SP2_10">&#167;2.10</a>).</p>
<p class="endnote">The function Task::is_before_stage appears nowhere else.</p>
@ -147,9 +155,9 @@ rough terms.
<p class="inwebparagraph"></p>
<p class="endnote">The function Task::project is used in 1/htc (<a href="1-htc.html#SP2_2">&#167;2.2</a>, <a href="1-htc.html#SP2_3">&#167;2.3</a>, <a href="1-htc.html#SP2_8">&#167;2.8</a>), 3/nl (<a href="3-nl.html#SP3">&#167;3</a>), 4/its (<a href="4-its.html#SP7">&#167;7</a>), 4/am (<a href="4-am.html#SP42">&#167;42</a>, <a href="4-am.html#SP43">&#167;43</a>), 5/ins (<a href="5-ins.html#SP14">&#167;14</a>, <a href="5-ins.html#SP25">&#167;25</a>, <a href="5-ins.html#SP26">&#167;26</a>), 5/ipw (<a href="5-ipw.html#SP3_3_1">&#167;3.3.1</a>, <a href="5-ipw.html#SP3_3_1_1">&#167;3.3.1.1</a>), 6/nv (<a href="6-nv.html#SP22">&#167;22</a>), 26/ts (<a href="26-ts.html#SP11">&#167;11</a>).</p>
<p class="endnote">The function Task::project is used in 3/nl (<a href="3-nl.html#SP3">&#167;3</a>), 4/its (<a href="4-its.html#SP7">&#167;7</a>), 4/am (<a href="4-am.html#SP42">&#167;42</a>, <a href="4-am.html#SP43">&#167;43</a>), 5/ins (<a href="5-ins.html#SP14">&#167;14</a>, <a href="5-ins.html#SP25">&#167;25</a>, <a href="5-ins.html#SP26">&#167;26</a>), 5/ipw (<a href="5-ipw.html#SP3_3_1">&#167;3.3.1</a>, <a href="5-ipw.html#SP3_3_1_1">&#167;3.3.1.1</a>), 6/nv (<a href="6-nv.html#SP22">&#167;22</a>), 26/ts (<a href="26-ts.html#SP11">&#167;11</a>).</p>
<p class="endnote">The function Task::vm is used in <a href="#SP14">&#167;14</a>, 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>), 5/lp (<a href="5-lp.html#SP12_2">&#167;12.2</a>, <a href="5-lp.html#SP18_3">&#167;18.3</a>), 6/rlt (<a href="6-rlt.html#SP14">&#167;14</a>), 7/hdn (<a href="7-hdn.html#SP12">&#167;12</a>), 8/ie (<a href="8-ie.html#SP9_1">&#167;9.1</a>), 13/rsfk (<a href="13-rsfk.html#SP18_1">&#167;18.1</a>, <a href="13-rsfk.html#SP20">&#167;20</a>, <a href="13-rsfk.html#SP26">&#167;26</a>), 17/ts (<a href="17-ts.html#SP11_1">&#167;11.1</a>), 25/cii (<a href="25-cii.html#SP3_5_8_3">&#167;3.5.8.3</a>), 26/fc (<a href="26-fc.html#SP3">&#167;3</a>), 26/uo (<a href="26-uo.html#SP18">&#167;18</a>), 26/rt (<a href="26-rt.html#SP4">&#167;4</a>), 27/ei (<a href="27-ei.html#SP2">&#167;2</a>).</p>
<p class="endnote">The function Task::vm is used in <a href="#SP15">&#167;15</a>, 5/lp (<a href="5-lp.html#SP12_2">&#167;12.2</a>, <a href="5-lp.html#SP18_3">&#167;18.3</a>), 6/rlt (<a href="6-rlt.html#SP14">&#167;14</a>), 7/hdn (<a href="7-hdn.html#SP12">&#167;12</a>), 8/ie (<a href="8-ie.html#SP9_1">&#167;9.1</a>), 13/rsfk (<a href="13-rsfk.html#SP18_1">&#167;18.1</a>, <a href="13-rsfk.html#SP20">&#167;20</a>, <a href="13-rsfk.html#SP26">&#167;26</a>), 17/ts (<a href="17-ts.html#SP11_1">&#167;11.1</a>), 25/cii (<a href="25-cii.html#SP3_5_8_3">&#167;3.5.8.3</a>), 26/fc (<a href="26-fc.html#SP3">&#167;3</a>), 26/uo (<a href="26-uo.html#SP18">&#167;18</a>), 26/rt (<a href="26-rt.html#SP4">&#167;4</a>), 27/ei (<a href="27-ei.html#SP2">&#167;2</a>).</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b>Resources in a Blorb file have unique ID numbers which are positive integers,
but these are not required to start from 1, nor to be contiguous. For Inform,
@ -191,7 +199,45 @@ a non-zero value to make testing Inform easier.
<p class="endnote">The function Task::rng_seed is used in 9/ma (<a href="9-ma.html#SP3_3_41_2_2_1">&#167;3.3.41.2.2.1</a>), 13/rsfk (<a href="13-rsfk.html#SP24">&#167;24</a>).</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. Project-related files and file paths. </b>An Inform compilation can touch dozens of different files, and the rest
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. </b>These four functions are for steps on the production line which involve
referring something back up to Inbuild.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Task::read_source_text</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">inform7_task</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">"there is no current task"</span><span class="plain">);</span>
<span class="functiontext">SourceFiles::read</span><span class="plain">(</span><span class="identifier">inform7_task</span><span class="plain">-</span><span class="element">&gt;project</span><span class="plain">-&gt;</span><span class="identifier">as_copy</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Task::activate_language_elements</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">inform7_task</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">"there is no current task"</span><span class="plain">);</span>
<span class="identifier">Projects::activate_plugins</span><span class="plain">(</span><span class="identifier">inform7_task</span><span class="plain">-</span><span class="element">&gt;project</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Task::load_types</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">inform7_task</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">"there is no current task"</span><span class="plain">);</span>
<span class="identifier">Projects::load_types</span><span class="plain">(</span><span class="identifier">inform7_task</span><span class="plain">-</span><span class="element">&gt;project</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Task::begin_execution_at_to_begin</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">inform7_task</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">"there is no current task"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Projects::Main_defined</span><span class="plain">(</span><span class="identifier">inform7_task</span><span class="plain">-</span><span class="element">&gt;project</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">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Task::read_source_text is used in 1/htc (<a href="1-htc.html#SP2_3">&#167;2.3</a>).</p>
<p class="endnote">The function Task::activate_language_elements is used in 1/htc (<a href="1-htc.html#SP2_4">&#167;2.4</a>).</p>
<p class="endnote">The function Task::load_types is used in 1/htc (<a href="1-htc.html#SP2_4">&#167;2.4</a>).</p>
<p class="endnote">The function Task::begin_execution_at_to_begin is used in 22/ph (<a href="22-ph.html#SP13">&#167;13</a>).</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. Project-related files and file paths. </b>An Inform compilation can touch dozens of different files, and the rest
of this section is a tour through the ones which are associated with the
project itself. (Common resources, used for all compilations, or optional
add-ins such as extensions are the business of Inbuild.)
@ -261,7 +307,7 @@ the command line), but they take no time to generate so we make them anyway.
<p class="endnote">The function Task::blurb_file appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. </b>The build folder for a project contains all of the working files created
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. </b>The build folder for a project contains all of the working files created
during the compilation process. The debugging log and Inform problems report
(its HTML file of error messages) are both written there: see the Main Routine
section for details. In addition we have:
@ -285,7 +331,7 @@ section for details. In addition we have:
<p class="endnote">The function Task::parse_tree_file is used in 7/ptu (<a href="7-ptu.html#SP18">&#167;18</a>).</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. </b>The name of the unblorbed story file is chosen for us by Inbuild, so
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. </b>The name of the unblorbed story file is chosen for us by Inbuild, so
we have to extract it from the build graph:
</p>
@ -303,7 +349,7 @@ we have to extract it from the build graph:
<p class="endnote">The function Task::storyfile_file appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. </b>Deeper inside the<code class="display"><span class="extract">Build</span></code> subfolder is an (also ephemeral) <code class="display"><span class="extract">Index</span></code> subfolder,
<p class="inwebparagraph"><a id="SP11"></a><b>&#167;11. </b>Deeper inside the<code class="display"><span class="extract">Build</span></code> subfolder is an (also ephemeral) <code class="display"><span class="extract">Index</span></code> subfolder,
which holds the mini-website of the Index for a project.
</p>
@ -323,9 +369,9 @@ details on actions live in the subfolder <code class="display"><span class="extr
<p class="inwebparagraph"></p>
<p class="endnote">The function Task::index_path is used in <a href="#SP11">&#167;11</a>, <a href="#SP12">&#167;12</a>, <a href="#SP13">&#167;13</a>.</p>
<p class="endnote">The function Task::index_path is used in <a href="#SP12">&#167;12</a>, <a href="#SP13">&#167;13</a>, <a href="#SP14">&#167;14</a>.</p>
<p class="inwebparagraph"><a id="SP11"></a><b>&#167;11. </b>An oddity in the Index folder is an XML file recording where the headings
<p class="inwebparagraph"><a id="SP12"></a><b>&#167;12. </b>An oddity in the Index folder is an XML file recording where the headings
are in the source text: this is for the benefit of the user interface
application, if it wants it, but is not linked to or used by the HTML of
the index as seen by the user.
@ -342,7 +388,7 @@ the index as seen by the user.
<p class="endnote">The function Task::xml_headings_file is used in 7/hdn (<a href="7-hdn.html#SP35">&#167;35</a>).</p>
<p class="inwebparagraph"><a id="SP12"></a><b>&#167;12. </b>Within the Index is a deeper level, into the weeds as it were, called
<p class="inwebparagraph"><a id="SP13"></a><b>&#167;13. </b>Within the Index is a deeper level, into the weeds as it were, called
<code class="display"><span class="extract">Details</span></code>.
</p>
@ -357,9 +403,9 @@ the index as seen by the user.
<p class="inwebparagraph"></p>
<p class="endnote">The function Task::index_details_path is used in <a href="#SP13">&#167;13</a>.</p>
<p class="endnote">The function Task::index_details_path is used in <a href="#SP14">&#167;14</a>.</p>
<p class="inwebparagraph"><a id="SP13"></a><b>&#167;13. </b>And the following routine determines the filename for a page in this
<p class="inwebparagraph"><a id="SP14"></a><b>&#167;14. </b>And the following routine determines the filename for a page in this
mini-website. Filenames down in the <code class="display"><span class="extract">Details</span></code> area have the form
<code class="display"><span class="extract">N_S</span></code> where <code class="display"><span class="extract">N</span></code> is an integer supplied and <code class="display"><span class="extract">S</span></code> the leafname; for instance,
<code class="display"><span class="extract">21_A.html</span></code> provides details page number 21 about actions, derived from the
@ -385,7 +431,7 @@ leafname <code class="display"><span class="extract">A.html</span></code>.
<p class="endnote">The function Task::index_file appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP14"></a><b>&#167;14. </b>That's it for the project folder, but other project-related stuff is in
<p class="inwebparagraph"><a id="SP15"></a><b>&#167;15. </b>That's it for the project folder, but other project-related stuff is in
the materials folder, which we turn to next.
</p>
@ -433,7 +479,7 @@ level of materuals.
<p class="endnote">The function Task::existing_storyfile_file appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP15"></a><b>&#167;15. </b>Materials is also where cover art lives: it could have either the file
<p class="inwebparagraph"><a id="SP16"></a><b>&#167;16. </b>Materials is also where cover art lives: it could have either the file
extension <code class="display"><span class="extract">.jpg</span></code> or <code class="display"><span class="extract">.png</span></code>, and we generate both sets of filenames, even
though at most one will actually work. This is also where we generate the EPS
file of the map, if so requested; a bit anomalously, it's the only file in
@ -476,7 +522,7 @@ and Sounds, if any, live: in their own subfolders.
<p class="endnote">The function Task::sounds_path appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP16"></a><b>&#167;16. </b>On a release run, Inblorb will populate the Release subfolder of Materials;
<p class="inwebparagraph"><a id="SP17"></a><b>&#167;17. </b>On a release run, Inblorb will populate the Release subfolder of Materials;
figures and sounds will be copied into the relevant subfolders. The principle
is that everything in Release can always be thrown away without loss, because
it can all be generated again.
@ -510,7 +556,7 @@ it can all be generated again.
<p class="endnote">The function Task::released_interpreter_path appears nowhere else.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="1-pp.html">Back to 'Progress Percentages'</a></li><li><a href="1-htc.html">Continue with 'How To Compile'</a></li></ul><hr class="tocbar">
<ul class="toc"><li><a href="1-mr.html">Back to 'Main Routine'</a></li><li><a href="1-htc.html">Continue with 'How To Compile'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>

View file

@ -79,7 +79,7 @@ which create routines which... and so on.
<p class="inwebparagraph"></p>
<p class="endnote">The function Calculus::Propositions::Deferred::compile_remaining_deferred is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Calculus::Propositions::Deferred::compile_remaining_deferred is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="endnote">The function Calculus::Propositions::Deferred::compilation_coroutine is used in 22/cs (<a href="22-cs.html#SP14">&#167;14</a>).</p>

View file

@ -68,7 +68,7 @@ all deferral requests are redeemed &mdash; they would then never be reached.
<p class="inwebparagraph"></p>
<p class="endnote">The function Calculus::Deferrals::allow_no_further_deferrals is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Calculus::Deferrals::allow_no_further_deferrals is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. Deferral requests. </b>The following fills out the paperwork to request a deferred proposition.
</p>

View file

@ -855,7 +855,7 @@ K, we have also seen its bases.
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::RunTime::compile_structures is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Kinds::RunTime::compile_structures is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="inwebparagraph"><a id="SP16_1"></a><b>&#167;16.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Compile the runtime ID structure for this kind</span> <span class="cwebmacronumber">16.1</span>&gt; =
@ -1057,7 +1057,7 @@ property values, table entries, list items) of pointer-value kinds:
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::RunTime::compile_heap_allocator is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Kinds::RunTime::compile_heap_allocator is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="inwebparagraph"><a id="SP18_1"></a><b>&#167;18.1. </b>By now, we know that we need at least <code class="display"><span class="extract">total_heap_allocation</span></code> bytes on the
heap, but the initial heap size has to be a power of 2, so we compute the
@ -1528,13 +1528,13 @@ each such kind, and needed at run-time.
<p class="endnote">The function Kinds::RunTime::emit appears nowhere else.</p>
<p class="endnote">The function Kinds::RunTime::kind_declarations is used in 1/htc (<a href="1-htc.html#SP2_4">&#167;2.4</a>).</p>
<p class="endnote">The function Kinds::RunTime::kind_declarations is used in 1/htc (<a href="1-htc.html#SP2_5">&#167;2.5</a>).</p>
<p class="endnote">The function Kinds::RunTime::compile_nnci is used in <a href="#SP18_1">&#167;18.1</a>.</p>
<p class="endnote">The function Kinds::RunTime::compile_instance_counts is used in 1/htc (<a href="1-htc.html#SP2_7">&#167;2.7</a>).</p>
<p class="endnote">The function Kinds::RunTime::compile_instance_counts is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Kinds::RunTime::compile_data_type_support_routines is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Kinds::RunTime::compile_data_type_support_routines is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="inwebparagraph"><a id="SP24_1"></a><b>&#167;24.1. </b>A slightly bogus case first. If the source text declares a kind but never
gives any enumerated values or literal patterns, then such values will never
@ -2409,7 +2409,7 @@ Z-machine array space.
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::RunTime::I7_Kind_Name_routine is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Kinds::RunTime::I7_Kind_Name_routine is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="inwebparagraph"><a id="SP26"></a><b>&#167;26. </b></p>

View file

@ -291,7 +291,7 @@ For now, though, we make a parallel decision here.
<p class="inwebparagraph"></p>
<p class="endnote">The function Properties::Emit::allocate_attributes is used in 1/htc (<a href="1-htc.html#SP2_5">&#167;2.5</a>).</p>
<p class="endnote">The function Properties::Emit::allocate_attributes is used in 1/htc (<a href="1-htc.html#SP2_6">&#167;2.6</a>).</p>
<p class="inwebparagraph"><a id="SP3_1"></a><b>&#167;3.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Any either/or property which some value can hold is ineligible</span> <span class="cwebmacronumber">3.1</span>&gt; =

View file

@ -183,7 +183,7 @@ definition structure stands incomplete for a while. Filling it in is called
<p class="inwebparagraph"></p>
<p class="endnote">The function Properties::Measurement::validate_definitions is used in 1/htc (<a href="1-htc.html#SP2_6">&#167;2.6</a>).</p>
<p class="endnote">The function Properties::Measurement::validate_definitions is used in 1/htc (<a href="1-htc.html#SP2_7">&#167;2.7</a>).</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. </b>Where:
</p>
@ -661,7 +661,7 @@ can't normally be unravelled at compile time.
<p class="inwebparagraph"></p>
<p class="endnote">The function Properties::Measurement::compile_MADJ_routines is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Properties::Measurement::compile_MADJ_routines is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="inwebparagraph"><a id="SP14"></a><b>&#167;14. Comparative forms. </b>For timing reasons, these are made all at once, and later than when the headword
adjectives and superlatives are made.

View file

@ -1084,11 +1084,11 @@ we find it, we compile it and return <code class="display"><span class="extract"
<p class="endnote">The function Properties::emit_single is used in 27/ei (<a href="27-ei.html#SP3">&#167;3</a>).</p>
<p class="endnote">The function Properties::emit is used in 1/htc (<a href="1-htc.html#SP2_5">&#167;2.5</a>).</p>
<p class="endnote">The function Properties::emit is used in 1/htc (<a href="1-htc.html#SP2_6">&#167;2.6</a>).</p>
<p class="endnote">The function Properties::emit_default_values appears nowhere else.</p>
<p class="endnote">The function Properties::annotate_attributes is used in 1/htc (<a href="1-htc.html#SP2_7">&#167;2.7</a>).</p>
<p class="endnote">The function Properties::annotate_attributes is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Properties::emit_instance_permissions is used in 5/ins (<a href="5-ins.html#SP34">&#167;34</a>).</p>

View file

@ -64,7 +64,7 @@ aren't allowed to add I7-accessible properties.)
<p class="inwebparagraph"></p>
<p class="endnote">The function World::complete is used in 1/htc (<a href="1-htc.html#SP2_5">&#167;2.5</a>).</p>
<p class="endnote">The function World::complete is used in 1/htc (<a href="1-htc.html#SP2_6">&#167;2.6</a>).</p>
<p class="inwebparagraph"><a id="SP1_1"></a><b>&#167;1.1. </b>The model world is a broth with many cooks. On the one hand, we have the
various different INFSs, with their different needs &mdash; a various-to-various
@ -304,7 +304,7 @@ about the Portal, to stand.
<p class="inwebparagraph"></p>
<p class="endnote">The function World::complete_additions is used in 1/htc (<a href="1-htc.html#SP2_6">&#167;2.6</a>).</p>
<p class="endnote">The function World::complete_additions is used in 1/htc (<a href="1-htc.html#SP2_7">&#167;2.7</a>).</p>
<hr class="tocbar">
<ul class="toc"><li><a href="16-in.html">Back to 'Inferences'</a></li><li><a href="16-cmw2.html">Continue with 'Compile Model World'</a></li></ul><hr class="tocbar">

View file

@ -60,7 +60,7 @@ to write anything, then put the same question to the subjects.
<p class="inwebparagraph"></p>
<p class="endnote">The function World::Compile::compile is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function World::Compile::compile is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<hr class="tocbar">
<ul class="toc"><li><a href="16-cmw.html">Back to 'Complete Model World'</a></li><li><a href="16-ic.html">Continue with 'Instance Counting'</a></li></ul><hr class="tocbar">

View file

@ -186,7 +186,7 @@ following.
<p class="inwebparagraph"></p>
<p class="endnote">The function InferenceSubjects::begin is used in 1/htc (<a href="1-htc.html#SP2_1">&#167;2.1</a>).</p>
<p class="endnote">The function InferenceSubjects::begin is used in 1/htc (<a href="1-htc.html#SP2_2">&#167;2.2</a>).</p>
<p class="endnote">The function InferenceSubjects::new_fundamental appears nowhere else.</p>

View file

@ -398,7 +398,7 @@ track of the content of each response.
<p class="inwebparagraph"></p>
<p class="endnote">The function Strings::compile_responses is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Strings::compile_responses is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="inwebparagraph"><a id="SP7_1"></a><b>&#167;7.1. </b>Note that each rule is allowed to tell us that it already has a better
text for the response than the one we first created.

View file

@ -437,7 +437,7 @@ number <code class="display"><span class="extract">-1</span></code>).
<p class="inwebparagraph"></p>
<p class="endnote">The function Strings::TextLiterals::compile is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Strings::TextLiterals::compile is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="endnote">The function Strings::TextLiterals::traverse_lts appears nowhere else.</p>

View file

@ -162,7 +162,7 @@ to do but panic.
<p class="inwebparagraph"></p>
<p class="endnote">The function Strings::TextSubstitutions::allow_no_further_text_subs is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Strings::TextSubstitutions::allow_no_further_text_subs is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. </b>For some years these were compiled to routines verbosely called
<code class="display"><span class="extract">text_routine_1</span></code> and so on, but no longer:

View file

@ -378,7 +378,7 @@ problem messages out into the open &mdash;
<p class="inwebparagraph"></p>
<p class="endnote">The function Lists::check is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Lists::check is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="inwebparagraph"><a id="SP11"></a><b>&#167;11. </b>That leaves just the compilation of lists at run-time. This used to be a
complex dance with initialisation code interleaved with heap construction,
@ -439,7 +439,7 @@ so there was once a two-page explanation here, but it is now blessedly simple.
<p class="inwebparagraph"></p>
<p class="endnote">The function Lists::compile is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Lists::compile is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="inwebparagraph"><a id="SP12_1"></a><b>&#167;12.1. </b>These are I6 word arrays, with the contents:
</p>

View file

@ -27,7 +27,7 @@
<p class="inwebparagraph"></p>
<p class="endnote">The function Tables::Support::compile is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Tables::Support::compile is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="inwebparagraph"><a id="SP1_1"></a><b>&#167;1.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Compile the data structures for entry storage</span> <span class="cwebmacronumber">1.1</span>&gt; =
@ -496,7 +496,7 @@ table values and prints the (title-cased) name of the one which matches.
<p class="inwebparagraph"></p>
<p class="endnote">The function Tables::Support::compile_print_table_names is used in 1/htc (<a href="1-htc.html#SP2_6">&#167;2.6</a>).</p>
<p class="endnote">The function Tables::Support::compile_print_table_names is used in 1/htc (<a href="1-htc.html#SP2_7">&#167;2.7</a>).</p>
<hr class="tocbar">
<ul class="toc"><li><a href="19-tb.html">Back to 'Tables'</a></li><li><a href="19-tod.html">Continue with 'Tables of Definitions'</a></li></ul><hr class="tocbar">

View file

@ -121,7 +121,7 @@ established names of tables and columns:
<p class="inwebparagraph"></p>
<p class="endnote">The function Tables::traverse_to_create is used in 1/htc (<a href="1-htc.html#SP2_3">&#167;2.3</a>).</p>
<p class="endnote">The function Tables::traverse_to_create is used in 1/htc (<a href="1-htc.html#SP2_4">&#167;2.4</a>).</p>
<p class="endnote">The function Tables::visit_to_create appears nowhere else.</p>
@ -148,7 +148,7 @@ see below.
<p class="inwebparagraph"></p>
<p class="endnote">The function Tables::traverse_to_stock is used in 1/htc (<a href="1-htc.html#SP2_4">&#167;2.4</a>, <a href="1-htc.html#SP2_7">&#167;2.7</a>).</p>
<p class="endnote">The function Tables::traverse_to_stock is used in 1/htc (<a href="1-htc.html#SP2_5">&#167;2.5</a>, <a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. </b>Last and least: a traverse existing just to issue a problem message in a
case which Inform can often cope with, but which the experience of users
@ -177,7 +177,7 @@ suggests is never a good idea.
<p class="inwebparagraph"></p>
<p class="endnote">The function Tables::check_tables_for_kind_clashes is used in 1/htc (<a href="1-htc.html#SP2_6">&#167;2.6</a>).</p>
<p class="endnote">The function Tables::check_tables_for_kind_clashes is used in 1/htc (<a href="1-htc.html#SP2_7">&#167;2.7</a>).</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. Table basics. </b>The following makes a blank structure for a table, but it isn't valid until
some of these fields have been properly filled in.
@ -1590,7 +1590,7 @@ people &mdash; it needs to be "yourself" instead, since "player" is a variable.
<p class="inwebparagraph"></p>
<p class="endnote">The function Tables::complete is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Tables::complete is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="inwebparagraph"><a id="SP26_1"></a><b>&#167;26.1. </b>For the actual code, see below.
</p>

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>1/htc</title>
<title>1/pp</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">

View file

@ -183,7 +183,7 @@ value <code class="display"><span class="extract">pi</span></code>.
<p class="inwebparagraph"></p>
<p class="endnote">The function Equations::traverse_to_create is used in 1/htc (<a href="1-htc.html#SP2_3">&#167;2.3</a>).</p>
<p class="endnote">The function Equations::traverse_to_create is used in 1/htc (<a href="1-htc.html#SP2_4">&#167;2.4</a>).</p>
<p class="endnote">The function Equations::visit_to_create appears nowhere else.</p>
@ -419,7 +419,7 @@ source text:
<p class="inwebparagraph"></p>
<p class="endnote">The function Equations::traverse_to_stock is used in 1/htc (<a href="1-htc.html#SP2_7">&#167;2.7</a>).</p>
<p class="endnote">The function Equations::traverse_to_stock is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="inwebparagraph"><a id="SP13"></a><b>&#167;13. </b>And, as with creation, <code class="display"><span class="extract">Equations::examine</span></code> is called explicitly in the meaning
list converter when an equation is found inline. So in all cases, we call the
@ -2197,7 +2197,7 @@ for equations a value; they are never called.
<p class="inwebparagraph"></p>
<p class="endnote">The function Equations::compile is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Equations::compile is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="inwebparagraph"><a id="SP44"></a><b>&#167;44. </b>These identifiers are used to compile equation names as values, so:
</p>

View file

@ -461,7 +461,7 @@ noun for it; for example, the "announcing activity".
<p class="endnote">The function Activities::add_variable is used in 9/ma (<a href="9-ma.html#SP3_3_25_1">&#167;3.3.25.1</a>).</p>
<p class="endnote">The function Activities::activity_var_creators is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Activities::activity_var_creators is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. Activity indexing. </b></p>
@ -907,15 +907,15 @@ values, of the kind to which the activity applies.
<p class="endnote">The function Activities::emit_activity_list is used in 22/prcd (<a href="22-prcd.html#SP10_5">&#167;10.5</a>).</p>
<p class="endnote">The function Activities::compile_activity_constants is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Activities::compile_activity_constants is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="endnote">The function Activities::Activity_before_rulebooks_array is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Activities::Activity_before_rulebooks_array is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="endnote">The function Activities::Activity_for_rulebooks_array is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Activities::Activity_for_rulebooks_array is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="endnote">The function Activities::Activity_after_rulebooks_array is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Activities::Activity_after_rulebooks_array is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="endnote">The function Activities::Activity_atb_rulebooks_array is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Activities::Activity_atb_rulebooks_array is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="endnote">The function Activities::annotate_list_for_cross_references is used in 22/prcd (<a href="22-prcd.html#SP10_5">&#167;10.5</a>).</p>

View file

@ -608,7 +608,7 @@ can be used in a void context as a sort of return-from-rule phrase.
<p class="endnote">The function Rulebooks::Outcomes::index_outcomes is used in 21/rl2 (<a href="21-rl2.html#SP15">&#167;15</a>).</p>
<p class="endnote">The function Rulebooks::Outcomes::RulebookOutcomePrintingRule is used in 1/htc (<a href="1-htc.html#SP2_7">&#167;2.7</a>).</p>
<p class="endnote">The function Rulebooks::Outcomes::RulebookOutcomePrintingRule is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Rulebooks::Outcomes::get_default_value is used in 13/rsfk (<a href="13-rsfk.html#SP5">&#167;5</a>).</p>

View file

@ -1373,7 +1373,7 @@ I wonder how useful this really is, but it was much requested at one time.
<p class="endnote">The function Rules::rule_defines_response is used in 17/ts (<a href="17-ts.html#SP11">&#167;11</a>), 17/rs (<a href="17-rs.html#SP4">&#167;4</a>, <a href="17-rs.html#SP7_1">&#167;7.1</a>, <a href="17-rs.html#SP7_3_1">&#167;7.3.1</a>, <a href="17-rs.html#SP12_1_1">&#167;12.1.1</a>).</p>
<p class="endnote">The function Rules::check_response_usages is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Rules::check_response_usages is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="endnote">The function Rules::now_rule_defines_response is used in 17/rs (<a href="17-rs.html#SP12_1_1">&#167;12.1.1</a>), 26/tti (<a href="26-tti.html#SP7">&#167;7</a>).</p>

View file

@ -673,7 +673,7 @@ built (for instance, scene endings).
<p class="endnote">The function Rulebooks::get_stv_creator_iname is used in <a href="#SP14_1">&#167;14.1</a>.</p>
<p class="endnote">The function Rulebooks::rulebook_var_creators is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Rulebooks::rulebook_var_creators is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="inwebparagraph"><a id="SP14_1"></a><b>&#167;14.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Make slow lookup routine</span> <span class="cwebmacronumber">14.1</span>&gt; =

View file

@ -89,7 +89,7 @@ name of a new constant.
<p class="inwebparagraph"></p>
<p class="endnote">The function Phrases::Manager::traverse_for_names is used in 1/htc (<a href="1-htc.html#SP2_3">&#167;2.3</a>).</p>
<p class="endnote">The function Phrases::Manager::traverse_for_names is used in 1/htc (<a href="1-htc.html#SP2_4">&#167;2.4</a>).</p>
<p class="endnote">The function Phrases::Manager::visit_for_names appears nowhere else.</p>
@ -189,7 +189,7 @@ placement later on.
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Phrases::Manager::visit_to_create</span><span class="plain">(</span><span class="identifier">parse_node</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">progress_target</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> *</span><span class="identifier">progress_made</span><span class="plain">) {</span>
<span class="plain">(*</span><span class="identifier">progress_made</span><span class="plain">)++;</span>
<span class="reserved">if</span><span class="plain"> ((*</span><span class="identifier">progress_made</span><span class="plain">) % 10 == 0)</span>
<span class="functiontext">ProgressBar::update_progress_bar</span><span class="plain">(3,</span>
<span class="functiontext">ProgressBar::update</span><span class="plain">(3,</span>
<span class="plain">((</span><span class="reserved">float</span><span class="plain">) (*</span><span class="identifier">progress_made</span><span class="plain">))/((</span><span class="reserved">float</span><span class="plain">) (*</span><span class="identifier">progress_target</span><span class="plain">)));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">) == </span><span class="constant">ROUTINE_NT</span><span class="plain">) {</span>
@ -200,7 +200,7 @@ placement later on.
<p class="inwebparagraph"></p>
<p class="endnote">The function Phrases::Manager::traverse is used in 1/htc (<a href="1-htc.html#SP2_7">&#167;2.7</a>).</p>
<p class="endnote">The function Phrases::Manager::traverse is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Phrases::Manager::visit_to_count appears nowhere else.</p>
@ -227,7 +227,7 @@ counting local variables, whose names only exist fleetingly).
<p class="inwebparagraph"></p>
<p class="endnote">The function Phrases::Manager::register_meanings is used in 1/htc (<a href="1-htc.html#SP2_7">&#167;2.7</a>).</p>
<p class="endnote">The function Phrases::Manager::register_meanings is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. Noon. </b>When the final phrase is registered, the hour chimes. From this point
onwards, there's no longer any text which can't be parsed because some
@ -276,7 +276,7 @@ correctly refer to the most recently mentioned action.
<p class="inwebparagraph"></p>
<p class="endnote">The function Phrases::Manager::parse_rule_parameters is used in 1/htc (<a href="1-htc.html#SP2_7">&#167;2.7</a>).</p>
<p class="endnote">The function Phrases::Manager::parse_rule_parameters is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. </b>We can finally make the automatic placements of rules into rulebooks: so
our "fire alarm rule" will at last be placed in the "Instead" rulebook. The
@ -296,7 +296,7 @@ PHRCDs are used to make sure it appears in the right position.
<p class="inwebparagraph"></p>
<p class="endnote">The function Phrases::Manager::add_rules_to_rulebooks is used in 1/htc (<a href="1-htc.html#SP2_7">&#167;2.7</a>).</p>
<p class="endnote">The function Phrases::Manager::add_rules_to_rulebooks is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. </b>It might seem as if the rulebooks are now complete, but this is not true,
because we still have to take care of manual placements like:
@ -333,7 +333,7 @@ only conditionally, or substituted by other rules.
<p class="inwebparagraph"></p>
<p class="endnote">The function Phrases::Manager::parse_rule_placements is used in 1/htc (<a href="1-htc.html#SP2_7">&#167;2.7</a>).</p>
<p class="endnote">The function Phrases::Manager::parse_rule_placements is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Phrases::Manager::visit_to_parse_placements appears nowhere else.</p>
@ -363,7 +363,7 @@ adjective definitions.
<p class="inwebparagraph"></p>
<p class="endnote">The function Phrases::Manager::compile_first_block is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Phrases::Manager::compile_first_block is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="inwebparagraph"><a id="SP10_1"></a><b>&#167;10.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Count up the scale of the task</span> <span class="cwebmacronumber">10.1</span>&gt; =
@ -598,11 +598,11 @@ noted down:
<p class="inwebparagraph"></p>
<p class="endnote">The function Phrases::Manager::rulebooks_array is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Phrases::Manager::rulebooks_array is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="endnote">The function Phrases::Manager::compile_rulebooks is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Phrases::Manager::compile_rulebooks is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="endnote">The function Phrases::Manager::RulebookNames_array is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Phrases::Manager::RulebookNames_array is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="inwebparagraph"><a id="SP13"></a><b>&#167;13. </b>And finally, just as the sun slips below the horizon, we compile the code
which prints out values of the kind "rule" at run-time &mdash; for example, taking
@ -620,7 +620,7 @@ printing out "fire alarm rule".
<p class="inwebparagraph"></p>
<p class="endnote">The function Phrases::Manager::RulePrintingRule_routine is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Phrases::Manager::RulePrintingRule_routine is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="inwebparagraph"><a id="SP14"></a><b>&#167;14. Evening. </b>The twilight gathers, but our work is far from done. Recall that we have
accumulated compilation requests for "To..." phrases, but haven't actually
@ -692,7 +692,7 @@ can be called multiple times in the course of the evening.)
<p class="inwebparagraph"></p>
<p class="endnote">The function Phrases::Manager::compile_as_needed is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Phrases::Manager::compile_as_needed is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<hr class="tocbar">
<ul class="toc"><li><a href="22-itp.html">Back to 'Introduction to Phrases'</a></li><li><a href="22-ph.html">Continue with 'Phrases'</a></li></ul><hr class="tocbar">

View file

@ -188,7 +188,7 @@ an I6 routine name, but no: it compiles to a small array called a "closure".
<p class="inwebparagraph"></p>
<p class="endnote">The function Phrases::Constants::compile_closures is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Phrases::Constants::compile_closures is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="inwebparagraph"><a id="SP8_1"></a><b>&#167;8.1. </b>The closure array consists of three words: the strong kind ID, the address
of the routine, and the text of the name. (The latter enables us to print

View file

@ -639,7 +639,7 @@ response to "requests". All other phrases are compiled just once.
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ph</span><span class="plain">-</span><span class="element">&gt;at_least_one_compiled_form_needed</span><span class="plain">) {</span>
<span class="identifier">ph</span><span class="plain">-</span><span class="element">&gt;at_least_one_compiled_form_needed</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">(*</span><span class="identifier">i</span><span class="plain">)++;</span>
<span class="functiontext">ProgressBar::update_progress_bar</span><span class="plain">(4, ((</span><span class="reserved">float</span><span class="plain">) (*</span><span class="identifier">i</span><span class="plain">))/((</span><span class="reserved">float</span><span class="plain">) </span><span class="identifier">max_i</span><span class="plain">));</span>
<span class="functiontext">ProgressBar::update</span><span class="plain">(4, ((</span><span class="reserved">float</span><span class="plain">) (*</span><span class="identifier">i</span><span class="plain">))/((</span><span class="reserved">float</span><span class="plain">) </span><span class="identifier">max_i</span><span class="plain">));</span>
<span class="plain">}</span>
</pre>
@ -652,48 +652,50 @@ response to "requests". All other phrases are compiled just once.
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Phrases::invoke_to_begin</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">iname</span><span class="plain"> = </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">SUBMAIN_HL</span><span class="plain">);</span>
<span class="identifier">packaging_state</span><span class="plain"> </span><span class="identifier">save</span><span class="plain"> = </span><span class="functiontext">Routines::begin</span><span class="plain">(</span><span class="identifier">iname</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">n</span><span class="plain"> = 0;</span>
<span class="reserved">phrase</span><span class="plain"> *</span><span class="identifier">ph</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">, </span><span class="reserved">phrase</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ph</span><span class="plain">-</span><span class="element">&gt;to_begin</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">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(...),</span>
<span class="string">"there seem to be multiple 'to begin' phrases"</span><span class="plain">,</span>
<span class="string">"but in Basic mode, Inform expects to see exactly one of "</span>
<span class="string">"these, specifying where execution should begin."</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="functiontext">Phrases::compiled_inline</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Task::begin_execution_at_to_begin</span><span class="plain">()) {</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">iname</span><span class="plain"> = </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">SUBMAIN_HL</span><span class="plain">);</span>
<span class="identifier">packaging_state</span><span class="plain"> </span><span class="identifier">save</span><span class="plain"> = </span><span class="functiontext">Routines::begin</span><span class="plain">(</span><span class="identifier">iname</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">n</span><span class="plain"> = 0;</span>
<span class="reserved">phrase</span><span class="plain"> *</span><span class="identifier">ph</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">, </span><span class="reserved">phrase</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ph</span><span class="plain">-</span><span class="element">&gt;to_begin</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">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(...),</span>
<span class="string">"the 'to begin' phrase seems to be defined inline"</span><span class="plain">,</span>
<span class="string">"which in Basic mode is not allowed."</span><span class="plain">);</span>
<span class="string">"there seem to be multiple 'to begin' phrases"</span><span class="plain">,</span>
<span class="string">"but in Basic mode, Inform expects to see exactly one of "</span>
<span class="string">"these, specifying where execution should begin."</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">void_kind</span><span class="plain"> = </span><span class="identifier">Kinds::function_kind</span><span class="plain">(0, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">K_nil</span><span class="plain">);</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">IS</span><span class="plain"> = </span><span class="functiontext">Routines::Compile::iname</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">,</span>
<span class="functiontext">Routines::ToPhrases::make_request</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">,</span>
<span class="identifier">void_kind</span><span class="plain">,</span>
<span class="identifier">NULL</span><span class="plain">,</span>
<span class="identifier">EMPTY_WORDING</span><span class="plain">));</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">IS</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Phrases::compiled_inline</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">)) {</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(...),</span>
<span class="string">"the 'to begin' phrase seems to be defined inline"</span><span class="plain">,</span>
<span class="string">"which in Basic mode is not allowed."</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">void_kind</span><span class="plain"> = </span><span class="identifier">Kinds::function_kind</span><span class="plain">(0, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">K_nil</span><span class="plain">);</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">IS</span><span class="plain"> = </span><span class="functiontext">Routines::Compile::iname</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">,</span>
<span class="functiontext">Routines::ToPhrases::make_request</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">,</span>
<span class="identifier">void_kind</span><span class="plain">,</span>
<span class="identifier">NULL</span><span class="plain">,</span>
<span class="identifier">EMPTY_WORDING</span><span class="plain">));</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">IS</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</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">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(...),</span>
<span class="string">"there seems not to be a 'to begin' phrase"</span><span class="plain">,</span>
<span class="string">"but in Basic mode, Inform expects to see exactly one of "</span>
<span class="string">"these, specifying where execution should begin."</span><span class="plain">);</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">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(...),</span>
<span class="string">"there seems not to be a 'to begin' phrase"</span><span class="plain">,</span>
<span class="string">"but in Basic mode, Inform expects to see exactly one of "</span>
<span class="string">"these, specifying where execution should begin."</span><span class="plain">);</span>
<span class="functiontext">Routines::end</span><span class="plain">(</span><span class="identifier">save</span><span class="plain">);</span>
<span class="functiontext">Hierarchy::make_available</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">iname</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="functiontext">Routines::end</span><span class="plain">(</span><span class="identifier">save</span><span class="plain">);</span>
<span class="functiontext">Hierarchy::make_available</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">iname</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Phrases::invoke_to_begin is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Phrases::invoke_to_begin is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<hr class="tocbar">
<ul class="toc"><li><a href="22-cs.html">Back to 'Construction Sequence'</a></li><li><a href="22-pu.html">Continue with 'Phrase Usage'</a></li></ul><hr class="tocbar">

View file

@ -91,9 +91,9 @@ defined as "At 9:00 AM: ..." But two values are special:
<p class="inwebparagraph"></p>
<p class="endnote">The function Phrases::Timed::TimedEventsTable is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>), 22/cs (<a href="22-cs.html#SP11">&#167;11</a>).</p>
<p class="endnote">The function Phrases::Timed::TimedEventsTable is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>), 22/cs (<a href="22-cs.html#SP11">&#167;11</a>).</p>
<p class="endnote">The function Phrases::Timed::TimedEventTimesTable is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>), 22/cs (<a href="22-cs.html#SP11">&#167;11</a>).</p>
<p class="endnote">The function Phrases::Timed::TimedEventTimesTable is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>), 22/cs (<a href="22-cs.html#SP11">&#167;11</a>).</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b>That's it, really: everything else is just indexing.
</p>
@ -144,7 +144,7 @@ arguably shouldn't block compilation. Then again...
<p class="inwebparagraph"></p>
<p class="endnote">The function Phrases::Timed::check_for_unused is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Phrases::Timed::check_for_unused is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. </b>And here's the actual index segment.
</p>

View file

@ -182,7 +182,7 @@ the doubled use of colons is unfortunate.)
<p class="inwebparagraph"></p>
<p class="endnote">The function Phrases::Adjectives::traverse is used in 1/htc (<a href="1-htc.html#SP2_3">&#167;2.3</a>).</p>
<p class="endnote">The function Phrases::Adjectives::traverse is used in 1/htc (<a href="1-htc.html#SP2_4">&#167;2.4</a>).</p>
<p class="endnote">The function Phrases::Adjectives::look_for_headers appears nowhere else.</p>

View file

@ -325,7 +325,7 @@ late to create any further past tense references, so:
<p class="inwebparagraph"></p>
<p class="endnote">The function Chronology::allow_no_further_past_tenses is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Chronology::allow_no_further_past_tenses is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. </b>The <code class="display"><span class="extract">{-A}</span></code> ("past actions") escape.
A series of <code class="display"><span class="extract">if</span></code> statements checking whether each past-tense action is now
@ -404,7 +404,7 @@ ever tampered with.
<p class="inwebparagraph"></p>
<p class="endnote">The function Chronology::past_actions_i6_routines is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Chronology::past_actions_i6_routines is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. </b></p>
@ -454,7 +454,7 @@ ever tampered with.
<p class="inwebparagraph"></p>
<p class="endnote">The function Chronology::past_tenses_i6_escape is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Chronology::past_tenses_i6_escape is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="inwebparagraph"><a id="SP7_1"></a><b>&#167;7.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Unpack the past</span> <span class="cwebmacronumber">7.1</span>&gt; =
@ -931,7 +931,7 @@ times".
<p class="inwebparagraph"></p>
<p class="endnote">The function Chronology::chronology_extents_i6_escape is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Chronology::chronology_extents_i6_escape is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<hr class="tocbar">
<ul class="toc"><li><a href="24-sf.html">Back to 'Stack Frames'</a></li><li><i>(This section ends Chapter 24: Compilation Context.)</i></li></ul><hr class="tocbar">

View file

@ -148,7 +148,7 @@ Inform's own version number), but it belongs nowhere else either, so:
<p class="inwebparagraph"></p>
<p class="endnote">The function FundamentalConstants::emit_build_number is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function FundamentalConstants::emit_build_number is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>This also doesn't really belong here, but...
</p>

View file

@ -181,7 +181,7 @@ specification <code class="display"><span class="extract">--&gt; 0</span></code>
<p class="endnote">The function JumpLabels::allocate_counter is used in 25/cii (<a href="25-cii.html#SP3_4_6">&#167;3.4.6</a>).</p>
<p class="endnote">The function JumpLabels::compile_necessary_storage is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function JumpLabels::compile_necessary_storage is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<hr class="tocbar">
<ul class="toc"><li><a href="26-lt.html">Back to 'List Together'</a></li><li><a href="26-ct.html">Continue with 'Compiled Text'</a></li></ul><hr class="tocbar">

View file

@ -238,7 +238,7 @@ present.
<p class="inwebparagraph"></p>
<p class="endnote">The function Plugins::Manage::start is used in 1/htc (<a href="1-htc.html#SP2_1">&#167;2.1</a>).</p>
<p class="endnote">The function Plugins::Manage::start is used in 1/htc (<a href="1-htc.html#SP2_2">&#167;2.2</a>).</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. </b>Although most of Inform's brain remains the same, the outermost part can
be put together from whatever skills are required: our modular oblongata,
@ -371,7 +371,7 @@ with the following.
<p class="inwebparagraph"></p>
<p class="endnote">The function Plugins::Manage::start_plugins is used in 1/htc (<a href="1-htc.html#SP2_3">&#167;2.3</a>).</p>
<p class="endnote">The function Plugins::Manage::start_plugins is used in 1/htc (<a href="1-htc.html#SP2_4">&#167;2.4</a>).</p>
<p class="inwebparagraph"><a id="SP12"></a><b>&#167;12. Describing the current VM. </b></p>
@ -482,7 +482,7 @@ with the following.
<p class="endnote">The function Plugins::Manage::show appears nowhere else.</p>
<p class="endnote">The function Plugins::Manage::plugged_in is used in 1/htc (<a href="1-htc.html#SP2_1">&#167;2.1</a>, <a href="1-htc.html#SP2_9">&#167;2.9</a>), 5/ipw (<a href="5-ipw.html#SP2">&#167;2</a>), 9/rpt (<a href="9-rpt.html#SP9_5">&#167;9.5</a>), 16/ic (<a href="16-ic.html#SP15">&#167;15</a>), 21/rl (<a href="21-rl.html#SP8">&#167;8</a>).</p>
<p class="endnote">The function Plugins::Manage::plugged_in is used in 1/htc (<a href="1-htc.html#SP2_1">&#167;2.1</a>), 5/ipw (<a href="5-ipw.html#SP2">&#167;2</a>), 9/rpt (<a href="9-rpt.html#SP9_5">&#167;9.5</a>), 16/ic (<a href="16-ic.html#SP15">&#167;15</a>), 21/rl (<a href="21-rl.html#SP8">&#167;8</a>).</p>
<hr class="tocbar">
<ul class="toc"><li><a href="26-iti.html">Back to 'I6 Template Interpreter'</a></li><li><a href="26-pc.html">Continue with 'Plugin Calls'</a></li></ul><hr class="tocbar">

View file

@ -531,11 +531,11 @@ without notice.
<p class="endnote">The function PL::Parsing::TestScripts::check_test_command is used in <a href="#SP8_1">&#167;8.1</a>.</p>
<p class="endnote">The function PL::Parsing::TestScripts::write_text is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function PL::Parsing::TestScripts::write_text is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="endnote">The function PL::Parsing::TestScripts::TestScriptSub_stub_routine is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function PL::Parsing::TestScripts::TestScriptSub_stub_routine is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="endnote">The function PL::Parsing::TestScripts::TestScriptSub_routine is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function PL::Parsing::TestScripts::TestScriptSub_routine is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="inwebparagraph"><a id="SP11"></a><b>&#167;11. </b></p>
@ -685,7 +685,7 @@ without notice.
<p class="endnote">The function PL::Parsing::TestScripts::new_internal is used in <a href="#SP9">&#167;9</a>.</p>
<p class="endnote">The function PL::Parsing::TestScripts::InternalTestCases_routine is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function PL::Parsing::TestScripts::InternalTestCases_routine is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="endnote">The function PL::Parsing::TestScripts::begin_internal_reporting is used in 20/eq (<a href="20-eq.html#SP52">&#167;52</a>).</p>

View file

@ -603,7 +603,7 @@ and problem messages must be issued.)
<p class="inwebparagraph"></p>
<p class="endnote">The function UseOptions::compile is used in 1/htc (<a href="1-htc.html#SP2_5">&#167;2.5</a>).</p>
<p class="endnote">The function UseOptions::compile is used in 1/htc (<a href="1-htc.html#SP2_6">&#167;2.6</a>).</p>
<p class="inwebparagraph"><a id="SP18"></a><b>&#167;18. </b>I6 memory settings need to be issued as ICL commands at the top of the I6
source code: see the DM4 for details.
@ -628,7 +628,7 @@ source code: see the DM4 for details.
<p class="inwebparagraph"></p>
<p class="endnote">The function UseOptions::compile_icl_commands is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function UseOptions::compile_icl_commands is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="inwebparagraph"><a id="SP19"></a><b>&#167;19. </b>Now for indexing, where there's nothing much to see.
</p>
@ -794,7 +794,7 @@ one to test them, one to print them.
<p class="inwebparagraph"></p>
<p class="endnote">The function UseOptions::TestUseOption_routine is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function UseOptions::TestUseOption_routine is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="inwebparagraph"><a id="SP21_1"></a><b>&#167;21.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Compile the TestUseOption routine</span> <span class="cwebmacronumber">21.1</span>&gt; =
@ -927,7 +927,7 @@ one to test them, one to print them.
<p class="endnote">The function UseOptions::ranking_table_given appears nowhere else.</p>
<p class="endnote">The function UseOptions::configure_template is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function UseOptions::configure_template is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<hr class="tocbar">
<ul class="toc"><li><a href="26-i6i.html">Back to 'Inform 6 Inclusions'</a></li><li><a href="26-lt.html">Continue with 'List Together'</a></li></ul><hr class="tocbar">

View file

@ -95,7 +95,7 @@ level-0 headings, which are the nodes from which these blocks of source text han
<p class="inwebparagraph"></p>
<p class="endnote">The function Modules::traverse_to_define is used in 1/htc (<a href="1-htc.html#SP2_3">&#167;2.3</a>).</p>
<p class="endnote">The function Modules::traverse_to_define is used in 1/htc (<a href="1-htc.html#SP2_4">&#167;2.4</a>).</p>
<p class="endnote">The function Modules::look_for_cu appears nowhere else.</p>

File diff suppressed because one or more lines are too long

View file

@ -75,7 +75,7 @@ can simply discard the search results.
<p class="inwebparagraph"></p>
<p class="endnote">The function NaturalLanguages::produce_index is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="endnote">The function NaturalLanguages::produce_index is used in 1/htc (<a href="1-htc.html#SP2_10">&#167;2.10</a>).</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b></p>

View file

@ -169,7 +169,7 @@ inclusion sentences &mdash; see Kits.
<p class="inwebparagraph"></p>
<p class="endnote">The function SourceFiles::read is used in 1/htc (<a href="1-htc.html#SP2_2">&#167;2.2</a>), 8/ie (<a href="8-ie.html#SP5_2">&#167;5.2</a>).</p>
<p class="endnote">The function SourceFiles::read is used in 1/wtc (<a href="1-wtc.html#SP7">&#167;7</a>), 8/ie (<a href="8-ie.html#SP5_2">&#167;5.2</a>).</p>
<p class="endnote">The function SourceFiles::issue_problems_arising is used in 8/ie (<a href="8-ie.html#SP5_2">&#167;5.2</a>).</p>

View file

@ -1976,7 +1976,7 @@ prefaced "(of a rulebook)", "(of an activity)", and so on.
<p class="inwebparagraph"></p>
<p class="endnote">The function Adjectives::Meanings::agreements is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Adjectives::Meanings::agreements is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="endnote">The function Adjectives::Meanings::emit is used in 25/ci (<a href="25-ci.html#SP3_1">&#167;3.1</a>, <a href="25-ci.html#SP3_2_3_3_1">&#167;3.2.3.3.1</a>, <a href="25-ci.html#SP3_2_3_4_1">&#167;3.2.3.4.1</a>).</p>

View file

@ -258,7 +258,7 @@ whole thing into a <code class="display"><span class="extract">specification</sp
<p class="inwebparagraph"></p>
<p class="endnote">The function Semantics::read_preform is used in 1/htc (<a href="1-htc.html#SP2_1">&#167;2.1</a>).</p>
<p class="endnote">The function Semantics::read_preform is used in 1/htc (<a href="1-htc.html#SP2_2">&#167;2.2</a>).</p>
<p class="inwebparagraph"><a id="SP7_1"></a><b>&#167;7.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Mark certain nonterminals to have their vocabularies numbered and flagged</span> <span class="cwebmacronumber">7.1</span>&gt; =

View file

@ -1012,7 +1012,7 @@ Note that only instances, not kinds, appear.
<p class="inwebparagraph"></p>
<p class="endnote">The function Instances::place_objects_in_definition_sequence is used in 1/htc (<a href="1-htc.html#SP2_5">&#167;2.5</a>).</p>
<p class="endnote">The function Instances::place_objects_in_definition_sequence is used in 1/htc (<a href="1-htc.html#SP2_6">&#167;2.6</a>).</p>
<p class="inwebparagraph"><a id="SP32"></a><b>&#167;32. </b>And we read the order back using these macros:
</p>

View file

@ -3924,7 +3924,7 @@ set.
<p class="inwebparagraph"></p>
<p class="endnote">The function LiteralPatterns::define_named_phrases is used in 1/htc (<a href="1-htc.html#SP2_7">&#167;2.7</a>).</p>
<p class="endnote">The function LiteralPatterns::define_named_phrases is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="inwebparagraph"><a id="SP40_1"></a><b>&#167;40.1. </b>These text substitutions correspond exactly neither to the LPs nor to the
names. For instance, "in tonnes" produces a text substitution which takes

View file

@ -100,7 +100,7 @@ instance, the Standard Rules want the player-character object to be called
<p class="inwebparagraph"></p>
<p class="endnote">The function UseNouns::name_all is used in 1/htc (<a href="1-htc.html#SP2_5">&#167;2.5</a>).</p>
<p class="endnote">The function UseNouns::name_all is used in 1/htc (<a href="1-htc.html#SP2_6">&#167;2.6</a>).</p>
<p class="endnote">The function UseNouns::visit_to_name appears nowhere else.</p>

View file

@ -1324,7 +1324,7 @@ above. This happens very early in compilation.
<p class="inwebparagraph"></p>
<p class="endnote">The function BinaryPredicates::make_built_in is used in 1/htc (<a href="1-htc.html#SP2_3">&#167;2.3</a>).</p>
<p class="endnote">The function BinaryPredicates::make_built_in is used in 1/htc (<a href="1-htc.html#SP2_4">&#167;2.4</a>).</p>
<p class="inwebparagraph"><a id="SP46"></a><b>&#167;46. Other property-based relations. </b></p>
@ -1349,7 +1349,7 @@ above. This happens very early in compilation.
<p class="inwebparagraph"></p>
<p class="endnote">The function BinaryPredicates::make_built_in_further is used in 1/htc (<a href="1-htc.html#SP2_6">&#167;2.6</a>).</p>
<p class="endnote">The function BinaryPredicates::make_built_in_further is used in 1/htc (<a href="1-htc.html#SP2_7">&#167;2.7</a>).</p>
<p class="inwebparagraph"><a id="SP47"></a><b>&#167;47. </b></p>

View file

@ -90,7 +90,7 @@ cleared.)
<p class="inwebparagraph"></p>
<p class="endnote">The function NewVerbs::add_inequalities is used in 1/htc (<a href="1-htc.html#SP2_3">&#167;2.3</a>).</p>
<p class="endnote">The function NewVerbs::add_inequalities is used in 1/htc (<a href="1-htc.html#SP2_4">&#167;2.4</a>).</p>
<p class="endnote">The function NewVerbs::add_inequalities_inner appears nowhere else.</p>
@ -1034,7 +1034,7 @@ foreign verbs (4).
<p class="endnote">The function NewVerbs::ConjugateVerbDefinitions is used in 27/ei (<a href="27-ei.html#SP2">&#167;2</a>).</p>
<p class="endnote">The function NewVerbs::ConjugateVerb is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function NewVerbs::ConjugateVerb is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="inwebparagraph"><a id="SP18_1"></a><b>&#167;18.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Compile ConjugateVerb routine</span> <span class="cwebmacronumber">18.1</span>&gt; =

View file

@ -1233,7 +1233,7 @@ logical properties of the two terms of the BP being defined.
<p class="endnote">The function Relations::compile_defined_relation_constant appears nowhere else.</p>
<p class="endnote">The function Relations::compile_defined_relation_constants is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Relations::compile_defined_relation_constants is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="inwebparagraph"><a id="SP15"></a><b>&#167;15. </b></p>
@ -2385,7 +2385,7 @@ logical properties of the two terms of the BP being defined.
<p class="inwebparagraph"></p>
<p class="endnote">The function Relations::IterateRelations is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Relations::IterateRelations is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="inwebparagraph"><a id="SP18"></a><b>&#167;18. The bitmap for various-to-various relations. </b>It is unavoidable that a general V-to-V relation will take at least LR bits
of storage, where L is the size of the left domain and R the size of the
@ -3141,7 +3141,7 @@ logical properties of the two terms of the BP being defined.
<p class="inwebparagraph"></p>
<p class="endnote">The function Relations::compile_defined_relations is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Relations::compile_defined_relations is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="inwebparagraph"><a id="SP29_1"></a><b>&#167;29.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Compile RProperty routine</span> <span class="cwebmacronumber">29.1</span>&gt; =

View file

@ -530,7 +530,7 @@ begin by removing any existing relationships between the heading nodes.
<p class="inwebparagraph"></p>
<p class="endnote">The function Sentences::Headings::make_tree is used in <a href="#SP10">&#167;10</a>, <a href="#SP28_3">&#167;28.3</a>, 1/htc (<a href="1-htc.html#SP2_3">&#167;2.3</a>).</p>
<p class="endnote">The function Sentences::Headings::make_tree is used in <a href="#SP10">&#167;10</a>, <a href="#SP28_3">&#167;28.3</a>, 1/htc (<a href="1-htc.html#SP2_4">&#167;2.4</a>).</p>
<p class="inwebparagraph"><a id="SP13_1"></a><b>&#167;13.1. </b>Note that the loop over headings below loops through all those which were
created by the memory manager: which is to say, all of them except for the
@ -849,7 +849,7 @@ But when the following is called, we do know that.
<p class="inwebparagraph"></p>
<p class="endnote">The function Sentences::Headings::satisfy_dependencies is used in 1/htc (<a href="1-htc.html#SP2_3">&#167;2.3</a>).</p>
<p class="endnote">The function Sentences::Headings::satisfy_dependencies is used in 1/htc (<a href="1-htc.html#SP2_4">&#167;2.4</a>).</p>
<p class="inwebparagraph"><a id="SP21"></a><b>&#167;21. </b>And now the code to check an individual heading's usage. This whole
thing is carefully timed so that we can still afford to cut up and rearrange
@ -1723,7 +1723,7 @@ Version", contains the Inform build number in its usual form: "4Q34", for instan
<p class="inwebparagraph"></p>
<p class="endnote">The function Sentences::Headings::write_as_xml is used in 1/htc (<a href="1-htc.html#SP2_3">&#167;2.3</a>).</p>
<p class="endnote">The function Sentences::Headings::write_as_xml is used in 1/htc (<a href="1-htc.html#SP2_4">&#167;2.4</a>).</p>
<p class="endnote">The function Sentences::Headings::write_headings_as_xml_inner appears nowhere else.</p>

View file

@ -152,7 +152,7 @@ in quick succession, the second run-through does nothing.)
<p class="inwebparagraph"></p>
<p class="endnote">The function Sentences::VPs::traverse is used in 1/htc (<a href="1-htc.html#SP2_3">&#167;2.3</a>).</p>
<p class="endnote">The function Sentences::VPs::traverse is used in 1/htc (<a href="1-htc.html#SP2_4">&#167;2.4</a>).</p>
<p class="endnote">The function Sentences::VPs::visit appears nowhere else.</p>

View file

@ -90,7 +90,7 @@ not be treated as a possessive, and expunge them.
<p class="endnote">The function Sentences::Rearrangement::further_material appears nowhere else.</p>
<p class="endnote">The function Sentences::Rearrangement::tidy_up_ofs_and_froms is used in 1/htc (<a href="1-htc.html#SP2_3">&#167;2.3</a>).</p>
<p class="endnote">The function Sentences::Rearrangement::tidy_up_ofs_and_froms is used in 1/htc (<a href="1-htc.html#SP2_4">&#167;2.4</a>).</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>The following array is used only by Traversals 1 to 3, and is how we
remember direction names.

View file

@ -879,9 +879,9 @@ be such that their head nodes each pass this test:
<p class="endnote">The function ParseTreeUsage::write_to_file appears nowhere else.</p>
<p class="endnote">The function ParseTreeUsage::plant_parse_tree is used in 1/htc (<a href="1-htc.html#SP2_3">&#167;2.3</a>).</p>
<p class="endnote">The function ParseTreeUsage::plant_parse_tree is used in 1/htc (<a href="1-htc.html#SP2_4">&#167;2.4</a>).</p>
<p class="endnote">The function ParseTreeUsage::verify is used in 1/htc (<a href="1-htc.html#SP2_3">&#167;2.3</a>).</p>
<p class="endnote">The function ParseTreeUsage::verify is used in 1/htc (<a href="1-htc.html#SP2_4">&#167;2.4</a>).</p>
<p class="endnote">The function ParseTreeUsage::write_main_source_to_log is used in 1/mr (<a href="1-mr.html#SP1_5">&#167;1.5</a>).</p>

View file

@ -83,7 +83,7 @@ on childless nodes, it cannot ever act on the same node twice.
<p class="inwebparagraph"></p>
<p class="endnote">The function Sentences::RuleSubtrees::register_recently_lexed_phrases is used in 1/htc (<a href="1-htc.html#SP2_3">&#167;2.3</a>), 5/lp (<a href="5-lp.html#SP40">&#167;40</a>, <a href="5-lp.html#SP41">&#167;41</a>), 7/oaf (<a href="7-oaf.html#SP3">&#167;3</a>), 15/ma (<a href="15-ma.html#SP11_4">&#167;11.4</a>).</p>
<p class="endnote">The function Sentences::RuleSubtrees::register_recently_lexed_phrases is used in 1/htc (<a href="1-htc.html#SP2_4">&#167;2.4</a>), 5/lp (<a href="5-lp.html#SP40">&#167;40</a>, <a href="5-lp.html#SP41">&#167;41</a>), 7/oaf (<a href="7-oaf.html#SP3">&#167;3</a>), 15/ma (<a href="15-ma.html#SP11_4">&#167;11.4</a>).</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b>Command nodes are demoted to be children of routine nodes:
</p>
@ -2181,7 +2181,7 @@ are added, they can fairly simply be put here.
<p class="endnote">The function Sentences::RuleSubtrees::csp_new appears nowhere else.</p>
<p class="endnote">The function Sentences::RuleSubtrees::create_standard_csps is used in 1/htc (<a href="1-htc.html#SP2_2">&#167;2.2</a>).</p>
<p class="endnote">The function Sentences::RuleSubtrees::create_standard_csps is used in 1/htc (<a href="1-htc.html#SP2_3">&#167;2.3</a>).</p>
<p class="endnote">The function Sentences::RuleSubtrees::log_control_structure is used in 7/ptu (<a href="7-ptu.html#SP17_2">&#167;17.2</a>).</p>

View file

@ -49,7 +49,7 @@ text has now officially been read.
<p class="inwebparagraph"></p>
<p class="endnote">The function StructuralSentences::declare_source_loaded is used in 1/htc (<a href="1-htc.html#SP2_3">&#167;2.3</a>).</p>
<p class="endnote">The function StructuralSentences::declare_source_loaded is used in 1/htc (<a href="1-htc.html#SP2_4">&#167;2.4</a>).</p>
<p class="endnote">The function StructuralSentences::annotate_new_sentence appears nowhere else.</p>
@ -139,7 +139,7 @@ though: extensions, including the Standard Rules, have yet to be read.)
<p class="inwebparagraph"></p>
<p class="endnote">The function StructuralSentences::break_source is used in 1/htc (<a href="1-htc.html#SP2_3">&#167;2.3</a>).</p>
<p class="endnote">The function StructuralSentences::break_source is used in 1/htc (<a href="1-htc.html#SP2_4">&#167;2.4</a>).</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. </b>Sentences in the source text are of five categories: dividing sentences,
which divide up the source into segments; structural sentences, which split

View file

@ -258,7 +258,7 @@ check that they have been met.
<p class="inwebparagraph"></p>
<p class="endnote">The function Extensions::Files::check_versions is used in 1/htc (<a href="1-htc.html#SP2_3">&#167;2.3</a>).</p>
<p class="endnote">The function Extensions::Files::check_versions is used in 1/htc (<a href="1-htc.html#SP2_4">&#167;2.4</a>).</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. Credit for extensions. </b>Here we compile an I6 routine to print out credits for all the extensions
present in the compiled work. This is important because the extensions
@ -354,7 +354,7 @@ feelings of modesty.
<p class="inwebparagraph"></p>
<p class="endnote">The function Extensions::Files::ShowExtensionVersions_routine is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="endnote">The function Extensions::Files::ShowExtensionVersions_routine is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. </b>The actual credit consists of a single line, with name, version number
and author. These are printed as I6 strings, hence the ISO encoding.

View file

@ -58,7 +58,7 @@ guaranteed to be no INCLUDE nodes remaining in the parse tree.
<p class="inwebparagraph"></p>
<p class="endnote">The function Extensions::Inclusion::traverse is used in 1/htc (<a href="1-htc.html#SP2_3">&#167;2.3</a>).</p>
<p class="endnote">The function Extensions::Inclusion::traverse is used in 1/htc (<a href="1-htc.html#SP2_4">&#167;2.4</a>).</p>
<p class="endnote">The function Extensions::Inclusion::visit appears nowhere else.</p>

View file

@ -143,6 +143,12 @@ we don't bother to print details of the closing <code class="display"><span clas
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">sentence_handlers_initialised</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">assembly_position</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span> <span class="comment">where assembled sentences are added</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::Traverse::traverse1</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="functiontext">Assertions::Traverse::traverse</span><span class="plain">(1);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::Traverse::traverse2</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="functiontext">Assertions::Traverse::traverse</span><span class="plain">(2);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::Traverse::traverse</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">pass</span><span class="plain">) {</span>
<span class="functiontext">Assertions::Traverse::new_discussion</span><span class="plain">(); </span> <span class="comment">clear memory of what the subject and object of discussion are</span>
<span class="identifier">traverse</span><span class="plain"> = </span><span class="identifier">pass</span><span class="plain">;</span>
@ -159,7 +165,11 @@ we don't bother to print details of the closing <code class="display"><span clas
<p class="inwebparagraph"></p>
<p class="endnote">The function Assertions::Traverse::traverse is used in 1/htc (<a href="1-htc.html#SP2_4">&#167;2.4</a>).</p>
<p class="endnote">The function Assertions::Traverse::traverse1 is used in 1/htc (<a href="1-htc.html#SP2_5">&#167;2.5</a>).</p>
<p class="endnote">The function Assertions::Traverse::traverse2 is used in 1/htc (<a href="1-htc.html#SP2_5">&#167;2.5</a>).</p>
<p class="endnote">The function Assertions::Traverse::traverse appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP7_1"></a><b>&#167;7.1. </b>Here's a tricky timing problem, or rather, here's the fix for it. Assemblies
are made when the kinds of objects are set, and they're made by inserting

View file

@ -13,19 +13,15 @@
<ul class="chapterlist">
<li>
<p><a name="1"></a><spon class="chaptertitle">Chapter 1: Configuration and Control</span></p>
<p><span class="purpose">The chief executive: the main routine through which Inform 7 begins execution, and which reads command-line switches supplied by its customers.</span></p>
<p><span class="purpose">The management and the production line for the compilation process.</span></p>
<ul class="sectionlist">
<li>
<p><a href="1-mr.html"><spon class="sectiontitle">Main Routine</span></a> -
<span class="purpose">The top level of the Inform 7 compiler, reading command line arguments and preparing the way.</span></p>
</li>
<li>
<p><a href="1-cm.html"><spon class="sectiontitle">Core Module</span></a> -
<span class="purpose">Setting up the use of this module.</span></p>
</li>
<li>
<p><a href="1-pp.html"><spon class="sectiontitle">Progress Percentages</span></a> -
<span class="purpose">This tiny section, the Lichtenstein of Inform, prints percentage of completion estimates onto |stderr| so that the host application can intercept them and update its graphical progress bar.</span></p>
<p><a href="1-mr.html"><spon class="sectiontitle">Main Routine</span></a> -
<span class="purpose">The top level of the Inform 7 compiler, reading command line arguments and preparing the way.</span></p>
</li>
<li>
<p><a href="1-wtc.html"><spon class="sectiontitle">What To Compile</span></a> -
@ -33,13 +29,17 @@
</li>
<li>
<p><a href="1-htc.html"><spon class="sectiontitle">How To Compile</span></a> -
<span class="purpose">To configure the many locations used in the host filing system.</span></p>
<span class="purpose">The long production line on which products of Inform are built, one step at a time.</span></p>
</li>
<li>
<p><a href="1-pp.html"><spon class="sectiontitle">Progress Percentages</span></a> -
<span class="purpose">This tiny section, the Lichtenstein of Inform, prints percentage of completion estimates so that the host application can intercept them and update its graphical progress bar.</span></p>
</li>
</ul>
</li>
<li>
<p><a name="2"></a><spon class="chaptertitle">Chapter 2: Bridge to Problems Module</span></p>
<p><span class="purpose">The issuing of Problem messages, and the debugging log file.</span></p>
<p><span class="purpose">The issuing of Problem messages.</span></p>
<ul class="sectionlist">
<li>
<p><a href="2-up.html"><spon class="sectiontitle">Using Problems</span></a> -

118
docs/html-module/1-im.html Normal file
View file

@ -0,0 +1,118 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Booklet Title</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<!--Weave of '1/im' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">html</a></li><li><a href="index.html#1">Chapter 1: Starting Up</a></li><li><b>Index Module</b></li></ul><p class="purpose">Setting up the use of this module.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Introduction</a></li><li><a href="#SP3">&#167;3. The beginning</a></li><li><a href="#SP4">&#167;4. The end</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Introduction. </b></p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">HTML_MODULE</span><span class="plain"> </span><span class="identifier">TRUE</span>
</pre>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>To begin with, this module needs to allocate memory:
</p>
<pre class="display">
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. The beginning. </b>(The client doesn't need to call the start and end routines, because the
foundation module does that automatically.)
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">HTMLModule::start</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
&lt;<span class="cwebmacro">Register this module's stream writers</span> <span class="cwebmacronumber">3.1</span>&gt;<span class="character">;</span>
&lt;<span class="cwebmacro">Register this module's debugging log aspects</span> <span class="cwebmacronumber">3.2</span>&gt;<span class="character">;</span>
&lt;<span class="cwebmacro">Register this module's debugging log writers</span> <span class="cwebmacronumber">3.3</span>&gt;<span class="character">;</span>
&lt;<span class="cwebmacro">Register this module's command line switches</span> <span class="cwebmacronumber">3.4</span>&gt;<span class="character">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function HTMLModule::start appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP3_1"></a><b>&#167;3.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Register this module's stream writers</span> <span class="cwebmacronumber">3.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP3_2"></a><b>&#167;3.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Register this module's debugging log aspects</span> <span class="cwebmacronumber">3.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP3_3"></a><b>&#167;3.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">Register this module's debugging log writers</span> <span class="cwebmacronumber">3.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP3_4"></a><b>&#167;3.4. </b><code class="display">
&lt;<span class="cwebmacrodefn">Register this module's command line switches</span> <span class="cwebmacronumber">3.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="plain">;</span>
</pre>
<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. The end. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">HTMLModule::end</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function HTMLModule::end appears nowhere else.</p>
<hr class="tocbar">
<ul class="toc"><li><i>(This section begins Chapter 1: Starting Up.)</i></li><li><i>(This section ends Chapter 1: Starting Up.)</i></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>

888
docs/html-module/2-hd.html Normal file
View file

@ -0,0 +1,888 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>2/jp</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<!--Weave of '2/hd' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">html</a></li><li><a href="index.html#2">Chapter 2: HTML</a></li><li><b>HTML Documentation</b></li></ul><p class="purpose">To translate a passage of source text into HTML-format documentation, for use in the automatically generated documentation pages on each installed extension.</p>
<ul class="toc"><li><a href="#SP2">&#167;2. Links and leafnames</a></li><li><a href="#SP7">&#167;7. The table of contents</a></li><li><a href="#SP9">&#167;9. Setting the body text</a></li><li><a href="#SP9_1">&#167;9.1. Typesetting the standard matter</a></li><li><a href="#SP9_6">&#167;9.6. Typesetting the headings</a></li><li><a href="#SP9_4_2_1">&#167;9.4.2.1. Typesetting I7 tables in displayed source text</a></li><li><a href="#SP9_8">&#167;9.8. Typesetting the body of an example</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. </b>This is a port of a simplified version of the Inform documentation tool
<code class="display"><span class="extract">indoc</span></code>, and like all Perl scripts ported to C, it bears a few scars.
</p>
<p class="inwebparagraph">Documentation is extracted from extensions by lexing them (ignoring all
of the actual source text and picking up only after the divider line)
and then running the code below on the word range for the lexed
documentation. Our task is therefore to print out this documentation
in an HTML format which matches the look and feel of pages produced
by <code class="display"><span class="extract">indoc</span></code> for the manuals.
</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. Links and leafnames. </b>Matters are complicated because an extension typically has not only a
run of source text, but also up to 26 examples: suppose there are X
of these. The extension then needs to produce X+1 pages of HTML: the
primary one, which just has the body text, and then X variants which
duplicate the primary one except that one of the examples is opened up
to reveal its content. Each of these pages will have X anchor points
named <code class="display"><span class="extract">#eg1</span></code> up to <code class="display"><span class="extract">#egX</span></code>, for the positions of the examples.
</p>
<p class="inwebparagraph">The pages will typically be filenamed with the extension title, followed
by <code class="display"><span class="extract">-eg1</span></code>, <code class="display"><span class="extract">-eg2</span></code>, ..., in the case of the example variants, and then
<code class="display"><span class="extract">.html</span></code>.
</p>
<p class="inwebparagraph">The following routine prints the leafname part of an HTML reference to the
extension documentation, at anchor point <code class="display"><span class="extract">to_example_anchor</span></code> (or if 0 then
at the top) of the version with example <code class="display"><span class="extract">to_example_variant</span></code> opened (or if
0 then the original with all examples closed). What complicates it is that
the base leafname might be any of the above variant filenames, so we may
need to strip off an existing ending. For instance, if we are in example 2
and want to link to anchor 5 on example 4, the base leafname might be
<code class="display"><span class="extract">Gusher-eg2</span></code> and we need to remove the <code class="display"><span class="extract">-eg2</span></code> and replace with <code class="display"><span class="extract">-eg4</span></code>
before we can add the <code class="display"><span class="extract">#eg5</span></code>.
</p>
<p class="inwebparagraph">This will fail if anyone's extension has a title ending in <code class="display"><span class="extract">-eg</span></code> followed
by a number. I believe I can live with the guilt.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">HTML::Documentation::href_of_example</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">base_leafname</span><span class="plain">,</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">to_example_variant</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">to_example_anchor</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">i</span><span class="plain">=0, </span><span class="identifier">L</span><span class="plain"> = </span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">base_leafname</span><span class="plain">); </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">L</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Str::includes_wide_string_at</span><span class="plain">(</span><span class="identifier">base_leafname</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"-eg"</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">Characters::isdigit</span><span class="plain">(</span><span class="identifier">Str::get_at</span><span class="plain">(</span><span class="identifier">base_leafname</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">+3)))) </span><span class="reserved">break</span><span class="plain">;</span>
<span class="identifier">PUT</span><span class="plain">(</span><span class="identifier">Str::get_at</span><span class="plain">(</span><span class="identifier">base_leafname</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">));</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">to_example_variant</span><span class="plain"> &gt; 0) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"-eg%d"</span><span class="plain">, </span><span class="identifier">to_example_variant</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">".html"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">to_example_anchor</span><span class="plain"> &gt; 0) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"#eg%d"</span><span class="plain">, </span><span class="identifier">to_example_anchor</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function HTML::Documentation::href_of_example is used in <a href="#SP7_2">&#167;7.2</a>, <a href="#SP9_7_2">&#167;9.7.2</a>.</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>The extension documentation text can optionally include section and
chapter headings, and also examples. Here we parse the opening of a paragraph
to see if it might be a heading. For instance, a paragraph consisting of
</p>
<blockquote>
<p>Section: Black Gold</p>
</blockquote>
<p class="inwebparagraph">matches successfully and sets the level to 2 and the name to the word range
"Black Gold".
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">extension</span><span class="plain">-</span><span class="identifier">documentation</span><span class="plain">-</span><span class="identifier">heading</span><span class="plain">&gt; ::=</span>
<span class="identifier">chapter</span><span class="plain"> : ... | ==&gt; 1</span>
<span class="identifier">section</span><span class="plain"> : ... ==&gt; 2</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b></p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">HTML::Documentation::extension_documentation_heading</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">int</span><span class="plain"> *</span><span class="identifier">level</span><span class="plain">, </span><span class="identifier">wording</span><span class="plain"> *</span><span class="identifier">HW</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">extension</span><span class="plain">-</span><span class="identifier">documentation</span><span class="plain">-</span><span class="identifier">heading</span><span class="plain">&gt;(</span><span class="identifier">W</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::length</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">) &gt; 10) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">; </span> <span class="comment">not enough space: this runs into the end-of-file padding</span>
<span class="plain">*</span><span class="identifier">level</span><span class="plain"> = &lt;&lt;</span><span class="identifier">r</span><span class="plain">&gt;&gt;;</span>
<span class="identifier">W</span><span class="plain"> = </span><span class="identifier">Wordings::trim_first_word</span><span class="plain">(</span><span class="identifier">Wordings::trim_first_word</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">));</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">end</span><span class="plain"> = </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">);</span>
<span class="reserved">while</span><span class="plain"> ((</span><span class="identifier">end</span><span class="plain">&lt;=</span><span class="identifier">Wordings::last_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) &amp;&amp; (</span><span class="identifier">Lexer::word</span><span class="plain">(</span><span class="identifier">end</span><span class="plain">) != </span><span class="identifier">PARBREAK_V</span><span class="plain">)) </span><span class="identifier">end</span><span class="plain">++;</span>
<span class="identifier">end</span><span class="plain">--;</span>
<span class="plain">*</span><span class="identifier">HW</span><span class="plain"> = </span><span class="identifier">Wordings::up_to</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">end</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="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function HTML::Documentation::extension_documentation_heading is used in <a href="#SP7">&#167;7</a>, <a href="#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b>And here we do the same to identify an example, which has to satisfy a
more exacting specification: a paragraph in the shape
</p>
<blockquote>
<p>Example: *** Gelignite Anderson - A Tale of the Texas Oilmen</p>
</blockquote>
<p class="inwebparagraph">which would result in the name being set to the range "Gelignite Anderson",
an asterisk count of 3, and the rubric being "A Tale of the Texas Oilmen".
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">extension</span><span class="plain">-</span><span class="identifier">example</span><span class="plain">-</span><span class="identifier">header</span><span class="plain">&gt; ::=</span>
<span class="identifier">example</span><span class="plain"> : &lt;</span><span class="identifier">row</span><span class="plain">-</span><span class="identifier">of</span><span class="plain">-</span><span class="identifier">asterisks</span><span class="plain">&gt; ... - ... | ==&gt; </span><span class="identifier">R</span><span class="plain">[1]</span>
<span class="identifier">example</span><span class="plain"> : ... - ... ==&gt; 0</span>
<span class="plain">&lt;</span><span class="identifier">row</span><span class="plain">-</span><span class="identifier">of</span><span class="plain">-</span><span class="identifier">asterisks</span><span class="plain">&gt; ::=</span>
<span class="plain">* | ==&gt; 1</span>
<span class="plain">** | ==&gt; 2</span>
<span class="plain">\*** | ==&gt; 3</span>
<span class="plain">**** ==&gt; 4</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. </b></p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">HTML::Documentation::extension_documentation_example</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">int</span><span class="plain"> *</span><span class="identifier">asterisks</span><span class="plain">, </span><span class="identifier">wording</span><span class="plain"> *</span><span class="identifier">egn</span><span class="plain">, </span><span class="identifier">wording</span><span class="plain"> *</span><span class="identifier">egr</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::length</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">) &gt; 10) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">; </span> <span class="comment">not enough space: this runs into the end-of-file padding</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">extension</span><span class="plain">-</span><span class="identifier">example</span><span class="plain">-</span><span class="identifier">header</span><span class="plain">&gt;(</span><span class="identifier">W</span><span class="plain">)) {</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">NW</span><span class="plain"> = </span><span class="identifier">GET_RW</span><span class="plain">(&lt;</span><span class="identifier">extension</span><span class="plain">-</span><span class="identifier">example</span><span class="plain">-</span><span class="identifier">header</span><span class="plain">&gt;, 1);</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">RW</span><span class="plain"> = </span><span class="identifier">Wordings::first_word</span><span class="plain">(</span><span class="identifier">GET_RW</span><span class="plain">(&lt;</span><span class="identifier">extension</span><span class="plain">-</span><span class="identifier">example</span><span class="plain">-</span><span class="identifier">header</span><span class="plain">&gt;, 2));</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">r2</span><span class="plain"> = </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">RW</span><span class="plain">);</span>
<span class="reserved">while</span><span class="plain"> ((</span><span class="identifier">r2</span><span class="plain"> &lt;= </span><span class="identifier">Wordings::last_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) &amp;&amp; ((</span><span class="identifier">Lexer::word</span><span class="plain">(</span><span class="identifier">r2</span><span class="plain">) == </span><span class="identifier">PARBREAK_V</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">)) </span><span class="identifier">r2</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">r2</span><span class="plain"> &gt;= </span><span class="identifier">Wordings::last_wn</span><span class="plain">(</span><span class="identifier">W</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="identifier">r2</span><span class="plain">--;</span>
<span class="comment">a successful match has now been made</span>
<span class="plain">*</span><span class="identifier">asterisks</span><span class="plain"> = &lt;&lt;</span><span class="identifier">r</span><span class="plain">&gt;&gt;; *</span><span class="identifier">egn</span><span class="plain"> = </span><span class="identifier">NW</span><span class="plain">; *</span><span class="identifier">egr</span><span class="plain"> = </span><span class="identifier">RW</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="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function HTML::Documentation::extension_documentation_example is used in <a href="#SP7">&#167;7</a>, <a href="#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. The table of contents. </b>The user sees chapters as A subheadings, numbered upwards from 1, and
sees sections as B subheadings, numbered from 1 within each chapter.
It is legal to have only A subheadings; only B subheadings; or a mixture
of the two.
</p>
<p class="inwebparagraph">If a scan can find any headings at all then we will wish to typeset
a table of contents up front. The following routine looks for what material
might go into a TOC, and sets one if it finds anything: otherwise, it sets
nothing and has no effect. Because of the compulsory paragraph break
following the divider line in the extension, we can safely assume that
every headng will follow a paragraph break word, even one right at the
top of the extension's documentation.
</p>
<p class="inwebparagraph">(Examples are included in the table of contents only if they occur after
the first heading, which I think is reasonable enough: there can be at most
26 per extension, enabling them to be lettered as Example A to Example Z.)
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">HTML::Documentation::set_table_of_contents</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">OUTPUT_STREAM</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">base_leafname</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">heading_count</span><span class="plain"> = 0, </span><span class="identifier">chapter_count</span><span class="plain"> = 0, </span><span class="identifier">section_count</span><span class="plain"> = 0, </span><span class="identifier">example_count</span><span class="plain"> = 0;</span>
<span class="identifier">LOOP_THROUGH_WORDING</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">edhl</span><span class="plain">, </span><span class="identifier">asterisks</span><span class="plain">;</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">NW</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">, </span><span class="identifier">RUBW</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Lexer::word</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">) == </span><span class="identifier">PARBREAK_V</span><span class="plain">) { </span> <span class="comment">the lexer records this to mean a paragraph break</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">Lexer::word</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">) == </span><span class="identifier">PARBREAK_V</span><span class="plain">) </span><span class="identifier">i</span><span class="plain">++; </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">&gt;</span><span class="identifier">Wordings::last_wn</span><span class="plain">(</span><span class="identifier">W</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="functiontext">HTML::Documentation::extension_documentation_heading</span><span class="plain">(</span><span class="identifier">Wordings::from</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">), &amp;</span><span class="identifier">edhl</span><span class="plain">, &amp;</span><span class="identifier">NW</span><span class="plain">)) {</span>
<span class="identifier">heading_count</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">heading_count</span><span class="plain"> == 1) {</span>
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">);</span>
<span class="identifier">HTML_TAG</span><span class="plain">(</span><span class="string">"hr"</span><span class="plain">); </span> <span class="comment">ruled line at top of TOC</span>
<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="reserved">if</span><span class="plain"> (</span><span class="identifier">edhl</span><span class="plain"> == 1) {</span>
<span class="identifier">chapter_count</span><span class="plain">++; </span><span class="identifier">section_count</span><span class="plain"> = 0;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">chapter_count</span><span class="plain"> &gt; 1) </span><span class="identifier">HTML_TAG</span><span class="plain">(</span><span class="string">"br"</span><span class="plain">); </span> <span class="comment">skip a line between chapters in TOC</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">edhl</span><span class="plain"> == 2) </span><span class="identifier">section_count</span><span class="plain">++;</span>
&lt;<span class="cwebmacro">Typeset the table of contents entry for this heading</span> <span class="cwebmacronumber">7.1</span>&gt;<span class="plain">;</span>
<span class="identifier">i</span><span class="plain"> = </span><span class="identifier">Wordings::last_wn</span><span class="plain">(</span><span class="identifier">NW</span><span class="plain">); </span><span class="reserved">continue</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">heading_count</span><span class="plain"> &gt; 0) &amp;&amp; (</span><span class="identifier">example_count</span><span class="plain"> &lt; 26) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">HTML::Documentation::extension_documentation_example</span><span class="plain">(</span>
<span class="identifier">Wordings::from</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">), &amp;</span><span class="identifier">asterisks</span><span class="plain">, &amp;</span><span class="identifier">NW</span><span class="plain">, &amp;</span><span class="identifier">RUBW</span><span class="plain">))) {</span>
<span class="reserved">if</span><span class="plain"> (++</span><span class="identifier">example_count</span><span class="plain"> == 1) {</span>
<span class="identifier">HTML_TAG</span><span class="plain">(</span><span class="string">"br"</span><span class="plain">);</span>
<span class="identifier">HTML_OPEN</span><span class="plain">(</span><span class="string">"b"</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"Examples"</span><span class="plain">);</span>
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"b"</span><span class="plain">);</span>
<span class="identifier">HTML_TAG</span><span class="plain">(</span><span class="string">"br"</span><span class="plain">);</span>
<span class="plain">}</span>
&lt;<span class="cwebmacro">Typeset the table of contents entry for this example</span> <span class="cwebmacronumber">7.2</span>&gt;<span class="plain">;</span>
<span class="identifier">i</span><span class="plain"> = </span><span class="identifier">Wordings::last_wn</span><span class="plain">(</span><span class="identifier">RUBW</span><span class="plain">); </span><span class="reserved">continue</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">heading_count</span><span class="plain"> &gt; 0) {</span>
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">);</span>
<span class="identifier">HTML_TAG</span><span class="plain">(</span><span class="string">"hr"</span><span class="plain">); </span> <span class="comment">ruled line at foot of TOC, if there is one</span>
<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="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function HTML::Documentation::set_table_of_contents appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP7_1"></a><b>&#167;7.1. </b>Internally, we are numbering all headings independently upwards from 1, and
we set anchor points in the documentation called <code class="display"><span class="extract">#docsec1</span></code>, <code class="display"><span class="extract">#docsec2</span></code>,
and so on: some of these will be chapter headings, some section headings.
These are the destinations of links from heading lines in the TOC.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Typeset the table of contents entry for this heading</span> <span class="cwebmacronumber">7.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">edhl</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> 1:</span>
<span class="identifier">HTML_OPEN</span><span class="plain">(</span><span class="string">"b"</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">"style=\</span><span class="plain">"</span><span class="string">text-decoration: none\</span><span class="plain">"</span><span class="string"> href=#docsec%d"</span><span class="plain">, </span><span class="identifier">heading_count</span><span class="plain">);</span>
<span class="identifier">HTML::begin_colour</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"000000"</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"Chapter %d: "</span><span class="plain">, </span><span class="identifier">chapter_count</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">HTML_CLOSE</span><span class="plain">(</span><span class="string">"a"</span><span class="plain">);</span>
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"b"</span><span class="plain">);</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> 2:</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">chapter_count</span><span class="plain"> &gt; 0) </span> <span class="comment">if there are chapters as well as sections...</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&amp;nbsp;&amp;nbsp;&amp;nbsp;"</span><span class="plain">); </span> <span class="comment">...then set an indentation before entry</span>
<span class="identifier">HTML_OPEN_WITH</span><span class="plain">(</span><span class="string">"a"</span><span class="plain">, </span><span class="string">"style=\</span><span class="plain">"</span><span class="string">text-decoration: none\</span><span class="plain">"</span><span class="string"> href=#docsec%d"</span><span class="plain">, </span><span class="identifier">heading_count</span><span class="plain">);</span>
<span class="identifier">HTML::begin_colour</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"000000"</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"Section "</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">chapter_count</span><span class="plain"> &gt; 0) </span> <span class="comment">if there are chapters as well as sections...</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%d.%d: "</span><span class="plain">, </span><span class="identifier">chapter_count</span><span class="plain">, </span><span class="identifier">section_count</span><span class="plain">); </span> <span class="comment">quote in form S.C</span>
<span class="reserved">else</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%d: "</span><span class="plain">, </span><span class="identifier">section_count</span><span class="plain">); </span> <span class="comment">otherwise quote section number only</span>
<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="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">"unable to set this heading level in extension TOC"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="functiontext">HTML::Documentation::set_body_text</span><span class="plain">(</span><span class="identifier">NW</span><span class="plain">, </span><span class="identifier">OUT</span><span class="plain">, </span><span class="constant">EDOC_FRAGMENT_ONLY</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="identifier">HTML_TAG</span><span class="plain">(</span><span class="string">"br"</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP7">&#167;7</a>.</p>
<p class="inwebparagraph"><a id="SP7_2"></a><b>&#167;7.2. </b>The TOC entries for examples are similar. Here the link is to the variant
page in the current family which has the given example open, and moreover,
to the anchor in that page corresponding to the top of the example: thus as
far as the user is concerned it opens the example and goes there.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Typeset the table of contents entry for this example</span> <span class="cwebmacronumber">7.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&amp;nbsp;&amp;nbsp;&amp;nbsp;"</span><span class="plain">); </span> <span class="comment">always indent TOC entries for examples</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">link</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">link</span><span class="plain">, </span><span class="string">"style=\</span><span class="plain">"</span><span class="string">text-decoration: none\</span><span class="plain">"</span><span class="string"> href=\</span><span class="plain">"</span><span class="string">"</span><span class="plain">);</span>
<span class="functiontext">HTML::Documentation::href_of_example</span><span class="plain">(</span><span class="identifier">link</span><span class="plain">, </span><span class="identifier">base_leafname</span><span class="plain">, </span><span class="identifier">example_count</span><span class="plain">, </span><span class="identifier">example_count</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">link</span><span class="plain">, </span><span class="string">"\</span><span class="plain">"</span><span class="string">"</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">"%S"</span><span class="plain">, </span><span class="identifier">link</span><span class="plain">);</span>
<span class="identifier">HTML::begin_colour</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"000000"</span><span class="plain">);</span>
<span class="identifier">PUT</span><span class="plain">(</span><span class="character">'A'</span><span class="plain">+</span><span class="identifier">example_count</span><span class="plain">-1); </span> <span class="comment">the letter A to Z</span>
<span class="functiontext">HTML::Documentation::set_body_text</span><span class="plain">(</span><span class="identifier">NW</span><span class="plain">, </span><span class="identifier">OUT</span><span class="plain">, </span><span class="constant">EDOC_FRAGMENT_ONLY</span><span class="plain">, </span><span class="identifier">NULL</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">HTML_CLOSE</span><span class="plain">(</span><span class="string">"a"</span><span class="plain">);</span>
<span class="identifier">HTML_TAG</span><span class="plain">(</span><span class="string">"br"</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP7">&#167;7</a>.</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. </b></p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">table</span><span class="plain">-</span><span class="identifier">sentence</span><span class="plain">&gt; ::=</span>
<span class="plain">&lt;</span><span class="reserved">if</span><span class="plain">-</span><span class="identifier">start</span><span class="plain">-</span><span class="identifier">of</span><span class="plain">-</span><span class="identifier">paragraph</span><span class="plain">&gt; </span><span class="identifier">table</span><span class="plain"> ...</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. Setting the body text. </b></p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">EDOC_ALL_EXAMPLES_CLOSED</span><span class="plain"> -1 </span> <span class="comment">do not change this without also changing Extensions</span>
<span class="definitionkeyword">define</span> <span class="constant">EDOC_FRAGMENT_ONLY</span><span class="plain"> -2 </span> <span class="comment">must differ from this and from all example variant numbers</span>
</pre>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">HTML::Documentation::set_body_text</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">OUTPUT_STREAM</span><span class="plain">,</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">example_which_is_open</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">base_leafname</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">heading_count</span><span class="plain"> = 0, </span><span class="identifier">chapter_count</span><span class="plain"> = 0, </span><span class="identifier">section_count</span><span class="plain"> = 0, </span><span class="identifier">example_count</span><span class="plain"> = 0;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">mid_example</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="identifier">skipping_text_of_an_example</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">,</span>
<span class="identifier">start_table_next_line</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="identifier">mid_I7_table</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="identifier">row_of_table_is_empty</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">,</span>
<span class="identifier">mid_displayed_source_text</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="identifier">indentation</span><span class="plain"> = 0, </span><span class="identifier">close_I6_position</span><span class="plain"> = -1;</span>
<span class="identifier">HTML_OPEN</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">);</span>
<span class="identifier">LOOP_THROUGH_WORDING</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">edhl</span><span class="plain">, </span><span class="identifier">asterisks</span><span class="plain">;</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">NW</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">, </span><span class="identifier">RUBW</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Lexer::word</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">) == </span><span class="identifier">PARBREAK_V</span><span class="plain">) { </span> <span class="comment">the lexer records this to mean a paragraph break</span>
&lt;<span class="cwebmacro">Handle a paragraph break</span> <span class="cwebmacronumber">9.1</span>&gt;<span class="plain">;</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">Lexer::word</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">) == </span><span class="identifier">PARBREAK_V</span><span class="plain">) </span><span class="identifier">i</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">&gt;</span><span class="identifier">Wordings::last_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) </span><span class="reserved">break</span><span class="plain">; </span> <span class="comment">treat multiple paragraph breaks as one</span>
&lt;<span class="cwebmacro">Determine indentation of new paragraph</span> <span class="cwebmacronumber">9.2</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">HTML::Documentation::extension_documentation_heading</span><span class="plain">(</span><span class="identifier">Wordings::from</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">), &amp;</span><span class="identifier">edhl</span><span class="plain">, &amp;</span><span class="identifier">NW</span><span class="plain">)) {</span>
<span class="identifier">heading_count</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">edhl</span><span class="plain"> == 1) {</span>
<span class="identifier">chapter_count</span><span class="plain">++; </span><span class="identifier">section_count</span><span class="plain"> = 0;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">chapter_count</span><span class="plain"> &gt; 1) {</span>
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">);</span>
<span class="identifier">HTML_TAG</span><span class="plain">(</span><span class="string">"hr"</span><span class="plain">); </span> <span class="comment">rule a line between chapters</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">edhl</span><span class="plain"> == 2) </span><span class="identifier">section_count</span><span class="plain">++;</span>
&lt;<span class="cwebmacro">Typeset the heading of this chapter or section</span> <span class="cwebmacronumber">9.6</span>&gt;<span class="plain">;</span>
<span class="identifier">i</span><span class="plain"> = </span><span class="identifier">Wordings::last_wn</span><span class="plain">(</span><span class="identifier">NW</span><span class="plain">); </span><span class="reserved">continue</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">example_count</span><span class="plain"> &lt; 26) &amp;&amp; (</span><span class="functiontext">HTML::Documentation::extension_documentation_example</span><span class="plain">(</span>
<span class="identifier">Wordings::from</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">), &amp;</span><span class="identifier">asterisks</span><span class="plain">, &amp;</span><span class="identifier">NW</span><span class="plain">, &amp;</span><span class="identifier">RUBW</span><span class="plain">))) {</span>
<span class="identifier">skipping_text_of_an_example</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">mid_example</span><span class="plain">) </span>&lt;<span class="cwebmacro">Close the previous example's text</span> <span class="cwebmacronumber">9.9</span>&gt;<span class="character">;</span>
<span class="identifier">mid_example</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">example_count</span><span class="plain">++;</span>
&lt;<span class="cwebmacro">Typeset the heading of this example</span> <span class="cwebmacronumber">9.7</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">example_count</span><span class="plain"> == </span><span class="identifier">example_which_is_open</span><span class="plain">) {</span>
&lt;<span class="cwebmacro">Open the new example's text</span> <span class="cwebmacronumber">9.8</span>&gt;<span class="character">;</span>
<span class="identifier">mid_example</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">skipping_text_of_an_example</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">i</span><span class="plain"> = </span><span class="identifier">Wordings::last_wn</span><span class="plain">(</span><span class="identifier">RUBW</span><span class="plain">); </span><span class="reserved">continue</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">skipping_text_of_an_example</span><span class="plain">) </span><span class="reserved">continue</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Handle a line or column break, if there is one</span> <span class="cwebmacronumber">9.4</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Transcribe an ordinary word of the documentation</span> <span class="cwebmacronumber">9.5</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">close_I6_position</span><span class="plain"> == </span><span class="identifier">i</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" -)"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">mid_example</span><span class="plain">) </span>&lt;<span class="cwebmacro">Close the previous example's text</span> <span class="cwebmacronumber">9.9</span>&gt;<span class="character">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">example_which_is_open</span><span class="plain"> != </span><span class="constant">EDOC_FRAGMENT_ONLY</span><span class="plain">) </span>&lt;<span class="cwebmacro">Handle a paragraph break</span> <span class="cwebmacronumber">9.1</span>&gt;<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="reserved">return</span><span class="plain"> </span><span class="identifier">example_count</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function HTML::Documentation::set_body_text is used in <a href="#SP7_1">&#167;7.1</a>, <a href="#SP7_2">&#167;7.2</a>, <a href="#SP9_6">&#167;9.6</a>, <a href="#SP9_7">&#167;9.7</a>.</p>
<p class="inwebparagraph"><a id="SP9_1"></a><b>&#167;9.1. Typesetting the standard matter. </b>A paragraph break might mean the end of displayed matter (and if so, then also
the end of any table being displayed). Otherwise, it just means a paragraph
break, and a chance to restore our tired variables.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Handle a paragraph break</span> <span class="cwebmacronumber">9.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">mid_displayed_source_text</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="reserved">if</span><span class="plain"> (</span><span class="identifier">mid_I7_table</span><span class="plain">) </span>&lt;<span class="cwebmacro">End I7 table in extension documentation</span> <span class="cwebmacronumber">9.1.1</span>&gt;<span class="plain">;</span>
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"blockquote"</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</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="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="identifier">HTML_OPEN</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">);</span>
<span class="identifier">mid_displayed_source_text</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">; </span><span class="identifier">mid_I7_table</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9">&#167;9</a> (twice).</p>
<p class="inwebparagraph"><a id="SP9_2"></a><b>&#167;9.2. </b>The indentation setting is made here because a tab anywhere else does
not mean a paragraph has been indented. Here <code class="display"><span class="extract">i</span></code> is at the number of the
first word after the paragraph break; the break character corresponding
to it is the one before that word, so describes the kind of whitespace
between the paragraph break and the first nonwhitespace of the new
paragraph.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Determine indentation of new paragraph</span> <span class="cwebmacronumber">9.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">indentation</span><span class="plain"> = 0; </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Lexer::break_before</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">) == </span><span class="character">'\</span><span class="plain">t</span><span class="character">'</span><span class="plain">) </span><span class="identifier">indentation</span><span class="plain"> = 1;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP9_3"></a><b>&#167;9.3. </b>Positions for paste icons in extension documentation are marked with
asterisk and colon:
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">extension</span><span class="plain">-</span><span class="identifier">documentation</span><span class="plain">-</span><span class="identifier">paste</span><span class="plain">-</span><span class="identifier">marker</span><span class="plain">&gt; ::=</span>
<span class="plain">* : ...</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP9_4"></a><b>&#167;9.4. </b>Two lower-level sorts of breaks can also occur in the middle of a paragraph:
line breaks, indicated by newlines plus some tabs, and column breaks inside
I7 source tables, indicated by tabs. We have to deal with those before we
can move on to the subsequent word.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Handle a line or column break, if there is one</span> <span class="cwebmacronumber">9.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Lexer::indentation_level</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">) &gt; 0) </span><span class="identifier">indentation</span><span class="plain"> = </span><span class="identifier">Lexer::indentation_level</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indentation</span><span class="plain"> &gt; 0) </span>&lt;<span class="cwebmacro">Handle the start of a line which is indented</span> <span class="cwebmacronumber">9.4.2</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">extension</span><span class="plain">-</span><span class="identifier">documentation</span><span class="plain">-</span><span class="identifier">paste</span><span class="plain">-</span><span class="identifier">marker</span><span class="plain">&gt;(</span><span class="identifier">Wordings::from</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">i</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">GET_RW</span><span class="plain">(&lt;</span><span class="identifier">extension</span><span class="plain">-</span><span class="identifier">documentation</span><span class="plain">-</span><span class="identifier">paste</span><span class="plain">-</span><span class="identifier">marker</span><span class="plain">&gt;, 1);</span>
&lt;<span class="cwebmacro">Incorporate an icon linking to a Javascript function to paste the text which follows</span> <span class="cwebmacronumber">9.4.1</span>&gt;<span class="plain">;</span>
<span class="identifier">i</span><span class="plain">++; </span><span class="reserved">continue</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">indentation</span><span class="plain"> = 0;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">mid_I7_table</span><span class="plain">) &amp;&amp; ((</span><span class="identifier">Lexer::break_before</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">) == </span><span class="character">'\</span><span class="plain">t</span><span class="character">'</span><span class="plain">) || (</span><span class="identifier">Lexer::indentation_level</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">) == 1))) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">row_of_table_is_empty</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">)</span>
&lt;<span class="cwebmacro">End table cell for I7 table in extension documentation</span> <span class="cwebmacronumber">9.4.3</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Begin table cell for I7 table in extension documentation</span> <span class="cwebmacronumber">9.4.4</span>&gt;<span class="plain">;</span>
<span class="identifier">row_of_table_is_empty</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">This code is used in <a href="#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP9_5"></a><b>&#167;9.5. </b>See Javascript Pastes for further explanation of the general method here.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Transcribe an ordinary word of the documentation</span> <span class="cwebmacronumber">9.5</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">wchar_t</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain"> = </span><span class="identifier">Lexer::word_raw_text</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">); </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">j</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">i</span><span class="plain">&gt;</span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">))</span>
<span class="plain">&amp;&amp; ((</span><span class="identifier">p</span><span class="plain">[1] != 0) || (</span><span class="identifier">Lexer::is_punctuation</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">[0]) == </span><span class="identifier">FALSE</span><span class="plain">)</span>
<span class="plain">|| (</span><span class="identifier">p</span><span class="plain">[0] == </span><span class="character">'('</span><span class="plain">) || (</span><span class="identifier">p</span><span class="plain">[0] == </span><span class="character">'{'</span><span class="plain">) || (</span><span class="identifier">p</span><span class="plain">[0] == </span><span class="character">'}'</span><span class="plain">))</span>
<span class="plain">&amp;&amp; (</span><span class="identifier">compare_word</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">-1, </span><span class="identifier">OPENBRACKET_V</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">" "</span><span class="plain">); </span> <span class="comment">restore normal spacing around punctuation</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">=0; </span><span class="identifier">p</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">]; </span><span class="identifier">j</span><span class="plain">++) </span><span class="functiontext">HTMLFiles::char_out</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">]); </span> <span class="comment">set the actual word</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Lexer::word</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">) == </span><span class="identifier">OPENI6_V</span><span class="plain">) </span><span class="identifier">close_I6_position</span><span class="plain"> = </span><span class="identifier">i</span><span class="plain">+1; </span> <span class="comment">ensure I6 literals are closed</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP9_4_1"></a><b>&#167;9.4.1. </b>A paste causes the same material to be set twice: once in the argument to
the Javascript paste function (which is passed to the application when the
user clicks on the paste icon, and thus ends up in the Source panel), and
once also in the HTML documentation. That's why the code here ranges forward
to see how far it should go (to the next paragraph break which is not followed
by further tabbed matter, or in other words, to the end of the display),
but does not advance <code class="display"><span class="extract">i</span></code> commensurately.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Incorporate an icon linking to a Javascript function to paste the text which follows</span> <span class="cwebmacronumber">9.4.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">x</span><span class="plain"> = </span><span class="identifier">i</span><span class="plain">+2, </span><span class="identifier">y</span><span class="plain"> = </span><span class="identifier">Wordings::last_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">), </span><span class="identifier">j</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">=</span><span class="identifier">x</span><span class="plain">; </span><span class="identifier">j</span><span class="plain">&lt;=</span><span class="identifier">y</span><span class="plain">; </span><span class="identifier">j</span><span class="plain">++) </span> <span class="comment">first find the end of the quoted passage</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Lexer::word</span><span class="plain">(</span><span class="identifier">j</span><span class="plain">) == </span><span class="identifier">PARBREAK_V</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">possible_end</span><span class="plain"> = </span><span class="identifier">j</span><span class="plain">-1;</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">Lexer::word</span><span class="plain">(</span><span class="identifier">j</span><span class="plain">) == </span><span class="identifier">PARBREAK_V</span><span class="plain">) </span><span class="identifier">j</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">j</span><span class="plain">&lt;</span><span class="identifier">y</span><span class="plain">) &amp;&amp; ((</span><span class="identifier">Lexer::break_before</span><span class="plain">(</span><span class="identifier">j</span><span class="plain">) == </span><span class="character">'\</span><span class="plain">t</span><span class="character">'</span><span class="plain">) || (</span><span class="identifier">Lexer::indentation_level</span><span class="plain">(</span><span class="identifier">j</span><span class="plain">) &gt; 0))) </span><span class="reserved">continue</span><span class="plain">;</span>
<span class="identifier">y</span><span class="plain"> = </span><span class="identifier">possible_end</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="functiontext">HTML::Javascript::paste_W</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">Wordings::new</span><span class="plain">(</span><span class="identifier">x</span><span class="plain">, </span><span class="identifier">y</span><span class="plain">));</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9_4">&#167;9.4</a>.</p>
<p class="inwebparagraph"><a id="SP9_4_2"></a><b>&#167;9.4.2. </b>The first step of indentation is handled using the <code class="display"><span class="extract">&lt;blockquote&gt;</span></code> tag;
within that, further tab stops are simulated by printing a row of four
non-breaking spaces for each indentation level above 1. A paragraph
of indented (i.e., display matter) beginning with the word "Table" is
taken to be an I7 table, and we remember that the next line break will
take us past the titling line and into the table entries, which we will
need to achieve with an HTML <code class="display"><span class="extract">&lt;table&gt;</span></code>.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Handle the start of a line which is indented</span> <span class="cwebmacronumber">9.4.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">j</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">mid_displayed_source_text</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">start_table_next_line</span><span class="plain">) {</span>
<span class="identifier">start_table_next_line</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">mid_I7_table</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Begin I7 table in extension documentation</span> <span class="cwebmacronumber">9.4.2.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">mid_I7_table</span><span class="plain">) </span>&lt;<span class="cwebmacro">Begin new row of I7 table in extension documentation</span> <span class="cwebmacronumber">9.4.2.2</span>&gt;
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">HTML_TAG</span><span class="plain">(</span><span class="string">"br"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">mid_I7_table</span><span class="plain">) </span><span class="identifier">row_of_table_is_empty</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">HTML_OPEN</span><span class="plain">(</span><span class="string">"blockquote"</span><span class="plain">);</span>
<span class="identifier">HTML::begin_colour</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"000080"</span><span class="plain">);</span>
<span class="identifier">mid_displayed_source_text</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">table</span><span class="plain">-</span><span class="identifier">sentence</span><span class="plain">&gt;(</span><span class="identifier">Wordings::from</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">)))</span>
<span class="identifier">start_table_next_line</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">indentation</span><span class="plain">--;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">=0; </span><span class="identifier">j</span><span class="plain">&lt;</span><span class="identifier">indentation</span><span class="plain">; </span><span class="identifier">j</span><span class="plain">++) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9_4">&#167;9.4</a>.</p>
<p class="inwebparagraph"><a id="SP9_6"></a><b>&#167;9.6. Typesetting the headings. </b>That is thankfully all for the tormented logic of all those changes of state:
from here to the rest of the section, all we do is to generate pretty HTML,
and without altering any variables or causing any side-effects at all.
First, the headings. Recall that heading number <code class="display"><span class="extract">N</span></code> is required to be at
anchor <code class="display"><span class="extract">#docsecN</span></code>.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Typeset the heading of this chapter or section</span> <span class="cwebmacronumber">9.6</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">HTML_OPEN</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">);</span>
<span class="identifier">HTML_TAG_WITH</span><span class="plain">(</span><span class="string">"a"</span><span class="plain">, </span><span class="string">"name=docsec%d"</span><span class="plain">, </span><span class="identifier">heading_count</span><span class="plain">);</span>
<span class="identifier">HTML_OPEN</span><span class="plain">(</span><span class="string">"b"</span><span class="plain">);</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">edhl</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> 1:</span>
<span class="identifier">HTML::begin_colour</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"800000"</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"Chapter %d: "</span><span class="plain">, </span><span class="identifier">chapter_count</span><span class="plain">);</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> 2:</span>
<span class="identifier">HTML::begin_colour</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"000000"</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"Section "</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">chapter_count</span><span class="plain"> &gt; 0) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%d."</span><span class="plain">, </span><span class="identifier">chapter_count</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">section_count</span><span class="plain">);</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="functiontext">HTML::Documentation::set_body_text</span><span class="plain">(</span><span class="identifier">NW</span><span class="plain">, </span><span class="identifier">OUT</span><span class="plain">, </span><span class="constant">EDOC_FRAGMENT_ONLY</span><span class="plain">, </span><span class="identifier">NULL</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">HTML_CLOSE</span><span class="plain">(</span><span class="string">"b"</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP9_7"></a><b>&#167;9.7. </b>An example is set with a two-table header, and followed optionally by a
table of its inset copy, shaded to distinguish it from the rest of the
page. The heading is constructed with a main table of one row of two cells,
in the following section. The left-hand cell then contains a further table,
in the next section.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Typeset the heading of this example</span> <span class="cwebmacronumber">9.7</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">HTML_OPEN</span><span class="plain">(</span><span class="string">"hr"</span><span class="plain">); </span> <span class="comment">rule a line before the example heading</span>
<span class="identifier">HTML_OPEN</span><span class="plain">(</span><span class="string">"p"</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">"name=eg%d"</span><span class="plain">, </span><span class="identifier">example_count</span><span class="plain">); </span> <span class="comment">provide the anchor point</span>
<span class="identifier">HTML::begin_plain_html_table</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
<span class="identifier">HTML_OPEN</span><span class="plain">(</span><span class="string">"tr"</span><span class="plain">);</span>
<span class="comment">Left hand cell: the oval icon</span>
<span class="identifier">HTML_OPEN_WITH</span><span class="plain">(</span><span class="string">"td"</span><span class="plain">, </span><span class="string">"halign=\</span><span class="plain">"</span><span class="string">left\</span><span class="plain">"</span><span class="string"> valign=\</span><span class="plain">"</span><span class="string">top\</span><span class="plain">"</span><span class="string"> cellpadding=0 cellspacing=0 width=38px"</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Typeset the lettered oval example icon</span> <span class="cwebmacronumber">9.7.1</span>&gt;<span class="plain">;</span>
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"td"</span><span class="plain">);</span>
<span class="comment">Right hand cell: the asterisks and title, with rubric underneath</span>
<span class="identifier">HTML_OPEN_WITH</span><span class="plain">(</span><span class="string">"td"</span><span class="plain">, </span><span class="string">"cellpadding=0 cellspacing=0 halign=\</span><span class="plain">"</span><span class="string">left\</span><span class="plain">"</span><span class="string"> valign=\</span><span class="plain">"</span><span class="string">top\</span><span class="plain">"</span><span class="string">"</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Incorporate link to the example opened up</span> <span class="cwebmacronumber">9.7.2</span>&gt;<span class="plain">;</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">asterisks</span><span class="plain">-- &gt; 0)</span>
<span class="identifier">HTML_TAG_WITH</span><span class="plain">(</span><span class="string">"img"</span><span class="plain">, </span><span class="string">"border=\</span><span class="plain">"</span><span class="string">0\</span><span class="plain">"</span><span class="string"> src='inform:/doc_images/asterisk.png'"</span><span class="plain">);</span>
<span class="identifier">HTML_OPEN</span><span class="plain">(</span><span class="string">"b"</span><span class="plain">);</span>
<span class="identifier">HTML::begin_colour</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"505050"</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&amp;nbsp;Example&amp;nbsp;"</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">HTML::begin_colour</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"000000"</span><span class="plain">);</span>
<span class="functiontext">HTML::Documentation::set_body_text</span><span class="plain">(</span><span class="identifier">NW</span><span class="plain">, </span><span class="identifier">OUT</span><span class="plain">, </span><span class="constant">EDOC_FRAGMENT_ONLY</span><span class="plain">, </span><span class="identifier">base_leafname</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">HTML_CLOSE</span><span class="plain">(</span><span class="string">"b"</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="comment">end the textual link</span>
<span class="identifier">HTML_TAG</span><span class="plain">(</span><span class="string">"br"</span><span class="plain">);</span>
<span class="functiontext">HTML::Documentation::set_body_text</span><span class="plain">(</span><span class="identifier">RUBW</span><span class="plain">, </span><span class="identifier">OUT</span><span class="plain">, </span><span class="constant">EDOC_FRAGMENT_ONLY</span><span class="plain">, </span><span class="identifier">base_leafname</span><span class="plain">);</span>
<span class="identifier">HTML_OPEN</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">);</span>
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"td"</span><span class="plain">);</span>
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"tr"</span><span class="plain">);</span>
<span class="identifier">HTML::end_html_table</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
<span class="identifier">HTML_OPEN</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP9_7_1"></a><b>&#167;9.7.1. </b>The little oval icon with its superimposed boldface letter is much harder to
get right on all browsers than it looks, and the following is the result of
some pretty grim experimentation. Basically, we make a tight, borderless,
one-cell-in-one-row table, use CSS to make a transparent PNG image of an oval
the background image for the table, then put a boldface letter in the centre
of its one and only cell. (Things were even worse when IE6 for Windows still
had its infamous PNG transparency bug.)
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Typeset the lettered oval example icon</span> <span class="cwebmacronumber">9.7.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">HTML::begin_plain_html_table</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
<span class="identifier">HTML_OPEN_WITH</span><span class="plain">(</span><span class="string">"tr"</span><span class="plain">, </span><span class="string">"class=\</span><span class="plain">"</span><span class="string">oval\</span><span class="plain">"</span><span class="string">"</span><span class="plain">);</span>
<span class="identifier">HTML_OPEN_WITH</span><span class="plain">(</span><span class="string">"td"</span><span class="plain">, </span><span class="string">"width=38px height=30px align=\</span><span class="plain">"</span><span class="string">left\</span><span class="plain">"</span><span class="string"> valign=\</span><span class="plain">"</span><span class="string">center\</span><span class="plain">"</span><span class="string">"</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Incorporate link to the example opened up</span> <span class="cwebmacronumber">9.7.2</span>&gt;<span class="plain">;</span>
<span class="identifier">HTML_OPEN_WITH</span><span class="plain">(</span><span class="string">"div"</span><span class="plain">,</span>
<span class="string">"class=\</span><span class="plain">"</span><span class="string">paragraph Body\</span><span class="plain">"</span><span class="string"> style=\</span><span class="plain">"</span><span class="string">line-height: 1px; margin-bottom: 0px; "</span>
<span class="string">"margin-top: 0px; padding-bottom: 0pt; padding-top: 0px; text-align: center; "</span>
<span class="string">"color: #202020; font-size: 14px; line-height: 1px;\</span><span class="plain">"</span><span class="string">"</span><span class="plain">);</span>
<span class="identifier">HTML_OPEN</span><span class="plain">(</span><span class="string">"b"</span><span class="plain">);</span>
<span class="identifier">PUT</span><span class="plain">(</span><span class="character">'A'</span><span class="plain"> + </span><span class="identifier">example_count</span><span class="plain"> - 1);</span>
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"b"</span><span class="plain">);</span>
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"div"</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="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"td"</span><span class="plain">);</span>
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"tr"</span><span class="plain">);</span>
<span class="identifier">HTML::end_html_table</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9_7">&#167;9.7</a>.</p>
<p class="inwebparagraph"><a id="SP9_7_2"></a><b>&#167;9.7.2. </b>Clicking on the example banner opens it up, if it's currently closed, or
closes it up, if it's currently open.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Incorporate link to the example opened up</span> <span class="cwebmacronumber">9.7.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">url</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">url</span><span class="plain">, </span><span class="string">"href=\</span><span class="plain">"</span><span class="string">"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">example_count</span><span class="plain"> == </span><span class="identifier">example_which_is_open</span><span class="plain">) </span> <span class="comment">this example currently open</span>
<span class="functiontext">HTML::Documentation::href_of_example</span><span class="plain">(</span><span class="identifier">url</span><span class="plain">, </span><span class="identifier">base_leafname</span><span class="plain">, </span><span class="constant">EDOC_ALL_EXAMPLES_CLOSED</span><span class="plain">, </span><span class="identifier">example_count</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span> <span class="comment">this example not yet open</span>
<span class="functiontext">HTML::Documentation::href_of_example</span><span class="plain">(</span><span class="identifier">url</span><span class="plain">, </span><span class="identifier">base_leafname</span><span class="plain">, </span><span class="identifier">example_count</span><span class="plain">, </span><span class="identifier">example_count</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">url</span><span class="plain">, </span><span class="string">"\</span><span class="plain">"</span><span class="string"> 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">HTML_OPEN_WITH</span><span class="plain">(</span><span class="string">"a"</span><span class="plain">, </span><span class="string">"%S"</span><span class="plain">, </span><span class="identifier">url</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">url</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9_7">&#167;9.7</a>, <a href="#SP9_7_1">&#167;9.7.1</a>.</p>
<p class="inwebparagraph"><a id="SP9_4_2_1"></a><b>&#167;9.4.2.1. Typesetting I7 tables in displayed source text. </b>Unsurprisingly, I7 tables are set (after their titling lines) as HTML tables,
and this is fiddly but elementary in the usual way of HTML tables:
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Begin I7 table in extension documentation</span> <span class="cwebmacronumber">9.4.2.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">HTML::end_colour</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
<span class="identifier">HTML_TAG</span><span class="plain">(</span><span class="string">"br"</span><span class="plain">);</span>
<span class="identifier">HTML::begin_plain_html_table</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
<span class="identifier">HTML::first_html_column</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, 0);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9_4_2">&#167;9.4.2</a>.</p>
<p class="inwebparagraph"><a id="SP9_4_3"></a><b>&#167;9.4.3. </b>Drinka.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">End table cell for I7 table in extension documentation</span> <span class="cwebmacronumber">9.4.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">HTML::end_colour</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
<span class="identifier">HTML::next_html_column</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, 0);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9_4">&#167;9.4</a>.</p>
<p class="inwebparagraph"><a id="SP9_4_4"></a><b>&#167;9.4.4. </b>Pinta.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Begin table cell for I7 table in extension documentation</span> <span class="cwebmacronumber">9.4.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">HTML::begin_colour</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"000080"</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9_4">&#167;9.4</a>.</p>
<p class="inwebparagraph"><a id="SP9_4_2_2"></a><b>&#167;9.4.2.2. </b>Milka.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Begin new row of I7 table in extension documentation</span> <span class="cwebmacronumber">9.4.2.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">HTML::end_html_row</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
<span class="identifier">HTML::first_html_column</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, 0);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9_4_2">&#167;9.4.2</a>.</p>
<p class="inwebparagraph"><a id="SP9_1_1"></a><b>&#167;9.1.1. </b>Day.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">End I7 table in extension documentation</span> <span class="cwebmacronumber">9.1.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">HTML::end_html_row</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
<span class="identifier">HTML::end_html_table</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9_1">&#167;9.1</a>.</p>
<p class="inwebparagraph"><a id="SP9_8"></a><b>&#167;9.8. Typesetting the body of an example. </b>This is done just the way all other extension documentation material is
handled, except that it is inside an inset box: which is provided by
a shaded HTML table, containing just one row, which contains just one
cell. Here the inset table begins:
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Open the new example's text</span> <span class="cwebmacronumber">9.8</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">HTML::begin_html_table</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="string">"#f0f0f0"</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">, 0, 0, 0, 0, 0);</span>
<span class="identifier">HTML::first_html_column</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, 0);</span>
<span class="identifier">HTML_OPEN</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP9_9"></a><b>&#167;9.9. </b>And here the inset table ends:
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Close the previous example's text</span> <span class="cwebmacronumber">9.9</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">HTML::end_html_row</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
<span class="identifier">HTML::end_html_table</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
<span class="identifier">HTML_OPEN</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9">&#167;9</a> (twice).</p>
<hr class="tocbar">
<ul class="toc"><li><a href="2-jp.html">Back to 'Javascript Pastes'</a></li><li><i>(This section ends Chapter 2: HTML.)</i></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>

401
docs/html-module/2-hf.html Normal file
View file

@ -0,0 +1,401 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>1/im</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<!--Weave of '2/hf' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">html</a></li><li><a href="index.html#2">Chapter 2: HTML</a></li><li><b>HTML Files</b></li></ul><p class="purpose">To provide utilities for writing HTML files such as the problems report, the extension documentation, the index files and so forth.</p>
<ul class="toc"><li><a href="#SP2">&#167;2. The "inform:" URL scheme</a></li><li><a href="#SP3">&#167;3. The "source:" URL scheme</a></li><li><a href="#SP4">&#167;4. Icons with and without tooltips</a></li><li><a href="#SP5">&#167;5. Outcome images</a></li><li><a href="#SP6">&#167;6. Header and footer</a></li><li><a href="#SP7">&#167;7. HTML paragraphs with indentation</a></li><li><a href="#SP8">&#167;8. Writing HTML characters</a></li><li><a href="#SP9">&#167;9. Writing streams in XML-escaped form</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. </b>Inform documentation &mdash; its HTML text and the images, etc., used within
it &mdash; is stored in two areas: "built-in" and "external". The built-in
area is expected to be within the Inform 7 application itself. For
instance, on OS X, this is at:
</p>
<p class="inwebparagraph"><code class="display"><span class="extract">...wherever.../Inform.app/Contents/Resources/</span></code> and/or
</p>
<p class="inwebparagraph"><code class="display"><span class="extract">...wherever.../Inform.app/Contents/Resources/English.lproj/</span></code>
</p>
<p class="inwebparagraph">(The duplication is a complication to do with localisation which we
can ignore here.) The material stored in this built-in area is fixed: the
Inform application needs to work even if stored on a read-only disc, or
where the user has insufficient permissions to alter it. NI itself neither
reads from, nor writes to, any file in the built-in documentation area.
</p>
<p class="inwebparagraph">Documentation for the installed extensions does, however, change: it is
written by NI as and when necessary. This is the material making up the
"external" area, and it needs to be somewhere which the user certainly
has the necessary permissions to write to. For instance:
</p>
<p class="inwebparagraph"><code class="display"><span class="extract">~/Library/Inform/Documentation/</span></code> (OS X)
</p>
<p class="inwebparagraph"><code class="display"><span class="extract">My Documents\Inform\Documentation\| (Windows)
</span></code></p>
<p class="inwebparagraph">Pages in these two areas, built-in and external, need to link to each other by
links: in addition, pages in the external area need access to images stored in
the built-in area.
</p>
<p class="inwebparagraph">The other HTML files written by NI are stored within the relevant
project's bundle: these are the report of Problems (if any) and the
Index. They, too, need access to images stored in the built-in area.
</p>
<p class="inwebparagraph">The problem we face is that these three mini-websites &mdash; the built-in
documentation, the external documentation, and the project-specific
pages &mdash; are written by tools which cannot know the correct file URLs.
(For instance, it would not even help for the application to tell NI
where the built-in area is: because the HTML written by NI would then
cease to work if the user moved the application elsewhere in the
filing system after NI had run.)
</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. The "inform:" URL scheme. </b>We solve this by requiring that the Inform 7 application must support
a new URL scheme.
</p>
<p class="inwebparagraph"></p>
<ul class="items"><li>(a) <code class="display"><span class="extract">&lt;inform://...&gt;</span></code> is interpreted as a file in the built-in documentation
area, except that
</li></ul>
<ul class="items"><li>(b) <code class="display"><span class="extract">&lt;inform://Extensions/...whatever...&gt;</span></code> should be fetched by first
checking for "...whatever..." in the external area, and then &mdash; if
that fails &mdash; also checking for "...whatever..." in the <code class="display"><span class="extract">ExtnDocs</span></code>
subfolder of the built-in area.
</li></ul>
<p class="inwebparagraph">For instance, Inform 7 for OS X would look for <code class="display"><span class="extract">inform://Extensions/magic.png</span></code>
at the following locations:
</p>
<p class="inwebparagraph"></p>
<ul class="items"><li>(i) <code class="display"><span class="extract">~/Library/Inform/Documentation/magic.png</span></code>
</li></ul>
<ul class="items"><li>(ii) <code class="display"><span class="extract">.../Inform.app/Contents/Resources/ExtnDocs/magic.png</span></code>
</li></ul>
<p class="inwebparagraph">If no file was found in either place, the link should simply do nothing:
the application is required not to produce a 404 error page, or to
blank out the page currently showing.
</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. The "source:" URL scheme. </b>The other non-standard Inform URL scheme is "source:", which is used
for a link which, when clicked, opens the Source panel with the given
line made visible.
</p>
<p class="inwebparagraph">For instance, line 21 of file <code class="display"><span class="extract">Bits and Pieces/marbles.txt</span></code> has URL
</p>
<p class="inwebparagraph"><code class="display"><span class="extract">source:Bits and Pieces/marbles.txt#line14</span></code>
</p>
<p class="inwebparagraph">Filenames are given relative to the current project bundle. However, if only
a leafname is supplied, then this is read as a file within the <code class="display"><span class="extract">Source</span></code>
subfolder of the project bundle. (Thus it is not possible to have a
source link to a source file at the root of the project bundle: but this is
no loss, since source is not allowed to be kept there.) For instance,
line 14 of file <code class="display"><span class="extract">Source/story.ni</span></code> has URL
</p>
<p class="inwebparagraph"><code class="display"><span class="extract">source:story.ni#line14</span></code>
</p>
<p class="inwebparagraph">The following routine writes the clickable source-reference icon, and
is the only place in NI where "source:" is used.
</p>
<p class="inwebparagraph">Source which is generated internally to NI cannot be opened in the Source
panel, for obvious reasons, so we produce nothing if the location is internal.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">source_link_case</span><span class="plain"> = 0;</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">HTMLFiles::set_source_link_case</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="identifier">source_link_case</span><span class="plain"> = </span><span class="identifier">Characters::toupper</span><span class="plain">(</span><span class="identifier">Str::get_first_char</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">));</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">HTMLFiles::html_source_link</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="identifier">source_location</span><span class="plain"> </span><span class="identifier">sl</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">nonbreaking_space</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sl</span><span class="plain">.</span><span class="identifier">file_of_origin</span><span class="plain">) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">fn</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">fn</span><span class="plain">, </span><span class="string">"%f"</span><span class="plain">, </span><span class="identifier">TextFromFiles::get_filename</span><span class="plain">(</span><span class="identifier">sl</span><span class="plain">.</span><span class="identifier">file_of_origin</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Projects::path</span><span class="plain">(</span><span class="identifier">Inbuild::project</span><span class="plain">())) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">pp</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">pp</span><span class="plain">, </span><span class="string">"%p"</span><span class="plain">, </span><span class="identifier">Projects::path</span><span class="plain">(</span><span class="identifier">Inbuild::project</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">Str::len</span><span class="plain">(</span><span class="identifier">pp</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::prefix_eq</span><span class="plain">(</span><span class="identifier">fn</span><span class="plain">, </span><span class="identifier">pp</span><span class="plain">, </span><span class="identifier">N</span><span class="plain">))</span>
<span class="identifier">Str::delete_n_characters</span><span class="plain">(</span><span class="identifier">fn</span><span class="plain">, </span><span class="identifier">N</span><span class="plain">+1);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">pp</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Str::begins_with_wide_string</span><span class="plain">(</span><span class="identifier">fn</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"Source"</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">Str::get_at</span><span class="plain">(</span><span class="identifier">fn</span><span class="plain">, 6) == </span><span class="identifier">FOLDER_SEPARATOR</span><span class="plain">))</span>
<span class="identifier">Str::delete_n_characters</span><span class="plain">(</span><span class="identifier">fn</span><span class="plain">, 7);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">nonbreaking_space</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&amp;nbsp;"</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">" "</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">source_link_case</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=\</span><span class="plain">"</span><span class="string">source:%S?case=%c#line%d\</span><span class="plain">"</span><span class="string">"</span><span class="plain">, </span><span class="identifier">fn</span><span class="plain">, </span><span class="identifier">source_link_case</span><span class="plain">, </span><span class="identifier">sl</span><span class="plain">.</span><span class="identifier">line_number</span><span class="plain">)</span>
<span class="reserved">else</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=\</span><span class="plain">"</span><span class="string">source:%S#line%d\</span><span class="plain">"</span><span class="string">"</span><span class="plain">, </span><span class="identifier">fn</span><span class="plain">, </span><span class="identifier">sl</span><span class="plain">.</span><span class="identifier">line_number</span><span class="plain">);</span>
<span class="identifier">HTML_TAG_WITH</span><span class="plain">(</span><span class="string">"img"</span><span class="plain">, </span><span class="string">"border=0 src=inform:/doc_images/Reveal.png"</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="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">fn</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function HTMLFiles::set_source_link_case appears nowhere else.</p>
<p class="endnote">The function HTMLFiles::html_source_link is used in <a href="#SP8">&#167;8</a>.</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. Icons with and without tooltips. </b>Tooltips are the evanescent pop-up windows which appear, a little behind the
mouse arrow, when it is poised waiting over the icon. (We make heavy use of
these in the World index, for instance, to clarify what abbreviations mean.)
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">HTMLFiles::html_icon_with_tooltip</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">icon_name</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">tip</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">tip2</span><span class="plain">) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">img</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">img</span><span class="plain">, </span><span class="string">"border=0 src=inform:/doc_images/%s "</span><span class="plain">, </span><span class="identifier">icon_name</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">tip</span><span class="plain">) {</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">img</span><span class="plain">, </span><span class="string">"title=\</span><span class="plain">"</span><span class="string">%s"</span><span class="plain">, </span><span class="identifier">tip</span><span class="plain">); </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">tip2</span><span class="plain">) </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">img</span><span class="plain">, </span><span class="string">" %s"</span><span class="plain">, </span><span class="identifier">tip2</span><span class="plain">); </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">img</span><span class="plain">, </span><span class="string">"\</span><span class="plain">"</span><span class="string">"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">HTML_TAG_WITH</span><span class="plain">(</span><span class="string">"img"</span><span class="plain">, </span><span class="string">"%S"</span><span class="plain">, </span><span class="identifier">img</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">img</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function HTMLFiles::html_icon_with_tooltip is used in <a href="#SP8">&#167;8</a>.</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. Outcome images. </b>These are the two images used on the Problems page to visually indicate
success or failure. We also use special images on special occasions.
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">CENTRED_OUTCOME_IMAGE_STYLE</span><span class="plain"> 1</span>
<span class="definitionkeyword">define</span> <span class="constant">SIDE_OUTCOME_IMAGE_STYLE</span><span class="plain"> 2</span>
</pre>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">outcome_image_style</span><span class="plain"> = </span><span class="constant">SIDE_OUTCOME_IMAGE_STYLE</span><span class="plain">;</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">HTMLFiles::html_outcome_image</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">image</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">verdict</span><span class="plain">) {</span>
<span class="reserved">char</span><span class="plain"> *</span><span class="identifier">vn</span><span class="plain"> = </span><span class="string">""</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">be_festive</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">CORE_MODULE</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">internal_error_thrown</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="identifier">be_festive</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">be_festive</span><span class="plain">) {</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">Time::feast</span><span class="plain">()) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">CHRISTMAS_FEAST</span><span class="plain">: </span><span class="identifier">vn</span><span class="plain"> = </span><span class="string">"_2"</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">EASTER_FEAST</span><span class="plain">: </span><span class="identifier">vn</span><span class="plain"> = </span><span class="string">"_3"</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">vn</span><span class="plain">[0]) </span><span class="identifier">outcome_image_style</span><span class="plain"> = </span><span class="constant">CENTRED_OUTCOME_IMAGE_STYLE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">PROBLEMS_MODULE</span>
<span class="identifier">Problems::Issue::issue_problems_banner</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">verdict</span><span class="plain">);</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">outcome_image_style</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">CENTRED_OUTCOME_IMAGE_STYLE</span><span class="plain">:</span>
<span class="identifier">HTML_OPEN</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">);</span>
<span class="identifier">HTML_OPEN</span><span class="plain">(</span><span class="string">"center"</span><span class="plain">);</span>
<span class="identifier">HTML_TAG_WITH</span><span class="plain">(</span><span class="string">"img"</span><span class="plain">, </span><span class="string">"src=inform:/outcome_images/%s%s.png border=0"</span><span class="plain">, </span><span class="identifier">image</span><span class="plain">, </span><span class="identifier">vn</span><span class="plain">);</span>
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"center"</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="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">SIDE_OUTCOME_IMAGE_STYLE</span><span class="plain">:</span>
<span class="identifier">HTML::begin_html_table</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">, 0, 4, 0, 0, 0);</span>
<span class="identifier">HTML::first_html_column</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, 110);</span>
<span class="identifier">HTML_TAG_WITH</span><span class="plain">(</span><span class="string">"img"</span><span class="plain">,</span>
<span class="string">"src=inform:/outcome_images/%s%s@2x.png border=1 width=100 height=100"</span><span class="plain">, </span><span class="identifier">image</span><span class="plain">, </span><span class="identifier">vn</span><span class="plain">);</span>
<span class="identifier">HTML::next_html_column</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, 0);</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">HTML::comment</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"HEADNOTE"</span><span class="plain">);</span>
<span class="identifier">HTML_OPEN_WITH</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">, </span><span class="string">"style=\</span><span class="plain">"</span><span class="string">margin-top:0;\</span><span class="plain">"</span><span class="string">"</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"(Each time &lt;b&gt;Go&lt;/b&gt; or &lt;b&gt;Replay&lt;/b&gt; is clicked, Inform tries to "</span>
<span class="string">"translate the source text into a working story, and updates this report.)"</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="identifier">HTML::comment</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"PROBLEMS BEGIN"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">HTMLFiles::outcome_image_tail</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">outcome_image_style</span><span class="plain"> == </span><span class="constant">SIDE_OUTCOME_IMAGE_STYLE</span><span class="plain">) {</span>
<span class="identifier">HTML::comment</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"PROBLEMS END"</span><span class="plain">);</span>
<span class="identifier">HTML::end_html_row</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
<span class="identifier">HTML::end_html_table</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
<span class="identifier">HTML::comment</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"FOOTNOTE"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function HTMLFiles::html_outcome_image appears nowhere else.</p>
<p class="endnote">The function HTMLFiles::outcome_image_tail appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. Header and footer. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">HTMLFiles::html_header</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">title</span><span class="plain">) {</span>
<span class="identifier">HTML::declare_as_HTML</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="identifier">HTML::begin_head</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="identifier">HTML::incorporate_CSS</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">,</span>
<span class="identifier">Inbuild::file_from_installation</span><span class="plain">(</span><span class="identifier">CSS_FOR_STANDARD_PAGES_IRES</span><span class="plain">));</span>
<span class="identifier">HTML::incorporate_javascript</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">,</span>
<span class="identifier">Inbuild::file_from_installation</span><span class="plain">(</span><span class="identifier">JAVASCRIPT_FOR_STANDARD_PAGES_IRES</span><span class="plain">));</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">INDEX_MODULE</span>
<span class="identifier">Index::scripting</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="identifier">HTML::end_head</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
<span class="identifier">HTML::begin_body</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="identifier">HTML::comment</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"CONTENT BEGINS"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">HTMLFiles::html_footer</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</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="identifier">HTML::comment</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"CONTENT ENDS"</span><span class="plain">);</span>
<span class="identifier">HTML::end_body</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function HTMLFiles::html_header appears nowhere else.</p>
<p class="endnote">The function HTMLFiles::html_footer appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. HTML paragraphs with indentation. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">HTMLFiles::open_para</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">depth</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">class</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">margin</span><span class="plain"> = </span><span class="identifier">depth</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">margin</span><span class="plain"> &lt; 1) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"minimal HTML indentation is 1"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">margin</span><span class="plain"> &gt; 9) </span><span class="identifier">margin</span><span class="plain"> = 9;</span>
<span class="identifier">HTML_OPEN_WITH</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">, </span><span class="string">"class=\</span><span class="plain">"</span><span class="string">%sin%d\</span><span class="plain">"</span><span class="string">"</span><span class="plain">, </span><span class="identifier">class</span><span class="plain">, </span><span class="identifier">margin</span><span class="plain">);</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">depth</span><span class="plain"> &gt; 9) { </span><span class="identifier">depth</span><span class="plain">--; </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"</span><span class="plain">); }</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function HTMLFiles::open_para appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. Writing HTML characters. </b>The following routine is a low-level filter which takes ISO Latin-1
characters one at a time, feeding them out to the given stream with any
unsafe characters converted to suitable HTML elements. (The stream writer
will transcode to UTF-8 encoding, since all HTML file streams written by
Inform are declared as having the UTF-8 character encoding.)
</p>
<p class="inwebparagraph">Recall that a source reference is fed into <code class="display"><span class="extract">HTMLFiles::char_out</span></code> as the
following stream of characters:
</p>
<p class="inwebparagraph"><code class="display"><span class="extract">*source text*Source/story.ni*14*</span></code>
</p>
<p class="inwebparagraph">(with <code class="display"><span class="extract">SOURCE_REF_CHAR</span></code> used in place of the asterisk).
</p>
<p class="inwebparagraph">When we notice the trigger character, we cease to output HTML and instead
buffer up the reference until we reach the terminating trigger character:
we then parse a little, tidy up and send it to <code class="display"><span class="extract">HTMLFiles::html_source_link</span></code> to be
turned into a <code class="display"><span class="extract">source:</span></code> link.
</p>
<pre class="display">
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">source_ref_fields</span><span class="plain">[3] = { </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain"> }; </span> <span class="comment">paraphrase, filename, line</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">source_ref_field</span><span class="plain"> = -1; </span> <span class="comment">which field we are buffering</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">HTMLFiles::char_out</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">charcode</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">source_ref_field</span><span class="plain"> &gt;= 0) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">source_ref_fields</span><span class="plain">[</span><span class="identifier">source_ref_field</span><span class="plain">] == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">source_ref_fields</span><span class="plain">[</span><span class="identifier">source_ref_field</span><span class="plain">] = </span><span class="identifier">Str::new</span><span class="plain">();</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">PROBLEMS_MODULE</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">charcode</span><span class="plain"> != </span><span class="identifier">SOURCE_REF_CHAR</span><span class="plain">) { </span><span class="identifier">PUT_TO</span><span class="plain">(</span><span class="identifier">source_ref_fields</span><span class="plain">[</span><span class="identifier">source_ref_field</span><span class="plain">], </span><span class="identifier">charcode</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">; }</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="plain">#</span><span class="identifier">ifndef</span><span class="plain"> </span><span class="identifier">PROBLEMS_MODULE</span>
<span class="identifier">PUT_TO</span><span class="plain">(</span><span class="identifier">source_ref_fields</span><span class="plain">[</span><span class="identifier">source_ref_field</span><span class="plain">], </span><span class="identifier">charcode</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="plain">}</span>
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">charcode</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="character">'"'</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&amp;quot;"</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="character">'&lt;'</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&amp;lt;"</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="character">'&gt;'</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&amp;gt;"</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="character">'&amp;'</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&amp;amp;"</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">NEWLINE_IN_STRING</span><span class="plain">: </span><span class="identifier">HTML_TAG</span><span class="plain">(</span><span class="string">"br"</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">PROBLEMS_MODULE</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">FORCE_NEW_PARA_CHAR</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="identifier">HTML_OPEN_WITH</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">, </span><span class="string">"class=\</span><span class="plain">"</span><span class="string">in2\</span><span class="plain">"</span><span class="string">"</span><span class="plain">);</span>
<span class="functiontext">HTMLFiles::html_icon_with_tooltip</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="string">"ornament_flower.png"</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&amp;nbsp;"</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">SOURCE_REF_CHAR</span><span class="plain">:</span>
<span class="identifier">source_ref_field</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">source_ref_field</span><span class="plain"> == 3) {</span>
<span class="identifier">source_ref_field</span><span class="plain"> = -1;</span>
<span class="identifier">source_location</span><span class="plain"> </span><span class="identifier">sl</span><span class="plain">;</span>
<span class="identifier">sl</span><span class="plain">.</span><span class="identifier">file_of_origin</span><span class="plain"> = </span><span class="identifier">TextFromFiles::filename_to_source_file</span><span class="plain">(</span><span class="identifier">source_ref_fields</span><span class="plain">[1]);</span>
<span class="identifier">sl</span><span class="plain">.</span><span class="identifier">line_number</span><span class="plain"> = </span><span class="identifier">Str::atoi</span><span class="plain">(</span><span class="identifier">source_ref_fields</span><span class="plain">[2], 0);</span>
<span class="functiontext">HTMLFiles::html_source_link</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">sl</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">Str::clear</span><span class="plain">(</span><span class="identifier">source_ref_fields</span><span class="plain">[</span><span class="identifier">source_ref_field</span><span class="plain">]);</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="reserved">default</span><span class="plain">:</span>
<span class="identifier">PUT</span><span class="plain">(</span><span class="identifier">charcode</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function HTMLFiles::char_out is used in 2/hd (<a href="2-hd.html#SP9_5">&#167;9.5</a>).</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. Writing streams in XML-escaped form. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">HTMLFiles::write_xml_safe_text</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">txt</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">txt</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">switch</span><span class="plain">(</span><span class="identifier">c</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="character">'&amp;'</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&amp;amp;"</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="character">'&lt;'</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&amp;lt;"</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="character">'&gt;'</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&amp;gt;"</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">PUT</span><span class="plain">(</span><span class="identifier">c</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function HTMLFiles::write_xml_safe_text appears nowhere else.</p>
<hr class="tocbar">
<ul class="toc"><li><i>(This section begins Chapter 2: HTML.)</i></li><li><a href="2-jp.html">Continue with 'Javascript Pastes'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>

387
docs/html-module/2-jp.html Normal file
View file

@ -0,0 +1,387 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>2/hf</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<!--Weave of '2/jp' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">html</a></li><li><a href="index.html#2">Chapter 2: HTML</a></li><li><b>Javascript Pastes</b></li></ul><p class="purpose">To write valid HTML for a paste icon which, when clicked, calls a Javascript function which will paste Inform source text into the Source panel of the application.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Definitions</a></li><li><a href="#SP7">&#167;7. Individual characters</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Definitions. </b></p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>The application is required to provide a Javascript function to copy text
into the source window. Broadly speaking, the application needs to support
Javascript in the following form:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">var myProject = external.Project;</span>
<span class="plain">myProject.selectView('source');</span>
<span class="plain">myProject.pasteCode('Trying Taking Manhattan');</span>
</pre>
<p class="inwebparagraph">This for Windows: for OS X, the same code but <code class="display"><span class="extract">window.Project</span></code> rather
than <code class="display"><span class="extract">external.Project</span></code>.
</p>
<p class="inwebparagraph">As this implies, the details unfortunately differ on different platforms:
</p>
<ul class="items"><li>(a) Model 1 - paste in OS X style, directly within the HREF of a link.
</li><li>(b) Model 2 - paste in Windows style, defining a function and calling that.
</li></ul>
<p class="inwebparagraph">In model 2 we define a Javascript function for each individual paste
because this protects against long paste texts overflowing what Windows
considers the maximum permitted length of a link: the WebKit rendering
engine in OS X has no such limit, apparently. This means that for Windows
we define numerous copies of the Javascript code above. In model 1, we
never need to compile fresh Javascript functions because the template file
<code class="display"><span class="extract">ExtensionFileModel.html</span></code> for OS X contains a definition of the single
Javascript function:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">&lt;script language="JavaScript"&gt;</span>
<span class="plain">function pasteCode(code) {</span>
<span class="plain"> var myProject = project();</span>
<span class="plain"> myProject.selectView('source');</span>
<span class="plain"> myProject.pasteCode(code);</span>
<span class="plain">}</span>
<span class="plain">&lt;/script&gt;</span>
</pre>
<p class="inwebparagraph">and we can simply call <code class="display"><span class="extract">href="javascript:pasteCode(...)"</span></code> from any link.
</p>
<p class="inwebparagraph">The text pasted may in some cases be quite long (say, 5K or more) and the
code below should work whatever its length. It will of course be UTF-8 encoded,
since all HTML produced by NI is.
</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>We have found that different Javascript implementations handle escape
characters in quoted text differently. (For instance, some allow a
double-quote <code class="display"><span class="extract">"</span></code> to appear as a literal in single-quoted text, others
require <code class="display"><span class="extract">&amp;quot;</span></code> to be used, others still do not recognise HTML entities
like <code class="display"><span class="extract">&amp;quot;</span></code> and treat them as literal text.) To avoid these tiresome
platform dependencies a single new escape-character syntax was added in
November 2007. This puts obligations both on NI (and <code class="display"><span class="extract">indoc</span></code>, which also
generates HTML with Javascript pastes), to make use of the escape syntax,
and also on the application, to understand and act on it.
</p>
<p class="inwebparagraph">The application must implement <code class="display"><span class="extract">myProject.pasteCode(code)</span></code> such that every
instance of <code class="display"><span class="extract">[=0xHHHH=]</span></code> is replaced with the Unicode character whose
hexadecimal code is <code class="display"><span class="extract">HHHH</span></code>. There will always be four digits, with leading
zeros as needed, and <code class="display"><span class="extract">A</span></code> to <code class="display"><span class="extract">F</span></code> will be written in upper case. The only
Unicode characters with codes below <code class="display"><span class="extract">0x0020</span></code> which must be handled are
newline, <code class="display"><span class="extract">0x000A</span></code>, and tab, <code class="display"><span class="extract">0x0009</span></code>.
</p>
<p class="inwebparagraph">The generator (NI or <code class="display"><span class="extract">indoc</span></code>) must always escape every instance of the
following characters:
</p>
<p class="inwebparagraph"></p>
<ul class="items"><li>(a) every tab is escaped to <code class="display"><span class="extract">[=0x0009=]</span></code>;
</li><li>(b) every newline is escaped to <code class="display"><span class="extract">[=0x000A=]</span></code>;
</li><li>(c) every double quotation mark is escaped to <code class="display"><span class="extract">[=0x0022=]</span></code>;
</li><li>(d) every ampersand is escaped to <code class="display"><span class="extract">[=0x0026=]</span></code>;
</li><li>(e) every single quotation mark is escaped to <code class="display"><span class="extract">[=0x0027=]</span></code>;
</li><li>(f) every less than sign is escaped to <code class="display"><span class="extract">[=0x003C=]</span></code>;
</li><li>(g) every greater than sign is escaped to <code class="display"><span class="extract">[=0x003E=]</span></code>;
</li><li>(h) every backslash is escaped to <code class="display"><span class="extract">[=0x005C=]</span></code>.
</li></ul>
<p class="inwebparagraph">It may also choose to escape other character codes, as it prefers. Other
characters are generated as literal UTF-8. In no case will any character
with code below <code class="display"><span class="extract">0x0020</span></code> be passed as a literal.
</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>At the top level, the form of link used depends on the Javascript model.
Note that model 0 results in no material at all being output. The actual
text to be passed is all set via <code class="display"><span class="extract">HTML::Javascript::javascript_string_out</span></code> below, and which
does not depend on the model.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">javascript_fn_counter</span><span class="plain"> = 1000;</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">HTML::Javascript::paste_W</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</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="functiontext">HTML::Javascript::paste_inner</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">), </span><span class="identifier">Wordings::last_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">), </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">HTML::Javascript::paste_stream</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">alt_stream</span><span class="plain">) {</span>
<span class="functiontext">HTML::Javascript::paste_inner</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, -1, -1, </span><span class="identifier">alt_stream</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">HTML::Javascript::paste_inner</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">from</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">to</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">alt_stream</span><span class="plain">) {</span>
<span class="plain">#</span><span class="identifier">ifndef</span><span class="plain"> </span><span class="identifier">WINDOWS_JAVASCRIPT</span><span class="plain"> </span> <span class="comment">OS X style, with long function arguments allowed in links</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">link</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">link</span><span class="plain">, </span><span class="string">"href=\</span><span class="plain">"</span><span class="string">javascript:pasteCode("</span><span class="plain">);</span>
<span class="functiontext">HTML::Javascript::javascript_string_out</span><span class="plain">(</span><span class="identifier">link</span><span class="plain">, </span><span class="identifier">from</span><span class="plain">, </span><span class="identifier">to</span><span class="plain">, </span><span class="identifier">alt_stream</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">link</span><span class="plain">, </span><span class="string">")\</span><span class="plain">"</span><span class="string">"</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">"%S"</span><span class="plain">, </span><span class="identifier">link</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">link</span><span class="plain">);</span>
<span class="identifier">HTML_TAG_WITH</span><span class="plain">(</span><span class="string">"img"</span><span class="plain">, </span><span class="string">"border=0 src=inform:/doc_images/paste.png"</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><span class="identifier">endif</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">WINDOWS_JAVASCRIPT</span><span class="plain"> </span> <span class="comment">Windows style, with long function arguments in links unreliable</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&lt;script language=\</span><span class="plain">"</span><span class="string">JavaScript\</span><span class="plain">"</span><span class="string">&gt;\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"function pasteCode%d(code) {\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">javascript_fn_counter</span><span class="plain">); </span><span class="identifier">INDENT</span><span class="plain">;</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"var myProject = project();\</span><span class="plain">n</span><span class="string">\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"myProject.selectView('source');\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"myProject.pasteCode("</span><span class="plain">);</span>
<span class="identifier">OUTDENT</span><span class="plain">; </span><span class="functiontext">HTML::Javascript::javascript_string_out</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">from</span><span class="plain">, </span><span class="identifier">to</span><span class="plain">, </span><span class="identifier">alt_stream</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="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="identifier">WRITE</span><span class="plain">(</span><span class="string">"&lt;/script&gt;\</span><span class="plain">n</span><span class="string">"</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=\</span><span class="plain">"</span><span class="string">javascript:pasteCode%d()\</span><span class="plain">"</span><span class="string">"</span><span class="plain">, </span><span class="identifier">javascript_fn_counter</span><span class="plain">++);</span>
<span class="identifier">HTML_TAG_WITH</span><span class="plain">(</span><span class="string">"img"</span><span class="plain">, </span><span class="string">"border=0 src=inform:/doc_images/paste.png"</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><span class="identifier">endif</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function HTML::Javascript::paste_W is used in 2/hd (<a href="2-hd.html#SP9_4_1">&#167;9.4.1</a>).</p>
<p class="endnote">The function HTML::Javascript::paste_stream appears nowhere else.</p>
<p class="endnote">The function HTML::Javascript::paste_inner appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b>Though the Javascript function is called <code class="display"><span class="extract">openFile</span></code>, it can equally well
compile a link to open a folder on the host filing system.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">HTML::Javascript::open_file</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</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">text_stream</span><span class="plain"> *</span><span class="identifier">leaf</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">contents</span><span class="plain">) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">fn</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">leaf</span><span class="plain">) </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">fn</span><span class="plain">, </span><span class="string">"%f"</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">leaf</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">fn</span><span class="plain">, </span><span class="string">"%p"</span><span class="plain">, </span><span class="identifier">P</span><span class="plain">);</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">WINDOWS_JAVASCRIPT</span>
<span class="identifier">LOOP_THROUGH_TEXT</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">, </span><span class="identifier">fn</span><span class="plain">) </span><span class="reserved">if</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="character">'\</span><span class="plain">\</span><span class="character">'</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="character">'/'</span><span class="plain">);</span>
<span class="plain">#</span><span class="identifier">endif</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='javascript:project().openFile(\</span><span class="plain">"</span><span class="string">%S\</span><span class="plain">"</span><span class="string">)'"</span><span class="plain">, </span><span class="identifier">fn</span><span class="plain">);</span>
<span class="identifier">HTML_TAG_WITH</span><span class="plain">(</span><span class="string">"img"</span><span class="plain">, </span><span class="string">"%s"</span><span class="plain">, </span><span class="identifier">contents</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="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">fn</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function HTML::Javascript::open_file appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. </b>In the following, the source of the text can be either a range of words
from the lexer (as for instance when a portion of an extension is being
typeset as documentation, with an example that can be pasted), or can
be a C string: if the latter, then its encoding must be ISO Latin-1.
The conversion to UTF-8 is performed in <code class="display"><span class="extract">HTML::Javascript::javascript_char_out</span></code> below.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">HTML::Javascript::javascript_string_out</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">from</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">to</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">alt_stream</span><span class="plain">) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"'"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">alt_stream</span><span class="plain">) </span>&lt;<span class="cwebmacro">Write stream as Javascript string</span> <span class="cwebmacronumber">6.1</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">from</span><span class="plain"> &gt;= 0) </span>&lt;<span class="cwebmacro">Write word range as Javascript string</span> <span class="cwebmacronumber">6.2</span>&gt;<span class="plain">;</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"'"</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function HTML::Javascript::javascript_string_out is used in <a href="#SP4">&#167;4</a>.</p>
<p class="inwebparagraph"><a id="SP6_1"></a><b>&#167;6.1. </b>The art of leadership is delegation.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Write stream as Javascript string</span> <span class="cwebmacronumber">6.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">LOOP_THROUGH_TEXT</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">, </span><span class="identifier">alt_stream</span><span class="plain">)</span>
<span class="functiontext">HTML::Javascript::javascript_char_out</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">Str::get</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">));</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP6">&#167;6</a>.</p>
<p class="inwebparagraph"><a id="SP6_2"></a><b>&#167;6.2. </b>Writing a word range is much harder. In effect, we have to provide an
inverse function for the lexer, which converted raw source text to nicely
packaged up words.
</p>
<p class="inwebparagraph">See Lexer for details of how words are stored, and in particular for the
<code class="display"><span class="extract">lw_break</span></code> character, which is <code class="display"><span class="extract">'\t'</span></code> when the word followed a tab, but is
<code class="display"><span class="extract">'1'</span></code> to <code class="display"><span class="extract">'9'</span></code> when it followed a newline plus that many tabs. We need
this because lexing has otherwise removed whitespace from the source, and
we need it back again if we're to paste a faithful Javascript representation:
otherwise the tabs used as column-dividers in tables will not come through,
for instance. Moreover, indentation from the left margin is used to make
prettier pastes (which respect the layout of the original examples from
which the paste has been made), and for that we need the <code class="display"><span class="extract">'1'</span></code> to <code class="display"><span class="extract">'9'</span></code>
possibilities.
</p>
<p class="inwebparagraph">Note that we expect the material pasted to be indented at 1 tab stop from
the margin already, because it will almost always be a source text within
an example, where any matter unindented will be commentary rather than
source text. Thus a single tab after a newline is not significant, and we
only need to supply extra Javascript tabs when the indentation is 2 tab
stops or more.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Write word range as Javascript string</span> <span class="cwebmacronumber">6.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">suppress_space</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="identifier">follows_paragraph_break</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">close_I6_position</span><span class="plain"> = -1;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=</span><span class="identifier">from</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">&lt;=</span><span class="identifier">to</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">j</span><span class="plain">;</span>
<span class="identifier">wchar_t</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain"> = </span><span class="identifier">Lexer::word_raw_text</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Lexer::word</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">) == </span><span class="identifier">PARBREAK_V</span><span class="plain">) { </span> <span class="comment">marker for a paragraph break</span>
<span class="functiontext">HTML::Javascript::javascript_char_out</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="character">'\</span><span class="plain">n</span><span class="character">'</span><span class="plain">);</span>
<span class="functiontext">HTML::Javascript::javascript_char_out</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="character">'\</span><span class="plain">n</span><span class="character">'</span><span class="plain">);</span>
<span class="identifier">suppress_space</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">follows_paragraph_break</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">Lexer::word</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">) == </span><span class="identifier">PARBREAK_V</span><span class="plain">) </span><span class="identifier">i</span><span class="plain">++; </span><span class="identifier">i</span><span class="plain">--; </span> <span class="comment">elide multiple breaks</span>
<span class="reserved">continue</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">indentation</span><span class="plain"> = </span><span class="identifier">Lexer::indentation_level</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">indentation</span><span class="plain"> &gt; 0) { </span> <span class="comment">number of tab stops of indentation on this para</span>
<span class="functiontext">HTML::Javascript::javascript_char_out</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="character">'\</span><span class="plain">n</span><span class="character">'</span><span class="plain">);</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">=0; </span><span class="identifier">j</span><span class="plain">&lt;</span><span class="identifier">indentation</span><span class="plain">-1; </span><span class="identifier">j</span><span class="plain">++) </span><span class="functiontext">HTML::Javascript::javascript_char_out</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="character">'\</span><span class="plain">t</span><span class="character">'</span><span class="plain">);</span>
<span class="identifier">suppress_space</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Lexer::break_before</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">) == </span><span class="character">'\</span><span class="plain">t</span><span class="character">'</span><span class="plain">) &amp;&amp; (</span><span class="identifier">follows_paragraph_break</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">)) {</span>
<span class="functiontext">HTML::Javascript::javascript_char_out</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="character">'\</span><span class="plain">t</span><span class="character">'</span><span class="plain">);</span>
<span class="identifier">suppress_space</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">follows_paragraph_break</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">suppress_space</span><span class="plain">==</span><span class="identifier">FALSE</span><span class="plain">)</span>
&lt;<span class="cwebmacro">Restore inter-word spaces unless this would be unnatural</span> <span class="cwebmacronumber">6.2.1</span>&gt;<span class="plain">;</span>
<span class="identifier">suppress_space</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">=0; </span><span class="identifier">p</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">]; </span><span class="identifier">j</span><span class="plain">++) </span><span class="functiontext">HTML::Javascript::javascript_char_out</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">]);</span>
&lt;<span class="cwebmacro">Insert a close-literal-I6 escape sequence if necessary</span> <span class="cwebmacronumber">6.2.2</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
<span class="functiontext">HTML::Javascript::javascript_char_out</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="character">'\</span><span class="plain">n</span><span class="character">'</span><span class="plain">);</span>
<span class="functiontext">HTML::Javascript::javascript_char_out</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="character">'\</span><span class="plain">n</span><span class="character">'</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP6">&#167;6</a>.</p>
<p class="inwebparagraph"><a id="SP6_2_1"></a><b>&#167;6.2.1. </b>The lexer also broke words around punctuation marks, so that, for instance,
"fish, finger" would have been lexed as <code class="display"><span class="extract">fish , finger</span></code> &mdash; three words.
But we want to restore the more natural spacing.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Restore inter-word spaces unless this would be unnatural</span> <span class="cwebmacronumber">6.2.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">i</span><span class="plain">&gt;</span><span class="identifier">from</span><span class="plain">)</span>
<span class="plain">&amp;&amp; ((</span><span class="identifier">p</span><span class="plain">[1] != 0) || (</span><span class="identifier">Lexer::is_punctuation</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">[0]) == </span><span class="identifier">FALSE</span><span class="plain">) ||</span>
<span class="plain">(</span><span class="identifier">p</span><span class="plain">[0] == </span><span class="character">'('</span><span class="plain">) || (</span><span class="identifier">p</span><span class="plain">[0] == </span><span class="character">'{'</span><span class="plain">) || (</span><span class="identifier">p</span><span class="plain">[0] == </span><span class="character">'}'</span><span class="plain">))</span>
<span class="plain">&amp;&amp; (</span><span class="identifier">compare_word</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">-1, </span><span class="identifier">OPENBRACKET_V</span><span class="plain">)==</span><span class="identifier">FALSE</span><span class="plain">))</span>
<span class="functiontext">HTML::Javascript::javascript_char_out</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="character">' '</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP6_2">&#167;6.2</a>.</p>
<p class="inwebparagraph"><a id="SP6_2_2"></a><b>&#167;6.2.2. </b>Finally, the lexer rendered a literal I6 inclusion in the form
</p>
<blockquote>
<p>(- self=2; -)</p>
</blockquote>
<p class="inwebparagraph">as a sequence of two lexical words: <code class="display"><span class="extract">(-</span></code> and then <code class="display"><span class="extract">self=2;</span></code>. In order
to paste back safely, we must supplement this with the closure "-)" once
again:
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Insert a close-literal-I6 escape sequence if necessary</span> <span class="cwebmacronumber">6.2.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Lexer::word</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">) == </span><span class="identifier">OPENI6_V</span><span class="plain">) </span><span class="identifier">close_I6_position</span><span class="plain"> = </span><span class="identifier">i</span><span class="plain">+1;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">close_I6_position</span><span class="plain"> == </span><span class="identifier">i</span><span class="plain">) {</span>
<span class="functiontext">HTML::Javascript::javascript_char_out</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="character">'-'</span><span class="plain">);</span>
<span class="functiontext">HTML::Javascript::javascript_char_out</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="character">')'</span><span class="plain">);</span>
<span class="functiontext">HTML::Javascript::javascript_char_out</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="character">' '</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP6_2">&#167;6.2</a>.</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. Individual characters. </b>Note that every character within the single quotes of a Javascript string
is produced through the following routine. It escapes certain awkward
characters, but need not convert from ISO Latin-1 to UTF-8 since that will
happen automatically downstream of us when the output is written as a
UTF-8 encoded HTML file.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">HTML::Javascript::javascript_char_out</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">c</span><span class="plain">) {</span>
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">c</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="character">'\</span><span class="plain">t</span><span class="character">'</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"[=0x0009=]"</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="character">'\</span><span class="plain">n</span><span class="character">'</span><span class="plain">: </span><span class="reserved">case</span><span class="plain"> </span><span class="identifier">NEWLINE_IN_STRING</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"[=0x000A=]"</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="character">'"'</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"[=0x0022=]"</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="character">'&amp;'</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"[=0x0026=]"</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="character">'\</span><span class="plain">'</span><span class="character">'</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"[=0x0027=]"</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="character">'&lt;'</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"[=0x003C=]"</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="character">'&gt;'</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"[=0x003E=]"</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="character">'\</span><span class="plain">\</span><span class="character">'</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"[=0x005C=]"</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">;</span>
<span class="reserved">default</span><span class="plain">: </span><span class="identifier">PUT</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="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function HTML::Javascript::javascript_char_out is used in <a href="#SP6_1">&#167;6.1</a>, <a href="#SP6_2">&#167;6.2</a>, <a href="#SP6_2_1">&#167;6.2.1</a>, <a href="#SP6_2_2">&#167;6.2.2</a>.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="2-hf.html">Back to 'HTML Files'</a></li><li><a href="2-hd.html">Continue with 'HTML Documentation'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>

BIN
docs/html-module/crumbs.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View file

@ -0,0 +1,47 @@
<html>
<head>
<title>html </title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><b>html </b></li></ul>
<p class="purpose">HTML and Javascript generation tools.</p>
<hr>
<ul class="chapterlist">
<li>
<p><a name="1"></a><spon class="chaptertitle">Chapter 1: Starting Up</span></p>
<p><span class="purpose"></span></p>
<ul class="sectionlist">
<li>
<p><a href="1-im.html"><spon class="sectiontitle">Index Module</span></a> -
<span class="purpose">Setting up the use of this module.</span></p>
</li>
</ul>
</li>
<li>
<p><a name="2"></a><spon class="chaptertitle">Chapter 2: HTML</span></p>
<p><span class="purpose">HTML and JavaScript generation.</span></p>
<ul class="sectionlist">
<li>
<p><a href="2-hf.html"><spon class="sectiontitle">HTML Files</span></a> -
<span class="purpose">To provide utilities for writing HTML files such as the problems report, the extension documentation, the index files and so forth.</span></p>
</li>
<li>
<p><a href="2-jp.html"><spon class="sectiontitle">Javascript Pastes</span></a> -
<span class="purpose">To write valid HTML for a paste icon which, when clicked, calls a Javascript function which will paste Inform source text into the Source panel of the application.</span></p>
</li>
<li>
<p><a href="2-hd.html"><spon class="sectiontitle">HTML Documentation</span></a> -
<span class="purpose">To translate a passage of source text into HTML-format documentation, for use in the automatically generated documentation pages on each installed extension.</span></p>
</li>
</ul>
</li>
</ul>
<hr>
</body>
</html>

288
docs/html-module/inweb.css Normal file
View file

@ -0,0 +1,288 @@
/* This is a CSS file for pages woven by the literate programming tool inweb */
/* We'll start with syntax colouring, since everyone likes to toy with this: */
.cwebmacrotext { color: #000000; font-weight: bold; } /* The name of a web macro */
.functiontext { color: #C00000; } /* When a C function is being defined */
.string { color: #408040; } /* A double-quoted C literal string */
.character { color: #204020; } /* A single-quoted C literal character */
.constant { color: #204020; } /* A named constant */
.element { color: #40407f; } /* A C structure element */
.identifier { color: #4040ff; } /* An identifier */
.reserved { color: #600000; } /* A reserved word */
/* Comments at the end of lines are rendered like so: */
.comment {
font: "Lucida Grande", "Lucida Sans Unicode", Helvetica, Arial, Verdana, sans-serif;
color: #404040;
font-style:italic;
}
/* The name of a web macro when being used: */
.cwebmacro {
font-family: "Lucida Grande", "Lucida Sans Unicode", Helvetica, Arial, Verdana, sans-serif;
text-decoration: none;
color: #000000; font-weight: bold;
}
.cwebmacronumber {
font-family: "Lucida Grande", "Lucida Sans Unicode", Helvetica, Arial, Verdana, sans-serif;
font-size: 80%;
text-decoration: none;
color: #000000;
}
/* And when being defined: */
.cwebmacrodefn {
font-family: "Lucida Grande", "Lucida Sans Unicode", Helvetica, Arial, Verdana, sans-serif;
text-decoration: none;
color: #000000; font-weight: bold;
font-weight:bold;
}
/* Now some generalities: */
body {
background-color: #ffffff;
margin: 8px;
font-family: "Lucida Grande", "Lucida Sans Unicode", Helvetica, Arial, Verdana, sans-serif;
font-size: 16px;
line-height: 24px;
background-color: transparent;
-webkit-font-smoothing: antialiased;
}
/* Forms of paragraph: */
p {
margin: 0;
padding-top: 5px;
padding-bottom: 5px;
clear: both;
}
/* Where an inweb paragraph begins: */
p.inwebparagraph {
width: 60em;
line-height: 150%;
padding-top: 15px;
padding-bottom: 5px;
}
/* If a web macro definition begins in its own paragraph, this is it: */
p.macrodefinition {
padding-top: 0px;
padding-bottom: 0px;
margin-left: 30px;
}
/* The endnotes at the foot of code: "The function foo_bar is used in ..." */
p.endnote {
font-size: 0.8em;
padding-top: 0px;
padding-bottom: 0px;
margin-left: 30px;
text-decoration:none;
color: #000000;
}
/* The Purpose slug: */
p.purpose {
width: 60em;
line-height: 150%;
font-size: 1em;
font-style:italic;
margin-left: 15px;
}
/* Blocks of code appear in these */
pre {
font-family: Monaco, monospace;
}
pre.display {
padding: 3px;
margin-top: 5px;
margin-bottom: 5px;
margin-left: 30px;
margin-right: 10px;
background: #f8f8f8;
border-width: 1px;
border-style: solid solid solid solid;
border-color: #ccc;
word-wrap: break-word;
white-space: pre-wrap;
}
pre.displaydefn {
padding: 3px;
margin-top: 0px;
margin-bottom: 0px;
margin-left: 0px;
margin-right: 10px;
background: #f8f8f8;
border-width: 1px;
border-style: solid solid solid solid;
border-color: #ccc;
word-wrap: break-word;
white-space: pre-wrap;
}
pre.definitions {
padding-top: 0px;
margin-top: 0px;
margin-left: 0px;
margin-right: 10px;
word-wrap: break-word;
white-space: pre-wrap;
}
/* The following are for breadcrumbs of links: */
ul, li {
list-style-type:none;
padding:0;
margin:0;
}
.crumbs {
border:1px solid #dedede;
height:3.45em;
}
.crumbs li {
float:left;
line-height:2.3em;
padding-left:.75em;
color:#333;
font-size: 1.5em;
}
.crumbs li a {
display:block;
padding:0 15px 0 0;
background:url(crumbs.gif) no-repeat right center;
}
.crumbs li a:link, #crumbs li a:visited {
text-decoration:none;
color:#333;
}
.crumbs li a:hover, #crumbs li a:focus {
color:#dd2c0d;
}
/* This is for items in lists from inweb source: */
ul.items {
margin-top: 3px;
margin-bottom: 3px;
}
ul.items li {
margin-top: 1px;
margin-bottom: 1px;
margin-left: 15px;
}
/* And this is for each section's table of contents: */
ul.toc {
margin-top: 3px;
margin-bottom: 3px;
}
ul.toc li {
float:left;
margin-left: 15px;
color:#000;
}
ul.toc li a {
display:block;
}
ul.toc li a:link, ul.toc li a:visited {
text-decoration:none;
color:#000;
}
ul.toc li a:hover, ul.toc li a:focus {
color:#dd2c0d;
}
hr.tocbar {
clear: both;
margin-top:3px;
margin-bottom:3px;
color:#333;
border:0
background-color:#333;
}
/* This is for cross-reference links ("This code is used in ...") */
p.endnote:link, p.endnote:visited, p.endnote:hover, p.endnote:focus {
text-decoration:none;
color:#000;
}
p.endnote a:link, p.endnote a:visited {
text-decoration:none;
color:#000;
}
p.endnote a:hover, p.endnote a:focus {
text-decoration:none;
color:#dd2c0d;
}
/* Now for the index page */
p.heading {
margin-top: 2px;
margin-bottom: 2px;
font-size: 20
}
p.chapter {
font-size: 14
}
p.tight {
font-size: 12
}
p.tightin {
padding-left: 25px;
font-size: 12
}
.chapterlist li {
padding-top: 8px;
padding-left: 16px;
}
.chaptertitle {
font-weight: bold;
}
.chapterlist .sectionlist li {
padding-left: 48px;
}
span.definitionkeyword {
color:#801010;
font-weight:bold;
}
span.extract {
font-size: 15px;
border: 1px solid #e8e8e8;
border-radius: 3px;
background-color: #eef;
width: 100%;
padding: 3px;
}

View file

@ -0,0 +1,771 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>1/im</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<!--Weave of '1/ic' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">inbuild</a></li><li><a href="index.html#1">Chapter 1: Setting Up</a></li><li><b>Inbuild Control</b></li></ul><p class="purpose">The top-level controller through which client tools use this module.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Phases</a></li><li><a href="#SP5">&#167;5. The nest list</a></li><li><a href="#SP10">&#167;10. The shared project</a></li><li><a href="#SP14">&#167;14. Kit requests</a></li><li><a href="#SP15">&#167;15. Installation</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Phases. </b>Although nothing at all clever happens in this section, it requires careful
sequencing to avoid invisible errors coming in because function X assumes
that function Y has already been called, or perhaos that it never will
be again. The client tool ("the tool") has to work in the following way
to avoid those problems.
</p>
<p class="inwebparagraph">Firstly, the inbuild module runs through the following phases in sequence:
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">CONFIGURATION_INBUILD_PHASE</span><span class="definitionkeyword"> from </span><span class="constant">1</span>
<span class="definitionkeyword">enum</span> <span class="constant">PRETINKERING_INBUILD_PHASE</span>
<span class="definitionkeyword">enum</span> <span class="constant">TINKERING_INBUILD_PHASE</span>
<span class="definitionkeyword">enum</span> <span class="constant">NESTED_INBUILD_PHASE</span>
<span class="definitionkeyword">enum</span> <span class="constant">PROJECTED_INBUILD_PHASE</span>
<span class="definitionkeyword">enum</span> <span class="constant">GOING_OPERATIONAL_INBUILD_PHASE</span>
<span class="definitionkeyword">enum</span> <span class="constant">OPERATIONAL_INBUILD_PHASE</span>
</pre>
<pre class="display">
<span class="definitionkeyword">define</span> <span class="identifier">RUN_ONLY_IN_PHASE</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">inbuild_phase</span><span class="plain"> &lt; </span><span class="identifier">P</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"too soon"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">inbuild_phase</span><span class="plain"> &gt; </span><span class="identifier">P</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"too late"</span><span class="plain">);</span>
<span class="definitionkeyword">define</span> <span class="identifier">RUN_ONLY_FROM_PHASE</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">inbuild_phase</span><span class="plain"> &lt; </span><span class="identifier">P</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"too soon"</span><span class="plain">);</span>
<span class="definitionkeyword">define</span> <span class="identifier">RUN_ONLY_BEFORE_PHASE</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">inbuild_phase</span><span class="plain"> &gt;= </span><span class="identifier">P</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"too late"</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">inbuild_phase</span><span class="plain"> = </span><span class="constant">CONFIGURATION_INBUILD_PHASE</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>Initially, then, we are in the configuration phase. This is when command
line processing should be done, and the tool should use the following routines
to add and process command line switches handled by inbuild:
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">INBUILD_INFORM_CLSG</span>
<span class="definitionkeyword">enum</span> <span class="constant">INBUILD_RESOURCES_CLSG</span>
<span class="definitionkeyword">enum</span> <span class="constant">INBUILD_INTER_CLSG</span>
<span class="definitionkeyword">enum</span> <span class="constant">INBUILD_CLSG</span>
<span class="definitionkeyword">enum</span> <span class="constant">NEST_CLSW</span>
<span class="definitionkeyword">enum</span> <span class="constant">INTERNAL_CLSW</span>
<span class="definitionkeyword">enum</span> <span class="constant">EXTERNAL_CLSW</span>
<span class="definitionkeyword">enum</span> <span class="constant">TRANSIENT_CLSW</span>
<span class="definitionkeyword">enum</span> <span class="constant">KIT_CLSW</span>
<span class="definitionkeyword">enum</span> <span class="constant">PROJECT_CLSW</span>
<span class="definitionkeyword">enum</span> <span class="constant">SOURCE_CLSW</span>
<span class="definitionkeyword">enum</span> <span class="constant">DEBUG_CLSW</span>
<span class="definitionkeyword">enum</span> <span class="constant">FORMAT_CLSW</span>
<span class="definitionkeyword">enum</span> <span class="constant">RELEASE_CLSW</span>
<span class="definitionkeyword">enum</span> <span class="constant">CENSUS_CLSW</span>
<span class="definitionkeyword">enum</span> <span class="constant">PIPELINE_CLSW</span>
<span class="definitionkeyword">enum</span> <span class="constant">PIPELINE_FILE_CLSW</span>
<span class="definitionkeyword">enum</span> <span class="constant">PIPELINE_VARIABLE_CLSW</span>
<span class="definitionkeyword">enum</span> <span class="constant">RNG_CLSW</span>
<span class="definitionkeyword">enum</span> <span class="constant">CASE_CLSW</span>
</pre>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Inbuild::declare_options</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">RUN_ONLY_IN_PHASE</span><span class="plain">(</span><span class="constant">CONFIGURATION_INBUILD_PHASE</span><span class="plain">)</span>
<span class="identifier">CommandLine::begin_group</span><span class="plain">(</span><span class="constant">INBUILD_INFORM_CLSG</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"for translating Inform source text to Inter"</span><span class="plain">);</span>
<span class="identifier">CommandLine::declare_switch</span><span class="plain">(</span><span class="constant">PROJECT_CLSW</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"project"</span><span class="plain">, 2,</span>
<span class="identifier">L</span><span class="string">"work within the Inform project X"</span><span class="plain">);</span>
<span class="identifier">CommandLine::declare_boolean_switch</span><span class="plain">(</span><span class="constant">DEBUG_CLSW</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"debug"</span><span class="plain">, 1,</span>
<span class="identifier">L</span><span class="string">"compile with debugging features even on a Release"</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="identifier">CommandLine::declare_boolean_switch</span><span class="plain">(</span><span class="constant">RELEASE_CLSW</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"release"</span><span class="plain">, 1,</span>
<span class="identifier">L</span><span class="string">"compile a version suitable for a Release build"</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="identifier">CommandLine::declare_textual_switch</span><span class="plain">(</span><span class="constant">FORMAT_CLSW</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"format"</span><span class="plain">, 1,</span>
<span class="identifier">L</span><span class="string">"compile I6 code suitable for the virtual machine X"</span><span class="plain">);</span>
<span class="identifier">CommandLine::declare_switch</span><span class="plain">(</span><span class="constant">SOURCE_CLSW</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"source"</span><span class="plain">, 2,</span>
<span class="identifier">L</span><span class="string">"use file X as the Inform source text"</span><span class="plain">);</span>
<span class="identifier">CommandLine::declare_boolean_switch</span><span class="plain">(</span><span class="constant">CENSUS_CLSW</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"census"</span><span class="plain">, 1,</span>
<span class="identifier">L</span><span class="string">"perform an extensions census"</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="identifier">CommandLine::declare_boolean_switch</span><span class="plain">(</span><span class="constant">RNG_CLSW</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"rng"</span><span class="plain">, 1,</span>
<span class="identifier">L</span><span class="string">"fix the random number generator of the story file (for testing)"</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="identifier">CommandLine::declare_switch</span><span class="plain">(</span><span class="constant">CASE_CLSW</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"case"</span><span class="plain">, 2,</span>
<span class="identifier">L</span><span class="string">"make any source links refer to the source in extension example X"</span><span class="plain">);</span>
<span class="identifier">CommandLine::end_group</span><span class="plain">();</span>
<span class="identifier">CommandLine::begin_group</span><span class="plain">(</span><span class="constant">INBUILD_RESOURCES_CLSG</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"for locating resources in the file system"</span><span class="plain">);</span>
<span class="identifier">CommandLine::declare_switch</span><span class="plain">(</span><span class="constant">NEST_CLSW</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"nest"</span><span class="plain">, 2,</span>
<span class="identifier">L</span><span class="string">"add the nest at pathname X to the search list"</span><span class="plain">);</span>
<span class="identifier">CommandLine::declare_switch</span><span class="plain">(</span><span class="constant">INTERNAL_CLSW</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"internal"</span><span class="plain">, 2,</span>
<span class="identifier">L</span><span class="string">"use X as the location of built-in material such as the Standard Rules"</span><span class="plain">);</span>
<span class="identifier">CommandLine::declare_switch</span><span class="plain">(</span><span class="constant">EXTERNAL_CLSW</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"external"</span><span class="plain">, 2,</span>
<span class="identifier">L</span><span class="string">"use X as the user's home for installed material such as extensions"</span><span class="plain">);</span>
<span class="identifier">CommandLine::declare_switch</span><span class="plain">(</span><span class="constant">TRANSIENT_CLSW</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"transient"</span><span class="plain">, 2,</span>
<span class="identifier">L</span><span class="string">"use X for transient data such as the extensions census"</span><span class="plain">);</span>
<span class="identifier">CommandLine::end_group</span><span class="plain">();</span>
<span class="identifier">CommandLine::begin_group</span><span class="plain">(</span><span class="constant">INBUILD_INTER_CLSG</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"for tweaking code generation from Inter"</span><span class="plain">);</span>
<span class="identifier">CommandLine::declare_switch</span><span class="plain">(</span><span class="constant">KIT_CLSW</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"kit"</span><span class="plain">, 2,</span>
<span class="identifier">L</span><span class="string">"include Inter code from the kit called X"</span><span class="plain">);</span>
<span class="identifier">CommandLine::declare_switch</span><span class="plain">(</span><span class="constant">PIPELINE_CLSW</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"pipeline"</span><span class="plain">, 2,</span>
<span class="identifier">L</span><span class="string">"specify code-generation pipeline"</span><span class="plain">);</span>
<span class="identifier">CommandLine::declare_switch</span><span class="plain">(</span><span class="constant">PIPELINE_FILE_CLSW</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"pipeline-file"</span><span class="plain">, 2,</span>
<span class="identifier">L</span><span class="string">"specify code-generation pipeline from file X"</span><span class="plain">);</span>
<span class="identifier">CommandLine::declare_switch</span><span class="plain">(</span><span class="constant">PIPELINE_VARIABLE_CLSW</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"variable"</span><span class="plain">, 2,</span>
<span class="identifier">L</span><span class="string">"set pipeline variable X (in form name=value)"</span><span class="plain">);</span>
<span class="identifier">CommandLine::end_group</span><span class="plain">();</span>
<span class="functiontext">Inbuild::set_defaults</span><span class="plain">();</span>
<span class="plain">}</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">inter_processing_file</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">inter_processing_pipeline</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">dictionary</span><span class="plain"> *</span><span class="identifier">pipeline_vars</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">shared_transient_resources</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">this_is_a_debug_compile</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">; </span> <span class="comment">Destined to be compiled with debug features</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">this_is_a_release_compile</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">; </span> <span class="comment">Omit sections of source text marked not for release</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">story_filename_extension</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span> <span class="comment">What story file we will eventually have</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">census_mode</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">; </span> <span class="comment">Running only to update extension documentation</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">rng_seed_at_start_of_play</span><span class="plain"> = 0; </span> <span class="comment">The seed value, or 0 if not seeded</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Inbuild::set_defaults</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">inter_processing_pipeline</span><span class="plain"> = </span><span class="identifier">Str::new</span><span class="plain">();</span>
<span class="identifier">inter_processing_file</span><span class="plain"> = </span><span class="identifier">I</span><span class="string">"compile"</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Inbuild::set_inter_pipeline</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">inter_processing_pipeline</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">inter_processing_pipeline</span><span class="plain">, </span><span class="string">"%W"</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
<span class="identifier">Str::delete_first_character</span><span class="plain">(</span><span class="identifier">inter_processing_pipeline</span><span class="plain">);</span>
<span class="identifier">Str::delete_last_character</span><span class="plain">(</span><span class="identifier">inter_processing_pipeline</span><span class="plain">);</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Setting pipeline %S\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">inter_processing_pipeline</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Inbuild::option</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">id</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">val</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="reserved">void</span><span class="plain"> *</span><span class="identifier">state</span><span class="plain">) {</span>
<span class="identifier">RUN_ONLY_IN_PHASE</span><span class="plain">(</span><span class="constant">CONFIGURATION_INBUILD_PHASE</span><span class="plain">)</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">id</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">DEBUG_CLSW</span><span class="plain">: </span><span class="identifier">this_is_a_debug_compile</span><span class="plain"> = </span><span class="identifier">val</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">FORMAT_CLSW</span><span class="plain">: </span><span class="identifier">story_filename_extension</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">arg</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">RELEASE_CLSW</span><span class="plain">: </span><span class="identifier">this_is_a_release_compile</span><span class="plain"> = </span><span class="identifier">val</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">NEST_CLSW</span><span class="plain">: </span><span class="functiontext">Inbuild::add_nest</span><span class="plain">(</span><span class="identifier">Pathnames::from_text</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">), </span><span class="constant">GENERIC_NEST_TAG</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">INTERNAL_CLSW</span><span class="plain">: </span><span class="functiontext">Inbuild::add_nest</span><span class="plain">(</span><span class="identifier">Pathnames::from_text</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">), </span><span class="constant">INTERNAL_NEST_TAG</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">EXTERNAL_CLSW</span><span class="plain">: </span><span class="functiontext">Inbuild::add_nest</span><span class="plain">(</span><span class="identifier">Pathnames::from_text</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">), </span><span class="constant">EXTERNAL_NEST_TAG</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">TRANSIENT_CLSW</span><span class="plain">: </span><span class="identifier">shared_transient_resources</span><span class="plain"> = </span><span class="identifier">Pathnames::from_text</span><span class="plain">(</span><span class="identifier">arg</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_CLSW</span><span class="plain">: </span><span class="functiontext">Inbuild::request_kit</span><span class="plain">(</span><span class="identifier">arg</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">PROJECT_CLSW</span><span class="plain">:</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Inbuild::set_I7_bundle</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">)</span>
<span class="identifier">Errors::fatal_with_text</span><span class="plain">(</span><span class="string">"can't specify the project twice: '%S'"</span><span class="plain">, </span><span class="identifier">arg</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">SOURCE_CLSW</span><span class="plain">:</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Inbuild::set_I7_source</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">)</span>
<span class="identifier">Errors::fatal_with_text</span><span class="plain">(</span><span class="string">"can't specify the source file twice: '%S'"</span><span class="plain">, </span><span class="identifier">arg</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">CENSUS_CLSW</span><span class="plain">: </span><span class="identifier">census_mode</span><span class="plain"> = </span><span class="identifier">val</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">PIPELINE_CLSW</span><span class="plain">: </span><span class="identifier">inter_processing_pipeline</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">arg</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">PIPELINE_FILE_CLSW</span><span class="plain">: </span><span class="identifier">inter_processing_file</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">arg</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">PIPELINE_VARIABLE_CLSW</span><span class="plain">: {</span>
<span class="identifier">match_results</span><span class="plain"> </span><span class="identifier">mr</span><span class="plain"> = </span><span class="identifier">Regexp::create_mr</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">arg</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"(%c+)=(%c+)"</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::get_first_char</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">) != </span><span class="character">'*'</span><span class="plain">) {</span>
<span class="identifier">Errors::fatal</span><span class="plain">(</span><span class="string">"-variable names must begin with '*'"</span><span class="plain">);</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">CODEGEN_MODULE</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pipeline_vars</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)</span>
<span class="identifier">pipeline_vars</span><span class="plain"> = </span><span class="identifier">CodeGen::Pipeline::basic_dictionary</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"output.z8"</span><span class="plain">);</span>
<span class="identifier">Str::copy</span><span class="plain">(</span><span class="identifier">Dictionaries::create_text</span><span class="plain">(</span><span class="identifier">pipeline_vars</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="identifier">mr</span><span class="plain">.</span><span class="identifier">exp</span><span class="plain">[1]);</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="plain">}</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Errors::fatal</span><span class="plain">(</span><span class="string">"-variable should take the form 'name=value'"</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>
<span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">RNG_CLSW</span><span class="plain">:</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">val</span><span class="plain">) </span><span class="identifier">rng_seed_at_start_of_play</span><span class="plain"> = -16339;</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">rng_seed_at_start_of_play</span><span class="plain"> = 0;</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">CASE_CLSW</span><span class="plain">: </span><span class="identifier">HTMLFiles::set_source_link_case</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Inbuild::declare_options appears nowhere else.</p>
<p class="endnote">The function Inbuild::set_defaults appears nowhere else.</p>
<p class="endnote">The function Inbuild::set_inter_pipeline appears nowhere else.</p>
<p class="endnote">The function Inbuild::option appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>Once the tool has finished with the command line, it should call this
function. Inbuild rapidly runs through the next few phases as it does so.
From the "nested" phase, the final list of nests in the search path for
finding kits, extensions and so on exists; from the "projected" phase,
the main Inform project exists. As we shall see, Inbuild deals with only
one Inform project at a time, though it may be handling many kits and
extensions, and so on, which are needed by that project.
</p>
<pre class="display">
<span class="identifier">target_vm</span><span class="plain"> *</span><span class="identifier">current_target_VM</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="functiontext">Inbuild::optioneering_complete</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">int</span><span class="plain"> </span><span class="identifier">compile_only</span><span class="plain">) {</span>
<span class="identifier">RUN_ONLY_IN_PHASE</span><span class="plain">(</span><span class="constant">CONFIGURATION_INBUILD_PHASE</span><span class="plain">)</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">CODEGEN_MODULE</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pipeline_vars</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)</span>
<span class="identifier">pipeline_vars</span><span class="plain"> = </span><span class="identifier">CodeGen::Pipeline::basic_dictionary</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"output.z8"</span><span class="plain">);</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="identifier">target_vm</span><span class="plain"> *</span><span class="identifier">VM</span><span class="plain"> = </span><span class="identifier">NULL</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">story_filename_extension</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">ext</span><span class="plain">) == 0) </span><span class="identifier">ext</span><span class="plain"> = </span><span class="identifier">I</span><span class="string">"ulx"</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">with_debugging</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">this_is_a_release_compile</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) || (</span><span class="identifier">this_is_a_debug_compile</span><span class="plain">))</span>
<span class="identifier">with_debugging</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">VM</span><span class="plain"> = </span><span class="identifier">TargetVMs::find</span><span class="plain">(</span><span class="identifier">ext</span><span class="plain">, </span><span class="identifier">with_debugging</span><span class="plain">);</span>
<span class="identifier">inbuild_phase</span><span class="plain"> = </span><span class="constant">PRETINKERING_INBUILD_PHASE</span><span class="plain">;</span>
<span class="reserved">inform_project</span><span class="plain"> *</span><span class="identifier">project</span><span class="plain"> = </span><span class="functiontext">Inbuild::create_shared_project</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">);</span>
<span class="identifier">inbuild_phase</span><span class="plain"> = </span><span class="constant">TINKERING_INBUILD_PHASE</span><span class="plain">;</span>
<span class="functiontext">Inbuild::sort_nest_list</span><span class="plain">();</span>
<span class="identifier">inbuild_phase</span><span class="plain"> = </span><span class="constant">NESTED_INBUILD_PHASE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">project</span><span class="plain">) </span><span class="functiontext">Projects::set_to_English</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="identifier">inbuild_phase</span><span class="plain"> = </span><span class="constant">PROJECTED_INBUILD_PHASE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">project</span><span class="plain">) {</span>
<span class="functiontext">Projects::construct_build_target</span><span class="plain">(</span><span class="identifier">project</span><span class="plain">, </span><span class="identifier">VM</span><span class="plain">, </span><span class="identifier">this_is_a_release_compile</span><span class="plain">, </span><span class="identifier">compile_only</span><span class="plain">);</span>
<span class="identifier">current_target_VM</span><span class="plain"> = </span><span class="identifier">VM</span><span class="plain">;</span>
<span class="reserved">return</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="reserved">else</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>
<span class="plain">}</span>
<span class="identifier">target_vm</span><span class="plain"> *</span><span class="functiontext">Inbuild::current_vm</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="identifier">current_target_VM</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Inbuild::currently_releasing</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="identifier">this_is_a_release_compile</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Inbuild::optioneering_complete appears nowhere else.</p>
<p class="endnote">The function Inbuild::current_vm appears nowhere else.</p>
<p class="endnote">The function Inbuild::currently_releasing appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>Inbuild is now in the "projected" phase, then. The idea is that this
is a short interval during which the tool can if it wishes add further
kit dependencies to the main project. Once that sort of thing is done,
the tool should call the following, which puts Inbuild into its
final "operational" phase &mdash; at this point Inbuild is fully configured
and ready for use.
</p>
<p class="inwebparagraph">The brief "going operational" phase is used, for example, to build out
dependency graphs.
</p>
<pre class="display">
<span class="reserved">inform_project</span><span class="plain"> *</span><span class="functiontext">Inbuild::go_operational</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">RUN_ONLY_IN_PHASE</span><span class="plain">(</span><span class="constant">PROJECTED_INBUILD_PHASE</span><span class="plain">)</span>
<span class="identifier">inbuild_phase</span><span class="plain"> = </span><span class="constant">GOING_OPERATIONAL_INBUILD_PHASE</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">LOOP_OVER</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="functiontext">Copies::go_operational</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">);</span>
<span class="identifier">inbuild_phase</span><span class="plain"> = </span><span class="constant">OPERATIONAL_INBUILD_PHASE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">census_mode</span><span class="plain">) </span><span class="functiontext">Extensions::Census::handle_census_mode</span><span class="plain">();</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Inbuild::project</span><span class="plain">();</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Inbuild::go_operational appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. The nest list. </b>Nests are directories which hold resources to be used by the Intools, and
one of Inbuild's main roles is to search and manage nests. All nests can
hold extensions, kits, language definitions, and so on.
</p>
<p class="inwebparagraph">But among nests three are special, and can hold other things as well.
</p>
<p class="inwebparagraph"></p>
<ul class="items"><li>(a) The "internal" nest is part of the installation of Inform as software.
It contains, for example, the build-in extensions. But it also contains
miscellaneous other files needed by Infomr (see below).
</li></ul>
<ul class="items"><li>(b) The "external" nest is the one to which the user installs her own
selection of extensions, and so on. On most platforms, the external nest
is also the default home of "transient" storage, for more ephemeral content,
such as the mechanically generated extension documentation. Some mobile
operating systems are aggressive about wanting to delete ephemeral files
used by applications, so <code class="display"><span class="extract">-transient</span></code> can be used to divert these.
</li></ul>
<ul class="items"><li>(c) Every project has its own private nest, in the form of its associated
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>
<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="SP6"></a><b>&#167;6. </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
nests, respectively.
</p>
<p class="inwebparagraph">The following hold the nests in declaration order.
</p>
<pre class="display">
<span class="identifier">linked_list</span><span class="plain"> *</span><span class="identifier">unsorted_nest_list</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">inbuild_nest</span><span class="plain"> *</span><span class="identifier">shared_internal_nest</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">inbuild_nest</span><span class="plain"> *</span><span class="identifier">shared_external_nest</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">inbuild_nest</span><span class="plain"> *</span><span class="identifier">shared_materials_nest</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">inbuild_nest</span><span class="plain"> *</span><span class="functiontext">Inbuild::add_nest</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">int</span><span class="plain"> </span><span class="identifier">tag</span><span class="plain">) {</span>
<span class="identifier">RUN_ONLY_BEFORE_PHASE</span><span class="plain">(</span><span class="constant">TINKERING_INBUILD_PHASE</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">unsorted_nest_list</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)</span>
<span class="identifier">unsorted_nest_list</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="reserved">inbuild_nest</span><span class="plain"> *</span><span class="identifier">N</span><span class="plain"> = </span><span class="functiontext">Nests::new</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">);</span>
<span class="functiontext">Nests::set_tag</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">, </span><span class="identifier">tag</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">unsorted_nest_list</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">tag</span><span class="plain"> == </span><span class="constant">EXTERNAL_NEST_TAG</span><span class="plain">) &amp;&amp; (</span><span class="identifier">shared_external_nest</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">))</span>
<span class="identifier">shared_external_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">tag</span><span class="plain"> == </span><span class="constant">INTERNAL_NEST_TAG</span><span class="plain">) &amp;&amp; (</span><span class="identifier">shared_internal_nest</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">))</span>
<span class="identifier">shared_internal_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">tag</span><span class="plain"> == </span><span class="constant">INTERNAL_NEST_TAG</span><span class="plain">) </span><span class="functiontext">Nests::protect</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">N</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Inbuild::add_nest is used in <a href="#SP2">&#167;2</a>, <a href="#SP11_1">&#167;11.1</a>, <a href="#SP11_2">&#167;11.2</a>.</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. </b>It is then sorted in tag order. This is so that if we look for, say, an
extension with a given name, then results in a project's materials folder
are given precedence over those in the external folder, and so on.
</p>
<pre class="display">
<span class="identifier">linked_list</span><span class="plain"> *</span><span class="identifier">shared_nest_list</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Inbuild::sort_nest_list</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">RUN_ONLY_IN_PHASE</span><span class="plain">(</span><span class="constant">TINKERING_INBUILD_PHASE</span><span class="plain">)</span>
<span class="identifier">shared_nest_list</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="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">unsorted_nest_list</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Nests::get_tag</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">) == </span><span class="constant">MATERIALS_NEST_TAG</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">shared_nest_list</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">unsorted_nest_list</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Nests::get_tag</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">) == </span><span class="constant">EXTERNAL_NEST_TAG</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">shared_nest_list</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">unsorted_nest_list</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Nests::get_tag</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">) == </span><span class="constant">GENERIC_NEST_TAG</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">shared_nest_list</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">unsorted_nest_list</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Nests::get_tag</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">) == </span><span class="constant">INTERNAL_NEST_TAG</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">shared_nest_list</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Inbuild::sort_nest_list is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. </b>And the rest of Inform or Inbuild can now use:
</p>
<pre class="display">
<span class="identifier">linked_list</span><span class="plain"> *</span><span class="functiontext">Inbuild::nest_list</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">RUN_ONLY_FROM_PHASE</span><span class="plain">(</span><span class="constant">NESTED_INBUILD_PHASE</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">shared_nest_list</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">"nest list never sorted"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">shared_nest_list</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">inbuild_nest</span><span class="plain"> *</span><span class="functiontext">Inbuild::internal</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">RUN_ONLY_FROM_PHASE</span><span class="plain">(</span><span class="constant">NESTED_INBUILD_PHASE</span><span class="plain">)</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">shared_internal_nest</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">inbuild_nest</span><span class="plain"> *</span><span class="functiontext">Inbuild::external</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">RUN_ONLY_FROM_PHASE</span><span class="plain">(</span><span class="constant">NESTED_INBUILD_PHASE</span><span class="plain">)</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">shared_external_nest</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">pathname</span><span class="plain"> *</span><span class="functiontext">Inbuild::materials</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">RUN_ONLY_FROM_PHASE</span><span class="plain">(</span><span class="constant">NESTED_INBUILD_PHASE</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">shared_materials_nest</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">shared_materials_nest</span><span class="plain">-</span><span class="element">&gt;location</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Inbuild::nest_list 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>, <a href="5-kts.html#SP2">&#167;2</a>), 5/ed2 (<a href="5-ed2.html#SP4">&#167;4</a>), 5/ec (<a href="5-ec.html#SP1">&#167;1</a>), 5/ps (<a href="5-ps.html#SP1">&#167;1</a>, <a href="5-ps.html#SP3">&#167;3</a>).</p>
<p class="endnote">The function Inbuild::internal is used in <a href="#SP15">&#167;15</a>.</p>
<p class="endnote">The function Inbuild::external is used in 5/ps (<a href="5-ps.html#SP4">&#167;4</a>).</p>
<p class="endnote">The function Inbuild::materials appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. </b>As noted above, the transient area is used for ephemera such as dynamically
written documentation and telemetry files. <code class="display"><span class="extract">-transient</span></code> sets it, but otherwise
the external nest is used.
</p>
<pre class="display">
<span class="identifier">pathname</span><span class="plain"> *</span><span class="functiontext">Inbuild::transient</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">RUN_ONLY_FROM_PHASE</span><span class="plain">(</span><span class="constant">PROJECTED_INBUILD_PHASE</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">shared_transient_resources</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">shared_external_nest</span><span class="plain">)</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">shared_external_nest</span><span class="plain">-</span><span class="element">&gt;location</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">shared_transient_resources</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Inbuild::transient is used in 5/ed (<a href="5-ed.html#SP11">&#167;11</a>), 5/ed2 (<a href="5-ed2.html#SP3">&#167;3</a>), 5/ec (<a href="5-ec.html#SP15">&#167;15</a>), 5/ps (<a href="5-ps.html#SP3">&#167;3</a>).</p>
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. The shared project. </b>In any single run, each of the Inform tools concerns itself with a single
Inform 7 program. This can be presented to it either in a project bundle
(a directory which contains source, settings, space for an index and for
temporary build files), or as a single file (just a text file containing
source text).
</p>
<p class="inwebparagraph">It is also possible o set a folder to be the project bundle, and nevertheless
specify a file somewhere else to be the source text. What you can't do is
specify the bundle twice, or specify the file twice.
</p>
<pre class="display">
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">project_bundle_request</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">project_file_request</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Inbuild::set_I7_source</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">loc</span><span class="plain">) {</span>
<span class="identifier">RUN_ONLY_FROM_PHASE</span><span class="plain">(</span><span class="constant">CONFIGURATION_INBUILD_PHASE</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">project_file_request</span><span class="plain">) &gt; 0) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">project_file_request</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">loc</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="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Inbuild::set_I7_bundle</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">loc</span><span class="plain">) {</span>
<span class="identifier">RUN_ONLY_FROM_PHASE</span><span class="plain">(</span><span class="constant">CONFIGURATION_INBUILD_PHASE</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">project_bundle_request</span><span class="plain">) &gt; 0) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">project_bundle_request</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">loc</span><span class="plain">);</span>
<span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">pathname_of_bundle</span><span class="plain"> = </span><span class="identifier">Pathnames::from_text</span><span class="plain">(</span><span class="identifier">project_bundle_request</span><span class="plain">);</span>
<span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">materials</span><span class="plain"> = </span><span class="functiontext">Inbuild::pathname_of_materials</span><span class="plain">(</span><span class="identifier">pathname_of_bundle</span><span class="plain">);</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">leaf</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">leaf</span><span class="plain">, </span><span class="string">"%s-settings.txt"</span><span class="plain">, </span><span class="identifier">INTOOL_NAME</span><span class="plain">);</span>
<span class="identifier">filename</span><span class="plain"> *</span><span class="identifier">expert_settings</span><span class="plain"> = </span><span class="identifier">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">materials</span><span class="plain">, </span><span class="identifier">leaf</span><span class="plain">);</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Speculatively %f\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">expert_settings</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">expert_settings</span><span class="plain">))</span>
<span class="identifier">CommandLine::also_read_file</span><span class="plain">(</span><span class="identifier">expert_settings</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">leaf</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="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Inbuild::set_I7_source is used in <a href="#SP2">&#167;2</a>.</p>
<p class="endnote">The function Inbuild::set_I7_bundle is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP11"></a><b>&#167;11. </b>If a bundle is found, then by default the source text within it is called
<code class="display"><span class="extract">story.ni</span></code>. The <code class="display"><span class="extract">.ni</span></code> is an anachronism now, but at one time stood for
"natural Inform", the working title for Inform 7 in the early 2000s.
</p>
<pre class="display">
<span class="reserved">inform_project</span><span class="plain"> *</span><span class="identifier">shared_project</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">inform_project</span><span class="plain"> *</span><span class="functiontext">Inbuild::create_shared_project</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">RUN_ONLY_IN_PHASE</span><span class="plain">(</span><span class="constant">PRETINKERING_INBUILD_PHASE</span><span class="plain">)</span>
<span class="identifier">filename</span><span class="plain"> *</span><span class="identifier">filename_of_i7_source</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">pathname_of_bundle</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">project_bundle_request</span><span class="plain">) &gt; 0) {</span>
<span class="identifier">pathname_of_bundle</span><span class="plain"> = </span><span class="identifier">Pathnames::from_text</span><span class="plain">(</span><span class="identifier">project_bundle_request</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">project_file_request</span><span class="plain">) &gt; 0) {</span>
<span class="identifier">filename_of_i7_source</span><span class="plain"> = </span><span class="identifier">Filenames::from_text</span><span class="plain">(</span><span class="identifier">project_file_request</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="identifier">pathname_of_bundle</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">filename_of_i7_source</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="plain">}</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">pathname_of_bundle</span><span class="plain">) &amp;&amp; (</span><span class="identifier">filename_of_i7_source</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">))</span>
<span class="identifier">filename_of_i7_source</span><span class="plain"> =</span>
<span class="identifier">Filenames::in_folder</span><span class="plain">(</span>
<span class="identifier">Pathnames::subfolder</span><span class="plain">(</span><span class="identifier">pathname_of_bundle</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Source"</span><span class="plain">),</span>
<span class="identifier">I</span><span class="string">"story.ni"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pathname_of_bundle</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">ProjectBundleManager::claim_folder_as_copy</span><span class="plain">(</span><span class="identifier">pathname_of_bundle</span><span class="plain">);</span>
<span class="identifier">shared_project</span><span class="plain"> = </span><span class="functiontext">ProjectBundleManager::from_copy</span><span class="plain">(</span><span class="identifier">C</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">filename_of_i7_source</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">ProjectFileManager::claim_file_as_copy</span><span class="plain">(</span><span class="identifier">filename_of_i7_source</span><span class="plain">);</span>
<span class="identifier">shared_project</span><span class="plain"> = </span><span class="functiontext">ProjectFileManager::from_copy</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">);</span>
<span class="plain">}</span>
&lt;<span class="cwebmacro">Create the default externals nest</span> <span class="cwebmacronumber">11.1</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Create the materials nest</span> <span class="cwebmacronumber">11.2</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">shared_project</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">shared_materials_nest</span><span class="plain">)?(</span><span class="identifier">shared_materials_nest</span><span class="plain">-</span><span class="element">&gt;location</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">P</span><span class="plain">) </span><span class="identifier">P</span><span class="plain"> = </span><span class="identifier">Pathnames::subfolder</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Source"</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">project_file_request</span><span class="plain">) &gt; 0) </span><span class="identifier">P</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="functiontext">Projects::set_source_filename</span><span class="plain">(</span><span class="identifier">shared_project</span><span class="plain">, </span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">filename_of_i7_source</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rng_seed_at_start_of_play</span><span class="plain"> != 0)</span>
<span class="functiontext">Projects::fix_rng</span><span class="plain">(</span><span class="identifier">shared_project</span><span class="plain">, </span><span class="identifier">rng_seed_at_start_of_play</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">shared_project</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Inbuild::create_shared_project is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP11_1"></a><b>&#167;11.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Create the default externals nest</span> <span class="cwebmacronumber">11.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">inbuild_nest</span><span class="plain"> *</span><span class="identifier">E</span><span class="plain"> = </span><span class="identifier">shared_external_nest</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="identifier">pathname</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain"> = </span><span class="identifier">home_path</span><span class="plain">;</span>
<span class="reserved">char</span><span class="plain"> *</span><span class="identifier">subfolder_within</span><span class="plain"> = </span><span class="identifier">INFORM_FOLDER_RELATIVE_TO_HOME</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">subfolder_within</span><span class="plain">[0]) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">SF</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">SF</span><span class="plain">, </span><span class="string">"%s"</span><span class="plain">, </span><span class="identifier">subfolder_within</span><span class="plain">);</span>
<span class="identifier">P</span><span class="plain"> = </span><span class="identifier">Pathnames::subfolder</span><span class="plain">(</span><span class="identifier">home_path</span><span class="plain">, </span><span class="identifier">SF</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">SF</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">P</span><span class="plain"> = </span><span class="identifier">Pathnames::subfolder</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Inform"</span><span class="plain">);</span>
<span class="identifier">E</span><span class="plain"> = </span><span class="functiontext">Inbuild::add_nest</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">, </span><span class="constant">EXTERNAL_NEST_TAG</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP11">&#167;11</a>.</p>
<p class="inwebparagraph"><a id="SP11_2"></a><b>&#167;11.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Create the materials nest</span> <span class="cwebmacronumber">11.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">materials</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">pathname_of_bundle</span><span class="plain">) {</span>
<span class="identifier">materials</span><span class="plain"> = </span><span class="functiontext">Inbuild::pathname_of_materials</span><span class="plain">(</span><span class="identifier">pathname_of_bundle</span><span class="plain">);</span>
<span class="identifier">Pathnames::create_in_file_system</span><span class="plain">(</span><span class="identifier">materials</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">filename_of_i7_source</span><span class="plain">) {</span>
<span class="identifier">materials</span><span class="plain"> = </span><span class="identifier">Pathnames::from_text</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"inform.materials"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">materials</span><span class="plain">) {</span>
<span class="identifier">shared_materials_nest</span><span class="plain"> = </span><span class="functiontext">Inbuild::add_nest</span><span class="plain">(</span><span class="identifier">materials</span><span class="plain">, </span><span class="constant">MATERIALS_NEST_TAG</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP11">&#167;11</a>.</p>
<p class="inwebparagraph"><a id="SP12"></a><b>&#167;12. </b>And the rest of Inform or Inbuild can now use:
</p>
<pre class="display">
<span class="reserved">inform_project</span><span class="plain"> *</span><span class="functiontext">Inbuild::project</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">RUN_ONLY_FROM_PHASE</span><span class="plain">(</span><span class="constant">PROJECTED_INBUILD_PHASE</span><span class="plain">)</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">shared_project</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Inbuild::project is used in <a href="#SP4">&#167;4</a>, 3/is (<a href="3-is.html#SP1">&#167;1</a>).</p>
<p class="inwebparagraph"><a id="SP13"></a><b>&#167;13. </b>The materials folder sits alongside the project folder and has the same name,
but ending <code class="display"><span class="extract">.materials</span></code> instead of <code class="display"><span class="extract">.inform</span></code>.
</p>
<pre class="display">
<span class="identifier">pathname</span><span class="plain"> *</span><span class="functiontext">Inbuild::pathname_of_materials</span><span class="plain">(</span><span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">pathname_of_bundle</span><span class="plain">) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">mf</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">mf</span><span class="plain">, </span><span class="string">"%S"</span><span class="plain">, </span><span class="identifier">Pathnames::directory_name</span><span class="plain">(</span><span class="identifier">pathname_of_bundle</span><span class="plain">));</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> = </span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">mf</span><span class="plain">)-1;</span>
<span class="reserved">while</span><span class="plain"> ((</span><span class="identifier">i</span><span class="plain">&gt;0) &amp;&amp; (</span><span class="identifier">Str::get_at</span><span class="plain">(</span><span class="identifier">mf</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">) != </span><span class="character">'.'</span><span class="plain">)) </span><span class="identifier">i</span><span class="plain">--;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">&gt;0) {</span>
<span class="identifier">Str::truncate</span><span class="plain">(</span><span class="identifier">mf</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">mf</span><span class="plain">, </span><span class="string">".materials"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">materials</span><span class="plain"> = </span><span class="identifier">Pathnames::subfolder</span><span class="plain">(</span><span class="identifier">Pathnames::up</span><span class="plain">(</span><span class="identifier">pathname_of_bundle</span><span class="plain">), </span><span class="identifier">mf</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">mf</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">materials</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Inbuild::pathname_of_materials is used in <a href="#SP10">&#167;10</a>, <a href="#SP11_2">&#167;11.2</a>.</p>
<p class="inwebparagraph"><a id="SP14"></a><b>&#167;14. Kit requests. </b>These are triggered by, for example, <code class="display"><span class="extract">-kit MyFancyKit</span></code> at the command line.
For timing reasons, we store those up in the configuration phase and then
add them as dependencies only when a project exists.
</p>
<pre class="display">
<span class="identifier">linked_list</span><span class="plain"> *</span><span class="identifier">kits_requested_at_command_line</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Inbuild::request_kit</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">RUN_ONLY_IN_PHASE</span><span class="plain">(</span><span class="constant">CONFIGURATION_INBUILD_PHASE</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">kits_requested_at_command_line</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)</span>
<span class="identifier">kits_requested_at_command_line</span><span class="plain"> = </span><span class="identifier">NEW_LINKED_LIST</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain">);</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">kit_name</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">kit_name</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain">, </span><span class="identifier">kits_requested_at_command_line</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">kit_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">ADD_TO_LINKED_LIST</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">text_stream</span><span class="plain">, </span><span class="identifier">kits_requested_at_command_line</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Inbuild::pass_kit_requests</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">RUN_ONLY_IN_PHASE</span><span class="plain">(</span><span class="constant">NESTED_INBUILD_PHASE</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">shared_project</span><span class="plain">) &amp;&amp; (</span><span class="identifier">kits_requested_at_command_line</span><span class="plain">)) {</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">kit_name</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">kit_name</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain">, </span><span class="identifier">kits_requested_at_command_line</span><span class="plain">) {</span>
<span class="functiontext">Projects::add_kit_dependency</span><span class="plain">(</span><span class="identifier">shared_project</span><span class="plain">, </span><span class="identifier">kit_name</span><span class="plain">);</span>
<span class="functiontext">Projects::not_necessarily_parser_IF</span><span class="plain">(</span><span class="identifier">shared_project</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Inbuild::request_kit is used in <a href="#SP2">&#167;2</a>.</p>
<p class="endnote">The function Inbuild::pass_kit_requests is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP15"></a><b>&#167;15. Installation. </b>Inform needs a whole pile of files to have been installed on the host computer
before it can run: everything from the Standard Rules to a PDF file explaining
what interactive fiction is. They're never written to, only read. They are
referred to as "internal" or "built-in", and they occupy a folder called the
"internal resources" folder.
</p>
<p class="inwebparagraph">Unfortunately we don't know where it is. Typically this compiler will be an
executable sitting somewhere inside a user interface application, and the
internal resources folder will be somewhere else inside it. But we don't
know how to find that folder, and we don't want to make any assumptions.
This is the purpose of the internal nest, and this is why inform7 can only
be run if an <code class="display"><span class="extract">-internal</span></code> switch has been used specifying where it is.
</p>
<p class="inwebparagraph">The internal nest has two additional subfolders (additional in that they
don't hold copies in the Inbuild sense, just a bunch of loose odds and ends):
<code class="display"><span class="extract">Miscellany</span></code> and <code class="display"><span class="extract">HTML</span></code>. Many of these files are to help Inblorb to perform
a release.
</p>
<p class="inwebparagraph">The documentation snippets file is generated by <code class="display"><span class="extract">indoc</span></code> and contains
brief specifications of phrases, extracted from the manual "Writing with
Inform". This is used to generate the Phrasebook index.
</p>
<p class="inwebparagraph">Anyway, Inform and its associated tools can then access these files using the
following routine:
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">CBLORB_REPORT_MODEL_IRES</span><span class="definitionkeyword"> from </span><span class="constant">1</span>
<span class="definitionkeyword">enum</span> <span class="constant">DOCUMENTATION_SNIPPETS_IRES</span>
<span class="definitionkeyword">enum</span> <span class="constant">INTRO_BOOKLET_IRES</span>
<span class="definitionkeyword">enum</span> <span class="constant">INTRO_POSTCARD_IRES</span>
<span class="definitionkeyword">enum</span> <span class="constant">LARGE_DEFAULT_COVER_ART_IRES</span>
<span class="definitionkeyword">enum</span> <span class="constant">SMALL_DEFAULT_COVER_ART_IRES</span>
<span class="definitionkeyword">enum</span> <span class="constant">DOCUMENTATION_XREFS_IRES</span>
<span class="definitionkeyword">enum</span> <span class="constant">JAVASCRIPT_FOR_STANDARD_PAGES_IRES</span>
<span class="definitionkeyword">enum</span> <span class="constant">JAVASCRIPT_FOR_EXTENSIONS_IRES</span>
<span class="definitionkeyword">enum</span> <span class="constant">JAVASCRIPT_FOR_ONE_EXTENSION_IRES</span>
<span class="definitionkeyword">enum</span> <span class="constant">CSS_FOR_STANDARD_PAGES_IRES</span>
<span class="definitionkeyword">enum</span> <span class="constant">EXTENSION_DOCUMENTATION_MODEL_IRES</span>
</pre>
<pre class="display">
<span class="identifier">filename</span><span class="plain"> *</span><span class="functiontext">Inbuild::file_from_installation</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">ires</span><span class="plain">) {</span>
<span class="reserved">inbuild_nest</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain"> = </span><span class="functiontext">Inbuild::internal</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">I</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">Errors::fatal</span><span class="plain">(</span><span class="string">"Did not set -internal when calling"</span><span class="plain">);</span>
<span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">misc</span><span class="plain"> = </span><span class="identifier">Pathnames::subfolder</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">-</span><span class="element">&gt;location</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Miscellany"</span><span class="plain">);</span>
<span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">models</span><span class="plain"> = </span><span class="identifier">Pathnames::subfolder</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">-</span><span class="element">&gt;location</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"HTML"</span><span class="plain">);</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">ires</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">DOCUMENTATION_SNIPPETS_IRES</span><span class="plain">: </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">misc</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"definitions.html"</span><span class="plain">);</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">INTRO_BOOKLET_IRES</span><span class="plain">: </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">misc</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"IntroductionToIF.pdf"</span><span class="plain">);</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">INTRO_POSTCARD_IRES</span><span class="plain">: </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">misc</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Postcard.pdf"</span><span class="plain">);</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">LARGE_DEFAULT_COVER_ART_IRES</span><span class="plain">: </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">misc</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Cover.jpg"</span><span class="plain">);</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">SMALL_DEFAULT_COVER_ART_IRES</span><span class="plain">: </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">misc</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Small Cover.jpg"</span><span class="plain">);</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">CBLORB_REPORT_MODEL_IRES</span><span class="plain">: </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">models</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"CblorbModel.html"</span><span class="plain">);</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">DOCUMENTATION_XREFS_IRES</span><span class="plain">: </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">models</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"xrefs.txt"</span><span class="plain">);</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">JAVASCRIPT_FOR_STANDARD_PAGES_IRES</span><span class="plain">: </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">models</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"main.js"</span><span class="plain">);</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">JAVASCRIPT_FOR_EXTENSIONS_IRES</span><span class="plain">: </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">models</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"extensions.js"</span><span class="plain">);</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">JAVASCRIPT_FOR_ONE_EXTENSION_IRES</span><span class="plain">: </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">models</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"extensionfile.js"</span><span class="plain">);</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">CSS_FOR_STANDARD_PAGES_IRES</span><span class="plain">: </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">models</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"main.css"</span><span class="plain">);</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">EXTENSION_DOCUMENTATION_MODEL_IRES</span><span class="plain">: </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">models</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"extensionfile.html"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"unknown installation resource file"</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 Inbuild::file_from_installation is used in 5/ed2 (<a href="5-ed2.html#SP3_2">&#167;3.2</a>), 5/ec (<a href="5-ec.html#SP15">&#167;15</a>).</p>
<hr class="tocbar">
<ul class="toc"><li><a href="1-im.html">Back to 'Inter Module'</a></li><li><i>(This section ends Chapter 1: Setting Up.)</i></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>

View file

@ -0,0 +1,196 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Booklet Title</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<!--Weave of '1/im' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">inbuild</a></li><li><a href="index.html#1">Chapter 1: Setting Up</a></li><li><b>Inter Module</b></li></ul><p class="purpose">Setting up the use of this module.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Introduction</a></li><li><a href="#SP3">&#167;3. The beginning</a></li><li><a href="#SP4">&#167;4. The end</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Introduction. </b></p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">INBUILD_MODULE</span><span class="plain"> </span><span class="identifier">TRUE</span>
</pre>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>To begin with, this module needs to allocate memory:
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">inform_kit_MT</span>
<span class="definitionkeyword">enum</span> <span class="constant">inform_extension_MT</span>
<span class="definitionkeyword">enum</span> <span class="constant">inform_kit_ittt_MT</span>
<span class="definitionkeyword">enum</span> <span class="constant">element_activation_MT</span>
<span class="definitionkeyword">enum</span> <span class="constant">inbuild_genre_MT</span>
<span class="definitionkeyword">enum</span> <span class="constant">inbuild_work_MT</span>
<span class="definitionkeyword">enum</span> <span class="constant">inbuild_edition_MT</span>
<span class="definitionkeyword">enum</span> <span class="constant">inbuild_requirement_MT</span>
<span class="definitionkeyword">enum</span> <span class="constant">inbuild_copy_MT</span>
<span class="definitionkeyword">enum</span> <span class="constant">build_vertex_MT</span>
<span class="definitionkeyword">enum</span> <span class="constant">build_methodology_MT</span>
<span class="definitionkeyword">enum</span> <span class="constant">build_script_MT</span>
<span class="definitionkeyword">enum</span> <span class="constant">build_step_MT</span>
<span class="definitionkeyword">enum</span> <span class="constant">inbuild_nest_MT</span>
<span class="definitionkeyword">enum</span> <span class="constant">inbuild_search_result_MT</span>
<span class="definitionkeyword">enum</span> <span class="constant">inbuild_work_database_entry_array_MT</span>
<span class="definitionkeyword">enum</span> <span class="constant">extension_census_datum_MT</span>
<span class="definitionkeyword">enum</span> <span class="constant">extension_census_MT</span>
<span class="definitionkeyword">enum</span> <span class="constant">inform_template_MT</span>
<span class="definitionkeyword">enum</span> <span class="constant">inform_project_MT</span>
<span class="definitionkeyword">enum</span> <span class="constant">inform_language_MT</span>
<span class="definitionkeyword">enum</span> <span class="constant">inform_pipeline_MT</span>
<span class="definitionkeyword">enum</span> <span class="constant">copy_error_MT</span>
<span class="definitionkeyword">enum</span> <span class="constant">extension_dictionary_entry_MT</span>
<span class="definitionkeyword">enum</span> <span class="constant">known_extension_clash_MT</span>
<span class="definitionkeyword">enum</span> <span class="constant">build_skill_MT</span>
</pre>
<pre class="display">
<span class="identifier">ALLOCATE_INDIVIDUALLY</span><span class="plain">(</span><span class="reserved">inform_kit</span><span class="plain">)</span>
<span class="identifier">ALLOCATE_INDIVIDUALLY</span><span class="plain">(</span><span class="reserved">inform_extension</span><span class="plain">)</span>
<span class="identifier">ALLOCATE_INDIVIDUALLY</span><span class="plain">(</span><span class="reserved">inform_kit_ittt</span><span class="plain">)</span>
<span class="identifier">ALLOCATE_INDIVIDUALLY</span><span class="plain">(</span><span class="reserved">element_activation</span><span class="plain">)</span>
<span class="identifier">ALLOCATE_INDIVIDUALLY</span><span class="plain">(</span><span class="reserved">inbuild_genre</span><span class="plain">)</span>
<span class="identifier">ALLOCATE_INDIVIDUALLY</span><span class="plain">(</span><span class="reserved">inbuild_work</span><span class="plain">)</span>
<span class="identifier">ALLOCATE_INDIVIDUALLY</span><span class="plain">(</span><span class="reserved">inbuild_edition</span><span class="plain">)</span>
<span class="identifier">ALLOCATE_INDIVIDUALLY</span><span class="plain">(</span><span class="reserved">inbuild_requirement</span><span class="plain">)</span>
<span class="identifier">ALLOCATE_INDIVIDUALLY</span><span class="plain">(</span><span class="reserved">inbuild_copy</span><span class="plain">)</span>
<span class="identifier">ALLOCATE_INDIVIDUALLY</span><span class="plain">(</span><span class="reserved">build_vertex</span><span class="plain">)</span>
<span class="identifier">ALLOCATE_INDIVIDUALLY</span><span class="plain">(</span><span class="reserved">build_methodology</span><span class="plain">)</span>
<span class="identifier">ALLOCATE_INDIVIDUALLY</span><span class="plain">(</span><span class="reserved">build_script</span><span class="plain">)</span>
<span class="identifier">ALLOCATE_INDIVIDUALLY</span><span class="plain">(</span><span class="reserved">build_step</span><span class="plain">)</span>
<span class="identifier">ALLOCATE_INDIVIDUALLY</span><span class="plain">(</span><span class="reserved">inbuild_nest</span><span class="plain">)</span>
<span class="identifier">ALLOCATE_INDIVIDUALLY</span><span class="plain">(</span><span class="reserved">inbuild_search_result</span><span class="plain">)</span>
<span class="identifier">ALLOCATE_INDIVIDUALLY</span><span class="plain">(</span><span class="reserved">extension_census_datum</span><span class="plain">)</span>
<span class="identifier">ALLOCATE_INDIVIDUALLY</span><span class="plain">(</span><span class="reserved">extension_census</span><span class="plain">)</span>
<span class="identifier">ALLOCATE_INDIVIDUALLY</span><span class="plain">(</span><span class="reserved">inform_template</span><span class="plain">)</span>
<span class="identifier">ALLOCATE_INDIVIDUALLY</span><span class="plain">(</span><span class="reserved">inform_project</span><span class="plain">)</span>
<span class="identifier">ALLOCATE_INDIVIDUALLY</span><span class="plain">(</span><span class="reserved">inform_language</span><span class="plain">)</span>
<span class="identifier">ALLOCATE_INDIVIDUALLY</span><span class="plain">(</span><span class="reserved">inform_pipeline</span><span class="plain">)</span>
<span class="identifier">ALLOCATE_INDIVIDUALLY</span><span class="plain">(</span><span class="reserved">copy_error</span><span class="plain">)</span>
<span class="identifier">ALLOCATE_INDIVIDUALLY</span><span class="plain">(</span><span class="reserved">extension_dictionary_entry</span><span class="plain">)</span>
<span class="identifier">ALLOCATE_INDIVIDUALLY</span><span class="plain">(</span><span class="reserved">known_extension_clash</span><span class="plain">)</span>
<span class="identifier">ALLOCATE_INDIVIDUALLY</span><span class="plain">(</span><span class="reserved">build_skill</span><span class="plain">)</span>
<span class="identifier">ALLOCATE_IN_ARRAYS</span><span class="plain">(</span><span class="reserved">inbuild_work_database_entry</span><span class="plain">, 100)</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. The beginning. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">InbuildModule::start</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
&lt;<span class="cwebmacro">Register this module's memory allocation reasons</span> <span class="cwebmacronumber">3.2</span>&gt;<span class="character">;</span>
&lt;<span class="cwebmacro">Register this module's stream writers</span> <span class="cwebmacronumber">3.3</span>&gt;<span class="character">;</span>
&lt;<span class="cwebmacro">Register this module's debugging log aspects</span> <span class="cwebmacronumber">3.5</span>&gt;<span class="character">;</span>
&lt;<span class="cwebmacro">Register this module's debugging log writers</span> <span class="cwebmacronumber">3.6</span>&gt;<span class="character">;</span>
<span class="functiontext">KitManager::start</span><span class="plain">();</span>
<span class="functiontext">ExtensionManager::start</span><span class="plain">();</span>
<span class="functiontext">TemplateManager::start</span><span class="plain">();</span>
<span class="functiontext">LanguageManager::start</span><span class="plain">();</span>
<span class="functiontext">ProjectBundleManager::start</span><span class="plain">();</span>
<span class="functiontext">ProjectFileManager::start</span><span class="plain">();</span>
<span class="functiontext">PipelineManager::start</span><span class="plain">();</span>
<span class="functiontext">InterSkill::create</span><span class="plain">();</span>
<span class="functiontext">Inform7Skill::create</span><span class="plain">();</span>
<span class="functiontext">Inform6Skill::create</span><span class="plain">();</span>
<span class="functiontext">InblorbSkill::create</span><span class="plain">();</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function InbuildModule::start appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP3_1"></a><b>&#167;3.1. </b></p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">EXTENSION_DICTIONARY_MREASON</span>
</pre>
<p class="inwebparagraph"><a id="SP3_2"></a><b>&#167;3.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Register this module's memory allocation reasons</span> <span class="cwebmacronumber">3.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Memory::reason_name</span><span class="plain">(</span><span class="constant">EXTENSION_DICTIONARY_MREASON</span><span class="plain">, </span><span class="string">"extension dictionary"</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP3_3"></a><b>&#167;3.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">Register this module's stream writers</span> <span class="cwebmacronumber">3.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Writers::register_writer</span><span class="plain">(</span><span class="character">'v'</span><span class="plain">, &amp;</span><span class="identifier">VersionNumbers::writer</span><span class="plain">);</span>
<span class="identifier">Writers::register_writer</span><span class="plain">(</span><span class="character">'X'</span><span class="plain">, &amp;</span><span class="functiontext">Works::writer</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP3_4"></a><b>&#167;3.4. </b></p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">EXTENSIONS_CENSUS_DA</span>
</pre>
<p class="inwebparagraph"><a id="SP3_5"></a><b>&#167;3.5. </b><code class="display">
&lt;<span class="cwebmacrodefn">Register this module's debugging log aspects</span> <span class="cwebmacronumber">3.5</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Log::declare_aspect</span><span class="plain">(</span><span class="constant">EXTENSIONS_CENSUS_DA</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"extensions census"</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP3_6"></a><b>&#167;3.6. </b><code class="display">
&lt;<span class="cwebmacrodefn">Register this module's debugging log writers</span> <span class="cwebmacronumber">3.6</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Writers::register_writer</span><span class="plain">(</span><span class="character">'J'</span><span class="plain">, &amp;</span><span class="functiontext">Languages::log</span><span class="plain">);</span>
</pre>
<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. The end. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">InbuildModule::end</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function InbuildModule::end appears nowhere else.</p>
<hr class="tocbar">
<ul class="toc"><li><i>(This section begins Chapter 1: Setting Up.)</i></li><li><a href="1-ic.html">Continue with 'Inbuild Control'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>

View file

@ -0,0 +1,287 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>2/edt</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<!--Weave of '2/cps' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</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">
<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
some edition of it. For some genres, copies will be files; for others,
directories holding a set of files.
</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="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="identifier">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">inbuild_copy</span><span class="plain">;</span>
<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>
<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;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="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_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>
<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="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>
<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>
<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>
<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>
<span class="plain">}</span>
<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>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Copies::scan</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_SCAN_COPY_MTID</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::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="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_BUILD_COPY_MTID</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">BM</span><span class="plain">, </span><span class="identifier">FALSE</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">Copies::rebuild</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="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_BUILD_COPY_MTID</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">BM</span><span class="plain">, </span><span class="identifier">TRUE</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">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="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_BUILD_COPY_MTID</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">NULL</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="identifier">TRUE</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">WRITE</span><span class="plain">(</span><span class="string">" in directory %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="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#SP4">&#167;4</a>).</p>
<p class="endnote">The function Copies::scan 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>).</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::read_source_text_for is used in 5/ed2 (<a href="5-ed2.html#SP3_1">&#167;3.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, 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 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>
<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>
</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="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;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">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 Copies::new_error is used in 5/st (<a href="5-st.html#SP2">&#167;2</a>), 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>).</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="endnote">The function Copies::new_error_on_file is used in 5/st (<a href="5-st.html#SP1">&#167;1</a>), 5/es (<a href="5-es.html#SP1_1">&#167;1.1</a>).</p>
<p class="endnote">The function Copies::attach is used in 5/st (<a href="5-st.html#SP1">&#167;1</a>, <a href="5-st.html#SP2">&#167;2</a>), 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>).</p>
<p class="endnote">The function Copies::list_problems_arising is used in <a href="#SP1">&#167;1</a>.</p>
<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="endnote">The structure copy_error is accessed in 2/nst, 3/is, 5/st, 5/ed2, 5/ec, 5/ps and here.</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">
<!--End of weave-->
</body>
</html>

View file

@ -0,0 +1,70 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>2/wrk</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<!--Weave of '2/edt' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</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="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.
</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_edition</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">work</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">semantic_version_number</span><span class="plain"> </span><span class="identifier">version</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">compatibility_specification</span><span class="plain"> *</span><span class="identifier">compatibility</span><span class="plain">;</span>
<span class="identifier">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">inbuild_edition</span><span class="plain">;</span>
<span class="reserved">inbuild_edition</span><span class="plain"> *</span><span class="functiontext">Editions::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">semantic_version_number</span><span class="plain"> </span><span class="identifier">version</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">CREATE</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="element">&gt;work</span><span class="plain"> = </span><span class="identifier">work</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">version</span><span class="plain">;</span>
<span class="identifier">edition</span><span class="plain">-</span><span class="element">&gt;compatibility</span><span class="plain"> = </span><span class="identifier">Compatibility::all</span><span class="plain">();</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">edition</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Editions::write</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">Works::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="element">&gt;work</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">E</span><span class="plain">-</span><span class="element">&gt;version</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">VersionNumbers::is_null</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<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>
<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>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" ("</span><span class="plain">);</span>
<span class="identifier">Compatibility::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="element">&gt;compatibility</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</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 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::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/is2, 4/km, 4/em, 4/lm, 4/pbm, 4/pfm, 4/tm, 4/pm, 5/vmg, 5/kts, 5/es, 5/ed, 5/ed2, 5/ec, 5/ts, 5/ps, 5/ls, 5/ps2 and here.</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">
<!--End of weave-->
</body>
</html>

View file

@ -0,0 +1,97 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>1/ic</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<!--Weave of '2/gnr' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</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></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Genres. </b>For example, "kit" and "extension" will both be both genres. There will be
few of these.
</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_genre</span><span class="plain"> {</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">genre_name</span><span class="plain">;</span>
<span class="identifier">METHOD_CALLS</span>
<span class="identifier">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">inbuild_genre</span><span class="plain">;</span>
<span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="functiontext">Genres::new</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">gen</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">gen</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</span><span class="plain">(</span><span class="identifier">gen</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">gen</span><span class="plain">;</span>
<span class="identifier">gen</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">inbuild_genre</span><span class="plain">);</span>
<span class="identifier">gen</span><span class="plain">-</span><span class="element">&gt;genre_name</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">ENABLE_METHOD_CALLS</span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">gen</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="functiontext">Genres::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="reserved">if</span><span class="plain"> (</span><span class="identifier">G</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">I</span><span class="string">"(none)"</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="element">&gt;genre_name</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<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 structure inbuild_genre is accessed in 2/rqr and here.</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b></p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">GENRE_WRITE_WORK_MTID</span>
<span class="definitionkeyword">enum</span> <span class="constant">GENRE_CLAIM_AS_COPY_MTID</span>
<span class="definitionkeyword">enum</span> <span class="constant">GENRE_SCAN_COPY_MTID</span>
<span class="definitionkeyword">enum</span> <span class="constant">GENRE_SEARCH_NEST_FOR_MTID</span>
<span class="definitionkeyword">enum</span> <span class="constant">GENRE_COPY_TO_NEST_MTID</span>
<span class="definitionkeyword">enum</span> <span class="constant">GENRE_GO_OPERATIONAL_MTID</span>
<span class="definitionkeyword">enum</span> <span class="constant">GENRE_READ_SOURCE_TEXT_FOR_MTID</span>
<span class="definitionkeyword">enum</span> <span class="constant">GENRE_BUILD_COPY_MTID</span>
</pre>
<pre class="display">
<span class="identifier">VMETHOD_TYPE</span><span class="plain">(</span><span class="constant">GENRE_WRITE_WORK_MTID</span><span class="plain">,</span>
<span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">gen</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">OUT</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_TYPE</span><span class="plain">(</span><span class="constant">GENRE_CLAIM_AS_COPY_MTID</span><span class="plain">,</span>
<span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">gen</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">arg</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="reserved">int</span><span class="plain"> </span><span class="identifier">directory_status</span><span class="plain">)</span>
<span class="identifier">VMETHOD_TYPE</span><span class="plain">(</span><span class="constant">GENRE_SCAN_COPY_MTID</span><span class="plain">,</span>
<span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">gen</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_TYPE</span><span class="plain">(</span><span class="constant">GENRE_SEARCH_NEST_FOR_MTID</span><span class="plain">,</span>
<span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">gen</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_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_results</span><span class="plain">)</span>
<span class="identifier">VMETHOD_TYPE</span><span class="plain">(</span><span class="constant">GENRE_COPY_TO_NEST_MTID</span><span class="plain">,</span>
<span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">gen</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">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="identifier">VMETHOD_TYPE</span><span class="plain">(</span><span class="constant">GENRE_GO_OPERATIONAL_MTID</span><span class="plain">,</span>
<span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">gen</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_TYPE</span><span class="plain">(</span><span class="constant">GENRE_READ_SOURCE_TEXT_FOR_MTID</span><span class="plain">,</span>
<span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">gen</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_TYPE</span><span class="plain">(</span><span class="constant">GENRE_BUILD_COPY_MTID</span><span class="plain">,</span>
<span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">gen</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">OUT</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">int</span><span class="plain"> </span><span class="identifier">rebuild</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">describe_only</span><span class="plain">)</span>
</pre>
<p class="inwebparagraph"></p>
<hr class="tocbar">
<ul class="toc"><li><i>(This section begins Chapter 2: Conceptual Framework.)</i></li><li><a href="2-wrk.html">Continue with 'Works'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>

View file

@ -0,0 +1,127 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>2/rqr</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<!--Weave of '2/nst' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</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>
<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="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>
<span class="identifier">N</span><span class="plain">-</span><span class="element">&gt;read_only</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<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>
<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>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Nests::set_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">int</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">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>
<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>
<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="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>
<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>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">already_here</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">inbuild_nest</span><span class="plain"> *</span><span class="identifier">M</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">M</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="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">MS</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">M</span><span class="plain">-</span><span class="element">&gt;location</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">NS</span><span class="plain">, </span><span class="identifier">MS</span><span class="plain">)) </span><span class="identifier">already_here</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">MS</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">NS</span><span class="plain">);</span>
<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>
<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>
<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="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>
<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="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#SP6">&#167;6</a>).</p>
<p class="endnote">The function Nests::get_tag is used in 1/ic (<a href="1-ic.html#SP7">&#167;7</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>).</p>
<p class="endnote">The function Nests::set_tag is used in 1/ic (<a href="1-ic.html#SP6">&#167;6</a>).</p>
<p class="endnote">The function Nests::protect is used in 1/ic (<a href="1-ic.html#SP6">&#167;6</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 3/is (<a href="3-is.html#SP1">&#167;1</a>), 5/ed2 (<a href="5-ed2.html#SP4">&#167;4</a>), 5/ec (<a href="5-ec.html#SP3">&#167;3</a>), 5/ps (<a href="5-ps.html#SP1">&#167;1</a>).</p>
<p class="endnote">The function Nests::copy_to appears nowhere else.</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/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/ed2, 5/ec, 5/ps and here.</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">
<!--End of weave-->
</body>
</html>

View file

@ -0,0 +1,236 @@
<!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 http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<!--Weave of '2/rqr' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</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".
</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_requirement</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">work</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">semantic_version_number</span><span class="plain"> </span><span class="identifier">min_version</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">semantic_version_number</span><span class="plain"> </span><span class="identifier">max_version</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">allow_malformed</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>
<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">semantic_version_number</span><span class="plain"> </span><span class="identifier">min</span><span class="plain">, </span><span class="identifier">semantic_version_number</span><span class="plain"> </span><span class="identifier">max</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>
<span class="identifier">req</span><span class="plain">-</span><span class="element">&gt;min_version</span><span class="plain"> = </span><span class="identifier">min</span><span class="plain">;</span>
<span class="identifier">req</span><span class="plain">-</span><span class="element">&gt;max_version</span><span class="plain"> = </span><span class="identifier">max</span><span class="plain">;</span>
<span class="identifier">req</span><span class="plain">-</span><span class="element">&gt;allow_malformed</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">req</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">inbuild_requirement</span><span class="plain"> *</span><span class="functiontext">Requirements::any_version_of</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">return</span><span class="plain"> </span><span class="functiontext">Requirements::new</span><span class="plain">(</span><span class="identifier">work</span><span class="plain">, </span><span class="identifier">VersionNumbers::null</span><span class="plain">(), </span><span class="identifier">VersionNumbers::null</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="reserved">inbuild_requirement</span><span class="plain"> *</span><span class="functiontext">Requirements::anything_of_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="reserved">return</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">G</span><span class="plain">, </span><span class="identifier">I</span><span class="string">""</span><span class="plain">, </span><span class="identifier">I</span><span class="string">""</span><span class="plain">));</span>
<span class="plain">}</span>
<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>
<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>
<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">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">initial</span><span class="plain">);</span>
<span class="identifier">Str::substr</span><span class="plain">(</span><span class="identifier">initial</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">from</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="functiontext">Requirements::impose_clause</span><span class="plain">(</span><span class="identifier">req</span><span class="plain">, </span><span class="identifier">initial</span><span class="plain">, </span><span class="identifier">errors</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">initial</span><span class="plain">);</span>
<span class="identifier">from</span><span class="plain"> = </span><span class="identifier">at</span><span class="plain"> + 1;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">from</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">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">final</span><span class="plain">);</span>
<span class="identifier">Str::substr</span><span class="plain">(</span><span class="identifier">final</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">from</span><span class="plain">), </span><span class="identifier">Str::end</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">));</span>
<span class="functiontext">Requirements::impose_clause</span><span class="plain">(</span><span class="identifier">req</span><span class="plain">, </span><span class="identifier">final</span><span class="plain">, </span><span class="identifier">errors</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">final</span><span class="plain">);</span>
<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>
<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::get_last_char</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">) == </span><span class="character">'*'</span><span class="plain">) {</span>
<span class="identifier">req</span><span class="plain">-</span><span class="element">&gt;allow_malformed</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">Str::delete_last_character</span><span class="plain">(</span><span class="identifier">T</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="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">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">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">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;min_version</span><span class="plain"> = </span><span class="identifier">V</span><span class="plain">;</span>
<span class="identifier">req</span><span class="plain">-</span><span class="element">&gt;max_version</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;min_version</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;max_version</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="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">value</span><span class="plain">);</span>
<span class="plain">}</span>
<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>
<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">claused</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">","</span><span class="plain">); </span><span class="identifier">claused</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"genre=%S"</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="element">&gt;genre_name</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">claused</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">","</span><span class="plain">); </span><span class="identifier">claused</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"work=%S"</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="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">claused</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">","</span><span class="plain">); </span><span class="identifier">claused</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"author=%S"</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="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">req</span><span class="plain">-</span><span class="element">&gt;min_version</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">claused</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">","</span><span class="plain">); </span><span class="identifier">claused</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"min=%v"</span><span class="plain">, &amp;(</span><span class="identifier">req</span><span class="plain">-</span><span class="element">&gt;min_version</span><span class="plain">));</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">req</span><span class="plain">-</span><span class="element">&gt;max_version</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">claused</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">","</span><span class="plain">); </span><span class="identifier">claused</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"max=%v"</span><span class="plain">, &amp;(</span><span class="identifier">req</span><span class="plain">-</span><span class="element">&gt;max_version</span><span class="plain">));</span>
<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="reserved">if</span><span class="plain"> (</span><span class="identifier">req</span><span class="plain">-</span><span class="element">&gt;allow_malformed</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"*"</span><span class="plain">);</span>
<span class="plain">}</span>
<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="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">req</span><span class="plain">-</span><span class="element">&gt;allow_malformed</span><span class="plain">) &amp;&amp; (</span><span class="identifier">Str::len</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">) == 0)) </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">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::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">if</span><span class="plain"> (</span><span class="identifier">VersionNumbers::is_null</span><span class="plain">(</span><span class="identifier">req</span><span class="plain">-</span><span class="element">&gt;min_version</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::is_null</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="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::lt</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;min_version</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">VersionNumbers::is_null</span><span class="plain">(</span><span class="identifier">req</span><span class="plain">-</span><span class="element">&gt;max_version</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::is_null</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="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">VersionNumbers::gt</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;max_version</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">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Requirements::ratchet_minimum</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="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">internal_error</span><span class="plain">(</span><span class="string">"no requirement"</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">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::is_null</span><span class="plain">(</span><span class="identifier">req</span><span class="plain">-</span><span class="element">&gt;min_version</span><span class="plain">)) ||</span>
<span class="plain">(</span><span class="identifier">VersionNumbers::gt</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">, </span><span class="identifier">req</span><span class="plain">-</span><span class="element">&gt;min_version</span><span class="plain">))) {</span>
<span class="identifier">req</span><span class="plain">-</span><span class="element">&gt;min_version</span><span class="plain"> = </span><span class="identifier">V</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="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Requirements::new appears nowhere else.</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/ps (<a href="5-ps.html#SP1">&#167;1</a>).</p>
<p class="endnote">The function Requirements::anything_of_genre is used in 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/es (<a href="5-es.html#SP4">&#167;4</a>), 5/ed2 (<a href="5-ed2.html#SP4">&#167;4</a>).</p>
<p class="endnote">The function Requirements::ratchet_minimum is used in 5/es (<a href="5-es.html#SP4">&#167;4</a>).</p>
<p class="endnote">The structure inbuild_requirement is accessed in 2/wrk, 2/edt, 2/cps, 2/nst, 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 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">
<!--End of weave-->
</body>
</html>

View file

@ -0,0 +1,607 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>2/gnr</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<!--Weave of '2/wrk' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</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">
<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
may exist over time, but they will all be versions of the same "work".
Extensions are also works: for example, Epistemology by Eric Eve is a work.
</p>
<p class="inwebparagraph">Works are identified by the pair of title and author name, each of which is an
ISO Latin-1 string limited in length, with certain bad-news characters
excluded (such as <code class="display"><span class="extract">/</span></code> and <code class="display"><span class="extract">:</span></code>) so that they can be used directly in filenames.
However, we will not want to compare these by string comparison: so we
hash-code the combination for speed. The following structure holds a
combination of the textual names and the hash code:
</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_work</span><span class="plain"> {</span>
<span class="reserved">struct</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="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">author_name</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">raw_author_name</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">title</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">raw_title</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">inbuild_work_hash_code</span><span class="plain">; </span> <span class="comment">hash code derived from the above</span>
<span class="identifier">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">inbuild_work</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The structure inbuild_work is accessed in 2/cps, 2/rqr, 2/nst, 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 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.
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">WORK_HASH_CODING_BASE</span><span class="plain"> 499</span>
</pre>
<pre class="display">
<span class="reserved">inbuild_work</span><span class="plain"> *</span><span class="functiontext">Works::new</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">TRUE</span><span class="plain">);</span>
<span class="plain">}</span>
<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>
<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>
<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">an</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">Str::duplicate</span><span class="plain">(</span><span class="identifier">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">ti</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="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">ti</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">norm</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;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>
<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>
<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="character">'/'</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">work</span><span class="plain">-</span><span class="element">&gt;title</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>
<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>
<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>
<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>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Works::write_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="reserved">int</span><span class="plain"> </span><span class="identifier">fancy</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="identifier">fancy</span><span class="plain">) </span><span class="identifier">HTML::begin_colour</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"404040"</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" by "</span><span class="plain">);</span>
<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>
<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>
<span class="identifier">HTML::begin_colour</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"404040"</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">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;title</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="functiontext">Works::write_to_HTML_file</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="identifier">FALSE</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">HTML_CLOSE</span><span class="plain">(</span><span class="string">"a"</span><span class="plain">);</span>
<span class="plain">}</span>
<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>
<span class="reserved">case</span><span class="plain"> </span><span class="character">'&lt;'</span><span class="plain">:</span>
<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="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>
<span class="reserved">case</span><span class="plain"> </span><span class="character">'X'</span><span class="plain">:</span>
<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">"&lt;no extension&gt;"</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 by %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="identifier">work</span><span class="plain">-</span><span class="element">&gt;raw_author_name</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">"bad %X extension"</span><span class="plain">);</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="#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/ps (<a href="5-ps.html#SP1">&#167;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>).</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
name. This is in effect case insensitive, since we normalised casing when
the works were created.
</p>
<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...)
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Works::match</span><span class="plain">(</span><span class="reserved">inbuild_work</span><span class="plain"> *</span><span class="identifier">eid1</span><span class="plain">, </span><span class="reserved">inbuild_work</span><span class="plain"> *</span><span class="identifier">eid2</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">eid1</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) || (</span><span class="identifier">eid2</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 work match"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">eid1</span><span class="plain">-</span><span class="element">&gt;inbuild_work_hash_code</span><span class="plain"> != </span><span class="identifier">eid2</span><span class="plain">-</span><span class="element">&gt;inbuild_work_hash_code</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">Str::eq</span><span class="plain">(</span><span class="identifier">eid1</span><span class="plain">-</span><span class="element">&gt;author_name</span><span class="plain">, </span><span class="identifier">eid2</span><span class="plain">-</span><span class="element">&gt;author_name</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</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">eid1</span><span class="plain">-</span><span class="element">&gt;title</span><span class="plain">, </span><span class="identifier">eid2</span><span class="plain">-</span><span class="element">&gt;title</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<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>).</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>These are quite a deal slower, but trichotomous.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Works::compare</span><span class="plain">(</span><span class="reserved">inbuild_work</span><span class="plain"> *</span><span class="identifier">eid1</span><span class="plain">, </span><span class="reserved">inbuild_work</span><span class="plain"> *</span><span class="identifier">eid2</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">eid1</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) || (</span><span class="identifier">eid2</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 work match"</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">d</span><span class="plain"> = </span><span class="identifier">Str::cmp</span><span class="plain">(</span><span class="identifier">eid1</span><span class="plain">-</span><span class="element">&gt;author_name</span><span class="plain">, </span><span class="identifier">eid2</span><span class="plain">-</span><span class="element">&gt;author_name</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">d</span><span class="plain"> != 0) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">d</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">Str::cmp</span><span class="plain">(</span><span class="identifier">eid1</span><span class="plain">-</span><span class="element">&gt;title</span><span class="plain">, </span><span class="identifier">eid2</span><span class="plain">-</span><span class="element">&gt;title</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Works::compare_by_title</span><span class="plain">(</span><span class="reserved">inbuild_work</span><span class="plain"> *</span><span class="identifier">eid1</span><span class="plain">, </span><span class="reserved">inbuild_work</span><span class="plain"> *</span><span class="identifier">eid2</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">eid1</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) || (</span><span class="identifier">eid2</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 work match"</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">d</span><span class="plain"> = </span><span class="identifier">Str::cmp</span><span class="plain">(</span><span class="identifier">eid1</span><span class="plain">-</span><span class="element">&gt;title</span><span class="plain">, </span><span class="identifier">eid2</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">d</span><span class="plain"> != 0) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">d</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">Str::cmp</span><span class="plain">(</span><span class="identifier">eid1</span><span class="plain">-</span><span class="element">&gt;author_name</span><span class="plain">, </span><span class="identifier">eid2</span><span class="plain">-</span><span class="element">&gt;author_name</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Works::compare_by_date</span><span class="plain">(</span><span class="reserved">inbuild_work</span><span class="plain"> *</span><span class="identifier">eid1</span><span class="plain">, </span><span class="reserved">inbuild_work</span><span class="plain"> *</span><span class="identifier">eid2</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">eid1</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) || (</span><span class="identifier">eid2</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 work match"</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">d</span><span class="plain"> = </span><span class="identifier">Str::cmp</span><span class="plain">(</span><span class="functiontext">Works::get_sort_date</span><span class="plain">(</span><span class="identifier">eid2</span><span class="plain">), </span><span class="functiontext">Works::get_sort_date</span><span class="plain">(</span><span class="identifier">eid1</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">d</span><span class="plain"> != 0) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">d</span><span class="plain">;</span>
<span class="identifier">d</span><span class="plain"> = </span><span class="identifier">Str::cmp</span><span class="plain">(</span><span class="identifier">eid1</span><span class="plain">-</span><span class="element">&gt;title</span><span class="plain">, </span><span class="identifier">eid2</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">d</span><span class="plain"> != 0) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">d</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">Str::cmp</span><span class="plain">(</span><span class="identifier">eid1</span><span class="plain">-</span><span class="element">&gt;author_name</span><span class="plain">, </span><span class="identifier">eid2</span><span class="plain">-</span><span class="element">&gt;author_name</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Works::compare_by_length</span><span class="plain">(</span><span class="reserved">inbuild_work</span><span class="plain"> *</span><span class="identifier">eid1</span><span class="plain">, </span><span class="reserved">inbuild_work</span><span class="plain"> *</span><span class="identifier">eid2</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">eid1</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) || (</span><span class="identifier">eid2</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 work match"</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">d</span><span class="plain"> = </span><span class="identifier">Str::cmp</span><span class="plain">(</span><span class="functiontext">Works::get_sort_word_count</span><span class="plain">(</span><span class="identifier">eid2</span><span class="plain">), </span><span class="functiontext">Works::get_sort_word_count</span><span class="plain">(</span><span class="identifier">eid1</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">d</span><span class="plain"> != 0) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">d</span><span class="plain">;</span>
<span class="identifier">d</span><span class="plain"> = </span><span class="identifier">Str::cmp</span><span class="plain">(</span><span class="identifier">eid1</span><span class="plain">-</span><span class="element">&gt;title</span><span class="plain">, </span><span class="identifier">eid2</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">d</span><span class="plain"> != 0) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">d</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">Str::cmp</span><span class="plain">(</span><span class="identifier">eid1</span><span class="plain">-</span><span class="element">&gt;author_name</span><span class="plain">, </span><span class="identifier">eid2</span><span class="plain">-</span><span class="element">&gt;author_name</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Works::compare is used in 5/ed (<a href="5-ed.html#SP18">&#167;18</a>), 5/ec (<a href="5-ec.html#SP8">&#167;8</a>).</p>
<p class="endnote">The function Works::compare_by_title is used in 5/ec (<a href="5-ec.html#SP8">&#167;8</a>).</p>
<p class="endnote">The function Works::compare_by_date is used in 5/ec (<a href="5-ec.html#SP8">&#167;8</a>).</p>
<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>
<pre class="display">
<span class="reserved">inbuild_work</span><span class="plain"> *</span><span class="identifier">a_work_for_standard_rules</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Works::is_standard_rules</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">if</span><span class="plain"> (</span><span class="identifier">a_work_for_standard_rules</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
<span class="identifier">a_work_for_standard_rules</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">"Standard Rules"</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Graham Nelson"</span><span class="plain">);</span>
<span class="functiontext">Works::add_to_database</span><span class="plain">(</span><span class="identifier">a_work_for_standard_rules</span><span class="plain">, </span><span class="constant">HYPOTHETICAL_WDBC</span><span class="plain">);</span>
<span class="plain">}</span>
<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="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Works::match</span><span class="plain">(</span><span class="identifier">work</span><span class="plain">, </span><span class="identifier">a_work_for_standard_rules</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">inbuild_work</span><span class="plain"> *</span><span class="identifier">a_work_for_basic_inform</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Works::is_basic_inform</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">if</span><span class="plain"> (</span><span class="identifier">a_work_for_basic_inform</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
<span class="identifier">a_work_for_basic_inform</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">"Basic Inform"</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Graham Nelson"</span><span class="plain">);</span>
<span class="functiontext">Works::add_to_database</span><span class="plain">(</span><span class="identifier">a_work_for_basic_inform</span><span class="plain">, </span><span class="constant">HYPOTHETICAL_WDBC</span><span class="plain">);</span>
<span class="plain">}</span>
<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="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Works::match</span><span class="plain">(</span><span class="identifier">work</span><span class="plain">, </span><span class="identifier">a_work_for_basic_inform</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<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_basic_inform appears nowhere else.</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
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
has been used, and store that in a hash table. Note that each distinct work
is recorded only once in the table: this is important, as although an
individual extension can only be loaded or installed once, it could be
referred to in the dictionary dozens or even hundreds of times.
</p>
<p class="inwebparagraph">The table is unsorted and is intended for rapid searching. Typically there
will be only a handful of works in the list of those with a given hash code:
indeed, the typical number will be 0 or 1.
</p>
<p class="inwebparagraph">Works are entered into the database with one of the following contexts:
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">NO_WDB_CONTEXTS</span><span class="plain"> 6</span>
<span class="definitionkeyword">define</span> <span class="constant">LOADED_WDBC</span><span class="plain"> 0</span>
<span class="definitionkeyword">define</span> <span class="constant">INSTALLED_WDBC</span><span class="plain"> 1</span>
<span class="definitionkeyword">define</span> <span class="constant">DICTIONARY_REFERRED_WDBC</span><span class="plain"> 2</span>
<span class="definitionkeyword">define</span> <span class="constant">HYPOTHETICAL_WDBC</span><span class="plain"> 3</span>
<span class="definitionkeyword">define</span> <span class="constant">USEWITH_WDBC</span><span class="plain"> 4</span>
<span class="definitionkeyword">define</span> <span class="constant">CLAIMED_WDBC</span><span class="plain"> 5</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">inbuild_work_database_entry</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">work</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">inbuild_work_database_entry</span><span class="plain"> *</span><span class="identifier">hash_next</span><span class="plain">; </span> <span class="comment">next one in hashed work database</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">incidence_count</span><span class="plain">[</span><span class="constant">NO_WDB_CONTEXTS</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">last_usage_date</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">sort_usage_date</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">word_count_text</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">word_count_number</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">inbuild_work_database_entry</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">work_database_created</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">inbuild_work_database_entry</span><span class="plain"> *</span><span class="identifier">hash_of_works</span><span class="plain">[</span><span class="constant">WORK_HASH_CODING_BASE</span><span class="plain">];</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Works::add_to_database</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">int</span><span class="plain"> </span><span class="identifier">context</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">work_database_created</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<span class="identifier">work_database_created</span><span class="plain"> = </span><span class="identifier">TRUE</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">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="constant">WORK_HASH_CODING_BASE</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">hash_of_works</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">hc</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">inbuild_work_database_entry</span><span class="plain"> *</span><span class="identifier">iwde</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">iwde</span><span class="plain"> = </span><span class="identifier">hash_of_works</span><span class="plain">[</span><span class="identifier">hc</span><span class="plain">]; </span><span class="identifier">iwde</span><span class="plain">; </span><span class="identifier">iwde</span><span class="plain"> = </span><span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;hash_next</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Works::match</span><span class="plain">(</span><span class="identifier">work</span><span class="plain">, </span><span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">)) {</span>
<span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;incidence_count</span><span class="plain">[</span><span class="identifier">context</span><span class="plain">]++;</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">iwde</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">inbuild_work_database_entry</span><span class="plain">);</span>
<span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;hash_next</span><span class="plain"> = </span><span class="identifier">hash_of_works</span><span class="plain">[</span><span class="identifier">hc</span><span class="plain">]; </span><span class="identifier">hash_of_works</span><span class="plain">[</span><span class="identifier">hc</span><span class="plain">] = </span><span class="identifier">iwde</span><span class="plain">;</span>
<span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain"> = </span><span class="identifier">work</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">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="constant">NO_WDB_CONTEXTS</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;incidence_count</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] = 0;</span>
<span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;incidence_count</span><span class="plain">[</span><span class="identifier">context</span><span class="plain">] = 1;</span>
<span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;last_usage_date</span><span class="plain"> = </span><span class="identifier">Str::new</span><span class="plain">();</span>
<span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;sort_usage_date</span><span class="plain"> = </span><span class="identifier">Str::new</span><span class="plain">();</span>
<span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;word_count_text</span><span class="plain"> = </span><span class="identifier">Str::new</span><span class="plain">();</span>
<span class="plain">}</span>
</pre>
<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>).</p>
<p class="endnote">The structure inbuild_work_database_entry is accessed in 2/edt, 2/cps, 2/rqr, 2/nst, 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 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>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Works::set_usage_date</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">date</span><span class="plain">) {</span>
<span class="reserved">inbuild_work_database_entry</span><span class="plain"> *</span><span class="identifier">iwde</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="identifier">work</span><span class="plain">-</span><span class="element">&gt;inbuild_work_hash_code</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">iwde</span><span class="plain"> = </span><span class="identifier">hash_of_works</span><span class="plain">[</span><span class="identifier">hc</span><span class="plain">]; </span><span class="identifier">iwde</span><span class="plain">; </span><span class="identifier">iwde</span><span class="plain"> = </span><span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;hash_next</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Works::match</span><span class="plain">(</span><span class="identifier">work</span><span class="plain">, </span><span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">)) {</span>
<span class="identifier">Str::copy</span><span class="plain">(</span><span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;last_usage_date</span><span class="plain">, </span><span class="identifier">date</span><span class="plain">);</span>
<span class="reserved">return</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">Works::set_sort_date</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">date</span><span class="plain">) {</span>
<span class="reserved">inbuild_work_database_entry</span><span class="plain"> *</span><span class="identifier">iwde</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="identifier">work</span><span class="plain">-</span><span class="element">&gt;inbuild_work_hash_code</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">iwde</span><span class="plain"> = </span><span class="identifier">hash_of_works</span><span class="plain">[</span><span class="identifier">hc</span><span class="plain">]; </span><span class="identifier">iwde</span><span class="plain">; </span><span class="identifier">iwde</span><span class="plain"> = </span><span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;hash_next</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Works::match</span><span class="plain">(</span><span class="identifier">work</span><span class="plain">, </span><span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">)) {</span>
<span class="identifier">Str::copy</span><span class="plain">(</span><span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;sort_usage_date</span><span class="plain">, </span><span class="identifier">date</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="functiontext">Works::get_usage_date</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_database_entry</span><span class="plain"> *</span><span class="identifier">iwde</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="identifier">work</span><span class="plain">-</span><span class="element">&gt;inbuild_work_hash_code</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">iwde</span><span class="plain"> = </span><span class="identifier">hash_of_works</span><span class="plain">[</span><span class="identifier">hc</span><span class="plain">]; </span><span class="identifier">iwde</span><span class="plain">; </span><span class="identifier">iwde</span><span class="plain"> = </span><span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;hash_next</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Works::match</span><span class="plain">(</span><span class="identifier">work</span><span class="plain">, </span><span class="identifier">iwde</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">Str::len</span><span class="plain">(</span><span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;last_usage_date</span><span class="plain">) &gt; 0)</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;last_usage_date</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;incidence_count</span><span class="plain">[</span><span class="constant">DICTIONARY_REFERRED_WDBC</span><span class="plain">] &gt; 0)</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">I</span><span class="string">"Once upon a time"</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">I</span><span class="string">"Never"</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">I</span><span class="string">"---"</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="functiontext">Works::get_sort_date</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_database_entry</span><span class="plain"> *</span><span class="identifier">iwde</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="identifier">work</span><span class="plain">-</span><span class="element">&gt;inbuild_work_hash_code</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">iwde</span><span class="plain"> = </span><span class="identifier">hash_of_works</span><span class="plain">[</span><span class="identifier">hc</span><span class="plain">]; </span><span class="identifier">iwde</span><span class="plain">; </span><span class="identifier">iwde</span><span class="plain"> = </span><span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;hash_next</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Works::match</span><span class="plain">(</span><span class="identifier">work</span><span class="plain">, </span><span class="identifier">iwde</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">Str::len</span><span class="plain">(</span><span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;sort_usage_date</span><span class="plain">) &gt; 0)</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;sort_usage_date</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;incidence_count</span><span class="plain">[</span><span class="constant">DICTIONARY_REFERRED_WDBC</span><span class="plain">] &gt; 0)</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">I</span><span class="string">"00000000000000Once upon a time"</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">I</span><span class="string">"00000000000000Never"</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">I</span><span class="string">"000000000000000"</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Works::set_word_count</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">int</span><span class="plain"> </span><span class="identifier">wc</span><span class="plain">) {</span>
<span class="reserved">inbuild_work_database_entry</span><span class="plain"> *</span><span class="identifier">iwde</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="identifier">work</span><span class="plain">-</span><span class="element">&gt;inbuild_work_hash_code</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">iwde</span><span class="plain"> = </span><span class="identifier">hash_of_works</span><span class="plain">[</span><span class="identifier">hc</span><span class="plain">]; </span><span class="identifier">iwde</span><span class="plain">; </span><span class="identifier">iwde</span><span class="plain"> = </span><span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;hash_next</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Works::match</span><span class="plain">(</span><span class="identifier">work</span><span class="plain">, </span><span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">)) {</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;word_count_text</span><span class="plain">, </span><span class="string">"%08d words"</span><span class="plain">, </span><span class="identifier">wc</span><span class="plain">);</span>
<span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;word_count_number</span><span class="plain"> = </span><span class="identifier">wc</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="functiontext">Works::get_sort_word_count</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_database_entry</span><span class="plain"> *</span><span class="identifier">iwde</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="identifier">work</span><span class="plain">-</span><span class="element">&gt;inbuild_work_hash_code</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">iwde</span><span class="plain"> = </span><span class="identifier">hash_of_works</span><span class="plain">[</span><span class="identifier">hc</span><span class="plain">]; </span><span class="identifier">iwde</span><span class="plain">; </span><span class="identifier">iwde</span><span class="plain"> = </span><span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;hash_next</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Works::match</span><span class="plain">(</span><span class="identifier">work</span><span class="plain">, </span><span class="identifier">iwde</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">Str::len</span><span class="plain">(</span><span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;word_count_text</span><span class="plain">) &gt; 0)</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;word_count_text</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;incidence_count</span><span class="plain">[</span><span class="constant">DICTIONARY_REFERRED_WDBC</span><span class="plain">] &gt; 0)</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">I</span><span class="string">"00000000I did read this, but forgot"</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">I</span><span class="string">"00000000I've never read this"</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">I</span><span class="string">"---"</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Works::forgot</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_database_entry</span><span class="plain"> *</span><span class="identifier">iwde</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="identifier">work</span><span class="plain">-</span><span class="element">&gt;inbuild_work_hash_code</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">iwde</span><span class="plain"> = </span><span class="identifier">hash_of_works</span><span class="plain">[</span><span class="identifier">hc</span><span class="plain">]; </span><span class="identifier">iwde</span><span class="plain">; </span><span class="identifier">iwde</span><span class="plain"> = </span><span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;hash_next</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Works::match</span><span class="plain">(</span><span class="identifier">work</span><span class="plain">, </span><span class="identifier">iwde</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">Str::len</span><span class="plain">(</span><span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;word_count_text</span><span class="plain">) &gt; 0)</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">iwde</span><span class="plain">-</span><span class="element">&gt;incidence_count</span><span class="plain">[</span><span class="constant">DICTIONARY_REFERRED_WDBC</span><span class="plain">] &gt; 0)</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
<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">int</span><span class="plain"> </span><span class="functiontext">Works::never</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_database_entry</span><span class="plain"> *</span><span class="identifier">iwde</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="identifier">work</span><span class="plain">-</span><span class="element">&gt;inbuild_work_hash_code</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">iwde</span><span class="plain"> = </span><span class="identifier">hash_of_works</span><span class="plain">[</span><span class="identifier">hc</span><span class="plain">]; </span><span class="identifier">iwde</span><span class="plain">; </span><span class="identifier">iwde</span><span class="plain"> = </span><span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;hash_next</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Works::match</span><span class="plain">(</span><span class="identifier">work</span><span class="plain">, </span><span class="identifier">iwde</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">Str::len</span><span class="plain">(</span><span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;word_count_text</span><span class="plain">) &gt; 0)</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">iwde</span><span class="plain">-</span><span class="element">&gt;incidence_count</span><span class="plain">[</span><span class="constant">DICTIONARY_REFERRED_WDBC</span><span class="plain">] &gt; 0)</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="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">int</span><span class="plain"> </span><span class="functiontext">Works::get_word_count</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_database_entry</span><span class="plain"> *</span><span class="identifier">iwde</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="identifier">work</span><span class="plain">-</span><span class="element">&gt;inbuild_work_hash_code</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">iwde</span><span class="plain"> = </span><span class="identifier">hash_of_works</span><span class="plain">[</span><span class="identifier">hc</span><span class="plain">]; </span><span class="identifier">iwde</span><span class="plain">; </span><span class="identifier">iwde</span><span class="plain"> = </span><span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;hash_next</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Works::match</span><span class="plain">(</span><span class="identifier">work</span><span class="plain">, </span><span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">))</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;word_count_number</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> 0;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Works::set_usage_date is used in 5/ed (<a href="5-ed.html#SP10">&#167;10</a>).</p>
<p class="endnote">The function Works::set_sort_date is used in 5/ed (<a href="5-ed.html#SP10">&#167;10</a>).</p>
<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::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::forgot 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::never 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_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
for one of the following usage counts:
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Works::no_times_used_in_context</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">int</span><span class="plain"> </span><span class="identifier">context</span><span class="plain">) {</span>
<span class="reserved">inbuild_work_database_entry</span><span class="plain"> *</span><span class="identifier">iwde</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">iwde</span><span class="plain"> = </span><span class="identifier">hash_of_works</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="identifier">iwde</span><span class="plain">; </span><span class="identifier">iwde</span><span class="plain"> = </span><span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;hash_next</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Works::match</span><span class="plain">(</span><span class="identifier">work</span><span class="plain">, </span><span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;incidence_count</span><span class="plain">[</span><span class="identifier">context</span><span class="plain">];</span>
<span class="reserved">return</span><span class="plain"> 0;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<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>).</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. </b>The work hash table makes quite interesting reading, so:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Works::log_work_hash_table</span><span class="plain">(</span><span class="reserved">void</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="identifier">total</span><span class="plain"> = 0;</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Work identifier hash table:\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">hc</span><span class="plain">=0; </span><span class="identifier">hc</span><span class="plain">&lt;</span><span class="constant">WORK_HASH_CODING_BASE</span><span class="plain">; </span><span class="identifier">hc</span><span class="plain">++) {</span>
<span class="reserved">inbuild_work_database_entry</span><span class="plain"> *</span><span class="identifier">iwde</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">iwde</span><span class="plain"> = </span><span class="identifier">hash_of_works</span><span class="plain">[</span><span class="identifier">hc</span><span class="plain">]; </span><span class="identifier">iwde</span><span class="plain">; </span><span class="identifier">iwde</span><span class="plain"> = </span><span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;hash_next</span><span class="plain">) {</span>
<span class="identifier">total</span><span class="plain">++;</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"%03d %3d %3d %3d %3d %X\</span><span class="plain">n</span><span class="string">"</span><span class="plain">,</span>
<span class="identifier">hc</span><span class="plain">, </span><span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;incidence_count</span><span class="plain">[0], </span><span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;incidence_count</span><span class="plain">[1],</span>
<span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;incidence_count</span><span class="plain">[2], </span><span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;incidence_count</span><span class="plain">[3],</span>
<span class="identifier">iwde</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"%d entries in all\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">total</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<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
each extension's page is generated from its <code class="display"><span class="extract">inbuild_work</span></code>.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Works::begin_extension_link</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">text_stream</span><span class="plain"> *</span><span class="identifier">rubric</span><span class="plain">) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">link</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">link</span><span class="plain">, </span><span class="string">"href='inform://Extensions/Extensions/"</span><span class="plain">);</span>
<span class="functiontext">Works::escape_apostrophes</span><span class="plain">(</span><span class="identifier">link</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">WRITE_TO</span><span class="plain">(</span><span class="identifier">link</span><span class="plain">, </span><span class="string">"/"</span><span class="plain">);</span>
<span class="functiontext">Works::escape_apostrophes</span><span class="plain">(</span><span class="identifier">link</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="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">link</span><span class="plain">, </span><span class="string">".html' "</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">rubric</span><span class="plain">) &gt; 0) </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">link</span><span class="plain">, </span><span class="string">"title=\</span><span class="plain">"</span><span class="string">%S\</span><span class="plain">"</span><span class="string"> "</span><span class="plain">, </span><span class="identifier">rubric</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">link</span><span class="plain">, </span><span class="string">"title=\</span><span class="plain">"</span><span class="string">%X\</span><span class="plain">"</span><span class="string"> "</span><span class="plain">, </span><span class="identifier">work</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">link</span><span class="plain">, </span><span class="string">"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">HTML_OPEN_WITH</span><span class="plain">(</span><span class="string">"a"</span><span class="plain">, </span><span class="string">"%S"</span><span class="plain">, </span><span class="identifier">link</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">link</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Works::escape_apostrophes</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">S</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">S</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">c</span><span class="plain"> == </span><span class="character">'\</span><span class="plain">'</span><span class="character">'</span><span class="plain">) || (</span><span class="identifier">c</span><span class="plain"> == </span><span class="character">'\</span><span class="plain">"</span><span class="character">'</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">c</span><span class="plain"> == </span><span class="character">'&amp;'</span><span class="plain">) ||</span>
<span class="plain">(</span><span class="identifier">c</span><span class="plain"> == </span><span class="character">'&lt;'</span><span class="plain">) || (</span><span class="identifier">c</span><span class="plain"> == </span><span class="character">'&gt;'</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">WRITE</span><span class="plain">(</span><span class="string">"%%%x"</span><span class="plain">, (</span><span class="reserved">int</span><span class="plain">) </span><span class="identifier">c</span><span class="plain">);</span>
<span class="reserved">else</span>
<span class="identifier">PUT</span><span class="plain">(</span><span class="identifier">c</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">Works::end_extension_link</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_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::begin_extension_link is used in 5/ec (<a href="5-ec.html#SP6_7_4_1">&#167;6.7.4.1</a>).</p>
<p class="endnote">The function Works::escape_apostrophes appears nowhere else.</p>
<p class="endnote">The function Works::end_extension_link is used in 5/ec (<a href="5-ec.html#SP6_7_4_1">&#167;6.7.4.1</a>).</p>
<hr class="tocbar">
<ul class="toc"><li><a href="2-gnr.html">Back to 'Genres'</a></li><li><a href="2-edt.html">Continue with 'Editions'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>

View file

@ -0,0 +1,318 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>2/nst</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<!--Weave of '3/bg' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">inbuild</a></li><li><a href="index.html#3">Chapter 3: Incremental Builds</a></li><li><b>Build Graphs</b></li></ul><p class="purpose">Graphs in which vertices correspond to files or copies, and arrows to dependencies between them.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Build graphs</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Build graphs. </b>These are directed acyclic graphs which show what depends on what in the
building process. If an arrow leads from A to B, then B must be built before
A can be built.
</p>
<p class="inwebparagraph">There can be two sorts of vertex in such a graph: copy vertices, each of which
belongs to a single copy, and internal vertices, each of which represents
a different file inside the copy.
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">COPY_VERTEX</span><span class="definitionkeyword"> from </span><span class="constant">1</span>
<span class="definitionkeyword">enum</span> <span class="constant">REQUIREMENT_VERTEX</span>
<span class="definitionkeyword">enum</span> <span class="constant">FILE_VERTEX</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">build_vertex</span><span class="plain"> {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">type</span><span class="plain">; </span> <span class="comment">one of the <code class="display"><span class="extract">*_VERTEX</span></code> values above</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">buildable_if_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">buildable_if_internal_file</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">findable</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">annotation</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">source_file</span><span class="plain"> *</span><span class="identifier">read_as</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">build_edges</span><span class="plain">; </span> <span class="comment">of <code class="display"><span class="extract">build_vertex</span></code></span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">linked_list</span><span class="plain"> *</span><span class="identifier">use_edges</span><span class="plain">; </span> <span class="comment">of <code class="display"><span class="extract">build_vertex</span></code></span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">build_script</span><span class="plain"> *</span><span class="identifier">script</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">last_described</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">built</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">force_this</span><span class="plain">;</span>
<span class="identifier">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">build_vertex</span><span class="plain">;</span>
<span class="reserved">build_vertex</span><span class="plain"> *</span><span class="functiontext">Graphs::file_vertex</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">build_vertex</span><span class="plain"> *</span><span class="identifier">V</span><span class="plain"> = </span><span class="identifier">CREATE</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="element">&gt;type</span><span class="plain"> = </span><span class="constant">FILE_VERTEX</span><span class="plain">;</span>
<span class="identifier">V</span><span class="plain">-</span><span class="element">&gt;buildable_if_copy</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">V</span><span class="plain">-</span><span class="element">&gt;buildable_if_internal_file</span><span class="plain"> = </span><span class="identifier">F</span><span class="plain">;</span>
<span class="identifier">V</span><span class="plain">-</span><span class="element">&gt;build_edges</span><span class="plain"> = </span><span class="identifier">NEW_LINKED_LIST</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="element">&gt;use_edges</span><span class="plain"> = </span><span class="identifier">NEW_LINKED_LIST</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="element">&gt;script</span><span class="plain"> = </span><span class="functiontext">BuildScripts::new</span><span class="plain">();</span>
<span class="identifier">V</span><span class="plain">-</span><span class="element">&gt;annotation</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">V</span><span class="plain">-</span><span class="element">&gt;read_as</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">V</span><span class="plain">-</span><span class="element">&gt;last_described</span><span class="plain"> = 0;</span>
<span class="identifier">V</span><span class="plain">-</span><span class="element">&gt;built</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">V</span><span class="plain">-</span><span class="element">&gt;force_this</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">V</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">build_vertex</span><span class="plain"> *</span><span class="functiontext">Graphs::copy_vertex</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">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="identifier">C</span><span class="plain">-</span><span class="element">&gt;vertex</span><span class="plain"> = </span><span class="functiontext">Graphs::file_vertex</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="element">&gt;vertex</span><span class="plain">-</span><span class="element">&gt;type</span><span class="plain"> = </span><span class="constant">COPY_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;buildable_if_copy</span><span class="plain"> = </span><span class="identifier">C</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;vertex</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">build_vertex</span><span class="plain"> *</span><span class="functiontext">Graphs::req_vertex</span><span class="plain">(</span><span class="reserved">inbuild_requirement</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">R</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 requirement"</span><span class="plain">);</span>
<span class="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">V</span><span class="plain"> = </span><span class="functiontext">Graphs::file_vertex</span><span class="plain">(</span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="identifier">V</span><span class="plain">-</span><span class="element">&gt;type</span><span class="plain"> = </span><span class="constant">REQUIREMENT_VERTEX</span><span class="plain">;</span>
<span class="identifier">V</span><span class="plain">-</span><span class="element">&gt;findable</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="identifier">V</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Graphs::need_this_to_build</span><span class="plain">(</span><span class="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">from</span><span class="plain">, </span><span class="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">to</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">from</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 from"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">to</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"no to"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">from</span><span class="plain"> == </span><span class="identifier">to</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"graph node depends on itself"</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">from</span><span class="plain">-</span><span class="element">&gt;build_edges</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">V</span><span class="plain"> == </span><span class="identifier">to</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">to</span><span class="plain">, </span><span class="reserved">build_vertex</span><span class="plain">, </span><span class="identifier">from</span><span class="plain">-</span><span class="element">&gt;build_edges</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Graphs::need_this_to_use</span><span class="plain">(</span><span class="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">from</span><span class="plain">, </span><span class="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">to</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">from</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 from"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">to</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"no to"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">from</span><span class="plain"> == </span><span class="identifier">to</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"graph node depends on itself"</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">from</span><span class="plain">-</span><span class="element">&gt;use_edges</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">V</span><span class="plain"> == </span><span class="identifier">to</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">to</span><span class="plain">, </span><span class="reserved">build_vertex</span><span class="plain">, </span><span class="identifier">from</span><span class="plain">-</span><span class="element">&gt;use_edges</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">description_round</span><span class="plain"> = 1;</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Graphs::describe</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</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="reserved">int</span><span class="plain"> </span><span class="identifier">recurse</span><span class="plain">) {</span>
<span class="functiontext">Graphs::describe_r</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, 0, </span><span class="identifier">V</span><span class="plain">, </span><span class="identifier">recurse</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="constant">NOT_A_GB</span><span class="plain">, </span><span class="identifier">description_round</span><span class="plain">++);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Graphs::describe_r</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">depth</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="reserved">int</span><span class="plain"> </span><span class="identifier">recurse</span><span class="plain">, </span><span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">stem</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">which</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">description_round</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">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">depth</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" "</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">which</span><span class="plain"> == </span><span class="constant">BUILD_GB</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"--build-&gt; "</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">which</span><span class="plain"> == </span><span class="constant">USE_GB</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"--use---&gt; "</span><span class="plain">);</span>
<span class="functiontext">Graphs::describe_vertex</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">WRITE</span><span class="plain">(</span><span class="string">" "</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">V</span><span class="plain">-</span><span class="element">&gt;last_described</span><span class="plain"> == </span><span class="identifier">description_round</span><span class="plain">) { </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"q.v.\</span><span class="plain">n</span><span class="string">"</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">T</span><span class="plain">);</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">V</span><span class="plain">-</span><span class="element">&gt;type</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">COPY_VERTEX</span><span class="plain">: </span><span class="functiontext">Copies::write_copy</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">-</span><span class="element">&gt;buildable_if_copy</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">REQUIREMENT_VERTEX</span><span class="plain">: </span><span class="functiontext">Requirements::write</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">-</span><span class="element">&gt;findable</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">FILE_VERTEX</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%f"</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">-</span><span class="element">&gt;buildable_if_internal_file</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="string">"%p"</span><span class="plain">, </span><span class="identifier">stem</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::prefix_eq</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">))) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"... "</span><span class="plain">); </span><span class="identifier">Str::substr</span><span class="plain">(</span><span class="identifier">OUT</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">Str::len</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">)), </span><span class="identifier">Str::end</span><span class="plain">(</span><span class="identifier">T</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">"%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">S</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">T</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">recurse</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">V</span><span class="plain">-</span><span class="element">&gt;buildable_if_copy</span><span class="plain">) </span><span class="identifier">stem</span><span class="plain"> = </span><span class="identifier">V</span><span class="plain">-</span><span class="element">&gt;buildable_if_copy</span><span class="plain">-</span><span class="element">&gt;location_if_path</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">V</span><span class="plain">-</span><span class="element">&gt;buildable_if_internal_file</span><span class="plain">)</span>
<span class="identifier">stem</span><span class="plain"> = </span><span class="identifier">Filenames::get_path_to</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">-</span><span class="element">&gt;buildable_if_internal_file</span><span class="plain">);</span>
<span class="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">W</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="element">&gt;build_edges</span><span class="plain">)</span>
<span class="functiontext">Graphs::describe_r</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">depth</span><span class="plain">+1, </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">, </span><span class="identifier">stem</span><span class="plain">, </span><span class="constant">BUILD_GB</span><span class="plain">, </span><span class="identifier">description_round</span><span class="plain">);</span>
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">W</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="element">&gt;use_edges</span><span class="plain">)</span>
<span class="functiontext">Graphs::describe_r</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">depth</span><span class="plain">+1, </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">, </span><span class="identifier">stem</span><span class="plain">, </span><span class="constant">USE_GB</span><span class="plain">, </span><span class="identifier">description_round</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">Graphs::describe_vertex</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</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="reserved">if</span><span class="plain"> (</span><span class="identifier">V</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">else</span><span class="plain"> </span><span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">V</span><span class="plain">-</span><span class="element">&gt;type</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">COPY_VERTEX</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"[c%d]"</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">-&gt;</span><span class="identifier">allocation_id</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">REQUIREMENT_VERTEX</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"[r%d]"</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">-&gt;</span><span class="identifier">allocation_id</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">FILE_VERTEX</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"[f%d]"</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">-&gt;</span><span class="identifier">allocation_id</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">time_t</span><span class="plain"> </span><span class="functiontext">Graphs::timestamp_for</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">time_t</span><span class="plain"> </span><span class="identifier">latest</span><span class="plain"> = (</span><span class="identifier">time_t</span><span class="plain">) 0;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">V</span><span class="plain">-</span><span class="element">&gt;buildable_if_internal_file</span><span class="plain">) {</span>
<span class="reserved">char</span><span class="plain"> </span><span class="identifier">transcoded_pathname</span><span class="plain">[4*</span><span class="identifier">MAX_FILENAME_LENGTH</span><span class="plain">];</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">FN</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">FN</span><span class="plain">, </span><span class="string">"%f"</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">-</span><span class="element">&gt;buildable_if_internal_file</span><span class="plain">);</span>
<span class="identifier">Str::copy_to_locale_string</span><span class="plain">(</span><span class="identifier">transcoded_pathname</span><span class="plain">, </span><span class="identifier">FN</span><span class="plain">, 4*</span><span class="identifier">MAX_FILENAME_LENGTH</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">FN</span><span class="plain">);</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">stat</span><span class="plain"> </span><span class="identifier">filestat</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">stat</span><span class="plain">(</span><span class="identifier">transcoded_pathname</span><span class="plain">, &amp;</span><span class="identifier">filestat</span><span class="plain">) != -1) </span><span class="identifier">latest</span><span class="plain"> = </span><span class="identifier">filestat</span><span class="plain">.</span><span class="identifier">st_mtime</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">latest</span><span class="plain"> = </span><span class="functiontext">Graphs::time_of_most_recent_ingredient</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">latest</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">time_t</span><span class="plain"> </span><span class="functiontext">Graphs::time_of_most_recent_ingredient</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">time_t</span><span class="plain"> </span><span class="identifier">latest</span><span class="plain"> = (</span><span class="identifier">time_t</span><span class="plain">) 0;</span>
<span class="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">W</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="element">&gt;build_edges</span><span class="plain">) {</span>
<span class="identifier">time_t</span><span class="plain"> </span><span class="identifier">inner</span><span class="plain"> = </span><span class="functiontext">Graphs::timestamp_for</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">latest</span><span class="plain"> == (</span><span class="identifier">time_t</span><span class="plain">) 0) || (</span><span class="identifier">difftime</span><span class="plain">(</span><span class="identifier">inner</span><span class="plain">, </span><span class="identifier">latest</span><span class="plain">) &gt; 0))</span>
<span class="identifier">latest</span><span class="plain"> = </span><span class="identifier">inner</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">latest</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">time_t</span><span class="plain"> </span><span class="functiontext">Graphs::time_of_most_recent_used_resource</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">time_t</span><span class="plain"> </span><span class="identifier">latest</span><span class="plain"> = (</span><span class="identifier">time_t</span><span class="plain">) 0;</span>
<span class="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">W</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="element">&gt;use_edges</span><span class="plain">) {</span>
<span class="identifier">time_t</span><span class="plain"> </span><span class="identifier">inner</span><span class="plain"> = </span><span class="functiontext">Graphs::timestamp_for</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">latest</span><span class="plain"> == (</span><span class="identifier">time_t</span><span class="plain">) 0) || (</span><span class="identifier">difftime</span><span class="plain">(</span><span class="identifier">inner</span><span class="plain">, </span><span class="identifier">latest</span><span class="plain">) &gt; 0))</span>
<span class="identifier">latest</span><span class="plain"> = </span><span class="identifier">inner</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">latest</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Graphs::file_vertex is used in 5/kts (<a href="5-kts.html#SP2">&#167;2</a>), 5/ps (<a href="5-ps.html#SP1">&#167;1</a>, <a href="5-ps.html#SP3">&#167;3</a>).</p>
<p class="endnote">The function Graphs::copy_vertex is used in 4/km (<a href="4-km.html#SP7">&#167;7</a>), 4/em (<a href="4-em.html#SP9">&#167;9</a>), 4/lm (<a href="4-lm.html#SP8">&#167;8</a>), 4/pbm (<a href="4-pbm.html#SP7">&#167;7</a>), 4/pfm (<a href="4-pfm.html#SP7">&#167;7</a>), 4/tm (<a href="4-tm.html#SP7">&#167;7</a>), 4/pm (<a href="4-pm.html#SP8">&#167;8</a>).</p>
<p class="endnote">The function Graphs::req_vertex is used in 5/kts (<a href="5-kts.html#SP2">&#167;2</a>).</p>
<p class="endnote">The function Graphs::need_this_to_build 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>).</p>
<p class="endnote">The function Graphs::need_this_to_use is used in 5/kts (<a href="5-kts.html#SP2">&#167;2</a>).</p>
<p class="endnote">The function Graphs::describe is used in <a href="#SP2">&#167;2</a>, 4/km (<a href="4-km.html#SP7">&#167;7</a>), 4/pbm (<a href="4-pbm.html#SP6">&#167;6</a>), 4/pfm (<a href="4-pfm.html#SP6">&#167;6</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::timestamp_for is used in <a href="#SP2_1">&#167;2.1</a>.</p>
<p class="endnote">The function Graphs::time_of_most_recent_ingredient is used in <a href="#SP2_1">&#167;2.1</a>.</p>
<p class="endnote">The function Graphs::time_of_most_recent_used_resource is used in <a href="#SP2_1">&#167;2.1</a>.</p>
<p class="endnote">The structure build_vertex is accessed in 3/bs2, 3/is, 3/is3, 5/ed, 5/ps and here.</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b></p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">NOT_A_GB</span><span class="plain"> 0</span>
<span class="definitionkeyword">define</span> <span class="constant">BUILD_GB</span><span class="plain"> 1</span>
<span class="definitionkeyword">define</span> <span class="constant">FORCE_GB</span><span class="plain"> 2</span>
<span class="definitionkeyword">define</span> <span class="constant">USE_GB</span><span class="plain"> 4</span>
</pre>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Graphs::build</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</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="reserved">build_methodology</span><span class="plain"> *</span><span class="identifier">meth</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Graphs::build_r</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="constant">BUILD_GB</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">, </span><span class="identifier">meth</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Graphs::rebuild</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</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="reserved">build_methodology</span><span class="plain"> *</span><span class="identifier">meth</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Graphs::build_r</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="constant">BUILD_GB</span><span class="plain"> + </span><span class="constant">FORCE_GB</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">, </span><span class="identifier">meth</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">trace_ibg</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Graphs::build_r</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">gb</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="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">trace_ibg</span><span class="plain">) { </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">STDOUT</span><span class="plain">, </span><span class="string">"Build: "</span><span class="plain">); </span><span class="functiontext">Graphs::describe</span><span class="plain">(</span><span class="identifier">STDOUT</span><span class="plain">, </span><span class="identifier">V</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">V</span><span class="plain">-</span><span class="element">&gt;built</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="identifier">STREAM_INDENT</span><span class="plain">(</span><span class="identifier">STDOUT</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">W</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="element">&gt;build_edges</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rv</span><span class="plain">)</span>
<span class="identifier">rv</span><span class="plain"> = </span><span class="functiontext">Graphs::build_r</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">gb</span><span class="plain"> | </span><span class="constant">USE_GB</span><span class="plain">, </span><span class="identifier">W</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">gb</span><span class="plain"> &amp; </span><span class="constant">USE_GB</span><span class="plain">)</span>
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">W</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="element">&gt;use_edges</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rv</span><span class="plain">)</span>
<span class="identifier">rv</span><span class="plain"> = </span><span class="functiontext">Graphs::build_r</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">gb</span><span class="plain"> &amp; (</span><span class="constant">BUILD_GB</span><span class="plain"> + </span><span class="constant">FORCE_GB</span><span class="plain">), </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">meth</span><span class="plain">);</span>
<span class="identifier">STREAM_OUTDENT</span><span class="plain">(</span><span class="identifier">STDOUT</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rv</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">needs_building</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">gb</span><span class="plain"> &amp; </span><span class="constant">FORCE_GB</span><span class="plain">) || (</span><span class="identifier">V</span><span class="plain">-</span><span class="element">&gt;force_this</span><span class="plain">)) </span><span class="identifier">needs_building</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">else</span><span class="plain"> </span>&lt;<span class="cwebmacro">Decide based on timestamps</span> <span class="cwebmacronumber">2.1</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">needs_building</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">trace_ibg</span><span class="plain">) { </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">STDOUT</span><span class="plain">, </span><span class="string">"Exec\</span><span class="plain">n</span><span class="string">"</span><span class="plain">); }</span>
<span class="identifier">rv</span><span class="plain"> = </span><span class="functiontext">BuildScripts::execute</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">-</span><span class="element">&gt;script</span><span class="plain">, </span><span class="identifier">meth</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="identifier">V</span><span class="plain">-</span><span class="element">&gt;built</span><span class="plain"> = </span><span class="identifier">rv</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Graphs::build is used in 4/km (<a href="4-km.html#SP7">&#167;7</a>), 4/pbm (<a href="4-pbm.html#SP6">&#167;6</a>), 4/pfm (<a href="4-pfm.html#SP6">&#167;6</a>).</p>
<p class="endnote">The function Graphs::rebuild is used in 4/km (<a href="4-km.html#SP7">&#167;7</a>), 4/pbm (<a href="4-pbm.html#SP6">&#167;6</a>), 4/pfm (<a href="4-pfm.html#SP6">&#167;6</a>).</p>
<p class="endnote">The function Graphs::build_r appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP2_1"></a><b>&#167;2.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Decide based on timestamps</span> <span class="cwebmacronumber">2.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">time_t</span><span class="plain"> </span><span class="identifier">last_built_at</span><span class="plain"> = </span><span class="functiontext">Graphs::timestamp_for</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">trace_ibg</span><span class="plain">) { </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">STDOUT</span><span class="plain">, </span><span class="string">"Last built at: %08x\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">last_built_at</span><span class="plain">); }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">last_built_at</span><span class="plain"> == (</span><span class="identifier">time_t</span><span class="plain">) 0)</span>
<span class="identifier">needs_building</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">time_t</span><span class="plain"> </span><span class="identifier">time_of_most_recent</span><span class="plain"> = </span><span class="functiontext">Graphs::time_of_most_recent_ingredient</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">time_of_most_recent</span><span class="plain"> != (</span><span class="identifier">time_t</span><span class="plain">) 0) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">trace_ibg</span><span class="plain">) { </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">STDOUT</span><span class="plain">, </span><span class="string">"Most recent: %08x\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">time_of_most_recent</span><span class="plain">); }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">difftime</span><span class="plain">(</span><span class="identifier">time_of_most_recent</span><span class="plain">, </span><span class="identifier">last_built_at</span><span class="plain">) &gt; 0)</span>
<span class="identifier">needs_building</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">gb</span><span class="plain"> &amp; </span><span class="constant">USE_GB</span><span class="plain">) {</span>
<span class="identifier">time_t</span><span class="plain"> </span><span class="identifier">time_of_most_recent_used</span><span class="plain"> = </span><span class="functiontext">Graphs::time_of_most_recent_used_resource</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">time_of_most_recent_used</span><span class="plain"> != (</span><span class="identifier">time_t</span><span class="plain">) 0) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">trace_ibg</span><span class="plain">) { </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">STDOUT</span><span class="plain">, </span><span class="string">"Most recent use: %08x\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">time_of_most_recent_used</span><span class="plain">); }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">difftime</span><span class="plain">(</span><span class="identifier">time_of_most_recent_used</span><span class="plain">, </span><span class="identifier">last_built_at</span><span class="plain">) &gt; 0)</span>
<span class="identifier">needs_building</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP2">&#167;2</a>.</p>
<hr class="tocbar">
<ul class="toc"><li><i>(This section begins Chapter 3: Incremental Builds.)</i></li><li><a href="3-bm.html">Continue with 'Build Methodology'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>

View file

@ -0,0 +1,81 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>3/bg</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<!--Weave of '3/bm' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">inbuild</a></li><li><a href="index.html#3">Chapter 3: Incremental Builds</a></li><li><b>Build Methodology</b></li></ul><p class="purpose">Whether to run tasks internally in some merged tool, or run via the shell, or simply trace to the standard output what we think ought to be done.</p>
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. </b></p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">DRY_RUN_METHODOLOGY</span><span class="definitionkeyword"> from </span><span class="constant">1</span>
<span class="definitionkeyword">enum</span> <span class="constant">SHELL_METHODOLOGY</span>
<span class="definitionkeyword">enum</span> <span class="constant">INTERNAL_METHODOLOGY</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">build_methodology</span><span class="plain"> {</span>
<span class="identifier">filename</span><span class="plain"> *</span><span class="identifier">to_inter</span><span class="plain">;</span>
<span class="identifier">filename</span><span class="plain"> *</span><span class="identifier">to_inform6</span><span class="plain">;</span>
<span class="identifier">filename</span><span class="plain"> *</span><span class="identifier">to_inform7</span><span class="plain">;</span>
<span class="identifier">filename</span><span class="plain"> *</span><span class="identifier">to_inblorb</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">methodology</span><span class="plain">;</span>
<span class="identifier">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">build_methodology</span><span class="plain">;</span>
<span class="reserved">build_methodology</span><span class="plain"> *</span><span class="functiontext">BuildMethodology::new</span><span class="plain">(</span><span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">tools_path</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">dev</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">meth</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="identifier">CREATE</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="element">&gt;methodology</span><span class="plain"> = </span><span class="identifier">meth</span><span class="plain">;</span>
<span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">inter_path</span><span class="plain"> = </span><span class="identifier">tools_path</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">dev</span><span class="plain">) {</span>
<span class="identifier">inter_path</span><span class="plain"> = </span><span class="identifier">Pathnames::subfolder</span><span class="plain">(</span><span class="identifier">inter_path</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"inter"</span><span class="plain">);</span>
<span class="identifier">inter_path</span><span class="plain"> = </span><span class="identifier">Pathnames::subfolder</span><span class="plain">(</span><span class="identifier">inter_path</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Tangled"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">BM</span><span class="plain">-</span><span class="element">&gt;to_inter</span><span class="plain"> = </span><span class="identifier">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">inter_path</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"inter"</span><span class="plain">);</span>
<span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">inform6_path</span><span class="plain"> = </span><span class="identifier">tools_path</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">dev</span><span class="plain">) {</span>
<span class="identifier">inform6_path</span><span class="plain"> = </span><span class="identifier">Pathnames::subfolder</span><span class="plain">(</span><span class="identifier">inform6_path</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"inform6"</span><span class="plain">);</span>
<span class="identifier">inform6_path</span><span class="plain"> = </span><span class="identifier">Pathnames::subfolder</span><span class="plain">(</span><span class="identifier">inform6_path</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Tangled"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">BM</span><span class="plain">-</span><span class="element">&gt;to_inform6</span><span class="plain"> = </span><span class="identifier">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">inform6_path</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"inform6"</span><span class="plain">);</span>
<span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">inform7_path</span><span class="plain"> = </span><span class="identifier">tools_path</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">dev</span><span class="plain">) {</span>
<span class="identifier">inform7_path</span><span class="plain"> = </span><span class="identifier">Pathnames::subfolder</span><span class="plain">(</span><span class="identifier">inform7_path</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"inform7"</span><span class="plain">);</span>
<span class="identifier">inform7_path</span><span class="plain"> = </span><span class="identifier">Pathnames::subfolder</span><span class="plain">(</span><span class="identifier">inform7_path</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Tangled"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">BM</span><span class="plain">-</span><span class="element">&gt;to_inform7</span><span class="plain"> = </span><span class="identifier">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">inform7_path</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"inform7"</span><span class="plain">);</span>
<span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">inblorb_path</span><span class="plain"> = </span><span class="identifier">tools_path</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">dev</span><span class="plain">) {</span>
<span class="identifier">inblorb_path</span><span class="plain"> = </span><span class="identifier">Pathnames::subfolder</span><span class="plain">(</span><span class="identifier">inblorb_path</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"inblorb"</span><span class="plain">);</span>
<span class="identifier">inblorb_path</span><span class="plain"> = </span><span class="identifier">Pathnames::subfolder</span><span class="plain">(</span><span class="identifier">inblorb_path</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Tangled"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">BM</span><span class="plain">-</span><span class="element">&gt;to_inblorb</span><span class="plain"> = </span><span class="identifier">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">inblorb_path</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"inblorb"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">BM</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">build_methodology</span><span class="plain"> *</span><span class="functiontext">BuildMethodology::stay_in_current_process</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">BuildMethodology::new</span><span class="plain">(</span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="constant">INTERNAL_METHODOLOGY</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function BuildMethodology::new appears nowhere else.</p>
<p class="endnote">The function BuildMethodology::stay_in_current_process appears nowhere else.</p>
<p class="endnote">The structure build_methodology is accessed in 3/bs2, 3/is, 3/is2, 3/is3, 4/km, 4/em, 4/lm, 4/tm, 4/pm and here.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="3-bg.html">Back to 'Build Graphs'</a></li><li><a href="3-bs.html">Continue with 'Build Scripts'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>

View file

@ -0,0 +1,69 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>3/bm</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<!--Weave of '3/bs' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">inbuild</a></li><li><a href="index.html#3">Chapter 3: Incremental Builds</a></li><li><b>Build Scripts</b></li></ul><p class="purpose">Scripts are nothing more than list of build steps.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Build scripts</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Build scripts. </b>Simple lists of steps: nothing to see 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">build_script</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">steps</span><span class="plain">; </span> <span class="comment">of <code class="display"><span class="extract">build_step</span></code></span>
<span class="identifier">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">build_script</span><span class="plain">;</span>
<span class="reserved">build_script</span><span class="plain"> *</span><span class="functiontext">BuildScripts::new</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="reserved">build_script</span><span class="plain"> *</span><span class="identifier">BS</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">build_script</span><span class="plain">);</span>
<span class="identifier">BS</span><span class="plain">-</span><span class="element">&gt;steps</span><span class="plain"> = </span><span class="identifier">NEW_LINKED_LIST</span><span class="plain">(</span><span class="reserved">build_step</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">BS</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">BuildScripts::add_step</span><span class="plain">(</span><span class="reserved">build_script</span><span class="plain"> *</span><span class="identifier">BS</span><span class="plain">, </span><span class="reserved">build_step</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">) {</span>
<span class="identifier">ADD_TO_LINKED_LIST</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="reserved">build_step</span><span class="plain">, </span><span class="identifier">BS</span><span class="plain">-</span><span class="element">&gt;steps</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">BuildScripts::concatenate</span><span class="plain">(</span><span class="reserved">build_script</span><span class="plain"> *</span><span class="identifier">BT</span><span class="plain">, </span><span class="reserved">build_script</span><span class="plain"> *</span><span class="identifier">BF</span><span class="plain">) {</span>
<span class="reserved">build_step</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="reserved">build_step</span><span class="plain">, </span><span class="identifier">BF</span><span class="plain">-</span><span class="element">&gt;steps</span><span class="plain">)</span>
<span class="functiontext">BuildScripts::add_step</span><span class="plain">(</span><span class="identifier">BT</span><span class="plain">, </span><span class="identifier">S</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">BuildScripts::execute</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="reserved">build_script</span><span class="plain"> *</span><span class="identifier">BS</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">int</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">build_step</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="reserved">build_step</span><span class="plain">, </span><span class="identifier">BS</span><span class="plain">-</span><span class="element">&gt;steps</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rv</span><span class="plain">)</span>
<span class="identifier">rv</span><span class="plain"> = </span><span class="functiontext">BuildSteps::execute</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">, </span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">meth</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function BuildScripts::new is used in 3/bg (<a href="3-bg.html#SP1">&#167;1</a>).</p>
<p class="endnote">The function BuildScripts::add_step is used in 3/bs2 (<a href="3-bs2.html#SP4">&#167;4</a>).</p>
<p class="endnote">The function BuildScripts::concatenate appears nowhere else.</p>
<p class="endnote">The function BuildScripts::execute is used in 3/bg (<a href="3-bg.html#SP2">&#167;2</a>).</p>
<p class="endnote">The structure build_script is private to this section.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="3-bm.html">Back to 'Build Methodology'</a></li><li><a href="3-bs2.html">Continue with 'Build Steps'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>

View file

@ -0,0 +1,132 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>3/bs</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<!--Weave of '3/bs2' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">inbuild</a></li><li><a href="index.html#3">Chapter 3: Incremental Builds</a></li><li><b>Build Steps</b></li></ul><p class="purpose">A build step is a task which exercises one of the build skills.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Build skills</a></li><li><a href="#SP3">&#167;3. Build steps</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Build skills. </b></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">build_skill</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">name</span><span class="plain">;</span>
<span class="identifier">METHOD_CALLS</span>
<span class="identifier">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">build_skill</span><span class="plain">;</span>
<span class="reserved">build_skill</span><span class="plain"> *</span><span class="functiontext">BuildSteps::new_skill</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">build_skill</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">build_skill</span><span class="plain">);</span>
<span class="identifier">S</span><span class="plain">-</span><span class="element">&gt;name</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">ENABLE_METHOD_CALLS</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">S</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function BuildSteps::new_skill is used in 3/is (<a href="3-is.html#SP1">&#167;1</a>), 3/is2 (<a href="3-is2.html#SP1">&#167;1</a>), 3/is3 (<a href="3-is3.html#SP1">&#167;1</a>), 3/is4 (<a href="3-is4.html#SP1">&#167;1</a>).</p>
<p class="endnote">The structure build_skill is private to this section.</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b></p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">BUILD_SKILL_COMMAND_MTID</span>
<span class="definitionkeyword">enum</span> <span class="constant">BUILD_SKILL_INTERNAL_MTID</span>
</pre>
<pre class="display">
<span class="identifier">VMETHOD_TYPE</span><span class="plain">(</span><span class="constant">BUILD_SKILL_COMMAND_MTID</span><span class="plain">,</span>
<span class="reserved">build_skill</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">, </span><span class="reserved">build_step</span><span class="plain"> *</span><span class="identifier">BS</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">command</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="identifier">IMETHOD_TYPE</span><span class="plain">(</span><span class="constant">BUILD_SKILL_INTERNAL_MTID</span><span class="plain">,</span>
<span class="reserved">build_skill</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">, </span><span class="reserved">build_step</span><span class="plain"> *</span><span class="identifier">BS</span><span class="plain">, </span><span class="reserved">build_methodology</span><span class="plain"> *</span><span class="identifier">meth</span><span class="plain">)</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. Build steps. </b></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">build_step</span><span class="plain"> {</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">build_skill</span><span class="plain"> *</span><span class="identifier">what_to_do</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="reserved">struct</span><span class="plain"> </span><span class="identifier">linked_list</span><span class="plain"> *</span><span class="identifier">search_path</span><span class="plain">; </span> <span class="comment">of <code class="display"><span class="extract">inbuild_nest</span></code></span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">target_vm</span><span class="plain"> *</span><span class="identifier">for_vm</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">inter_architecture</span><span class="plain"> *</span><span class="identifier">for_arch</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">for_release</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">associated_copy</span><span class="plain">;</span>
<span class="identifier">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">build_step</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The structure build_step is accessed in 2/cps, 3/bg, 3/is, 3/is2, 3/is3, 4/km, 5/kts, 5/ps and here.</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b></p>
<pre class="display">
<span class="reserved">build_step</span><span class="plain"> *</span><span class="functiontext">BuildSteps::attach</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">build_skill</span><span class="plain"> *</span><span class="identifier">to_do</span><span class="plain">, </span><span class="identifier">linked_list</span><span class="plain"> *</span><span class="identifier">search</span><span class="plain">,</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">rel</span><span class="plain">, </span><span class="identifier">target_vm</span><span class="plain"> *</span><span class="identifier">VM</span><span class="plain">, </span><span class="identifier">inter_architecture</span><span class="plain"> *</span><span class="identifier">arch</span><span class="plain">, </span><span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">assoc</span><span class="plain">) {</span>
<span class="reserved">build_step</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">build_step</span><span class="plain">);</span>
<span class="identifier">S</span><span class="plain">-</span><span class="element">&gt;vertex</span><span class="plain"> = </span><span class="identifier">vertex</span><span class="plain">;</span>
<span class="identifier">S</span><span class="plain">-</span><span class="element">&gt;what_to_do</span><span class="plain"> = </span><span class="identifier">to_do</span><span class="plain">;</span>
<span class="identifier">S</span><span class="plain">-</span><span class="element">&gt;search_path</span><span class="plain"> = </span><span class="identifier">search</span><span class="plain">;</span>
<span class="identifier">S</span><span class="plain">-</span><span class="element">&gt;for_vm</span><span class="plain"> = </span><span class="identifier">VM</span><span class="plain">;</span>
<span class="identifier">S</span><span class="plain">-</span><span class="element">&gt;for_arch</span><span class="plain"> = </span><span class="identifier">arch</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">VM</span><span class="plain">) &amp;&amp; (</span><span class="identifier">arch</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)) </span><span class="identifier">S</span><span class="plain">-</span><span class="element">&gt;for_arch</span><span class="plain"> = </span><span class="identifier">TargetVMs::get_architecture</span><span class="plain">(</span><span class="identifier">VM</span><span class="plain">);</span>
<span class="identifier">S</span><span class="plain">-</span><span class="element">&gt;for_release</span><span class="plain"> = </span><span class="identifier">rel</span><span class="plain">;</span>
<span class="identifier">S</span><span class="plain">-</span><span class="element">&gt;associated_copy</span><span class="plain"> = </span><span class="identifier">assoc</span><span class="plain">;</span>
<span class="functiontext">BuildScripts::add_step</span><span class="plain">(</span><span class="identifier">vertex</span><span class="plain">-</span><span class="element">&gt;script</span><span class="plain">, </span><span class="identifier">S</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">S</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">BuildSteps::execute</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="reserved">build_step</span><span class="plain"> *</span><span class="identifier">S</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">int</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">);</span>
<span class="identifier">VMETHOD_CALL</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">-</span><span class="element">&gt;what_to_do</span><span class="plain">, </span><span class="constant">BUILD_SKILL_COMMAND_MTID</span><span class="plain">, </span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">command</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">rv</span><span class="plain">) &amp;&amp; (</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">) &gt; 0)) </span><span class="identifier">rv</span><span class="plain"> = </span><span class="functiontext">BuildSteps::shell</span><span class="plain">(</span><span class="identifier">command</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">rv</span><span class="plain">) &amp;&amp; (</span><span class="identifier">meth</span><span class="plain">-</span><span class="element">&gt;methodology</span><span class="plain"> == </span><span class="constant">INTERNAL_METHODOLOGY</span><span class="plain">)) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">returned</span><span class="plain"> = 0;</span>
<span class="identifier">IMETHOD_CALL</span><span class="plain">(</span><span class="identifier">returned</span><span class="plain">, </span><span class="identifier">S</span><span class="plain">-</span><span class="element">&gt;what_to_do</span><span class="plain">, </span><span class="constant">BUILD_SKILL_INTERNAL_MTID</span><span class="plain">, </span><span class="identifier">S</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">returned</span><span class="plain"> != </span><span class="identifier">TRUE</span><span class="plain">) </span><span class="identifier">rv</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">rv</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">STDERR</span><span class="plain">, </span><span class="string">"Build failed at '%S'\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">command</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">BuildSteps::shell</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">command</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">int</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">STDOUT</span><span class="plain">, </span><span class="string">"%S\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">command</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">SHELL_METHODOLOGY</span><span class="plain">) </span><span class="identifier">rv</span><span class="plain"> = (</span><span class="identifier">Shell::run</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">) == 0)?</span><span class="identifier">TRUE</span><span class="plain">:</span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function BuildSteps::attach 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>).</p>
<p class="endnote">The function BuildSteps::execute is used in 3/bs (<a href="3-bs.html#SP1">&#167;1</a>).</p>
<p class="endnote">The function BuildSteps::shell is used in 4/em (<a href="4-em.html#SP8">&#167;8</a>), 4/pm (<a href="4-pm.html#SP7">&#167;7</a>).</p>
<hr class="tocbar">
<ul class="toc"><li><a href="3-bs.html">Back to 'Build Scripts'</a></li><li><a href="3-is.html">Continue with 'Inter Skill'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>

View file

@ -0,0 +1,156 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>3/bs2</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<!--Weave of '3/is' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">inbuild</a></li><li><a href="index.html#3">Chapter 3: Incremental Builds</a></li><li><b>Inter Skill</b></li></ul><p class="purpose">A build step is a task such as running inform7 or inblorb on some file.</p>
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. </b></p>
<pre class="display">
<span class="reserved">build_skill</span><span class="plain"> *</span><span class="identifier">assimilate_using_inter_skill</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">build_skill</span><span class="plain"> *</span><span class="identifier">code_generate_using_inter_skill</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">InterSkill::create</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">assimilate_using_inter_skill</span><span class="plain"> = </span><span class="functiontext">BuildSteps::new_skill</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"assimilate using inter"</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">assimilate_using_inter_skill</span><span class="plain">, </span><span class="constant">BUILD_SKILL_COMMAND_MTID</span><span class="plain">, </span><span class="functiontext">InterSkill::assimilate_via_shell</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">assimilate_using_inter_skill</span><span class="plain">, </span><span class="constant">BUILD_SKILL_INTERNAL_MTID</span><span class="plain">, </span><span class="functiontext">InterSkill::assimilate_internally</span><span class="plain">);</span>
<span class="identifier">code_generate_using_inter_skill</span><span class="plain"> = </span><span class="functiontext">BuildSteps::new_skill</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"code generate using inter"</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">code_generate_using_inter_skill</span><span class="plain">, </span><span class="constant">BUILD_SKILL_INTERNAL_MTID</span><span class="plain">, </span><span class="functiontext">InterSkill::code_generate_internally</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">InterSkill::assimilate_via_shell</span><span class="plain">(</span><span class="reserved">build_skill</span><span class="plain"> *</span><span class="identifier">skill</span><span class="plain">, </span><span class="reserved">build_step</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">command</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="identifier">inter_architecture</span><span class="plain"> *</span><span class="identifier">A</span><span class="plain"> = </span><span class="identifier">S</span><span class="plain">-</span><span class="element">&gt;for_arch</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">A</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 architecture given"</span><span class="plain">);</span>
<span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">kit_path</span><span class="plain"> = </span><span class="identifier">S</span><span class="plain">-</span><span class="element">&gt;associated_copy</span><span class="plain">-</span><span class="element">&gt;location_if_path</span><span class="plain">;</span>
<span class="identifier">Shell::quote_file</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="identifier">meth</span><span class="plain">-</span><span class="element">&gt;to_inter</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="string">"-architecture %S "</span><span class="plain">, </span><span class="identifier">Architectures::to_codename</span><span class="plain">(</span><span class="identifier">A</span><span class="plain">));</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="string">"-assimilate "</span><span class="plain">);</span>
<span class="identifier">Shell::quote_path</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="identifier">kit_path</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="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">InterSkill::assimilate_internally</span><span class="plain">(</span><span class="reserved">build_skill</span><span class="plain"> *</span><span class="identifier">skill</span><span class="plain">, </span><span class="reserved">build_step</span><span class="plain"> *</span><span class="identifier">S</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="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">CODEGEN_MODULE</span>
<span class="identifier">inter_architecture</span><span class="plain"> *</span><span class="identifier">A</span><span class="plain"> = </span><span class="identifier">S</span><span class="plain">-</span><span class="element">&gt;for_arch</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">A</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 architecture given"</span><span class="plain">);</span>
<span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">kit_path</span><span class="plain"> = </span><span class="identifier">S</span><span class="plain">-</span><span class="element">&gt;associated_copy</span><span class="plain">-</span><span class="element">&gt;location_if_path</span><span class="plain">;</span>
<span class="identifier">dictionary</span><span class="plain"> *</span><span class="identifier">pipeline_vars</span><span class="plain"> = </span><span class="identifier">CodeGen::Pipeline::basic_dictionary</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"output.i6"</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">I</span><span class="string">"assimilate.interpipeline"</span><span class="plain">, </span><span class="identifier">NULL</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="functiontext">Inbuild::nest_list</span><span class="plain">(), </span><span class="identifier">L</span><span class="plain">);</span>
<span class="identifier">filename</span><span class="plain"> *</span><span class="identifier">pipeline_as_file</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="identifier">LOOP_OVER_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">L</span><span class="plain">) {</span>
<span class="identifier">pipeline_as_file</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;location_if_file</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">pipeline_as_file</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>
<span class="plain">}</span>
<span class="identifier">filename</span><span class="plain"> *</span><span class="identifier">assim</span><span class="plain"> = </span><span class="identifier">Architectures::canonical_binary</span><span class="plain">(</span><span class="identifier">kit_path</span><span class="plain">, </span><span class="identifier">A</span><span class="plain">);</span>
<span class="identifier">filename</span><span class="plain"> *</span><span class="identifier">assim_t</span><span class="plain"> = </span><span class="identifier">Architectures::canonical_textual</span><span class="plain">(</span><span class="identifier">kit_path</span><span class="plain">, </span><span class="identifier">A</span><span class="plain">);</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">fullname</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">fullname</span><span class="plain">, </span><span class="string">"%f"</span><span class="plain">, </span><span class="identifier">assim</span><span class="plain">);</span>
<span class="identifier">Str::copy</span><span class="plain">(</span><span class="identifier">Dictionaries::create_text</span><span class="plain">(</span><span class="identifier">pipeline_vars</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"*out"</span><span class="plain">), </span><span class="identifier">fullname</span><span class="plain">);</span>
<span class="identifier">Str::clear</span><span class="plain">(</span><span class="identifier">fullname</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">fullname</span><span class="plain">, </span><span class="string">"%f"</span><span class="plain">, </span><span class="identifier">assim_t</span><span class="plain">);</span>
<span class="identifier">Str::copy</span><span class="plain">(</span><span class="identifier">Dictionaries::create_text</span><span class="plain">(</span><span class="identifier">pipeline_vars</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"*outt"</span><span class="plain">), </span><span class="identifier">fullname</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">fullname</span><span class="plain">);</span>
<span class="identifier">Str::copy</span><span class="plain">(</span><span class="identifier">Dictionaries::create_text</span><span class="plain">(</span><span class="identifier">pipeline_vars</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"*attach"</span><span class="plain">), </span><span class="identifier">Pathnames::directory_name</span><span class="plain">(</span><span class="identifier">kit_path</span><span class="plain">));</span>
<span class="identifier">linked_list</span><span class="plain"> *</span><span class="identifier">inter_paths</span><span class="plain"> = </span><span class="identifier">NEW_LINKED_LIST</span><span class="plain">(</span><span class="identifier">pathname</span><span class="plain">);</span>
<span class="identifier">ADD_TO_LINKED_LIST</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">-</span><span class="element">&gt;associated_copy</span><span class="plain">-</span><span class="element">&gt;location_if_path</span><span class="plain">, </span><span class="identifier">pathname</span><span class="plain">, </span><span class="identifier">inter_paths</span><span class="plain">);</span>
<span class="identifier">codegen_pipeline</span><span class="plain"> *</span><span class="identifier">SS</span><span class="plain"> = </span><span class="identifier">CodeGen::Pipeline::parse_from_file</span><span class="plain">(</span><span class="identifier">pipeline_as_file</span><span class="plain">, </span><span class="identifier">pipeline_vars</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">SS</span><span class="plain">) {</span>
<span class="identifier">linked_list</span><span class="plain"> *</span><span class="identifier">requirements_list</span><span class="plain"> = </span><span class="identifier">NEW_LINKED_LIST</span><span class="plain">(</span><span class="identifier">inter_library</span><span class="plain">);</span>
<span class="identifier">CodeGen::Pipeline::run</span><span class="plain">(</span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">SS</span><span class="plain">, </span><span class="identifier">inter_paths</span><span class="plain">, </span><span class="identifier">requirements_list</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="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Errors::nowhere</span><span class="plain">(</span><span class="string">"assimilate pipeline could not be parsed"</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="identifier">endif</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">int</span><span class="plain"> </span><span class="functiontext">InterSkill::code_generate_internally</span><span class="plain">(</span><span class="reserved">build_skill</span><span class="plain"> *</span><span class="identifier">skill</span><span class="plain">, </span><span class="reserved">build_step</span><span class="plain"> *</span><span class="identifier">S</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="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">CODEGEN_MODULE</span>
<span class="identifier">clock_t</span><span class="plain"> </span><span class="identifier">back_end</span><span class="plain"> = </span><span class="identifier">clock</span><span class="plain">();</span>
<span class="identifier">CodeGen::Architecture::set</span><span class="plain">(</span>
<span class="identifier">Architectures::to_codename</span><span class="plain">(</span>
<span class="identifier">TargetVMs::get_architecture</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">-</span><span class="element">&gt;for_vm</span><span class="plain">)));</span>
<span class="identifier">Str::copy</span><span class="plain">(</span><span class="identifier">Dictionaries::create_text</span><span class="plain">(</span><span class="identifier">pipeline_vars</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"*in"</span><span class="plain">), </span><span class="identifier">I</span><span class="string">"*memory"</span><span class="plain">);</span>
<span class="identifier">Str::copy</span><span class="plain">(</span><span class="identifier">Dictionaries::create_text</span><span class="plain">(</span><span class="identifier">pipeline_vars</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"*out"</span><span class="plain">),</span>
<span class="identifier">Filenames::get_leafname</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">-</span><span class="element">&gt;vertex</span><span class="plain">-</span><span class="element">&gt;buildable_if_internal_file</span><span class="plain">));</span>
<span class="identifier">codegen_pipeline</span><span class="plain"> *</span><span class="identifier">SS</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">inter_processing_pipeline</span><span class="plain">) &gt; 0) {</span>
<span class="identifier">SS</span><span class="plain"> = </span><span class="identifier">CodeGen::Pipeline::parse</span><span class="plain">(</span><span class="identifier">inter_processing_pipeline</span><span class="plain">, </span><span class="identifier">pipeline_vars</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">SS</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">"inter pipeline text could not be parsed"</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">else</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_processing_file</span><span class="plain">, </span><span class="identifier">NULL</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="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="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">STDERR</span><span class="plain">, </span><span class="string">"Sought pipeline '%S'\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">inter_processing_file</span><span class="plain">);</span>
<span class="identifier">Errors::nowhere</span><span class="plain">(</span><span class="string">"inter pipeline file 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>
<span class="plain">} </span><span class="reserved">else</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">LOOP_OVER_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">L</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="identifier">filename</span><span class="plain"> *</span><span class="identifier">F</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">SS</span><span class="plain"> = </span><span class="identifier">CodeGen::Pipeline::parse_from_file</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">, </span><span class="identifier">pipeline_vars</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">SS</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">"inter pipeline file could not be parsed"</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">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="identifier">CodeGen::Pipeline::set_repository</span><span class="plain">(</span><span class="identifier">SS</span><span class="plain">, </span><span class="identifier">Emit::tree</span><span class="plain">());</span>
<span class="identifier">CodeGen::Pipeline::run</span><span class="plain">(</span><span class="identifier">Filenames::get_path_to</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">-</span><span class="element">&gt;vertex</span><span class="plain">-</span><span class="element">&gt;buildable_if_internal_file</span><span class="plain">),</span>
<span class="identifier">SS</span><span class="plain">, </span><span class="functiontext">Kits::inter_paths</span><span class="plain">(), </span><span class="functiontext">Projects::list_of_inter_libraries</span><span class="plain">(</span><span class="functiontext">Inbuild::project</span><span class="plain">()));</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Back end elapsed time: %dcs\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, ((</span><span class="reserved">int</span><span class="plain">) (</span><span class="identifier">clock</span><span class="plain">() - </span><span class="identifier">back_end</span><span class="plain">)) / (</span><span class="identifier">CLOCKS_PER_SEC</span><span class="plain">/100));</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="plain">#</span><span class="identifier">ifndef</span><span class="plain"> </span><span class="identifier">CORE_MODULE</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="identifier">endif</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function InterSkill::create is used in 1/im (<a href="1-im.html#SP3">&#167;3</a>).</p>
<p class="endnote">The function InterSkill::assimilate_via_shell appears nowhere else.</p>
<p class="endnote">The function InterSkill::assimilate_internally appears nowhere else.</p>
<p class="endnote">The function InterSkill::code_generate_internally appears nowhere else.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="3-bs2.html">Back to 'Build Steps'</a></li><li><a href="3-is2.html">Continue with 'Inform7 Skill'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>

View file

@ -0,0 +1,78 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>3/is</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<!--Weave of '3/is2' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">inbuild</a></li><li><a href="index.html#3">Chapter 3: Incremental Builds</a></li><li><b>Inform7 Skill</b></li></ul><p class="purpose">A build step is a task such as running inform7 or inblorb on some file.</p>
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. </b></p>
<pre class="display">
<span class="reserved">build_skill</span><span class="plain"> *</span><span class="identifier">compile_using_inform7_skill</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Inform7Skill::create</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">compile_using_inform7_skill</span><span class="plain"> = </span><span class="functiontext">BuildSteps::new_skill</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"compile using inform7"</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">compile_using_inform7_skill</span><span class="plain">, </span><span class="constant">BUILD_SKILL_COMMAND_MTID</span><span class="plain">, </span><span class="functiontext">Inform7Skill::inform7_via_shell</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">compile_using_inform7_skill</span><span class="plain">, </span><span class="constant">BUILD_SKILL_INTERNAL_MTID</span><span class="plain">, </span><span class="functiontext">Inform7Skill::inform7_internally</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Inform7Skill::inform7_via_shell</span><span class="plain">(</span><span class="reserved">build_skill</span><span class="plain"> *</span><span class="identifier">skill</span><span class="plain">, </span><span class="reserved">build_step</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">command</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">inform_project</span><span class="plain"> *</span><span class="identifier">project</span><span class="plain"> = </span><span class="functiontext">ProjectBundleManager::from_copy</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">-</span><span class="element">&gt;associated_copy</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">project</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">project</span><span class="plain"> = </span><span class="functiontext">ProjectFileManager::from_copy</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">-</span><span class="element">&gt;associated_copy</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">project</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 project"</span><span class="plain">);</span>
<span class="identifier">Shell::quote_file</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="identifier">meth</span><span class="plain">-</span><span class="element">&gt;to_inform7</span><span class="plain">);</span>
<span class="reserved">inform_kit</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="reserved">inform_kit</span><span class="plain">, </span><span class="identifier">project</span><span class="plain">-</span><span class="element">&gt;kits_to_include</span><span class="plain">) {</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="string">"-kit %S "</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="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="plain">}</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="string">"-format=%S "</span><span class="plain">, </span><span class="identifier">TargetVMs::get_unblorbed_extension</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">-</span><span class="element">&gt;for_vm</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">S</span><span class="plain">-</span><span class="element">&gt;search_path</span><span class="plain">) {</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="functiontext">Nests::get_tag</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">)) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">MATERIALS_NEST_TAG</span><span class="plain">: </span><span class="reserved">continue</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">EXTERNAL_NEST_TAG</span><span class="plain">: </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="string">"-external "</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">GENERIC_NEST_TAG</span><span class="plain">: </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="string">"-nest "</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">INTERNAL_NEST_TAG</span><span class="plain">: </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="string">"-internal "</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">"mystery nest"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">Shell::quote_path</span><span class="plain">(</span><span class="identifier">command</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="plain">}</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="string">"-project "</span><span class="plain">);</span>
<span class="identifier">Shell::quote_path</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="identifier">S</span><span class="plain">-</span><span class="element">&gt;associated_copy</span><span class="plain">-</span><span class="element">&gt;location_if_path</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="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Inform7Skill::inform7_internally</span><span class="plain">(</span><span class="reserved">build_skill</span><span class="plain"> *</span><span class="identifier">skill</span><span class="plain">, </span><span class="reserved">build_step</span><span class="plain"> *</span><span class="identifier">S</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="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">CORE_MODULE</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain"> = </span><span class="identifier">Task::carry_out</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Inform7Skill::create is used in 1/im (<a href="1-im.html#SP3">&#167;3</a>).</p>
<p class="endnote">The function Inform7Skill::inform7_via_shell appears nowhere else.</p>
<p class="endnote">The function Inform7Skill::inform7_internally appears nowhere else.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="3-is.html">Back to 'Inter Skill'</a></li><li><a href="3-is3.html">Continue with 'Inform6 Skill'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>

View file

@ -0,0 +1,58 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>3/is2</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<!--Weave of '3/is3' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">inbuild</a></li><li><a href="index.html#3">Chapter 3: Incremental Builds</a></li><li><b>Inform6 Skill</b></li></ul><p class="purpose">A build step is a task such as running inform7 or inblorb on some file.</p>
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. </b></p>
<pre class="display">
<span class="reserved">build_skill</span><span class="plain"> *</span><span class="identifier">compile_using_inform6_skill</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Inform6Skill::create</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">compile_using_inform6_skill</span><span class="plain"> = </span><span class="functiontext">BuildSteps::new_skill</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"compile using inform6"</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">compile_using_inform6_skill</span><span class="plain">, </span><span class="constant">BUILD_SKILL_COMMAND_MTID</span><span class="plain">, </span><span class="functiontext">Inform6Skill::inform6_via_shell</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Inform6Skill::inform6_via_shell</span><span class="plain">(</span><span class="reserved">build_skill</span><span class="plain"> *</span><span class="identifier">skill</span><span class="plain">, </span><span class="reserved">build_step</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">command</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="identifier">Shell::quote_file</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="identifier">meth</span><span class="plain">-</span><span class="element">&gt;to_inform6</span><span class="plain">);</span>
<span class="reserved">inform_project</span><span class="plain"> *</span><span class="identifier">project</span><span class="plain"> = </span><span class="functiontext">ProjectBundleManager::from_copy</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">-</span><span class="element">&gt;associated_copy</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">project</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">project</span><span class="plain"> = </span><span class="functiontext">ProjectFileManager::from_copy</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">-</span><span class="element">&gt;associated_copy</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">project</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 project"</span><span class="plain">);</span>
<span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">build_folder</span><span class="plain"> = </span><span class="identifier">Pathnames::subfolder</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="element">&gt;location_if_path</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Build"</span><span class="plain">);</span>
<span class="identifier">filename</span><span class="plain"> *</span><span class="identifier">inf_F</span><span class="plain"> = </span><span class="identifier">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">build_folder</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"auto.inf"</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="string">"-kE2S"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">TargetVMs::debug_enabled</span><span class="plain">((</span><span class="identifier">S</span><span class="plain">-</span><span class="element">&gt;for_vm</span><span class="plain">))) </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="string">"D"</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">TargetVMs::get_unblorbed_extension</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">-</span><span class="element">&gt;for_vm</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">ext</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"ulx"</span><span class="plain">)) </span><span class="identifier">ext</span><span class="plain"> = </span><span class="identifier">I</span><span class="string">"G"</span><span class="plain">;</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="string">"w%S "</span><span class="plain">, </span><span class="identifier">ext</span><span class="plain">);</span>
<span class="identifier">Shell::quote_file</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="identifier">inf_F</span><span class="plain">);</span>
<span class="identifier">Shell::quote_file</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="identifier">S</span><span class="plain">-</span><span class="element">&gt;vertex</span><span class="plain">-</span><span class="element">&gt;buildable_if_internal_file</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="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Inform6Skill::create is used in 1/im (<a href="1-im.html#SP3">&#167;3</a>).</p>
<p class="endnote">The function Inform6Skill::inform6_via_shell appears nowhere else.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="3-is2.html">Back to 'Inform7 Skill'</a></li><li><a href="3-is4.html">Continue with 'Inblorb Skill'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>

View file

@ -0,0 +1,43 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>3/is3</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<!--Weave of '3/is4' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">inbuild</a></li><li><a href="index.html#3">Chapter 3: Incremental Builds</a></li><li><b>Inblorb Skill</b></li></ul><p class="purpose">A build step is a task such as running inform7 or inblorb on some file.</p>
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. </b></p>
<pre class="display">
<span class="reserved">build_skill</span><span class="plain"> *</span><span class="identifier">package_using_inblorb_skill</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">InblorbSkill::create</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">package_using_inblorb_skill</span><span class="plain"> = </span><span class="functiontext">BuildSteps::new_skill</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"package using inblorb"</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">package_using_inblorb_skill</span><span class="plain">, </span><span class="constant">BUILD_SKILL_COMMAND_MTID</span><span class="plain">, </span><span class="functiontext">InblorbSkill::inblorb_via_shell</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">InblorbSkill::inblorb_via_shell</span><span class="plain">(</span><span class="reserved">build_skill</span><span class="plain"> *</span><span class="identifier">skill</span><span class="plain">, </span><span class="reserved">build_step</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">command</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">command</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">"not available in-app"</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="string">"echo 'Not done yet'"</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="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function InblorbSkill::create is used in 1/im (<a href="1-im.html#SP3">&#167;3</a>).</p>
<p class="endnote">The function InblorbSkill::inblorb_via_shell appears nowhere else.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="3-is3.html">Back to 'Inform6 Skill'</a></li><li><i>(This section ends Chapter 3: Incremental Builds.)</i></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>

View file

@ -0,0 +1,323 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>4/km</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<!--Weave of '4/em' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">inbuild</a></li><li><a href="index.html#4">Chapter 4: Managing Genres of Work</a></li><li><b>Extension Manager</b></li></ul><p class="purpose">An Inform 7 extension.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Genre definition</a></li><li><a href="#SP6">&#167;6. Claiming</a></li><li><a href="#SP7">&#167;7. Searching</a></li><li><a href="#SP8">&#167;8. Copying</a></li><li><a href="#SP9">&#167;9. Build graph</a></li><li><a href="#SP10">&#167;10. Source text</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Genre definition. </b></p>
<pre class="display">
<span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">extension_genre</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>An extension has a title and an author name, each of which is limited in
length to one character less than the following constants:
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">MAX_EXTENSION_TITLE_LENGTH</span><span class="plain"> 51</span>
<span class="definitionkeyword">define</span> <span class="constant">MAX_EXTENSION_AUTHOR_LENGTH</span><span class="plain"> 51</span>
</pre>
<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">ExtensionManager::start</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">extension_genre</span><span class="plain"> = </span><span class="functiontext">Genres::new</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"extension"</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">extension_genre</span><span class="plain">, </span><span class="constant">GENRE_WRITE_WORK_MTID</span><span class="plain">, </span><span class="functiontext">ExtensionManager::write_work</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">extension_genre</span><span class="plain">, </span><span class="constant">GENRE_CLAIM_AS_COPY_MTID</span><span class="plain">, </span><span class="functiontext">ExtensionManager::claim_as_copy</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">extension_genre</span><span class="plain">, </span><span class="constant">GENRE_SCAN_COPY_MTID</span><span class="plain">, </span><span class="functiontext">Extensions::scan</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">extension_genre</span><span class="plain">, </span><span class="constant">GENRE_SEARCH_NEST_FOR_MTID</span><span class="plain">, </span><span class="functiontext">ExtensionManager::search_nest_for</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">extension_genre</span><span class="plain">, </span><span class="constant">GENRE_COPY_TO_NEST_MTID</span><span class="plain">, </span><span class="functiontext">ExtensionManager::copy_to_nest</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">extension_genre</span><span class="plain">, </span><span class="constant">GENRE_READ_SOURCE_TEXT_FOR_MTID</span><span class="plain">, </span><span class="functiontext">ExtensionManager::read_source_text_for</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">ExtensionManager::write_work</span><span class="plain">(</span><span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">gen</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">WRITE</span><span class="plain">(</span><span class="string">"%X"</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 ExtensionManager::start is used in 1/im (<a href="1-im.html#SP3">&#167;3</a>).</p>
<p class="endnote">The function ExtensionManager::write_work appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>Extensions live in their namesake subdirectory of a nest:
</p>
<pre class="display">
<span class="identifier">pathname</span><span class="plain"> *</span><span class="functiontext">ExtensionManager::path_within_nest</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="identifier">internal_error</span><span class="plain">(</span><span class="string">"no nest"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">Pathnames::subfolder</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">I</span><span class="string">"Extensions"</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function ExtensionManager::path_within_nest is used in <a href="#SP7">&#167;7</a>, <a href="#SP8">&#167;8</a>, 5/ec (<a href="5-ec.html#SP1">&#167;1</a>, <a href="5-ec.html#SP6_7_4_3">&#167;6.7.4.3</a>).</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b>Extension copies are annotated with a structure called an <code class="display"><span class="extract">inform_extension</span></code>,
which stores data about extensions used by the Inform compiler.
</p>
<pre class="display">
<span class="reserved">inform_extension</span><span class="plain"> *</span><span class="functiontext">ExtensionManager::from_copy</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">) &amp;&amp; (</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="identifier">extension_genre</span><span class="plain">)) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">RETRIEVE_POINTER_inform_extension</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="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">dictionary</span><span class="plain"> *</span><span class="identifier">ext_copy_cache</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="functiontext">ExtensionManager::new_copy</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">if</span><span class="plain"> (</span><span class="identifier">ext_copy_cache</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">ext_copy_cache</span><span class="plain"> = </span><span class="identifier">Dictionaries::new</span><span class="plain">(16, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">key</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">key</span><span class="plain">, </span><span class="string">"%f"</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="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Dictionaries::find</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="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">Copies::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>
<span class="identifier">Dictionaries::create</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="identifier">Dictionaries::write_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="identifier">C</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">key</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>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function ExtensionManager::from_copy is used in <a href="#SP10">&#167;10</a>, 5/ed2 (<a href="5-ed2.html#SP4">&#167;4</a>), 5/ec (<a href="5-ec.html#SP2">&#167;2</a>).</p>
<p class="endnote">The function ExtensionManager::new_copy is used in <a href="#SP6">&#167;6</a>.</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. Claiming. </b>Here <code class="display"><span class="extract">arg</span></code> is a textual form of a filename or pathname, such as may have been
supplied at the command line; <code class="display"><span class="extract">ext</span></code> is a substring of it, and is its extension
(e.g., <code class="display"><span class="extract">jpg</span></code> if <code class="display"><span class="extract">arg</span></code> is <code class="display"><span class="extract">Geraniums.jpg</span></code>), or is empty if there isn't one;
<code class="display"><span class="extract">directory_status</span></code> is true if we know for some reason that this is a directory
not a file, false if we know the reverse, and otherwise not applicable.
</p>
<p class="inwebparagraph">An extension, for us, needs to be a file with extension <code class="display"><span class="extract">i7x</span></code>, but it needs
also to scan properly &mdash; which means the top line of the file has to be right.
So we'll open it and look.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">ExtensionManager::claim_as_copy</span><span class="plain">(</span><span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">gen</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">arg</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="reserved">int</span><span class="plain"> </span><span class="identifier">directory_status</span><span class="plain">) {</span>
<span class="reserved">if</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="reserved">return</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">ext</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"i7x"</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">Filenames::from_text</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">);</span>
<span class="plain">*</span><span class="identifier">C</span><span class="plain"> = </span><span class="functiontext">ExtensionManager::claim_file_as_copy</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="functiontext">ExtensionManager::claim_file_as_copy</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">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="identifier">FALSE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain"> = </span><span class="functiontext">ExtensionManager::new_copy</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">);</span>
<span class="functiontext">ExtensionManager::build_vertex</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">);</span>
<span class="functiontext">Works::add_to_database</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="constant">CLAIMED_WDBC</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>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function ExtensionManager::claim_as_copy is used in <a href="#SP3">&#167;3</a>.</p>
<p class="endnote">The function ExtensionManager::claim_file_as_copy is used in <a href="#SP7">&#167;7</a>.</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. Searching. </b>Here we look through a nest to find all extensions matching the supplied
requirements.
</p>
<p class="inwebparagraph">For efficiency's sake, since the nest could contain many hundreds of
extensions, we narrow down to the author's subfolder if a specific
author is required, and to the specific extension file if title is
also known. (In particular, this happens when the Inform compiler is
using us to search for, say, Locksmith by Emily Short.)
</p>
<p class="inwebparagraph">Nobody should any longer be storing extension files without the file
extension <code class="display"><span class="extract">.i7x</span></code>, but this was allowed in the early days of Inform 7,
so we'll quietly allow for it.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">ExtensionManager::search_nest_for</span><span class="plain">(</span><span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">gen</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_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_results</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">) &amp;&amp; (</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">extension_genre</span><span class="plain">)) </span><span class="reserved">return</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="functiontext">ExtensionManager::path_within_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">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="identifier">pathname</span><span class="plain"> *</span><span class="identifier">Q</span><span class="plain"> = </span><span class="identifier">Pathnames::subfolder</span><span class="plain">(</span><span class="identifier">P</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="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">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i7x_flag</span><span class="plain"> = 1; </span><span class="identifier">i7x_flag</span><span class="plain"> &gt;= 0; </span><span class="identifier">i7x_flag</span><span class="plain">--) {</span>
<span class="identifier">TEMPORARY_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">i7x_flag</span><span class="plain">) </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">leaf</span><span class="plain">, </span><span class="string">"%S.i7x"</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="reserved">else</span><span class="plain"> </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">leaf</span><span class="plain">, </span><span class="string">"%S"</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">filename</span><span class="plain"> *</span><span class="identifier">F</span><span class="plain"> = </span><span class="identifier">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">Q</span><span class="plain">, </span><span class="identifier">leaf</span><span class="plain">);</span>
<span class="functiontext">ExtensionManager::search_nest_for_single_file</span><span class="plain">(</span><span class="identifier">F</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">search_results</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">leaf</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="functiontext">ExtensionManager::search_nest_for_r</span><span class="plain">(</span><span class="identifier">Q</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">search_results</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="functiontext">ExtensionManager::search_nest_for_r</span><span class="plain">(</span><span class="identifier">P</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">search_results</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">ExtensionManager::search_nest_for_r</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="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_results</span><span class="plain">) {</span>
<span class="identifier">scan_directory</span><span class="plain"> *</span><span class="identifier">D</span><span class="plain"> = </span><span class="identifier">Directories::open</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">D</span><span class="plain">) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">LEAFNAME</span><span class="plain">);</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">Directories::next</span><span class="plain">(</span><span class="identifier">D</span><span class="plain">, </span><span class="identifier">LEAFNAME</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">LEAFNAME</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">LEAFNAME</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::ne</span><span class="plain">(</span><span class="identifier">LEAFNAME</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Reserved"</span><span class="plain">)) {</span>
<span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">Q</span><span class="plain"> = </span><span class="identifier">Pathnames::subfolder</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">LEAFNAME</span><span class="plain">);</span>
<span class="functiontext">ExtensionManager::search_nest_for_r</span><span class="plain">(</span><span class="identifier">Q</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">search_results</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">} </span><span class="reserved">else</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">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">LEAFNAME</span><span class="plain">);</span>
<span class="functiontext">ExtensionManager::search_nest_for_single_file</span><span class="plain">(</span><span class="identifier">F</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">search_results</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">LEAFNAME</span><span class="plain">);</span>
<span class="identifier">Directories::close</span><span class="plain">(</span><span class="identifier">D</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">ExtensionManager::search_nest_for_single_file</span><span class="plain">(</span><span class="identifier">filename</span><span class="plain"> *</span><span class="identifier">F</span><span class="plain">, </span><span class="reserved">inbuild_nest</span><span class="plain"> *</span><span class="identifier">N</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_results</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">ExtensionManager::claim_file_as_copy</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">C</span><span class="plain">) &amp;&amp; (</span><span class="functiontext">Requirements::meets</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">req</span><span class="plain">))) {</span>
<span class="functiontext">Nests::add_search_result</span><span class="plain">(</span><span class="identifier">search_results</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="identifier">req</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function ExtensionManager::search_nest_for is used in <a href="#SP3">&#167;3</a>.</p>
<p class="endnote">The function ExtensionManager::search_nest_for_r appears nowhere else.</p>
<p class="endnote">The function ExtensionManager::search_nest_for_single_file appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. Copying. </b>Now the task is to copy an extension into place in a nest. This is easy,
since an extension is a single file; to sync, we just overwrite.
</p>
<pre class="display">
<span class="identifier">filename</span><span class="plain"> *</span><span class="functiontext">ExtensionManager::filename_in_nest</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">title</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">author</span><span class="plain">) {</span>
<span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">E</span><span class="plain"> = </span><span class="functiontext">ExtensionManager::path_within_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">leaf</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">leaf</span><span class="plain">, </span><span class="string">"%S.i7x"</span><span class="plain">, </span><span class="identifier">title</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">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">Pathnames::subfolder</span><span class="plain">(</span><span class="identifier">E</span><span class="plain">, </span><span class="identifier">author</span><span class="plain">), </span><span class="identifier">leaf</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">leaf</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">F</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">ExtensionManager::copy_to_nest</span><span class="plain">(</span><span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">gen</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">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="identifier">pathname</span><span class="plain"> *</span><span class="identifier">E</span><span class="plain"> = </span><span class="functiontext">ExtensionManager::path_within_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">leaf</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">leaf</span><span class="plain">, </span><span class="string">"%S.i7x"</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;title</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">Filenames::in_folder</span><span class="plain">(</span>
<span class="identifier">Pathnames::subfolder</span><span class="plain">(</span><span class="identifier">E</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;author_name</span><span class="plain">), </span><span class="identifier">leaf</span><span class="plain">);</span>
<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="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>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="string">"mkdir -p "</span><span class="plain">);</span>
<span class="identifier">Shell::quote_path</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="identifier">Filenames::get_path_to</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">));</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">STDOUT</span><span class="plain">, </span><span class="string">"%S\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">command</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Pathnames::create_in_file_system</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">Pathnames::create_in_file_system</span><span class="plain">(</span><span class="identifier">Pathnames::subfolder</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">I</span><span class="string">"Extensions"</span><span class="plain">));</span>
<span class="identifier">Pathnames::create_in_file_system</span><span class="plain">(</span><span class="identifier">Filenames::get_path_to</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">));</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="string">"cp -f "</span><span class="plain">);</span>
<span class="identifier">Shell::quote_file</span><span class="plain">(</span><span class="identifier">command</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">Shell::quote_file</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="identifier">F</span><span class="plain">);</span>
<span class="functiontext">BuildSteps::shell</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="identifier">meth</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function ExtensionManager::filename_in_nest appears nowhere else.</p>
<p class="endnote">The function ExtensionManager::copy_to_nest is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. Build graph. </b>The build graph for an extension is just a single node: you don't need to
build an extension at all.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">ExtensionManager::build_vertex</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">Graphs::copy_vertex</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 ExtensionManager::build_vertex is used in <a href="#SP6">&#167;6</a>.</p>
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. Source text. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">ExtensionManager::read_source_text_for</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="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain">) {</span>
<span class="functiontext">Extensions::read_source_text_for</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="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function ExtensionManager::read_source_text_for is used in <a href="#SP3">&#167;3</a>.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="4-km.html">Back to 'Kit Manager'</a></li><li><a href="4-lm.html">Continue with 'Language Manager'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>

View file

@ -0,0 +1,276 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>3/is4</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<!--Weave of '4/km' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">inbuild</a></li><li><a href="index.html#4">Chapter 4: Managing Genres of Work</a></li><li><b>Kit Manager</b></li></ul><p class="purpose">A kit is a combination of Inter code with an Inform 7 extension.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Genre definition</a></li><li><a href="#SP4">&#167;4. Claiming</a></li><li><a href="#SP5">&#167;5. Searching</a></li><li><a href="#SP6">&#167;6. Copying</a></li><li><a href="#SP7">&#167;7. Build graph</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Genre definition. </b></p>
<pre class="display">
<span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">kit_genre</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">KitManager::start</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">kit_genre</span><span class="plain"> = </span><span class="functiontext">Genres::new</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"kit"</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">kit_genre</span><span class="plain">, </span><span class="constant">GENRE_WRITE_WORK_MTID</span><span class="plain">, </span><span class="functiontext">KitManager::write_work</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">kit_genre</span><span class="plain">, </span><span class="constant">GENRE_CLAIM_AS_COPY_MTID</span><span class="plain">, </span><span class="functiontext">KitManager::claim_as_copy</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">kit_genre</span><span class="plain">, </span><span class="constant">GENRE_SCAN_COPY_MTID</span><span class="plain">, </span><span class="functiontext">Kits::scan</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">kit_genre</span><span class="plain">, </span><span class="constant">GENRE_SEARCH_NEST_FOR_MTID</span><span class="plain">, </span><span class="functiontext">KitManager::search_nest_for</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">kit_genre</span><span class="plain">, </span><span class="constant">GENRE_COPY_TO_NEST_MTID</span><span class="plain">, </span><span class="functiontext">KitManager::copy_to_nest</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">kit_genre</span><span class="plain">, </span><span class="constant">GENRE_GO_OPERATIONAL_MTID</span><span class="plain">, </span><span class="functiontext">KitManager::go_operational</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">kit_genre</span><span class="plain">, </span><span class="constant">GENRE_BUILD_COPY_MTID</span><span class="plain">, </span><span class="functiontext">KitManager::build</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">KitManager::write_work</span><span class="plain">(</span><span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">gen</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">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;title</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function KitManager::start is used in 1/im (<a href="1-im.html#SP3">&#167;3</a>).</p>
<p class="endnote">The function KitManager::write_work appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>Kits live in the <code class="display"><span class="extract">Inter</span></code> subdirectory of a nest:
</p>
<pre class="display">
<span class="identifier">pathname</span><span class="plain"> *</span><span class="functiontext">KitManager::path_within_nest</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="identifier">internal_error</span><span class="plain">(</span><span class="string">"no nest"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">Pathnames::subfolder</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">I</span><span class="string">"Inter"</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function KitManager::path_within_nest is used in <a href="#SP5">&#167;5</a>, <a href="#SP6">&#167;6</a>, 5/kts (<a href="5-kts.html#SP1">&#167;1</a>).</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>Kit copies are annotated with a structure called an <code class="display"><span class="extract">inform_kit</span></code>,
which stores data about extensions used by the Inform compiler.
</p>
<pre class="display">
<span class="reserved">inform_kit</span><span class="plain"> *</span><span class="functiontext">KitManager::from_copy</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">) &amp;&amp; (</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="identifier">kit_genre</span><span class="plain">)) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">RETRIEVE_POINTER_inform_kit</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="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">dictionary</span><span class="plain"> *</span><span class="identifier">kit_copy_cache</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="functiontext">KitManager::new_copy</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">pathname</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">kit_copy_cache</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">kit_copy_cache</span><span class="plain"> = </span><span class="identifier">Dictionaries::new</span><span class="plain">(16, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">key</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">key</span><span class="plain">, </span><span class="string">"%p"</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">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">Dictionaries::find</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><span class="identifier">Dictionaries::read_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="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="functiontext">Copies::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>
<span class="plain">}</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">key</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>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function KitManager::from_copy is used in <a href="#SP7">&#167;7</a>, 5/kts (<a href="5-kts.html#SP1">&#167;1</a>).</p>
<p class="endnote">The function KitManager::new_copy is used in <a href="#SP4">&#167;4</a>, 5/kts (<a href="5-kts.html#SP1">&#167;1</a>).</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. Claiming. </b>Here <code class="display"><span class="extract">arg</span></code> is a textual form of a filename or pathname, such as may have been
supplied at the command line; <code class="display"><span class="extract">ext</span></code> is a substring of it, and is its extension
(e.g., <code class="display"><span class="extract">jpg</span></code> if <code class="display"><span class="extract">arg</span></code> is <code class="display"><span class="extract">Geraniums.jpg</span></code>), or is empty if there isn't one;
<code class="display"><span class="extract">directory_status</span></code> is true if we know for some reason that this is a directory
not a file, false if we know the reverse, and otherwise not applicable.
</p>
<p class="inwebparagraph">A kit needs to be a directory whose name ends in <code class="display"><span class="extract">Kit</span></code>, and which contains
a valid metadata file.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">KitManager::claim_as_copy</span><span class="plain">(</span><span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">gen</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">arg</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="reserved">int</span><span class="plain"> </span><span class="identifier">directory_status</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">directory_status</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">kitpos</span><span class="plain"> = </span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">) - 3;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">kitpos</span><span class="plain"> &gt;= 0) &amp;&amp; (</span><span class="identifier">Str::get_at</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">, </span><span class="identifier">kitpos</span><span class="plain">) == </span><span class="character">'K'</span><span class="plain">) &amp;&amp;</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">kitpos</span><span class="plain">+1) == </span><span class="character">'i'</span><span class="plain">) &amp;&amp;</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">kitpos</span><span class="plain">+2) == </span><span class="character">'t'</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">Pathnames::from_text</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">);</span>
<span class="plain">*</span><span class="identifier">C</span><span class="plain"> = </span><span class="functiontext">KitManager::claim_folder_as_copy</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="functiontext">KitManager::claim_folder_as_copy</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">filename</span><span class="plain"> *</span><span class="identifier">canary</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">"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">canary</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">KitManager::new_copy</span><span class="plain">(</span><span class="identifier">Pathnames::directory_name</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">), </span><span class="identifier">P</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>
<span class="functiontext">Works::add_to_database</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="constant">CLAIMED_WDBC</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">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 KitManager::claim_as_copy is used in <a href="#SP1">&#167;1</a>.</p>
<p class="endnote">The function KitManager::claim_folder_as_copy is used in <a href="#SP5">&#167;5</a>.</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. Searching. </b>Here we look through a nest to find all kits matching the supplied
requirements.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">KitManager::search_nest_for</span><span class="plain">(</span><span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">gen</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_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_results</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">) &amp;&amp; (</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">kit_genre</span><span class="plain">)) </span><span class="reserved">return</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="functiontext">KitManager::path_within_nest</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">);</span>
<span class="identifier">scan_directory</span><span class="plain"> *</span><span class="identifier">D</span><span class="plain"> = </span><span class="identifier">Directories::open</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">D</span><span class="plain">) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">LEAFNAME</span><span class="plain">);</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">Directories::next</span><span class="plain">(</span><span class="identifier">D</span><span class="plain">, </span><span class="identifier">LEAFNAME</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">LEAFNAME</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">LEAFNAME</span><span class="plain">);</span>
<span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">Q</span><span class="plain"> = </span><span class="identifier">Pathnames::subfolder</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">LEAFNAME</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">KitManager::claim_folder_as_copy</span><span class="plain">(</span><span class="identifier">Q</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">C</span><span class="plain">) &amp;&amp; (</span><span class="functiontext">Requirements::meets</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">req</span><span class="plain">))) {</span>
<span class="functiontext">Nests::add_search_result</span><span class="plain">(</span><span class="identifier">search_results</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="identifier">req</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">LEAFNAME</span><span class="plain">);</span>
<span class="identifier">Directories::close</span><span class="plain">(</span><span class="identifier">D</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function KitManager::search_nest_for is used in <a href="#SP1">&#167;1</a>.</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. Copying. </b>Now the task is to copy a kit into place in a nest. Since a kit is a folder,
we need to <code class="display"><span class="extract">rsync</span></code> it.
</p>
<pre class="display">
<span class="identifier">pathname</span><span class="plain"> *</span><span class="functiontext">KitManager::pathname_in_nest</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_work</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">Pathnames::subfolder</span><span class="plain">(</span><span class="functiontext">KitManager::path_within_nest</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">), </span><span class="identifier">W</span><span class="plain">-</span><span class="element">&gt;title</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">KitManager::copy_to_nest</span><span class="plain">(</span><span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">gen</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">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="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="element">&gt;work</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="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>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="string">"mkdir -p "</span><span class="plain">);</span>
<span class="identifier">Shell::quote_path</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="identifier">dest_kit</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">STDOUT</span><span class="plain">, </span><span class="string">"%S\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">command</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Pathnames::create_in_file_system</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">Pathnames::create_in_file_system</span><span class="plain">(</span><span class="functiontext">KitManager::path_within_nest</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">));</span>
<span class="identifier">Pathnames::create_in_file_system</span><span class="plain">(</span><span class="identifier">dest_kit</span><span class="plain">);</span>
<span class="plain">}</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>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="string">"rsync -a --delete "</span><span class="plain">);</span>
<span class="identifier">Shell::quote_path</span><span class="plain">(</span><span class="identifier">command</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">Shell::quote_path</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="identifier">dest_kit</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">STDOUT</span><span class="plain">, </span><span class="string">"%S\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">command</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Pathnames::rsync</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">dest_kit</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function KitManager::pathname_in_nest appears nowhere else.</p>
<p class="endnote">The function KitManager::copy_to_nest is used in <a href="#SP1">&#167;1</a>.</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. Build graph. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">KitManager::build</span><span class="plain">(</span><span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">gen</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">OUT</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">int</span><span class="plain"> </span><span class="identifier">rebuild</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">describe_only</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">describe_only</span><span class="plain">) </span><span class="functiontext">Graphs::describe</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">TRUE</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">rebuild</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">C</span><span class="plain">-</span><span class="element">&gt;vertex</span><span class="plain">, </span><span class="identifier">BM</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="functiontext">Graphs::build</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">BM</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">KitManager::build_vertex</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">Graphs::copy_vertex</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">KitManager::go_operational</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="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain">) {</span>
<span class="functiontext">Kits::construct_graph</span><span class="plain">(</span><span class="functiontext">KitManager::from_copy</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">));</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">kit_contents_section_state</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">sects</span><span class="plain">; </span> <span class="comment">of <code class="display"><span class="extract">text_stream</span></code></span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">active</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">kit_contents_section_state</span><span class="plain">;</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">KitManager::read_contents</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">text</span><span class="plain">, </span><span class="identifier">text_file_position</span><span class="plain"> *</span><span class="identifier">tfp</span><span class="plain">, </span><span class="reserved">void</span><span class="plain"> *</span><span class="identifier">state</span><span class="plain">) {</span>
<span class="reserved">kit_contents_section_state</span><span class="plain"> *</span><span class="identifier">CSS</span><span class="plain"> = (</span><span class="reserved">kit_contents_section_state</span><span class="plain"> *) </span><span class="identifier">state</span><span class="plain">;</span>
<span class="identifier">match_results</span><span class="plain"> </span><span class="identifier">mr</span><span class="plain"> = </span><span class="identifier">Regexp::create_mr</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">"Sections"</span><span class="plain">))</span>
<span class="identifier">CSS</span><span class="plain">-</span><span class="element">&gt;active</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">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">" (%c+)"</span><span class="plain">)) &amp;&amp; (</span><span class="identifier">CSS</span><span class="plain">-</span><span class="element">&gt;active</span><span class="plain">)) {</span>
<span class="identifier">WRITE_TO</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="string">".i6t"</span><span class="plain">);</span>
<span class="identifier">ADD_TO_LINKED_LIST</span><span class="plain">(</span><span class="identifier">Str::duplicate</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="identifier">text_stream</span><span class="plain">, </span><span class="identifier">CSS</span><span class="plain">-</span><span class="element">&gt;sects</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>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function KitManager::build is used in <a href="#SP1">&#167;1</a>.</p>
<p class="endnote">The function KitManager::build_vertex is used in <a href="#SP4">&#167;4</a>, 5/kts (<a href="5-kts.html#SP1">&#167;1</a>).</p>
<p class="endnote">The function KitManager::go_operational is used in <a href="#SP1">&#167;1</a>.</p>
<p class="endnote">The function KitManager::read_contents is used in 5/kts (<a href="5-kts.html#SP2">&#167;2</a>).</p>
<p class="endnote">The structure kit_contents_section_state is accessed in 5/kts and here.</p>
<hr class="tocbar">
<ul class="toc"><li><i>(This section begins Chapter 4: Managing Genres of Work.)</i></li><li><a href="4-em.html">Continue with 'Extension Manager'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>

View file

@ -0,0 +1,252 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>4/em</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<!--Weave of '4/lm' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">inbuild</a></li><li><a href="index.html#4">Chapter 4: Managing Genres of Work</a></li><li><b>Language Manager</b></li></ul><p class="purpose">A language is a combination of Inter code with an Inform 7 extension.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Genre definition</a></li><li><a href="#SP5">&#167;5. Claiming</a></li><li><a href="#SP6">&#167;6. Searching</a></li><li><a href="#SP7">&#167;7. Copying</a></li><li><a href="#SP8">&#167;8. Build graph</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Genre definition. </b></p>
<pre class="display">
<span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">language_genre</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">LanguageManager::start</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">language_genre</span><span class="plain"> = </span><span class="functiontext">Genres::new</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"language"</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">language_genre</span><span class="plain">, </span><span class="constant">GENRE_WRITE_WORK_MTID</span><span class="plain">, </span><span class="functiontext">LanguageManager::write_work</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">language_genre</span><span class="plain">, </span><span class="constant">GENRE_CLAIM_AS_COPY_MTID</span><span class="plain">, </span><span class="functiontext">LanguageManager::claim_as_copy</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">language_genre</span><span class="plain">, </span><span class="constant">GENRE_SEARCH_NEST_FOR_MTID</span><span class="plain">, </span><span class="functiontext">LanguageManager::search_nest_for</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">language_genre</span><span class="plain">, </span><span class="constant">GENRE_COPY_TO_NEST_MTID</span><span class="plain">, </span><span class="functiontext">LanguageManager::copy_to_nest</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">LanguageManager::write_work</span><span class="plain">(</span><span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">gen</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">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;title</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function LanguageManager::start is used in 1/im (<a href="1-im.html#SP3">&#167;3</a>).</p>
<p class="endnote">The function LanguageManager::write_work appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>Languages live in the <code class="display"><span class="extract">Inter</span></code> subdirectory of a nest:
</p>
<pre class="display">
<span class="identifier">pathname</span><span class="plain"> *</span><span class="functiontext">LanguageManager::path_within_nest</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="identifier">internal_error</span><span class="plain">(</span><span class="string">"no nest"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">Pathnames::subfolder</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">I</span><span class="string">"Languages"</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function LanguageManager::path_within_nest is used in <a href="#SP6">&#167;6</a>, <a href="#SP7">&#167;7</a>.</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>Language copies are annotated with a structure called an <code class="display"><span class="extract">inform_language</span></code>,
which stores data about extensions used by the Inform compiler.
</p>
<pre class="display">
<span class="reserved">inform_language</span><span class="plain"> *</span><span class="functiontext">LanguageManager::from_copy</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">) &amp;&amp; (</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="identifier">language_genre</span><span class="plain">)) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">RETRIEVE_POINTER_inform_language</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="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">dictionary</span><span class="plain"> *</span><span class="identifier">language_copy_cache</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="functiontext">LanguageManager::new_copy</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">pathname</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">language_copy_cache</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">language_copy_cache</span><span class="plain"> = </span><span class="identifier">Dictionaries::new</span><span class="plain">(16, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">key</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">key</span><span class="plain">, </span><span class="string">"%p"</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">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">Dictionaries::find</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><span class="identifier">Dictionaries::read_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="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">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">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>
<span class="plain">}</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">key</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>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function LanguageManager::from_copy is used in 5/ps (<a href="5-ps.html#SP1">&#167;1</a>).</p>
<p class="endnote">The function LanguageManager::new_copy is used in <a href="#SP5">&#167;5</a>.</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. Claiming. </b>Here <code class="display"><span class="extract">arg</span></code> is a textual form of a filename or pathname, such as may have been
supplied at the command line; <code class="display"><span class="extract">ext</span></code> is a substring of it, and is its extension
(e.g., <code class="display"><span class="extract">jpg</span></code> if <code class="display"><span class="extract">arg</span></code> is <code class="display"><span class="extract">Geraniums.jpg</span></code>), or is empty if there isn't one;
<code class="display"><span class="extract">directory_status</span></code> is true if we know for some reason that this is a directory
not a file, false if we know the reverse, and otherwise not applicable.
</p>
<p class="inwebparagraph">A language needs to be a directory whose name ends in <code class="display"><span class="extract">Language</span></code>, and which contains
a valid metadata file. The name should be in English text, without accents.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">LanguageManager::claim_as_copy</span><span class="plain">(</span><span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">gen</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">arg</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="reserved">int</span><span class="plain"> </span><span class="identifier">directory_status</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">directory_status</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain"> = </span><span class="identifier">Pathnames::from_text</span><span class="plain">(</span><span class="identifier">arg</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">Pathnames::directory_name</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">acceptable</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">name</span><span class="plain">) {</span>
<span class="reserved">int</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">c</span><span class="plain"> &lt; 32) || (</span><span class="identifier">c</span><span class="plain"> &gt; 126)) </span><span class="identifier">acceptable</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">; </span> <span class="comment">contains non-ASCII</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="identifier">Str::put</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">, 0); </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">Str::len</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">) == 0) </span><span class="identifier">acceptable</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">; </span> <span class="comment">i.e., an empty text</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">acceptable</span><span class="plain">) {</span>
<span class="plain">*</span><span class="identifier">C</span><span class="plain"> = </span><span class="functiontext">LanguageManager::claim_folder_as_copy</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="functiontext">LanguageManager::claim_folder_as_copy</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">filename</span><span class="plain"> *</span><span class="identifier">canary</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">"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">canary</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">LanguageManager::new_copy</span><span class="plain">(</span><span class="identifier">Pathnames::directory_name</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">), </span><span class="identifier">P</span><span class="plain">);</span>
<span class="functiontext">LanguageManager::build_vertex</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">);</span>
<span class="functiontext">Works::add_to_database</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="constant">CLAIMED_WDBC</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">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 LanguageManager::claim_as_copy is used in <a href="#SP2">&#167;2</a>.</p>
<p class="endnote">The function LanguageManager::claim_folder_as_copy is used in <a href="#SP6">&#167;6</a>.</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. Searching. </b>Here we look through a nest to find all languages matching the supplied
requirements.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">LanguageManager::search_nest_for</span><span class="plain">(</span><span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">gen</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_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_results</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="functiontext">LanguageManager::path_within_nest</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">);</span>
<span class="identifier">scan_directory</span><span class="plain"> *</span><span class="identifier">D</span><span class="plain"> = </span><span class="identifier">Directories::open</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">D</span><span class="plain">) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">LEAFNAME</span><span class="plain">);</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">Directories::next</span><span class="plain">(</span><span class="identifier">D</span><span class="plain">, </span><span class="identifier">LEAFNAME</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">LEAFNAME</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">LEAFNAME</span><span class="plain">);</span>
<span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">Q</span><span class="plain"> = </span><span class="identifier">Pathnames::subfolder</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">LEAFNAME</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">LanguageManager::claim_folder_as_copy</span><span class="plain">(</span><span class="identifier">Q</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">C</span><span class="plain">) &amp;&amp; (</span><span class="functiontext">Requirements::meets</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">req</span><span class="plain">))) {</span>
<span class="functiontext">Nests::add_search_result</span><span class="plain">(</span><span class="identifier">search_results</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="identifier">req</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">LEAFNAME</span><span class="plain">);</span>
<span class="identifier">Directories::close</span><span class="plain">(</span><span class="identifier">D</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function LanguageManager::search_nest_for is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. Copying. </b>Now the task is to copy a language into place in a nest. Since a language is a folder,
we need to <code class="display"><span class="extract">rsync</span></code> it.
</p>
<pre class="display">
<span class="identifier">pathname</span><span class="plain"> *</span><span class="functiontext">LanguageManager::pathname_in_nest</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_work</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">Pathnames::subfolder</span><span class="plain">(</span><span class="functiontext">LanguageManager::path_within_nest</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">), </span><span class="identifier">W</span><span class="plain">-</span><span class="element">&gt;title</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">LanguageManager::copy_to_nest</span><span class="plain">(</span><span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">gen</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">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="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="element">&gt;work</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="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>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="string">"mkdir -p "</span><span class="plain">);</span>
<span class="identifier">Shell::quote_path</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="identifier">dest_language</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">STDOUT</span><span class="plain">, </span><span class="string">"%S\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">command</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Pathnames::create_in_file_system</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">Pathnames::create_in_file_system</span><span class="plain">(</span><span class="functiontext">LanguageManager::path_within_nest</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">));</span>
<span class="identifier">Pathnames::create_in_file_system</span><span class="plain">(</span><span class="identifier">dest_language</span><span class="plain">);</span>
<span class="plain">}</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>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="string">"rsync -a --delete "</span><span class="plain">);</span>
<span class="identifier">Shell::quote_path</span><span class="plain">(</span><span class="identifier">command</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">Shell::quote_path</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="identifier">dest_language</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">STDOUT</span><span class="plain">, </span><span class="string">"%S\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">command</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Pathnames::rsync</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">dest_language</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function LanguageManager::pathname_in_nest appears nowhere else.</p>
<p class="endnote">The function LanguageManager::copy_to_nest is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. Build graph. </b>The build graph for a language bundle is just a single node: you don't need to
build it at all.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">LanguageManager::build_vertex</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">Graphs::copy_vertex</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 LanguageManager::build_vertex is used in <a href="#SP5">&#167;5</a>.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="4-em.html">Back to 'Extension Manager'</a></li><li><a href="4-pbm.html">Continue with 'Project Bundle Manager'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>

View file

@ -0,0 +1,202 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>4/lm</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<!--Weave of '4/pbm' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">inbuild</a></li><li><a href="index.html#4">Chapter 4: Managing Genres of Work</a></li><li><b>Project Bundle Manager</b></li></ul><p class="purpose">A project bundle is a folder holding an Inform 7 work. The app creates these.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Genre definition</a></li><li><a href="#SP3">&#167;3. Claiming</a></li><li><a href="#SP4">&#167;4. Searching</a></li><li><a href="#SP5">&#167;5. Copying</a></li><li><a href="#SP6">&#167;6. Build graph</a></li><li><a href="#SP9">&#167;9. Source text</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Genre definition. </b></p>
<pre class="display">
<span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">project_bundle_genre</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">ProjectBundleManager::start</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">project_bundle_genre</span><span class="plain"> = </span><span class="functiontext">Genres::new</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"projectbundle"</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">project_bundle_genre</span><span class="plain">, </span><span class="constant">GENRE_WRITE_WORK_MTID</span><span class="plain">, </span><span class="functiontext">ProjectBundleManager::write_work</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">project_bundle_genre</span><span class="plain">, </span><span class="constant">GENRE_CLAIM_AS_COPY_MTID</span><span class="plain">, </span><span class="functiontext">ProjectBundleManager::claim_as_copy</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">project_bundle_genre</span><span class="plain">, </span><span class="constant">GENRE_SEARCH_NEST_FOR_MTID</span><span class="plain">, </span><span class="functiontext">ProjectBundleManager::search_nest_for</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">project_bundle_genre</span><span class="plain">, </span><span class="constant">GENRE_COPY_TO_NEST_MTID</span><span class="plain">, </span><span class="functiontext">ProjectBundleManager::copy_to_nest</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">project_bundle_genre</span><span class="plain">, </span><span class="constant">GENRE_GO_OPERATIONAL_MTID</span><span class="plain">, </span><span class="functiontext">ProjectBundleManager::go_operational</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">project_bundle_genre</span><span class="plain">, </span><span class="constant">GENRE_READ_SOURCE_TEXT_FOR_MTID</span><span class="plain">, </span><span class="functiontext">ProjectBundleManager::read_source_text_for</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">project_bundle_genre</span><span class="plain">, </span><span class="constant">GENRE_BUILD_COPY_MTID</span><span class="plain">, </span><span class="functiontext">ProjectBundleManager::build</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">ProjectBundleManager::write_work</span><span class="plain">(</span><span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">gen</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">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;title</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function ProjectBundleManager::start is used in 1/im (<a href="1-im.html#SP3">&#167;3</a>).</p>
<p class="endnote">The function ProjectBundleManager::write_work appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>Project copies are annotated with a structure called an <code class="display"><span class="extract">inform_project</span></code>,
which stores data about extensions used by the Inform compiler.
</p>
<pre class="display">
<span class="reserved">inform_project</span><span class="plain"> *</span><span class="functiontext">ProjectBundleManager::from_copy</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">) &amp;&amp; (</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="identifier">project_bundle_genre</span><span class="plain">)) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">RETRIEVE_POINTER_inform_project</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="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="functiontext">ProjectBundleManager::new_copy</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">pathname</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain">) {</span>
<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="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>
<p class="inwebparagraph"></p>
<p class="endnote">The function ProjectBundleManager::from_copy is used in <a href="#SP6">&#167;6</a>, <a href="#SP8">&#167;8</a>, <a href="#SP9">&#167;9</a>, 1/ic (<a href="1-ic.html#SP11">&#167;11</a>), 3/is2 (<a href="3-is2.html#SP1">&#167;1</a>), 3/is3 (<a href="3-is3.html#SP1">&#167;1</a>), 4/pfm (<a href="4-pfm.html#SP6">&#167;6</a>, <a href="4-pfm.html#SP9">&#167;9</a>).</p>
<p class="endnote">The function ProjectBundleManager::new_copy is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. Claiming. </b>Here <code class="display"><span class="extract">arg</span></code> is a textual form of a filename or pathname, such as may have been
supplied at the command line; <code class="display"><span class="extract">ext</span></code> is a substring of it, and is its extension
(e.g., <code class="display"><span class="extract">jpg</span></code> if <code class="display"><span class="extract">arg</span></code> is <code class="display"><span class="extract">Geraniums.jpg</span></code>), or is empty if there isn't one;
<code class="display"><span class="extract">directory_status</span></code> is true if we know for some reason that this is a directory
not a file, false if we know the reverse, and otherwise not applicable.
</p>
<p class="inwebparagraph">A project needs to be a directory whose name ends in <code class="display"><span class="extract">.inform</span></code>.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">ProjectBundleManager::claim_as_copy</span><span class="plain">(</span><span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">gen</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">arg</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="reserved">int</span><span class="plain"> </span><span class="identifier">directory_status</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">directory_status</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::eq_insensitive</span><span class="plain">(</span><span class="identifier">ext</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"inform"</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">Pathnames::from_text</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">);</span>
<span class="plain">*</span><span class="identifier">C</span><span class="plain"> = </span><span class="functiontext">ProjectBundleManager::claim_folder_as_copy</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="functiontext">ProjectBundleManager::claim_folder_as_copy</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">C</span><span class="plain"> = </span><span class="functiontext">ProjectBundleManager::new_copy</span><span class="plain">(</span><span class="identifier">Pathnames::directory_name</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">), </span><span class="identifier">P</span><span class="plain">);</span>
<span class="functiontext">ProjectBundleManager::build_vertex</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">);</span>
<span class="functiontext">Works::add_to_database</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="constant">CLAIMED_WDBC</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>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function ProjectBundleManager::claim_as_copy is used in <a href="#SP1">&#167;1</a>.</p>
<p class="endnote">The function ProjectBundleManager::claim_folder_as_copy is used in 1/ic (<a href="1-ic.html#SP11">&#167;11</a>).</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. Searching. </b>Here we look through a nest to find all projects matching the supplied
requirements; though in fact... projects are not nesting birds.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">ProjectBundleManager::search_nest_for</span><span class="plain">(</span><span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">gen</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_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_results</span><span class="plain">) {</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function ProjectBundleManager::search_nest_for is used in <a href="#SP1">&#167;1</a>.</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. Copying. </b>Now the task is to copy a project into place in a nest; or would be, if only
projects lived there.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">ProjectBundleManager::copy_to_nest</span><span class="plain">(</span><span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">gen</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">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="identifier">Errors::with_text</span><span class="plain">(</span><span class="string">"projects (which is what '%S' is) cannot be copied to nests"</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;title</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function ProjectBundleManager::copy_to_nest is used in <a href="#SP1">&#167;1</a>.</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. Build graph. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">ProjectBundleManager::build</span><span class="plain">(</span><span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">gen</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">OUT</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">int</span><span class="plain"> </span><span class="identifier">rebuild</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">describe_only</span><span class="plain">) {</span>
<span class="reserved">inform_project</span><span class="plain"> *</span><span class="identifier">project</span><span class="plain"> = </span><span class="functiontext">ProjectBundleManager::from_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">project</span><span class="plain">-</span><span class="element">&gt;chosen_build_target</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">describe_only</span><span class="plain">) </span><span class="functiontext">Graphs::describe</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">TRUE</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">rebuild</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="reserved">else</span><span class="plain"> </span><span class="functiontext">Graphs::build</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 ProjectBundleManager::build is used in <a href="#SP1">&#167;1</a>.</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. </b>The build graph for a project will need further thought...
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">ProjectBundleManager::build_vertex</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">Graphs::copy_vertex</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 ProjectBundleManager::build_vertex is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. </b>which it will get here:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">ProjectBundleManager::go_operational</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="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain">) {</span>
<span class="functiontext">Projects::construct_graph</span><span class="plain">(</span><span class="functiontext">ProjectBundleManager::from_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 ProjectBundleManager::go_operational is used in <a href="#SP1">&#167;1</a>.</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. Source text. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">ProjectBundleManager::read_source_text_for</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="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain">) {</span>
<span class="functiontext">Projects::read_source_text_for</span><span class="plain">(</span><span class="functiontext">ProjectBundleManager::from_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 ProjectBundleManager::read_source_text_for is used in <a href="#SP1">&#167;1</a>.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="4-lm.html">Back to 'Language Manager'</a></li><li><a href="4-pfm.html">Continue with 'Project File Manager'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>

View file

@ -0,0 +1,205 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>4/pbm</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<!--Weave of '4/pfm' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">inbuild</a></li><li><a href="index.html#4">Chapter 4: Managing Genres of Work</a></li><li><b>Project File Manager</b></li></ul><p class="purpose">A project file is a plain text file of Inform 7 source text.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Genre definition</a></li><li><a href="#SP3">&#167;3. Claiming</a></li><li><a href="#SP4">&#167;4. Searching</a></li><li><a href="#SP5">&#167;5. Copying</a></li><li><a href="#SP6">&#167;6. Build graph</a></li><li><a href="#SP9">&#167;9. Source text</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Genre definition. </b></p>
<pre class="display">
<span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">project_file_genre</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">ProjectFileManager::start</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">project_file_genre</span><span class="plain"> = </span><span class="functiontext">Genres::new</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"projectfile"</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">project_file_genre</span><span class="plain">, </span><span class="constant">GENRE_WRITE_WORK_MTID</span><span class="plain">, </span><span class="functiontext">ProjectFileManager::write_work</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">project_file_genre</span><span class="plain">, </span><span class="constant">GENRE_CLAIM_AS_COPY_MTID</span><span class="plain">, </span><span class="functiontext">ProjectFileManager::claim_as_copy</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">project_file_genre</span><span class="plain">, </span><span class="constant">GENRE_SEARCH_NEST_FOR_MTID</span><span class="plain">, </span><span class="functiontext">ProjectFileManager::search_nest_for</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">project_file_genre</span><span class="plain">, </span><span class="constant">GENRE_COPY_TO_NEST_MTID</span><span class="plain">, </span><span class="functiontext">ProjectFileManager::copy_to_nest</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">project_file_genre</span><span class="plain">, </span><span class="constant">GENRE_GO_OPERATIONAL_MTID</span><span class="plain">, </span><span class="functiontext">ProjectFileManager::go_operational</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">project_file_genre</span><span class="plain">, </span><span class="constant">GENRE_READ_SOURCE_TEXT_FOR_MTID</span><span class="plain">, </span><span class="functiontext">ProjectFileManager::read_source_text_for</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">project_file_genre</span><span class="plain">, </span><span class="constant">GENRE_BUILD_COPY_MTID</span><span class="plain">, </span><span class="functiontext">ProjectFileManager::build</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">ProjectFileManager::write_work</span><span class="plain">(</span><span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">gen</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">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;title</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function ProjectFileManager::start is used in 1/im (<a href="1-im.html#SP3">&#167;3</a>).</p>
<p class="endnote">The function ProjectFileManager::write_work appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>Project copies are annotated with a structure called an <code class="display"><span class="extract">inform_project</span></code>,
which stores data about extensions used by the Inform compiler.
</p>
<pre class="display">
<span class="reserved">inform_project</span><span class="plain"> *</span><span class="functiontext">ProjectFileManager::from_copy</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">) &amp;&amp; (</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="identifier">project_file_genre</span><span class="plain">)) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">RETRIEVE_POINTER_inform_project</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="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="functiontext">ProjectFileManager::new_copy</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">filename</span><span class="plain"> *</span><span class="identifier">F</span><span class="plain">) {</span>
<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="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>
<p class="inwebparagraph"></p>
<p class="endnote">The function ProjectFileManager::from_copy is used in <a href="#SP8">&#167;8</a>, 1/ic (<a href="1-ic.html#SP11">&#167;11</a>), 3/is2 (<a href="3-is2.html#SP1">&#167;1</a>), 3/is3 (<a href="3-is3.html#SP1">&#167;1</a>).</p>
<p class="endnote">The function ProjectFileManager::new_copy is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. Claiming. </b>Here <code class="display"><span class="extract">arg</span></code> is a textual form of a filename or pathname, such as may have been
supplied at the command line; <code class="display"><span class="extract">ext</span></code> is a substring of it, and is its extension
(e.g., <code class="display"><span class="extract">jpg</span></code> if <code class="display"><span class="extract">arg</span></code> is <code class="display"><span class="extract">Geraniums.jpg</span></code>), or is empty if there isn't one;
<code class="display"><span class="extract">directory_status</span></code> is true if we know for some reason that this is a directory
not a file, false if we know the reverse, and otherwise not applicable.
</p>
<p class="inwebparagraph">A project file needs to be a plain text file whose name ends in <code class="display"><span class="extract">.txt</span></code>, <code class="display"><span class="extract">.ni</span></code>
or <code class="display"><span class="extract">.i7</span></code>.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">ProjectFileManager::claim_as_copy</span><span class="plain">(</span><span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">gen</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">arg</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="reserved">int</span><span class="plain"> </span><span class="identifier">directory_status</span><span class="plain">) {</span>
<span class="reserved">if</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="reserved">return</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">ext</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"txt"</span><span class="plain">)) ||</span>
<span class="plain">(</span><span class="identifier">Str::eq_insensitive</span><span class="plain">(</span><span class="identifier">ext</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"ni"</span><span class="plain">)) ||</span>
<span class="plain">(</span><span class="identifier">Str::eq_insensitive</span><span class="plain">(</span><span class="identifier">ext</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"i7"</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">Filenames::from_text</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">);</span>
<span class="plain">*</span><span class="identifier">C</span><span class="plain"> = </span><span class="functiontext">ProjectFileManager::claim_file_as_copy</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="functiontext">ProjectFileManager::claim_file_as_copy</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">C</span><span class="plain"> = </span><span class="functiontext">ProjectFileManager::new_copy</span><span class="plain">(</span><span class="identifier">Filenames::get_leafname</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">), </span><span class="identifier">F</span><span class="plain">);</span>
<span class="functiontext">ProjectFileManager::build_vertex</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">);</span>
<span class="functiontext">Works::add_to_database</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="constant">CLAIMED_WDBC</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>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function ProjectFileManager::claim_as_copy is used in <a href="#SP1">&#167;1</a>.</p>
<p class="endnote">The function ProjectFileManager::claim_file_as_copy is used in 1/ic (<a href="1-ic.html#SP11">&#167;11</a>).</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. Searching. </b>Here we look through a nest to find all projects matching the supplied
requirements; though in fact... projects are not nesting birds.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">ProjectFileManager::search_nest_for</span><span class="plain">(</span><span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">gen</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_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_results</span><span class="plain">) {</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function ProjectFileManager::search_nest_for is used in <a href="#SP1">&#167;1</a>.</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. Copying. </b>Now the task is to copy a project into place in a nest; or would be, if only
projects lived there.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">ProjectFileManager::copy_to_nest</span><span class="plain">(</span><span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">gen</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">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="identifier">Errors::with_text</span><span class="plain">(</span><span class="string">"projects (which is what '%S' is) cannot be copied to nests"</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;title</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function ProjectFileManager::copy_to_nest is used in <a href="#SP1">&#167;1</a>.</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. Build graph. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">ProjectFileManager::build</span><span class="plain">(</span><span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">gen</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">OUT</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">int</span><span class="plain"> </span><span class="identifier">rebuild</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">describe_only</span><span class="plain">) {</span>
<span class="reserved">inform_project</span><span class="plain"> *</span><span class="identifier">project</span><span class="plain"> = </span><span class="functiontext">ProjectBundleManager::from_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">project</span><span class="plain">-</span><span class="element">&gt;chosen_build_target</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">describe_only</span><span class="plain">) </span><span class="functiontext">Graphs::describe</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">TRUE</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">rebuild</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="reserved">else</span><span class="plain"> </span><span class="functiontext">Graphs::build</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 ProjectFileManager::build is used in <a href="#SP1">&#167;1</a>.</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. </b>The build graph for a project will need further thought...
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">ProjectFileManager::build_vertex</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">Graphs::copy_vertex</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 ProjectFileManager::build_vertex is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. </b>which it will get here:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">ProjectFileManager::go_operational</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="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain">) {</span>
<span class="functiontext">Projects::construct_graph</span><span class="plain">(</span><span class="functiontext">ProjectFileManager::from_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 ProjectFileManager::go_operational is used in <a href="#SP1">&#167;1</a>.</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. Source text. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">ProjectFileManager::read_source_text_for</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="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain">) {</span>
<span class="functiontext">Projects::read_source_text_for</span><span class="plain">(</span><span class="functiontext">ProjectBundleManager::from_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 ProjectFileManager::read_source_text_for is used in <a href="#SP1">&#167;1</a>.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="4-pbm.html">Back to 'Project Bundle Manager'</a></li><li><a href="4-tm.html">Continue with 'Template Manager'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>

View file

@ -0,0 +1,234 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>4/tm</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<!--Weave of '4/pm' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">inbuild</a></li><li><a href="index.html#4">Chapter 4: Managing Genres of Work</a></li><li><b>Pipeline Manager</b></li></ul><p class="purpose">An Inform 7 pipeline.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Genre definition</a></li><li><a href="#SP5">&#167;5. Claiming</a></li><li><a href="#SP6">&#167;6. Searching</a></li><li><a href="#SP7">&#167;7. Copying</a></li><li><a href="#SP8">&#167;8. Build graph</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Genre definition. </b></p>
<pre class="display">
<span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">pipeline_genre</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">PipelineManager::start</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">pipeline_genre</span><span class="plain"> = </span><span class="functiontext">Genres::new</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"pipeline"</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pipeline_genre</span><span class="plain">, </span><span class="constant">GENRE_WRITE_WORK_MTID</span><span class="plain">, </span><span class="functiontext">PipelineManager::write_work</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pipeline_genre</span><span class="plain">, </span><span class="constant">GENRE_CLAIM_AS_COPY_MTID</span><span class="plain">, </span><span class="functiontext">PipelineManager::claim_as_copy</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pipeline_genre</span><span class="plain">, </span><span class="constant">GENRE_SEARCH_NEST_FOR_MTID</span><span class="plain">, </span><span class="functiontext">PipelineManager::search_nest_for</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pipeline_genre</span><span class="plain">, </span><span class="constant">GENRE_COPY_TO_NEST_MTID</span><span class="plain">, </span><span class="functiontext">PipelineManager::copy_to_nest</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">PipelineManager::write_work</span><span class="plain">(</span><span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">gen</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">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;title</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function PipelineManager::start is used in 1/im (<a href="1-im.html#SP3">&#167;3</a>).</p>
<p class="endnote">The function PipelineManager::write_work appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>Pipelines live in their namesake subdirectory of a nest:
</p>
<pre class="display">
<span class="identifier">pathname</span><span class="plain"> *</span><span class="functiontext">PipelineManager::path_within_nest</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="identifier">internal_error</span><span class="plain">(</span><span class="string">"no nest"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">Pathnames::subfolder</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">I</span><span class="string">"Pipelines"</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function PipelineManager::path_within_nest is used in <a href="#SP6">&#167;6</a>, <a href="#SP7">&#167;7</a>.</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>Pipeline copies are annotated with a structure called an <code class="display"><span class="extract">inform_pipeline</span></code>,
which stores data about pipelines used by the Inform compiler.
</p>
<pre class="display">
<span class="reserved">inform_pipeline</span><span class="plain"> *</span><span class="functiontext">PipelineManager::from_copy</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">) &amp;&amp; (</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="identifier">pipeline_genre</span><span class="plain">)) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">RETRIEVE_POINTER_inform_pipeline</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="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="plain">}</span>
<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="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>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function PipelineManager::from_copy appears nowhere else.</p>
<p class="endnote">The function PipelineManager::new_copy is used in <a href="#SP5">&#167;5</a>.</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. Claiming. </b>Here <code class="display"><span class="extract">arg</span></code> is a textual form of a filename or pathname, such as may have been
supplied at the command line; <code class="display"><span class="extract">ext</span></code> is a substring of it, and is its extension
(e.g., <code class="display"><span class="extract">jpg</span></code> if <code class="display"><span class="extract">arg</span></code> is <code class="display"><span class="extract">Geraniums.jpg</span></code>), or is empty if there isn't one;
<code class="display"><span class="extract">directory_status</span></code> is true if we know for some reason that this is a directory
not a file, false if we know the reverse, and otherwise not applicable.
</p>
<p class="inwebparagraph">An pipeline, for us, simply needs to be a file with extension <code class="display"><span class="extract">interpipeline</span></code>.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">PipelineManager::claim_as_copy</span><span class="plain">(</span><span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">gen</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">arg</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="reserved">int</span><span class="plain"> </span><span class="identifier">directory_status</span><span class="plain">) {</span>
<span class="reserved">if</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="reserved">return</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">ext</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"interpipeline"</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">Filenames::from_text</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">);</span>
<span class="plain">*</span><span class="identifier">C</span><span class="plain"> = </span><span class="functiontext">PipelineManager::claim_file_as_copy</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="identifier">FALSE</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="functiontext">PipelineManager::claim_file_as_copy</span><span class="plain">(</span><span class="identifier">filename</span><span class="plain"> *</span><span class="identifier">F</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">error_text</span><span class="plain">,</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">allow_malformed</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="identifier">FALSE</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="identifier">semantic_version_number</span><span class="plain"> </span><span class="identifier">V</span><span class="plain"> = </span><span class="identifier">VersionNumbers::null</span><span class="plain">();</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">unext</span><span class="plain">);</span>
<span class="identifier">Filenames::write_unextended_leafname</span><span class="plain">(</span><span class="identifier">unext</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">PipelineManager::new_copy</span><span class="plain">(</span>
<span class="functiontext">Editions::new</span><span class="plain">(</span><span class="functiontext">Works::new_raw</span><span class="plain">(</span><span class="identifier">pipeline_genre</span><span class="plain">, </span><span class="identifier">unext</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">), </span><span class="identifier">V</span><span class="plain">), </span><span class="identifier">F</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">unext</span><span class="plain">);</span>
<span class="functiontext">Works::add_to_database</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="constant">CLAIMED_WDBC</span><span class="plain">);</span>
<span class="functiontext">PipelineManager::build_vertex</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>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function PipelineManager::claim_as_copy is used in <a href="#SP2">&#167;2</a>.</p>
<p class="endnote">The function PipelineManager::claim_file_as_copy is used in <a href="#SP6">&#167;6</a>.</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. Searching. </b>Here we look through a nest to find all pipelines matching the supplied
requirements.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">PipelineManager::search_nest_for</span><span class="plain">(</span><span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">gen</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_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_results</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">) &amp;&amp; (</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">pipeline_genre</span><span class="plain">)) </span><span class="reserved">return</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="functiontext">PipelineManager::path_within_nest</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">);</span>
<span class="identifier">scan_directory</span><span class="plain"> *</span><span class="identifier">D</span><span class="plain"> = </span><span class="identifier">Directories::open</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">D</span><span class="plain">) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">LEAFNAME</span><span class="plain">);</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">Directories::next</span><span class="plain">(</span><span class="identifier">D</span><span class="plain">, </span><span class="identifier">LEAFNAME</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">LEAFNAME</span><span class="plain">) != </span><span class="identifier">FOLDER_SEPARATOR</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">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">LEAFNAME</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">PipelineManager::claim_file_as_copy</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="identifier">req</span><span class="plain">-</span><span class="element">&gt;allow_malformed</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">C</span><span class="plain">) &amp;&amp; (</span><span class="functiontext">Requirements::meets</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">req</span><span class="plain">))) {</span>
<span class="functiontext">Nests::add_search_result</span><span class="plain">(</span><span class="identifier">search_results</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="identifier">req</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">LEAFNAME</span><span class="plain">);</span>
<span class="identifier">Directories::close</span><span class="plain">(</span><span class="identifier">D</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function PipelineManager::search_nest_for is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. Copying. </b>Now the task is to copy a pipeline into place in a nest. This is easy,
since a pipeline is a single file; to sync, we just overwrite.
</p>
<pre class="display">
<span class="identifier">filename</span><span class="plain"> *</span><span class="functiontext">PipelineManager::filename_in_nest</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">title</span><span class="plain">) {</span>
<span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">E</span><span class="plain"> = </span><span class="functiontext">PipelineManager::path_within_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">leaf</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">leaf</span><span class="plain">, </span><span class="string">"%S.interpipeline"</span><span class="plain">, </span><span class="identifier">title</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">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">E</span><span class="plain">, </span><span class="identifier">leaf</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">leaf</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">F</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">PipelineManager::copy_to_nest</span><span class="plain">(</span><span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">gen</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">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="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="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">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="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>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="string">"mkdir -p "</span><span class="plain">);</span>
<span class="identifier">Shell::quote_path</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="identifier">Filenames::get_path_to</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">));</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">STDOUT</span><span class="plain">, </span><span class="string">"%S\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">command</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Pathnames::create_in_file_system</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">Pathnames::create_in_file_system</span><span class="plain">(</span><span class="identifier">Filenames::get_path_to</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">));</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="string">"cp -f "</span><span class="plain">);</span>
<span class="identifier">Shell::quote_file</span><span class="plain">(</span><span class="identifier">command</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">Shell::quote_file</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="identifier">F</span><span class="plain">);</span>
<span class="functiontext">BuildSteps::shell</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="identifier">meth</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function PipelineManager::filename_in_nest appears nowhere else.</p>
<p class="endnote">The function PipelineManager::copy_to_nest is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. Build graph. </b>The build graph for a pipeline is just a single node: you don't need to
build a pipeline at all.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">PipelineManager::build_vertex</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">Graphs::copy_vertex</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 PipelineManager::build_vertex is used in <a href="#SP5">&#167;5</a>.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="4-tm.html">Back to 'Template Manager'</a></li><li><i>(This section ends Chapter 4: Managing Genres of Work.)</i></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>

View file

@ -0,0 +1,224 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>4/pfm</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<!--Weave of '4/tm' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">inbuild</a></li><li><a href="index.html#4">Chapter 4: Managing Genres of Work</a></li><li><b>Template Manager</b></li></ul><p class="purpose">A template is the outline for a website presenting an Inform work.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Genre definition</a></li><li><a href="#SP4">&#167;4. Claiming</a></li><li><a href="#SP5">&#167;5. Searching</a></li><li><a href="#SP6">&#167;6. Copying</a></li><li><a href="#SP7">&#167;7. Build graph</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Genre definition. </b></p>
<pre class="display">
<span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">template_genre</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">TemplateManager::start</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">template_genre</span><span class="plain"> = </span><span class="functiontext">Genres::new</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"template"</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">template_genre</span><span class="plain">, </span><span class="constant">GENRE_WRITE_WORK_MTID</span><span class="plain">, </span><span class="functiontext">TemplateManager::write_work</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">template_genre</span><span class="plain">, </span><span class="constant">GENRE_CLAIM_AS_COPY_MTID</span><span class="plain">, </span><span class="functiontext">TemplateManager::claim_as_copy</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">template_genre</span><span class="plain">, </span><span class="constant">GENRE_SEARCH_NEST_FOR_MTID</span><span class="plain">, </span><span class="functiontext">TemplateManager::search_nest_for</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">template_genre</span><span class="plain">, </span><span class="constant">GENRE_COPY_TO_NEST_MTID</span><span class="plain">, </span><span class="functiontext">TemplateManager::copy_to_nest</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">TemplateManager::write_work</span><span class="plain">(</span><span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">gen</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">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;title</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function TemplateManager::start is used in 1/im (<a href="1-im.html#SP3">&#167;3</a>).</p>
<p class="endnote">The function TemplateManager::write_work appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>Templates live in the <code class="display"><span class="extract">Templates</span></code> subdirectory of a nest:
</p>
<pre class="display">
<span class="identifier">pathname</span><span class="plain"> *</span><span class="functiontext">TemplateManager::path_within_nest</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="identifier">internal_error</span><span class="plain">(</span><span class="string">"no nest"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">Pathnames::subfolder</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">I</span><span class="string">"Templates"</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function TemplateManager::path_within_nest is used in <a href="#SP5">&#167;5</a>, <a href="#SP6">&#167;6</a>.</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>Template copies are annotated with a structure called an <code class="display"><span class="extract">inform_template</span></code>,
which stores data about extensions used by the Inform compiler.
</p>
<pre class="display">
<span class="reserved">inform_template</span><span class="plain"> *</span><span class="functiontext">TemplateManager::from_copy</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">) &amp;&amp; (</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="identifier">template_genre</span><span class="plain">)) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">RETRIEVE_POINTER_inform_template</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="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="functiontext">TemplateManager::new_copy</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">pathname</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain">) {</span>
<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="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>
<p class="inwebparagraph"></p>
<p class="endnote">The function TemplateManager::from_copy appears nowhere else.</p>
<p class="endnote">The function TemplateManager::new_copy is used in <a href="#SP4">&#167;4</a>.</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. Claiming. </b>Here <code class="display"><span class="extract">arg</span></code> is a textual form of a filename or pathname, such as may have been
supplied at the command line; <code class="display"><span class="extract">ext</span></code> is a substring of it, and is its extension
(e.g., <code class="display"><span class="extract">jpg</span></code> if <code class="display"><span class="extract">arg</span></code> is <code class="display"><span class="extract">Geraniums.jpg</span></code>), or is empty if there isn't one;
<code class="display"><span class="extract">directory_status</span></code> is true if we know for some reason that this is a directory
not a file, false if we know the reverse, and otherwise not applicable.
</p>
<p class="inwebparagraph">Templates are slightly hard to recognise in isolation, but they contain
either a manifest file, or else an <code class="display"><span class="extract">index.html</span></code>, so that will have to do.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">TemplateManager::claim_as_copy</span><span class="plain">(</span><span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">gen</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">arg</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="reserved">int</span><span class="plain"> </span><span class="identifier">directory_status</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">directory_status</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain"> = </span><span class="identifier">Pathnames::from_text</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">);</span>
<span class="plain">*</span><span class="identifier">C</span><span class="plain"> = </span><span class="functiontext">TemplateManager::claim_folder_as_copy</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="functiontext">TemplateManager::claim_folder_as_copy</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">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">inbuild_copy</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain"> = </span><span class="functiontext">TemplateManager::new_copy</span><span class="plain">(</span><span class="identifier">Pathnames::directory_name</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">), </span><span class="identifier">P</span><span class="plain">);</span>
<span class="functiontext">TemplateManager::build_vertex</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">);</span>
<span class="functiontext">Works::add_to_database</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="constant">CLAIMED_WDBC</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">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 TemplateManager::claim_as_copy is used in <a href="#SP1">&#167;1</a>.</p>
<p class="endnote">The function TemplateManager::claim_folder_as_copy is used in <a href="#SP5">&#167;5</a>.</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. Searching. </b>Here we look through a nest to find all kits matching the supplied
requirements.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">TemplateManager::search_nest_for</span><span class="plain">(</span><span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">gen</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_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_results</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">) &amp;&amp; (</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">template_genre</span><span class="plain">)) </span><span class="reserved">return</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="functiontext">TemplateManager::path_within_nest</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">);</span>
<span class="identifier">scan_directory</span><span class="plain"> *</span><span class="identifier">D</span><span class="plain"> = </span><span class="identifier">Directories::open</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">D</span><span class="plain">) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">LEAFNAME</span><span class="plain">);</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">Directories::next</span><span class="plain">(</span><span class="identifier">D</span><span class="plain">, </span><span class="identifier">LEAFNAME</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">LEAFNAME</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">LEAFNAME</span><span class="plain">);</span>
<span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">Q</span><span class="plain"> = </span><span class="identifier">Pathnames::subfolder</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">LEAFNAME</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">TemplateManager::claim_folder_as_copy</span><span class="plain">(</span><span class="identifier">Q</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">C</span><span class="plain">) &amp;&amp; (</span><span class="functiontext">Requirements::meets</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">req</span><span class="plain">))) {</span>
<span class="functiontext">Nests::add_search_result</span><span class="plain">(</span><span class="identifier">search_results</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="identifier">req</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">LEAFNAME</span><span class="plain">);</span>
<span class="identifier">Directories::close</span><span class="plain">(</span><span class="identifier">D</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function TemplateManager::search_nest_for is used in <a href="#SP1">&#167;1</a>.</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. Copying. </b>Now the task is to copy a template into place in a nest. Since a template is
a folder, we need to <code class="display"><span class="extract">rsync</span></code> it.
</p>
<pre class="display">
<span class="identifier">pathname</span><span class="plain"> *</span><span class="functiontext">TemplateManager::pathname_in_nest</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_work</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">Pathnames::subfolder</span><span class="plain">(</span><span class="functiontext">TemplateManager::path_within_nest</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">), </span><span class="identifier">W</span><span class="plain">-</span><span class="element">&gt;title</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">TemplateManager::copy_to_nest</span><span class="plain">(</span><span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">gen</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">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="identifier">pathname</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain"> = </span><span class="functiontext">TemplateManager::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="element">&gt;work</span><span class="plain">);</span>
<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="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>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="string">"mkdir -p "</span><span class="plain">);</span>
<span class="identifier">Shell::quote_path</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="identifier">P</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">STDOUT</span><span class="plain">, </span><span class="string">"%S\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">command</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Pathnames::create_in_file_system</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">Pathnames::create_in_file_system</span><span class="plain">(</span><span class="functiontext">TemplateManager::path_within_nest</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">));</span>
<span class="identifier">Pathnames::create_in_file_system</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">);</span>
<span class="plain">}</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>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="string">"rsync -a --delete "</span><span class="plain">);</span>
<span class="identifier">Shell::quote_path</span><span class="plain">(</span><span class="identifier">command</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">Shell::quote_path</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="identifier">P</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">STDOUT</span><span class="plain">, </span><span class="string">"%S\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">command</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Pathnames::rsync</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">P</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function TemplateManager::pathname_in_nest appears nowhere else.</p>
<p class="endnote">The function TemplateManager::copy_to_nest is used in <a href="#SP1">&#167;1</a>.</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. Build graph. </b>The build graph for a template is just a single node: you don't need to
build a template at all.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">TemplateManager::build_vertex</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">Graphs::copy_vertex</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 TemplateManager::build_vertex is used in <a href="#SP4">&#167;4</a>.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="4-pfm.html">Back to 'Project File Manager'</a></li><li><a href="4-pm.html">Continue with 'Pipeline Manager'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,990 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>5/es</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<!--Weave of '5/ed' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">inbuild</a></li><li><a href="index.html#5">Chapter 5: Services for the Inform Compiler</a></li><li><b>Extension Dictionary</b></li></ul><p class="purpose">To maintain a database of names and constructions in all extensions so far used by this installation of Inform, and spot potential namespace clashes.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Definitions</a></li><li><a href="#SP8">&#167;8. Erasing entries</a></li><li><a href="#SP10">&#167;10. Making new entries</a></li><li><a href="#SP11">&#167;11. Loading from disc</a></li><li><a href="#SP13">&#167;13. Time stamping</a></li><li><a href="#SP14">&#167;14. Saving to disc</a></li><li><a href="#SP15">&#167;15. Sorting the extension dictionary</a></li><li><a href="#SP17">&#167;17. Extension clashes</a></li><li><a href="#SP20">&#167;20. Writing the HTML extension index</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Definitions. </b></p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>Not during the census, but rather when extensions are successfully
used, a dictionary is kept of the terms defined in them: this is used
to generate the dynamic documentation on installed extensions, and
is stored between runs in a cache file inside the I7 application.
This means dictionary entries are first read in from the cache; then
the entries for any extension used by Inform in its current run are
revised, which may mean deleting some entries or adding new ones;
and at last Inform writes the final state of the dictionary back to the
cache. In this way, changes in what an extension defines are reflected
in the dictionary after each successful use of that extension.
</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">extension_dictionary_entry</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">ede_work</span><span class="plain">; </span> <span class="comment">author name and title, with hash code</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">entry_text</span><span class="plain">; </span> <span class="comment">text of the dictionary entry</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">sorting</span><span class="plain">; </span> <span class="comment">text reprocessed for sorting purposes</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">type</span><span class="plain">; </span> <span class="comment">grammatical category, such as "kind"</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">erased</span><span class="plain">; </span> <span class="comment">marked to be erased</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">extension_dictionary_entry</span><span class="plain"> *</span><span class="identifier">next_in_sorted_dictionary</span><span class="plain">; </span> <span class="comment">link in linked list</span>
<span class="identifier">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">extension_dictionary_entry</span><span class="plain">;</span>
<span class="reserved">extension_dictionary_entry</span><span class="plain"> *</span><span class="identifier">first_in_sorted_dictionary</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The structure extension_dictionary_entry is accessed in 3/bg and here.</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>Clashes occur if, say, two extensions define "chopper" as a kind
of vehicle (for instance, meaning a helicopter in one and a motorcycle
in the other). This results in two dictionary entries under "chopper"
and is recorded as a clash between them. Often, more will turn up:
perhaps "chopper" might elsewhere mean a butchery tool. In the
event of 3 or more clashing entries, A, B, C, ..., a linked list of
ordered pairs (A,B), (A,C), ... is maintained where in each pair the
first term (the left one) is from an extension lexicographically earlier
than the second (the right one): see below.
</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">known_extension_clash</span><span class="plain"> {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">first_known</span><span class="plain">; </span> <span class="comment">heads a linked list of clashes with a given <code class="display"><span class="extract">ede1</span></code></span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">known_extension_clash</span><span class="plain"> *</span><span class="identifier">next</span><span class="plain">; </span> <span class="comment">next in linked list of clashes</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">extension_dictionary_entry</span><span class="plain"> *</span><span class="identifier">leftx</span><span class="plain">; </span> <span class="comment">clash is between this entry...</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">extension_dictionary_entry</span><span class="plain"> *</span><span class="identifier">rightx</span><span class="plain">; </span> <span class="comment">...and this one</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">number_clashes</span><span class="plain">; </span> <span class="comment">number of entries clashing between <code class="display"><span class="extract">ede1</span></code> and <code class="display"><span class="extract">ede2</span></code></span>
<span class="identifier">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">known_extension_clash</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The structure known_extension_clash is accessed in 5/ec and here.</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>The extension dictionary has no natural order as such. In order to generate
the dictionary page of the documentation, we will sort it alphabetically,
but it is not alphabetically stored either in memory or in its serialised
form on disc. (It might seem advantageous, since we're going to sort it
anyway, to use the sorted ordering when saving it back to disc, as at least
the structure will then be nearly sorted most of the time: but in fact the
reverse is true, because we will sort using the C library's implementation
of quicksort, an algorithm whose worst-case performance is on nearly
sorted lists.)
</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b>The following sample is an extract of the dictionary in its serialised
form on disc. The four columns are author, title, headword and category.
The special entries with category "indexing" have two roles: they are
markers that the extension in question is indexed in the dictionary, and
they record the last date on which the extension was used.
</p>
<p class="inwebparagraph">Note that the stroke character is illegal in unquoted Inform source text,
and therefore also in excerpts with meanings, in extension titles and in
author names. It can therefore safely be used as a record divider.
</p>
<p class="inwebparagraph">In December 2007, the dictionary file of a user who had employed 155 different
extensions (by 33 different authors) contained 2223 entries, the longest of
which formed a line 95 characters long: the most prolific extension made 380
definitions. The total file size was about 130K. Some typical entries:
</p>
<pre class="display">
<span class="plain">...</span>
<span class="plain">|Emily Short|Plurality|20110130181823:Sun 30 January 2011 18:18|indexing|</span>
<span class="plain">|Emily Short|Plurality|prior named noun|value|</span>
<span class="plain">|Emily Short|Plurality|ambiguously plural|property|</span>
<span class="plain">|Emily Short|Plurality|ordinarily enumerated|property|</span>
<span class="plain">|Emily Short|Locksmith|20110130181823:Sun 30 January 2011 18:18|indexing|</span>
<span class="plain">|Emily Short|Locksmith|passkey|kind|</span>
<span class="plain">|Emily Short|Locksmith|keychain|kind|</span>
<span class="plain">...</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. </b>The file is encoded as ISO Latin-1 and can in principle have any of <code class="display"><span class="extract">0A</span></code>, <code class="display"><span class="extract">0D</span></code>,
<code class="display"><span class="extract">0A 0D</span></code> or <code class="display"><span class="extract">0D 0A</span></code> as line divider. Each line must be no longer than the
following number of characters minus 1:
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">MAX_ED_LINE_LENGTH</span><span class="plain"> 512</span>
</pre>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. </b>The following logs the dictionary as it stands in memory, in a similar
format but also recorded the erasure flag.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Extensions::Dictionary::log_entry</span><span class="plain">(</span><span class="reserved">extension_dictionary_entry</span><span class="plain"> *</span><span class="identifier">ede</span><span class="plain">) {</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"ede: %4d %d |%S|%S|%S|%S|\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">ede</span><span class="plain">-&gt;</span><span class="identifier">allocation_id</span><span class="plain">,</span>
<span class="identifier">ede</span><span class="plain">-</span><span class="element">&gt;erased</span><span class="plain">, </span><span class="identifier">ede</span><span class="plain">-</span><span class="element">&gt;ede_work</span><span class="plain">-</span><span class="element">&gt;author_name</span><span class="plain">, </span><span class="identifier">ede</span><span class="plain">-</span><span class="element">&gt;ede_work</span><span class="plain">-</span><span class="element">&gt;title</span><span class="plain">,</span>
<span class="identifier">ede</span><span class="plain">-</span><span class="element">&gt;entry_text</span><span class="plain">, </span><span class="identifier">ede</span><span class="plain">-</span><span class="element">&gt;type</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Extensions::Dictionary::log_extension_dictionary</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="reserved">extension_dictionary_entry</span><span class="plain"> *</span><span class="identifier">ede</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">n</span><span class="plain">=0;</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">EXTENSIONS_CENSUS</span><span class="plain">, </span><span class="string">"Extension dictionary:\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">ede</span><span class="plain">, </span><span class="reserved">extension_dictionary_entry</span><span class="plain">) {</span>
<span class="identifier">n</span><span class="plain">++; </span><span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">EXTENSIONS_CENSUS</span><span class="plain">, </span><span class="string">"$d"</span><span class="plain">, </span><span class="identifier">ede</span><span class="plain">);</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">LOGIF</span><span class="plain">(</span><span class="identifier">EXTENSIONS_CENSUS</span><span class="plain">, </span><span class="string">"no entries\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Extensions::Dictionary::log_entry appears nowhere else.</p>
<p class="endnote">The function Extensions::Dictionary::log_extension_dictionary appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. Erasing entries. </b>The erasure flag is used to mark entries in the dictionary which are to
be erased, in that they will not survive when we save it back from memory
to disc. (Entries are never physically deleted from the memory structures.)
</p>
<p class="inwebparagraph">There are two reasons to erase entries. First, the following routine sets the
erased flag for dictionary entries corresponding to an extension which,
according to the census returns, is no longer installed. (This can happen
if the user has uninstalled an extension since the last time Inform successfully
ran.)
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Extensions::Dictionary::erase_entries_of_uninstalled_extensions</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="reserved">extension_dictionary_entry</span><span class="plain"> *</span><span class="identifier">ede</span><span class="plain">;</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">EXTENSIONS_CENSUS</span><span class="plain">, </span><span class="string">"Erasure of dictionary entries for uninstalled extensions\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">ede</span><span class="plain">, </span><span class="reserved">extension_dictionary_entry</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">ede</span><span class="plain">-</span><span class="element">&gt;erased</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Works::no_times_used_in_context</span><span class="plain">(</span><span class="identifier">ede</span><span class="plain">-</span><span class="element">&gt;ede_work</span><span class="plain">, </span><span class="constant">INSTALLED_WDBC</span><span class="plain">) == 0)) {</span>
<span class="identifier">ede</span><span class="plain">-</span><span class="element">&gt;erased</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">EXTENSIONS_CENSUS</span><span class="plain">, </span><span class="string">"Erased $d"</span><span class="plain">, </span><span class="identifier">ede</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Extensions::Dictionary::erase_entries_of_uninstalled_extensions is used in <a href="#SP20">&#167;20</a>.</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. </b>The second reason arises when we are making the dictionary entries for an
extension which was used on the current run. (For instance, if it created a
kind of vehicle called "dragster", then we will make a dictionary entry
for that.) Before making its dictionary entries, we first erase all entries
for the same extension which are left in the dictionary from some previous
run of Inform, as those are now out of date.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Extensions::Dictionary::erase_entries</span><span class="plain">(</span><span class="reserved">inform_extension</span><span class="plain"> *</span><span class="identifier">E</span><span class="plain">) {</span>
<span class="reserved">extension_dictionary_entry</span><span class="plain"> *</span><span class="identifier">ede</span><span class="plain">;</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">EXTENSIONS_CENSUS</span><span class="plain">, </span><span class="string">"Erasure of dictionary entries for %X\</span><span class="plain">n</span><span class="string">"</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="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">ede</span><span class="plain">, </span><span class="reserved">extension_dictionary_entry</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">ede</span><span class="plain">-</span><span class="element">&gt;erased</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Works::match</span><span class="plain">(</span><span class="identifier">ede</span><span class="plain">-</span><span class="element">&gt;ede_work</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="identifier">ede</span><span class="plain">-</span><span class="element">&gt;erased</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">EXTENSIONS_CENSUS</span><span class="plain">, </span><span class="string">"Erased $d"</span><span class="plain">, </span><span class="identifier">ede</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Extensions::Dictionary::erase_entries appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. Making new entries. </b>We provide two ways to add a new entry: from a C string or from a word range.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Extensions::Dictionary::new_entry</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">category</span><span class="plain">, </span><span class="reserved">inform_extension</span><span class="plain"> *</span><span class="identifier">E</span><span class="plain">, </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) { </span> <span class="comment">a safety precaution: never index the empty text</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">headword</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">headword</span><span class="plain">, </span><span class="string">"%+W"</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
<span class="functiontext">Extensions::Dictionary::new_dictionary_entry_raw</span><span class="plain">(</span><span class="identifier">category</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;raw_author_name</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;raw_title</span><span class="plain">, </span><span class="identifier">headword</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">headword</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">Extensions::Dictionary::new_entry_from_stream</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">category</span><span class="plain">, </span><span class="reserved">inform_extension</span><span class="plain"> *</span><span class="identifier">E</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">headword</span><span class="plain">) {</span>
<span class="functiontext">Extensions::Dictionary::new_dictionary_entry_raw</span><span class="plain">(</span><span class="identifier">category</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;author_name</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="identifier">headword</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Extensions::Dictionary::new_dictionary_entry_raw</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">category</span><span class="plain">,</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">author</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">title</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">headword</span><span class="plain">) {</span>
<span class="reserved">extension_dictionary_entry</span><span class="plain"> *</span><span class="identifier">ede</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">extension_dictionary_entry</span><span class="plain">);</span>
<span class="identifier">ede</span><span class="plain">-</span><span class="element">&gt;ede_work</span><span class="plain"> = </span><span class="functiontext">Works::new</span><span class="plain">(</span><span class="identifier">extension_genre</span><span class="plain">, </span><span class="identifier">title</span><span class="plain">, </span><span class="identifier">author</span><span class="plain">);</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">EXTENSIONS_CENSUS</span><span class="plain">, </span><span class="string">"NDER %X\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">ede</span><span class="plain">-</span><span class="element">&gt;ede_work</span><span class="plain">);</span>
<span class="functiontext">Works::add_to_database</span><span class="plain">(</span><span class="identifier">ede</span><span class="plain">-</span><span class="element">&gt;ede_work</span><span class="plain">, </span><span class="constant">DICTIONARY_REFERRED_WDBC</span><span class="plain">);</span>
<span class="identifier">ede</span><span class="plain">-</span><span class="element">&gt;entry_text</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">headword</span><span class="plain">);</span>
<span class="identifier">ede</span><span class="plain">-</span><span class="element">&gt;type</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">category</span><span class="plain">);</span>
<span class="identifier">ede</span><span class="plain">-</span><span class="element">&gt;sorting</span><span class="plain"> = </span><span class="identifier">Str::new</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::eq_wide_string</span><span class="plain">(</span><span class="identifier">category</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"indexing"</span><span class="plain">)) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">sdate</span><span class="plain">);</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">udate</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">mode</span><span class="plain"> = 0, </span><span class="identifier">wc</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">ede</span><span class="plain">-</span><span class="element">&gt;entry_text</span><span class="plain">) {</span>
<span class="reserved">if</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="character">'/'</span><span class="plain">) { </span><span class="identifier">mode</span><span class="plain"> = 1; </span><span class="reserved">continue</span><span class="plain">; }</span>
<span class="reserved">if</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="character">':'</span><span class="plain">) { </span><span class="identifier">mode</span><span class="plain"> = 2; </span><span class="reserved">continue</span><span class="plain">; }</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">digital</span><span class="plain"> = </span><span class="identifier">Characters::isdigit</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">switch</span><span class="plain"> (</span><span class="identifier">mode</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> 0:</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">digital</span><span class="plain">) </span><span class="identifier">PUT_TO</span><span class="plain">(</span><span class="identifier">sdate</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">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> 1:</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">digital</span><span class="plain">) </span><span class="identifier">wc</span><span class="plain"> = 10*</span><span class="identifier">wc</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="reserved">int</span><span class="plain">) </span><span class="character">'0'</span><span class="plain">);</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> 2:</span>
<span class="identifier">PUT_TO</span><span class="plain">(</span><span class="identifier">udate</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">break</span><span class="plain">;</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">sdate</span><span class="plain">) &gt; 0) </span><span class="functiontext">Works::set_sort_date</span><span class="plain">(</span><span class="identifier">ede</span><span class="plain">-</span><span class="element">&gt;ede_work</span><span class="plain">, </span><span class="identifier">sdate</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">wc</span><span class="plain"> &gt; 0) </span><span class="functiontext">Works::set_word_count</span><span class="plain">(</span><span class="identifier">ede</span><span class="plain">-</span><span class="element">&gt;ede_work</span><span class="plain">, </span><span class="identifier">wc</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">udate</span><span class="plain">) &gt; 0) </span><span class="functiontext">Works::set_usage_date</span><span class="plain">(</span><span class="identifier">ede</span><span class="plain">-</span><span class="element">&gt;ede_work</span><span class="plain">, </span><span class="identifier">udate</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">sdate</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">udate</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">ede</span><span class="plain">-</span><span class="element">&gt;erased</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">ede</span><span class="plain">-</span><span class="element">&gt;next_in_sorted_dictionary</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">EXTENSIONS_CENSUS</span><span class="plain">, </span><span class="string">"Created $d"</span><span class="plain">, </span><span class="identifier">ede</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Extensions::Dictionary::new_entry appears nowhere else.</p>
<p class="endnote">The function Extensions::Dictionary::new_entry_from_stream is used in <a href="#SP13">&#167;13</a>.</p>
<p class="endnote">The function Extensions::Dictionary::new_dictionary_entry_raw is used in <a href="#SP12">&#167;12</a>.</p>
<p class="inwebparagraph"><a id="SP11"></a><b>&#167;11. Loading from disc. </b>Not a surprising routine: open, convert one line at a time to dictionary
entries, close.
</p>
<pre class="display">
<span class="identifier">filename</span><span class="plain"> *</span><span class="functiontext">Extensions::Dictionary::filename</span><span class="plain">(</span><span class="reserved">void</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="functiontext">Inbuild::transient</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">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">P</span><span class="plain"> = </span><span class="identifier">Pathnames::subfolder</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Documentation"</span><span class="plain">);</span>
<span class="identifier">P</span><span class="plain"> = </span><span class="identifier">Pathnames::subfolder</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Census"</span><span class="plain">);</span>
<span class="reserved">return</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">"Dictionary.txt"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Extensions::Dictionary::load</span><span class="plain">(</span><span class="reserved">void</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="functiontext">Extensions::Dictionary::filename</span><span class="plain">();</span>
<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">return</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Ensure the serialised extensions dictionary file exists</span> <span class="cwebmacronumber">11.1</span>&gt;<span class="plain">;</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">EXTENSIONS_CENSUS</span><span class="plain">, </span><span class="string">"Reading dictionary file %f\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">F</span><span class="plain">);</span>
<span class="identifier">TextFiles::read</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">,</span>
<span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="functiontext">Extensions::Dictionary::load_helper</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">EXTENSIONS_CENSUS</span><span class="plain">, </span><span class="string">"Finished reading dictionary file\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Extensions::Dictionary::filename is used in <a href="#SP14">&#167;14</a>.</p>
<p class="endnote">The function Extensions::Dictionary::load is used in 5/ec (<a href="5-ec.html#SP11">&#167;11</a>).</p>
<p class="inwebparagraph"><a id="SP11_1"></a><b>&#167;11.1. </b>The extension dictionary file is stored only transiently and may never have
been made, or may have been wiped by a zealous mobile OS. If it doesn't exist,
we try to make an empty one. Should these attempts fail, we simply return:
there might be permissions reasons, and it doesn't matter too much if the
dictionary isn't read. A fatal error results only if, having written the empty
file, we are then unable to open it again: that must mean a file I/O error of
some kind, which is bad enough news to bother the user with.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Ensure the serialised extensions dictionary file exists</span> <span class="cwebmacronumber">11.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">FILE</span><span class="plain"> *</span><span class="identifier">DICTF</span><span class="plain"> = </span><span class="identifier">Filenames::fopen</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">, </span><span class="string">"r"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">DICTF</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">EXTENSIONS_CENSUS</span><span class="plain">, </span><span class="string">"Creating new empty dictionary file\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
<span class="reserved">FILE</span><span class="plain"> *</span><span class="identifier">EMPTY_DICTF</span><span class="plain"> = </span><span class="identifier">Filenames::fopen</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">, </span><span class="string">"w"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">EMPTY_DICTF</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">fclose</span><span class="plain">(</span><span class="identifier">EMPTY_DICTF</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP11">&#167;11</a>.</p>
<p class="inwebparagraph"><a id="SP12"></a><b>&#167;12. </b>We parse lines in a fairly forgiving way. Material before the initial stroke
is ignored (this helps us cope with any spare newline characters if there are
blank lines, or if the line division is multi-byte); material after the final
stroke is also ignored, and any line not containing five vertical strokes
(i.e., four stroke-divided columns) is ignored altogether. This means that
any truncated, overlong lines are ineffectual but safe.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Extensions::Dictionary::load_helper</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">line_entry</span><span class="plain">,</span>
<span class="identifier">text_file_position</span><span class="plain"> *</span><span class="identifier">tfp</span><span class="plain">, </span><span class="reserved">void</span><span class="plain"> *</span><span class="identifier">state</span><span class="plain">) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">author</span><span class="plain">);</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">title</span><span class="plain">);</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">headword</span><span class="plain">);</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">category</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">strokes</span><span class="plain"> = 0, </span><span class="identifier">pos</span><span class="plain"> = 0; </span><span class="identifier">strokes</span><span class="plain"> &lt;= 4; </span><span class="identifier">pos</span><span class="plain">++) {</span>
<span class="reserved">int</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">line_entry</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"> == 0) </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="reserved">if</span><span class="plain"> (++</span><span class="identifier">strokes</span><span class="plain"> == 5)</span>
<span class="functiontext">Extensions::Dictionary::new_dictionary_entry_raw</span><span class="plain">(</span>
<span class="identifier">category</span><span class="plain">, </span><span class="identifier">author</span><span class="plain">, </span><span class="identifier">title</span><span class="plain">, </span><span class="identifier">headword</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">strokes</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> 1: </span><span class="identifier">PUT_TO</span><span class="plain">(</span><span class="identifier">author</span><span class="plain">, </span><span class="identifier">c</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> 2: </span><span class="identifier">PUT_TO</span><span class="plain">(</span><span class="identifier">title</span><span class="plain">, </span><span class="identifier">c</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> 3: </span><span class="identifier">PUT_TO</span><span class="plain">(</span><span class="identifier">headword</span><span class="plain">, </span><span class="identifier">c</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> 4: </span><span class="identifier">PUT_TO</span><span class="plain">(</span><span class="identifier">category</span><span class="plain">, </span><span class="identifier">c</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">author</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">title</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">headword</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">category</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Extensions::Dictionary::load_helper is used in <a href="#SP11">&#167;11</a>.</p>
<p class="inwebparagraph"><a id="SP13"></a><b>&#167;13. Time stamping. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Extensions::Dictionary::time_stamp</span><span class="plain">(</span><span class="reserved">inform_extension</span><span class="plain"> *</span><span class="identifier">E</span><span class="plain">) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">dbuff</span><span class="plain">);</span>
<span class="reserved">char</span><span class="plain"> *</span><span class="identifier">ascday</span><span class="plain">[] = { </span><span class="string">"Sun"</span><span class="plain">, </span><span class="string">"Mon"</span><span class="plain">, </span><span class="string">"Tue"</span><span class="plain">, </span><span class="string">"Wed"</span><span class="plain">, </span><span class="string">"Thu"</span><span class="plain">, </span><span class="string">"Fri"</span><span class="plain">, </span><span class="string">"Sat"</span><span class="plain"> };</span>
<span class="reserved">char</span><span class="plain"> *</span><span class="identifier">ascmon</span><span class="plain">[] = { </span><span class="string">"January"</span><span class="plain">, </span><span class="string">"February"</span><span class="plain">, </span><span class="string">"March"</span><span class="plain">, </span><span class="string">"April"</span><span class="plain">, </span><span class="string">"May"</span><span class="plain">, </span><span class="string">"June"</span><span class="plain">,</span>
<span class="string">"July"</span><span class="plain">, </span><span class="string">"August"</span><span class="plain">, </span><span class="string">"September"</span><span class="plain">, </span><span class="string">"October"</span><span class="plain">, </span><span class="string">"November"</span><span class="plain">, </span><span class="string">"December"</span><span class="plain"> };</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">dbuff</span><span class="plain">, </span><span class="string">"%04d%02d%02d%02d%02d%02d/%d:%s %d %s %d %02d:%02d"</span><span class="plain">,</span>
<span class="identifier">the_present</span><span class="plain">-&gt;</span><span class="identifier">tm_year</span><span class="plain">+1900, </span><span class="identifier">the_present</span><span class="plain">-&gt;</span><span class="identifier">tm_mon</span><span class="plain"> + 1, </span><span class="identifier">the_present</span><span class="plain">-&gt;</span><span class="identifier">tm_mday</span><span class="plain">,</span>
<span class="identifier">the_present</span><span class="plain">-&gt;</span><span class="identifier">tm_hour</span><span class="plain">, </span><span class="identifier">the_present</span><span class="plain">-&gt;</span><span class="identifier">tm_min</span><span class="plain">, </span><span class="identifier">the_present</span><span class="plain">-&gt;</span><span class="identifier">tm_sec</span><span class="plain">,</span>
<span class="plain">(</span><span class="identifier">E</span><span class="plain">-</span><span class="element">&gt;read_into_file</span><span class="plain">)?(</span><span class="identifier">TextFromFiles::total_word_count</span><span class="plain">(</span><span class="identifier">E</span><span class="plain">-</span><span class="element">&gt;read_into_file</span><span class="plain">)):0,</span>
<span class="identifier">ascday</span><span class="plain">[</span><span class="identifier">the_present</span><span class="plain">-&gt;</span><span class="identifier">tm_wday</span><span class="plain">], </span><span class="identifier">the_present</span><span class="plain">-&gt;</span><span class="identifier">tm_mday</span><span class="plain">,</span>
<span class="identifier">ascmon</span><span class="plain">[</span><span class="identifier">the_present</span><span class="plain">-&gt;</span><span class="identifier">tm_mon</span><span class="plain">], </span><span class="identifier">the_present</span><span class="plain">-&gt;</span><span class="identifier">tm_year</span><span class="plain">+1900,</span>
<span class="identifier">the_present</span><span class="plain">-&gt;</span><span class="identifier">tm_hour</span><span class="plain">, </span><span class="identifier">the_present</span><span class="plain">-&gt;</span><span class="identifier">tm_min</span><span class="plain">);</span>
<span class="functiontext">Extensions::Dictionary::new_entry_from_stream</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"indexing"</span><span class="plain">, </span><span class="identifier">E</span><span class="plain">, </span><span class="identifier">dbuff</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">dbuff</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Extensions::Dictionary::time_stamp is used in 5/ec (<a href="5-ec.html#SP6_2">&#167;6.2</a>).</p>
<p class="inwebparagraph"><a id="SP14"></a><b>&#167;14. Saving to disc. </b>And inversely...
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Extensions::Dictionary::write_back</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="reserved">extension_dictionary_entry</span><span class="plain"> *</span><span class="identifier">ede</span><span class="plain">;</span>
<span class="identifier">text_stream</span><span class="plain"> </span><span class="identifier">DICTF_struct</span><span class="plain">;</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">DICTF</span><span class="plain"> = &amp;</span><span class="identifier">DICTF_struct</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="functiontext">Extensions::Dictionary::filename</span><span class="plain">();</span>
<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">return</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">STREAM_OPEN_TO_FILE</span><span class="plain">(</span><span class="identifier">DICTF</span><span class="plain">, </span><span class="identifier">F</span><span class="plain">, </span><span class="identifier">UTF8_ENC</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">EXTENSIONS_CENSUS</span><span class="plain">, </span><span class="string">"Writing dictionary file\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">ede</span><span class="plain">, </span><span class="reserved">extension_dictionary_entry</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ede</span><span class="plain">-</span><span class="element">&gt;erased</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">EXTENSIONS_CENSUS</span><span class="plain">, </span><span class="string">"Writing $d"</span><span class="plain">, </span><span class="identifier">ede</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Write line to the dictionary file from single entry</span> <span class="cwebmacronumber">14.1</span>&gt;<span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">EXTENSIONS_CENSUS</span><span class="plain">, </span><span class="string">"Suppressing $d\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">ede</span><span class="plain">);</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">EXTENSIONS_CENSUS</span><span class="plain">, </span><span class="string">"Finished writing dictionary file\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
<span class="identifier">STREAM_CLOSE</span><span class="plain">(</span><span class="identifier">DICTF</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Extensions::Dictionary::write_back is used in 5/ec (<a href="5-ec.html#SP11">&#167;11</a>).</p>
<p class="inwebparagraph"><a id="SP14_1"></a><b>&#167;14.1. </b>We needn't worry overmuch about exceeding the maximum length, since any such
lines are handled safely by the loading code above. In any case, they could
only occur if it were true that
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">4 + MAX_ED_CATEGORY_LENGTH + MAX_ED_HEADWORD_LENGTH +</span>
<span class="plain"> MAX_EXTENSION_TITLE_LENGTH + MAX_EXTENSION_AUTHOR_LENGTH &gt;= MAX_ED_LINE_LENGTH</span>
</pre>
<p class="inwebparagraph">and this is not nearly the case. (<code class="display"><span class="extract">MAX_ED_LINE_LENGTH</span></code> is larger than
strictly necessary since it costs us only temporary stack space and allows
for any future increase of the above maxima without fuss.)
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Write line to the dictionary file from single entry</span> <span class="cwebmacronumber">14.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">DICTF</span><span class="plain">, </span><span class="string">"|%S|%S|%S|%S|\</span><span class="plain">n</span><span class="string">"</span><span class="plain">,</span>
<span class="identifier">ede</span><span class="plain">-</span><span class="element">&gt;ede_work</span><span class="plain">-</span><span class="element">&gt;author_name</span><span class="plain">, </span><span class="identifier">ede</span><span class="plain">-</span><span class="element">&gt;ede_work</span><span class="plain">-</span><span class="element">&gt;title</span><span class="plain">,</span>
<span class="identifier">ede</span><span class="plain">-</span><span class="element">&gt;entry_text</span><span class="plain">, </span><span class="identifier">ede</span><span class="plain">-</span><span class="element">&gt;type</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP14">&#167;14</a>.</p>
<p class="inwebparagraph"><a id="SP15"></a><b>&#167;15. Sorting the extension dictionary. </b>We pass this job on to the standard C library <code class="display"><span class="extract">qsort</span></code>, in hopes that it is
reasonably efficiently implemented. We need to bear in mind that the
extensions database can be expected to have some thousands of entries,
and that the O(n^2) insertion sorts used so casually elsewhere in Inform &mdash;
where lists are certainly much smaller &mdash; could cause misery here.
</p>
<p class="inwebparagraph">This routine returns the number of (unerased) entries in the dictionary,
and on its exit the (unerased) entries each occur once in alphabetical
order in the linked list beginning at <code class="display"><span class="extract">first_in_sorted_dictionary</span></code>.
If two entries have identical headwords, the earliest created is the
one which appears earlier in the sorted dictionary.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Extensions::Dictionary::sort_extension_dictionary</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="reserved">extension_dictionary_entry</span><span class="plain"> **</span><span class="identifier">sorted_extension_dictionary</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">no_entries</span><span class="plain"> = 0;</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">EXTENSIONS_CENSUS</span><span class="plain">, </span><span class="string">"Beginning dictionary sort\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
<span class="identifier">sorted_extension_dictionary</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Count headwords and reprocess their texts for dictionary sorting</span> <span class="cwebmacronumber">15.1</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">no_entries</span><span class="plain"> == 0) {</span>
<span class="identifier">first_in_sorted_dictionary</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="plain">}</span>
&lt;<span class="cwebmacro">Allocate memory for, and fill, an array of pointers to the EDEs</span> <span class="cwebmacronumber">15.2</span>&gt;<span class="plain">;</span>
<span class="identifier">qsort</span><span class="plain">(</span><span class="identifier">sorted_extension_dictionary</span><span class="plain">, (</span><span class="identifier">size_t</span><span class="plain">) </span><span class="identifier">no_entries</span><span class="plain">, </span><span class="reserved">sizeof</span><span class="plain">(</span><span class="reserved">extension_dictionary_entry</span><span class="plain"> *),</span>
<span class="functiontext">Extensions::Dictionary::compare_ed_entries</span><span class="plain">);</span>
&lt;<span class="cwebmacro">String the sorted array together into a sorted linked list of EDEs</span> <span class="cwebmacronumber">15.3</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Deallocate memory for the array again</span> <span class="cwebmacronumber">15.4</span>&gt;<span class="plain">;</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">EXTENSIONS_CENSUS</span><span class="plain">, </span><span class="string">"Sorted dictionary: %d entries\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">no_entries</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">no_entries</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Extensions::Dictionary::sort_extension_dictionary is used in <a href="#SP20">&#167;20</a>.</p>
<p class="inwebparagraph"><a id="SP15_1"></a><b>&#167;15.1. </b>Dictionary entries must be in mixed case: we might have both "green" the
colour and "Green" the kind of person (an environmental activist), say.
But we want to compare them with <code class="display"><span class="extract">strcmp</span></code>, which is much faster than its
case-insensitive analogue. So we trade memory for speed and store a modified
form of the headword in which spaces are removed and letters are reduced
to lower case; note that this is no larger than the original, so there is
no risk of the <code class="display"><span class="extract">sorting</span></code> string (which is 10 characters longer than the
unprocessed version) overflowing. Note: later we shall rely on the first
character of the sorting text being the lower-case form of the first
character of the original word.
</p>
<p class="inwebparagraph">We then append the allocation ID number, padded with initial zeros. We do
this so that (i) all sorting texts will be distinct, and (ii) alphabetical
order for sorting texts derived from two identical headword texts will
correspond to creation order. This means that <code class="display"><span class="extract">qsort</span></code>'s output will be
predictable (whereas different implementations of Quicksort might use the
freedom to sort unstably in different ways), and this seems a good idea
for better testing.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Count headwords and reprocess their texts for dictionary sorting</span> <span class="cwebmacronumber">15.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">extension_dictionary_entry</span><span class="plain"> *</span><span class="identifier">ede</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">ede</span><span class="plain">, </span><span class="reserved">extension_dictionary_entry</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ede</span><span class="plain">-</span><span class="element">&gt;erased</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<span class="identifier">no_entries</span><span class="plain">++;</span>
<span class="identifier">Str::clear</span><span class="plain">(</span><span class="identifier">ede</span><span class="plain">-</span><span class="element">&gt;sorting</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">ede</span><span class="plain">-</span><span class="element">&gt;entry_text</span><span class="plain">)</span>
<span class="reserved">if</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="character">' '</span><span class="plain">)</span>
<span class="identifier">PUT_TO</span><span class="plain">(</span><span class="identifier">ede</span><span class="plain">-</span><span class="element">&gt;sorting</span><span class="plain">,</span>
<span class="identifier">Characters::tolower</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">WRITE_TO</span><span class="plain">(</span><span class="identifier">ede</span><span class="plain">-</span><span class="element">&gt;sorting</span><span class="plain">, </span><span class="string">"-%09d"</span><span class="plain">, </span><span class="identifier">ede</span><span class="plain">-&gt;</span><span class="identifier">allocation_id</span><span class="plain">);</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">EXTENSIONS_CENSUS</span><span class="plain">, </span><span class="string">"Sorted under '%S': $d"</span><span class="plain">, </span><span class="identifier">ede</span><span class="plain">-</span><span class="element">&gt;sorting</span><span class="plain">, </span><span class="identifier">ede</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP15">&#167;15</a>.</p>
<p class="inwebparagraph"><a id="SP15_2"></a><b>&#167;15.2. </b>We unbundle the linked list of EDEs in creation order into an array
temporarily allocated in memory:
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Allocate memory for, and fill, an array of pointers to the EDEs</span> <span class="cwebmacronumber">15.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">extension_dictionary_entry</span><span class="plain"> *</span><span class="identifier">ede</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> = 0;</span>
<span class="identifier">sorted_extension_dictionary</span><span class="plain"> = </span><span class="identifier">Memory::I7_calloc</span><span class="plain">(</span><span class="identifier">no_entries</span><span class="plain">,</span>
<span class="reserved">sizeof</span><span class="plain">(</span><span class="reserved">extension_dictionary_entry</span><span class="plain"> *), </span><span class="constant">EXTENSION_DICTIONARY_MREASON</span><span class="plain">);</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">ede</span><span class="plain">, </span><span class="reserved">extension_dictionary_entry</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ede</span><span class="plain">-</span><span class="element">&gt;erased</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">)</span>
<span class="identifier">sorted_extension_dictionary</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">++] = </span><span class="identifier">ede</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP15">&#167;15</a>.</p>
<p class="inwebparagraph"><a id="SP15_3"></a><b>&#167;15.3. </b>We then use the sorted version of the same array to reorder the EDEs:
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">String the sorted array together into a sorted linked list of EDEs</span> <span class="cwebmacronumber">15.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">;</span>
<span class="identifier">first_in_sorted_dictionary</span><span class="plain"> = </span><span class="identifier">sorted_extension_dictionary</span><span class="plain">[0];</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">no_entries</span><span class="plain">-1; </span><span class="identifier">i</span><span class="plain">++)</span>
<span class="identifier">sorted_extension_dictionary</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]-</span><span class="element">&gt;next_in_sorted_dictionary</span><span class="plain"> =</span>
<span class="identifier">sorted_extension_dictionary</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">+1];</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">no_entries</span><span class="plain"> &gt; 0)</span>
<span class="identifier">sorted_extension_dictionary</span><span class="plain">[</span><span class="identifier">no_entries</span><span class="plain">-1]-</span><span class="element">&gt;next_in_sorted_dictionary</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP15">&#167;15</a>.</p>
<p class="inwebparagraph"><a id="SP15_4"></a><b>&#167;15.4. </b>And for the sake of tidiness:
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Deallocate memory for the array again</span> <span class="cwebmacronumber">15.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Memory::I7_array_free</span><span class="plain">(</span><span class="identifier">sorted_extension_dictionary</span><span class="plain">, </span><span class="constant">EXTENSION_DICTIONARY_MREASON</span><span class="plain">,</span>
<span class="identifier">no_entries</span><span class="plain">, </span><span class="reserved">sizeof</span><span class="plain">(</span><span class="reserved">extension_dictionary_entry</span><span class="plain"> *));</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP15">&#167;15</a>.</p>
<p class="inwebparagraph"><a id="SP16"></a><b>&#167;16. </b>As always with <code class="display"><span class="extract">qsort</span></code>, there's a palaver about the types used for the
comparison function so that the result will compile without errors. The
comparison of two EDEs is in fact delegated to a <code class="display"><span class="extract">strcmp</span></code> comparison
of their sorting texts:
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Extensions::Dictionary::compare_ed_entries</span><span class="plain">(</span><span class="reserved">const</span><span class="plain"> </span><span class="reserved">void</span><span class="plain"> *</span><span class="identifier">elem1</span><span class="plain">, </span><span class="reserved">const</span><span class="plain"> </span><span class="reserved">void</span><span class="plain"> *</span><span class="identifier">elem2</span><span class="plain">) {</span>
<span class="reserved">const</span><span class="plain"> </span><span class="reserved">extension_dictionary_entry</span><span class="plain"> **</span><span class="identifier">e1</span><span class="plain"> = (</span><span class="reserved">const</span><span class="plain"> </span><span class="reserved">extension_dictionary_entry</span><span class="plain"> **) </span><span class="identifier">elem1</span><span class="plain">;</span>
<span class="reserved">const</span><span class="plain"> </span><span class="reserved">extension_dictionary_entry</span><span class="plain"> **</span><span class="identifier">e2</span><span class="plain"> = (</span><span class="reserved">const</span><span class="plain"> </span><span class="reserved">extension_dictionary_entry</span><span class="plain"> **) </span><span class="identifier">elem2</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((*</span><span class="identifier">e1</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) || (*</span><span class="identifier">e2</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">"Disaster while sorting extension dictionary"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">Str::cmp</span><span class="plain">((*</span><span class="identifier">e1</span><span class="plain">)-</span><span class="element">&gt;sorting</span><span class="plain">, (*</span><span class="identifier">e2</span><span class="plain">)-</span><span class="element">&gt;sorting</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Extensions::Dictionary::compare_ed_entries is used in <a href="#SP15">&#167;15</a>.</p>
<p class="inwebparagraph"><a id="SP17"></a><b>&#167;17. Extension clashes. </b>All Inform extensions included share the main name-space of the source
text, and this causes potential problems with name clashes between two
different extensions if ever an author wants to include both at once. To
try to detect these clashes, we automatically scan the dictionary for them,
and provide warnings on the dynamic extension index.
</p>
<pre class="display">
<span class="reserved">known_extension_clash</span><span class="plain"> *</span><span class="functiontext">Extensions::Dictionary::kec_new</span><span class="plain">(</span><span class="reserved">extension_dictionary_entry</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain">, </span><span class="reserved">extension_dictionary_entry</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain">,</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">first_known_flag</span><span class="plain">) {</span>
<span class="reserved">known_extension_clash</span><span class="plain"> *</span><span class="identifier">kec</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">known_extension_clash</span><span class="plain">);</span>
<span class="identifier">kec</span><span class="plain">-</span><span class="element">&gt;leftx</span><span class="plain"> = </span><span class="identifier">L</span><span class="plain">;</span>
<span class="identifier">kec</span><span class="plain">-</span><span class="element">&gt;rightx</span><span class="plain"> = </span><span class="identifier">R</span><span class="plain">;</span>
<span class="identifier">kec</span><span class="plain">-</span><span class="element">&gt;number_clashes</span><span class="plain"> = 1;</span>
<span class="identifier">kec</span><span class="plain">-</span><span class="element">&gt;first_known</span><span class="plain"> = </span><span class="identifier">first_known_flag</span><span class="plain">;</span>
<span class="identifier">kec</span><span class="plain">-</span><span class="element">&gt;next</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">kec</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Extensions::Dictionary::kec_new is used in <a href="#SP18">&#167;18</a>, <a href="#SP18_2">&#167;18.2</a>.</p>
<p class="inwebparagraph"><a id="SP18"></a><b>&#167;18. </b>Every clash of names arises from definitions made in a pair of EDEs,
which we shall call left and right. Each distinct KEC ("known extension
clash") represents a different pair of extensions which clash, one
example of a name clashing between them, and a count of the number of
such names.
</p>
<p class="inwebparagraph"></p>
<ul class="items"><li>(a) Given a pair of extensions, the left one is the one whose author name
followed by title is lexicographically earlier. Since we are only concerned
with clashes between different extensions, this unambiguously decides which
is leftmost, as title and author suffice to identify extensions.
</li></ul>
<ul class="items"><li>(b) Similarly, given a pair of EDEs, the left one is the one whose definition
arises from the lefthand extension. (So, for instance, any definition made
in one of Eric Eve's extensions is always to the left of any definition in
one of John Clemens's.) Different EDEs deriving from the same extension do
not exemplify a clash.
</li></ul>
<ul class="items"><li>(c) For each extension L, there is at most one KEC whose left EDE derives
from L and which has the "first known" flag set.
</li></ul>
<p class="inwebparagraph">(-c.1) If such a KEC does not exist, then L does not clash with any other
extension.
</p>
<p class="inwebparagraph">(-c.2) If such a KEC does exist, then it is the head of a linked list of
KECs all of which have lefthand EDE deriving from L, and in which no two
entries have righthand EDEs deriving from the same extension as each other.
</p>
<p class="inwebparagraph">It follows that we can determine if extensions X and Y clash by arranging
them as L and R (rule (a)), looking for L among the left EDEs of all KECs
with the "first known" flag set (rule (c)), and then looking for Y among
the right EDEs of all KECs in the list which hangs from that (rule (c.2)).
Should either of these searches fail, there is no clash between X and Y.
Should both succeed, then the KEC found provides a single example of the
clash (in its left and right EDEs), together with the number of clashes.
</p>
<p class="inwebparagraph">If there are n extensions then there could in theory be n(n-1)/2 KECs,
which might amount to a lot of storage. In practice, though, Inform source
text tends to be dispersed around the cloud of English nouns and adjectives
fairly well, and since extension authors use each other's extensions, there
is also some social pressure to reduce the number of clashes. The user
mentioned above who had installed 155 different extensions &mdash; for a possible
11,935 distinct clashing pairs &mdash; in fact observed 15 such pairs, mostly arising
from part-finished drafts which had borrowed source text from pieces of other
extensions. Of the few remaining, several were cases where the same name
occurred in rival extensions aspiring to do much the same thing as each
other: for instance, "current quip" was defined by two different conversation
extensions. The only clashes of different meanings which might both be needed,
and which seem to have arisen spontaneously, were from definitions of the
words "seen" and "implicit", both treacherously ambiguous. Clashes did
not seem to have arisen from homonyms like "lead" (the substance) versus
"lead" (the attachment to a collar).
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Extensions::Dictionary::extension_clash</span><span class="plain">(</span><span class="reserved">extension_dictionary_entry</span><span class="plain"> *</span><span class="identifier">ede1</span><span class="plain">, </span><span class="reserved">extension_dictionary_entry</span><span class="plain"> *</span><span class="identifier">ede2</span><span class="plain">) {</span>
<span class="reserved">extension_dictionary_entry</span><span class="plain"> *</span><span class="identifier">left</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">right</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">leftx</span><span class="plain">, *</span><span class="identifier">rightx</span><span class="plain">;</span>
<span class="reserved">known_extension_clash</span><span class="plain"> *</span><span class="identifier">kec</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">ede1</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) || (</span><span class="identifier">ede2</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 extension clash"</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">d</span><span class="plain"> = </span><span class="functiontext">Works::compare</span><span class="plain">(</span><span class="identifier">ede1</span><span class="plain">-</span><span class="element">&gt;ede_work</span><span class="plain">, </span><span class="identifier">ede2</span><span class="plain">-</span><span class="element">&gt;ede_work</span><span class="plain">); </span> <span class="comment">compare source extensions</span>
&lt;<span class="cwebmacro">Ignore apparent clashes which are in fact not troublesome</span> <span class="cwebmacronumber">18.1</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">d</span><span class="plain"> &lt; 0) { </span><span class="identifier">left</span><span class="plain"> = </span><span class="identifier">ede1</span><span class="plain">; </span><span class="identifier">right</span><span class="plain"> = </span><span class="identifier">ede2</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">d</span><span class="plain"> &gt; 0) { </span><span class="identifier">left</span><span class="plain"> = </span><span class="identifier">ede2</span><span class="plain">; </span><span class="identifier">right</span><span class="plain"> = </span><span class="identifier">ede1</span><span class="plain">; }</span>
<span class="identifier">leftx</span><span class="plain"> = </span><span class="identifier">left</span><span class="plain">-</span><span class="element">&gt;ede_work</span><span class="plain">; </span><span class="identifier">rightx</span><span class="plain"> = </span><span class="identifier">right</span><span class="plain">-</span><span class="element">&gt;ede_work</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">kec</span><span class="plain">, </span><span class="reserved">known_extension_clash</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">kec</span><span class="plain">-</span><span class="element">&gt;first_known</span><span class="plain">) &amp;&amp; (</span><span class="functiontext">Works::match</span><span class="plain">(</span><span class="identifier">leftx</span><span class="plain">, </span><span class="identifier">kec</span><span class="plain">-</span><span class="element">&gt;leftx</span><span class="plain">-</span><span class="element">&gt;ede_work</span><span class="plain">))) {</span>
&lt;<span class="cwebmacro">Search list of KECs deriving from the same left extension as this clash</span> <span class="cwebmacronumber">18.2</span>&gt;<span class="plain">;</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">kec</span><span class="plain"> = </span><span class="functiontext">Extensions::Dictionary::kec_new</span><span class="plain">(</span><span class="identifier">left</span><span class="plain">, </span><span class="identifier">right</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Extensions::Dictionary::extension_clash is used in <a href="#SP20_1">&#167;20.1</a>.</p>
<p class="inwebparagraph"><a id="SP18_1"></a><b>&#167;18.1. </b>If two name clashes occur in the same extension then, since we can presume
that this extension does actually work, the clash cannot cause problems.
We also ignore a clash of a property name against some other form of name,
because these occur quite often and cause little difficulty in practice: so
they would only clutter up the dictionary with spurious warnings.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Ignore apparent clashes which are in fact not troublesome</span> <span class="cwebmacronumber">18.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">d</span><span class="plain"> == 0) </span><span class="reserved">return</span><span class="plain">; </span> <span class="comment">both definitions come from the same extension</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Str::eq_wide_string</span><span class="plain">(</span><span class="identifier">ede1</span><span class="plain">-</span><span class="element">&gt;type</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"property"</span><span class="plain">)) &amp;&amp; (</span><span class="identifier">Str::eq_wide_string</span><span class="plain">(</span><span class="identifier">ede2</span><span class="plain">-</span><span class="element">&gt;type</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"property"</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Str::eq_wide_string</span><span class="plain">(</span><span class="identifier">ede1</span><span class="plain">-</span><span class="element">&gt;type</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"property"</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) &amp;&amp; (</span><span class="identifier">Str::eq_wide_string</span><span class="plain">(</span><span class="identifier">ede2</span><span class="plain">-</span><span class="element">&gt;type</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"property"</span><span class="plain">))) </span><span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP18">&#167;18</a>.</p>
<p class="inwebparagraph"><a id="SP18_2"></a><b>&#167;18.2. </b>If we can find the righthand extension on the righthand side of any KEC
in the list, then the clash is not a new one: we simply increment the number
of definition pairs clashing between the left and right extensions, and
return. (Thus forgetting what the actual definitions causing the present
clash were: we don't need them, as we already have an example of the
definitions clashing between the two.) But if we can't find righthand
extension anywhere in the list, we must add the new pair of definitions:
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Search list of KECs deriving from the same left extension as this clash</span> <span class="cwebmacronumber">18.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">kec</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Works::match</span><span class="plain">(</span><span class="identifier">rightx</span><span class="plain">, </span><span class="identifier">kec</span><span class="plain">-</span><span class="element">&gt;rightx</span><span class="plain">-</span><span class="element">&gt;ede_work</span><span class="plain">)) {</span>
<span class="identifier">kec</span><span class="plain">-</span><span class="element">&gt;number_clashes</span><span class="plain">++; </span><span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">kec</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
<span class="identifier">kec</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain"> = </span><span class="functiontext">Extensions::Dictionary::kec_new</span><span class="plain">(</span><span class="identifier">left</span><span class="plain">, </span><span class="identifier">right</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">kec</span><span class="plain"> = </span><span class="identifier">kec</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP18">&#167;18</a>.</p>
<p class="inwebparagraph"><a id="SP19"></a><b>&#167;19. </b>The above arrangement was designed to make it easy to print out the
clashes in a concise, human-readable way, which is what we now do.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Extensions::Dictionary::list_known_extension_clashes</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">) {</span>
<span class="reserved">known_extension_clash</span><span class="plain"> *</span><span class="identifier">kec</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">NUMBER_CREATED</span><span class="plain">(</span><span class="reserved">known_extension_clash</span><span class="plain">) == 0) </span><span class="reserved">return</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Write the headnote about what extension clashes mean</span> <span class="cwebmacronumber">19.1</span>&gt;<span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">kec</span><span class="plain">, </span><span class="reserved">known_extension_clash</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">kec</span><span class="plain">-</span><span class="element">&gt;first_known</span><span class="plain">)</span>
&lt;<span class="cwebmacro">Write a paragraph about extensions clashing with the lefthand one here</span> <span class="cwebmacronumber">19.2</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Extensions::Dictionary::list_known_extension_clashes is used in <a href="#SP20">&#167;20</a>.</p>
<p class="inwebparagraph"><a id="SP19_1"></a><b>&#167;19.1. </b>Not the end of the world! Extension clashes are not an error condition: they
are, if anything, a sign of life and activity.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Write the headnote about what extension clashes mean</span> <span class="cwebmacronumber">19.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">HTML_OPEN</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&lt;b&gt;Clashes found.&lt;/b&gt; The dictionary above shows that some "</span>
<span class="string">"extensions make incompatible definitions of the same words or phrases. "</span>
<span class="string">"When two extensions disagree like this, it is not necessarily a bad "</span>
<span class="string">"sign (they might simply be two ways to approach the same problem), "</span>
<span class="string">"but in general it means that it may not be safe to use both "</span>
<span class="string">"extensions at the same time. The following list shows some potential "</span>
<span class="string">"clashes."</span><span class="plain">);</span>
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP19">&#167;19</a>.</p>
<p class="inwebparagraph"><a id="SP19_2"></a><b>&#167;19.2. </b>As always, we need to be careful about writing the ISO text of clashing
matter to the UTF-8 HTML file:
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Write a paragraph about extensions clashing with the lefthand one here</span> <span class="cwebmacronumber">19.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">known_extension_clash</span><span class="plain"> *</span><span class="identifier">example</span><span class="plain">;</span>
<span class="identifier">HTML_OPEN</span><span class="plain">(</span><span class="string">"b"</span><span class="plain">);</span>
<span class="functiontext">Works::write_to_HTML_file</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">kec</span><span class="plain">-</span><span class="element">&gt;leftx</span><span class="plain">-</span><span class="element">&gt;ede_work</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"b"</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">": "</span><span class="plain">);</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">example</span><span class="plain"> = </span><span class="identifier">kec</span><span class="plain">; </span><span class="identifier">example</span><span class="plain">; </span><span class="identifier">example</span><span class="plain"> = </span><span class="identifier">example</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"clash with "</span><span class="plain">);</span>
<span class="identifier">HTML_OPEN</span><span class="plain">(</span><span class="string">"b"</span><span class="plain">);</span>
<span class="functiontext">Works::write_to_HTML_file</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">example</span><span class="plain">-</span><span class="element">&gt;rightx</span><span class="plain">-</span><span class="element">&gt;ede_work</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"b"</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" (on "</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">example</span><span class="plain">-</span><span class="element">&gt;number_clashes</span><span class="plain"> &gt; 1)</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%d names, for instance "</span><span class="plain">, </span><span class="identifier">example</span><span class="plain">-</span><span class="element">&gt;number_clashes</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">example</span><span class="plain">-</span><span class="element">&gt;leftx</span><span class="plain">-</span><span class="element">&gt;entry_text</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">example</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"; "</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">HTML_OPEN</span><span class="plain">(</span><span class="string">"p"</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>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP19">&#167;19</a>.</p>
<p class="inwebparagraph"><a id="SP20"></a><b>&#167;20. Writing the HTML extension index. </b>This is the index of terms, not the directory of extensions: it is, in
fact, the HTML rendering of the dictionary constructed above.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Extensions::Dictionary::write_to_HTML</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">) {</span>
<span class="identifier">HTML_OPEN</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"Whenever an extension is used, its definitions are entered into the "</span>
<span class="string">"following index. (Thus, a newly installed but never-used extension "</span>
<span class="string">"is not indexed yet.)."</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="identifier">HTML::end_html_row</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
<span class="identifier">HTML::end_html_table</span><span class="plain">(</span><span class="identifier">OUT</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">int</span><span class="plain"> </span><span class="identifier">first_letter</span><span class="plain"> = </span><span class="character">'a'</span><span class="plain">;</span>
<span class="reserved">extension_dictionary_entry</span><span class="plain"> *</span><span class="identifier">ede</span><span class="plain">, *</span><span class="identifier">previous_ede</span><span class="plain">, *</span><span class="identifier">next_ede</span><span class="plain">;</span>
<span class="functiontext">Extensions::Dictionary::erase_entries_of_uninstalled_extensions</span><span class="plain">();</span>
<span class="identifier">n</span><span class="plain"> = </span><span class="functiontext">Extensions::Dictionary::sort_extension_dictionary</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">n</span><span class="plain"> &lt;= 0) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">previous_ede</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">ede</span><span class="plain"> = </span><span class="identifier">first_in_sorted_dictionary</span><span class="plain">; </span><span class="identifier">ede</span><span class="plain">;</span>
<span class="identifier">previous_ede</span><span class="plain"> = </span><span class="identifier">ede</span><span class="plain">, </span><span class="identifier">ede</span><span class="plain"> = </span><span class="identifier">ede</span><span class="plain">-</span><span class="element">&gt;next_in_sorted_dictionary</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::eq_wide_string</span><span class="plain">(</span><span class="identifier">ede</span><span class="plain">-</span><span class="element">&gt;type</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"indexing"</span><span class="plain">)) </span><span class="reserved">continue</span><span class="plain">;</span>
<span class="identifier">next_ede</span><span class="plain"> = </span><span class="identifier">ede</span><span class="plain">-</span><span class="element">&gt;next_in_sorted_dictionary</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">this_first</span><span class="plain"> = </span><span class="identifier">Characters::tolower</span><span class="plain">(</span><span class="identifier">Str::get_first_char</span><span class="plain">(</span><span class="identifier">ede</span><span class="plain">-</span><span class="element">&gt;entry_text</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">first_letter</span><span class="plain"> != </span><span class="identifier">this_first</span><span class="plain">) {</span>
<span class="identifier">HTML_TAG</span><span class="plain">(</span><span class="string">"br"</span><span class="plain">); </span><span class="identifier">first_letter</span><span class="plain"> = </span><span class="identifier">this_first</span><span class="plain">;</span>
<span class="plain">}</span>
&lt;<span class="cwebmacro">Write extension dictionary entry for this headword</span> <span class="cwebmacronumber">20.1</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
<span class="functiontext">Extensions::Dictionary::list_known_extension_clashes</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Extensions::Dictionary::write_to_HTML is used in 5/ec (<a href="5-ec.html#SP15">&#167;15</a>).</p>
<p class="inwebparagraph"><a id="SP20_1"></a><b>&#167;20.1. </b>A run of N words which are all the same should appear in tinted type
throughout, while N(N-1)/2 clashes should be reported to the machinery above:
if we find definitions A, B, C, for instance, the clashes are reported as
A vs B, A vs C, then B vs C. This has O(N^2) running time, so if there are
1000 extensions, each of which gives 1000 different meanings to the word
"frog", we would be in some trouble here. Let's take the risk.
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="identifier">EDES_DEFINE_SAME_WORD</span><span class="plain">(</span><span class="identifier">X</span><span class="plain">, </span><span class="identifier">Y</span><span class="plain">) ((</span><span class="identifier">X</span><span class="plain">) &amp;&amp; (</span><span class="identifier">Y</span><span class="plain">) &amp;&amp; (</span><span class="identifier">Str::eq</span><span class="plain">(</span><span class="identifier">X</span><span class="plain">-</span><span class="element">&gt;sorting</span><span class="plain">, </span><span class="identifier">Y</span><span class="plain">-</span><span class="element">&gt;sorting</span><span class="plain">)))</span>
</pre>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Write extension dictionary entry for this headword</span> <span class="cwebmacronumber">20.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">tint</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">EDES_DEFINE_SAME_WORD</span><span class="plain">(</span><span class="identifier">ede</span><span class="plain">, </span><span class="identifier">previous_ede</span><span class="plain">)) </span><span class="identifier">tint</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">EDES_DEFINE_SAME_WORD</span><span class="plain">(</span><span class="identifier">ede</span><span class="plain">, </span><span class="identifier">next_ede</span><span class="plain">)) {</span>
<span class="identifier">tint</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="functiontext">Extensions::Dictionary::extension_clash</span><span class="plain">(</span><span class="identifier">ede</span><span class="plain">, </span><span class="identifier">next_ede</span><span class="plain">);</span>
<span class="identifier">next_ede</span><span class="plain"> = </span><span class="identifier">next_ede</span><span class="plain">-</span><span class="element">&gt;next_in_sorted_dictionary</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">HTML_OPEN_WITH</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">, </span><span class="string">"style='margin:0px; padding:0px;'"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">tint</span><span class="plain">) </span><span class="identifier">HTML::begin_colour</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"FF8080"</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">ede</span><span class="plain">-</span><span class="element">&gt;entry_text</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">tint</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">" - &lt;i&gt;%S&lt;/i&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;"</span><span class="plain">, </span><span class="identifier">ede</span><span class="plain">-</span><span class="element">&gt;type</span><span class="plain">);</span>
<span class="identifier">HTML_OPEN_WITH</span><span class="plain">(</span><span class="string">"span"</span><span class="plain">, </span><span class="string">"class=\</span><span class="plain">"</span><span class="string">smaller\</span><span class="plain">"</span><span class="string">"</span><span class="plain">);</span>
<span class="functiontext">Works::write_link_to_HTML_file</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">ede</span><span class="plain">-</span><span class="element">&gt;ede_work</span><span class="plain">);</span>
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"span"</span><span class="plain">);</span>
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP20">&#167;20</a>.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="5-es.html">Back to 'Extension Services'</a></li><li><a href="5-ed2.html">Continue with 'Extension Documentation'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>

Some files were not shown because too many files have changed in this diff Show more