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

Documented Inbuild

This commit is contained in:
Graham Nelson 2020-03-26 19:22:26 +00:00
parent 3c59521ab7
commit 4054358914
58 changed files with 1915 additions and 551 deletions

View file

@ -1,6 +1,6 @@
# Inform 7
v10.1.0-alpha.1+6Q27 'Krypton' (25 March 2020)
v10.1.0-alpha.1+6Q28 'Krypton' (26 March 2020)
## About Inform 7

View file

@ -1,3 +1,3 @@
Prerelease: alpha.1
Build Date: 25 March 2020
Build Number: 6Q27
Build Date: 26 March 2020
Build Number: 6Q28

View file

@ -736,7 +736,6 @@ routines:
<p class="inwebparagraph"></p>
<hr class="tocbar">
<ul class="toc"><li><i>(This section begins Sections.)</i></li><li><i>(This section ends Sections.)</i></li></ul><hr class="tocbar">
<!--End of weave-->
</main>
</body>

View file

@ -182,7 +182,6 @@
<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-->
</main>
</body>

View file

@ -546,7 +546,6 @@ the list!);
<p class="endnote">The function Lists::compile_default_list is used in 13/rsfk (<a href="13-rsfk.html#SP16_2">&#167;16.2</a>).</p>
<hr class="tocbar">
<ul class="toc"><li><i>(This section begins Chapter 18: List Data.)</i></li><li><i>(This section ends Chapter 18: List Data.)</i></li></ul><hr class="tocbar">
<!--End of weave-->
</main>
</body>

View file

@ -3118,7 +3118,6 @@ parse the equation, then rearrange to solve it for each variable in turn.
<p class="endnote">The function Equations::index appears nowhere else.</p>
<hr class="tocbar">
<ul class="toc"><li><i>(This section begins Chapter 20: Equations.)</i></li><li><i>(This section ends Chapter 20: Equations.)</i></li></ul><hr class="tocbar">
<!--End of weave-->
</main>
</body>

View file

@ -853,7 +853,6 @@ we might in future.
<p class="endnote">The function Extensions::Files::handle_extension_ends appears nowhere else.</p>
<hr class="tocbar">
<ul class="toc"><li><i>(This section begins Chapter 8: Extensions.)</i></li><li><i>(This section ends Chapter 8: Extensions.)</i></li></ul><hr class="tocbar">
<!--End of weave-->
</main>
</body>

View file

@ -159,7 +159,6 @@ foundation module does that automatically.)
<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-->
</main>
</body>

View file

@ -264,7 +264,6 @@ foundation module does that automatically.)
<p class="endnote">The function IFModule::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-->
</main>
</body>

View file

@ -870,7 +870,6 @@ so they come with ready-made headers.
<p class="endnote">This code is used in <a href="#SP24">&#167;24</a>.</p>
<hr class="tocbar">
<ul class="toc"><li><i>(This section begins Chapter 2: Blorbs.)</i></li><li><i>(This section ends Chapter 2: Blorbs.)</i></li></ul><hr class="tocbar">
<!--End of weave-->
</main>
</body>

View file

@ -346,9 +346,12 @@ dependency graphs.
<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">inform_project</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain"> = </span><span class="functiontext">Inbuild::project</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="functiontext">Copies::go_operational</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">-</span><span class="element">&gt;as_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="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="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="identifier">C</span><span class="plain"> != </span><span class="identifier">P</span><span class="plain">-</span><span class="element">&gt;as_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>

View file

@ -128,27 +128,28 @@ directories holding a set of files.
<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="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="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="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">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="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">FALSE</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">Copies::show_needs</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">Graphs::show_needs</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="reserved">void</span><span class="plain"> </span><span class="functiontext">Copies::show_needs</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">int</span><span class="plain"> </span><span class="identifier">uses_only</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">FALSE</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="functiontext">Graphs::show_needs</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;vertex</span><span class="plain">, </span><span class="identifier">uses_only</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Copies::show_missing</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">int</span><span class="plain"> </span><span class="identifier">N</span><span class="plain"> = </span><span class="functiontext">Graphs::show_missing</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;vertex</span><span class="plain">);</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Copies::show_missing</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">int</span><span class="plain"> </span><span class="identifier">uses_only</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">FALSE</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">N</span><span class="plain"> = </span><span class="functiontext">Graphs::show_missing</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;vertex</span><span class="plain">, </span><span class="identifier">uses_only</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">N</span><span class="plain"> == 0) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"Nothing is missing\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Copies::archive</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain">, </span><span class="reserved">inbuild_nest</span><span class="plain"> *</span><span class="identifier">N</span><span class="plain">, </span><span class="reserved">build_methodology</span><span class="plain"> *</span><span class="identifier">BM</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">NM</span><span class="plain"> = </span><span class="functiontext">Graphs::show_missing</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;vertex</span><span class="plain">);</span>
<span class="identifier">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">FALSE</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">NM</span><span class="plain"> = </span><span class="functiontext">Graphs::show_missing</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;vertex</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">NM</span><span class="plain"> &gt; 0) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"Because there are missing resources, -archive is cancelled\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> {</span>
<span class="functiontext">Graphs::archive</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;vertex</span><span class="plain">, </span><span class="identifier">N</span><span class="plain">, </span><span class="identifier">BM</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">N</span><span class="plain">) </span><span class="functiontext">Graphs::archive</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;vertex</span><span class="plain">, </span><span class="identifier">N</span><span class="plain">, </span><span class="identifier">BM</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Copies::source_text_has_been_read</span><span class="plain">(</span><span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain">) {</span>
@ -199,7 +200,8 @@ directories holding a set of files.
<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="identifier">pathname</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain"> = </span><span class="identifier">Filenames::get_path_to</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;location_if_file</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">P</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" in directory %p"</span><span class="plain">, </span><span class="identifier">P</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">N</span><span class="plain"> = </span><span class="identifier">LinkedLists::len</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;errors_reading_source_text</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">N</span><span class="plain"> &gt; 0) {</span>
@ -245,7 +247,7 @@ directories holding a set of files.
<p class="endnote">The function Copies::source_text_has_been_read is used in 6/inc (<a href="6-inc.html#SP6">&#167;6</a>).</p>
<p class="endnote">The function Copies::read_source_text_for is used in 1/ic (<a href="1-ic.html#SP3">&#167;3</a>), 5/ed2 (<a href="5-ed2.html#SP3_1">&#167;3.1</a>), 6/inc (<a href="6-inc.html#SP6_1">&#167;6.1</a>).</p>
<p class="endnote">The function Copies::read_source_text_for is used in 1/ic (<a href="1-ic.html#SP3">&#167;3</a>), 4/em (<a href="4-em.html#SP9">&#167;9</a>), 5/ed2 (<a href="5-ed2.html#SP3_1">&#167;3.1</a>), 6/inc (<a href="6-inc.html#SP6_1">&#167;6.1</a>).</p>
<p class="endnote">The function Copies::claim appears nowhere else.</p>

View file

@ -141,7 +141,7 @@ few of these.
<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>
<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">build</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>

View file

@ -155,7 +155,9 @@
<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="reserved">if</span><span class="plain"> (</span><span class="identifier">destination_nest</span><span class="plain">)</span>
<span class="identifier">VMETHOD_CALL</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;edition</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">-</span><span class="element">&gt;genre</span><span class="plain">, </span><span class="constant">GENRE_COPY_TO_NEST_MTID</span><span class="plain">,</span>
<span class="identifier">C</span><span class="plain">, </span><span class="identifier">destination_nest</span><span class="plain">, </span><span class="identifier">syncing</span><span class="plain">, </span><span class="identifier">meth</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Nests::overwrite_error</span><span class="plain">(</span><span class="reserved">inbuild_nest</span><span class="plain"> *</span><span class="identifier">N</span><span class="plain">, </span><span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain">) {</span>

View file

@ -144,6 +144,8 @@ a different file inside the copy.
<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="comment">Graphs::describe(STDOUT, from, FALSE); PRINT(" needs ");</span>
<span class="comment">Graphs::describe(STDOUT, to, FALSE); PRINT("\n");</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>
@ -208,11 +210,11 @@ a different file inside the copy.
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Graphs::show_needs</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="functiontext">Graphs::show_needs_r</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">, 0, 0);</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Graphs::show_needs</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">uses_only</span><span class="plain">) {</span>
<span class="functiontext">Graphs::show_needs_r</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">, 0, 0, </span><span class="identifier">uses_only</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Graphs::show_needs_r</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">depth</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">true_depth</span><span class="plain">) {</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Graphs::show_needs_r</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">depth</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">true_depth</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">uses_only</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">V</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="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">inbuild_copy</span><span class="plain"> *</span><span class="identifier">C</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>
@ -233,19 +235,20 @@ a different file inside the copy.
<span class="identifier">depth</span><span class="plain">++;</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::show_needs_r</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">depth</span><span class="plain">, </span><span class="identifier">true_depth</span><span class="plain">+1);</span>
<span class="reserved">if</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">COPY_VERTEX</span><span class="plain">) &amp;&amp; (</span><span class="identifier">true_depth</span><span class="plain"> &gt; 0)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">uses_only</span><span class="plain"> == </span><span class="identifier">FALSE</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::show_needs_r</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">depth</span><span class="plain">, </span><span class="identifier">true_depth</span><span class="plain">+1, </span><span class="identifier">uses_only</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;type</span><span class="plain"> == </span><span class="constant">COPY_VERTEX</span><span class="plain">) &amp;&amp; ((</span><span class="identifier">true_depth</span><span class="plain"> &gt; 0) || (</span><span class="identifier">uses_only</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::show_needs_r</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">depth</span><span class="plain">, </span><span class="identifier">true_depth</span><span class="plain">+1);</span>
<span class="functiontext">Graphs::show_needs_r</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">depth</span><span class="plain">, </span><span class="identifier">true_depth</span><span class="plain">+1, </span><span class="identifier">uses_only</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Graphs::show_missing</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">return</span><span class="plain"> </span><span class="functiontext">Graphs::show_missing_r</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">, 0);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Graphs::show_missing</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">uses_only</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Graphs::show_missing_r</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">, 0, </span><span class="identifier">uses_only</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Graphs::show_missing_r</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">true_depth</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Graphs::show_missing_r</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">true_depth</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">uses_only</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">if</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">WRITE</span><span class="plain">(</span><span class="string">"missing %S: "</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="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>
@ -259,11 +262,12 @@ a different file inside the copy.
<span class="identifier">N</span><span class="plain"> = 1;</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="identifier">N</span><span class="plain"> += </span><span class="functiontext">Graphs::show_missing_r</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">true_depth</span><span class="plain">+1);</span>
<span class="reserved">if</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">COPY_VERTEX</span><span class="plain">) &amp;&amp; (</span><span class="identifier">true_depth</span><span class="plain"> &gt; 0)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">uses_only</span><span class="plain"> == </span><span class="identifier">FALSE</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">N</span><span class="plain"> += </span><span class="functiontext">Graphs::show_missing_r</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">true_depth</span><span class="plain">+1, </span><span class="identifier">uses_only</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;type</span><span class="plain"> == </span><span class="constant">COPY_VERTEX</span><span class="plain">) &amp;&amp; ((</span><span class="identifier">true_depth</span><span class="plain"> &gt; 0) || (</span><span class="identifier">uses_only</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">N</span><span class="plain"> += </span><span class="functiontext">Graphs::show_missing_r</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">true_depth</span><span class="plain">+1);</span>
<span class="identifier">N</span><span class="plain"> += </span><span class="functiontext">Graphs::show_missing_r</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">true_depth</span><span class="plain">+1, </span><span class="identifier">uses_only</span><span class="plain">);</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>
@ -363,9 +367,9 @@ a different file inside the copy.
<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>), 6/inc (<a href="6-inc.html#SP1_1">&#167;1.1</a>, <a href="6-inc.html#SP6_1">&#167;6.1</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>), 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>), 5/ps (<a href="5-ps.html#SP3">&#167;3</a>), 6/inc (<a href="6-inc.html#SP1_1">&#167;1.1</a>).</p>
<p class="endnote">The function Graphs::describe is used in <a href="#SP2">&#167;2</a>, 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 is used in <a href="#SP2">&#167;2</a>, 4/km (<a href="4-km.html#SP7">&#167;7</a>), 4/em (<a href="4-em.html#SP9">&#167;9</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>
@ -389,7 +393,7 @@ a different file inside the copy.
<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, 3/is4, 5/ed, 5/ps and here.</p>
<p class="endnote">The structure build_vertex is accessed in 3/bs2, 3/is, 3/is3, 3/is4, 4/em, 5/ed, 5/ps, 6/inc and here.</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b></p>
@ -417,7 +421,7 @@ a different file inside the copy.
<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="reserved">int</span><span class="plain"> </span><span class="identifier">changes_so_far</span><span class="plain"> = *</span><span class="identifier">changes</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">if</span><span class="plain"> (</span><span class="identifier">trace_ibg</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>
@ -427,7 +431,7 @@ a different file inside the copy.
<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">changes</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">trace_ibg</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>
@ -449,9 +453,9 @@ a different file inside the copy.
<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::build 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/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::rebuild 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/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>

View file

@ -120,7 +120,7 @@
<p class="inwebparagraph"></p>
<p class="endnote">The structure build_step is accessed in 2/cps, 3/bg, 3/is, 3/is2, 3/is3, 3/is4, 4/km, 5/kts, 5/ps, 6/hdn, 6/inc and here.</p>
<p class="endnote">The structure build_step is accessed in 2/cps, 3/bg, 3/is, 3/is2, 3/is3, 3/is4, 4/km, 4/em, 5/kts, 5/ps, 6/hdn, 6/inc and here.</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b></p>

View file

@ -91,6 +91,7 @@ length to one character less than the following constants:
<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="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">extension_genre</span><span class="plain">, </span><span class="constant">GENRE_BUILD_COPY_MTID</span><span class="plain">, </span><span class="functiontext">ExtensionManager::build</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>
@ -157,7 +158,7 @@ which stores data about extensions used by the Inform compiler.
<p class="inwebparagraph"></p>
<p class="endnote">The function ExtensionManager::from_copy is used in <a href="#SP10">&#167;10</a>, 5/es (<a href="5-es.html#SP5">&#167;5</a>), 5/ed2 (<a href="5-ed2.html#SP4">&#167;4</a>), 5/ec (<a href="5-ec.html#SP2">&#167;2</a>), 6/st (<a href="6-st.html#SP11">&#167;11</a>), 6/inc (<a href="6-inc.html#SP6_1">&#167;6.1</a>).</p>
<p class="endnote">The function ExtensionManager::from_copy is used in <a href="#SP9">&#167;9</a>, <a href="#SP10">&#167;10</a>, 5/es (<a href="5-es.html#SP5">&#167;5</a>), 5/ed2 (<a href="5-ed2.html#SP4">&#167;4</a>), 5/ec (<a href="5-ec.html#SP2">&#167;2</a>), 6/st (<a href="6-st.html#SP11">&#167;11</a>), 6/inc (<a href="6-inc.html#SP6_1">&#167;6.1</a>).</p>
<p class="endnote">The function ExtensionManager::new_copy is used in <a href="#SP6">&#167;6</a>.</p>
@ -311,12 +312,37 @@ since an extension is a single file; to sync, we just overwrite.
<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 class="inwebparagraph"><a id="SP9"></a><b>&#167;9. Build graph. </b>As far as building goes, the build graph for an extension is just a single node:
you don't need to build an extension at all. But it may well have use edges,
thanks to including other extensions, and because of that we have to read the
source text before we can do anything with the graph.
</p>
<p class="inwebparagraph">We don't do this at the going operational stage because that would be
inefficient and might cause VM-related problems &mdash; it would mean that many
extraneous extensions, discovered only when scanning some directory, would
be read in as source text; and some of those might not be compatible with
the current VM settings.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">ExtensionManager::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">build</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="functiontext">ExtensionManager::ensure_graphed</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">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="reserved">if</span><span class="plain"> (</span><span class="identifier">build</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">ExtensionManager::ensure_graphed</span><span class="plain">(</span><span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain">) {</span>
<span class="functiontext">Copies::read_source_text_for</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">);</span>
<span class="functiontext">Inclusions::traverse</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="functiontext">ExtensionManager::from_copy</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">)-</span><span class="element">&gt;syntax_tree</span><span class="plain">);</span>
<span class="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">V</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">, </span><span class="reserved">build_vertex</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;vertex</span><span class="plain">-</span><span class="element">&gt;use_edges</span><span class="plain">)</span>
<span class="functiontext">ExtensionManager::ensure_graphed</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="plain">}</span>
<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>
@ -324,6 +350,10 @@ build an extension at all.
<p class="inwebparagraph"></p>
<p class="endnote">The function ExtensionManager::build is used in <a href="#SP3">&#167;3</a>.</p>
<p class="endnote">The function ExtensionManager::ensure_graphed appears nowhere else.</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>

View file

@ -276,10 +276,10 @@ we need to <code class="display"><span class="extract">rsync</span></code> it.
<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">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">build</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="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">build</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>

View file

@ -188,12 +188,12 @@ projects lived there.
<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">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">build</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="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">build</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>

View file

@ -191,12 +191,12 @@ projects lived there.
<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">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">build</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="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">build</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>

View file

@ -133,7 +133,7 @@
<p class="endnote">The function Extensions::scan is used in 4/em (<a href="4-em.html#SP3">&#167;3</a>).</p>
<p class="endnote">The structure inform_extension is accessed in 1/ic, 3/is2, 3/is3, 4/lm, 4/pbm, 4/pfm, 4/tm, 4/pm, 5/kts, 5/ed, 5/ed2, 5/ts, 5/ps, 5/ls, 5/ps2, 6/hdn, 6/inc and here.</p>
<p class="endnote">The structure inform_extension is accessed in 1/ic, 3/is2, 3/is3, 4/em, 4/lm, 4/pbm, 4/pfm, 4/tm, 4/pm, 5/kts, 5/ed, 5/ed2, 5/ts, 5/ps, 5/ls, 5/ps2, 6/hdn, 6/inc and here.</p>
<p class="inwebparagraph"><a id="SP1_1"></a><b>&#167;1.1. </b>The following scans a potential extension file. If it seems malformed, a
suitable error is written to the stream <code class="display"><span class="extract">error_text</span></code>. If not, this is left

View file

@ -279,7 +279,7 @@
<p class="endnote">The structure kit_dependency is accessed in 3/is2 and here.</p>
<p class="endnote">The structure inform_project is accessed in 1/ic, 2/edt, 2/rqr, 2/nst, 3/is2, 3/is3, 4/lm, 4/pbm, 4/pfm, 4/tm, 4/pm, 5/kts, 5/es, 5/ed, 5/ed2, 5/ec, 5/ts, 5/ls, 5/ps2, 6/hdn, 6/inc, 6/vmg and here.</p>
<p class="endnote">The structure inform_project is accessed in 1/ic, 2/edt, 2/rqr, 2/nst, 3/is2, 3/is3, 4/em, 4/lm, 4/pbm, 4/pfm, 4/tm, 4/pm, 5/kts, 5/es, 5/ed, 5/ed2, 5/ec, 5/ts, 5/ls, 5/ps2, 6/hdn, 6/inc, 6/vmg and here.</p>
<p class="inwebparagraph"><a id="SP1_1"></a><b>&#167;1.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Perform if-this-then-that</span> <span class="cwebmacronumber">1.1</span>&gt; =

View file

@ -115,7 +115,7 @@ guaranteed to be no INCLUDE nodes remaining in the parse tree.
<p class="inwebparagraph"></p>
<p class="endnote">The function Inclusions::traverse is used in 5/ps (<a href="5-ps.html#SP4">&#167;4</a>).</p>
<p class="endnote">The function Inclusions::traverse is used in 4/em (<a href="4-em.html#SP9">&#167;9</a>), 5/ps (<a href="5-ps.html#SP4">&#167;4</a>).</p>
<p class="endnote">The function Inclusions::spawned_from_vertex is used in <a href="#SP1_1">&#167;1.1</a>, <a href="#SP6_1">&#167;6.1</a>.</p>
@ -146,7 +146,10 @@ guaranteed to be no INCLUDE nodes remaining in the parse tree.
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">last_H0</span><span class="plain">) &amp;&amp; (</span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">last_H0</span><span class="plain">, </span><span class="identifier">implied_heading_ANNOT</span><span class="plain">) != </span><span class="identifier">TRUE</span><span class="plain">)) {</span>
<span class="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">V</span><span class="plain"> = </span><span class="functiontext">Inclusions::spawned_from_vertex</span><span class="plain">(</span><span class="identifier">last_H0</span><span class="plain">);</span>
<span class="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">EV</span><span class="plain"> = </span><span class="identifier">E</span><span class="plain">-</span><span class="element">&gt;as_copy</span><span class="plain">-</span><span class="element">&gt;vertex</span><span class="plain">;</span>
<span class="functiontext">Graphs::need_this_to_build</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">, </span><span class="identifier">EV</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="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="functiontext">Graphs::need_this_to_use</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">, </span><span class="identifier">EV</span><span class="plain">);</span>
<span class="reserved">else</span>
<span class="functiontext">Graphs::need_this_to_build</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">, </span><span class="identifier">EV</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>

View file

@ -57,103 +57,38 @@
<main role="main">
<!--Weave of '1/mn' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">Source</a></li><li><a href="../compiler.html">Compiler Tools</a></li><li><a href="index.html">inbuild</a></li><li><a href="index.html#1">Chapter 1: Delegation</a></li><li><b>Main</b></li></ul><p class="purpose">The top level, which decides what is to be done and then carries this plan out.</p>
<ul class="crumbs"><li><a href="../webs.html">Source</a></li><li><a href="../compiler.html">Compiler Tools</a></li><li><a href="index.html">inbuild</a></li><li><a href="index.html#1">Chapter 1: Inbuild outside of Inform</a></li><li><b>Main</b></li></ul><p class="purpose">A command-line interface for Inbuild functions which are not part of the normal operation of the Inform compiler.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Main routine</a></li></ul><hr class="tocbar">
<ul class="toc"><li><a href="#SP1">&#167;1. Main routine</a></li><li><a href="#SP1_6">&#167;1.6. Target list</a></li><li><a href="#SP1_7">&#167;1.7. Command line</a></li><li><a href="#SP4">&#167;4. Interface to Words module</a></li><li><a href="#SP6">&#167;6. Interface to Syntax module</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Main routine. </b></p>
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Main routine. </b>When Inbuild is called at the command line, it begins at <code class="display"><span class="extract">main</span></code>, like all C
programs.
</p>
<p class="inwebparagraph">Inbuild manages "copies", which are instances of programs or resources found
somewhere in the file system. The copies which it acts on in a given run are
called "targets". The task of <code class="display"><span class="extract">main</span></code> is to read the command-line arguments,
set the following variables as needed, and produce a list of targets to work
on; then to carry out that work, and then shut down again.
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">INTOOL_NAME</span><span class="plain"> </span><span class="string">"inbuild"</span>
<span class="definitionkeyword">enum</span> <span class="constant">INSPECT_TTASK</span><span class="definitionkeyword"> from </span><span class="constant">1</span>
<span class="definitionkeyword">enum</span> <span class="constant">GRAPH_TTASK</span>
<span class="definitionkeyword">enum</span> <span class="constant">NEEDS_TTASK</span>
<span class="definitionkeyword">enum</span> <span class="constant">ARCHIVE_TTASK</span>
<span class="definitionkeyword">enum</span> <span class="constant">ARCHIVE_TO_TTASK</span>
<span class="definitionkeyword">enum</span> <span class="constant">MISSING_TTASK</span>
<span class="definitionkeyword">enum</span> <span class="constant">BUILD_TTASK</span>
<span class="definitionkeyword">enum</span> <span class="constant">REBUILD_TTASK</span>
<span class="definitionkeyword">enum</span> <span class="constant">COPY_TO_TTASK</span>
<span class="definitionkeyword">enum</span> <span class="constant">SYNC_TO_TTASK</span>
</pre>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">inbuild_task</span><span class="plain"> = </span><span class="constant">INSPECT_TTASK</span><span class="plain">;</span>
<span class="reserved">pathname</span><span class="plain"> *</span><span class="identifier">path_to_inbuild</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">pathname</span><span class="plain"> *</span><span class="identifier">path_to_tools</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">inbuild_task</span><span class="plain"> = </span><span class="constant">INSPECT_TTASK</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">dry_run_mode</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">, </span><span class="identifier">build_trace_mode</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
<span class="reserved">linked_list</span><span class="plain"> *</span><span class="identifier">targets</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span> <span class="comment">of <code class="display"><span class="extract">inbuild_copy</span></code></span>
<span class="reserved">inbuild_nest</span><span class="plain"> *</span><span class="identifier">destination_nest</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">filter_text</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">unit_test</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">linked_list</span><span class="plain"> *</span><span class="identifier">inbuild_nest_list</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">main</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="functiontext">Foundation::start</span><span class="plain">();</span>
<span class="functiontext">WordsModule::start</span><span class="plain">();</span>
<span class="functiontext">SyntaxModule::start</span><span class="plain">();</span>
<span class="functiontext">HTMLModule::start</span><span class="plain">();</span>
<span class="functiontext">ArchModule::start</span><span class="plain">();</span>
<span class="functiontext">InbuildModule::start</span><span class="plain">();</span>
<span class="identifier">targets</span><span class="plain"> = </span><span class="identifier">NEW_LINKED_LIST</span><span class="plain">(</span><span class="reserved">inbuild_copy</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Read the command line</span> <span class="cwebmacronumber">1.2</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Str::len</span><span class="plain">(</span><span class="identifier">unit_test</span><span class="plain">) &gt; 0) </span><span class="identifier">dry_run_mode</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">use</span><span class="plain"> = </span><span class="constant">SHELL_METHODOLOGY</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">dry_run_mode</span><span class="plain">) </span><span class="identifier">use</span><span class="plain"> = </span><span class="constant">DRY_RUN_METHODOLOGY</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">if</span><span class="plain"> (</span><span class="identifier">path_to_tools</span><span class="plain">) </span><span class="identifier">BM</span><span class="plain"> = </span><span class="functiontext">BuildMethodology::new</span><span class="plain">(</span><span class="identifier">path_to_tools</span><span class="plain">, </span><span class="constant">FALSE</span><span class="plain">, </span><span class="identifier">use</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">BM</span><span class="plain"> = </span><span class="functiontext">BuildMethodology::new</span><span class="plain">(</span><span class="functiontext">Pathnames::up</span><span class="plain">(</span><span class="identifier">path_to_inbuild</span><span class="plain">), </span><span class="constant">TRUE</span><span class="plain">, </span><span class="identifier">use</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">build_trace_mode</span><span class="plain">) </span><span class="identifier">trace_ibg</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Str::len</span><span class="plain">(</span><span class="identifier">unit_test</span><span class="plain">) &gt; 0) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Str::eq</span><span class="plain">(</span><span class="identifier">unit_test</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"compatibility"</span><span class="plain">)) </span><span class="functiontext">Compatibility::test</span><span class="plain">(</span><span class="constant">STDOUT</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="functiontext">Errors::with_text</span><span class="plain">(</span><span class="string">"no such unit test: %S"</span><span class="plain">, </span><span class="identifier">unit_test</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">Str::len</span><span class="plain">(</span><span class="identifier">filter_text</span><span class="plain">) &gt; 0) {</span>
<span class="identifier">TEMPORARY_TEXT</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::from_text</span><span class="plain">(</span><span class="identifier">filter_text</span><span class="plain">, </span><span class="identifier">errors</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Str::len</span><span class="plain">(</span><span class="identifier">errors</span><span class="plain">) &gt; 0) {</span>
<span class="functiontext">Errors::with_text</span><span class="plain">(</span><span class="string">"requirement malformed: %S"</span><span class="plain">, </span><span class="identifier">errors</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">linked_list</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain"> = </span><span class="identifier">NEW_LINKED_LIST</span><span class="plain">(</span><span class="reserved">inbuild_search_result</span><span class="plain">);</span>
<span class="functiontext">Nests::search_for</span><span class="plain">(</span><span class="identifier">req</span><span class="plain">, </span><span class="identifier">inbuild_nest_list</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">);</span>
<span class="reserved">inbuild_search_result</span><span class="plain"> *</span><span class="identifier">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">ADD_TO_LINKED_LIST</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;copy</span><span class="plain">, </span><span class="reserved">inbuild_copy</span><span class="plain">, </span><span class="identifier">targets</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">errors</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">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="reserved">inbuild_copy</span><span class="plain">, </span><span class="identifier">targets</span><span class="plain">) {</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">inbuild_task</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">INSPECT_TTASK</span><span class="plain">: </span><span class="functiontext">Copies::inspect</span><span class="plain">(</span><span class="constant">STDOUT</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">GRAPH_TTASK</span><span class="plain">: </span><span class="functiontext">Copies::show_graph</span><span class="plain">(</span><span class="constant">STDOUT</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">NEEDS_TTASK</span><span class="plain">: </span><span class="functiontext">Copies::show_needs</span><span class="plain">(</span><span class="constant">STDOUT</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">ARCHIVE_TTASK</span><span class="plain">:</span>
<span class="identifier">destination_nest</span><span class="plain"> = </span><span class="functiontext">Inbuild::materials_nest</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">destination_nest</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)</span>
<span class="functiontext">Errors::with_text</span><span class="plain">(</span><span class="string">"no -project in use, so ignoring -archive"</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="reserved">else</span>
<span class="functiontext">Copies::archive</span><span class="plain">(</span><span class="constant">STDOUT</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">destination_nest</span><span class="plain">, </span><span class="identifier">BM</span><span class="plain">);</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">ARCHIVE_TO_TTASK</span><span class="plain">: </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">destination_nest</span><span class="plain">) </span><span class="functiontext">Copies::archive</span><span class="plain">(</span><span class="constant">STDOUT</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">destination_nest</span><span class="plain">, </span><span class="identifier">BM</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">MISSING_TTASK</span><span class="plain">: </span><span class="functiontext">Copies::show_missing</span><span class="plain">(</span><span class="constant">STDOUT</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">BUILD_TTASK</span><span class="plain">: </span><span class="functiontext">Copies::build</span><span class="plain">(</span><span class="constant">STDOUT</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">BM</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">REBUILD_TTASK</span><span class="plain">: </span><span class="functiontext">Copies::rebuild</span><span class="plain">(</span><span class="constant">STDOUT</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">BM</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">COPY_TO_TTASK</span><span class="plain">: </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">destination_nest</span><span class="plain">) </span><span class="functiontext">Nests::copy_to</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">destination_nest</span><span class="plain">, </span><span class="constant">FALSE</span><span class="plain">, </span><span class="identifier">BM</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">SYNC_TO_TTASK</span><span class="plain">: </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">destination_nest</span><span class="plain">) </span><span class="functiontext">Nests::copy_to</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">destination_nest</span><span class="plain">, </span><span class="constant">TRUE</span><span class="plain">, </span><span class="identifier">BM</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="functiontext">ArchModule::end</span><span class="plain">();</span>
<span class="functiontext">InbuildModule::end</span><span class="plain">();</span>
<span class="functiontext">HTMLModule::end</span><span class="plain">();</span>
<span class="functiontext">SyntaxModule::end</span><span class="plain">();</span>
<span class="functiontext">WordsModule::end</span><span class="plain">();</span>
<span class="functiontext">Foundation::end</span><span class="plain">();</span>
&lt;<span class="cwebmacro">Start up the modules</span> <span class="cwebmacronumber">1.1</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Read the command line</span> <span class="cwebmacronumber">1.7</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Load the Preform grammar</span> <span class="cwebmacronumber">1.2</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Complete the list of targets</span> <span class="cwebmacronumber">1.3</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Act on the targets</span> <span class="cwebmacronumber">1.4</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Shut down the modules</span> <span class="cwebmacronumber">1.5</span>&gt;<span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> 0;</span>
<span class="plain">}</span>
</pre>
@ -162,16 +97,293 @@
<p class="endnote">The function main is used in 1/ic (<a href="1-ic.html#SP15">&#167;15</a>), 5/kts (<a href="5-kts.html#SP1">&#167;1</a>), 6/st (<a href="6-st.html#SP1">&#167;1</a>).</p>
<p class="inwebparagraph"><a id="SP1_1"></a><b>&#167;1.1. </b>We use Foundation to read the command line:
<p class="inwebparagraph"><a id="SP1_1"></a><b>&#167;1.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Start up the modules</span> <span class="cwebmacronumber">1.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="functiontext">Foundation::start</span><span class="plain">();</span>
<span class="functiontext">WordsModule::start</span><span class="plain">();</span>
<span class="functiontext">SyntaxModule::start</span><span class="plain">();</span>
<span class="functiontext">HTMLModule::start</span><span class="plain">();</span>
<span class="functiontext">ArchModule::start</span><span class="plain">();</span>
<span class="functiontext">InbuildModule::start</span><span class="plain">();</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP1">&#167;1</a>.</p>
<p class="inwebparagraph"><a id="SP1_2"></a><b>&#167;1.2. </b>Preform is the crowning jewel of the <code class="display"><span class="extract">words</span></code> module, and parses excerpts of
natural-language text against a "grammar". The <code class="display"><span class="extract">inform7</span></code> executable makes very
heavy-duty use of Preform, but we use a much coarser grammar, which simply
breaks down source text into sentences, headings and so on. That grammar is
stored in a file called <code class="display"><span class="extract">Syntax.preform</span></code> inside the installation of Inbuild,
which is why we need to have worked out <code class="display"><span class="extract">path_to_inbuild</span></code> (the pathname at
which we are installed) already. Once the following is run, Preform is ready
for use.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Load the Preform grammar</span> <span class="cwebmacronumber">1.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">pathname</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain"> = </span><span class="functiontext">Pathnames::subfolder</span><span class="plain">(</span><span class="identifier">path_to_inbuild</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Tangled"</span><span class="plain">);</span>
<span class="reserved">filename</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain"> = </span><span class="functiontext">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">"Syntax.preform"</span><span class="plain">);</span>
<span class="reserved">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain"> = </span><span class="functiontext">Preform::load_from_file</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">);</span>
<span class="functiontext">Preform::parse_preform</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">, </span><span class="constant">FALSE</span><span class="plain">);</span>
<span class="functiontext">CommandLine::play_back_log</span><span class="plain">();</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP1">&#167;1</a>.</p>
<p class="inwebparagraph"><a id="SP1_3"></a><b>&#167;1.3. </b>Targets can arise in three ways:
</p>
<ul class="items"><li>(1) They can be specified at the command line, either as bare names of files
or paths, or with <code class="display"><span class="extract">-contents-of D</span></code> for a directory <code class="display"><span class="extract">D</span></code>. By the time the code
in this paragraph runs, those targets are already in the list.
</li><li>(2) They can be specified by a search request <code class="display"><span class="extract">-matching R</span></code> where <code class="display"><span class="extract">R</span></code> is a
list of requirements to match. We now add anything found that way. (We didn't
do so when reading the command line because at that time the search path for
nests did not yet exist: it is created when <code class="display"><span class="extract">Inbuild::optioneering_complete</span></code>
is called.)
</li><li>(3) One copy is always special to Inbuild: the "project", usually an Inform
project bundle with a pathname like <code class="display"><span class="extract">Counterfeit Monkey.inform</span></code>. We go
through a little dance with <code class="display"><span class="extract">Inbuild::optioneering_complete</span></code> to ensure that
if a project is already in the target list, Inbuild will use that; and if not,
but the user has specified a project to Inbuild already with <code class="display"><span class="extract">-project</span></code> (a
command-line option recognised by <code class="display"><span class="extract">inbuild</span></code> but not by us), then we add that
to the target list. Tne net result is that however the user indicates interest
in an Inform project bundle, it becomes both the Inbuild current project, and
also a member of our target list. It follows that we cannot have two project
bundles in the target list, because they cannot both be the current project;
and to avoid the user being confused when only one is acted on, we throw an
error in this case.
</li></ul>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Complete the list of targets</span> <span class="cwebmacronumber">1.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">linked_list</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain"> = </span><span class="functiontext">Main::list_of_targets</span><span class="plain">();</span>
<span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">proj</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="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="reserved">inbuild_copy</span><span class="plain">, </span><span class="identifier">L</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;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="identifier">proj</span><span class="plain"> = </span><span class="identifier">C</span><span class="plain">;</span>
<span class="identifier">proj</span><span class="plain"> = </span><span class="functiontext">Inbuild::optioneering_complete</span><span class="plain">(</span><span class="identifier">proj</span><span class="plain">, </span><span class="constant">FALSE</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">proj</span><span class="plain">) </span><span class="functiontext">Main::add_target</span><span class="plain">(</span><span class="identifier">proj</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">count</span><span class="plain"> = 0;</span>
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="reserved">inbuild_copy</span><span class="plain">, </span><span class="identifier">L</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;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="identifier">count</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">count</span><span class="plain"> &gt; 1)</span>
<span class="functiontext">Errors::with_text</span><span class="plain">(</span><span class="string">"can only work on one project bundle at a time"</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="functiontext">Str::len</span><span class="plain">(</span><span class="identifier">filter_text</span><span class="plain">) &gt; 0) </span><span class="functiontext">Main::add_search_results_as_targets</span><span class="plain">(</span><span class="identifier">filter_text</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP1">&#167;1</a>.</p>
<p class="inwebparagraph"><a id="SP1_4"></a><b>&#167;1.4. </b>We make the function call <code class="display"><span class="extract">Inbuild::go_operational</span></code> to signal to <code class="display"><span class="extract">inbuild</span></code>
that we want to start work now.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Act on the targets</span> <span class="cwebmacronumber">1.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="functiontext">Inbuild::go_operational</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Str::len</span><span class="plain">(</span><span class="identifier">unit_test</span><span class="plain">) &gt; 0) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Str::eq</span><span class="plain">(</span><span class="identifier">unit_test</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"compatibility"</span><span class="plain">)) </span><span class="functiontext">Compatibility::test</span><span class="plain">(</span><span class="constant">STDOUT</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="functiontext">Errors::with_text</span><span class="plain">(</span><span class="string">"no such unit test: %S"</span><span class="plain">, </span><span class="identifier">unit_test</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">use</span><span class="plain"> = </span><span class="constant">SHELL_METHODOLOGY</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">dry_run_mode</span><span class="plain">) </span><span class="identifier">use</span><span class="plain"> = </span><span class="constant">DRY_RUN_METHODOLOGY</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">if</span><span class="plain"> (</span><span class="identifier">path_to_tools</span><span class="plain">) </span><span class="identifier">BM</span><span class="plain"> = </span><span class="functiontext">BuildMethodology::new</span><span class="plain">(</span><span class="identifier">path_to_tools</span><span class="plain">, </span><span class="constant">FALSE</span><span class="plain">, </span><span class="identifier">use</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">BM</span><span class="plain"> = </span><span class="functiontext">BuildMethodology::new</span><span class="plain">(</span><span class="functiontext">Pathnames::up</span><span class="plain">(</span><span class="identifier">path_to_inbuild</span><span class="plain">), </span><span class="constant">TRUE</span><span class="plain">, </span><span class="identifier">use</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">build_trace_mode</span><span class="plain">) </span><span class="identifier">trace_ibg</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">;</span>
<span class="reserved">linked_list</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain"> = </span><span class="functiontext">Main::list_of_targets</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_LINKED_LIST</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="reserved">inbuild_copy</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">)</span>
&lt;<span class="cwebmacro">Carry out the required task on the copy C</span> <span class="cwebmacronumber">1.4.2</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP1">&#167;1</a>.</p>
<p class="inwebparagraph"><a id="SP1_4_1"></a><b>&#167;1.4.1. </b>The list of possible tasks is as follows; they basically all correspond to
utility functions in the <code class="display"><span class="extract">inbuild</span></code> module, which we call.
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">INSPECT_TTASK</span><span class="definitionkeyword"> from </span><span class="constant">1</span>
<span class="definitionkeyword">enum</span> <span class="constant">GRAPH_TTASK</span>
<span class="definitionkeyword">enum</span> <span class="constant">USE_NEEDS_TTASK</span>
<span class="definitionkeyword">enum</span> <span class="constant">BUILD_NEEDS_TTASK</span>
<span class="definitionkeyword">enum</span> <span class="constant">ARCHIVE_TTASK</span>
<span class="definitionkeyword">enum</span> <span class="constant">ARCHIVE_TO_TTASK</span>
<span class="definitionkeyword">enum</span> <span class="constant">USE_MISSING_TTASK</span>
<span class="definitionkeyword">enum</span> <span class="constant">BUILD_MISSING_TTASK</span>
<span class="definitionkeyword">enum</span> <span class="constant">BUILD_TTASK</span>
<span class="definitionkeyword">enum</span> <span class="constant">REBUILD_TTASK</span>
<span class="definitionkeyword">enum</span> <span class="constant">COPY_TO_TTASK</span>
<span class="definitionkeyword">enum</span> <span class="constant">SYNC_TO_TTASK</span>
</pre>
<p class="inwebparagraph"><a id="SP1_4_2"></a><b>&#167;1.4.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Carry out the required task on the copy C</span> <span class="cwebmacronumber">1.4.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">inbuild_task</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">INSPECT_TTASK</span><span class="plain">: </span><span class="functiontext">Copies::inspect</span><span class="plain">(</span><span class="constant">STDOUT</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">GRAPH_TTASK</span><span class="plain">: </span><span class="functiontext">Copies::show_graph</span><span class="plain">(</span><span class="constant">STDOUT</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">USE_NEEDS_TTASK</span><span class="plain">: </span><span class="functiontext">Copies::show_needs</span><span class="plain">(</span><span class="constant">STDOUT</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">, </span><span class="constant">TRUE</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">BUILD_NEEDS_TTASK</span><span class="plain">: </span><span class="functiontext">Copies::show_needs</span><span class="plain">(</span><span class="constant">STDOUT</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">, </span><span class="constant">FALSE</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">ARCHIVE_TTASK</span><span class="plain">:</span>
<span class="identifier">destination_nest</span><span class="plain"> = </span><span class="functiontext">Inbuild::materials_nest</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">destination_nest</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)</span>
<span class="functiontext">Errors::with_text</span><span class="plain">(</span><span class="string">"no -project in use, so ignoring -archive"</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="reserved">else</span>
<span class="functiontext">Copies::archive</span><span class="plain">(</span><span class="constant">STDOUT</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">destination_nest</span><span class="plain">, </span><span class="identifier">BM</span><span class="plain">);</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">ARCHIVE_TO_TTASK</span><span class="plain">: </span><span class="functiontext">Copies::archive</span><span class="plain">(</span><span class="constant">STDOUT</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">destination_nest</span><span class="plain">, </span><span class="identifier">BM</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">USE_MISSING_TTASK</span><span class="plain">: </span><span class="functiontext">Copies::show_missing</span><span class="plain">(</span><span class="constant">STDOUT</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">, </span><span class="constant">TRUE</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">BUILD_MISSING_TTASK</span><span class="plain">: </span><span class="functiontext">Copies::show_missing</span><span class="plain">(</span><span class="constant">STDOUT</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">, </span><span class="constant">FALSE</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">BUILD_TTASK</span><span class="plain">: </span><span class="functiontext">Copies::build</span><span class="plain">(</span><span class="constant">STDOUT</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">BM</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">REBUILD_TTASK</span><span class="plain">: </span><span class="functiontext">Copies::rebuild</span><span class="plain">(</span><span class="constant">STDOUT</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">BM</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">COPY_TO_TTASK</span><span class="plain">: </span><span class="functiontext">Nests::copy_to</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">destination_nest</span><span class="plain">, </span><span class="constant">FALSE</span><span class="plain">, </span><span class="identifier">BM</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">SYNC_TO_TTASK</span><span class="plain">: </span><span class="functiontext">Nests::copy_to</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">destination_nest</span><span class="plain">, </span><span class="constant">TRUE</span><span class="plain">, </span><span class="identifier">BM</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP1_4">&#167;1.4</a>.</p>
<p class="inwebparagraph"><a id="SP1_5"></a><b>&#167;1.5. </b><code class="display">
&lt;<span class="cwebmacrodefn">Shut down the modules</span> <span class="cwebmacronumber">1.5</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="functiontext">ArchModule::end</span><span class="plain">();</span>
<span class="functiontext">InbuildModule::end</span><span class="plain">();</span>
<span class="functiontext">HTMLModule::end</span><span class="plain">();</span>
<span class="functiontext">SyntaxModule::end</span><span class="plain">();</span>
<span class="functiontext">WordsModule::end</span><span class="plain">();</span>
<span class="functiontext">Foundation::end</span><span class="plain">();</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP1">&#167;1</a>.</p>
<p class="inwebparagraph"><a id="SP1_6"></a><b>&#167;1.6. Target list. </b>This where we keep the list of targets, in which no copy occurs more than
once. The following code runs quadratically in the number of targets, but for
Inbuild this number is never likely to be more than about 100 at a time.
</p>
<pre class="display">
<span class="reserved">linked_list</span><span class="plain"> *</span><span class="identifier">targets</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span> <span class="comment">of <code class="display"><span class="extract">inbuild_copy</span></code></span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Main::add_target</span><span class="plain">(</span><span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">to_add</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">targets</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">targets</span><span class="plain"> = </span><span class="identifier">NEW_LINKED_LIST</span><span class="plain">(</span><span class="reserved">inbuild_copy</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">found</span><span class="plain"> = </span><span class="constant">FALSE</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_LINKED_LIST</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="reserved">inbuild_copy</span><span class="plain">, </span><span class="identifier">targets</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">to_add</span><span class="plain">)</span>
<span class="identifier">found</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">found</span><span class="plain"> == </span><span class="constant">FALSE</span><span class="plain">) </span><span class="identifier">ADD_TO_LINKED_LIST</span><span class="plain">(</span><span class="identifier">to_add</span><span class="plain">, </span><span class="reserved">inbuild_copy</span><span class="plain">, </span><span class="identifier">targets</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">linked_list</span><span class="plain"> *</span><span class="functiontext">Main::list_of_targets</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">targets</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">targets</span><span class="plain"> = </span><span class="identifier">NEW_LINKED_LIST</span><span class="plain">(</span><span class="reserved">inbuild_copy</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">targets</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Main::add_search_results_as_targets</span><span class="plain">(</span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">req_text</span><span class="plain">) {</span>
<span class="identifier">TEMPORARY_TEXT</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::from_text</span><span class="plain">(</span><span class="identifier">req_text</span><span class="plain">, </span><span class="identifier">errors</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Str::len</span><span class="plain">(</span><span class="identifier">errors</span><span class="plain">) &gt; 0) {</span>
<span class="functiontext">Errors::with_text</span><span class="plain">(</span><span class="string">"requirement malformed: %S"</span><span class="plain">, </span><span class="identifier">errors</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">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">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="functiontext">Main::add_target</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">-</span><span class="element">&gt;copy</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">errors</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Main::add_directory_contents_targets</span><span class="plain">(</span><span class="reserved">pathname</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain">) {</span>
<span class="reserved">scan_directory</span><span class="plain"> *</span><span class="identifier">D</span><span class="plain"> = </span><span class="functiontext">Directories::open</span><span class="plain">(</span><span class="identifier">P</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="functiontext">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="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">FILENAME</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">FILENAME</span><span class="plain">, </span><span class="string">"%p%c%S"</span><span class="plain">, </span><span class="identifier">P</span><span class="plain">, </span><span class="constant">FOLDER_SEPARATOR</span><span class="plain">, </span><span class="identifier">LEAFNAME</span><span class="plain">);</span>
<span class="functiontext">Main::add_file_or_path_as_target</span><span class="plain">(</span><span class="identifier">FILENAME</span><span class="plain">, </span><span class="constant">FALSE</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">FILENAME</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="functiontext">Directories::close</span><span class="plain">(</span><span class="identifier">D</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Main::add_file_or_path_as_target</span><span class="plain">(</span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">arg</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">throwing_error</span><span class="plain">) {</span>
<span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain"> = </span><span class="functiontext">Copies::claim</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">C</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">throwing_error</span><span class="plain">) </span><span class="functiontext">Errors::with_text</span><span class="plain">(</span><span class="string">"unable to identify '%S'"</span><span class="plain">, </span><span class="identifier">arg</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="functiontext">Main::add_target</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 Main::add_target is used in <a href="#SP1_3">&#167;1.3</a>.</p>
<p class="endnote">The function Main::list_of_targets is used in <a href="#SP1_3">&#167;1.3</a>, <a href="#SP1_4">&#167;1.4</a>.</p>
<p class="endnote">The function Main::add_search_results_as_targets is used in <a href="#SP1_3">&#167;1.3</a>.</p>
<p class="endnote">The function Main::add_directory_contents_targets is used in <a href="#SP2">&#167;2</a>.</p>
<p class="endnote">The function Main::add_file_or_path_as_target is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP1_7"></a><b>&#167;1.7. Command line. </b>Note the call below to <code class="display"><span class="extract">Inbuild::declare_options</span></code>, which adds a whole lot of
other options to the selection defined here.
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">INTOOL_NAME</span><span class="plain"> </span><span class="string">"inbuild"</span>
<span class="definitionkeyword">enum</span> <span class="constant">BUILD_CLSW</span>
<span class="definitionkeyword">enum</span> <span class="constant">REBUILD_CLSW</span>
<span class="definitionkeyword">enum</span> <span class="constant">GRAPH_CLSW</span>
<span class="definitionkeyword">enum</span> <span class="constant">NEEDS_CLSW</span>
<span class="definitionkeyword">enum</span> <span class="constant">MISSING_CLSW</span>
<span class="definitionkeyword">enum</span> <span class="constant">USE_NEEDS_CLSW</span>
<span class="definitionkeyword">enum</span> <span class="constant">BUILD_NEEDS_CLSW</span>
<span class="definitionkeyword">enum</span> <span class="constant">USE_MISSING_CLSW</span>
<span class="definitionkeyword">enum</span> <span class="constant">BUILD_MISSING_CLSW</span>
<span class="definitionkeyword">enum</span> <span class="constant">ARCHIVE_CLSW</span>
<span class="definitionkeyword">enum</span> <span class="constant">ARCHIVE_TO_CLSW</span>
<span class="definitionkeyword">enum</span> <span class="constant">INSPECT_CLSW</span>
@ -184,8 +396,9 @@
<span class="definitionkeyword">enum</span> <span class="constant">SYNC_TO_CLSW</span>
<span class="definitionkeyword">enum</span> <span class="constant">UNIT_TEST_CLSW</span>
</pre>
<p class="inwebparagraph"><a id="SP1_2"></a><b>&#167;1.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Read the command line</span> <span class="cwebmacronumber">1.2</span>&gt; =
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Read the command line</span> <span class="cwebmacronumber">1.7</span>&gt; =
</code></p>
@ -205,10 +418,14 @@
<span class="identifier">L</span><span class="string">"show target(s) but take no action"</span><span class="plain">);</span>
<span class="functiontext">CommandLine::declare_switch</span><span class="plain">(</span><span class="constant">GRAPH_CLSW</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"graph"</span><span class="plain">, 1,</span>
<span class="identifier">L</span><span class="string">"show dependency graph of target(s) but take no action"</span><span class="plain">);</span>
<span class="functiontext">CommandLine::declare_switch</span><span class="plain">(</span><span class="constant">NEEDS_CLSW</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"needs"</span><span class="plain">, 1,</span>
<span class="functiontext">CommandLine::declare_switch</span><span class="plain">(</span><span class="constant">USE_NEEDS_CLSW</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"use-needs"</span><span class="plain">, 1,</span>
<span class="identifier">L</span><span class="string">"show all the extensions, kits and so on needed to use"</span><span class="plain">);</span>
<span class="functiontext">CommandLine::declare_switch</span><span class="plain">(</span><span class="constant">BUILD_NEEDS_CLSW</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"build-needs"</span><span class="plain">, 1,</span>
<span class="identifier">L</span><span class="string">"show all the extensions, kits and so on needed to build"</span><span class="plain">);</span>
<span class="functiontext">CommandLine::declare_switch</span><span class="plain">(</span><span class="constant">MISSING_CLSW</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"missing"</span><span class="plain">, 1,</span>
<span class="identifier">L</span><span class="string">"show the extensions, kits and so on which are needed but missing"</span><span class="plain">);</span>
<span class="functiontext">CommandLine::declare_switch</span><span class="plain">(</span><span class="constant">USE_MISSING_CLSW</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"use-missing"</span><span class="plain">, 1,</span>
<span class="identifier">L</span><span class="string">"show the extensions, kits and so on which are needed to use but missing"</span><span class="plain">);</span>
<span class="functiontext">CommandLine::declare_switch</span><span class="plain">(</span><span class="constant">BUILD_MISSING_CLSW</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"build-missing"</span><span class="plain">, 1,</span>
<span class="identifier">L</span><span class="string">"show the extensions, kits and so on which are needed to build but missing"</span><span class="plain">);</span>
<span class="functiontext">CommandLine::declare_switch</span><span class="plain">(</span><span class="constant">ARCHIVE_CLSW</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"archive"</span><span class="plain">, 1,</span>
<span class="identifier">L</span><span class="string">"sync copies of all extensions, kits and so on needed for -project into Materials"</span><span class="plain">);</span>
<span class="functiontext">CommandLine::declare_switch</span><span class="plain">(</span><span class="constant">ARCHIVE_TO_CLSW</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"archive-to"</span><span class="plain">, 2,</span>
@ -234,38 +451,14 @@
<span class="functiontext">Pathnames::from_text</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"inform7/Internal"</span><span class="plain">), </span><span class="constant">INTERNAL_NEST_TAG</span><span class="plain">);</span>
<span class="identifier">path_to_inbuild</span><span class="plain"> = </span><span class="functiontext">Pathnames::installation_path</span><span class="plain">(</span><span class="string">"INBUILD_PATH"</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"inbuild"</span><span class="plain">);</span>
<span class="reserved">pathname</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain"> = </span><span class="functiontext">Pathnames::subfolder</span><span class="plain">(</span><span class="identifier">path_to_inbuild</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Tangled"</span><span class="plain">);</span>
<span class="reserved">filename</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain"> = </span><span class="functiontext">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">"Syntax.preform"</span><span class="plain">);</span>
<span class="reserved">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain"> = </span><span class="functiontext">Preform::load_from_file</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">);</span>
<span class="functiontext">Preform::parse_preform</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">, </span><span class="constant">FALSE</span><span class="plain">);</span>
<span class="functiontext">CommandLine::play_back_log</span><span class="plain">();</span>
<span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">proj</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="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="reserved">inbuild_copy</span><span class="plain">, </span><span class="identifier">targets</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;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">if</span><span class="plain"> (</span><span class="functiontext">Str::len</span><span class="plain">(</span><span class="identifier">project_bundle_request</span><span class="plain">) &gt; 0)</span>
<span class="functiontext">Errors::with_text</span><span class="plain">(</span><span class="string">"can only work on one project bundle at a time, so ignoring '%S'"</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">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">proj</span><span class="plain">) </span><span class="functiontext">Errors::with_text</span><span class="plain">(</span><span class="string">"can only work on one project bundle at a time, so ignoring '%S'"</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">else</span><span class="plain"> </span><span class="identifier">proj</span><span class="plain"> = </span><span class="identifier">C</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">proj</span><span class="plain"> = </span><span class="functiontext">Inbuild::optioneering_complete</span><span class="plain">(</span><span class="identifier">proj</span><span class="plain">, </span><span class="constant">FALSE</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">proj</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">found</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="reserved">inbuild_copy</span><span class="plain">, </span><span class="identifier">targets</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">proj</span><span class="plain">)</span>
<span class="identifier">found</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">found</span><span class="plain"> == </span><span class="constant">FALSE</span><span class="plain">) </span><span class="identifier">ADD_TO_LINKED_LIST</span><span class="plain">(</span><span class="identifier">proj</span><span class="plain">, </span><span class="reserved">inbuild_copy</span><span class="plain">, </span><span class="identifier">targets</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">inbuild_nest_list</span><span class="plain"> = </span><span class="functiontext">Inbuild::nest_list</span><span class="plain">();</span>
<span class="functiontext">Inbuild::go_operational</span><span class="plain">();</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP1">&#167;1</a>.</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b></p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>Here we handle those options not handled by the <code class="display"><span class="extract">inbuild</span></code> module.
</p>
<pre class="display">
@ -275,18 +468,19 @@
<span class="reserved">case</span><span class="plain"> </span><span class="constant">REBUILD_CLSW</span><span class="plain">: </span><span class="identifier">inbuild_task</span><span class="plain"> = </span><span class="constant">REBUILD_TTASK</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">INSPECT_CLSW</span><span class="plain">: </span><span class="identifier">inbuild_task</span><span class="plain"> = </span><span class="constant">INSPECT_TTASK</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">GRAPH_CLSW</span><span class="plain">: </span><span class="identifier">inbuild_task</span><span class="plain"> = </span><span class="constant">GRAPH_TTASK</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">NEEDS_CLSW</span><span class="plain">: </span><span class="identifier">inbuild_task</span><span class="plain"> = </span><span class="constant">NEEDS_TTASK</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">USE_NEEDS_CLSW</span><span class="plain">: </span><span class="identifier">inbuild_task</span><span class="plain"> = </span><span class="constant">USE_NEEDS_TTASK</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">BUILD_NEEDS_CLSW</span><span class="plain">: </span><span class="identifier">inbuild_task</span><span class="plain"> = </span><span class="constant">BUILD_NEEDS_TTASK</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">ARCHIVE_TO_CLSW</span><span class="plain">:</span>
<span class="identifier">destination_nest</span><span class="plain"> = </span><span class="functiontext">Nests::new</span><span class="plain">(</span><span class="functiontext">Pathnames::from_text</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">));</span>
<span class="identifier">inbuild_task</span><span class="plain"> = </span><span class="constant">ARCHIVE_TO_TTASK</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">ARCHIVE_CLSW</span><span class="plain">:</span>
<span class="identifier">inbuild_task</span><span class="plain"> = </span><span class="constant">ARCHIVE_TTASK</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">MISSING_CLSW</span><span class="plain">: </span><span class="identifier">inbuild_task</span><span class="plain"> = </span><span class="constant">MISSING_TTASK</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">ARCHIVE_CLSW</span><span class="plain">: </span><span class="identifier">inbuild_task</span><span class="plain"> = </span><span class="constant">ARCHIVE_TTASK</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">USE_MISSING_CLSW</span><span class="plain">: </span><span class="identifier">inbuild_task</span><span class="plain"> = </span><span class="constant">USE_MISSING_TTASK</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">BUILD_MISSING_CLSW</span><span class="plain">: </span><span class="identifier">inbuild_task</span><span class="plain"> = </span><span class="constant">BUILD_MISSING_TTASK</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">TOOLS_CLSW</span><span class="plain">: </span><span class="identifier">path_to_tools</span><span class="plain"> = </span><span class="functiontext">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">MATCHING_CLSW</span><span class="plain">: </span><span class="identifier">filter_text</span><span class="plain"> = </span><span class="functiontext">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">CONTENTS_OF_CLSW</span><span class="plain">: </span><span class="functiontext">Main::load_many</span><span class="plain">(</span><span class="functiontext">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">CONTENTS_OF_CLSW</span><span class="plain">:</span>
<span class="functiontext">Main::add_directory_contents_targets</span><span class="plain">(</span><span class="functiontext">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">DRY_CLSW</span><span class="plain">: </span><span class="identifier">dry_run_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">BUILD_TRACE_CLSW</span><span class="plain">: </span><span class="identifier">build_trace_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">COPY_TO_CLSW</span><span class="plain">: </span><span class="identifier">inbuild_task</span><span class="plain"> = </span><span class="constant">COPY_TO_TTASK</span><span class="plain">;</span>
@ -299,68 +493,45 @@
<span class="plain">}</span>
<span class="functiontext">Inbuild::option</span><span class="plain">(</span><span class="identifier">id</span><span class="plain">, </span><span class="identifier">val</span><span class="plain">, </span><span class="identifier">arg</span><span class="plain">, </span><span class="identifier">state</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Main::option is used in <a href="#SP1_7">&#167;1.7</a>.</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>This is called for a command-line argument which doesn't appear as
subordinate to any switch; we take it as the name of a copy.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Main::bareword</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">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="functiontext">Main::load_one</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">, </span><span class="constant">TRUE</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Main::load_many</span><span class="plain">(</span><span class="reserved">pathname</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain">) {</span>
<span class="reserved">scan_directory</span><span class="plain"> *</span><span class="identifier">D</span><span class="plain"> = </span><span class="functiontext">Directories::open</span><span class="plain">(</span><span class="identifier">P</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="functiontext">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="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">FILENAME</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">FILENAME</span><span class="plain">, </span><span class="string">"%p%c%S"</span><span class="plain">, </span><span class="identifier">P</span><span class="plain">, </span><span class="constant">FOLDER_SEPARATOR</span><span class="plain">, </span><span class="identifier">LEAFNAME</span><span class="plain">);</span>
<span class="functiontext">Main::load_one</span><span class="plain">(</span><span class="identifier">FILENAME</span><span class="plain">, </span><span class="constant">FALSE</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">FILENAME</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="functiontext">Directories::close</span><span class="plain">(</span><span class="identifier">D</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Main::load_one</span><span class="plain">(</span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">arg</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">throwing_error</span><span class="plain">) {</span>
<span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain"> = </span><span class="functiontext">Copies::claim</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">C</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">throwing_error</span><span class="plain">) </span><span class="functiontext">Errors::with_text</span><span class="plain">(</span><span class="string">"unable to identify '%S'"</span><span class="plain">, </span><span class="identifier">arg</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">ADD_TO_LINKED_LIST</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="reserved">inbuild_copy</span><span class="plain">, </span><span class="identifier">targets</span><span class="plain">);</span>
<span class="functiontext">Main::add_file_or_path_as_target</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">, </span><span class="constant">TRUE</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Main::option is used in <a href="#SP1_2">&#167;1.2</a>.</p>
<p class="endnote">The function Main::bareword is used in <a href="#SP1_7">&#167;1.7</a>.</p>
<p class="endnote">The function Main::bareword is used in <a href="#SP1_2">&#167;1.2</a>.</p>
<p class="endnote">The function Main::load_many appears nowhere else.</p>
<p class="endnote">The function Main::load_one appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>Since we want to include the words module, we have to define the following
structure and initialiser:
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. Interface to Words module. </b>Since we want to include the <code class="display"><span class="extract">words</span></code> module, we have to define the following
structure and initialiser. The type <code class="display"><span class="extract">vocabulary_meaning</span></code> is expected to hold
meanings associated with a given word; when <code class="display"><span class="extract">inform7</span></code> uses <code class="display"><span class="extract">word</span></code> it is rich
and full of significance, but for us it does nothing. We give it a meaningless
integer as its content, since in C it isn't legal to have an empty <code class="display"><span class="extract">struct</span></code>.
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">VOCABULARY_MEANING_INITIALISER</span><span class="plain"> </span><span class="functiontext">Main::ignore</span>
<span class="definitionkeyword">define</span> <span class="constant">VOCABULARY_MEANING_INITIALISER</span><span class="plain"> </span><span class="functiontext">Main::create_meaningless_vm</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">vocabulary_meaning</span><span class="plain"> {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">enigmatic_number</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">vocabulary_meaning</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The structure vocabulary_meaning is private to this section.</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b></p>
<pre class="display">
<span class="reserved">vocabulary_meaning</span><span class="plain"> </span><span class="functiontext">Main::ignore</span><span class="plain">(</span><span class="reserved">vocabulary_entry</span><span class="plain"> *</span><span class="identifier">ve</span><span class="plain">) {</span>
<span class="reserved">vocabulary_meaning</span><span class="plain"> </span><span class="functiontext">Main::create_meaningless_vm</span><span class="plain">(</span><span class="reserved">vocabulary_entry</span><span class="plain"> *</span><span class="identifier">ve</span><span class="plain">) {</span>
<span class="reserved">vocabulary_meaning</span><span class="plain"> </span><span class="identifier">vm</span><span class="plain">;</span>
<span class="identifier">vm</span><span class="element">.enigmatic_number</span><span class="plain"> = 90125;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">vm</span><span class="plain">;</span>
@ -369,30 +540,28 @@ structure and initialiser:
<p class="inwebparagraph"></p>
<p class="endnote">The function Main::ignore appears nowhere else.</p>
<p class="endnote">The function Main::create_meaningless_vm appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b></p>
<p class="endnote">The structure vocabulary_meaning is private to this section.</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b>We use the mighty Preform natural-language parser only a little when
Inbuild runs on its own, but it needs to be told what C type to use when
identifying natural languages.
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">PREFORM_LANGUAGE_TYPE</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">inform_language</span>
</pre>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. Interface to Syntax module. </b>Again, we make a fairly light use of <code class="display"><span class="extract">syntax</span></code> when Inbuild runs alone.
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">PREFORM_LANGUAGE_TYPE</span><span class="plain"> </span><span class="reserved">void</span>
<span class="definitionkeyword">define</span> <span class="constant">PARSE_TREE_TRAVERSE_TYPE</span><span class="plain"> </span><span class="reserved">void</span>
<span class="definitionkeyword">define</span> <span class="constant">SENTENCE_NODE</span><span class="plain"> </span><span class="functiontext">Main::sentence_level</span>
<span class="definitionkeyword">define</span> <span class="constant">PARSE_TREE_METADATA_SETUP</span><span class="plain"> </span><span class="functiontext">SourceText::node_metadata</span>
</pre>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Main::sentence_level</span><span class="plain">(</span><span class="constant">node_type_t</span><span class="plain"> </span><span class="identifier">t</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="constant">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Main::sentence_level appears nowhere else.</p>
<hr class="tocbar">
<ul class="toc"><li><i>(This section begins Chapter 1: Delegation.)</i></li><li><i>(This section ends Chapter 1: Delegation.)</i></li></ul><hr class="tocbar">
<!--End of weave-->
</main>
</body>

View file

@ -57,13 +57,663 @@
<main role="main">
<!--Weave of 'M/ui' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">Source</a></li><li><a href="../compiler.html">Compiler Tools</a></li><li><a href="index.html">inbuild</a></li><li><a href="index.html#M">Manual</a></li><li><b>Using Inbuild</b></li></ul><p class="purpose">A brief user guide.</p>
<ul class="crumbs"><li><a href="../webs.html">Source</a></li><li><a href="../compiler.html">Compiler Tools</a></li><li><a href="index.html">inbuild</a></li><li><a href="index.html#M">Manual</a></li><li><b>Using Inbuild</b></li></ul><p class="purpose">An introduction to the use of Inbuild on the command line.</p>
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. </b>Inbuild is a rudimentary build and package manager for the Inform tools.
<ul class="toc"><li><a href="#SP1">&#167;1. What Inbuild is</a></li><li><a href="#SP2">&#167;2. Installation</a></li><li><a href="#SP3">&#167;3. Basic concepts</a></li><li><a href="#SP5">&#167;5. Graphs</a></li><li><a href="#SP10">&#167;10. Building</a></li><li><a href="#SP12">&#167;12. Specifying what to act on</a></li><li><a href="#SP14">&#167;14. Nests and searches</a></li><li><a href="#SP17">&#167;17. Copy, sync and archive</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. What Inbuild is. </b>Inbuild is a rudimentary build and package manager for the Inform tools.
It consists of a large part of the front end of the Inform 7 compiler,
together with a command-line interface to access its functions. Because
it doesn't contain the middle or back ends of Inform 7, it cannot itself
compile Inform projects. But it can issue shell commands which have
this effect. When used that way, it's a little like the traditional Unix
build tool <code class="display"><span class="extract">make</span></code>.
</p>
<p class="inwebparagraph">It can also be used in <code class="display"><span class="extract">make</span></code> scripts itself. Inbuild returns an exit code
of 0 if successful, or else it throws errors to <code class="display"><span class="extract">stderr</span></code> and returns 1
if unsuccessful.
</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. Installation. </b>When it runs, Inbuild needs to know where it is installed in the file
system. There is no completely foolproof, cross-platform way to know this
(on some Unixes, a program cannot determine its own location), so Inbuild
decides by the following set of rules:
</p>
<p class="inwebparagraph"></p>
<ul class="items"><li>(a) If the user, at the command line, specified <code class="display"><span class="extract">-at P</span></code>, for some path
<code class="display"><span class="extract">P</span></code>, then we use that.
</li><li>(b) Otherwise, if the host operating system can indeed tell us where the
executable is, we use that. This is currently implemented only on MacOS,
Windows and Linux.
</li><li>(c) Otherwise, if the environment variable <code class="display"><span class="extract">$INBUILD_PATH</span></code> exists and is
non-empty, we use that.
</li><li>(d) And if all else fails, we assume that the location is <code class="display"><span class="extract">inbuild</span></code>, with
respect to the current working directory.
</li></ul>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. Basic concepts. </b>Inbuild manages "copies". A copy is an instance in the file system of an
asset like an Inform project, an extension, a kit of Inter code, and so on.
Those categories are called "genres". Any given copy will be a copy of
what is called an "edition", which in turn is a version of a "work".
</p>
<p class="inwebparagraph">For example, perhaps the user has two copies of version 3 of the extension
Locksmith by Emily Short, in different places in the file system, and also
a further copy of version 4. These are three different "copies", but only two
different "editions", and all are of the same "work". A work &mdash; in this case.
Locksmith by Emily Short &mdash; is identified by its title, author name and
genre &mdash; in this case, an Inform extension.
</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>Inbuild has a plethora of command-line options, but at its most basic, the
user should specify what to do and then give a list of things to do it to.
For example, here we run <code class="display"><span class="extract">-inspect</span></code> on a single copy, and get a one-line
description of what it is:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">$ inbuild/Tangled/inbuild -inspect 'inform7/Internal/Extensions/Emily Short/Locksmith.i7x'</span>
<span class="plain">extension: Locksmith by Emily Short v12 in directory inform7/Internal/Extensions/Emily Short</span>
</pre>
<p class="inwebparagraph">This is reassuring &mdash; the file which looks as if it ought to be a copy of
Locksmith actually is. Inbuild always looks at the contents of something,
and doesn't trust its location as any indication of what it is. For
example:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">$ inbuild/Tangled/inbuild -inspect junk/Mystery.i7x</span>
<span class="plain">extension: Complex Listing by Emily Short v9 in directory junk.</span>
</pre>
<p class="inwebparagraph">If Inbuild can see that something is damaged in some way, it will report that.
For example,
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">extension: Skeleton Keys by Emily Short - 1 error</span>
<span class="plain"> 1. extension misworded: the opening line does not end 'begin(s) here'</span>
</pre>
<p class="inwebparagraph">Only superficial problems can be spotted so far in advance of actually using
the software, but it's still helpful.
</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. Graphs. </b>More ambitiously, we can look at the "graph" of a copy.
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">$ inbuild/Tangled/inbuild -graph 'Basic Help Menu.i7x'</span>
<span class="plain">[c0] Basic Help Menu by Emily Short</span>
<span class="plain"> --use---&gt; [c26] Menus by Emily Short v3</span>
<span class="plain"> --use---&gt; [c34] Basic Screen Effects by Emily Short v7.140425</span>
</pre>
<p class="inwebparagraph">The graph begins at the copy we asked for, and then continues through arrows
to other copies. It gives a systematic answer to the question "how do I
build or use this?". There are two kinds of arrows, use arrows and build
arrows. A use arrow from A to B means that you need to have B installed
in order to be able to use A. The above example, then, tells us that we
Menus in order to use Basic Help Menu, and we need Basic Screen Effects in
order to use Menus.
</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. </b>Now suppose we have an Inform project called <code class="display"><span class="extract">Menu Time.inform</span></code>, whose
source text is as follows:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">Include Basic Help Menu by Emily Short.</span>
<span class="plain">The French Laundry is a room.</span>
</pre>
<p class="inwebparagraph">Once again, we can inspect this:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">inbuild/Tangled/inbuild -inspect 'Menu Time.inform'</span>
<span class="plain">projectbundle: Menu Time.inform at path Menu Time.inform</span>
</pre>
<p class="inwebparagraph">We can also use <code class="display"><span class="extract">-graph</span></code>, but the output from this is surprisingly long,
because an innocent-looking source text like the above depends on many other
resources.
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">[f59] Menu Time.inform/Build/output.ulx</span>
<span class="plain"> --build-&gt; [f58] Menu Time.inform/Build/auto.inf</span>
<span class="plain"> --build-&gt; [f57] Menu Time.inform/Build/auto.inf</span>
<span class="plain"> --build-&gt; [c0] Menu Time.inform</span>
<span class="plain"> --build-&gt; [c53] Basic Help Menu by Emily Short</span>
<span class="plain"> --use---&gt; [c47] Menus by Emily Short v3</span>
<span class="plain"> --use---&gt; [c55] Basic Screen Effects by Emily Short v7.140425</span>
<span class="plain"> --build-&gt; [f1] Menu Time.inform/Source/story.ni</span>
<span class="plain"> --build-&gt; [c12] BasicInformKit</span>
</pre>
<p class="inwebparagraph">...and so on. What's going on here is that if the user wants to compile the
source text, that will (by default) mean making a story file in Glulx format,
called <code class="display"><span class="extract">output.ulx</span></code>, which sits inside the project bundle. So that is the top
node. Note that it is a "file node", not a "copy node", as we can see from the
<code class="display"><span class="extract">f</span></code> not <code class="display"><span class="extract">c</span></code> in its node number. This means that <code class="display"><span class="extract">output.ulx</span></code> is not a kind of
resource managed by Inbuild (like an extension, pr a project): it's just a
plain old file.
</p>
<p class="inwebparagraph">There's then a build arrow to another file called <code class="display"><span class="extract">auto.inf</span></code>. That's because
in order to build <code class="display"><span class="extract">output.ulx</span></code>, we first need <code class="display"><span class="extract">auto.inf</span></code> to exist. This is
a file in Inform 6 format. Something unexpected then happens: a further arrow
appears, and connects to another <code class="display"><span class="extract">auto.inf</span></code>. There aren't really two files
here: this is a device to capture the fact that generating <code class="display"><span class="extract">auto.inf</span></code> is a
two-stage process, with the intermediate results between the two stages
being held in memory rather than in a file. (These stages are, first,
converting I7 source text to inter code, and then code-generating that
inter code to I6.) Finally, though, we have a build arrow leading to the
place we might have expected to start: the <code class="display"><span class="extract">Menu Time.inform</span></code> project.
</p>
<p class="inwebparagraph">And that is where the graph branches outwards, because we need many
different resources in order to build <code class="display"><span class="extract">Menu Time.inform</span></code>. We finally see
that we need Basic Help Menu, and because that uses two other extensions
in turn, we'll need both of those as well. We need the actual file which
holds the source text inside the project bundle, <code class="display"><span class="extract">story.ni</span></code>. And then
we need various build-in extensions and kits, the first of which is
<code class="display"><span class="extract">BasicInformKit</span></code>, and that turns out to need lots of files to exist.
</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. </b>The full <code class="display"><span class="extract">-graph</span></code> is not always what we want to see. Often all we really
want to know is: what do I need to use, or to build, something?
</p>
<p class="inwebparagraph">The command <code class="display"><span class="extract">-use-needs</span></code> applied to our example extension gives:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">extension: Basic Help Menu by Emily Short</span>
<span class="plain"> extension: Menus by Emily Short v3</span>
<span class="plain"> extension: Basic Screen Effects by Emily Short v7.140425</span>
</pre>
<p class="inwebparagraph">and applied to our example story gives just:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">projectbundle: Menu Time.inform</span>
</pre>
<p class="inwebparagraph">That's because once Menu Time is built, nothing else is needed to use it.
On the other hand, <code class="display"><span class="extract">-build-needs</span></code> has the opposite effect. Applied to the
extension, we get:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">extension: Basic Help Menu by Emily Short</span>
</pre>
<p class="inwebparagraph">because extensions need no building, so certainly nothing else is needed
to build them. But <code class="display"><span class="extract">-build-needs</span></code> on our story produces:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">projectbundle: Menu Time.inform</span>
<span class="plain"> extension: Basic Help Menu by Emily Short</span>
<span class="plain"> extension: Menus by Emily Short v3</span>
<span class="plain"> extension: Basic Screen Effects by Emily Short v7.140425</span>
<span class="plain"> kit: BasicInformKit</span>
<span class="plain"> extension: Basic Inform by Graham Nelson v1</span>
<span class="plain"> extension: English Language by Graham Nelson v1</span>
<span class="plain"> kit: CommandParserKit</span>
<span class="plain"> kit: WorldModelKit</span>
<span class="plain"> extension: Standard Rules by Graham Nelson v6</span>
<span class="plain"> extension: Standard Rules by Graham Nelson v6</span>
<span class="plain"> language: English</span>
<span class="plain"> kit: EnglishLanguageKit</span>
<span class="plain"> extension: English Language by Graham Nelson v1</span>
</pre>
<p class="inwebparagraph">And there it is: six extensions, four kits and one natural language definition
are needed. Two of the extensions are listed twice: that's because they are
each needed for two different reasons.
</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. </b>The version numbers listed above do not mean that only those exact versions
will do: they mean that this is (the best) version Inbuild has access to.
They're given because two different versions of the same extension might
make different choices about which other extensions to include. We can say
that version 3 of Menus wants to have Basic Screen Effects, but maybe someday
tbere will be a version 4 which doesn't need it.
</p>
<p class="inwebparagraph">Another issue to watch out for is that a copy may use different other copies
when compiled to different virtual machines. For example, an extension can
contain a heading of material "for Glulx only", and that heading might
comtain a line which includes another extension X. If so, then we use X on
Glulx but not on other architectures. We can also flag materual as being for
release only, or for debugging only.
</p>
<p class="inwebparagraph">Inbuild accepts the same command-line options as <code class="display"><span class="extract">inform7</span></code> does to specify
these: <code class="display"><span class="extract">-debug</span></code> for debugging features, <code class="display"><span class="extract">-release</span></code> for a release run, and
<code class="display"><span class="extract">-format=X</span></code> to select a virtual machine. (See the <code class="display"><span class="extract">inform7</span></code> documentation.)
</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. </b>Now suppose that the project asks for something impossible, with a line
such as:
</p>
<blockquote>
<p>Include Xylophones by Jimmy Stewart.</p>
</blockquote>
<p class="inwebparagraph">No such extension exists. If we look at the graph, or the <code class="display"><span class="extract">-build-needs</span></code> list
for the project, we see that it includes:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">missing extension: Xylophones by Jimmy Stewart, any version will do</span>
</pre>
<p class="inwebparagraph">If we had instead written:
</p>
<blockquote>
<p>Include version 6.2 of Xylophones by Jimmy Stewart.</p>
</blockquote>
<p class="inwebparagraph">we would see:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">missing extension: Xylophones by Jimmy Stewart, need version in range [6.2,7-A)</span>
</pre>
<p class="inwebparagraph">This slightly arcane mathematical notation means that Inform would accept any
version from 6.2 upwards, provided it still begins with a 6. This is a change
over pre-2020 versions of Inform, and has been brought about by the adoption
of the semantic version number standard.
</p>
<p class="inwebparagraph">Inbuild can list missing resources with <code class="display"><span class="extract">-use-missing</span></code> and <code class="display"><span class="extract">-build-missing</span></code>
respectively. At present, it has no means of fetching missing resources from
any central repository.
</p>
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. Building. </b>The graph for a copy tells Inbuild not only what is necessary for a build,
but also how to perform that build.
</p>
<p class="inwebparagraph">As noted above, not everything needs building. Extensions do not, in particular,
so running <code class="display"><span class="extract">-build</span></code> on one will do nothing. Kits do need building: what this
does is to "assimilate" the Unform 6-notation source files inside the kit into
binary files of Inter, one for each possible architecture.
</p>
<p class="inwebparagraph">But building is mostly done with projects. If we run:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">$ inbuild/Tangled/inbuild -build Example.inform</span>
</pre>
<p class="inwebparagraph">then Inbuild will first build everthing needed to build the Example story
file, including everything needed to use the things needed to build it, and
so on; and then will build Example itself. As with the Unix utility <code class="display"><span class="extract">make</span></code>,
this is an incremental process, and looks at the timestamps of files to see
which steps are needed and which are not. If all the kits needed by Example
are up to date, then the kits will not be re-assimilated, and so on. If the
same project is built twice in a row, and nothing about it has changed since
the first time, the second <code class="display"><span class="extract">-build</span></code> does nothing.
</p>
<p class="inwebparagraph">Inbuild uses the graph to work out what needs to be done, and then issues
a series of shell commands to other Inform tools. If any of those commands
fail (returning a non-zero exit code) then the build process halts at once.
</p>
<p class="inwebparagraph">As noted above, the <code class="display"><span class="extract">-release</span></code> switch tells Inbuild that we want to go all
the way to a release of the project, not just a build. This makes a more
extensive graph, and is likely to mean that the final step followed by
Inbuild is a call to <code class="display"><span class="extract">inblorb</span></code>, the releasing tool for Inform.
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">$ inbuild/Tangled/inbuild -release -build Example.inform</span>
</pre>
<p class="inwebparagraph">Using the <code class="display"><span class="extract">-rebuild</span></code> command performs a build in a way which isn't incremental:
timestamps of files are ignored and everything is remade from scratch.
</p>
<p class="inwebparagraph"><a id="SP11"></a><b>&#167;11. </b>It takes a certain trust to just let Inbuild rip, and if you don't feel that
trust, adding the <code class="display"><span class="extract">-dry</span></code> switch causes shell commands to be printed out but
not actually executed &mdash; a dry run. If you are debugging Inbuild, you may
also want to look at the copious output produced when <code class="display"><span class="extract">-build-trace</span></code> is used.
These are not commands: they simply modify the behaviour of <code class="display"><span class="extract">-build</span></code> and
<code class="display"><span class="extract">-rebuild</span></code>.
</p>
<p class="inwebparagraph">Inbuild uses a handful of standard Unix shell commands, but it also uses
<code class="display"><span class="extract">inform7</span></code>, <code class="display"><span class="extract">inform6</span></code>, <code class="display"><span class="extract">inblorb</span></code> and <code class="display"><span class="extract">inter</span></code>. To do that, it needs to know
where they are installed. By default, Inbuild assumes they are in the same
folder as Inbuild itself, side by side. If not, you can use <code class="display"><span class="extract">-tools P</span></code> to
specify path <code class="display"><span class="extract">P</span></code> as the home of the other Intools.
</p>
<p class="inwebparagraph"><a id="SP12"></a><b>&#167;12. Specifying what to act on. </b>In all of the examples above, Inbuild is given just one copy to act on.
(That action may end up invplving lots of other copies, but only one is
mentioned on the command line.) In fact it's legal to give a list of
copies to work on, one at a time, except that only one of those copies
can be an Inform project. Multiple extensions, or kits, are fine.
</p>
<p class="inwebparagraph">We can also tell Inbuild to work on everything it finds in a given directory
<code class="display"><span class="extract">D</span></code> using <code class="display"><span class="extract">-contents-of D</span></code>:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">$ inbuild/Tangled/inbuild -inspect -contents-of inform7/Internal/Inter</span>
<span class="plain">kit: EnglishLanguageKit at path inform7/Internal/Inter/EnglishLanguageKit</span>
<span class="plain">kit: CommandParserKit at path inform7/Internal/Inter/CommandParserKit</span>
<span class="plain">kit: BasicInformExtrasKit at path inform7/Internal/Inter/BasicInformExtrasKit</span>
<span class="plain">kit: WorldModelKit at path inform7/Internal/Inter/WorldModelKit</span>
<span class="plain">kit: BasicInformKit at path inform7/Internal/Inter/BasicInformKit</span>
</pre>
<p class="inwebparagraph">For compatibility with the <code class="display"><span class="extract">inform7</span></code> command line syntax, we can also specify
the project target using <code class="display"><span class="extract">-project</span></code>:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">$ inbuild/Tangled/inbuild -build -project Example.inform</span>
</pre>
<p class="inwebparagraph">But this is quite unnecessary: the effect is the same as if <code class="display"><span class="extract">-project</span></code> had
been missed out.
</p>
<p class="inwebparagraph"><a id="SP13"></a><b>&#167;13. </b>Listing filenames or pathnames of copies on the command line, or using the
<code class="display"><span class="extract">-contents-of D</span></code> switch, is only possible if we know where in the file system
these copies are; and sometimes we do not.
</p>
<p class="inwebparagraph">If we instead specify <code class="display"><span class="extract">-matching R</span></code>, where <code class="display"><span class="extract">R</span></code> is a list of requirements,
Inbuild will act on every copy it can find which matches that. For example,
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">$ inbuild/Tangled/inbuild -inspect -matching 'genre=kit'</span>
</pre>
<p class="inwebparagraph">lists all the kits which Inbuild can see; and
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">$ inbuild/Tangled/inbuild -inspect -matching 'genre=extension,author=Eric Eve'</span>
</pre>
<p class="inwebparagraph">lists all extensions by Eric Eve which Inbuild can see. The legal clauses to
specify are <code class="display"><span class="extract">title</span></code>, <code class="display"><span class="extract">author</span></code>, <code class="display"><span class="extract">genre</span></code> and <code class="display"><span class="extract">version</span></code>. Note that <code class="display"><span class="extract">version=5.1.1</span></code>
would match version numbers 5.1.1, 5.1.2, 5.2.0, etc., but not 6 or above:
again, this is following semver conventions. To specify an explicit maximum
and minimum version number, use <code class="display"><span class="extract">max</span></code> and <code class="display"><span class="extract">min</span></code>. For example:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">-matching 'genre=extension,author=Emily Short,title=Locksmith,min=6.1-alpha.2,max=17.2</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP14"></a><b>&#167;14. Nests and searches. </b>When searching with <code class="display"><span class="extract">-matching R</span></code>, or indeed when running Inform and needing
to find certain resources, Inbuild looks inside what are called "nests".
</p>
<p class="inwebparagraph">A nest is a directory with structured subdirectories, which correspond to
the genres of copies put into them. For example, in the standard distribution
of Inform as a command-line tool, the path <code class="display"><span class="extract">inform7/Internal</span></code> is a nest:
this contains the extensions, kits and so on which are built in to Inform
when it's used as an app.
</p>
<p class="inwebparagraph">Inbuild recognises the following subdirectories of a nest as significant:
</p>
<p class="inwebparagraph"> Templates
Pipelines
Inter
Languages
Extensions
</p>
<p class="inwebparagraph">Other subdirectories can also exist, and Inbuild ignores those. The above
five containers hold website templates (used by Inblorb), Inter pipelines,
kits, language definitions, and extensions. In the case of extensions, where
there may be very many in total, a further level of subdirectory is used
for the authpr's name. Thus:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">Extensions/Emily Short/Locksmith.i7x</span>
</pre>
<p class="inwebparagraph">(In some early releases of Inform 7, it was legal for this file not to have
the <code class="display"><span class="extract">.i7x</span></code> extension: but now it is compulsory.)
</p>
<p class="inwebparagraph">As of 2020, nests can contain multiple versions of the same work. To do
this, they should have a filename (or pathname) which ends with <code class="display"><span class="extract">-vN</span></code>, where
<code class="display"><span class="extract">N</span></code> is semantic version number but with any dots replaced by underscores.
Thus, we can have e.g.:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">Extensions/Emily Short/Locksmith-v3_2.i7x</span>
<span class="plain">Extensions/Emily Short/Locksmith-v4_0_0-prealpha_13.i7x</span>
</pre>
<p class="inwebparagraph">co-existing side by side. If the user asks to
</p>
<blockquote>
<p>Include Locksmith by Emily Short.</p>
</blockquote>
<p class="inwebparagraph">then version <code class="display"><span class="extract">4.0.0-prealpha.13</span></code> will be chosen, as the one with highest
precedence in this nest (but see below for how Inbuild chooses between
versions in the same nest). But if the user asks for
</p>
<blockquote>
<p>Include version 3 Locksmith by Emily Short.</p>
</blockquote>
<p class="inwebparagraph">then version <code class="display"><span class="extract">3.2</span></code> is the winner, as the highest-numbered extension in the
nest with the right major version number (3).
</p>
<p class="inwebparagraph"><a id="SP15"></a><b>&#167;15. </b>In most runs of the Inform compiler, three nests are used: the "internal"
one, so-called, which holds built-in extensions and is read-only; the
"external" one, which will be somewhere outside of the Inform GUI app, and
will hold additional extensions downloaded by the user; and the Materials
folder for an Inform project, which is a nest all by itself.
</p>
<p class="inwebparagraph">Inbuild looks for these as follows:
</p>
<ul class="items"><li>(a) <code class="display"><span class="extract">-internal N</span></code> tells Inbuild the path <code class="display"><span class="extract">N</span></code> for the internal nest; if this
is not given, the default is <code class="display"><span class="extract">inform7/Internal</span></code>.
</li><li>(b) <code class="display"><span class="extract">-external N</span></code> tells Inbuild the path <code class="display"><span class="extract">N</span></code> for the external nest; if this
is not given, the default depends on the host operating system. For example,
on MacOS it will be <code class="display"><span class="extract">~/Library/Inform</span></code> (which is what the Inform GUI app
uses too if it is not sandboxed: if it is indeed sandboxed, then it will
have a deliberately obfuscated location which MacOS does not want tools
like ours to access externally).
</li><li>(c) The Materials nest is always the Materials folder associated with the
project Inbuild is working on; if it isn't working on a project, then this
nest is of course not present.
</li></ul>
<p class="inwebparagraph">In addition, extra nests can be specified with <code class="display"><span class="extract">-nest N</span></code>.
</p>
<p class="inwebparagraph"><a id="SP16"></a><b>&#167;16. </b>When Inbuild searches for some resource needed by Inform &mdash; let's continue
to use the Locksmith extension as an example &mdash; it always has some range of
version numbers in mind: it will only accept a version in that range. (The
range can be unlimited, in which case any version is acceptable.)
</p>
<p class="inwebparagraph">This may well produce multiple results: as noted above, we might have multiple
copies of Locksmith around. Inbuild first reduces the list to just those
whose version lies in the acceptable range. It then applies the following
rules:
</p>
<ul class="items"><li>(1) A copy in the Materials nest takes precedence over all others.
</li><li>(2) Otherwise, all other copies take precendence over those in the
internal nest.
</li><li>(3) Otherwise, semantic version number rules are used to determine which
copy had precedence.
</li></ul>
<p class="inwebparagraph">Suppose the Materials folder for our project contains <code class="display"><span class="extract">Locksmith-v3_2.i7x</span></code>,
while the external folder contains <code class="display"><span class="extract">Locksmith-v3_3.i7x</span></code> and <code class="display"><span class="extract">Locksmith-v4.i7x</span></code>.
Then the sentence:
</p>
<blockquote>
<p>Include Locksmith by Emily Short.</p>
</blockquote>
<p class="inwebparagraph">would result in <code class="display"><span class="extract">Locksmith-v3_2.i7x</span></code> from Materials being used, even though
there's a later version in the external area: Materials always wins. But
</p>
<blockquote>
<p>Include version 4 of Locksmith by Emily Short.</p>
</blockquote>
<p class="inwebparagraph">would use <code class="display"><span class="extract">Locksmith-v4.i7x</span></code> from the external area, because the copy in the
Materials folder doesn't qualify.
</p>
<p class="inwebparagraph"><a id="SP17"></a><b>&#167;17. Copy, sync and archive. </b>Clerical work is generally best done automatically, and Inbuild offers some
useful filing commands.
</p>
<p class="inwebparagraph">The command <code class="display"><span class="extract">-copy-to N</span></code> makes a duplicate copy in the nest <code class="display"><span class="extract">N</span></code>. For example:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">$ inbuild/Tangled/inbuild -inspect junk/Mystery.i7x</span>
<span class="plain">extension: Complex Listing by Emily Short v9 in directory junk.</span>
<span class="plain">$ inbuild/Tangled/inbuild -copy-to MyNest junk/Mystery.i7x</span>
<span class="plain">cp -f 'junk/Mystery.i7x' 'MyNest/Extensions/Emily Short/Complex Listing-v9.i7x'</span>
</pre>
<p class="inwebparagraph">Note that Inbuild replies to the <code class="display"><span class="extract">-copy-to N</span></code> command by executing a shell
command to copy what is, in this case, a single file. As when building, the
<code class="display"><span class="extract">-dry</span></code> option puts Inbuild into dry-run mode, where it prints the commands it
would like to execute but doesn't execute them.
</p>
<p class="inwebparagraph">The command <code class="display"><span class="extract">-sync-to N</span></code> is similar, but will overwrite any existing copy
already in <code class="display"><span class="extract">N</span></code>, rather than producing an error if a collision occurs.
</p>
<p class="inwebparagraph"><a id="SP18"></a><b>&#167;18. </b>The <code class="display"><span class="extract">-archive-to N</span></code> command performs <code class="display"><span class="extract">-sync-to N</span></code> on any resource needed
to build the copy it is working on (with one exception, for technical reasons:
the configuration file telling Inform how to use the English natural language).
</p>
<p class="inwebparagraph">This is really only useful for Inform projects, and the abbreviated form
<code class="display"><span class="extract">-archive</span></code> performs <code class="display"><span class="extract">-archive-to</span></code> to the Materials folder for a project.
The net effect of this is that all extensions needed to build a story file
are gathered, with their correct versions, into the Materials folder; this
means that if the project and its Materials are moved to a different user's
computer, where a quite different set of extensions may be installed, then
the project will still work exactly as it originally did.
</p>
<hr class="tocbar">
<ul class="toc"><li><i>(This section begins Manual.)</i></li><li><i>(This section ends Manual.)</i></li></ul><hr class="tocbar">
<!--End of weave-->
</main>
</body>

View file

@ -64,17 +64,17 @@
<ul class="sectionlist">
<li>
<p><a href="M-ui.html"><spon class="sectiontitle">Using Inbuild</span></a> -
<span class="purpose">A brief user guide.</span></p>
<span class="purpose">An introduction to the use of Inbuild on the command line.</span></p>
</li>
</ul>
</li>
<li>
<p><a name="1"></a><spon class="chaptertitle">Chapter 1: Delegation</span></p>
<p><a name="1"></a><spon class="chaptertitle">Chapter 1: Inbuild outside of Inform</span></p>
<p><span class="purpose"></span></p>
<ul class="sectionlist">
<li>
<p><a href="1-mn.html"><spon class="sectiontitle">Main</span></a> -
<span class="purpose">The top level, which decides what is to be done and then carries this plan out.</span></p>
<span class="purpose">A command-line interface for Inbuild functions which are not part of the normal operation of the Inform compiler.</span></p>
</li>
</ul>
</li>

View file

@ -156,7 +156,6 @@ foundation module does that automatically.)
<p class="endnote">The function IndexModule::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-->
</main>
</body>

View file

@ -178,7 +178,6 @@ foundation module does that automatically.)
<p class="endnote">The function InflectionsModule::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-->
</main>
</body>

View file

@ -3528,7 +3528,6 @@ don't distinguish nominative from accusative.
<p class="inwebparagraph"></p>
<hr class="tocbar">
<ul class="toc"><li><i>(This section begins Chapter 4: Default Language.)</i></li><li><i>(This section ends Chapter 4: Default Language.)</i></li></ul><hr class="tocbar">
<!--End of weave-->
</main>
</body>

View file

@ -162,7 +162,6 @@ Multimedia.
<p class="endnote">The function Main::core_inform_main is used in <a href="#SP2">&#167;2</a>.</p>
<hr class="tocbar">
<ul class="toc"><li><i>(This section begins Chapter 1: Delegation.)</i></li><li><i>(This section ends Chapter 1: Delegation.)</i></li></ul><hr class="tocbar">
<!--End of weave-->
</main>
</body>

View file

@ -238,7 +238,6 @@ had been worked into the verification process for builds. The history since
</p>
<hr class="tocbar">
<ul class="toc"><li><i>(This section begins Manual.)</i></li><li><i>(This section ends Manual.)</i></li></ul><hr class="tocbar">
<!--End of weave-->
</main>
</body>

View file

@ -408,7 +408,6 @@ not a specific problem case.
<p class="endnote">The function Coverage::list is used in <a href="#SP8_2">&#167;8.2</a>.</p>
<hr class="tocbar">
<ul class="toc"><li><i>(This section begins Chapter 2: Policies.)</i></li><li><i>(This section ends Chapter 2: Policies.)</i></li></ul><hr class="tocbar">
<!--End of weave-->
</main>
</body>

View file

@ -113,7 +113,6 @@ attempts to match these up. It prints out a report, and concludes with either
</p>
<hr class="tocbar">
<ul class="toc"><li><i>(This section begins Manual.)</i></li><li><i>(This section ends Manual.)</i></li></ul><hr class="tocbar">
<!--End of weave-->
</main>
</body>

View file

@ -133,7 +133,6 @@ escape codes, which Inrtps expands. Thus:
blank if <code class="display"><span class="extract">nofont</span></code> is set, or will choose a Helvetica-like font if <code class="display"><span class="extract">font</span></code> is set.)
</li></ul>
<hr class="tocbar">
<ul class="toc"><li><i>(This section begins Manual.)</i></li><li><i>(This section ends Manual.)</i></li></ul><hr class="tocbar">
<!--End of weave-->
</main>
</body>

View file

@ -241,7 +241,6 @@ foundation module does that automatically.)
<p class="endnote">The function InterModule::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-->
</main>
</body>

View file

@ -196,7 +196,6 @@ foundation module does that automatically.)
<p class="endnote">The function KindsModule::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-->
</main>
</body>

View file

@ -38,7 +38,7 @@
<!--Weave of '1/bsc' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">Source</a></li><li><a href="../units.html">Unit Test Tools</a></li><li><a href="index.html">kinds-test</a></li><li><a href="index.html#1">Chapter 1: Everything</a></li><li><b>Basics</b></li></ul><p class="purpose">Some fundamental definitions.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Build identity</a></li><li><a href="#SP7">&#167;7. Preform error handling</a></li><li><a href="#SP12">&#167;12. Problems with kinds</a></li></ul><hr class="tocbar">
<ul class="toc"><li><a href="#SP1">&#167;1. Build identity</a></li><li><a href="#SP7">&#167;7. Preform error handling</a></li><li><a href="#SP11">&#167;11. Problems with kinds</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Build identity. </b>First we define the build, using a notation which tangles out to the current
build number as specified in the contents section of this web.
@ -244,23 +244,6 @@ build number as specified in the contents section of this web.
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">PARSE_TREE_TRAVERSE_TYPE</span><span class="plain"> </span><span class="reserved">void</span>
<span class="definitionkeyword">define</span> <span class="constant">SENTENCE_NODE</span><span class="plain"> </span><span class="functiontext">Basics::sentence_level</span>
</pre>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Basics::sentence_level</span><span class="plain">(</span><span class="constant">node_type_t</span><span class="plain"> </span><span class="identifier">t</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="constant">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Basics::sentence_level appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. </b></p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">ADJECTIVE_MEANING_TYPE</span><span class="plain"> </span><span class="reserved">void</span>
<span class="definitionkeyword">define</span> <span class="constant">VERB_MEANING_EQUALITY</span><span class="plain"> </span><span class="identifier">vc_be</span>
<span class="definitionkeyword">define</span> <span class="constant">VERB_MEANING_POSSESSION</span><span class="plain"> </span><span class="identifier">vc_have</span>
@ -278,7 +261,7 @@ build number as specified in the contents section of this web.
<p class="endnote">The function Basics::dummy appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. </b></p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. </b></p>
<pre class="definitions">
@ -290,7 +273,7 @@ build number as specified in the contents section of this web.
<span class="definitionkeyword">define</span> <span class="constant">PARAMETRISED_PARSING_BITMAP</span>
<span class="plain">(</span><span class="constant">ONE_WEIRD_TRICK_MC</span><span class="plain">)</span>
</pre>
<p class="inwebparagraph"><a id="SP11"></a><b>&#167;11. </b></p>
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. </b></p>
<pre class="definitions">
@ -320,7 +303,7 @@ build number as specified in the contents section of this web.
<p class="endnote">The function Basics::move_within appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP12"></a><b>&#167;12. Problems with kinds. </b></p>
<p class="inwebparagraph"><a id="SP11"></a><b>&#167;11. Problems with kinds. </b></p>
<pre class="definitions">

View file

@ -229,7 +229,6 @@ foundation module does that automatically.)
<p class="endnote">The function LinguisticsModule::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-->
</main>
</body>

View file

@ -244,23 +244,6 @@ build number as specified in the contents section of this web.
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">PARSE_TREE_TRAVERSE_TYPE</span><span class="plain"> </span><span class="reserved">void</span>
<span class="definitionkeyword">define</span> <span class="constant">SENTENCE_NODE</span><span class="plain"> </span><span class="functiontext">Basics::sentence_level</span>
</pre>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Basics::sentence_level</span><span class="plain">(</span><span class="constant">node_type_t</span><span class="plain"> </span><span class="identifier">t</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="constant">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Basics::sentence_level appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. </b></p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">ADJECTIVE_MEANING_TYPE</span><span class="plain"> </span><span class="reserved">void</span>
<span class="definitionkeyword">define</span> <span class="constant">VERB_MEANING_EQUALITY</span><span class="plain"> </span><span class="identifier">vc_be</span>
<span class="definitionkeyword">define</span> <span class="constant">VERB_MEANING_POSSESSION</span><span class="plain"> </span><span class="identifier">vc_have</span>
@ -278,7 +261,7 @@ build number as specified in the contents section of this web.
<p class="endnote">The function Basics::dummy appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. </b></p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. </b></p>
<pre class="definitions">

View file

@ -168,7 +168,6 @@ foundation module does that automatically.)
<p class="endnote">The function MultimediaModule::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-->
</main>
</body>

View file

@ -235,23 +235,6 @@ structure and initialiser:
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">PARSE_TREE_TRAVERSE_TYPE</span><span class="plain"> </span><span class="reserved">void</span>
<span class="definitionkeyword">define</span> <span class="constant">SENTENCE_NODE</span><span class="plain"> </span><span class="functiontext">Basics::sentence_level</span>
</pre>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Basics::sentence_level</span><span class="plain">(</span><span class="constant">node_type_t</span><span class="plain"> </span><span class="identifier">t</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="constant">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Basics::sentence_level appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. </b></p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">NO_HEADING_LEVELS</span><span class="plain"> 10</span>
</pre>
<hr class="tocbar">

View file

@ -178,7 +178,6 @@ foundation module does that automatically.)
<p class="endnote">The function SyntaxModule::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-->
</main>
</body>

View file

@ -59,7 +59,7 @@
<!--Weave of '2/pt' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">Source</a></li><li><a href="../compiler.html">Compiler Modules</a></li><li><a href="index.html">syntax</a></li><li><a href="index.html#2">Chapter 2: The Parse Tree</a></li><li><b>Parse Tree</b></li></ul><p class="purpose">To parse trees which decompose the meaning of excerpts of text, and which allow annotations to be made at each node.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Trees store meanings</a></li><li><a href="#SP4">&#167;4. Structural vs specifications</a></li><li><a href="#SP5">&#167;5. Node types</a></li><li><a href="#SP7">&#167;7. The structure</a></li><li><a href="#SP8">&#167;8. Where we currently are in the text</a></li><li><a href="#SP12">&#167;12. Node metadata</a></li><li><a href="#SP16">&#167;16. The metadata table</a></li><li><a href="#SP20">&#167;20. Logging node types</a></li><li><a href="#SP21">&#167;21. Creation</a></li><li><a href="#SP24">&#167;24. Annotations</a></li><li><a href="#SP33">&#167;33. Copying parse nodes</a></li><li><a href="#SP36">&#167;36. Child count</a></li><li><a href="#SP37">&#167;37. Detection of subnodes</a></li><li><a href="#SP38">&#167;38. The word range beneath a given node</a></li><li><a href="#SP45">&#167;45. Logging the parse tree</a></li><li><a href="#SP50">&#167;50. General traversals</a></li><li><a href="#SP51">&#167;51. Verify integrity</a></li><li><a href="#SP53">&#167;53. Verify structure</a></li><li><a href="#SP55">&#167;55. Parentage rules</a></li><li><a href="#SP57">&#167;57. Annotation rules</a></li><li><a href="#SP59">&#167;59. Ambiguity subtrees</a></li></ul><hr class="tocbar">
<ul class="toc"><li><a href="#SP1">&#167;1. Trees store meanings</a></li><li><a href="#SP4">&#167;4. Structural vs specifications</a></li><li><a href="#SP5">&#167;5. Node types</a></li><li><a href="#SP7">&#167;7. The structure</a></li><li><a href="#SP8">&#167;8. Where we currently are in the text</a></li><li><a href="#SP12">&#167;12. Node metadata</a></li><li><a href="#SP16">&#167;16. The metadata table</a></li><li><a href="#SP20">&#167;20. Logging node types</a></li><li><a href="#SP21">&#167;21. Creation</a></li><li><a href="#SP24">&#167;24. Annotations</a></li><li><a href="#SP33">&#167;33. Copying parse nodes</a></li><li><a href="#SP36">&#167;36. Child count</a></li><li><a href="#SP37">&#167;37. Detection of subnodes</a></li><li><a href="#SP38">&#167;38. The word range beneath a given node</a></li><li><a href="#SP45">&#167;45. Logging the parse tree</a></li><li><a href="#SP50">&#167;50. General traversals</a></li><li><a href="#SP52">&#167;52. Verify integrity</a></li><li><a href="#SP54">&#167;54. Verify structure</a></li><li><a href="#SP56">&#167;56. Parentage rules</a></li><li><a href="#SP58">&#167;58. Annotation rules</a></li><li><a href="#SP60">&#167;60. Ambiguity subtrees</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Trees store meanings. </b>Most algorithms for parsing natural language involve the construction of
trees, in which the original words appear as leaves at the top of the tree,
@ -452,7 +452,7 @@ codes such as <code class="display"><span class="extract">RULE_MC</span></code>,
<p class="inwebparagraph"></p>
<p class="endnote">The function ParseTree::node_metadata is used in <a href="#SP19">&#167;19</a>, <a href="#SP20">&#167;20</a>, <a href="#SP54">&#167;54</a>, <a href="#SP54_3">&#167;54.3</a>.</p>
<p class="endnote">The function ParseTree::node_metadata is used in <a href="#SP19">&#167;19</a>, <a href="#SP20">&#167;20</a>, <a href="#SP55">&#167;55</a>, <a href="#SP55_3">&#167;55.3</a>.</p>
<p class="inwebparagraph"><a id="SP19"></a><b>&#167;19. </b></p>
@ -489,9 +489,9 @@ codes such as <code class="display"><span class="extract">RULE_MC</span></code>,
<p class="inwebparagraph"></p>
<p class="endnote">The function ParseTree::valid_type is used in <a href="#SP16">&#167;16</a>, <a href="#SP52">&#167;52</a>.</p>
<p class="endnote">The function ParseTree::valid_type is used in <a href="#SP16">&#167;16</a>, <a href="#SP53">&#167;53</a>.</p>
<p class="endnote">The function ParseTree::cat is used in <a href="#SP57">&#167;57</a>.</p>
<p class="endnote">The function ParseTree::cat is used in <a href="#SP58">&#167;58</a>.</p>
<p class="endnote">The function ParseTree::top_level is used in <a href="#SP50">&#167;50</a>.</p>
@ -567,7 +567,7 @@ Here's one if a word range is to be attached:
<p class="inwebparagraph"></p>
<p class="endnote">The function ParseTree::new_with_words is used in <a href="#SP59">&#167;59</a>.</p>
<p class="endnote">The function ParseTree::new_with_words is used in <a href="#SP60">&#167;60</a>.</p>
<p class="inwebparagraph"><a id="SP23"></a><b>&#167;23. </b>The attached text.
</p>
@ -609,9 +609,9 @@ at each node is its node type, accessed as follows:
<p class="inwebparagraph"></p>
<p class="endnote">The function ParseTree::get_type is used in <a href="#SP44">&#167;44</a>, <a href="#SP44_1">&#167;44.1</a>, <a href="#SP52">&#167;52</a>, <a href="#SP54">&#167;54</a>, <a href="#SP54_3">&#167;54.3</a>, <a href="#SP59">&#167;59</a>.</p>
<p class="endnote">The function ParseTree::get_type is used in <a href="#SP44">&#167;44</a>, <a href="#SP44_1">&#167;44.1</a>, <a href="#SP53">&#167;53</a>, <a href="#SP55">&#167;55</a>, <a href="#SP55_3">&#167;55.3</a>, <a href="#SP60">&#167;60</a>.</p>
<p class="endnote">The function ParseTree::is is used in <a href="#SP50">&#167;50</a>, <a href="#SP54_1_1">&#167;54.1.1</a>, <a href="#SP59">&#167;59</a>.</p>
<p class="endnote">The function ParseTree::is is used in <a href="#SP50">&#167;50</a>, <a href="#SP55_1_1">&#167;55.1.1</a>, <a href="#SP60">&#167;60</a>.</p>
<p class="inwebparagraph"><a id="SP25"></a><b>&#167;25. </b>When setting, we have to preserve the invariant, so we clear away any
annotations no longer relevant to the node's new identity.
@ -1340,7 +1340,7 @@ routine above, these all assume that the tree is well-formed.
<span class="reserved">for</span><span class="plain"> (; </span><span class="identifier">pn</span><span class="plain">; </span><span class="identifier">pn</span><span class="plain"> = </span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">ParseTree::top_level</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;node_type</span><span class="plain">)) </span><span class="functiontext">ParseTree::traverse_from</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">, </span><span class="identifier">visitor</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">ParseTree::visitable</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;node_type</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">SENTENCE_NODE</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;node_type</span><span class="plain">)) </span><span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">pn</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">ParseTree::sentence_node</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;node_type</span><span class="plain">)) </span><span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">pn</span><span class="plain">;</span>
<span class="plain">(*</span><span class="identifier">visitor</span><span class="plain">)(</span><span class="identifier">pn</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
@ -1353,7 +1353,7 @@ routine above, these all assume that the tree is well-formed.
<span class="reserved">parse_node</span><span class="plain"> *</span><span class="identifier">SCS</span><span class="plain"> = </span><span class="identifier">current_sentence</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (; </span><span class="identifier">pn</span><span class="plain">; </span><span class="identifier">pn</span><span class="plain"> = </span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">) {</span>
<span class="functiontext">ParseTree::traverse_dfirst_from</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">, </span><span class="identifier">visitor</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">SENTENCE_NODE</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;node_type</span><span class="plain">)) </span><span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">pn</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">ParseTree::sentence_node</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;node_type</span><span class="plain">)) </span><span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">pn</span><span class="plain">;</span>
<span class="plain">(*</span><span class="identifier">visitor</span><span class="plain">)(</span><span class="identifier">pn</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">SCS</span><span class="plain">;</span>
@ -1364,7 +1364,7 @@ routine above, these all assume that the tree is well-formed.
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">ParseTree::traverse_wfirst_from</span><span class="plain">(</span><span class="reserved">parse_node</span><span class="plain"> *</span><span class="identifier">pn</span><span class="plain">, </span><span class="reserved">void</span><span class="plain"> (*</span><span class="identifier">visitor</span><span class="plain">)(</span><span class="reserved">parse_node</span><span class="plain"> *)) {</span>
<span class="reserved">parse_node</span><span class="plain"> *</span><span class="identifier">SCS</span><span class="plain"> = </span><span class="identifier">current_sentence</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (; </span><span class="identifier">pn</span><span class="plain">; </span><span class="identifier">pn</span><span class="plain"> = </span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">SENTENCE_NODE</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;node_type</span><span class="plain">)) </span><span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">pn</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">ParseTree::sentence_node</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;node_type</span><span class="plain">)) </span><span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">pn</span><span class="plain">;</span>
<span class="functiontext">ParseTree::traverse_wfirst_from</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">, </span><span class="identifier">visitor</span><span class="plain">);</span>
<span class="plain">(*</span><span class="identifier">visitor</span><span class="plain">)(</span><span class="identifier">pn</span><span class="plain">);</span>
<span class="plain">}</span>
@ -1379,7 +1379,7 @@ routine above, these all assume that the tree is well-formed.
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">ParseTree::top_level</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;node_type</span><span class="plain">))</span>
<span class="functiontext">ParseTree::traverse_from_with_stream</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">, </span><span class="identifier">visitor</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">ParseTree::visitable</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;node_type</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">SENTENCE_NODE</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;node_type</span><span class="plain">)) </span><span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">pn</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">ParseTree::sentence_node</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;node_type</span><span class="plain">)) </span><span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">pn</span><span class="plain">;</span>
<span class="plain">(*</span><span class="identifier">visitor</span><span class="plain">)(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">pn</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
@ -1393,7 +1393,7 @@ routine above, these all assume that the tree is well-formed.
<span class="reserved">for</span><span class="plain"> (; </span><span class="identifier">pn</span><span class="plain">; </span><span class="identifier">pn</span><span class="plain"> = </span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">ParseTree::top_level</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;node_type</span><span class="plain">)) </span><span class="functiontext">ParseTree::traverse_from_int</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">, </span><span class="identifier">visitor</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="functiontext">ParseTree::visitable</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;node_type</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">SENTENCE_NODE</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;node_type</span><span class="plain">)) </span><span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">pn</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">ParseTree::sentence_node</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;node_type</span><span class="plain">)) </span><span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">pn</span><span class="plain">;</span>
<span class="plain">(*</span><span class="identifier">visitor</span><span class="plain">)(</span><span class="identifier">pn</span><span class="plain">, </span><span class="identifier">X</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
@ -1407,7 +1407,7 @@ routine above, these all assume that the tree is well-formed.
<span class="reserved">for</span><span class="plain"> (; </span><span class="identifier">pn</span><span class="plain">; </span><span class="identifier">pn</span><span class="plain"> = </span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">ParseTree::top_level</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;node_type</span><span class="plain">)) </span><span class="functiontext">ParseTree::traverse_from_int_int</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">, </span><span class="identifier">visitor</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="reserved">if</span><span class="plain"> (</span><span class="functiontext">ParseTree::visitable</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;node_type</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">SENTENCE_NODE</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;node_type</span><span class="plain">)) </span><span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">pn</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">ParseTree::sentence_node</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;node_type</span><span class="plain">)) </span><span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">pn</span><span class="plain">;</span>
<span class="plain">(*</span><span class="identifier">visitor</span><span class="plain">)(</span><span class="identifier">pn</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="plain">}</span>
<span class="plain">}</span>
@ -1421,7 +1421,7 @@ routine above, these all assume that the tree is well-formed.
<span class="reserved">for</span><span class="plain"> (; </span><span class="identifier">pn</span><span class="plain">; </span><span class="identifier">pn</span><span class="plain"> = </span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">ParseTree::top_level</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;node_type</span><span class="plain">)) </span><span class="functiontext">ParseTree::traverse_from_ppn</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">, </span><span class="identifier">visitor</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="functiontext">ParseTree::visitable</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;node_type</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">SENTENCE_NODE</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;node_type</span><span class="plain">)) </span><span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">pn</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">ParseTree::sentence_node</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;node_type</span><span class="plain">)) </span><span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">pn</span><span class="plain">;</span>
<span class="plain">(*</span><span class="identifier">visitor</span><span class="plain">)(</span><span class="identifier">pn</span><span class="plain">, </span><span class="identifier">X</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
@ -1440,7 +1440,7 @@ routine above, these all assume that the tree is well-formed.
<span class="functiontext">ParseTree::traverse_from_ppni</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">, </span><span class="identifier">visitor</span><span class="plain">, </span><span class="identifier">H0</span><span class="plain">, </span><span class="identifier">N</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">ParseTree::visitable</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;node_type</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">SENTENCE_NODE</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;node_type</span><span class="plain">)) </span><span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">pn</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">ParseTree::sentence_node</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;node_type</span><span class="plain">)) </span><span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">pn</span><span class="plain">;</span>
<span class="plain">(*</span><span class="identifier">visitor</span><span class="plain">)(</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">pn</span><span class="plain">, </span><span class="identifier">last_h0</span><span class="plain">, </span><span class="identifier">N</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
@ -1459,7 +1459,7 @@ routine above, these all assume that the tree is well-formed.
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">ParseTree::visitable</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;node_type</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">SENTENCE_NODE</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;node_type</span><span class="plain">)) </span><span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">pn</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">ParseTree::sentence_node</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">-</span><span class="element">&gt;node_type</span><span class="plain">)) </span><span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">pn</span><span class="plain">;</span>
<span class="plain">(*</span><span class="identifier">visitor</span><span class="plain">)(</span><span class="identifier">pn</span><span class="plain">, </span><span class="identifier">X</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
@ -1528,7 +1528,26 @@ routine above, these all assume that the tree is well-formed.
<p class="endnote">The function ParseTree::traverse_from_ppn_nocs appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP51"></a><b>&#167;51. Verify integrity. </b>The first duty of a tree is to contain no loops, and the following checks
<p class="inwebparagraph"><a id="SP51"></a><b>&#167;51. </b>This provides a way for users of the module to indicate what's a sentence:
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">ParseTree::sentence_node</span><span class="plain">(</span><span class="constant">node_type_t</span><span class="plain"> </span><span class="identifier">t</span><span class="plain">) {</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">SENTENCE_NODE</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">SENTENCE_NODE</span><span class="plain">(</span><span class="identifier">t</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">SENTENCE_NODE</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 ParseTree::sentence_node is used in <a href="#SP50">&#167;50</a>.</p>
<p class="inwebparagraph"><a id="SP52"></a><b>&#167;52. Verify integrity. </b>The first duty of a tree is to contain no loops, and the following checks
that (rejecting even undirected loops). In addition, it checks that each
node has an enumerated node type, rather than a meaning code.
</p>
@ -1548,9 +1567,9 @@ node has an enumerated node type, rather than a meaning code.
<p class="inwebparagraph"></p>
<p class="endnote">The function ParseTree::verify_integrity is used in <a href="#SP53">&#167;53</a>.</p>
<p class="endnote">The function ParseTree::verify_integrity is used in <a href="#SP54">&#167;54</a>.</p>
<p class="inwebparagraph"><a id="SP52"></a><b>&#167;52. </b>The verification traverse is a very cautious manoeuvre: we step through
<p class="inwebparagraph"><a id="SP53"></a><b>&#167;53. </b>The verification traverse is a very cautious manoeuvre: we step through
the tree, testing each branch with our outstretched foot in case it might
be illusory or broken. At the first sign of trouble we panic.
</p>
@ -1592,9 +1611,9 @@ be illusory or broken. At the first sign of trouble we panic.
<p class="inwebparagraph"></p>
<p class="endnote">The function ParseTree::verify_tree_integrity_recursively is used in <a href="#SP51">&#167;51</a>.</p>
<p class="endnote">The function ParseTree::verify_tree_integrity_recursively is used in <a href="#SP52">&#167;52</a>.</p>
<p class="inwebparagraph"><a id="SP53"></a><b>&#167;53. Verify structure. </b>The parse tree is a complicated structure, arbitrarily wide and deep, and
<p class="inwebparagraph"><a id="SP54"></a><b>&#167;54. Verify structure. </b>The parse tree is a complicated structure, arbitrarily wide and deep, and
containing many different node types, each subject to its own rules of usage.
(For instance, a <code class="display"><span class="extract">SENTENCE_NT</span></code> node cannot legally be beneath a
<code class="display"><span class="extract">PROPER_NOUN_NT</span></code> one.) This is both good and bad: bad because complexity is
@ -1650,7 +1669,7 @@ about counting children with impunity.
<p class="endnote">The function ParseTree::verify_structure appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP54"></a><b>&#167;54. </b>Note that on every call to the following routine, (i) <code class="display"><span class="extract">p</span></code> is a valid
<p class="inwebparagraph"><a id="SP55"></a><b>&#167;55. </b>Note that on every call to the following routine, (i) <code class="display"><span class="extract">p</span></code> is a valid
parse node and (ii) either <code class="display"><span class="extract">p</span></code> is the tree root, in which case <code class="display"><span class="extract">parent</span></code> is
<code class="display"><span class="extract">NULL</span></code>, or <code class="display"><span class="extract">parent</span></code> is the unique node having <code class="display"><span class="extract">p</span></code> (or an alternative to <code class="display"><span class="extract">p</span></code>)
among its children.
@ -1663,15 +1682,15 @@ among its children.
<span class="reserved">parse_tree_node_type</span><span class="plain"> *</span><span class="identifier">metadata</span><span class="plain"> = </span><span class="functiontext">ParseTree::node_metadata</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">metadata</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">"broken tree should have been reported"</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Check rule (1) of the invariant</span> <span class="cwebmacronumber">54.1</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Check rule (2) of the invariant</span> <span class="cwebmacronumber">54.2</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parent</span><span class="plain">) </span>&lt;<span class="cwebmacro">Check rule (3) of the invariant</span> <span class="cwebmacronumber">54.3</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Check rule (1) of the invariant</span> <span class="cwebmacronumber">55.1</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Check rule (2) of the invariant</span> <span class="cwebmacronumber">55.2</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parent</span><span class="plain">) </span>&lt;<span class="cwebmacro">Check rule (3) of the invariant</span> <span class="cwebmacronumber">55.3</span>&gt;<span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">children_count</span><span class="plain"> = 0;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">parse_node</span><span class="plain"> *</span><span class="identifier">q</span><span class="plain">=</span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">; </span><span class="identifier">q</span><span class="plain">; </span><span class="identifier">q</span><span class="plain">=</span><span class="identifier">q</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">, </span><span class="identifier">children_count</span><span class="plain">++)</span>
<span class="functiontext">ParseTree::verify_structure_recursively</span><span class="plain">(</span><span class="identifier">q</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Check rule (4) of the invariant</span> <span class="cwebmacronumber">54.4</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Check rule (4) of the invariant</span> <span class="cwebmacronumber">55.4</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;next_alternative</span><span class="plain">)</span>
<span class="functiontext">ParseTree::verify_structure_recursively</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">-</span><span class="element">&gt;next_alternative</span><span class="plain">, </span><span class="identifier">parent</span><span class="plain">);</span>
@ -1680,34 +1699,34 @@ among its children.
<p class="inwebparagraph"></p>
<p class="endnote">The function ParseTree::verify_structure_recursively is used in <a href="#SP53">&#167;53</a>.</p>
<p class="endnote">The function ParseTree::verify_structure_recursively is used in <a href="#SP54">&#167;54</a>.</p>
<p class="inwebparagraph"><a id="SP54_1"></a><b>&#167;54.1. </b>Rule (1): no INVALID nodes.
<p class="inwebparagraph"><a id="SP55_1"></a><b>&#167;55.1. </b>Rule (1): no INVALID nodes.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Check rule (1) of the invariant</span> <span class="cwebmacronumber">54.1</span>&gt; =
&lt;<span class="cwebmacrodefn">Check rule (1) of the invariant</span> <span class="cwebmacronumber">55.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">t</span><span class="plain"> == </span><span class="constant">INVALID_NT</span><span class="plain">) {</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"N%d is $N, which is not allowed except temporarily\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">-&gt;</span><span class="identifier">allocation_id</span><span class="plain">, </span><span class="identifier">t</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Log this invariant failure</span> <span class="cwebmacronumber">54.1.1</span>&gt;
&lt;<span class="cwebmacro">Log this invariant failure</span> <span class="cwebmacronumber">55.1.1</span>&gt;
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP54">&#167;54</a>.</p>
<p class="endnote">This code is used in <a href="#SP55">&#167;55</a>.</p>
<p class="inwebparagraph"><a id="SP54_2"></a><b>&#167;54.2. </b>Rule (2): all annotations must be legal for the given node type.
<p class="inwebparagraph"><a id="SP55_2"></a><b>&#167;55.2. </b>Rule (2): all annotations must be legal for the given node type.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Check rule (2) of the invariant</span> <span class="cwebmacronumber">54.2</span>&gt; =
&lt;<span class="cwebmacrodefn">Check rule (2) of the invariant</span> <span class="cwebmacronumber">55.2</span>&gt; =
</code></p>
@ -1717,20 +1736,20 @@ among its children.
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"N%d is $N, which is not allowed to have annotation %d\</span><span class="plain">n</span><span class="string">"</span><span class="plain">,</span>
<span class="identifier">p</span><span class="plain">-&gt;</span><span class="identifier">allocation_id</span><span class="plain">, </span><span class="identifier">t</span><span class="plain">, </span><span class="identifier">pna</span><span class="plain">-</span><span class="element">&gt;kind_of_annotation</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">);</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Node %08x, ann %d\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">t</span><span class="plain">, </span><span class="identifier">pna</span><span class="plain">-</span><span class="element">&gt;kind_of_annotation</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Log this invariant failure</span> <span class="cwebmacronumber">54.1.1</span>&gt;
&lt;<span class="cwebmacro">Log this invariant failure</span> <span class="cwebmacronumber">55.1.1</span>&gt;
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP54">&#167;54</a>.</p>
<p class="endnote">This code is used in <a href="#SP55">&#167;55</a>.</p>
<p class="inwebparagraph"><a id="SP54_3"></a><b>&#167;54.3. </b>Rule (3): can this combination of parent and child exist?
<p class="inwebparagraph"><a id="SP55_3"></a><b>&#167;55.3. </b>Rule (3): can this combination of parent and child exist?
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Check rule (3) of the invariant</span> <span class="cwebmacronumber">54.3</span>&gt; =
&lt;<span class="cwebmacrodefn">Check rule (3) of the invariant</span> <span class="cwebmacronumber">55.3</span>&gt; =
</code></p>
@ -1744,20 +1763,20 @@ among its children.
<span class="reserved">if</span><span class="plain"> (!(</span><span class="functiontext">ParseTree::parentage_allowed</span><span class="plain">(</span><span class="identifier">t_parent</span><span class="plain">, </span><span class="identifier">parent_category</span><span class="plain">, </span><span class="identifier">t</span><span class="plain">, </span><span class="identifier">child_category</span><span class="plain">))) {</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"N%d is $N (category %d): should not be a child of $N (category %d)\</span><span class="plain">n</span><span class="string">"</span><span class="plain">,</span>
<span class="identifier">p</span><span class="plain">-&gt;</span><span class="identifier">allocation_id</span><span class="plain">, </span><span class="identifier">t</span><span class="plain">, </span><span class="identifier">child_category</span><span class="plain">, </span><span class="identifier">t_parent</span><span class="plain">, </span><span class="identifier">parent_category</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Log this invariant failure</span> <span class="cwebmacronumber">54.1.1</span>&gt;
&lt;<span class="cwebmacro">Log this invariant failure</span> <span class="cwebmacronumber">55.1.1</span>&gt;
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP54">&#167;54</a>.</p>
<p class="endnote">This code is used in <a href="#SP55">&#167;55</a>.</p>
<p class="inwebparagraph"><a id="SP54_4"></a><b>&#167;54.4. </b>Rule (4): The number of children has to be within the given extrema.
<p class="inwebparagraph"><a id="SP55_4"></a><b>&#167;55.4. </b>Rule (4): The number of children has to be within the given extrema.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Check rule (4) of the invariant</span> <span class="cwebmacronumber">54.4</span>&gt; =
&lt;<span class="cwebmacrodefn">Check rule (4) of the invariant</span> <span class="cwebmacronumber">55.4</span>&gt; =
</code></p>
@ -1765,21 +1784,21 @@ among its children.
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">children_count</span><span class="plain"> &lt; </span><span class="identifier">metadata</span><span class="plain">-</span><span class="element">&gt;min_children</span><span class="plain">) {</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"N%d has %d children, but min for $N is %d:\</span><span class="plain">n</span><span class="string">"</span><span class="plain">,</span>
<span class="identifier">p</span><span class="plain">-&gt;</span><span class="identifier">allocation_id</span><span class="plain">, </span><span class="identifier">children_count</span><span class="plain">, </span><span class="identifier">t</span><span class="plain">, </span><span class="identifier">metadata</span><span class="plain">-</span><span class="element">&gt;min_children</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Log this invariant failure</span> <span class="cwebmacronumber">54.1.1</span>&gt;
&lt;<span class="cwebmacro">Log this invariant failure</span> <span class="cwebmacronumber">55.1.1</span>&gt;
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">children_count</span><span class="plain"> &gt; </span><span class="identifier">metadata</span><span class="plain">-</span><span class="element">&gt;max_children</span><span class="plain">) {</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"N%d has %d children, but max for $N is %d:\</span><span class="plain">n</span><span class="string">"</span><span class="plain">,</span>
<span class="identifier">p</span><span class="plain">-&gt;</span><span class="identifier">allocation_id</span><span class="plain">, </span><span class="identifier">children_count</span><span class="plain">, </span><span class="identifier">t</span><span class="plain">, </span><span class="identifier">metadata</span><span class="plain">-</span><span class="element">&gt;max_children</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Log this invariant failure</span> <span class="cwebmacronumber">54.1.1</span>&gt;
&lt;<span class="cwebmacro">Log this invariant failure</span> <span class="cwebmacronumber">55.1.1</span>&gt;
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP54">&#167;54</a>.</p>
<p class="endnote">This code is used in <a href="#SP55">&#167;55</a>.</p>
<p class="inwebparagraph"><a id="SP54_1_1"></a><b>&#167;54.1.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Log this invariant failure</span> <span class="cwebmacronumber">54.1.1</span>&gt; =
<p class="inwebparagraph"><a id="SP55_1_1"></a><b>&#167;55.1.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Log this invariant failure</span> <span class="cwebmacronumber">55.1.1</span>&gt; =
</code></p>
@ -1791,9 +1810,9 @@ among its children.
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP54_1">&#167;54.1</a>, <a href="#SP54_2">&#167;54.2</a>, <a href="#SP54_3">&#167;54.3</a>, <a href="#SP54_4">&#167;54.4</a> (twice).</p>
<p class="endnote">This code is used in <a href="#SP55_1">&#167;55.1</a>, <a href="#SP55_2">&#167;55.2</a>, <a href="#SP55_3">&#167;55.3</a>, <a href="#SP55_4">&#167;55.4</a> (twice).</p>
<p class="inwebparagraph"><a id="SP55"></a><b>&#167;55. Parentage rules. </b>It's mostly the case that node category determines whether one node can be
<p class="inwebparagraph"><a id="SP56"></a><b>&#167;56. Parentage rules. </b>It's mostly the case that node category determines whether one node can be
parent to another:
</p>
@ -1815,9 +1834,9 @@ parent to another:
<p class="inwebparagraph"></p>
<p class="endnote">The function ParseTree::make_parentage_allowed_table is used in <a href="#SP53">&#167;53</a>.</p>
<p class="endnote">The function ParseTree::make_parentage_allowed_table is used in <a href="#SP54">&#167;54</a>.</p>
<p class="inwebparagraph"><a id="SP56"></a><b>&#167;56. </b>But there are exceptions. Note that an <code class="display"><span class="extract">L2_NCAT</span></code> node can have no parent
<p class="inwebparagraph"><a id="SP57"></a><b>&#167;57. </b>But there are exceptions. Note that an <code class="display"><span class="extract">L2_NCAT</span></code> node can have no parent
at all, according to the broad rules above: in fact, it can, but only if
the parent is <code class="display"><span class="extract">HEADING_NT</span></code>.
</p>
@ -1841,9 +1860,9 @@ the parent is <code class="display"><span class="extract">HEADING_NT</span></cod
<p class="inwebparagraph"></p>
<p class="endnote">The function ParseTree::parentage_allowed is used in <a href="#SP54_3">&#167;54.3</a>.</p>
<p class="endnote">The function ParseTree::parentage_allowed is used in <a href="#SP55_3">&#167;55.3</a>.</p>
<p class="inwebparagraph"><a id="SP57"></a><b>&#167;57. Annotation rules. </b>This is on an altogether grander scale.
<p class="inwebparagraph"><a id="SP58"></a><b>&#167;58. Annotation rules. </b>This is on an altogether grander scale.
</p>
@ -1868,11 +1887,11 @@ the parent is <code class="display"><span class="extract">HEADING_NT</span></cod
<p class="inwebparagraph"></p>
<p class="endnote">The function ParseTree::allow_annotation is used in <a href="#SP58">&#167;58</a>.</p>
<p class="endnote">The function ParseTree::allow_annotation is used in <a href="#SP59">&#167;59</a>.</p>
<p class="endnote">The function ParseTree::allow_annotation_to_category is used in <a href="#SP58">&#167;58</a>.</p>
<p class="endnote">The function ParseTree::allow_annotation_to_category is used in <a href="#SP59">&#167;59</a>.</p>
<p class="inwebparagraph"><a id="SP58"></a><b>&#167;58. </b>The eagle-eyed observer will note that the <code class="display"><span class="extract">meaning</span></code> annotation is never
<p class="inwebparagraph"><a id="SP59"></a><b>&#167;59. </b>The eagle-eyed observer will note that the <code class="display"><span class="extract">meaning</span></code> annotation is never
allowed. In fact it does exist, but only for meaning-coded parse nodes, which
never exist inside trees and are used only as parsing intermediates. So we
never see this annotation here.
@ -1904,11 +1923,11 @@ never see this annotation here.
<p class="inwebparagraph"></p>
<p class="endnote">The function ParseTree::make_annotation_allowed_table is used in <a href="#SP53">&#167;53</a>.</p>
<p class="endnote">The function ParseTree::make_annotation_allowed_table is used in <a href="#SP54">&#167;54</a>.</p>
<p class="endnote">The function ParseTree::annotation_allowed is used in <a href="#SP25">&#167;25</a>, <a href="#SP54_2">&#167;54.2</a>.</p>
<p class="endnote">The function ParseTree::annotation_allowed is used in <a href="#SP25">&#167;25</a>, <a href="#SP55_2">&#167;55.2</a>.</p>
<p class="inwebparagraph"><a id="SP59"></a><b>&#167;59. Ambiguity subtrees. </b></p>
<p class="inwebparagraph"><a id="SP60"></a><b>&#167;60. Ambiguity subtrees. </b></p>
<pre class="display">

View file

@ -235,20 +235,7 @@ structure and initialiser:
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">PARSE_TREE_TRAVERSE_TYPE</span><span class="plain"> </span><span class="reserved">void</span>
<span class="definitionkeyword">define</span> <span class="constant">SENTENCE_NODE</span><span class="plain"> </span><span class="functiontext">Basics::sentence_level</span>
</pre>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Basics::sentence_level</span><span class="plain">(</span><span class="constant">node_type_t</span><span class="plain"> </span><span class="identifier">t</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="constant">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Basics::sentence_level appears nowhere else.</p>
<hr class="tocbar">
<ul class="toc"><li><i>(This section begins Chapter 1: Everything.)</i></li><li><a href="1-pc.html">Continue with 'Program Control'</a></li></ul><hr class="tocbar">
<!--End of weave-->

View file

@ -194,7 +194,6 @@ foundation module does that automatically.)
<p class="endnote">The function WordsModule::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-->
</main>
</body>

View file

@ -4,164 +4,236 @@ A command-line interface for Inbuild functions which are not part of the
normal operation of the Inform compiler.
@h Main routine.
When Inbuild is called at the command line, it begins at |main|, like all C
programs.
@d INTOOL_NAME "inbuild"
@e INSPECT_TTASK from 1
@e GRAPH_TTASK
@e NEEDS_TTASK
@e ARCHIVE_TTASK
@e ARCHIVE_TO_TTASK
@e MISSING_TTASK
@e BUILD_TTASK
@e REBUILD_TTASK
@e COPY_TO_TTASK
@e SYNC_TO_TTASK
Inbuild manages "copies", which are instances of programs or resources found
somewhere in the file system. The copies which it acts on in a given run are
called "targets". The task of |main| is to read the command-line arguments,
set the following variables as needed, and produce a list of targets to work
on; then to carry out that work, and then shut down again.
=
int inbuild_task = INSPECT_TTASK;
pathname *path_to_inbuild = NULL;
pathname *path_to_tools = NULL;
int inbuild_task = INSPECT_TTASK;
int dry_run_mode = FALSE, build_trace_mode = FALSE;
linked_list *targets = NULL; /* of |inbuild_copy| */
inbuild_nest *destination_nest = NULL;
text_stream *filter_text = NULL;
text_stream *unit_test = NULL;
linked_list *inbuild_nest_list = NULL;
int main(int argc, char **argv) {
@<Start up the modules@>;
@<Read the command line@>;
@<Load the Preform grammar@>;
@<Complete the list of targets@>;
@<Act on the targets@>;
@<Shut down the modules@>;
return 0;
}
@<Start up the modules@> =
Foundation::start();
WordsModule::start();
SyntaxModule::start();
HTMLModule::start();
ArchModule::start();
InbuildModule::start();
targets = NEW_LINKED_LIST(inbuild_copy);
@<Read the command line@>;
@<Manage Inbuild@>;
if (Str::len(unit_test) > 0) dry_run_mode = TRUE;
int use = SHELL_METHODOLOGY;
if (dry_run_mode) use = DRY_RUN_METHODOLOGY;
build_methodology *BM;
if (path_to_tools) BM = BuildMethodology::new(path_to_tools, FALSE, use);
else BM = BuildMethodology::new(Pathnames::up(path_to_inbuild), TRUE, use);
if (build_trace_mode) trace_ibg = TRUE;
@ Preform is the crowning jewel of the |words| module, and parses excerpts of
natural-language text against a "grammar". The |inform7| executable makes very
heavy-duty use of Preform, but we use a much coarser grammar, which simply
breaks down source text into sentences, headings and so on. That grammar is
stored in a file called |Syntax.preform| inside the installation of Inbuild,
which is why we need to have worked out |path_to_inbuild| (the pathname at
which we are installed) already. Once the following is run, Preform is ready
for use.
@<Load the Preform grammar@> =
pathname *P = Pathnames::subfolder(path_to_inbuild, I"Tangled");
filename *S = Filenames::in_folder(P, I"Syntax.preform");
wording W = Preform::load_from_file(S);
Preform::parse_preform(W, FALSE);
CommandLine::play_back_log();
@ Targets can arise in three ways:
(1) They can be specified at the command line, either as bare names of files
or paths, or with |-contents-of D| for a directory |D|. By the time the code
in this paragraph runs, those targets are already in the list.
(2) They can be specified by a search request |-matching R| where |R| is a
list of requirements to match. We now add anything found that way. (We didn't
do so when reading the command line because at that time the search path for
nests did not yet exist: it is created when |Inbuild::optioneering_complete|
is called.)
(3) One copy is always special to Inbuild: the "project", usually an Inform
project bundle with a pathname like |Counterfeit Monkey.inform|. We go
through a little dance with |Inbuild::optioneering_complete| to ensure that
if a project is already in the target list, Inbuild will use that; and if not,
but the user has specified a project to Inbuild already with |-project| (a
command-line option recognised by |inbuild| but not by us), then we add that
to the target list. Tne net result is that however the user indicates interest
in an Inform project bundle, it becomes both the Inbuild current project, and
also a member of our target list. It follows that we cannot have two project
bundles in the target list, because they cannot both be the current project;
and to avoid the user being confused when only one is acted on, we throw an
error in this case.
@<Complete the list of targets@> =
linked_list *L = Main::list_of_targets();
inbuild_copy *proj = NULL, *C;
LOOP_OVER_LINKED_LIST(C, inbuild_copy, L)
if (C->edition->work->genre == project_bundle_genre)
proj = C;
proj = Inbuild::optioneering_complete(proj, FALSE);
if (proj) Main::add_target(proj);
int count = 0;
LOOP_OVER_LINKED_LIST(C, inbuild_copy, L)
if (C->edition->work->genre == project_bundle_genre)
count++;
if (count > 1)
Errors::with_text("can only work on one project bundle at a time", NULL);
if (Str::len(filter_text) > 0) Main::add_search_results_as_targets(filter_text);
@ We make the function call |Inbuild::go_operational| to signal to |inbuild|
that we want to start work now.
@<Act on the targets@> =
Inbuild::go_operational();
if (Str::len(unit_test) > 0) {
if (Str::eq(unit_test, I"compatibility")) Compatibility::test(STDOUT);
else Errors::with_text("no such unit test: %S", unit_test);
} else {
if (Str::len(filter_text) > 0) {
TEMPORARY_TEXT(errors);
inbuild_requirement *req = Requirements::from_text(filter_text, errors);
if (Str::len(errors) > 0) {
Errors::with_text("requirement malformed: %S", errors);
} else {
linked_list *L = NEW_LINKED_LIST(inbuild_search_result);
Nests::search_for(req, inbuild_nest_list, L);
inbuild_search_result *R;
LOOP_OVER_LINKED_LIST(R, inbuild_search_result, L) {
ADD_TO_LINKED_LIST(R->copy, inbuild_copy, targets);
}
}
DISCARD_TEXT(errors);
}
int use = SHELL_METHODOLOGY;
if (dry_run_mode) use = DRY_RUN_METHODOLOGY;
build_methodology *BM;
if (path_to_tools) BM = BuildMethodology::new(path_to_tools, FALSE, use);
else BM = BuildMethodology::new(Pathnames::up(path_to_inbuild), TRUE, use);
if (build_trace_mode) trace_ibg = TRUE;
linked_list *L = Main::list_of_targets();
inbuild_copy *C;
LOOP_OVER_LINKED_LIST(C, inbuild_copy, targets) {
switch (inbuild_task) {
case INSPECT_TTASK: Copies::inspect(STDOUT, C); break;
case GRAPH_TTASK: Copies::show_graph(STDOUT, C); break;
case NEEDS_TTASK: Copies::show_needs(STDOUT, C); break;
case ARCHIVE_TTASK:
destination_nest = Inbuild::materials_nest();
if (destination_nest == NULL)
Errors::with_text("no -project in use, so ignoring -archive", NULL);
else
Copies::archive(STDOUT, C, destination_nest, BM);
break;
case ARCHIVE_TO_TTASK: if (destination_nest) Copies::archive(STDOUT, C, destination_nest, BM); break;
case MISSING_TTASK: Copies::show_missing(STDOUT, C); break;
case BUILD_TTASK: Copies::build(STDOUT, C, BM); break;
case REBUILD_TTASK: Copies::rebuild(STDOUT, C, BM); break;
case COPY_TO_TTASK: if (destination_nest) Nests::copy_to(C, destination_nest, FALSE, BM); break;
case SYNC_TO_TTASK: if (destination_nest) Nests::copy_to(C, destination_nest, TRUE, BM); break;
}
}
LOOP_OVER_LINKED_LIST(C, inbuild_copy, L)
@<Carry out the required task on the copy C@>;
}
@ The list of possible tasks is as follows; they basically all correspond to
utility functions in the |inbuild| module, which we call.
@e INSPECT_TTASK from 1
@e GRAPH_TTASK
@e USE_NEEDS_TTASK
@e BUILD_NEEDS_TTASK
@e ARCHIVE_TTASK
@e ARCHIVE_TO_TTASK
@e USE_MISSING_TTASK
@e BUILD_MISSING_TTASK
@e BUILD_TTASK
@e REBUILD_TTASK
@e COPY_TO_TTASK
@e SYNC_TO_TTASK
@<Carry out the required task on the copy C@> =
switch (inbuild_task) {
case INSPECT_TTASK: Copies::inspect(STDOUT, C); break;
case GRAPH_TTASK: Copies::show_graph(STDOUT, C); break;
case USE_NEEDS_TTASK: Copies::show_needs(STDOUT, C, TRUE); break;
case BUILD_NEEDS_TTASK: Copies::show_needs(STDOUT, C, FALSE); break;
case ARCHIVE_TTASK:
destination_nest = Inbuild::materials_nest();
if (destination_nest == NULL)
Errors::with_text("no -project in use, so ignoring -archive", NULL);
else
Copies::archive(STDOUT, C, destination_nest, BM);
break;
case ARCHIVE_TO_TTASK: Copies::archive(STDOUT, C, destination_nest, BM); break;
case USE_MISSING_TTASK: Copies::show_missing(STDOUT, C, TRUE); break;
case BUILD_MISSING_TTASK: Copies::show_missing(STDOUT, C, FALSE); break;
case BUILD_TTASK: Copies::build(STDOUT, C, BM); break;
case REBUILD_TTASK: Copies::rebuild(STDOUT, C, BM); break;
case COPY_TO_TTASK: Nests::copy_to(C, destination_nest, FALSE, BM); break;
case SYNC_TO_TTASK: Nests::copy_to(C, destination_nest, TRUE, BM); break;
}
@<Shut down the modules@> =
ArchModule::end();
InbuildModule::end();
HTMLModule::end();
SyntaxModule::end();
WordsModule::end();
Foundation::end();
return 0;
@h Target list.
This where we keep the list of targets, in which no copy occurs more than
once. The following code runs quadratically in the number of targets, but for
Inbuild this number is never likely to be more than about 100 at a time.
=
linked_list *targets = NULL; /* of |inbuild_copy| */
void Main::add_target(inbuild_copy *to_add) {
if (targets == NULL) targets = NEW_LINKED_LIST(inbuild_copy);
int found = FALSE;
inbuild_copy *C;
LOOP_OVER_LINKED_LIST(C, inbuild_copy, targets)
if (C == to_add)
found = TRUE;
if (found == FALSE) ADD_TO_LINKED_LIST(to_add, inbuild_copy, targets);
}
@<Manage Inbuild@> =
if (LinkedLists::len(unsorted_nest_list) == 0)
Inbuild::add_nest(
Pathnames::from_text(I"inform7/Internal"), INTERNAL_NEST_TAG);
linked_list *Main::list_of_targets(void) {
if (targets == NULL) targets = NEW_LINKED_LIST(inbuild_copy);
return targets;
}
path_to_inbuild = Pathnames::installation_path("INBUILD_PATH", I"inbuild");
pathname *P = Pathnames::subfolder(path_to_inbuild, I"Tangled");
filename *S = Filenames::in_folder(P, I"Syntax.preform");
wording W = Preform::load_from_file(S);
Preform::parse_preform(W, FALSE);
CommandLine::play_back_log();
inbuild_copy *proj = NULL, *C;
LOOP_OVER_LINKED_LIST(C, inbuild_copy, targets)
if (C->edition->work->genre == project_bundle_genre) {
if (Str::len(project_bundle_request) > 0)
Errors::with_text("can only work on one project bundle at a time, so ignoring '%S'", C->edition->work->title);
else if (proj) Errors::with_text("can only work on one project bundle at a time, so ignoring '%S'", C->edition->work->title);
else proj = C;
}
proj = Inbuild::optioneering_complete(proj, FALSE);
if (proj) {
int found = FALSE;
LOOP_OVER_LINKED_LIST(C, inbuild_copy, targets)
if (C == proj)
found = TRUE;
if (found == FALSE) ADD_TO_LINKED_LIST(proj, inbuild_copy, targets);
void Main::add_search_results_as_targets(text_stream *req_text) {
TEMPORARY_TEXT(errors);
inbuild_requirement *req = Requirements::from_text(req_text, errors);
if (Str::len(errors) > 0) {
Errors::with_text("requirement malformed: %S", errors);
} else {
linked_list *L = NEW_LINKED_LIST(inbuild_search_result);
Nests::search_for(req, Inbuild::nest_list(), L);
inbuild_search_result *R;
LOOP_OVER_LINKED_LIST(R, inbuild_search_result, L)
Main::add_target(R->copy);
}
inbuild_nest_list = Inbuild::nest_list();
Inbuild::go_operational();
DISCARD_TEXT(errors);
}
@ =
void Main::load_many(pathname *P) {
void Main::add_directory_contents_targets(pathname *P) {
scan_directory *D = Directories::open(P);
TEMPORARY_TEXT(LEAFNAME);
while (Directories::next(D, LEAFNAME)) {
TEMPORARY_TEXT(FILENAME);
WRITE_TO(FILENAME, "%p%c%S", P, FOLDER_SEPARATOR, LEAFNAME);
Main::load_one(FILENAME, FALSE);
Main::add_file_or_path_as_target(FILENAME, FALSE);
DISCARD_TEXT(FILENAME);
}
DISCARD_TEXT(LEAFNAME);
Directories::close(D);
}
void Main::load_one(text_stream *arg, int throwing_error) {
void Main::add_file_or_path_as_target(text_stream *arg, int throwing_error) {
inbuild_copy *C = Copies::claim(arg);
if (C == NULL) {
if (throwing_error) Errors::with_text("unable to identify '%S'", arg);
return;
}
ADD_TO_LINKED_LIST(C, inbuild_copy, targets);
Main::add_target(C);
}
@h Command line.
Note the call below to |Inbuild::declare_options|, which adds a whole lot of
other options to the selection defined here.
@d INTOOL_NAME "inbuild"
@e BUILD_CLSW
@e REBUILD_CLSW
@e GRAPH_CLSW
@e NEEDS_CLSW
@e MISSING_CLSW
@e USE_NEEDS_CLSW
@e BUILD_NEEDS_CLSW
@e USE_MISSING_CLSW
@e BUILD_MISSING_CLSW
@e ARCHIVE_CLSW
@e ARCHIVE_TO_CLSW
@e INSPECT_CLSW
@ -190,10 +262,14 @@ other options to the selection defined here.
L"show target(s) but take no action");
CommandLine::declare_switch(GRAPH_CLSW, L"graph", 1,
L"show dependency graph of target(s) but take no action");
CommandLine::declare_switch(NEEDS_CLSW, L"needs", 1,
CommandLine::declare_switch(USE_NEEDS_CLSW, L"use-needs", 1,
L"show all the extensions, kits and so on needed to use");
CommandLine::declare_switch(BUILD_NEEDS_CLSW, L"build-needs", 1,
L"show all the extensions, kits and so on needed to build");
CommandLine::declare_switch(MISSING_CLSW, L"missing", 1,
L"show the extensions, kits and so on which are needed but missing");
CommandLine::declare_switch(USE_MISSING_CLSW, L"use-missing", 1,
L"show the extensions, kits and so on which are needed to use but missing");
CommandLine::declare_switch(BUILD_MISSING_CLSW, L"build-missing", 1,
L"show the extensions, kits and so on which are needed to build but missing");
CommandLine::declare_switch(ARCHIVE_CLSW, L"archive", 1,
L"sync copies of all extensions, kits and so on needed for -project into Materials");
CommandLine::declare_switch(ARCHIVE_TO_CLSW, L"archive-to", 2,
@ -214,6 +290,12 @@ other options to the selection defined here.
CommandLine::read(argc, argv, NULL, &Main::option, &Main::bareword);
if (LinkedLists::len(unsorted_nest_list) == 0)
Inbuild::add_nest(
Pathnames::from_text(I"inform7/Internal"), INTERNAL_NEST_TAG);
path_to_inbuild = Pathnames::installation_path("INBUILD_PATH", I"inbuild");
@ Here we handle those options not handled by the |inbuild| module.
=
@ -223,18 +305,19 @@ void Main::option(int id, int val, text_stream *arg, void *state) {
case REBUILD_CLSW: inbuild_task = REBUILD_TTASK; break;
case INSPECT_CLSW: inbuild_task = INSPECT_TTASK; break;
case GRAPH_CLSW: inbuild_task = GRAPH_TTASK; break;
case NEEDS_CLSW: inbuild_task = NEEDS_TTASK; break;
case USE_NEEDS_CLSW: inbuild_task = USE_NEEDS_TTASK; break;
case BUILD_NEEDS_CLSW: inbuild_task = BUILD_NEEDS_TTASK; break;
case ARCHIVE_TO_CLSW:
destination_nest = Nests::new(Pathnames::from_text(arg));
inbuild_task = ARCHIVE_TO_TTASK;
break;
case ARCHIVE_CLSW:
inbuild_task = ARCHIVE_TTASK;
break;
case MISSING_CLSW: inbuild_task = MISSING_TTASK; break;
case ARCHIVE_CLSW: inbuild_task = ARCHIVE_TTASK; break;
case USE_MISSING_CLSW: inbuild_task = USE_MISSING_TTASK; break;
case BUILD_MISSING_CLSW: inbuild_task = BUILD_MISSING_TTASK; break;
case TOOLS_CLSW: path_to_tools = Pathnames::from_text(arg); break;
case MATCHING_CLSW: filter_text = Str::duplicate(arg); break;
case CONTENTS_OF_CLSW: Main::load_many(Pathnames::from_text(arg)); break;
case CONTENTS_OF_CLSW:
Main::add_directory_contents_targets(Pathnames::from_text(arg)); break;
case DRY_CLSW: dry_run_mode = val; break;
case BUILD_TRACE_CLSW: build_trace_mode = val; break;
case COPY_TO_CLSW: inbuild_task = COPY_TO_TTASK;
@ -253,7 +336,7 @@ subordinate to any switch; we take it as the name of a copy.
=
void Main::bareword(int id, text_stream *arg, void *state) {
Main::load_one(arg, TRUE);
Main::add_file_or_path_as_target(arg, TRUE);
}
@h Interface to Words module.
@ -276,14 +359,14 @@ vocabulary_meaning Main::create_meaningless_vm(vocabulary_entry *ve) {
return vm;
}
@
@ We use the mighty Preform natural-language parser only a little when
Inbuild runs on its own, but it needs to be told what C type to use when
identifying natural languages.
@d PREFORM_LANGUAGE_TYPE struct inform_language
@h Interface to Syntax module.
Again, we make a fairly light use of |syntax| when Inbuild runs alone.
@d PREFORM_LANGUAGE_TYPE void
@d PARSE_TREE_TRAVERSE_TYPE void
@d CCCCSENTENCE_NODE Main::sentence_level
@d PARSE_TREE_METADATA_SETUP SourceText::node_metadata
=
int Main::sentence_level(node_type_t t) {
return FALSE;
}

View file

@ -16,5 +16,5 @@ Import: inbuild
Manual
Using Inbuild
Chapter 1: Delegation
Chapter 1: Inbuild outside of Inform
Main

View file

@ -1,5 +1,451 @@
Using Inbuild.
A brief user guide.
An introduction to the use of Inbuild on the command line.
@ Inbuild is a rudimentary build and package manager for the Inform tools.
@h What Inbuild is.
Inbuild is a rudimentary build and package manager for the Inform tools.
It consists of a large part of the front end of the Inform 7 compiler,
together with a command-line interface to access its functions. Because
it doesn't contain the middle or back ends of Inform 7, it cannot itself
compile Inform projects. But it can issue shell commands which have
this effect. When used that way, it's a little like the traditional Unix
build tool |make|.
It can also be used in |make| scripts itself. Inbuild returns an exit code
of 0 if successful, or else it throws errors to |stderr| and returns 1
if unsuccessful.
@h Installation.
When it runs, Inbuild needs to know where it is installed in the file
system. There is no completely foolproof, cross-platform way to know this
(on some Unixes, a program cannot determine its own location), so Inbuild
decides by the following set of rules:
(a) If the user, at the command line, specified |-at P|, for some path
|P|, then we use that.
(b) Otherwise, if the host operating system can indeed tell us where the
executable is, we use that. This is currently implemented only on MacOS,
Windows and Linux.
(c) Otherwise, if the environment variable |$INBUILD_PATH| exists and is
non-empty, we use that.
(d) And if all else fails, we assume that the location is |inbuild|, with
respect to the current working directory.
@h Basic concepts.
Inbuild manages "copies". A copy is an instance in the file system of an
asset like an Inform project, an extension, a kit of Inter code, and so on.
Those categories are called "genres". Any given copy will be a copy of
what is called an "edition", which in turn is a version of a "work".
For example, perhaps the user has two copies of version 3 of the extension
Locksmith by Emily Short, in different places in the file system, and also
a further copy of version 4. These are three different "copies", but only two
different "editions", and all are of the same "work". A work -- in this case.
Locksmith by Emily Short -- is identified by its title, author name and
genre -- in this case, an Inform extension.
@ Inbuild has a plethora of command-line options, but at its most basic, the
user should specify what to do and then give a list of things to do it to.
For example, here we run |-inspect| on a single copy, and get a one-line
description of what it is:
|$ inbuild/Tangled/inbuild -inspect 'inform7/Internal/Extensions/Emily Short/Locksmith.i7x'|
|extension: Locksmith by Emily Short v12 in directory inform7/Internal/Extensions/Emily Short|
This is reassuring -- the file which looks as if it ought to be a copy of
Locksmith actually is. Inbuild always looks at the contents of something,
and doesn't trust its location as any indication of what it is. For
example:
|$ inbuild/Tangled/inbuild -inspect junk/Mystery.i7x|
|extension: Complex Listing by Emily Short v9 in directory junk.|
If Inbuild can see that something is damaged in some way, it will report that.
For example,
|extension: Skeleton Keys by Emily Short - 1 error|
| 1. extension misworded: the opening line does not end 'begin(s) here'|
Only superficial problems can be spotted so far in advance of actually using
the software, but it's still helpful.
@h Graphs.
More ambitiously, we can look at the "graph" of a copy.
|$ inbuild/Tangled/inbuild -graph 'Basic Help Menu.i7x'|
|[c0] Basic Help Menu by Emily Short|
| --use---> [c26] Menus by Emily Short v3|
| --use---> [c34] Basic Screen Effects by Emily Short v7.140425|
The graph begins at the copy we asked for, and then continues through arrows
to other copies. It gives a systematic answer to the question "how do I
build or use this?". There are two kinds of arrows, use arrows and build
arrows. A use arrow from A to B means that you need to have B installed
in order to be able to use A. The above example, then, tells us that we
Menus in order to use Basic Help Menu, and we need Basic Screen Effects in
order to use Menus.
@ Now suppose we have an Inform project called |Menu Time.inform|, whose
source text is as follows:
|Include Basic Help Menu by Emily Short.|
||
|The French Laundry is a room.|
Once again, we can inspect this:
|inbuild/Tangled/inbuild -inspect 'Menu Time.inform'|
|projectbundle: Menu Time.inform at path Menu Time.inform|
We can also use |-graph|, but the output from this is surprisingly long,
because an innocent-looking source text like the above depends on many other
resources.
|[f59] Menu Time.inform/Build/output.ulx|
| --build-> [f58] Menu Time.inform/Build/auto.inf|
| --build-> [f57] Menu Time.inform/Build/auto.inf|
| --build-> [c0] Menu Time.inform|
| --build-> [c53] Basic Help Menu by Emily Short|
| --use---> [c47] Menus by Emily Short v3|
| --use---> [c55] Basic Screen Effects by Emily Short v7.140425|
| --build-> [f1] Menu Time.inform/Source/story.ni|
| --build-> [c12] BasicInformKit|
...and so on. What's going on here is that if the user wants to compile the
source text, that will (by default) mean making a story file in Glulx format,
called |output.ulx|, which sits inside the project bundle. So that is the top
node. Note that it is a "file node", not a "copy node", as we can see from the
|f| not |c| in its node number. This means that |output.ulx| is not a kind of
resource managed by Inbuild (like an extension, pr a project): it's just a
plain old file.
There's then a build arrow to another file called |auto.inf|. That's because
in order to build |output.ulx|, we first need |auto.inf| to exist. This is
a file in Inform 6 format. Something unexpected then happens: a further arrow
appears, and connects to another |auto.inf|. There aren't really two files
here: this is a device to capture the fact that generating |auto.inf| is a
two-stage process, with the intermediate results between the two stages
being held in memory rather than in a file. (These stages are, first,
converting I7 source text to inter code, and then code-generating that
inter code to I6.) Finally, though, we have a build arrow leading to the
place we might have expected to start: the |Menu Time.inform| project.
And that is where the graph branches outwards, because we need many
different resources in order to build |Menu Time.inform|. We finally see
that we need Basic Help Menu, and because that uses two other extensions
in turn, we'll need both of those as well. We need the actual file which
holds the source text inside the project bundle, |story.ni|. And then
we need various build-in extensions and kits, the first of which is
|BasicInformKit|, and that turns out to need lots of files to exist.
@ The full |-graph| is not always what we want to see. Often all we really
want to know is: what do I need to use, or to build, something?
The command |-use-needs| applied to our example extension gives:
|extension: Basic Help Menu by Emily Short|
| extension: Menus by Emily Short v3|
| extension: Basic Screen Effects by Emily Short v7.140425|
and applied to our example story gives just:
|projectbundle: Menu Time.inform|
That's because once Menu Time is built, nothing else is needed to use it.
On the other hand, |-build-needs| has the opposite effect. Applied to the
extension, we get:
|extension: Basic Help Menu by Emily Short|
because extensions need no building, so certainly nothing else is needed
to build them. But |-build-needs| on our story produces:
|projectbundle: Menu Time.inform|
| extension: Basic Help Menu by Emily Short|
| extension: Menus by Emily Short v3|
| extension: Basic Screen Effects by Emily Short v7.140425|
| kit: BasicInformKit|
| extension: Basic Inform by Graham Nelson v1|
| extension: English Language by Graham Nelson v1|
| kit: CommandParserKit|
| kit: WorldModelKit|
| extension: Standard Rules by Graham Nelson v6|
| extension: Standard Rules by Graham Nelson v6|
| language: English|
| kit: EnglishLanguageKit|
| extension: English Language by Graham Nelson v1|
And there it is: six extensions, four kits and one natural language definition
are needed. Two of the extensions are listed twice: that's because they are
each needed for two different reasons.
@ The version numbers listed above do not mean that only those exact versions
will do: they mean that this is (the best) version Inbuild has access to.
They're given because two different versions of the same extension might
make different choices about which other extensions to include. We can say
that version 3 of Menus wants to have Basic Screen Effects, but maybe someday
tbere will be a version 4 which doesn't need it.
Another issue to watch out for is that a copy may use different other copies
when compiled to different virtual machines. For example, an extension can
contain a heading of material "for Glulx only", and that heading might
comtain a line which includes another extension X. If so, then we use X on
Glulx but not on other architectures. We can also flag materual as being for
release only, or for debugging only.
Inbuild accepts the same command-line options as |inform7| does to specify
these: |-debug| for debugging features, |-release| for a release run, and
|-format=X| to select a virtual machine. (See the |inform7| documentation.)
@ Now suppose that the project asks for something impossible, with a line
such as:
>> Include Xylophones by Jimmy Stewart.
No such extension exists. If we look at the graph, or the |-build-needs| list
for the project, we see that it includes:
|missing extension: Xylophones by Jimmy Stewart, any version will do|
If we had instead written:
>> Include version 6.2 of Xylophones by Jimmy Stewart.
we would see:
|missing extension: Xylophones by Jimmy Stewart, need version in range [6.2,7-A)|
This slightly arcane mathematical notation means that Inform would accept any
version from 6.2 upwards, provided it still begins with a 6. This is a change
over pre-2020 versions of Inform, and has been brought about by the adoption
of the semantic version number standard.
Inbuild can list missing resources with |-use-missing| and |-build-missing|
respectively. At present, it has no means of fetching missing resources from
any central repository.
@h Building.
The graph for a copy tells Inbuild not only what is necessary for a build,
but also how to perform that build.
As noted above, not everything needs building. Extensions do not, in particular,
so running |-build| on one will do nothing. Kits do need building: what this
does is to "assimilate" the Unform 6-notation source files inside the kit into
binary files of Inter, one for each possible architecture.
But building is mostly done with projects. If we run:
|$ inbuild/Tangled/inbuild -build Example.inform|
then Inbuild will first build everthing needed to build the Example story
file, including everything needed to use the things needed to build it, and
so on; and then will build Example itself. As with the Unix utility |make|,
this is an incremental process, and looks at the timestamps of files to see
which steps are needed and which are not. If all the kits needed by Example
are up to date, then the kits will not be re-assimilated, and so on. If the
same project is built twice in a row, and nothing about it has changed since
the first time, the second |-build| does nothing.
Inbuild uses the graph to work out what needs to be done, and then issues
a series of shell commands to other Inform tools. If any of those commands
fail (returning a non-zero exit code) then the build process halts at once.
As noted above, the |-release| switch tells Inbuild that we want to go all
the way to a release of the project, not just a build. This makes a more
extensive graph, and is likely to mean that the final step followed by
Inbuild is a call to |inblorb|, the releasing tool for Inform.
|$ inbuild/Tangled/inbuild -release -build Example.inform|
Using the |-rebuild| command performs a build in a way which isn't incremental:
timestamps of files are ignored and everything is remade from scratch.
@ It takes a certain trust to just let Inbuild rip, and if you don't feel that
trust, adding the |-dry| switch causes shell commands to be printed out but
not actually executed -- a dry run. If you are debugging Inbuild, you may
also want to look at the copious output produced when |-build-trace| is used.
These are not commands: they simply modify the behaviour of |-build| and
|-rebuild|.
Inbuild uses a handful of standard Unix shell commands, but it also uses
|inform7|, |inform6|, |inblorb| and |inter|. To do that, it needs to know
where they are installed. By default, Inbuild assumes they are in the same
folder as Inbuild itself, side by side. If not, you can use |-tools P| to
specify path |P| as the home of the other Intools.
@h Specifying what to act on.
In all of the examples above, Inbuild is given just one copy to act on.
(That action may end up invplving lots of other copies, but only one is
mentioned on the command line.) In fact it's legal to give a list of
copies to work on, one at a time, except that only one of those copies
can be an Inform project. Multiple extensions, or kits, are fine.
We can also tell Inbuild to work on everything it finds in a given directory
|D| using |-contents-of D|:
|$ inbuild/Tangled/inbuild -inspect -contents-of inform7/Internal/Inter|
|kit: EnglishLanguageKit at path inform7/Internal/Inter/EnglishLanguageKit|
|kit: CommandParserKit at path inform7/Internal/Inter/CommandParserKit|
|kit: BasicInformExtrasKit at path inform7/Internal/Inter/BasicInformExtrasKit|
|kit: WorldModelKit at path inform7/Internal/Inter/WorldModelKit|
|kit: BasicInformKit at path inform7/Internal/Inter/BasicInformKit|
For compatibility with the |inform7| command line syntax, we can also specify
the project target using |-project|:
|$ inbuild/Tangled/inbuild -build -project Example.inform|
But this is quite unnecessary: the effect is the same as if |-project| had
been missed out.
@ Listing filenames or pathnames of copies on the command line, or using the
|-contents-of D| switch, is only possible if we know where in the file system
these copies are; and sometimes we do not.
If we instead specify |-matching R|, where |R| is a list of requirements,
Inbuild will act on every copy it can find which matches that. For example,
|$ inbuild/Tangled/inbuild -inspect -matching 'genre=kit'|
lists all the kits which Inbuild can see; and
|$ inbuild/Tangled/inbuild -inspect -matching 'genre=extension,author=Eric Eve'|
lists all extensions by Eric Eve which Inbuild can see. The legal clauses to
specify are |title|, |author|, |genre| and |version|. Note that |version=5.1.1|
would match version numbers 5.1.1, 5.1.2, 5.2.0, etc., but not 6 or above:
again, this is following semver conventions. To specify an explicit maximum
and minimum version number, use |max| and |min|. For example:
|-matching 'genre=extension,author=Emily Short,title=Locksmith,min=6.1-alpha.2,max=17.2|
@h Nests and searches.
When searching with |-matching R|, or indeed when running Inform and needing
to find certain resources, Inbuild looks inside what are called "nests".
A nest is a directory with structured subdirectories, which correspond to
the genres of copies put into them. For example, in the standard distribution
of Inform as a command-line tool, the path |inform7/Internal| is a nest:
this contains the extensions, kits and so on which are built in to Inform
when it's used as an app.
Inbuild recognises the following subdirectories of a nest as significant:
Templates
Pipelines
Inter
Languages
Extensions
Other subdirectories can also exist, and Inbuild ignores those. The above
five containers hold website templates (used by Inblorb), Inter pipelines,
kits, language definitions, and extensions. In the case of extensions, where
there may be very many in total, a further level of subdirectory is used
for the authpr's name. Thus:
|Extensions/Emily Short/Locksmith.i7x|
(In some early releases of Inform 7, it was legal for this file not to have
the |.i7x| extension: but now it is compulsory.)
As of 2020, nests can contain multiple versions of the same work. To do
this, they should have a filename (or pathname) which ends with |-vN|, where
|N| is semantic version number but with any dots replaced by underscores.
Thus, we can have e.g.:
|Extensions/Emily Short/Locksmith-v3_2.i7x|
|Extensions/Emily Short/Locksmith-v4_0_0-prealpha_13.i7x|
co-existing side by side. If the user asks to
>> Include Locksmith by Emily Short.
then version |4.0.0-prealpha.13| will be chosen, as the one with highest
precedence in this nest (but see below for how Inbuild chooses between
versions in the same nest). But if the user asks for
>> Include version 3 Locksmith by Emily Short.
then version |3.2| is the winner, as the highest-numbered extension in the
nest with the right major version number (3).
@ In most runs of the Inform compiler, three nests are used: the "internal"
one, so-called, which holds built-in extensions and is read-only; the
"external" one, which will be somewhere outside of the Inform GUI app, and
will hold additional extensions downloaded by the user; and the Materials
folder for an Inform project, which is a nest all by itself.
Inbuild looks for these as follows:
(a) |-internal N| tells Inbuild the path |N| for the internal nest; if this
is not given, the default is |inform7/Internal|.
(b) |-external N| tells Inbuild the path |N| for the external nest; if this
is not given, the default depends on the host operating system. For example,
on MacOS it will be |~/Library/Inform| (which is what the Inform GUI app
uses too if it is not sandboxed: if it is indeed sandboxed, then it will
have a deliberately obfuscated location which MacOS does not want tools
like ours to access externally).
(c) The Materials nest is always the Materials folder associated with the
project Inbuild is working on; if it isn't working on a project, then this
nest is of course not present.
In addition, extra nests can be specified with |-nest N|.
@ When Inbuild searches for some resource needed by Inform -- let's continue
to use the Locksmith extension as an example -- it always has some range of
version numbers in mind: it will only accept a version in that range. (The
range can be unlimited, in which case any version is acceptable.)
This may well produce multiple results: as noted above, we might have multiple
copies of Locksmith around. Inbuild first reduces the list to just those
whose version lies in the acceptable range. It then applies the following
rules:
(1) A copy in the Materials nest takes precedence over all others.
(2) Otherwise, all other copies take precendence over those in the
internal nest.
(3) Otherwise, semantic version number rules are used to determine which
copy had precedence.
Suppose the Materials folder for our project contains |Locksmith-v3_2.i7x|,
while the external folder contains |Locksmith-v3_3.i7x| and |Locksmith-v4.i7x|.
Then the sentence:
>> Include Locksmith by Emily Short.
would result in |Locksmith-v3_2.i7x| from Materials being used, even though
there's a later version in the external area: Materials always wins. But
>> Include version 4 of Locksmith by Emily Short.
would use |Locksmith-v4.i7x| from the external area, because the copy in the
Materials folder doesn't qualify.
@h Copy, sync and archive.
Clerical work is generally best done automatically, and Inbuild offers some
useful filing commands.
The command |-copy-to N| makes a duplicate copy in the nest |N|. For example:
|$ inbuild/Tangled/inbuild -inspect junk/Mystery.i7x|
|extension: Complex Listing by Emily Short v9 in directory junk.|
|$ inbuild/Tangled/inbuild -copy-to MyNest junk/Mystery.i7x|
|cp -f 'junk/Mystery.i7x' 'MyNest/Extensions/Emily Short/Complex Listing-v9.i7x'|
Note that Inbuild replies to the |-copy-to N| command by executing a shell
command to copy what is, in this case, a single file. As when building, the
|-dry| option puts Inbuild into dry-run mode, where it prints the commands it
would like to execute but doesn't execute them.
The command |-sync-to N| is similar, but will overwrite any existing copy
already in |N|, rather than producing an error if a collision occurs.
@ The |-archive-to N| command performs |-sync-to N| on any resource needed
to build the copy it is working on (with one exception, for technical reasons:
the configuration file telling Inform how to use the English natural language).
This is really only useful for Inform projects, and the abbreviated form
|-archive| performs |-archive-to| to the Materials folder for a project.
The net effect of this is that all extensions needed to build a story file
are gathered, with their correct versions, into the Materials folder; this
means that if the project and its Materials are moved to a different user's
computer, where a quite different set of extensions may be installed, then
the project will still work exactly as it originally did.

View file

@ -251,9 +251,12 @@ dependency graphs.
inform_project *Inbuild::go_operational(void) {
RUN_ONLY_IN_PHASE(PROJECTED_INBUILD_PHASE)
inbuild_phase = GOING_OPERATIONAL_INBUILD_PHASE;
inform_project *P = Inbuild::project();
if (P) Copies::go_operational(P->as_copy);
inbuild_copy *C;
LOOP_OVER(C, inbuild_copy)
Copies::go_operational(C);
if ((P == NULL) || (C != P->as_copy))
Copies::go_operational(C);
inbuild_phase = OPERATIONAL_INBUILD_PHASE;
if (census_mode) Extensions::Census::handle_census_mode();
return Inbuild::project();

View file

@ -68,27 +68,28 @@ void Copies::scan(inbuild_copy *C) {
}
void Copies::build(OUTPUT_STREAM, inbuild_copy *C, build_methodology *BM) {
VMETHOD_CALL(C->edition->work->genre, GENRE_BUILD_COPY_MTID, OUT, C, BM, FALSE, FALSE);
VMETHOD_CALL(C->edition->work->genre, GENRE_BUILD_COPY_MTID, OUT, C, BM, TRUE, FALSE, FALSE);
}
void Copies::rebuild(OUTPUT_STREAM, inbuild_copy *C, build_methodology *BM) {
VMETHOD_CALL(C->edition->work->genre, GENRE_BUILD_COPY_MTID, OUT, C, BM, TRUE, FALSE);
VMETHOD_CALL(C->edition->work->genre, GENRE_BUILD_COPY_MTID, OUT, C, BM, FALSE, TRUE, FALSE);
}
void Copies::show_graph(OUTPUT_STREAM, inbuild_copy *C) {
VMETHOD_CALL(C->edition->work->genre, GENRE_BUILD_COPY_MTID, OUT, C, NULL, FALSE, TRUE);
VMETHOD_CALL(C->edition->work->genre, GENRE_BUILD_COPY_MTID, OUT, C, NULL, FALSE, FALSE, TRUE);
}
void Copies::show_needs(OUTPUT_STREAM, inbuild_copy *C) {
Graphs::show_needs(OUT, C->vertex);
void Copies::show_needs(OUTPUT_STREAM, inbuild_copy *C, int uses_only) {
VMETHOD_CALL(C->edition->work->genre, GENRE_BUILD_COPY_MTID, OUT, C, NULL, FALSE, FALSE, FALSE);
Graphs::show_needs(OUT, C->vertex, uses_only);
}
void Copies::show_missing(OUTPUT_STREAM, inbuild_copy *C) {
int N = Graphs::show_missing(OUT, C->vertex);
void Copies::show_missing(OUTPUT_STREAM, inbuild_copy *C, int uses_only) {
VMETHOD_CALL(C->edition->work->genre, GENRE_BUILD_COPY_MTID, OUT, C, NULL, FALSE, FALSE, FALSE);
int N = Graphs::show_missing(OUT, C->vertex, uses_only);
if (N == 0) WRITE("Nothing is missing\n");
}
void Copies::archive(OUTPUT_STREAM, inbuild_copy *C, inbuild_nest *N, build_methodology *BM) {
int NM = Graphs::show_missing(OUT, C->vertex);
VMETHOD_CALL(C->edition->work->genre, GENRE_BUILD_COPY_MTID, OUT, C, NULL, FALSE, FALSE, FALSE);
int NM = Graphs::show_missing(OUT, C->vertex, FALSE);
if (NM > 0) WRITE("Because there are missing resources, -archive is cancelled\n");
else {
Graphs::archive(OUT, C->vertex, N, BM);
}
else if (N) Graphs::archive(OUT, C->vertex, N, BM);
}
int Copies::source_text_has_been_read(inbuild_copy *C) {
@ -139,7 +140,8 @@ void Copies::inspect(OUTPUT_STREAM, inbuild_copy *C) {
WRITE(" at path %p", C->location_if_path);
}
if (C->location_if_file) {
WRITE(" in directory %p", Filenames::get_path_to(C->location_if_file));
pathname *P = Filenames::get_path_to(C->location_if_file);
if (P) WRITE(" in directory %p", P);
}
int N = LinkedLists::len(C->errors_reading_source_text);
if (N > 0) {

View file

@ -67,4 +67,4 @@ VMETHOD_TYPE(GENRE_READ_SOURCE_TEXT_FOR_MTID,
inbuild_genre *gen, inbuild_copy *C)
VMETHOD_TYPE(GENRE_BUILD_COPY_MTID,
inbuild_genre *gen, text_stream *OUT, inbuild_copy *C,
build_methodology *BM, int rebuild, int describe_only)
build_methodology *BM, int build, int rebuild, int describe_only)

View file

@ -99,7 +99,9 @@ int Nests::better_result(inbuild_search_result *R1, inbuild_search_result *R2) {
void Nests::copy_to(inbuild_copy *C, inbuild_nest *destination_nest, int syncing,
build_methodology *meth) {
VMETHOD_CALL(C->edition->work->genre, GENRE_COPY_TO_NEST_MTID, C, destination_nest, syncing, meth);
if (destination_nest)
VMETHOD_CALL(C->edition->work->genre, GENRE_COPY_TO_NEST_MTID,
C, destination_nest, syncing, meth);
}
void Nests::overwrite_error(inbuild_nest *N, inbuild_copy *C) {

View file

@ -82,6 +82,8 @@ void Graphs::need_this_to_build(build_vertex *from, build_vertex *to) {
build_vertex *V;
LOOP_OVER_LINKED_LIST(V, build_vertex, from->build_edges)
if (V == to) return;
// Graphs::describe(STDOUT, from, FALSE); PRINT(" needs ");
// Graphs::describe(STDOUT, to, FALSE); PRINT("\n");
ADD_TO_LINKED_LIST(to, build_vertex, from->build_edges);
}
@ -146,11 +148,11 @@ void Graphs::describe_vertex(OUTPUT_STREAM, build_vertex *V) {
}
}
void Graphs::show_needs(OUTPUT_STREAM, build_vertex *V) {
Graphs::show_needs_r(OUT, V, 0, 0);
void Graphs::show_needs(OUTPUT_STREAM, build_vertex *V, int uses_only) {
Graphs::show_needs_r(OUT, V, 0, 0, uses_only);
}
void Graphs::show_needs_r(OUTPUT_STREAM, build_vertex *V, int depth, int true_depth) {
void Graphs::show_needs_r(OUTPUT_STREAM, build_vertex *V, int depth, int true_depth, int uses_only) {
if (V->type == COPY_VERTEX) {
for (int i=0; i<depth; i++) WRITE(" ");
inbuild_copy *C = V->buildable_if_copy;
@ -171,19 +173,20 @@ void Graphs::show_needs_r(OUTPUT_STREAM, build_vertex *V, int depth, int true_de
depth++;
}
build_vertex *W;
LOOP_OVER_LINKED_LIST(W, build_vertex, V->build_edges)
Graphs::show_needs_r(OUT, W, depth, true_depth+1);
if ((V->type == COPY_VERTEX) && (true_depth > 0)) {
if (uses_only == FALSE)
LOOP_OVER_LINKED_LIST(W, build_vertex, V->build_edges)
Graphs::show_needs_r(OUT, W, depth, true_depth+1, uses_only);
if ((V->type == COPY_VERTEX) && ((true_depth > 0) || (uses_only))) {
LOOP_OVER_LINKED_LIST(W, build_vertex, V->use_edges)
Graphs::show_needs_r(OUT, W, depth, true_depth+1);
Graphs::show_needs_r(OUT, W, depth, true_depth+1, uses_only);
}
}
int Graphs::show_missing(OUTPUT_STREAM, build_vertex *V) {
return Graphs::show_missing_r(OUT, V, 0);
int Graphs::show_missing(OUTPUT_STREAM, build_vertex *V, int uses_only) {
return Graphs::show_missing_r(OUT, V, 0, uses_only);
}
int Graphs::show_missing_r(OUTPUT_STREAM, build_vertex *V, int true_depth) {
int Graphs::show_missing_r(OUTPUT_STREAM, build_vertex *V, int true_depth, int uses_only) {
int N = 0;
if (V->type == REQUIREMENT_VERTEX) {
WRITE("missing %S: ", V->findable->work->genre->genre_name);
@ -197,11 +200,12 @@ int Graphs::show_missing_r(OUTPUT_STREAM, build_vertex *V, int true_depth) {
N = 1;
}
build_vertex *W;
LOOP_OVER_LINKED_LIST(W, build_vertex, V->build_edges)
N += Graphs::show_missing_r(OUT, W, true_depth+1);
if ((V->type == COPY_VERTEX) && (true_depth > 0)) {
if (uses_only == FALSE)
LOOP_OVER_LINKED_LIST(W, build_vertex, V->build_edges)
N += Graphs::show_missing_r(OUT, W, true_depth+1, uses_only);
if ((V->type == COPY_VERTEX) && ((true_depth > 0) || (uses_only))) {
LOOP_OVER_LINKED_LIST(W, build_vertex, V->use_edges)
N += Graphs::show_missing_r(OUT, W, true_depth+1);
N += Graphs::show_missing_r(OUT, W, true_depth+1, uses_only);
}
return N;
}
@ -311,7 +315,7 @@ int Graphs::build_r(OUTPUT_STREAM, int gb, build_vertex *V, build_methodology *m
if (V->built) return TRUE;
int changes_so_far = *changes;
STREAM_INDENT(STDOUT);
if (trace_ibg) { STREAM_INDENT(STDOUT); }
int rv = TRUE;
build_vertex *W;
LOOP_OVER_LINKED_LIST(W, build_vertex, V->build_edges)
@ -321,7 +325,7 @@ int Graphs::build_r(OUTPUT_STREAM, int gb, build_vertex *V, build_methodology *m
LOOP_OVER_LINKED_LIST(W, build_vertex, V->use_edges)
if (rv)
rv = Graphs::build_r(OUT, gb & (BUILD_GB + FORCE_GB), W, meth, changes);
STREAM_OUTDENT(STDOUT);
if (trace_ibg) { STREAM_OUTDENT(STDOUT); }
if (rv) {
int needs_building = FALSE;
if ((gb & FORCE_GB) || (V->force_this)) needs_building = TRUE;

View file

@ -22,6 +22,7 @@ void ExtensionManager::start(void) {
METHOD_ADD(extension_genre, GENRE_SEARCH_NEST_FOR_MTID, ExtensionManager::search_nest_for);
METHOD_ADD(extension_genre, GENRE_COPY_TO_NEST_MTID, ExtensionManager::copy_to_nest);
METHOD_ADD(extension_genre, GENRE_READ_SOURCE_TEXT_FOR_MTID, ExtensionManager::read_source_text_for);
METHOD_ADD(extension_genre, GENRE_BUILD_COPY_MTID, ExtensionManager::build);
}
void ExtensionManager::write_work(inbuild_genre *gen, OUTPUT_STREAM, inbuild_work *work) {
@ -193,10 +194,34 @@ void ExtensionManager::copy_to_nest(inbuild_genre *gen, inbuild_copy *C, inbuild
}
@h Build graph.
The build graph for an extension is just a single node: you don't need to
build an extension at all.
As far as building goes, the build graph for an extension is just a single node:
you don't need to build an extension at all. But it may well have use edges,
thanks to including other extensions, and because of that we have to read the
source text before we can do anything with the graph.
We don't do this at the going operational stage because that would be
inefficient and might cause VM-related problems -- it would mean that many
extraneous extensions, discovered only when scanning some directory, would
be read in as source text; and some of those might not be compatible with
the current VM settings.
=
void ExtensionManager::build(inbuild_genre *gen, text_stream *OUT, inbuild_copy *C,
build_methodology *BM, int build, int rebuild, int describe_only) {
ExtensionManager::ensure_graphed(C);
if (describe_only) Graphs::describe(OUT, C->vertex, TRUE);
else if (rebuild) Graphs::rebuild(OUT, C->vertex, BM);
else if (build) Graphs::build(OUT, C->vertex, BM);
}
void ExtensionManager::ensure_graphed(inbuild_copy *C) {
Copies::read_source_text_for(C);
Inclusions::traverse(C, ExtensionManager::from_copy(C)->syntax_tree);
build_vertex *V;
LOOP_OVER_LINKED_LIST(V, build_vertex, C->vertex->use_edges)
ExtensionManager::ensure_graphed(V->buildable_if_copy);
}
void ExtensionManager::build_vertex(inbuild_copy *C) {
Graphs::copy_vertex(C);
}

View file

@ -169,10 +169,10 @@ void KitManager::copy_to_nest(inbuild_genre *gen, inbuild_copy *C, inbuild_nest
=
void KitManager::build(inbuild_genre *gen, text_stream *OUT, inbuild_copy *C,
build_methodology *BM, int rebuild, int describe_only) {
build_methodology *BM, int build, int rebuild, int describe_only) {
if (describe_only) Graphs::describe(OUT, C->vertex, TRUE);
else if (rebuild) Graphs::rebuild(OUT, C->vertex, BM);
else Graphs::build(OUT, C->vertex, BM);
else if (build) Graphs::build(OUT, C->vertex, BM);
}
void KitManager::build_vertex(inbuild_copy *C) {

View file

@ -90,12 +90,12 @@ void ProjectBundleManager::copy_to_nest(inbuild_genre *gen, inbuild_copy *C, inb
=
void ProjectBundleManager::build(inbuild_genre *gen, text_stream *OUT, inbuild_copy *C,
build_methodology *BM, int rebuild, int describe_only) {
build_methodology *BM, int build, int rebuild, int describe_only) {
inform_project *project = ProjectBundleManager::from_copy(C);
build_vertex *V = project->chosen_build_target;
if (describe_only) Graphs::describe(OUT, V, TRUE);
else if (rebuild) Graphs::rebuild(OUT, V, BM);
else Graphs::build(OUT, V, BM);
else if (build) Graphs::build(OUT, V, BM);
}
@ The build graph for a project will need further thought...

View file

@ -93,12 +93,12 @@ void ProjectFileManager::copy_to_nest(inbuild_genre *gen, inbuild_copy *C, inbui
=
void ProjectFileManager::build(inbuild_genre *gen, text_stream *OUT, inbuild_copy *C,
build_methodology *BM, int rebuild, int describe_only) {
build_methodology *BM, int build, int rebuild, int describe_only) {
inform_project *project = ProjectBundleManager::from_copy(C);
build_vertex *V = project->chosen_build_target;
if (describe_only) Graphs::describe(OUT, V, TRUE);
else if (rebuild) Graphs::rebuild(OUT, V, BM);
else Graphs::build(OUT, V, BM);
else if (build) Graphs::build(OUT, V, BM);
}
@ The build graph for a project will need further thought...

View file

@ -68,7 +68,10 @@ void Inclusions::visit(parse_node_tree *T, parse_node *pn, parse_node *last_H0,
if ((last_H0) && (ParseTree::int_annotation(last_H0, implied_heading_ANNOT) != TRUE)) {
build_vertex *V = Inclusions::spawned_from_vertex(last_H0);
build_vertex *EV = E->as_copy->vertex;
Graphs::need_this_to_build(V, EV);
if (V->buildable_if_copy->edition->work->genre == extension_genre)
Graphs::need_this_to_use(V, EV);
else
Graphs::need_this_to_build(V, EV);
}
}