mirror of
https://github.com/ganelson/inform.git
synced 2024-06-26 04:00:43 +03:00
Redrafted most of Chapter 3 of inbuild
This commit is contained in:
parent
e76d02da6e
commit
123b9c166e
|
@ -1,6 +1,6 @@
|
|||
# Inform 7
|
||||
|
||||
v10.1.0-alpha.1+6Q30 'Krypton' (29 March 2020)
|
||||
v10.1.0-alpha.1+6Q31 'Krypton' (30 March 2020)
|
||||
|
||||
## About Inform 7
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Prerelease: alpha.1
|
||||
Build Date: 29 March 2020
|
||||
Build Number: 6Q30
|
||||
Build Date: 30 March 2020
|
||||
Build Number: 6Q31
|
||||
|
|
|
@ -91,7 +91,7 @@ stored here.
|
|||
|
||||
<p class="inwebparagraph"></p>
|
||||
|
||||
<p class="endnote">The structure inbuild_copy is accessed in 1/ic, 2/nst, 3/bg, 3/bs2, 3/is, 3/is2, 3/is3, 3/is4, 4/km, 4/em, 4/lm, 4/pbm, 4/pfm, 4/tm, 4/pm, 5/kts, 5/es, 5/ed, 5/ed2, 5/ec, 5/ps, 5/ls, 6/hdn, 6/inc and here.</p>
|
||||
<p class="endnote">The structure inbuild_copy is accessed in 1/ic, 2/nst, 3/bg, 3/ib, 3/bs2, 3/is, 3/is2, 3/is3, 3/is4, 4/km, 4/em, 4/lm, 4/pbm, 4/pfm, 4/tm, 4/pm, 5/kts, 5/es, 5/ed, 5/ed2, 5/ec, 5/ps, 5/ls, 6/hdn, 6/inc and here.</p>
|
||||
|
||||
<p class="inwebparagraph"><a id="SP2"></a><b>§2. </b>Copies are created by the managers for the respective genres, usually when
|
||||
claiming. If you are a manager, do not call this...
|
||||
|
@ -196,7 +196,7 @@ for later reporting. These are stored in a list.
|
|||
|
||||
<p class="inwebparagraph"></p>
|
||||
|
||||
<p class="endnote">The function Copies::write_copy is used in 3/bg (<a href="3-bg.html#SP1">§1</a>).</p>
|
||||
<p class="endnote">The function Copies::write_copy is used in 3/bg (<a href="3-bg.html#SP5">§5</a>, <a href="3-bg.html#SP6">§6</a>, <a href="3-bg.html#SP8_1">§8.1</a>).</p>
|
||||
|
||||
<p class="inwebparagraph"><a id="SP7"></a><b>§7. Reading source text. </b></p>
|
||||
|
||||
|
@ -279,12 +279,12 @@ its main task: building an Inform project.
|
|||
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Copies::build</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain">, </span><span class="reserved">build_methodology</span><span class="plain"> *</span><span class="identifier">BM</span><span class="plain">) {</span>
|
||||
<span class="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">V</span><span class="plain"> = </span><span class="identifier">C</span><span class="plain">-</span><span class="element">>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">>edition</span><span class="plain">-</span><span class="element">>work</span><span class="plain">-</span><span class="element">>genre</span><span class="plain">, </span><span class="constant">GENRE_BUILDING_SOON_MTID</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="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="functiontext">IncrementalBuild::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>
|
||||
<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="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">V</span><span class="plain"> = </span><span class="identifier">C</span><span class="plain">-</span><span class="element">>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">>edition</span><span class="plain">-</span><span class="element">>work</span><span class="plain">-</span><span class="element">>genre</span><span class="plain">, </span><span class="constant">GENRE_BUILDING_SOON_MTID</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="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="functiontext">IncrementalBuild::rebuild</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">, </span><span class="identifier">BM</span><span class="plain">);</span>
|
||||
<span class="plain">}</span>
|
||||
</pre>
|
||||
|
||||
|
@ -365,7 +365,7 @@ its main task: building an Inform project.
|
|||
|
||||
<p class="inwebparagraph"></p>
|
||||
|
||||
<p class="endnote">The function Copies::copy_to is used in 3/bg (<a href="3-bg.html#SP1">§1</a>).</p>
|
||||
<p class="endnote">The function Copies::copy_to is used in 3/bg (<a href="3-bg.html#SP8_1">§8.1</a>).</p>
|
||||
|
||||
<p class="endnote">The function Copies::overwrite_error is used in 4/km (<a href="4-km.html#SP6">§6</a>), 4/em (<a href="4-em.html#SP8">§8</a>), 4/lm (<a href="4-lm.html#SP7">§7</a>), 4/tm (<a href="4-tm.html#SP6">§6</a>), 4/pm (<a href="4-pm.html#SP7">§7</a>).</p>
|
||||
|
||||
|
|
|
@ -121,7 +121,7 @@ nest depends only on its genre.
|
|||
|
||||
<p class="inwebparagraph"></p>
|
||||
|
||||
<p class="endnote">The function Genres::stored_in_nests is used in 3/bg (<a href="3-bg.html#SP1">§1</a>).</p>
|
||||
<p class="endnote">The function Genres::stored_in_nests is used in 3/bg (<a href="3-bg.html#SP8">§8</a>).</p>
|
||||
|
||||
<p class="inwebparagraph"><a id="SP3"></a><b>§3. </b>The requirements parser needs to identify genres by name, so:
|
||||
</p>
|
||||
|
|
|
@ -282,7 +282,7 @@ empty text is legal here, and produces an unlimited requirement.
|
|||
|
||||
<p class="inwebparagraph"></p>
|
||||
|
||||
<p class="endnote">The function Requirements::write is used in 3/bg (<a href="3-bg.html#SP1">§1</a>).</p>
|
||||
<p class="endnote">The function Requirements::write is used in 3/bg (<a href="3-bg.html#SP5">§5</a>).</p>
|
||||
|
||||
<p class="inwebparagraph"><a id="SP7"></a><b>§7. Meeting requirements. </b>Finally, we actually use these intricacies for something. Given an edition,
|
||||
we return <code class="display"><span class="extract">TRUE</span></code> if it meets the requirements and <code class="display"><span class="extract">FALSE</span></code> if it does not.
|
||||
|
|
|
@ -225,7 +225,7 @@ begins at the start of the text, after a hyphen, or after a bracket. Thus
|
|||
|
||||
<p class="inwebparagraph"></p>
|
||||
|
||||
<p class="endnote">The function Works::write is used in 2/edt (<a href="2-edt.html#SP1">§1</a>), 3/bg (<a href="3-bg.html#SP1">§1</a>).</p>
|
||||
<p class="endnote">The function Works::write is used in 2/edt (<a href="2-edt.html#SP1">§1</a>), 3/bg (<a href="3-bg.html#SP6">§6</a>, <a href="3-bg.html#SP7">§7</a>).</p>
|
||||
|
||||
<p class="endnote">The function Works::write_to_HTML_file is used in <a href="#SP6">§6</a>, 5/ed (<a href="5-ed.html#SP19_2">§19.2</a>), 5/ed2 (<a href="5-ed2.html#SP3_2_1">§3.2.1</a>).</p>
|
||||
|
||||
|
|
|
@ -57,45 +57,69 @@
|
|||
<main role="main">
|
||||
|
||||
<!--Weave of '3/bg' generated by 7-->
|
||||
<ul class="crumbs"><li><a href="../webs.html">Source</a></li><li><a href="../compiler.html">Compiler Modules</a></li><li><a href="index.html">inbuild</a></li><li><a href="index.html#3">Chapter 3: Incremental Builds</a></li><li><b>Build Graphs</b></li></ul><p class="purpose">Graphs in which vertices correspond to files or copies, and arrows to dependencies between them.</p>
|
||||
<ul class="crumbs"><li><a href="../webs.html">Source</a></li><li><a href="../compiler.html">Compiler Modules</a></li><li><a href="index.html">inbuild</a></li><li><a href="index.html#3">Chapter 3: Incremental Builds</a></li><li><b>Build Graphs</b></li></ul><p class="purpose">Graphs in which vertices correspond to files or copies, and edges to dependencies between them.</p>
|
||||
|
||||
<ul class="toc"><li><a href="#SP1">§1. Build graphs</a></li></ul><hr class="tocbar">
|
||||
<ul class="toc"><li><a href="#SP1">§1. Build graphs</a></li><li><a href="#SP2">§2. Creation</a></li><li><a href="#SP5">§5. Writing</a></li><li><a href="#SP8">§8. Archiving</a></li></ul><hr class="tocbar">
|
||||
|
||||
<p class="inwebparagraph"><a id="SP1"></a><b>§1. Build graphs. </b>These are directed acyclic graphs which show what depends on what in the
|
||||
building process. If an arrow leads from A to B, then B must be built before
|
||||
A can be built.
|
||||
<p class="inwebparagraph"><a id="SP1"></a><b>§1. Build graphs. </b>See the Inbuild manual for an introduction to the build graph. Properly
|
||||
speaking, it is a directed acyclic multigraph which us usually disconnected.
|
||||
</p>
|
||||
|
||||
<p class="inwebparagraph">There can be two sorts of vertex in such a graph: copy vertices, each of which
|
||||
belongs to a single copy, and internal vertices, each of which represents
|
||||
a different file inside the copy.
|
||||
<p class="inwebparagraph">There are two colours of edge: build edges and use edges. A build edge between
|
||||
A and B means that B must exist and be up-to-date before A can be built.
|
||||
A use edge between A and B means that B must exist and be up-to-date before
|
||||
A can be used.
|
||||
</p>
|
||||
|
||||
<p class="inwebparagraph">There are three colours of vertex: copy, file and requirement. Copy vertices
|
||||
correspond to copies which the user does have; requirement vertices to copies
|
||||
which she doesn't have; and file vertices to unmanaged plain files in
|
||||
the build process. For example, if an Inform project says it wants to include
|
||||
an extension which isn't anywhere to be seen, then the project itself is a
|
||||
copy vertex, as are the Standard Rules extension, the CommandParserKit kit,
|
||||
and such; the missing extension is represneted by a requirement vertex; and
|
||||
the story file which the project would compile to, if only it could be
|
||||
compiled, is a file vertex.
|
||||
</p>
|
||||
|
||||
|
||||
<pre class="definitions">
|
||||
<span class="definitionkeyword">enum</span> <span class="constant">COPY_VERTEX</span><span class="definitionkeyword"> from </span><span class="constant">1</span>
|
||||
<span class="definitionkeyword">enum</span> <span class="constant">REQUIREMENT_VERTEX</span>
|
||||
<span class="definitionkeyword">enum</span> <span class="constant">FILE_VERTEX</span>
|
||||
<span class="definitionkeyword">enum</span> <span class="constant">GHOST_VERTEX</span>
|
||||
<span class="definitionkeyword">enum</span> <span class="constant">REQUIREMENT_VERTEX</span>
|
||||
</pre>
|
||||
|
||||
<pre class="display">
|
||||
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">build_vertex</span><span class="plain"> {</span>
|
||||
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">type</span><span class="plain">; </span> <span class="comment">one of the <code class="display"><span class="extract">*_VERTEX</span></code> values above</span>
|
||||
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">linked_list</span><span class="plain"> *</span><span class="identifier">build_edges</span><span class="plain">; </span> <span class="comment">of <code class="display"><span class="extract">build_vertex</span></code></span>
|
||||
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">linked_list</span><span class="plain"> *</span><span class="identifier">use_edges</span><span class="plain">; </span> <span class="comment">of <code class="display"><span class="extract">build_vertex</span></code></span>
|
||||
|
||||
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">buildable_if_copy</span><span class="plain">;</span>
|
||||
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">filename</span><span class="plain"> *</span><span class="identifier">buildable_if_internal_file</span><span class="plain">;</span>
|
||||
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">inbuild_requirement</span><span class="plain"> *</span><span class="identifier">findable</span><span class="plain">;</span>
|
||||
|
||||
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">annotation</span><span class="plain">;</span>
|
||||
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">source_file</span><span class="plain"> *</span><span class="identifier">read_as</span><span class="plain">;</span>
|
||||
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">linked_list</span><span class="plain"> *</span><span class="identifier">build_edges</span><span class="plain">; </span> <span class="comment">of <code class="display"><span class="extract">build_vertex</span></code></span>
|
||||
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">linked_list</span><span class="plain"> *</span><span class="identifier">use_edges</span><span class="plain">; </span> <span class="comment">of <code class="display"><span class="extract">build_vertex</span></code></span>
|
||||
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">last_described_in_generation</span><span class="plain">;</span>
|
||||
|
||||
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">build_result</span><span class="plain">;</span>
|
||||
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">last_built_in_generation</span><span class="plain">;</span>
|
||||
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">always_build_this</span><span class="plain">;</span>
|
||||
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">build_script</span><span class="plain"> *</span><span class="identifier">script</span><span class="plain">;</span>
|
||||
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">last_described</span><span class="plain">;</span>
|
||||
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">built</span><span class="plain">;</span>
|
||||
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">force_this</span><span class="plain">;</span>
|
||||
<span class="identifier">MEMORY_MANAGEMENT</span>
|
||||
<span class="plain">} </span><span class="reserved">build_vertex</span><span class="plain">;</span>
|
||||
</pre>
|
||||
|
||||
<p class="inwebparagraph"></p>
|
||||
|
||||
<p class="endnote">The structure build_vertex is accessed in 3/ib, 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>§2. Creation. </b>First, the three colours of vertex.
|
||||
</p>
|
||||
|
||||
|
||||
<pre class="display">
|
||||
<span class="reserved">build_vertex</span><span class="plain"> *</span><span class="functiontext">Graphs::file_vertex</span><span class="plain">(</span><span class="identifier">filename</span><span class="plain"> *</span><span class="identifier">F</span><span class="plain">) {</span>
|
||||
<span class="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">V</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">build_vertex</span><span class="plain">);</span>
|
||||
<span class="identifier">V</span><span class="plain">-</span><span class="element">>type</span><span class="plain"> = </span><span class="constant">FILE_VERTEX</span><span class="plain">;</span>
|
||||
|
@ -106,9 +130,10 @@ a different file inside the copy.
|
|||
<span class="identifier">V</span><span class="plain">-</span><span class="element">>script</span><span class="plain"> = </span><span class="functiontext">BuildScripts::new</span><span class="plain">();</span>
|
||||
<span class="identifier">V</span><span class="plain">-</span><span class="element">>annotation</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
||||
<span class="identifier">V</span><span class="plain">-</span><span class="element">>read_as</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
||||
<span class="identifier">V</span><span class="plain">-</span><span class="element">>last_described</span><span class="plain"> = 0;</span>
|
||||
<span class="identifier">V</span><span class="plain">-</span><span class="element">>built</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
||||
<span class="identifier">V</span><span class="plain">-</span><span class="element">>force_this</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
||||
<span class="identifier">V</span><span class="plain">-</span><span class="element">>last_described_in_generation</span><span class="plain"> = 0;</span>
|
||||
<span class="identifier">V</span><span class="plain">-</span><span class="element">>build_result</span><span class="plain"> = </span><span class="identifier">NOT_APPLICABLE</span><span class="plain">;</span>
|
||||
<span class="identifier">V</span><span class="plain">-</span><span class="element">>last_built_in_generation</span><span class="plain"> = -1;</span>
|
||||
<span class="identifier">V</span><span class="plain">-</span><span class="element">>always_build_this</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
||||
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">V</span><span class="plain">;</span>
|
||||
<span class="plain">}</span>
|
||||
|
||||
|
@ -129,14 +154,22 @@ a different file inside the copy.
|
|||
<span class="identifier">V</span><span class="plain">-</span><span class="element">>findable</span><span class="plain"> = </span><span class="identifier">R</span><span class="plain">;</span>
|
||||
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">V</span><span class="plain">;</span>
|
||||
<span class="plain">}</span>
|
||||
</pre>
|
||||
|
||||
<span class="reserved">build_vertex</span><span class="plain"> *</span><span class="functiontext">Graphs::ghost_vertex</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">) {</span>
|
||||
<span class="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">V</span><span class="plain"> = </span><span class="functiontext">Graphs::file_vertex</span><span class="plain">(</span><span class="identifier">NULL</span><span class="plain">);</span>
|
||||
<span class="identifier">V</span><span class="plain">-</span><span class="element">>type</span><span class="plain"> = </span><span class="constant">GHOST_VERTEX</span><span class="plain">;</span>
|
||||
<span class="identifier">V</span><span class="plain">-</span><span class="element">>annotation</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">);</span>
|
||||
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">V</span><span class="plain">;</span>
|
||||
<span class="plain">}</span>
|
||||
<p class="inwebparagraph"></p>
|
||||
|
||||
<p class="endnote">The function Graphs::file_vertex is used in 5/kts (<a href="5-kts.html#SP2">§2</a>), 5/ps (<a href="5-ps.html#SP1">§1</a>, <a href="5-ps.html#SP3">§3</a>).</p>
|
||||
|
||||
<p class="endnote">The function Graphs::copy_vertex is used in 4/km (<a href="4-km.html#SP7">§7</a>), 4/em (<a href="4-em.html#SP9">§9</a>), 4/lm (<a href="4-lm.html#SP8">§8</a>), 4/pbm (<a href="4-pbm.html#SP7">§7</a>), 4/pfm (<a href="4-pfm.html#SP7">§7</a>), 4/tm (<a href="4-tm.html#SP7">§7</a>), 4/pm (<a href="4-pm.html#SP8">§8</a>).</p>
|
||||
|
||||
<p class="endnote">The function Graphs::req_vertex is used in 5/kts (<a href="5-kts.html#SP2">§2</a>), 6/inc (<a href="6-inc.html#SP6_1">§6.1</a>).</p>
|
||||
|
||||
<p class="inwebparagraph"><a id="SP3"></a><b>§3. </b>Next, the two colours of edge. Note that between A and B there can be
|
||||
at most one edge of each colour.
|
||||
</p>
|
||||
|
||||
|
||||
<pre class="display">
|
||||
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Graphs::need_this_to_build</span><span class="plain">(</span><span class="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">from</span><span class="plain">, </span><span class="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">to</span><span class="plain">) {</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">from</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"no from"</span><span class="plain">);</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">to</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"no to"</span><span class="plain">);</span>
|
||||
|
@ -144,8 +177,6 @@ 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">>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">>build_edges</span><span class="plain">);</span>
|
||||
<span class="plain">}</span>
|
||||
|
||||
|
@ -158,25 +189,52 @@ 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="identifier">to</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
|
||||
<span class="identifier">ADD_TO_LINKED_LIST</span><span class="plain">(</span><span class="identifier">to</span><span class="plain">, </span><span class="reserved">build_vertex</span><span class="plain">, </span><span class="identifier">from</span><span class="plain">-</span><span class="element">>use_edges</span><span class="plain">);</span>
|
||||
<span class="plain">}</span>
|
||||
</pre>
|
||||
|
||||
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">description_round</span><span class="plain"> = 1;</span>
|
||||
<p class="inwebparagraph"></p>
|
||||
|
||||
<p class="endnote">The function Graphs::need_this_to_build is used in 5/kts (<a href="5-kts.html#SP2">§2</a>), 5/ps (<a href="5-ps.html#SP3">§3</a>), 6/inc (<a href="6-inc.html#SP1_1">§1.1</a>, <a href="6-inc.html#SP6_1">§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">§2</a>), 5/ps (<a href="5-ps.html#SP3">§3</a>), 6/inc (<a href="6-inc.html#SP1_1">§1.1</a>).</p>
|
||||
|
||||
<p class="inwebparagraph"><a id="SP4"></a><b>§4. </b>The script attached to a vertex is a list of instructions for how to build
|
||||
the resource it refers to. Some vertices have no instructions provided, so:
|
||||
</p>
|
||||
|
||||
|
||||
<pre class="display">
|
||||
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Graphs::can_be_built</span><span class="plain">(</span><span class="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">V</span><span class="plain">) {</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">BuildScripts::script_length</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">-</span><span class="element">>script</span><span class="plain">) > 0) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
||||
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
||||
<span class="plain">}</span>
|
||||
</pre>
|
||||
|
||||
<p class="inwebparagraph"></p>
|
||||
|
||||
<p class="endnote">The function Graphs::can_be_built is used in 3/ib (<a href="3-ib.html#SP7_1">§7.1</a>).</p>
|
||||
|
||||
<p class="inwebparagraph"><a id="SP5"></a><b>§5. Writing. </b>This is a suitably indented printout of the graph as seen from a given
|
||||
vertex: it's used by the Inbuild command <code class="display"><span class="extract">-graph</span></code>.
|
||||
</p>
|
||||
|
||||
|
||||
<pre class="display">
|
||||
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">no_desc_generations</span><span class="plain"> = 1;</span>
|
||||
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Graphs::describe</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">V</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">recurse</span><span class="plain">) {</span>
|
||||
<span class="functiontext">Graphs::describe_r</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, 0, </span><span class="identifier">V</span><span class="plain">, </span><span class="identifier">recurse</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="constant">NOT_A_GB</span><span class="plain">, </span><span class="identifier">description_round</span><span class="plain">++);</span>
|
||||
<span class="functiontext">Graphs::describe_r</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, 0, </span><span class="identifier">V</span><span class="plain">, </span><span class="identifier">recurse</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">NOT_APPLICABLE</span><span class="plain">, </span><span class="identifier">no_desc_generations</span><span class="plain">++);</span>
|
||||
<span class="plain">}</span>
|
||||
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Graphs::describe_r</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">depth</span><span class="plain">, </span><span class="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">V</span><span class="plain">,</span>
|
||||
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">recurse</span><span class="plain">, </span><span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">stem</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">which</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">description_round</span><span class="plain">) {</span>
|
||||
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">recurse</span><span class="plain">, </span><span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">stem</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">following_build_edge</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">description_round</span><span class="plain">) {</span>
|
||||
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain"><</span><span class="identifier">depth</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" "</span><span class="plain">);</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">which</span><span class="plain"> == </span><span class="constant">BUILD_GB</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"--build-> "</span><span class="plain">);</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">which</span><span class="plain"> == </span><span class="constant">USE_GB</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"--use---> "</span><span class="plain">);</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">following_build_edge</span><span class="plain"> == </span><span class="identifier">TRUE</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"--build-> "</span><span class="plain">);</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">following_build_edge</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"--use---> "</span><span class="plain">);</span>
|
||||
<span class="functiontext">Graphs::describe_vertex</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">);</span>
|
||||
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" "</span><span class="plain">);</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">V</span><span class="plain">-</span><span class="element">>last_described</span><span class="plain"> == </span><span class="identifier">description_round</span><span class="plain">) { </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"q.v.\</span><span class="plain">n</span><span class="string">"</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">; }</span>
|
||||
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">);</span>
|
||||
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">V</span><span class="plain">-</span><span class="element">>type</span><span class="plain">) {</span>
|
||||
<span class="reserved">case</span><span class="plain"> </span><span class="constant">COPY_VERTEX</span><span class="plain">: </span><span class="functiontext">Copies::write_copy</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">-</span><span class="element">>buildable_if_copy</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
|
||||
<span class="reserved">case</span><span class="plain"> </span><span class="constant">REQUIREMENT_VERTEX</span><span class="plain">: </span><span class="functiontext">Requirements::write</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">-</span><span class="element">>findable</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
|
||||
<span class="reserved">case</span><span class="plain"> </span><span class="constant">FILE_VERTEX</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%f"</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">-</span><span class="element">>buildable_if_internal_file</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
|
||||
<span class="reserved">case</span><span class="plain"> </span><span class="constant">GHOST_VERTEX</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"(%S)"</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">-</span><span class="element">>annotation</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
|
||||
<span class="plain">}</span>
|
||||
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">);</span>
|
||||
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="string">"%p"</span><span class="plain">, </span><span class="identifier">stem</span><span class="plain">);</span>
|
||||
|
@ -187,6 +245,8 @@ a different file inside the copy.
|
|||
<span class="plain">}</span>
|
||||
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">);</span>
|
||||
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">);</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">V</span><span class="plain">-</span><span class="element">>last_described_in_generation</span><span class="plain"> == </span><span class="identifier">description_round</span><span class="plain">) { </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" q.v.\</span><span class="plain">n</span><span class="string">"</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">; }</span>
|
||||
<span class="identifier">V</span><span class="plain">-</span><span class="element">>last_described_in_generation</span><span class="plain"> = </span><span class="identifier">description_round</span><span class="plain">;</span>
|
||||
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">recurse</span><span class="plain">) {</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">V</span><span class="plain">-</span><span class="element">>buildable_if_copy</span><span class="plain">) </span><span class="identifier">stem</span><span class="plain"> = </span><span class="identifier">V</span><span class="plain">-</span><span class="element">>buildable_if_copy</span><span class="plain">-</span><span class="element">>location_if_path</span><span class="plain">;</span>
|
||||
|
@ -194,9 +254,9 @@ a different file inside the copy.
|
|||
<span class="identifier">stem</span><span class="plain"> = </span><span class="identifier">Filenames::get_path_to</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">-</span><span class="element">>buildable_if_internal_file</span><span class="plain">);</span>
|
||||
<span class="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">;</span>
|
||||
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">, </span><span class="reserved">build_vertex</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">-</span><span class="element">>build_edges</span><span class="plain">)</span>
|
||||
<span class="functiontext">Graphs::describe_r</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">depth</span><span class="plain">+1, </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">, </span><span class="identifier">stem</span><span class="plain">, </span><span class="constant">BUILD_GB</span><span class="plain">, </span><span class="identifier">description_round</span><span class="plain">);</span>
|
||||
<span class="functiontext">Graphs::describe_r</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">depth</span><span class="plain">+1, </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">, </span><span class="identifier">stem</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">, </span><span class="identifier">description_round</span><span class="plain">);</span>
|
||||
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">, </span><span class="reserved">build_vertex</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">-</span><span class="element">>use_edges</span><span class="plain">)</span>
|
||||
<span class="functiontext">Graphs::describe_r</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">depth</span><span class="plain">+1, </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">, </span><span class="identifier">stem</span><span class="plain">, </span><span class="constant">USE_GB</span><span class="plain">, </span><span class="identifier">description_round</span><span class="plain">);</span>
|
||||
<span class="functiontext">Graphs::describe_r</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">depth</span><span class="plain">+1, </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">, </span><span class="identifier">stem</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="identifier">description_round</span><span class="plain">);</span>
|
||||
<span class="plain">}</span>
|
||||
<span class="plain">}</span>
|
||||
|
||||
|
@ -206,15 +266,29 @@ a different file inside the copy.
|
|||
<span class="reserved">case</span><span class="plain"> </span><span class="constant">COPY_VERTEX</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"[c%d]"</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">-></span><span class="identifier">allocation_id</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
|
||||
<span class="reserved">case</span><span class="plain"> </span><span class="constant">REQUIREMENT_VERTEX</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"[r%d]"</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">-></span><span class="identifier">allocation_id</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
|
||||
<span class="reserved">case</span><span class="plain"> </span><span class="constant">FILE_VERTEX</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"[f%d]"</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">-></span><span class="identifier">allocation_id</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
|
||||
<span class="reserved">case</span><span class="plain"> </span><span class="constant">GHOST_VERTEX</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"[g%d]"</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">-></span><span class="identifier">allocation_id</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
|
||||
<span class="plain">}</span>
|
||||
<span class="plain">}</span>
|
||||
</pre>
|
||||
|
||||
<p class="inwebparagraph"></p>
|
||||
|
||||
<p class="endnote">The function Graphs::describe is used in 2/cps (<a href="2-cps.html#SP11">§11</a>), 3/ib (<a href="3-ib.html#SP7">§7</a>, <a href="3-ib.html#SP7_1_3">§7.1.3</a>).</p>
|
||||
|
||||
<p class="endnote">The function Graphs::describe_r appears nowhere else.</p>
|
||||
|
||||
<p class="endnote">The function Graphs::describe_vertex appears nowhere else.</p>
|
||||
|
||||
<p class="inwebparagraph"><a id="SP6"></a><b>§6. </b>A similar but slightly different recursion for <code class="display"><span class="extract">-build-needs</span></code> and <code class="display"><span class="extract">-use-needs</span></code>.
|
||||
</p>
|
||||
|
||||
|
||||
<pre class="display">
|
||||
<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">int</span><span class="plain"> </span><span class="identifier">uses_only</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">>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"><</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">>buildable_if_copy</span><span class="plain">;</span>
|
||||
|
@ -227,7 +301,8 @@ a different file inside the copy.
|
|||
<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">>findable</span><span class="plain">-</span><span class="element">>work</span><span class="plain">-</span><span class="element">>genre</span><span class="plain">-</span><span class="element">>genre_name</span><span class="plain">);</span>
|
||||
<span class="functiontext">Works::write</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">-</span><span class="element">>findable</span><span class="plain">-</span><span class="element">>work</span><span class="plain">);</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">VersionNumberRanges::is_any_range</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">-</span><span class="element">>findable</span><span class="plain">-</span><span class="element">>version_range</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
|
||||
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">", need version in range "</span><span class="plain">); </span><span class="identifier">VersionNumberRanges::write_range</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="element">>findable</span><span class="plain">-</span><span class="element">>version_range</span><span class="plain">);</span>
|
||||
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">", need version in range "</span><span class="plain">);</span>
|
||||
<span class="identifier">VersionNumberRanges::write_range</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="element">>findable</span><span class="plain">-</span><span class="element">>version_range</span><span class="plain">);</span>
|
||||
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
||||
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">", any version will do"</span><span class="plain">);</span>
|
||||
<span class="plain">}</span>
|
||||
|
@ -243,18 +318,32 @@ a different file inside the copy.
|
|||
<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>
|
||||
</pre>
|
||||
|
||||
<p class="inwebparagraph"></p>
|
||||
|
||||
<p class="endnote">The function Graphs::show_needs is used in 2/cps (<a href="2-cps.html#SP11">§11</a>).</p>
|
||||
|
||||
<p class="endnote">The function Graphs::show_needs_r appears nowhere else.</p>
|
||||
|
||||
<p class="inwebparagraph"><a id="SP7"></a><b>§7. </b>And for <code class="display"><span class="extract">-build-missing</span></code> and <code class="display"><span class="extract">-use-missing</span></code>.
|
||||
</p>
|
||||
|
||||
|
||||
<pre class="display">
|
||||
<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="identifier">uses_only</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">>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">>findable</span><span class="plain">-</span><span class="element">>work</span><span class="plain">-</span><span class="element">>genre</span><span class="plain">-</span><span class="element">>genre_name</span><span class="plain">);</span>
|
||||
<span class="functiontext">Works::write</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">-</span><span class="element">>findable</span><span class="plain">-</span><span class="element">>work</span><span class="plain">);</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">VersionNumberRanges::is_any_range</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">-</span><span class="element">>findable</span><span class="plain">-</span><span class="element">>version_range</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
|
||||
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">", need version in range "</span><span class="plain">); </span><span class="identifier">VersionNumberRanges::write_range</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="element">>findable</span><span class="plain">-</span><span class="element">>version_range</span><span class="plain">);</span>
|
||||
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">", need version in range "</span><span class="plain">);</span>
|
||||
<span class="identifier">VersionNumberRanges::write_range</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="element">>findable</span><span class="plain">-</span><span class="element">>version_range</span><span class="plain">);</span>
|
||||
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
||||
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">", any version will do"</span><span class="plain">);</span>
|
||||
<span class="plain">}</span>
|
||||
|
@ -271,35 +360,37 @@ a different file inside the copy.
|
|||
<span class="plain">}</span>
|
||||
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">N</span><span class="plain">;</span>
|
||||
<span class="plain">}</span>
|
||||
</pre>
|
||||
|
||||
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Graphs::archive</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">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>
|
||||
<p class="inwebparagraph"></p>
|
||||
|
||||
<p class="endnote">The function Graphs::show_missing is used in 2/cps (<a href="2-cps.html#SP11">§11</a>, <a href="2-cps.html#SP12">§12</a>).</p>
|
||||
|
||||
<p class="endnote">The function Graphs::show_missing_r appears nowhere else.</p>
|
||||
|
||||
<p class="inwebparagraph"><a id="SP8"></a><b>§8. Archiving. </b>This isn't simply a matter of printing out, of course, but very similar code
|
||||
handles <code class="display"><span class="extract">-archive</span></code> and <code class="display"><span class="extract">-archive-to N</span></code>.
|
||||
</p>
|
||||
|
||||
<p class="inwebparagraph">Note that the English language definition, which lives in the internal nest,
|
||||
cannot be read from any other nest — so we won't archive it.
|
||||
</p>
|
||||
|
||||
|
||||
<pre class="display">
|
||||
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Graphs::archive</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">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="functiontext">Graphs::archive_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">N</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">Graphs::archive_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">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">void</span><span class="plain"> </span><span class="functiontext">Graphs::archive_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">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">if</span><span class="plain"> (</span><span class="identifier">V</span><span class="plain">-</span><span class="element">>type</span><span class="plain"> == </span><span class="constant">COPY_VERTEX</span><span class="plain">) {</span>
|
||||
<span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain"> = </span><span class="identifier">V</span><span class="plain">-</span><span class="element">>buildable_if_copy</span><span class="plain">;</span>
|
||||
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Genres::stored_in_nests</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">-</span><span class="element">>edition</span><span class="plain">-</span><span class="element">>work</span><span class="plain">-</span><span class="element">>genre</span><span class="plain">)) &&</span>
|
||||
<span class="plain">((</span><span class="identifier">Str::ne</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">-</span><span class="element">>edition</span><span class="plain">-</span><span class="element">>work</span><span class="plain">-</span><span class="element">>title</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"English"</span><span class="plain">)) ||</span>
|
||||
<span class="plain">(</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">-</span><span class="element">>edition</span><span class="plain">-</span><span class="element">>work</span><span class="plain">-</span><span class="element">>author_name</span><span class="plain">) > 0))) {</span>
|
||||
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%S: "</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">-</span><span class="element">>edition</span><span class="plain">-</span><span class="element">>work</span><span class="plain">-</span><span class="element">>genre</span><span class="plain">-</span><span class="element">>genre_name</span><span class="plain">);</span>
|
||||
<span class="functiontext">Copies::write_copy</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">pathname</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain"> = </span><span class="identifier">C</span><span class="plain">-</span><span class="element">>location_if_path</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">>location_if_file</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">>location_if_file</span><span class="plain">);</span>
|
||||
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">nl</span><span class="plain">);</span>
|
||||
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">cl</span><span class="plain">);</span>
|
||||
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">nl</span><span class="plain">, </span><span class="string">"%p/"</span><span class="plain">, </span><span class="identifier">N</span><span class="plain">-</span><span class="element">>location</span><span class="plain">);</span>
|
||||
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">cl</span><span class="plain">, </span><span class="string">"%p/"</span><span class="plain">, </span><span class="identifier">P</span><span class="plain">);</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::prefix_eq</span><span class="plain">(</span><span class="identifier">cl</span><span class="plain">, </span><span class="identifier">nl</span><span class="plain">, </span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">nl</span><span class="plain">))) {</span>
|
||||
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" -- already there\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
|
||||
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
||||
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" -- archiving\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
|
||||
<span class="functiontext">Copies::copy_to</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">N</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">, </span><span class="identifier">BM</span><span class="plain">);</span>
|
||||
<span class="plain">}</span>
|
||||
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">nl</span><span class="plain">);</span>
|
||||
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">cl</span><span class="plain">);</span>
|
||||
<span class="plain">}</span>
|
||||
<span class="plain">(</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">-</span><span class="element">>edition</span><span class="plain">-</span><span class="element">>work</span><span class="plain">-</span><span class="element">>author_name</span><span class="plain">) > 0)))</span>
|
||||
<<span class="cwebmacro">Archive a single copy</span> <span class="cwebmacronumber">8.1</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">>build_edges</span><span class="plain">)</span>
|
||||
|
@ -309,187 +400,47 @@ a different file inside the copy.
|
|||
<span class="functiontext">Graphs::archive_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="identifier">BM</span><span class="plain">);</span>
|
||||
<span class="plain">}</span>
|
||||
<span class="plain">}</span>
|
||||
|
||||
<span class="identifier">time_t</span><span class="plain"> </span><span class="functiontext">Graphs::timestamp_for</span><span class="plain">(</span><span class="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">V</span><span class="plain">) {</span>
|
||||
<span class="identifier">time_t</span><span class="plain"> </span><span class="identifier">latest</span><span class="plain"> = (</span><span class="identifier">time_t</span><span class="plain">) 0;</span>
|
||||
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">V</span><span class="plain">-</span><span class="element">>buildable_if_internal_file</span><span class="plain">) {</span>
|
||||
<span class="reserved">char</span><span class="plain"> </span><span class="identifier">transcoded_pathname</span><span class="plain">[4*</span><span class="identifier">MAX_FILENAME_LENGTH</span><span class="plain">];</span>
|
||||
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">FN</span><span class="plain">);</span>
|
||||
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">FN</span><span class="plain">, </span><span class="string">"%f"</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">-</span><span class="element">>buildable_if_internal_file</span><span class="plain">);</span>
|
||||
<span class="identifier">Str::copy_to_locale_string</span><span class="plain">(</span><span class="identifier">transcoded_pathname</span><span class="plain">, </span><span class="identifier">FN</span><span class="plain">, 4*</span><span class="identifier">MAX_FILENAME_LENGTH</span><span class="plain">);</span>
|
||||
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">FN</span><span class="plain">);</span>
|
||||
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">stat</span><span class="plain"> </span><span class="identifier">filestat</span><span class="plain">;</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">stat</span><span class="plain">(</span><span class="identifier">transcoded_pathname</span><span class="plain">, &</span><span class="identifier">filestat</span><span class="plain">) != -1) </span><span class="identifier">latest</span><span class="plain"> = </span><span class="identifier">filestat</span><span class="plain">.</span><span class="identifier">st_mtime</span><span class="plain">;</span>
|
||||
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
||||
<span class="identifier">latest</span><span class="plain"> = </span><span class="functiontext">Graphs::time_of_most_recent_ingredient</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">);</span>
|
||||
<span class="plain">}</span>
|
||||
|
||||
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">latest</span><span class="plain">;</span>
|
||||
<span class="plain">}</span>
|
||||
|
||||
<span class="identifier">time_t</span><span class="plain"> </span><span class="functiontext">Graphs::time_of_most_recent_ingredient</span><span class="plain">(</span><span class="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">V</span><span class="plain">) {</span>
|
||||
<span class="identifier">time_t</span><span class="plain"> </span><span class="identifier">latest</span><span class="plain"> = (</span><span class="identifier">time_t</span><span class="plain">) 0;</span>
|
||||
|
||||
<span class="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">;</span>
|
||||
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">, </span><span class="reserved">build_vertex</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">-</span><span class="element">>build_edges</span><span class="plain">) {</span>
|
||||
<span class="identifier">time_t</span><span class="plain"> </span><span class="identifier">inner</span><span class="plain"> = </span><span class="functiontext">Graphs::timestamp_for</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">);</span>
|
||||
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">latest</span><span class="plain"> == (</span><span class="identifier">time_t</span><span class="plain">) 0) || (</span><span class="identifier">difftime</span><span class="plain">(</span><span class="identifier">inner</span><span class="plain">, </span><span class="identifier">latest</span><span class="plain">) > 0))</span>
|
||||
<span class="identifier">latest</span><span class="plain"> = </span><span class="identifier">inner</span><span class="plain">;</span>
|
||||
<span class="plain">}</span>
|
||||
|
||||
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">latest</span><span class="plain">;</span>
|
||||
<span class="plain">}</span>
|
||||
|
||||
<span class="identifier">time_t</span><span class="plain"> </span><span class="functiontext">Graphs::time_of_most_recent_used_resource</span><span class="plain">(</span><span class="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">V</span><span class="plain">) {</span>
|
||||
<span class="identifier">time_t</span><span class="plain"> </span><span class="identifier">latest</span><span class="plain"> = (</span><span class="identifier">time_t</span><span class="plain">) 0;</span>
|
||||
|
||||
<span class="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">;</span>
|
||||
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">, </span><span class="reserved">build_vertex</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">-</span><span class="element">>use_edges</span><span class="plain">) {</span>
|
||||
<span class="identifier">time_t</span><span class="plain"> </span><span class="identifier">inner</span><span class="plain"> = </span><span class="functiontext">Graphs::timestamp_for</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">);</span>
|
||||
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">latest</span><span class="plain"> == (</span><span class="identifier">time_t</span><span class="plain">) 0) || (</span><span class="identifier">difftime</span><span class="plain">(</span><span class="identifier">inner</span><span class="plain">, </span><span class="identifier">latest</span><span class="plain">) > 0))</span>
|
||||
<span class="identifier">latest</span><span class="plain"> = </span><span class="identifier">inner</span><span class="plain">;</span>
|
||||
<span class="plain">}</span>
|
||||
|
||||
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">latest</span><span class="plain">;</span>
|
||||
<span class="plain">}</span>
|
||||
</pre>
|
||||
|
||||
<p class="inwebparagraph"></p>
|
||||
|
||||
<p class="endnote">The function Graphs::file_vertex is used in 5/kts (<a href="5-kts.html#SP2">§2</a>), 5/ps (<a href="5-ps.html#SP1">§1</a>, <a href="5-ps.html#SP3">§3</a>).</p>
|
||||
|
||||
<p class="endnote">The function Graphs::copy_vertex is used in 4/km (<a href="4-km.html#SP7">§7</a>), 4/em (<a href="4-em.html#SP9">§9</a>), 4/lm (<a href="4-lm.html#SP8">§8</a>), 4/pbm (<a href="4-pbm.html#SP7">§7</a>), 4/pfm (<a href="4-pfm.html#SP7">§7</a>), 4/tm (<a href="4-tm.html#SP7">§7</a>), 4/pm (<a href="4-pm.html#SP8">§8</a>).</p>
|
||||
|
||||
<p class="endnote">The function Graphs::req_vertex is used in 5/kts (<a href="5-kts.html#SP2">§2</a>), 6/inc (<a href="6-inc.html#SP6_1">§6.1</a>).</p>
|
||||
|
||||
<p class="endnote">The function Graphs::ghost_vertex is used in 5/ps (<a href="5-ps.html#SP3">§3</a>).</p>
|
||||
|
||||
<p class="endnote">The function Graphs::need_this_to_build is used in 5/kts (<a href="5-kts.html#SP2">§2</a>), 5/ps (<a href="5-ps.html#SP3">§3</a>), 6/inc (<a href="6-inc.html#SP1_1">§1.1</a>, <a href="6-inc.html#SP6_1">§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">§2</a>), 5/ps (<a href="5-ps.html#SP3">§3</a>), 6/inc (<a href="6-inc.html#SP1_1">§1.1</a>).</p>
|
||||
|
||||
<p class="endnote">The function Graphs::describe is used in <a href="#SP2">§2</a>, 2/cps (<a href="2-cps.html#SP11">§11</a>).</p>
|
||||
|
||||
<p class="endnote">The function Graphs::describe_r appears nowhere else.</p>
|
||||
|
||||
<p class="endnote">The function Graphs::describe_vertex appears nowhere else.</p>
|
||||
|
||||
<p class="endnote">The function Graphs::show_needs is used in 2/cps (<a href="2-cps.html#SP11">§11</a>).</p>
|
||||
|
||||
<p class="endnote">The function Graphs::show_needs_r appears nowhere else.</p>
|
||||
|
||||
<p class="endnote">The function Graphs::show_missing is used in 2/cps (<a href="2-cps.html#SP11">§11</a>, <a href="2-cps.html#SP12">§12</a>).</p>
|
||||
|
||||
<p class="endnote">The function Graphs::show_missing_r appears nowhere else.</p>
|
||||
|
||||
<p class="endnote">The function Graphs::archive is used in 2/cps (<a href="2-cps.html#SP12">§12</a>).</p>
|
||||
|
||||
<p class="endnote">The function Graphs::archive_r appears nowhere else.</p>
|
||||
|
||||
<p class="endnote">The function Graphs::timestamp_for is used in <a href="#SP2_1">§2.1</a>.</p>
|
||||
|
||||
<p class="endnote">The function Graphs::time_of_most_recent_ingredient is used in <a href="#SP2_1">§2.1</a>.</p>
|
||||
|
||||
<p class="endnote">The function Graphs::time_of_most_recent_used_resource is used in <a href="#SP2_1">§2.1</a>.</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>§2. </b></p>
|
||||
<p class="inwebparagraph"><a id="SP8_1"></a><b>§8.1. </b>The most delicate thing here is that we don't want to archive something
|
||||
to <code class="display"><span class="extract">N</span></code> if it's already there; but that is difficult to detect.
|
||||
</p>
|
||||
|
||||
|
||||
<pre class="definitions">
|
||||
<span class="definitionkeyword">define</span> <span class="constant">NOT_A_GB</span><span class="plain"> 0</span>
|
||||
<span class="definitionkeyword">define</span> <span class="constant">BUILD_GB</span><span class="plain"> 1</span>
|
||||
<span class="definitionkeyword">define</span> <span class="constant">FORCE_GB</span><span class="plain"> 2</span>
|
||||
<span class="definitionkeyword">define</span> <span class="constant">USE_GB</span><span class="plain"> 4</span>
|
||||
</pre>
|
||||
|
||||
<pre class="display">
|
||||
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Graphs::build</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">V</span><span class="plain">, </span><span class="reserved">build_methodology</span><span class="plain"> *</span><span class="identifier">meth</span><span class="plain">) {</span>
|
||||
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">changes</span><span class="plain"> = 0;</span>
|
||||
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Graphs::build_r</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="constant">BUILD_GB</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">, </span><span class="identifier">meth</span><span class="plain">, &</span><span class="identifier">changes</span><span class="plain">);</span>
|
||||
<span class="plain">}</span>
|
||||
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Graphs::rebuild</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">V</span><span class="plain">, </span><span class="reserved">build_methodology</span><span class="plain"> *</span><span class="identifier">meth</span><span class="plain">) {</span>
|
||||
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">changes</span><span class="plain"> = 0;</span>
|
||||
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Graphs::build_r</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="constant">BUILD_GB</span><span class="plain"> + </span><span class="constant">FORCE_GB</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">, </span><span class="identifier">meth</span><span class="plain">, &</span><span class="identifier">changes</span><span class="plain">);</span>
|
||||
<span class="plain">}</span>
|
||||
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">trace_ibg</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
||||
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Graphs::build_r</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">gb</span><span class="plain">, </span><span class="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">V</span><span class="plain">, </span><span class="reserved">build_methodology</span><span class="plain"> *</span><span class="identifier">meth</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> *</span><span class="identifier">changes</span><span class="plain">) {</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">trace_ibg</span><span class="plain">) { </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">STDOUT</span><span class="plain">, </span><span class="string">"Visit: "</span><span class="plain">); </span><span class="functiontext">Graphs::describe</span><span class="plain">(</span><span class="identifier">STDOUT</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">); }</span>
|
||||
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">V</span><span class="plain">-</span><span class="element">>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="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">>build_edges</span><span class="plain">)</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rv</span><span class="plain">)</span>
|
||||
<span class="identifier">rv</span><span class="plain"> = </span><span class="functiontext">Graphs::build_r</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">gb</span><span class="plain"> | </span><span class="constant">USE_GB</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">meth</span><span class="plain">, </span><span class="identifier">changes</span><span class="plain">);</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">gb</span><span class="plain"> & </span><span class="constant">USE_GB</span><span class="plain">)</span>
|
||||
<span class="identifier">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">>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"> & (</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="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"> & </span><span class="constant">FORCE_GB</span><span class="plain">) || (</span><span class="identifier">V</span><span class="plain">-</span><span class="element">>force_this</span><span class="plain">)) </span><span class="identifier">needs_building</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
||||
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">V</span><span class="plain">-</span><span class="element">>type</span><span class="plain"> == </span><span class="constant">GHOST_VERTEX</span><span class="plain">) && (*</span><span class="identifier">changes</span><span class="plain"> > </span><span class="identifier">changes_so_far</span><span class="plain">)) </span><span class="identifier">needs_building</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
||||
<span class="reserved">else</span><span class="plain"> </span><<span class="cwebmacro">Decide based on timestamps</span> <span class="cwebmacronumber">2.1</span>><span class="plain">;</span>
|
||||
|
||||
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">needs_building</span><span class="plain">) && (</span><span class="functiontext">BuildScripts::script_length</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">-</span><span class="element">>script</span><span class="plain">) > 0)) {</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">trace_ibg</span><span class="plain">) { </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">STDOUT</span><span class="plain">, </span><span class="string">"Build: "</span><span class="plain">); </span><span class="functiontext">Graphs::describe</span><span class="plain">(</span><span class="identifier">STDOUT</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">); }</span>
|
||||
<span class="plain">(*</span><span class="identifier">changes</span><span class="plain">)++;</span>
|
||||
<span class="identifier">rv</span><span class="plain"> = </span><span class="functiontext">BuildScripts::execute</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">-</span><span class="element">>script</span><span class="plain">, </span><span class="identifier">meth</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">trace_ibg</span><span class="plain">) { </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">STDOUT</span><span class="plain">, </span><span class="string">"No Build\</span><span class="plain">n</span><span class="string">"</span><span class="plain">); }</span>
|
||||
<span class="plain">}</span>
|
||||
<span class="plain">}</span>
|
||||
<span class="identifier">V</span><span class="plain">-</span><span class="element">>built</span><span class="plain"> = </span><span class="identifier">rv</span><span class="plain">;</span>
|
||||
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain">;</span>
|
||||
<span class="plain">}</span>
|
||||
</pre>
|
||||
|
||||
<p class="inwebparagraph"></p>
|
||||
|
||||
<p class="endnote">The function Graphs::build is used in 2/cps (<a href="2-cps.html#SP10">§10</a>).</p>
|
||||
|
||||
<p class="endnote">The function Graphs::rebuild is used in 2/cps (<a href="2-cps.html#SP10">§10</a>).</p>
|
||||
|
||||
<p class="endnote">The function Graphs::build_r appears nowhere else.</p>
|
||||
|
||||
<p class="inwebparagraph"><a id="SP2_1"></a><b>§2.1. </b><code class="display">
|
||||
<<span class="cwebmacrodefn">Decide based on timestamps</span> <span class="cwebmacronumber">2.1</span>> =
|
||||
<p class="macrodefinition"><code class="display">
|
||||
<<span class="cwebmacrodefn">Archive a single copy</span> <span class="cwebmacronumber">8.1</span>> =
|
||||
</code></p>
|
||||
|
||||
|
||||
<pre class="displaydefn">
|
||||
<span class="identifier">time_t</span><span class="plain"> </span><span class="identifier">last_built_at</span><span class="plain"> = </span><span class="functiontext">Graphs::timestamp_for</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">);</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">trace_ibg</span><span class="plain">) { </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">STDOUT</span><span class="plain">, </span><span class="string">"Last built at: %08x\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">last_built_at</span><span class="plain">); }</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">last_built_at</span><span class="plain"> == (</span><span class="identifier">time_t</span><span class="plain">) 0)</span>
|
||||
<span class="identifier">needs_building</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
||||
<span class="reserved">else</span><span class="plain"> {</span>
|
||||
<span class="identifier">time_t</span><span class="plain"> </span><span class="identifier">time_of_most_recent</span><span class="plain"> = </span><span class="functiontext">Graphs::time_of_most_recent_ingredient</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">);</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">time_of_most_recent</span><span class="plain"> != (</span><span class="identifier">time_t</span><span class="plain">) 0) {</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">trace_ibg</span><span class="plain">) { </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">STDOUT</span><span class="plain">, </span><span class="string">"Most recent: %08x\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">time_of_most_recent</span><span class="plain">); }</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">difftime</span><span class="plain">(</span><span class="identifier">time_of_most_recent</span><span class="plain">, </span><span class="identifier">last_built_at</span><span class="plain">) > 0)</span>
|
||||
<span class="identifier">needs_building</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
||||
<span class="plain">}</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">gb</span><span class="plain"> & </span><span class="constant">USE_GB</span><span class="plain">) {</span>
|
||||
<span class="identifier">time_t</span><span class="plain"> </span><span class="identifier">time_of_most_recent_used</span><span class="plain"> = </span><span class="functiontext">Graphs::time_of_most_recent_used_resource</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">);</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">time_of_most_recent_used</span><span class="plain"> != (</span><span class="identifier">time_t</span><span class="plain">) 0) {</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">trace_ibg</span><span class="plain">) { </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">STDOUT</span><span class="plain">, </span><span class="string">"Most recent use: %08x\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">time_of_most_recent_used</span><span class="plain">); }</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">difftime</span><span class="plain">(</span><span class="identifier">time_of_most_recent_used</span><span class="plain">, </span><span class="identifier">last_built_at</span><span class="plain">) > 0)</span>
|
||||
<span class="identifier">needs_building</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
||||
<span class="plain">}</span>
|
||||
<span class="plain">}</span>
|
||||
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%S: "</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">-</span><span class="element">>edition</span><span class="plain">-</span><span class="element">>work</span><span class="plain">-</span><span class="element">>genre</span><span class="plain">-</span><span class="element">>genre_name</span><span class="plain">);</span>
|
||||
<span class="functiontext">Copies::write_copy</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">pathname</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain"> = </span><span class="identifier">C</span><span class="plain">-</span><span class="element">>location_if_path</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">>location_if_file</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">>location_if_file</span><span class="plain">);</span>
|
||||
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">nl</span><span class="plain">);</span>
|
||||
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">cl</span><span class="plain">);</span>
|
||||
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">nl</span><span class="plain">, </span><span class="string">"%p/"</span><span class="plain">, </span><span class="identifier">N</span><span class="plain">-</span><span class="element">>location</span><span class="plain">);</span>
|
||||
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">cl</span><span class="plain">, </span><span class="string">"%p/"</span><span class="plain">, </span><span class="identifier">P</span><span class="plain">);</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::prefix_eq</span><span class="plain">(</span><span class="identifier">cl</span><span class="plain">, </span><span class="identifier">nl</span><span class="plain">, </span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">nl</span><span class="plain">))) {</span>
|
||||
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" -- already there\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
|
||||
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
||||
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" -- archiving\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
|
||||
<span class="functiontext">Copies::copy_to</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">N</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">, </span><span class="identifier">BM</span><span class="plain">);</span>
|
||||
<span class="plain">}</span>
|
||||
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">nl</span><span class="plain">);</span>
|
||||
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">cl</span><span class="plain">);</span>
|
||||
</pre>
|
||||
|
||||
<p class="inwebparagraph"></p>
|
||||
|
||||
<p class="endnote">This code is used in <a href="#SP2">§2</a>.</p>
|
||||
<p class="endnote">This code is used in <a href="#SP8">§8</a>.</p>
|
||||
|
||||
<hr class="tocbar">
|
||||
<ul class="toc"><li><i>(This section begins Chapter 3: Incremental Builds.)</i></li><li><a href="3-bm.html">Continue with 'Build Methodology'</a></li></ul><hr class="tocbar">
|
||||
|
|
|
@ -122,7 +122,7 @@
|
|||
<p class="endnote">The structure build_methodology is accessed in 3/bs2, 3/is, 3/is2, 3/is3, 3/is4, 4/km, 4/em, 4/lm, 4/tm, 4/pm and here.</p>
|
||||
|
||||
<hr class="tocbar">
|
||||
<ul class="toc"><li><a href="3-bg.html">Back to 'Build Graphs'</a></li><li><a href="3-bs.html">Continue with 'Build Scripts'</a></li></ul><hr class="tocbar">
|
||||
<ul class="toc"><li><a href="3-bg.html">Back to 'Build Graphs'</a></li><li><a href="3-ib.html">Continue with 'Incremental Building'</a></li></ul><hr class="tocbar">
|
||||
<!--End of weave-->
|
||||
</main>
|
||||
</body>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>3/bm</title>
|
||||
<title>3/ib</title>
|
||||
<meta name="viewport" content="width=device-width initial-scale=1">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta http-equiv="Content-Language" content="en-gb">
|
||||
|
@ -104,20 +104,20 @@
|
|||
|
||||
<p class="inwebparagraph"></p>
|
||||
|
||||
<p class="endnote">The function BuildScripts::new is used in 3/bg (<a href="3-bg.html#SP1">§1</a>).</p>
|
||||
<p class="endnote">The function BuildScripts::new is used in 3/bg (<a href="3-bg.html#SP2">§2</a>).</p>
|
||||
|
||||
<p class="endnote">The function BuildScripts::script_length is used in 3/bg (<a href="3-bg.html#SP2">§2</a>).</p>
|
||||
<p class="endnote">The function BuildScripts::script_length is used in 3/bg (<a href="3-bg.html#SP4">§4</a>).</p>
|
||||
|
||||
<p class="endnote">The function BuildScripts::add_step is used in 3/bs2 (<a href="3-bs2.html#SP4">§4</a>).</p>
|
||||
|
||||
<p class="endnote">The function BuildScripts::concatenate appears nowhere else.</p>
|
||||
|
||||
<p class="endnote">The function BuildScripts::execute is used in 3/bg (<a href="3-bg.html#SP2">§2</a>).</p>
|
||||
<p class="endnote">The function BuildScripts::execute is used in 3/ib (<a href="3-ib.html#SP7_1_3">§7.1.3</a>).</p>
|
||||
|
||||
<p class="endnote">The structure build_script is private to this section.</p>
|
||||
|
||||
<hr class="tocbar">
|
||||
<ul class="toc"><li><a href="3-bm.html">Back to 'Build Methodology'</a></li><li><a href="3-bs2.html">Continue with 'Build Steps'</a></li></ul><hr class="tocbar">
|
||||
<ul class="toc"><li><a href="3-ib.html">Back to 'Incremental Building'</a></li><li><a href="3-bs2.html">Continue with 'Build Steps'</a></li></ul><hr class="tocbar">
|
||||
<!--End of weave-->
|
||||
</main>
|
||||
</body>
|
||||
|
|
413
docs/inbuild-module/3-ib.html
Normal file
413
docs/inbuild-module/3-ib.html
Normal file
|
@ -0,0 +1,413 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>3/bm</title>
|
||||
<meta name="viewport" content="width=device-width initial-scale=1">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta http-equiv="Content-Language" content="en-gb">
|
||||
<link href="../inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
||||
</head>
|
||||
<body>
|
||||
<nav role="navigation">
|
||||
<h1><a href="../webs.html">Sources</a></h1>
|
||||
<ul>
|
||||
<li><a href="../compiler.html"><b>compiler tools</b></a></li>
|
||||
<li><a href="../other.html">other tools</a></li>
|
||||
<li><a href="../extensions.html">extensions and kits</a></li>
|
||||
<li><a href="../units.html">unit test tools</a></li>
|
||||
</ul>
|
||||
<h2>Compiler Webs</h2>
|
||||
<ul>
|
||||
<li><a href="../inbuild/index.html">inbuild</a></li>
|
||||
<li><a href="../inform7/index.html">inform7</a></li>
|
||||
<li><a href="../inter/index.html">inter</a></li>
|
||||
</ul>
|
||||
<h2>Inbuild Modules</h2>
|
||||
<ul>
|
||||
<li><a href="../inbuild-module/index.html">inbuild</a></li>
|
||||
<li><a href="../arch-module/index.html">arch</a></li>
|
||||
<li><a href="../words-module/index.html">words</a></li>
|
||||
<li><a href="../syntax-module/index.html">syntax</a></li>
|
||||
<li><a href="../html-module/index.html">html</a></li>
|
||||
</ul>
|
||||
<h2>Inform7 Modules</h2>
|
||||
<ul>
|
||||
<li><a href="../core-module/index.html">core</a></li>
|
||||
<li><a href="../problems-module/index.html">problems</a></li>
|
||||
<li><a href="../inflections-module/index.html">inflections</a></li>
|
||||
<li><a href="../linguistics-module/index.html">linguistics</a></li>
|
||||
<li><a href="../kinds-module/index.html">kinds</a></li>
|
||||
<li><a href="../if-module/index.html">if</a></li>
|
||||
<li><a href="../multimedia-module/index.html">multimedia</a></li>
|
||||
<li><a href="../index-module/index.html">index</a></li>
|
||||
</ul>
|
||||
<h2>Inter Modules</h2>
|
||||
<ul>
|
||||
<li><a href="../inter-module/index.html">inter</a></li>
|
||||
<li><a href="../building-module/index.html">building</a></li>
|
||||
<li><a href="../codegen-module/index.html">codegen</a></li>
|
||||
</ul>
|
||||
<h2>Foundation</h2>
|
||||
<ul>
|
||||
<li><a href="../../../inweb/docs/foundation-module/index.html">foundation</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
</nav>
|
||||
<main role="main">
|
||||
|
||||
<!--Weave of '3/ib' generated by 7-->
|
||||
<ul class="crumbs"><li><a href="../webs.html">Source</a></li><li><a href="../compiler.html">Compiler Modules</a></li><li><a href="index.html">inbuild</a></li><li><a href="index.html#3">Chapter 3: Incremental Builds</a></li><li><b>Incremental Building</b></li></ul><p class="purpose">Deciding what is the least possible amount which needs to be built, in what order, to arrive at a working version of a copy.</p>
|
||||
|
||||
<ul class="toc"><li><a href="#SP1">§1. Timestamps</a></li><li><a href="#SP5">§5. Build process</a></li></ul><hr class="tocbar">
|
||||
|
||||
<p class="inwebparagraph"><a id="SP1"></a><b>§1. Timestamps. </b>We want to assign a timestamp to every vertex in the graph, whose meaning is
|
||||
that what it represents has been up-to-date since that time.
|
||||
</p>
|
||||
|
||||
<p class="inwebparagraph">For a file vertex, we take that from the file system's timestamp. For a
|
||||
copy vertex, we do the same for a copy which is a single file (such as an
|
||||
extension), but for a copy which is a directory containing a composite of
|
||||
resources, there's no good way to know. (Perhaps we could scan the files
|
||||
in it recursively, but then we have to worry about hidden files, symlinks,
|
||||
and all of that.) Instead, we use the build graph itself to decide; for
|
||||
example, the timestamp for a kit is the most recent timestamp of any of its
|
||||
binary Inter files, because those are its build-dependencies.
|
||||
</p>
|
||||
|
||||
|
||||
<pre class="display">
|
||||
<span class="identifier">time_t</span><span class="plain"> </span><span class="functiontext">IncrementalBuild::timestamp</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">switch</span><span class="plain"> (</span><span class="identifier">V</span><span class="plain">-</span><span class="element">>type</span><span class="plain">) {</span>
|
||||
<span class="reserved">case</span><span class="plain"> </span><span class="constant">FILE_VERTEX</span><span class="plain">:</span>
|
||||
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">Filenames::timestamp</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">-</span><span class="element">>buildable_if_internal_file</span><span class="plain">);</span>
|
||||
<span class="reserved">case</span><span class="plain"> </span><span class="constant">COPY_VERTEX</span><span class="plain">:</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">V</span><span class="plain">-</span><span class="element">>buildable_if_copy</span><span class="plain">-</span><span class="element">>location_if_file</span><span class="plain">)</span>
|
||||
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">Filenames::timestamp</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">-</span><span class="element">>buildable_if_copy</span><span class="plain">-</span><span class="element">>location_if_file</span><span class="plain">);</span>
|
||||
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">IncrementalBuild::time_of_latest_build_dependency</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">);</span>
|
||||
<span class="reserved">default</span><span class="plain">:</span>
|
||||
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">Platform::never_time</span><span class="plain">();</span>
|
||||
<span class="plain">}</span>
|
||||
<span class="plain">}</span>
|
||||
</pre>
|
||||
|
||||
<p class="inwebparagraph"></p>
|
||||
|
||||
<p class="endnote">The function IncrementalBuild::timestamp is used in <a href="#SP3">§3</a>, <a href="#SP4">§4</a>, <a href="#SP7_1_3_1">§7.1.3.1</a>.</p>
|
||||
|
||||
<p class="inwebparagraph"><a id="SP2"></a><b>§2. </b>The following compares two times: it returns 1 if <code class="display"><span class="extract">t1</span></code> is later, -1 if
|
||||
<code class="display"><span class="extract">t2</span></code> is later, and 0 if they are identical.
|
||||
</p>
|
||||
|
||||
<p class="inwebparagraph">Note that we never apply the C standard library function <code class="display"><span class="extract">difftime</span></code> in
|
||||
the case of the never-time, which we consider to be before all other times.
|
||||
(On most platforms it will be the C epoch of 1970, and <code class="display"><span class="extract">difftime</span></code> alone
|
||||
would be fine, but we're being careful.)
|
||||
</p>
|
||||
|
||||
|
||||
<pre class="display">
|
||||
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">IncrementalBuild::timecmp</span><span class="plain">(</span><span class="identifier">time_t</span><span class="plain"> </span><span class="identifier">t1</span><span class="plain">, </span><span class="identifier">time_t</span><span class="plain"> </span><span class="identifier">t2</span><span class="plain">) {</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">t1</span><span class="plain"> == </span><span class="identifier">Platform::never_time</span><span class="plain">()) {</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">t2</span><span class="plain"> == </span><span class="identifier">Platform::never_time</span><span class="plain">()) </span><span class="reserved">return</span><span class="plain"> 0;</span>
|
||||
<span class="reserved">return</span><span class="plain"> -1;</span>
|
||||
<span class="plain">}</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">t2</span><span class="plain"> == </span><span class="identifier">Platform::never_time</span><span class="plain">()) {</span>
|
||||
<span class="reserved">return</span><span class="plain"> 1;</span>
|
||||
<span class="plain">}</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">t1</span><span class="plain"> == </span><span class="identifier">t2</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> 0;</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">difftime</span><span class="plain">(</span><span class="identifier">t1</span><span class="plain">, </span><span class="identifier">t2</span><span class="plain">) > 0) </span><span class="reserved">return</span><span class="plain"> 1;</span>
|
||||
<span class="reserved">return</span><span class="plain"> -1;</span>
|
||||
<span class="plain">}</span>
|
||||
</pre>
|
||||
|
||||
<p class="inwebparagraph"></p>
|
||||
|
||||
<p class="endnote">The function IncrementalBuild::timecmp is used in <a href="#SP3">§3</a>, <a href="#SP4">§4</a>, <a href="#SP7_1_3_1">§7.1.3.1</a>.</p>
|
||||
|
||||
<p class="inwebparagraph"><a id="SP3"></a><b>§3. </b>We then take the latest timestamp of any build dependency:
|
||||
</p>
|
||||
|
||||
|
||||
<pre class="display">
|
||||
<span class="identifier">time_t</span><span class="plain"> </span><span class="functiontext">IncrementalBuild::time_of_latest_build_dependency</span><span class="plain">(</span><span class="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">V</span><span class="plain">) {</span>
|
||||
<span class="identifier">time_t</span><span class="plain"> </span><span class="identifier">latest</span><span class="plain"> = </span><span class="identifier">Platform::never_time</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">>build_edges</span><span class="plain">) {</span>
|
||||
<span class="identifier">time_t</span><span class="plain"> </span><span class="identifier">t</span><span class="plain"> = </span><span class="functiontext">IncrementalBuild::timestamp</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">);</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">IncrementalBuild::timecmp</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">, </span><span class="identifier">latest</span><span class="plain">) > 0) </span><span class="identifier">latest</span><span class="plain"> = </span><span class="identifier">t</span><span class="plain">;</span>
|
||||
<span class="plain">}</span>
|
||||
|
||||
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">latest</span><span class="plain">;</span>
|
||||
<span class="plain">}</span>
|
||||
</pre>
|
||||
|
||||
<p class="inwebparagraph"></p>
|
||||
|
||||
<p class="endnote">The function IncrementalBuild::time_of_latest_build_dependency is used in <a href="#SP1">§1</a>, <a href="#SP7_1_3_1">§7.1.3.1</a>.</p>
|
||||
|
||||
<p class="inwebparagraph"><a id="SP4"></a><b>§4. </b>And of any use dependency:
|
||||
</p>
|
||||
|
||||
|
||||
<pre class="display">
|
||||
<span class="identifier">time_t</span><span class="plain"> </span><span class="functiontext">IncrementalBuild::time_of_latest_use_dependency</span><span class="plain">(</span><span class="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">V</span><span class="plain">) {</span>
|
||||
<span class="identifier">time_t</span><span class="plain"> </span><span class="identifier">latest</span><span class="plain"> = </span><span class="identifier">Platform::never_time</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">>use_edges</span><span class="plain">) {</span>
|
||||
<span class="identifier">time_t</span><span class="plain"> </span><span class="identifier">t</span><span class="plain"> = </span><span class="functiontext">IncrementalBuild::timestamp</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">);</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">IncrementalBuild::timecmp</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">, </span><span class="identifier">latest</span><span class="plain">) > 0) </span><span class="identifier">latest</span><span class="plain"> = </span><span class="identifier">t</span><span class="plain">;</span>
|
||||
<span class="plain">}</span>
|
||||
|
||||
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">latest</span><span class="plain">;</span>
|
||||
<span class="plain">}</span>
|
||||
</pre>
|
||||
|
||||
<p class="inwebparagraph"></p>
|
||||
|
||||
<p class="endnote">The function IncrementalBuild::time_of_latest_use_dependency is used in <a href="#SP7_1_3_1">§7.1.3.1</a>.</p>
|
||||
|
||||
<p class="inwebparagraph"><a id="SP5"></a><b>§5. Build process. </b>This is a recursive process, beginning at the node representing what we want
|
||||
to build. As we recurse, we pass a bitmap of the following:
|
||||
</p>
|
||||
|
||||
|
||||
<pre class="definitions">
|
||||
<span class="definitionkeyword">define</span> <span class="constant">BUILD_DEPENDENCIES_MATTER_GB</span><span class="plain"> 1 </span> <span class="comment">We will need all your build dependencies too</span>
|
||||
<span class="definitionkeyword">define</span> <span class="constant">USE_DEPENDENCIES_MATTER_GB</span><span class="plain"> 2 </span> <span class="comment">We will need all your use dependencies too</span>
|
||||
<span class="definitionkeyword">define</span> <span class="constant">IGNORE_TIMESTAMPS_GB</span><span class="plain"> 4 </span> <span class="comment">Don't be incremental: trust nothing, rebuild everything</span>
|
||||
</pre>
|
||||
|
||||
<pre class="display">
|
||||
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">IncrementalBuild::build</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">V</span><span class="plain">, </span><span class="reserved">build_methodology</span><span class="plain"> *</span><span class="identifier">meth</span><span class="plain">) {</span>
|
||||
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">IncrementalBuild::begin_recursion</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">,</span>
|
||||
<span class="constant">BUILD_DEPENDENCIES_MATTER_GB</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">, </span><span class="identifier">meth</span><span class="plain">);</span>
|
||||
<span class="plain">}</span>
|
||||
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">IncrementalBuild::rebuild</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">V</span><span class="plain">, </span><span class="reserved">build_methodology</span><span class="plain"> *</span><span class="identifier">meth</span><span class="plain">) {</span>
|
||||
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">IncrementalBuild::begin_recursion</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">,</span>
|
||||
<span class="constant">BUILD_DEPENDENCIES_MATTER_GB</span><span class="plain"> + </span><span class="constant">IGNORE_TIMESTAMPS_GB</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">, </span><span class="identifier">meth</span><span class="plain">);</span>
|
||||
<span class="plain">}</span>
|
||||
</pre>
|
||||
|
||||
<p class="inwebparagraph"></p>
|
||||
|
||||
<p class="endnote">The function IncrementalBuild::build is used in 2/cps (<a href="2-cps.html#SP10">§10</a>).</p>
|
||||
|
||||
<p class="endnote">The function IncrementalBuild::rebuild is used in 2/cps (<a href="2-cps.html#SP10">§10</a>).</p>
|
||||
|
||||
<p class="inwebparagraph"><a id="SP6"></a><b>§6. </b>This is called when Inbuild's <code class="display"><span class="extract">-trace</span></code> switch is set at the command line.
|
||||
</p>
|
||||
|
||||
|
||||
<pre class="display">
|
||||
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">trace_ibg</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
||||
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">IncrementalBuild::enable_trace</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
||||
<span class="identifier">trace_ibg</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
||||
<span class="plain">}</span>
|
||||
</pre>
|
||||
|
||||
<p class="inwebparagraph"></p>
|
||||
|
||||
<p class="endnote">The function IncrementalBuild::enable_trace appears nowhere else.</p>
|
||||
|
||||
<p class="inwebparagraph"><a id="SP7"></a><b>§7. </b>We want to be very sure that this recursion does not lock up, or perform
|
||||
unnecessary work by performing the same node twice. To do this we apply the
|
||||
<code class="display"><span class="extract">built</span></code> flag to a node when it has been built; but to make this is not left
|
||||
over from last time around, we only regard it when the <code class="display"><span class="extract">last_built_in_generation</span></code> count
|
||||
for the node is set to the current "generation", a unique number incremented
|
||||
for each time we recurse.
|
||||
</p>
|
||||
|
||||
|
||||
<pre class="display">
|
||||
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">no_build_generations</span><span class="plain"> = 0;</span>
|
||||
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">IncrementalBuild::begin_recursion</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">gb</span><span class="plain">, </span><span class="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">V</span><span class="plain">,</span>
|
||||
<span class="reserved">build_methodology</span><span class="plain"> *</span><span class="identifier">meth</span><span class="plain">) {</span>
|
||||
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">changes</span><span class="plain"> = 0;</span>
|
||||
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">trace</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">trace_ibg</span><span class="plain">) </span><span class="identifier">trace</span><span class="plain"> = </span><span class="identifier">STDOUT</span><span class="plain">;</span>
|
||||
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">trace</span><span class="plain">, </span><span class="string">"Incremental build %d:\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">no_build_generations</span><span class="plain">);</span>
|
||||
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain"> = </span><span class="functiontext">IncrementalBuild::recurse</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">trace</span><span class="plain">, </span><span class="identifier">gb</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">, </span><span class="identifier">meth</span><span class="plain">, &</span><span class="identifier">changes</span><span class="plain">, </span><span class="identifier">no_build_generations</span><span class="plain">++);</span>
|
||||
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">trace</span><span class="plain">, </span><span class="string">"%d change(s)\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">changes</span><span class="plain">);</span>
|
||||
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain">;</span>
|
||||
<span class="plain">}</span>
|
||||
|
||||
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">IncrementalBuild::recurse</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">trace</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">gb</span><span class="plain">, </span><span class="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">V</span><span class="plain">,</span>
|
||||
<span class="reserved">build_methodology</span><span class="plain"> *</span><span class="identifier">meth</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> *</span><span class="identifier">changes</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">generation</span><span class="plain">) {</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">trace</span><span class="plain">) {</span>
|
||||
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">trace</span><span class="plain">, </span><span class="string">"Visit %c%c%c: "</span><span class="plain">,</span>
|
||||
<span class="plain">(</span><span class="identifier">gb</span><span class="plain"> & </span><span class="constant">BUILD_DEPENDENCIES_MATTER_GB</span><span class="plain">)?</span><span class="character">'b'</span><span class="plain">:</span><span class="character">'.'</span><span class="plain">,</span>
|
||||
<span class="plain">(</span><span class="identifier">gb</span><span class="plain"> & </span><span class="constant">USE_DEPENDENCIES_MATTER_GB</span><span class="plain">)?</span><span class="character">'u'</span><span class="plain">:</span><span class="character">'.'</span><span class="plain">,</span>
|
||||
<span class="plain">(</span><span class="identifier">gb</span><span class="plain"> & </span><span class="constant">IGNORE_TIMESTAMPS_GB</span><span class="plain">)?</span><span class="character">'i'</span><span class="plain">:</span><span class="character">'.'</span><span class="plain">);</span>
|
||||
<span class="functiontext">Graphs::describe</span><span class="plain">(</span><span class="identifier">trace</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
|
||||
<span class="plain">}</span>
|
||||
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">V</span><span class="plain">-</span><span class="element">>last_built_in_generation</span><span class="plain"> == </span><span class="identifier">generation</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">V</span><span class="plain">-</span><span class="element">>build_result</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="cwebmacro">Build this node if necessary, setting rv to its success or failure</span> <span class="cwebmacronumber">7.1</span>><span class="plain">;</span>
|
||||
<span class="identifier">V</span><span class="plain">-</span><span class="element">>build_result</span><span class="plain"> = </span><span class="identifier">rv</span><span class="plain">;</span>
|
||||
<span class="identifier">V</span><span class="plain">-</span><span class="element">>last_built_in_generation</span><span class="plain"> = </span><span class="identifier">generation</span><span class="plain">;</span>
|
||||
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain">;</span>
|
||||
<span class="plain">}</span>
|
||||
</pre>
|
||||
|
||||
<p class="inwebparagraph"></p>
|
||||
|
||||
<p class="endnote">The function IncrementalBuild::begin_recursion is used in <a href="#SP5">§5</a>.</p>
|
||||
|
||||
<p class="endnote">The function IncrementalBuild::recurse is used in <a href="#SP7_1_1">§7.1.1</a>, <a href="#SP7_1_2">§7.1.2</a>.</p>
|
||||
|
||||
<p class="inwebparagraph"><a id="SP7_1"></a><b>§7.1. </b>In everything which follows, <code class="display"><span class="extract">rv</span></code> (prosaically, this stands only for "return
|
||||
value") remains <code class="display"><span class="extract">TRUE</span></code> until the first active step fails, at which point no
|
||||
other active steps are ever taken, nor are any recursions made. In effect,
|
||||
the first failure halts the process.
|
||||
</p>
|
||||
|
||||
<p class="inwebparagraph">We are recursing depth-first, that is, we build the things needed to build
|
||||
<code class="display"><span class="extract">V</span></code> before we build <code class="display"><span class="extract">V</span></code> itself.
|
||||
</p>
|
||||
|
||||
<p class="inwebparagraph">A point of difference between this algorithm and <code class="display"><span class="extract">make</span></code> is that we do not
|
||||
halt with an error if a node has no way to be built. This is because the
|
||||
graphs are here are built by Inbuild itself, not by a possibly erroneous
|
||||
makefile whose author has forgotten something and whose intentions are not
|
||||
clear. Here, if a node has no build script attached, it must be because it
|
||||
needs no action taken.
|
||||
</p>
|
||||
|
||||
|
||||
<p class="macrodefinition"><code class="display">
|
||||
<<span class="cwebmacrodefn">Build this node if necessary, setting rv to its success or failure</span> <span class="cwebmacronumber">7.1</span>> =
|
||||
</code></p>
|
||||
|
||||
|
||||
<pre class="displaydefn">
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">trace</span><span class="plain">) </span><span class="identifier">STREAM_INDENT</span><span class="plain">(</span><span class="identifier">trace</span><span class="plain">);</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">gb</span><span class="plain"> & </span><span class="constant">BUILD_DEPENDENCIES_MATTER_GB</span><span class="plain">) </span><<span class="cwebmacro">Build the build dependencies of the node</span> <span class="cwebmacronumber">7.1.1</span>><span class="plain">;</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">gb</span><span class="plain"> & </span><span class="constant">USE_DEPENDENCIES_MATTER_GB</span><span class="plain">) </span><<span class="cwebmacro">Build the use dependencies of the node</span> <span class="cwebmacronumber">7.1.2</span>><span class="plain">;</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">trace</span><span class="plain">) </span><span class="identifier">STREAM_OUTDENT</span><span class="plain">(</span><span class="identifier">trace</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="functiontext">Graphs::can_be_built</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">))) </span><<span class="cwebmacro">Build the node itself, if necessary</span> <span class="cwebmacronumber">7.1.3</span>><span class="plain">;</span>
|
||||
</pre>
|
||||
|
||||
<p class="inwebparagraph"></p>
|
||||
|
||||
<p class="endnote">This code is used in <a href="#SP7">§7</a>.</p>
|
||||
|
||||
<p class="inwebparagraph"><a id="SP7_1_1"></a><b>§7.1.1. </b>Suppose V needs W (for whatever reason), and that W can only be used with X.
|
||||
It follows that we will have to build X as well as W, since the process of
|
||||
building V is itself a use of W, and therefore of X. So we always enable the
|
||||
<code class="display"><span class="extract">USE_DEPENDENCIES_MATTER_GB</span></code> bit when recursing through an edge.
|
||||
</p>
|
||||
|
||||
|
||||
<p class="macrodefinition"><code class="display">
|
||||
<<span class="cwebmacrodefn">Build the build dependencies of the node</span> <span class="cwebmacronumber">7.1.1</span>> =
|
||||
</code></p>
|
||||
|
||||
|
||||
<pre class="displaydefn">
|
||||
<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">>build_edges</span><span class="plain">)</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rv</span><span class="plain">)</span>
|
||||
<span class="identifier">rv</span><span class="plain"> = </span><span class="functiontext">IncrementalBuild::recurse</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">trace</span><span class="plain">,</span>
|
||||
<span class="identifier">gb</span><span class="plain"> | </span><span class="constant">USE_DEPENDENCIES_MATTER_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">generation</span><span class="plain">);</span>
|
||||
</pre>
|
||||
|
||||
<p class="inwebparagraph"></p>
|
||||
|
||||
<p class="endnote">This code is used in <a href="#SP7_1">§7.1</a>.</p>
|
||||
|
||||
<p class="inwebparagraph"><a id="SP7_1_2"></a><b>§7.1.2. </b><code class="display">
|
||||
<<span class="cwebmacrodefn">Build the use dependencies of the node</span> <span class="cwebmacronumber">7.1.2</span>> =
|
||||
</code></p>
|
||||
|
||||
|
||||
<pre class="displaydefn">
|
||||
<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">>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">IncrementalBuild::recurse</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">trace</span><span class="plain">,</span>
|
||||
<span class="identifier">gb</span><span class="plain"> | </span><span class="constant">USE_DEPENDENCIES_MATTER_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">generation</span><span class="plain">);</span>
|
||||
</pre>
|
||||
|
||||
<p class="inwebparagraph"></p>
|
||||
|
||||
<p class="endnote">This code is used in <a href="#SP7_1">§7.1</a>.</p>
|
||||
|
||||
<p class="inwebparagraph"><a id="SP7_1_3"></a><b>§7.1.3. </b>Now for the node <code class="display"><span class="extract">V</span></code> itself.
|
||||
</p>
|
||||
|
||||
|
||||
<p class="macrodefinition"><code class="display">
|
||||
<<span class="cwebmacrodefn">Build the node itself, if necessary</span> <span class="cwebmacronumber">7.1.3</span>> =
|
||||
</code></p>
|
||||
|
||||
|
||||
<pre class="displaydefn">
|
||||
<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"> & </span><span class="constant">IGNORE_TIMESTAMPS_GB</span><span class="plain">) || (</span><span class="identifier">V</span><span class="plain">-</span><span class="element">>always_build_this</span><span class="plain">)) </span><span class="identifier">needs_building</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
||||
<span class="reserved">else</span><span class="plain"> </span><<span class="cwebmacro">Decide based on timestamps</span> <span class="cwebmacronumber">7.1.3.1</span>><span class="plain">;</span>
|
||||
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">needs_building</span><span class="plain">) {</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">trace</span><span class="plain">) { </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">trace</span><span class="plain">, </span><span class="string">"Build: "</span><span class="plain">); </span><span class="functiontext">Graphs::describe</span><span class="plain">(</span><span class="identifier">trace</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">); }</span>
|
||||
<span class="plain">(*</span><span class="identifier">changes</span><span class="plain">)++;</span>
|
||||
<span class="identifier">rv</span><span class="plain"> = </span><span class="functiontext">BuildScripts::execute</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">, </span><span class="identifier">V</span><span class="plain">-</span><span class="element">>script</span><span class="plain">, </span><span class="identifier">meth</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">trace</span><span class="plain">) { </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">trace</span><span class="plain">, </span><span class="string">"No build\</span><span class="plain">n</span><span class="string">"</span><span class="plain">); }</span>
|
||||
<span class="plain">}</span>
|
||||
</pre>
|
||||
|
||||
<p class="inwebparagraph"></p>
|
||||
|
||||
<p class="endnote">This code is used in <a href="#SP7_1">§7.1</a>.</p>
|
||||
|
||||
<p class="inwebparagraph"><a id="SP7_1_3_1"></a><b>§7.1.3.1. </b>This is where the incremental promise is finally kept. If the timestamp of
|
||||
<code class="display"><span class="extract">V</span></code> is definitely before later than that of everything it depends on, then
|
||||
it would be redundant to recreate it.
|
||||
</p>
|
||||
|
||||
<p class="inwebparagraph">Note that equal timestamps force rebuilding. File timestamping is quite coarse
|
||||
on some systems, so equal timeatamps might only mean that the two files were
|
||||
created during the same second.
|
||||
</p>
|
||||
|
||||
|
||||
<p class="macrodefinition"><code class="display">
|
||||
<<span class="cwebmacrodefn">Decide based on timestamps</span> <span class="cwebmacronumber">7.1.3.1</span>> =
|
||||
</code></p>
|
||||
|
||||
|
||||
<pre class="displaydefn">
|
||||
<span class="identifier">time_t</span><span class="plain"> </span><span class="identifier">last_up_to_date_at</span><span class="plain"> = </span><span class="functiontext">IncrementalBuild::timestamp</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">);</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">last_up_to_date_at</span><span class="plain"> == </span><span class="identifier">Platform::never_time</span><span class="plain">())</span>
|
||||
<span class="identifier">needs_building</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
||||
<span class="reserved">else</span><span class="plain"> {</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">trace</span><span class="plain">) { </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">trace</span><span class="plain">, </span><span class="string">"Last built at: %08x\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">last_up_to_date_at</span><span class="plain">); }</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">gb</span><span class="plain"> & </span><span class="constant">BUILD_DEPENDENCIES_MATTER_GB</span><span class="plain">) {</span>
|
||||
<span class="identifier">time_t</span><span class="plain"> </span><span class="identifier">t</span><span class="plain"> = </span><span class="functiontext">IncrementalBuild::time_of_latest_build_dependency</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">);</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">trace</span><span class="plain">) { </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">trace</span><span class="plain">, </span><span class="string">"Most recent build dependency: %08x\</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="reserved">if</span><span class="plain"> (</span><span class="functiontext">IncrementalBuild::timecmp</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">, </span><span class="identifier">last_up_to_date_at</span><span class="plain">) >= 0)</span>
|
||||
<span class="identifier">needs_building</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
||||
<span class="plain">}</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">gb</span><span class="plain"> & </span><span class="constant">USE_DEPENDENCIES_MATTER_GB</span><span class="plain">) {</span>
|
||||
<span class="identifier">time_t</span><span class="plain"> </span><span class="identifier">t</span><span class="plain"> = </span><span class="functiontext">IncrementalBuild::time_of_latest_use_dependency</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">);</span>
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">trace</span><span class="plain">) { </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">trace</span><span class="plain">, </span><span class="string">"Most recent use dependency: %08x\</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="reserved">if</span><span class="plain"> (</span><span class="functiontext">IncrementalBuild::timecmp</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">, </span><span class="identifier">last_up_to_date_at</span><span class="plain">) >= 0)</span>
|
||||
<span class="identifier">needs_building</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
||||
<span class="plain">}</span>
|
||||
<span class="plain">}</span>
|
||||
</pre>
|
||||
|
||||
<p class="inwebparagraph"></p>
|
||||
|
||||
<p class="endnote">This code is used in <a href="#SP7_1_3">§7.1.3</a>.</p>
|
||||
|
||||
<hr class="tocbar">
|
||||
<ul class="toc"><li><a href="3-bm.html">Back to 'Build Methodology'</a></li><li><a href="3-bs.html">Continue with 'Build Scripts'</a></li></ul><hr class="tocbar">
|
||||
<!--End of weave-->
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -92,7 +92,7 @@ in the dictionary after each successful use of that extension.
|
|||
|
||||
<p class="inwebparagraph"></p>
|
||||
|
||||
<p class="endnote">The structure extension_dictionary_entry is accessed in 3/bg and here.</p>
|
||||
<p class="endnote">The structure extension_dictionary_entry is accessed in 3/bg, 3/ib and here.</p>
|
||||
|
||||
<p class="inwebparagraph"><a id="SP3"></a><b>§3. </b>Clashes occur if, say, two extensions define "chopper" as a kind
|
||||
of vehicle (for instance, meaning a helicopter in one and a motorcycle
|
||||
|
|
|
@ -389,7 +389,6 @@ may be multiple sentences, which we need to count up.
|
|||
<span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">build_folder</span><span class="plain"> = </span><span class="functiontext">Projects::build_pathname</span><span class="plain">(</span><span class="identifier">project</span><span class="plain">);</span>
|
||||
<span class="identifier">filename</span><span class="plain"> *</span><span class="identifier">inf_F</span><span class="plain"> = </span><span class="identifier">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">build_folder</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"auto.inf"</span><span class="plain">);</span>
|
||||
|
||||
<span class="comment">build_vertex *inter_V = Graphs::ghost_vertex(I"binary inter in memory");</span>
|
||||
<span class="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">inter_V</span><span class="plain"> = </span><span class="functiontext">Graphs::file_vertex</span><span class="plain">(</span><span class="identifier">inf_F</span><span class="plain">);</span>
|
||||
<span class="functiontext">Graphs::need_this_to_build</span><span class="plain">(</span><span class="identifier">inter_V</span><span class="plain">, </span><span class="identifier">project</span><span class="plain">-</span><span class="element">>as_copy</span><span class="plain">-</span><span class="element">>vertex</span><span class="plain">);</span>
|
||||
<span class="functiontext">BuildSteps::attach</span><span class="plain">(</span><span class="identifier">inter_V</span><span class="plain">, </span><span class="identifier">compile_using_inform7_skill</span><span class="plain">,</span>
|
||||
|
@ -414,16 +413,14 @@ may be multiple sentences, which we need to count up.
|
|||
<span class="identifier">filename</span><span class="plain"> *</span><span class="identifier">blorbed_F</span><span class="plain"> = </span><span class="identifier">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">build_folder</span><span class="plain">, </span><span class="identifier">story_file_leafname2</span><span class="plain">);</span>
|
||||
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">story_file_leafname2</span><span class="plain">);</span>
|
||||
<span class="identifier">project</span><span class="plain">-</span><span class="element">>blorbed_vertex</span><span class="plain"> = </span><span class="functiontext">Graphs::file_vertex</span><span class="plain">(</span><span class="identifier">blorbed_F</span><span class="plain">);</span>
|
||||
<span class="identifier">project</span><span class="plain">-</span><span class="element">>blorbed_vertex</span><span class="plain">-</span><span class="element">>force_this</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
||||
<span class="identifier">project</span><span class="plain">-</span><span class="element">>blorbed_vertex</span><span class="plain">-</span><span class="element">>always_build_this</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
||||
<span class="functiontext">Graphs::need_this_to_build</span><span class="plain">(</span><span class="identifier">project</span><span class="plain">-</span><span class="element">>blorbed_vertex</span><span class="plain">, </span><span class="identifier">project</span><span class="plain">-</span><span class="element">>unblorbed_vertex</span><span class="plain">);</span>
|
||||
<span class="functiontext">BuildSteps::attach</span><span class="plain">(</span><span class="identifier">project</span><span class="plain">-</span><span class="element">>blorbed_vertex</span><span class="plain">, </span><span class="identifier">package_using_inblorb_skill</span><span class="plain">,</span>
|
||||
<span class="functiontext">Inbuild::nest_list</span><span class="plain">(), </span><span class="identifier">releasing</span><span class="plain">, </span><span class="identifier">VM</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">project</span><span class="plain">-</span><span class="element">>as_copy</span><span class="plain">);</span>
|
||||
|
||||
<span class="comment">inter_V->force_this = TRUE;</span>
|
||||
|
||||
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">compile_only</span><span class="plain">) {</span>
|
||||
<span class="identifier">project</span><span class="plain">-</span><span class="element">>chosen_build_target</span><span class="plain"> = </span><span class="identifier">inf_V</span><span class="plain">;</span>
|
||||
<span class="identifier">inf_V</span><span class="plain">-</span><span class="element">>force_this</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
||||
<span class="identifier">inf_V</span><span class="plain">-</span><span class="element">>always_build_this</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
||||
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">releasing</span><span class="plain">) </span><span class="identifier">project</span><span class="plain">-</span><span class="element">>chosen_build_target</span><span class="plain"> = </span><span class="identifier">project</span><span class="plain">-</span><span class="element">>blorbed_vertex</span><span class="plain">;</span>
|
||||
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">project</span><span class="plain">-</span><span class="element">>chosen_build_target</span><span class="plain"> = </span><span class="identifier">project</span><span class="plain">-</span><span class="element">>unblorbed_vertex</span><span class="plain">;</span>
|
||||
<span class="plain">}</span>
|
||||
|
|
|
@ -112,12 +112,16 @@
|
|||
<ul class="sectionlist">
|
||||
<li>
|
||||
<p><a href="3-bg.html"><spon class="sectiontitle">Build Graphs</span></a> -
|
||||
<span class="purpose">Graphs in which vertices correspond to files or copies, and arrows to dependencies between them.</span></p>
|
||||
<span class="purpose">Graphs in which vertices correspond to files or copies, and edges to dependencies between them.</span></p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="3-bm.html"><spon class="sectiontitle">Build Methodology</span></a> -
|
||||
<span class="purpose">Whether to run tasks internally in some merged tool, or run via the shell, or simply trace to the standard output what we think ought to be done.</span></p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="3-ib.html"><spon class="sectiontitle">Incremental Building</span></a> -
|
||||
<span class="purpose">Deciding what is the least possible amount which needs to be built, in what order, to arrive at a working version of a copy.</span></p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="3-bs.html"><spon class="sectiontitle">Build Scripts</span></a> -
|
||||
<span class="purpose">Scripts are nothing more than list of build steps.</span></p>
|
||||
|
|
|
@ -192,7 +192,7 @@ that we want to start work now.
|
|||
<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="identifier">build_trace_mode</span><span class="plain">) </span><span class="functiontext">IncrementalBuild::enable_trace</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>
|
||||
|
|
|
@ -93,7 +93,7 @@ that we want to start work now.
|
|||
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;
|
||||
if (build_trace_mode) IncrementalBuild::enable_trace();
|
||||
linked_list *L = Main::list_of_targets();
|
||||
inbuild_copy *C;
|
||||
LOOP_OVER_LINKED_LIST(C, inbuild_copy, L)
|
||||
|
|
|
@ -154,12 +154,12 @@ its main task: building an Inform project.
|
|||
void Copies::build(OUTPUT_STREAM, inbuild_copy *C, build_methodology *BM) {
|
||||
build_vertex *V = C->vertex;
|
||||
VMETHOD_CALL(C->edition->work->genre, GENRE_BUILDING_SOON_MTID, C, &V);
|
||||
Graphs::build(OUT, V, BM);
|
||||
IncrementalBuild::build(OUT, V, BM);
|
||||
}
|
||||
void Copies::rebuild(OUTPUT_STREAM, inbuild_copy *C, build_methodology *BM) {
|
||||
build_vertex *V = C->vertex;
|
||||
VMETHOD_CALL(C->edition->work->genre, GENRE_BUILDING_SOON_MTID, C, &V);
|
||||
Graphs::rebuild(OUT, V, BM);
|
||||
IncrementalBuild::rebuild(OUT, V, BM);
|
||||
}
|
||||
|
||||
@ Now in quick succession |-graph|, |-build-needs|, |-use-needs|, |-build-missing|,
|
||||
|
|
|
@ -1,39 +1,56 @@
|
|||
[Graphs::] Build Graphs.
|
||||
|
||||
Graphs in which vertices correspond to files or copies, and arrows to
|
||||
Graphs in which vertices correspond to files or copies, and edges to
|
||||
dependencies between them.
|
||||
|
||||
@h Build graphs.
|
||||
These are directed acyclic graphs which show what depends on what in the
|
||||
building process. If an arrow leads from A to B, then B must be built before
|
||||
A can be built.
|
||||
See the Inbuild manual for an introduction to the build graph. Properly
|
||||
speaking, it is a directed acyclic multigraph which us usually disconnected.
|
||||
|
||||
There can be two sorts of vertex in such a graph: copy vertices, each of which
|
||||
belongs to a single copy, and internal vertices, each of which represents
|
||||
a different file inside the copy.
|
||||
There are two colours of edge: build edges and use edges. A build edge between
|
||||
A and B means that B must exist and be up-to-date before A can be built.
|
||||
A use edge between A and B means that B must exist and be up-to-date before
|
||||
A can be used.
|
||||
|
||||
There are three colours of vertex: copy, file and requirement. Copy vertices
|
||||
correspond to copies which the user does have; requirement vertices to copies
|
||||
which she doesn't have; and file vertices to unmanaged plain files in
|
||||
the build process. For example, if an Inform project says it wants to include
|
||||
an extension which isn't anywhere to be seen, then the project itself is a
|
||||
copy vertex, as are the Standard Rules extension, the CommandParserKit kit,
|
||||
and such; the missing extension is represneted by a requirement vertex; and
|
||||
the story file which the project would compile to, if only it could be
|
||||
compiled, is a file vertex.
|
||||
|
||||
@e COPY_VERTEX from 1
|
||||
@e REQUIREMENT_VERTEX
|
||||
@e FILE_VERTEX
|
||||
@e GHOST_VERTEX
|
||||
@e REQUIREMENT_VERTEX
|
||||
|
||||
=
|
||||
typedef struct build_vertex {
|
||||
int type; /* one of the |*_VERTEX| values above */
|
||||
struct linked_list *build_edges; /* of |build_vertex| */
|
||||
struct linked_list *use_edges; /* of |build_vertex| */
|
||||
|
||||
struct inbuild_copy *buildable_if_copy;
|
||||
struct filename *buildable_if_internal_file;
|
||||
struct inbuild_requirement *findable;
|
||||
|
||||
struct text_stream *annotation;
|
||||
struct source_file *read_as;
|
||||
struct linked_list *build_edges; /* of |build_vertex| */
|
||||
struct linked_list *use_edges; /* of |build_vertex| */
|
||||
int last_described_in_generation;
|
||||
|
||||
int build_result;
|
||||
int last_built_in_generation;
|
||||
int always_build_this;
|
||||
struct build_script *script;
|
||||
int last_described;
|
||||
int built;
|
||||
int force_this;
|
||||
MEMORY_MANAGEMENT
|
||||
} build_vertex;
|
||||
|
||||
@h Creation.
|
||||
First, the three colours of vertex.
|
||||
|
||||
=
|
||||
build_vertex *Graphs::file_vertex(filename *F) {
|
||||
build_vertex *V = CREATE(build_vertex);
|
||||
V->type = FILE_VERTEX;
|
||||
|
@ -44,9 +61,10 @@ build_vertex *Graphs::file_vertex(filename *F) {
|
|||
V->script = BuildScripts::new();
|
||||
V->annotation = NULL;
|
||||
V->read_as = NULL;
|
||||
V->last_described = 0;
|
||||
V->built = FALSE;
|
||||
V->force_this = FALSE;
|
||||
V->last_described_in_generation = 0;
|
||||
V->build_result = NOT_APPLICABLE;
|
||||
V->last_built_in_generation = -1;
|
||||
V->always_build_this = FALSE;
|
||||
return V;
|
||||
}
|
||||
|
||||
|
@ -68,13 +86,10 @@ build_vertex *Graphs::req_vertex(inbuild_requirement *R) {
|
|||
return V;
|
||||
}
|
||||
|
||||
build_vertex *Graphs::ghost_vertex(text_stream *S) {
|
||||
build_vertex *V = Graphs::file_vertex(NULL);
|
||||
V->type = GHOST_VERTEX;
|
||||
V->annotation = Str::duplicate(S);
|
||||
return V;
|
||||
}
|
||||
@ Next, the two colours of edge. Note that between A and B there can be
|
||||
at most one edge of each colour.
|
||||
|
||||
=
|
||||
void Graphs::need_this_to_build(build_vertex *from, build_vertex *to) {
|
||||
if (from == NULL) internal_error("no from");
|
||||
if (to == NULL) internal_error("no to");
|
||||
|
@ -82,8 +97,6 @@ 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);
|
||||
}
|
||||
|
||||
|
@ -97,24 +110,36 @@ void Graphs::need_this_to_use(build_vertex *from, build_vertex *to) {
|
|||
ADD_TO_LINKED_LIST(to, build_vertex, from->use_edges);
|
||||
}
|
||||
|
||||
int description_round = 1;
|
||||
@ The script attached to a vertex is a list of instructions for how to build
|
||||
the resource it refers to. Some vertices have no instructions provided, so:
|
||||
|
||||
=
|
||||
int Graphs::can_be_built(build_vertex *V) {
|
||||
if (BuildScripts::script_length(V->script) > 0) return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@h Writing.
|
||||
This is a suitably indented printout of the graph as seen from a given
|
||||
vertex: it's used by the Inbuild command |-graph|.
|
||||
|
||||
=
|
||||
int no_desc_generations = 1;
|
||||
void Graphs::describe(OUTPUT_STREAM, build_vertex *V, int recurse) {
|
||||
Graphs::describe_r(OUT, 0, V, recurse, NULL, NOT_A_GB, description_round++);
|
||||
Graphs::describe_r(OUT, 0, V, recurse, NULL, NOT_APPLICABLE, no_desc_generations++);
|
||||
}
|
||||
void Graphs::describe_r(OUTPUT_STREAM, int depth, build_vertex *V,
|
||||
int recurse, pathname *stem, int which, int description_round) {
|
||||
int recurse, pathname *stem, int following_build_edge, int description_round) {
|
||||
for (int i=0; i<depth; i++) WRITE(" ");
|
||||
if (which == BUILD_GB) WRITE("--build-> ");
|
||||
if (which == USE_GB) WRITE("--use---> ");
|
||||
if (following_build_edge == TRUE) WRITE("--build-> ");
|
||||
if (following_build_edge == FALSE) WRITE("--use---> ");
|
||||
Graphs::describe_vertex(OUT, V);
|
||||
WRITE(" ");
|
||||
if (V->last_described == description_round) { WRITE("q.v.\n"); return; }
|
||||
TEMPORARY_TEXT(T);
|
||||
switch (V->type) {
|
||||
case COPY_VERTEX: Copies::write_copy(T, V->buildable_if_copy); break;
|
||||
case REQUIREMENT_VERTEX: Requirements::write(T, V->findable); break;
|
||||
case FILE_VERTEX: WRITE("%f", V->buildable_if_internal_file); break;
|
||||
case GHOST_VERTEX: WRITE("(%S)", V->annotation); break;
|
||||
}
|
||||
TEMPORARY_TEXT(S);
|
||||
WRITE_TO(S, "%p", stem);
|
||||
|
@ -125,6 +150,8 @@ void Graphs::describe_r(OUTPUT_STREAM, int depth, build_vertex *V,
|
|||
}
|
||||
DISCARD_TEXT(S);
|
||||
DISCARD_TEXT(T);
|
||||
if (V->last_described_in_generation == description_round) { WRITE(" q.v.\n"); return; }
|
||||
V->last_described_in_generation = description_round;
|
||||
WRITE("\n");
|
||||
if (recurse) {
|
||||
if (V->buildable_if_copy) stem = V->buildable_if_copy->location_if_path;
|
||||
|
@ -132,9 +159,9 @@ void Graphs::describe_r(OUTPUT_STREAM, int depth, build_vertex *V,
|
|||
stem = Filenames::get_path_to(V->buildable_if_internal_file);
|
||||
build_vertex *W;
|
||||
LOOP_OVER_LINKED_LIST(W, build_vertex, V->build_edges)
|
||||
Graphs::describe_r(OUT, depth+1, W, TRUE, stem, BUILD_GB, description_round);
|
||||
Graphs::describe_r(OUT, depth+1, W, TRUE, stem, TRUE, description_round);
|
||||
LOOP_OVER_LINKED_LIST(W, build_vertex, V->use_edges)
|
||||
Graphs::describe_r(OUT, depth+1, W, TRUE, stem, USE_GB, description_round);
|
||||
Graphs::describe_r(OUT, depth+1, W, TRUE, stem, FALSE, description_round);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -144,15 +171,18 @@ void Graphs::describe_vertex(OUTPUT_STREAM, build_vertex *V) {
|
|||
case COPY_VERTEX: WRITE("[c%d]", V->allocation_id); break;
|
||||
case REQUIREMENT_VERTEX: WRITE("[r%d]", V->allocation_id); break;
|
||||
case FILE_VERTEX: WRITE("[f%d]", V->allocation_id); break;
|
||||
case GHOST_VERTEX: WRITE("[g%d]", V->allocation_id); break;
|
||||
}
|
||||
}
|
||||
|
||||
@ A similar but slightly different recursion for |-build-needs| and |-use-needs|.
|
||||
|
||||
=
|
||||
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, int uses_only) {
|
||||
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;
|
||||
|
@ -165,7 +195,8 @@ void Graphs::show_needs_r(OUTPUT_STREAM, build_vertex *V, int depth, int true_de
|
|||
WRITE("missing %S: ", V->findable->work->genre->genre_name);
|
||||
Works::write(OUT, V->findable->work);
|
||||
if (VersionNumberRanges::is_any_range(V->findable->version_range) == FALSE) {
|
||||
WRITE(", need version in range "); VersionNumberRanges::write_range(OUT, V->findable->version_range);
|
||||
WRITE(", need version in range ");
|
||||
VersionNumberRanges::write_range(OUT, V->findable->version_range);
|
||||
} else {
|
||||
WRITE(", any version will do");
|
||||
}
|
||||
|
@ -182,17 +213,22 @@ void Graphs::show_needs_r(OUTPUT_STREAM, build_vertex *V, int depth, int true_de
|
|||
}
|
||||
}
|
||||
|
||||
@ And for |-build-missing| and |-use-missing|.
|
||||
|
||||
=
|
||||
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 uses_only) {
|
||||
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);
|
||||
Works::write(OUT, V->findable->work);
|
||||
if (VersionNumberRanges::is_any_range(V->findable->version_range) == FALSE) {
|
||||
WRITE(", need version in range "); VersionNumberRanges::write_range(OUT, V->findable->version_range);
|
||||
WRITE(", need version in range ");
|
||||
VersionNumberRanges::write_range(OUT, V->findable->version_range);
|
||||
} else {
|
||||
WRITE(", any version will do");
|
||||
}
|
||||
|
@ -210,34 +246,27 @@ int Graphs::show_missing_r(OUTPUT_STREAM, build_vertex *V, int true_depth, int u
|
|||
return N;
|
||||
}
|
||||
|
||||
void Graphs::archive(OUTPUT_STREAM, build_vertex *V, inbuild_nest *N, build_methodology *BM) {
|
||||
@h Archiving.
|
||||
This isn't simply a matter of printing out, of course, but very similar code
|
||||
handles |-archive| and |-archive-to N|.
|
||||
|
||||
Note that the English language definition, which lives in the internal nest,
|
||||
cannot be read from any other nest -- so we won't archive it.
|
||||
|
||||
=
|
||||
void Graphs::archive(OUTPUT_STREAM, build_vertex *V, inbuild_nest *N,
|
||||
build_methodology *BM) {
|
||||
Graphs::archive_r(OUT, V, 0, N, BM);
|
||||
}
|
||||
|
||||
void Graphs::archive_r(OUTPUT_STREAM, build_vertex *V, int true_depth, inbuild_nest *N, build_methodology *BM) {
|
||||
void Graphs::archive_r(OUTPUT_STREAM, build_vertex *V, int true_depth, inbuild_nest *N,
|
||||
build_methodology *BM) {
|
||||
if (V->type == COPY_VERTEX) {
|
||||
inbuild_copy *C = V->buildable_if_copy;
|
||||
if ((Genres::stored_in_nests(C->edition->work->genre)) &&
|
||||
((Str::ne(C->edition->work->title, I"English")) ||
|
||||
(Str::len(C->edition->work->author_name) > 0))) {
|
||||
WRITE("%S: ", C->edition->work->genre->genre_name);
|
||||
Copies::write_copy(OUT, C);
|
||||
|
||||
pathname *P = C->location_if_path;
|
||||
if (C->location_if_file) P = Filenames::get_path_to(C->location_if_file);
|
||||
TEMPORARY_TEXT(nl);
|
||||
TEMPORARY_TEXT(cl);
|
||||
WRITE_TO(nl, "%p/", N->location);
|
||||
WRITE_TO(cl, "%p/", P);
|
||||
if (Str::prefix_eq(cl, nl, Str::len(nl))) {
|
||||
WRITE(" -- already there\n");
|
||||
} else {
|
||||
WRITE(" -- archiving\n");
|
||||
Copies::copy_to(C, N, TRUE, BM);
|
||||
}
|
||||
DISCARD_TEXT(nl);
|
||||
DISCARD_TEXT(cl);
|
||||
}
|
||||
(Str::len(C->edition->work->author_name) > 0)))
|
||||
@<Archive a single copy@>;
|
||||
}
|
||||
build_vertex *W;
|
||||
LOOP_OVER_LINKED_LIST(W, build_vertex, V->build_edges)
|
||||
|
@ -248,120 +277,24 @@ void Graphs::archive_r(OUTPUT_STREAM, build_vertex *V, int true_depth, inbuild_n
|
|||
}
|
||||
}
|
||||
|
||||
time_t Graphs::timestamp_for(build_vertex *V) {
|
||||
time_t latest = (time_t) 0;
|
||||
@ The most delicate thing here is that we don't want to archive something
|
||||
to |N| if it's already there; but that is difficult to detect.
|
||||
|
||||
if (V->buildable_if_internal_file) {
|
||||
char transcoded_pathname[4*MAX_FILENAME_LENGTH];
|
||||
TEMPORARY_TEXT(FN);
|
||||
WRITE_TO(FN, "%f", V->buildable_if_internal_file);
|
||||
Str::copy_to_locale_string(transcoded_pathname, FN, 4*MAX_FILENAME_LENGTH);
|
||||
DISCARD_TEXT(FN);
|
||||
struct stat filestat;
|
||||
if (stat(transcoded_pathname, &filestat) != -1) latest = filestat.st_mtime;
|
||||
@<Archive a single copy@> =
|
||||
WRITE("%S: ", C->edition->work->genre->genre_name);
|
||||
Copies::write_copy(OUT, C);
|
||||
|
||||
pathname *P = C->location_if_path;
|
||||
if (C->location_if_file) P = Filenames::get_path_to(C->location_if_file);
|
||||
TEMPORARY_TEXT(nl);
|
||||
TEMPORARY_TEXT(cl);
|
||||
WRITE_TO(nl, "%p/", N->location);
|
||||
WRITE_TO(cl, "%p/", P);
|
||||
if (Str::prefix_eq(cl, nl, Str::len(nl))) {
|
||||
WRITE(" -- already there\n");
|
||||
} else {
|
||||
latest = Graphs::time_of_most_recent_ingredient(V);
|
||||
}
|
||||
|
||||
return latest;
|
||||
}
|
||||
|
||||
time_t Graphs::time_of_most_recent_ingredient(build_vertex *V) {
|
||||
time_t latest = (time_t) 0;
|
||||
|
||||
build_vertex *W;
|
||||
LOOP_OVER_LINKED_LIST(W, build_vertex, V->build_edges) {
|
||||
time_t inner = Graphs::timestamp_for(W);
|
||||
if ((latest == (time_t) 0) || (difftime(inner, latest) > 0))
|
||||
latest = inner;
|
||||
}
|
||||
|
||||
return latest;
|
||||
}
|
||||
|
||||
time_t Graphs::time_of_most_recent_used_resource(build_vertex *V) {
|
||||
time_t latest = (time_t) 0;
|
||||
|
||||
build_vertex *W;
|
||||
LOOP_OVER_LINKED_LIST(W, build_vertex, V->use_edges) {
|
||||
time_t inner = Graphs::timestamp_for(W);
|
||||
if ((latest == (time_t) 0) || (difftime(inner, latest) > 0))
|
||||
latest = inner;
|
||||
}
|
||||
|
||||
return latest;
|
||||
}
|
||||
|
||||
@
|
||||
|
||||
@d NOT_A_GB 0
|
||||
@d BUILD_GB 1
|
||||
@d FORCE_GB 2
|
||||
@d USE_GB 4
|
||||
|
||||
=
|
||||
int Graphs::build(OUTPUT_STREAM, build_vertex *V, build_methodology *meth) {
|
||||
int changes = 0;
|
||||
return Graphs::build_r(OUT, BUILD_GB, V, meth, &changes);
|
||||
}
|
||||
int Graphs::rebuild(OUTPUT_STREAM, build_vertex *V, build_methodology *meth) {
|
||||
int changes = 0;
|
||||
return Graphs::build_r(OUT, BUILD_GB + FORCE_GB, V, meth, &changes);
|
||||
}
|
||||
int trace_ibg = FALSE;
|
||||
int Graphs::build_r(OUTPUT_STREAM, int gb, build_vertex *V, build_methodology *meth, int *changes) {
|
||||
if (trace_ibg) { WRITE_TO(STDOUT, "Visit: "); Graphs::describe(STDOUT, V, FALSE); }
|
||||
|
||||
if (V->built) return TRUE;
|
||||
|
||||
int changes_so_far = *changes;
|
||||
if (trace_ibg) { STREAM_INDENT(STDOUT); }
|
||||
int rv = TRUE;
|
||||
build_vertex *W;
|
||||
LOOP_OVER_LINKED_LIST(W, build_vertex, V->build_edges)
|
||||
if (rv)
|
||||
rv = Graphs::build_r(OUT, gb | USE_GB, W, meth, changes);
|
||||
if (gb & USE_GB)
|
||||
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);
|
||||
if (trace_ibg) { STREAM_OUTDENT(STDOUT); }
|
||||
if (rv) {
|
||||
int needs_building = FALSE;
|
||||
if ((gb & FORCE_GB) || (V->force_this)) needs_building = TRUE;
|
||||
else if ((V->type == GHOST_VERTEX) && (*changes > changes_so_far)) needs_building = TRUE;
|
||||
else @<Decide based on timestamps@>;
|
||||
|
||||
if ((needs_building) && (BuildScripts::script_length(V->script) > 0)) {
|
||||
if (trace_ibg) { WRITE_TO(STDOUT, "Build: "); Graphs::describe(STDOUT, V, FALSE); }
|
||||
(*changes)++;
|
||||
rv = BuildScripts::execute(V, V->script, meth);
|
||||
} else {
|
||||
if (trace_ibg) { WRITE_TO(STDOUT, "No Build\n"); }
|
||||
}
|
||||
}
|
||||
V->built = rv;
|
||||
return rv;
|
||||
}
|
||||
|
||||
@<Decide based on timestamps@> =
|
||||
time_t last_built_at = Graphs::timestamp_for(V);
|
||||
if (trace_ibg) { WRITE_TO(STDOUT, "Last built at: %08x\n", last_built_at); }
|
||||
if (last_built_at == (time_t) 0)
|
||||
needs_building = TRUE;
|
||||
else {
|
||||
time_t time_of_most_recent = Graphs::time_of_most_recent_ingredient(V);
|
||||
if (time_of_most_recent != (time_t) 0) {
|
||||
if (trace_ibg) { WRITE_TO(STDOUT, "Most recent: %08x\n", time_of_most_recent); }
|
||||
if (difftime(time_of_most_recent, last_built_at) > 0)
|
||||
needs_building = TRUE;
|
||||
}
|
||||
if (gb & USE_GB) {
|
||||
time_t time_of_most_recent_used = Graphs::time_of_most_recent_used_resource(V);
|
||||
if (time_of_most_recent_used != (time_t) 0) {
|
||||
if (trace_ibg) { WRITE_TO(STDOUT, "Most recent use: %08x\n", time_of_most_recent_used); }
|
||||
if (difftime(time_of_most_recent_used, last_built_at) > 0)
|
||||
needs_building = TRUE;
|
||||
}
|
||||
}
|
||||
WRITE(" -- archiving\n");
|
||||
Copies::copy_to(C, N, TRUE, BM);
|
||||
}
|
||||
DISCARD_TEXT(nl);
|
||||
DISCARD_TEXT(cl);
|
||||
|
|
231
inbuild/inbuild-module/Chapter 3/Incremental Building.w
Normal file
231
inbuild/inbuild-module/Chapter 3/Incremental Building.w
Normal file
|
@ -0,0 +1,231 @@
|
|||
[IncrementalBuild::] Incremental Building.
|
||||
|
||||
Deciding what is the least possible amount which needs to be built, in what
|
||||
order, to arrive at a working version of a copy.
|
||||
|
||||
@h Timestamps.
|
||||
We want to assign a timestamp to every vertex in the graph, whose meaning is
|
||||
that what it represents has been up-to-date since that time.
|
||||
|
||||
For a file vertex, we take that from the file system's timestamp. For a
|
||||
copy vertex, we do the same for a copy which is a single file (such as an
|
||||
extension), but for a copy which is a directory containing a composite of
|
||||
resources, there's no good way to know. (Perhaps we could scan the files
|
||||
in it recursively, but then we have to worry about hidden files, symlinks,
|
||||
and all of that.) Instead, we use the build graph itself to decide; for
|
||||
example, the timestamp for a kit is the most recent timestamp of any of its
|
||||
binary Inter files, because those are its build-dependencies.
|
||||
|
||||
=
|
||||
time_t IncrementalBuild::timestamp(build_vertex *V) {
|
||||
switch (V->type) {
|
||||
case FILE_VERTEX:
|
||||
return Filenames::timestamp(V->buildable_if_internal_file);
|
||||
case COPY_VERTEX:
|
||||
if (V->buildable_if_copy->location_if_file)
|
||||
return Filenames::timestamp(V->buildable_if_copy->location_if_file);
|
||||
return IncrementalBuild::time_of_latest_build_dependency(V);
|
||||
default:
|
||||
return Platform::never_time();
|
||||
}
|
||||
}
|
||||
|
||||
@ The following compares two times: it returns 1 if |t1| is later, -1 if
|
||||
|t2| is later, and 0 if they are identical.
|
||||
|
||||
Note that we never apply the C standard library function |difftime| in
|
||||
the case of the never-time, which we consider to be before all other times.
|
||||
(On most platforms it will be the C epoch of 1970, and |difftime| alone
|
||||
would be fine, but we're being careful.)
|
||||
|
||||
=
|
||||
int IncrementalBuild::timecmp(time_t t1, time_t t2) {
|
||||
if (t1 == Platform::never_time()) {
|
||||
if (t2 == Platform::never_time()) return 0;
|
||||
return -1;
|
||||
}
|
||||
if (t2 == Platform::never_time()) {
|
||||
return 1;
|
||||
}
|
||||
if (t1 == t2) return 0;
|
||||
if (difftime(t1, t2) > 0) return 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ We then take the latest timestamp of any build dependency:
|
||||
|
||||
=
|
||||
time_t IncrementalBuild::time_of_latest_build_dependency(build_vertex *V) {
|
||||
time_t latest = Platform::never_time();
|
||||
|
||||
build_vertex *W;
|
||||
LOOP_OVER_LINKED_LIST(W, build_vertex, V->build_edges) {
|
||||
time_t t = IncrementalBuild::timestamp(W);
|
||||
if (IncrementalBuild::timecmp(t, latest) > 0) latest = t;
|
||||
}
|
||||
|
||||
return latest;
|
||||
}
|
||||
|
||||
@ And of any use dependency:
|
||||
|
||||
=
|
||||
time_t IncrementalBuild::time_of_latest_use_dependency(build_vertex *V) {
|
||||
time_t latest = Platform::never_time();
|
||||
|
||||
build_vertex *W;
|
||||
LOOP_OVER_LINKED_LIST(W, build_vertex, V->use_edges) {
|
||||
time_t t = IncrementalBuild::timestamp(W);
|
||||
if (IncrementalBuild::timecmp(t, latest) > 0) latest = t;
|
||||
}
|
||||
|
||||
return latest;
|
||||
}
|
||||
|
||||
@h Build process.
|
||||
This is a recursive process, beginning at the node representing what we want
|
||||
to build. As we recurse, we pass a bitmap of the following:
|
||||
|
||||
@d BUILD_DEPENDENCIES_MATTER_GB 1 /* We will need all your build dependencies too */
|
||||
@d USE_DEPENDENCIES_MATTER_GB 2 /* We will need all your use dependencies too */
|
||||
@d IGNORE_TIMESTAMPS_GB 4 /* Don't be incremental: trust nothing, rebuild everything */
|
||||
|
||||
=
|
||||
int IncrementalBuild::build(OUTPUT_STREAM, build_vertex *V, build_methodology *meth) {
|
||||
return IncrementalBuild::begin_recursion(OUT,
|
||||
BUILD_DEPENDENCIES_MATTER_GB, V, meth);
|
||||
}
|
||||
int IncrementalBuild::rebuild(OUTPUT_STREAM, build_vertex *V, build_methodology *meth) {
|
||||
return IncrementalBuild::begin_recursion(OUT,
|
||||
BUILD_DEPENDENCIES_MATTER_GB + IGNORE_TIMESTAMPS_GB, V, meth);
|
||||
}
|
||||
|
||||
@ This is called when Inbuild's |-trace| switch is set at the command line.
|
||||
|
||||
=
|
||||
int trace_ibg = FALSE;
|
||||
void IncrementalBuild::enable_trace(void) {
|
||||
trace_ibg = TRUE;
|
||||
}
|
||||
|
||||
@ We want to be very sure that this recursion does not lock up, or perform
|
||||
unnecessary work by performing the same node twice. To do this we apply the
|
||||
|built| flag to a node when it has been built; but to make this is not left
|
||||
over from last time around, we only regard it when the |last_built_in_generation| count
|
||||
for the node is set to the current "generation", a unique number incremented
|
||||
for each time we recurse.
|
||||
|
||||
=
|
||||
int no_build_generations = 0;
|
||||
int IncrementalBuild::begin_recursion(OUTPUT_STREAM, int gb, build_vertex *V,
|
||||
build_methodology *meth) {
|
||||
int changes = 0;
|
||||
text_stream *trace = NULL;
|
||||
if (trace_ibg) trace = STDOUT;
|
||||
WRITE_TO(trace, "Incremental build %d:\n", no_build_generations);
|
||||
int rv = IncrementalBuild::recurse(OUT, trace, gb, V, meth, &changes, no_build_generations++);
|
||||
WRITE_TO(trace, "%d change(s)\n", changes);
|
||||
return rv;
|
||||
}
|
||||
|
||||
int IncrementalBuild::recurse(OUTPUT_STREAM, text_stream *trace, int gb, build_vertex *V,
|
||||
build_methodology *meth, int *changes, int generation) {
|
||||
if (trace) {
|
||||
WRITE_TO(trace, "Visit %c%c%c: ",
|
||||
(gb & BUILD_DEPENDENCIES_MATTER_GB)?'b':'.',
|
||||
(gb & USE_DEPENDENCIES_MATTER_GB)?'u':'.',
|
||||
(gb & IGNORE_TIMESTAMPS_GB)?'i':'.');
|
||||
Graphs::describe(trace, V, FALSE);
|
||||
}
|
||||
|
||||
if (V->last_built_in_generation == generation) return V->build_result;
|
||||
int rv = TRUE;
|
||||
@<Build this node if necessary, setting rv to its success or failure@>;
|
||||
V->build_result = rv;
|
||||
V->last_built_in_generation = generation;
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ In everything which follows, |rv| (prosaically, this stands only for "return
|
||||
value") remains |TRUE| until the first active step fails, at which point no
|
||||
other active steps are ever taken, nor are any recursions made. In effect,
|
||||
the first failure halts the process.
|
||||
|
||||
We are recursing depth-first, that is, we build the things needed to build
|
||||
|V| before we build |V| itself.
|
||||
|
||||
A point of difference between this algorithm and |make| is that we do not
|
||||
halt with an error if a node has no way to be built. This is because the
|
||||
graphs are here are built by Inbuild itself, not by a possibly erroneous
|
||||
makefile whose author has forgotten something and whose intentions are not
|
||||
clear. Here, if a node has no build script attached, it must be because it
|
||||
needs no action taken.
|
||||
|
||||
@<Build this node if necessary, setting rv to its success or failure@> =
|
||||
if (trace) STREAM_INDENT(trace);
|
||||
if (gb & BUILD_DEPENDENCIES_MATTER_GB) @<Build the build dependencies of the node@>;
|
||||
if (gb & USE_DEPENDENCIES_MATTER_GB) @<Build the use dependencies of the node@>;
|
||||
if (trace) STREAM_OUTDENT(trace);
|
||||
if ((rv) && (Graphs::can_be_built(V))) @<Build the node itself, if necessary@>;
|
||||
|
||||
@ Suppose V needs W (for whatever reason), and that W can only be used with X.
|
||||
It follows that we will have to build X as well as W, since the process of
|
||||
building V is itself a use of W, and therefore of X. So we always enable the
|
||||
|USE_DEPENDENCIES_MATTER_GB| bit when recursing through an edge.
|
||||
|
||||
@<Build the build dependencies of the node@> =
|
||||
build_vertex *W;
|
||||
LOOP_OVER_LINKED_LIST(W, build_vertex, V->build_edges)
|
||||
if (rv)
|
||||
rv = IncrementalBuild::recurse(OUT, trace,
|
||||
gb | USE_DEPENDENCIES_MATTER_GB, W, meth, changes, generation);
|
||||
|
||||
@<Build the use dependencies of the node@> =
|
||||
build_vertex *W;
|
||||
LOOP_OVER_LINKED_LIST(W, build_vertex, V->use_edges)
|
||||
if (rv)
|
||||
rv = IncrementalBuild::recurse(OUT, trace,
|
||||
gb | USE_DEPENDENCIES_MATTER_GB, W, meth, changes, generation);
|
||||
|
||||
@ Now for the node |V| itself.
|
||||
|
||||
@<Build the node itself, if necessary@> =
|
||||
int needs_building = FALSE;
|
||||
if ((gb & IGNORE_TIMESTAMPS_GB) || (V->always_build_this)) needs_building = TRUE;
|
||||
else @<Decide based on timestamps@>;
|
||||
|
||||
if (needs_building) {
|
||||
if (trace) { WRITE_TO(trace, "Build: "); Graphs::describe(trace, V, FALSE); }
|
||||
(*changes)++;
|
||||
rv = BuildScripts::execute(V, V->script, meth);
|
||||
} else {
|
||||
if (trace) { WRITE_TO(trace, "No build\n"); }
|
||||
}
|
||||
|
||||
@ This is where the incremental promise is finally kept. If the timestamp of
|
||||
|V| is definitely before later than that of everything it depends on, then
|
||||
it would be redundant to recreate it.
|
||||
|
||||
Note that equal timestamps force rebuilding. File timestamping is quite coarse
|
||||
on some systems, so equal timeatamps might only mean that the two files were
|
||||
created during the same second.
|
||||
|
||||
@<Decide based on timestamps@> =
|
||||
time_t last_up_to_date_at = IncrementalBuild::timestamp(V);
|
||||
if (last_up_to_date_at == Platform::never_time())
|
||||
needs_building = TRUE;
|
||||
else {
|
||||
if (trace) { WRITE_TO(trace, "Last built at: %08x\n", last_up_to_date_at); }
|
||||
if (gb & BUILD_DEPENDENCIES_MATTER_GB) {
|
||||
time_t t = IncrementalBuild::time_of_latest_build_dependency(V);
|
||||
if (trace) { WRITE_TO(trace, "Most recent build dependency: %08x\n", t); }
|
||||
if (IncrementalBuild::timecmp(t, last_up_to_date_at) >= 0)
|
||||
needs_building = TRUE;
|
||||
}
|
||||
if (gb & USE_DEPENDENCIES_MATTER_GB) {
|
||||
time_t t = IncrementalBuild::time_of_latest_use_dependency(V);
|
||||
if (trace) { WRITE_TO(trace, "Most recent use dependency: %08x\n", t); }
|
||||
if (IncrementalBuild::timecmp(t, last_up_to_date_at) >= 0)
|
||||
needs_building = TRUE;
|
||||
}
|
||||
}
|
|
@ -262,7 +262,6 @@ void Projects::construct_build_target(inform_project *project, target_vm *VM,
|
|||
pathname *build_folder = Projects::build_pathname(project);
|
||||
filename *inf_F = Filenames::in_folder(build_folder, I"auto.inf");
|
||||
|
||||
// build_vertex *inter_V = Graphs::ghost_vertex(I"binary inter in memory");
|
||||
build_vertex *inter_V = Graphs::file_vertex(inf_F);
|
||||
Graphs::need_this_to_build(inter_V, project->as_copy->vertex);
|
||||
BuildSteps::attach(inter_V, compile_using_inform7_skill,
|
||||
|
@ -287,16 +286,14 @@ void Projects::construct_build_target(inform_project *project, target_vm *VM,
|
|||
filename *blorbed_F = Filenames::in_folder(build_folder, story_file_leafname2);
|
||||
DISCARD_TEXT(story_file_leafname2);
|
||||
project->blorbed_vertex = Graphs::file_vertex(blorbed_F);
|
||||
project->blorbed_vertex->force_this = TRUE;
|
||||
project->blorbed_vertex->always_build_this = TRUE;
|
||||
Graphs::need_this_to_build(project->blorbed_vertex, project->unblorbed_vertex);
|
||||
BuildSteps::attach(project->blorbed_vertex, package_using_inblorb_skill,
|
||||
Inbuild::nest_list(), releasing, VM, NULL, project->as_copy);
|
||||
|
||||
// inter_V->force_this = TRUE;
|
||||
|
||||
if (compile_only) {
|
||||
project->chosen_build_target = inf_V;
|
||||
inf_V->force_this = TRUE;
|
||||
inf_V->always_build_this = TRUE;
|
||||
} else if (releasing) project->chosen_build_target = project->blorbed_vertex;
|
||||
else project->chosen_build_target = project->unblorbed_vertex;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ Chapter 2: Conceptual Framework
|
|||
Chapter 3: Incremental Builds
|
||||
Build Graphs
|
||||
Build Methodology
|
||||
Incremental Building
|
||||
Build Scripts
|
||||
Build Steps
|
||||
Inter Skill
|
||||
|
|
Loading…
Reference in a new issue