inweb-bootstrap/docs/foundation-module/8-bf.html
2020-04-07 00:53:26 +01:00

289 lines
40 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>8/wm</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="../inweb/index.html">inweb</a></li>
</ul>
<h2>Foundation</h2>
<ul>
<li><a href="../foundation-module/index.html">foundation-module</a></li>
<li><a href="../foundation-test/index.html">foundation-test</a></li>
</ul>
</nav>
<main role="main">
<!--Weave of '8/bf' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">Source</a></li><li><a href="index.html">foundation</a></li><li><a href="index.html#8">Chapter 8: Literate Programming</a></li><li><b>Build Files</b></li></ul><p class="purpose">Manages the build metadata for an inweb project.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. About build files</a></li><li><a href="#SP5">&#167;5. Bibliographic implications</a></li><li><a href="#SP7">&#167;7. Advancing</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. About build files. </b>When we read a web, we look for a file in it called <code class="display"><span class="extract">build.txt</span></code>. If no such
file exists, we look for the same thing in the current working directory.
</p>
<pre class="display">
<span class="reserved">filename</span><span class="plain"> *</span><span class="functiontext">BuildFiles::build_file_for_web</span><span class="plain">(</span><span class="reserved">web_md</span><span class="plain"> *</span><span class="identifier">WS</span><span class="plain">) {</span>
<span class="reserved">filename</span><span class="plain"> *</span><span class="identifier">F</span><span class="plain"> = </span><span class="functiontext">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">WS</span><span class="plain">-&gt;</span><span class="element">path_to_web</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"build.txt"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">TextFiles::exists</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">F</span><span class="plain">;</span>
<span class="identifier">F</span><span class="plain"> = </span><span class="functiontext">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"build.txt"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">TextFiles::exists</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">F</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function BuildFiles::build_file_for_web is used in <a href="#SP5">&#167;5</a>, <a href="#SP7">&#167;7</a>.</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>The format of such a file is very simple: up to three text fields:
</p>
<pre class="display">
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">build_file_data</span><span class="plain"> {</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">prerelease_text</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">build_code</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">build_date</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">build_file_data</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The structure build_file_data is private to this section.</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>Here's how to read in a build file:
</p>
<pre class="display">
<span class="reserved">build_file_data</span><span class="plain"> </span><span class="functiontext">BuildFiles::read</span><span class="plain">(</span><span class="reserved">filename</span><span class="plain"> *</span><span class="identifier">F</span><span class="plain">) {</span>
<span class="reserved">build_file_data</span><span class="plain"> </span><span class="identifier">bfd</span><span class="plain">;</span>
<span class="identifier">bfd</span><span class="plain">.</span><span class="element">prerelease_text</span><span class="plain"> = </span><span class="functiontext">Str::new</span><span class="plain">();</span>
<span class="identifier">bfd</span><span class="plain">.</span><span class="element">build_code</span><span class="plain"> = </span><span class="functiontext">Str::new</span><span class="plain">();</span>
<span class="identifier">bfd</span><span class="plain">.</span><span class="element">build_date</span><span class="plain"> = </span><span class="functiontext">Str::new</span><span class="plain">();</span>
<span class="functiontext">TextFiles::read</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">, </span><span class="constant">FALSE</span><span class="plain">, </span><span class="string">"unable to read build file"</span><span class="plain">, </span><span class="constant">TRUE</span><span class="plain">,</span>
<span class="plain">&amp;</span><span class="functiontext">BuildFiles::build_file_helper</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, (</span><span class="reserved">void</span><span class="plain"> *) &amp;</span><span class="identifier">bfd</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">bfd</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">BuildFiles::build_file_helper</span><span class="plain">(</span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">text</span><span class="plain">, </span><span class="reserved">text_file_position</span><span class="plain"> *</span><span class="identifier">tfp</span><span class="plain">, </span><span class="reserved">void</span><span class="plain"> *</span><span class="identifier">state</span><span class="plain">) {</span>
<span class="reserved">build_file_data</span><span class="plain"> *</span><span class="identifier">bfd</span><span class="plain"> = (</span><span class="reserved">build_file_data</span><span class="plain"> *) </span><span class="identifier">state</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Str::len</span><span class="plain">(</span><span class="identifier">text</span><span class="plain">) == </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="reserved">match_results</span><span class="plain"> </span><span class="identifier">mr</span><span class="plain"> = </span><span class="functiontext">Regexp::create_mr</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Regexp::match</span><span class="plain">(&amp;</span><span class="identifier">mr</span><span class="plain">, </span><span class="identifier">text</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"Build Date: *(%c*)"</span><span class="plain">)) {</span>
<span class="identifier">bfd</span><span class="plain">-&gt;</span><span class="element">build_date</span><span class="plain"> = </span><span class="functiontext">Str::duplicate</span><span class="plain">(</span><span class="identifier">mr</span><span class="plain">.</span><span class="element">exp</span><span class="plain">[0]);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Regexp::match</span><span class="plain">(&amp;</span><span class="identifier">mr</span><span class="plain">, </span><span class="identifier">text</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"Build Number: *(%c*)"</span><span class="plain">)) {</span>
<span class="identifier">bfd</span><span class="plain">-&gt;</span><span class="element">build_code</span><span class="plain"> = </span><span class="functiontext">Str::duplicate</span><span class="plain">(</span><span class="identifier">mr</span><span class="plain">.</span><span class="element">exp</span><span class="plain">[0]);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Regexp::match</span><span class="plain">(&amp;</span><span class="identifier">mr</span><span class="plain">, </span><span class="identifier">text</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"Prerelease: *(%c*)"</span><span class="plain">)) {</span>
<span class="identifier">bfd</span><span class="plain">-&gt;</span><span class="element">prerelease_text</span><span class="plain"> = </span><span class="functiontext">Str::duplicate</span><span class="plain">(</span><span class="identifier">mr</span><span class="plain">.</span><span class="element">exp</span><span class="plain">[0]);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="functiontext">Errors::in_text_file</span><span class="plain">(</span><span class="string">"can't parse build file line"</span><span class="plain">, </span><span class="identifier">tfp</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="functiontext">Regexp::dispose_of</span><span class="plain">(&amp;</span><span class="identifier">mr</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function BuildFiles::read is used in <a href="#SP5">&#167;5</a>, <a href="#SP7">&#167;7</a>.</p>
<p class="endnote">The function BuildFiles::build_file_helper appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>And here is how to write one:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">BuildFiles::write</span><span class="plain">(</span><span class="reserved">build_file_data</span><span class="plain"> </span><span class="identifier">bfd</span><span class="plain">, </span><span class="reserved">filename</span><span class="plain"> *</span><span class="identifier">F</span><span class="plain">) {</span>
<span class="reserved">text_stream</span><span class="plain"> </span><span class="identifier">vr_stream</span><span class="plain">;</span>
<span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">OUT</span><span class="plain"> = &amp;</span><span class="identifier">vr_stream</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Streams::open_to_file</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">F</span><span class="plain">, </span><span class="constant">UTF8_ENC</span><span class="plain">) == </span><span class="constant">FALSE</span><span class="plain">)</span>
<span class="functiontext">Errors::fatal_with_file</span><span class="plain">(</span><span class="string">"can't write build file"</span><span class="plain">, </span><span class="identifier">F</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Str::len</span><span class="plain">(</span><span class="identifier">bfd</span><span class="plain">.</span><span class="element">prerelease_text</span><span class="plain">) &gt; </span><span class="constant">0</span><span class="plain">)</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"Prerelease: %S\n"</span><span class="plain">, </span><span class="identifier">bfd</span><span class="plain">.</span><span class="element">prerelease_text</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"Build Date: %S\n"</span><span class="plain">, </span><span class="identifier">bfd</span><span class="plain">.</span><span class="element">build_date</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Str::len</span><span class="plain">(</span><span class="identifier">bfd</span><span class="plain">.</span><span class="element">build_code</span><span class="plain">) &gt; </span><span class="constant">0</span><span class="plain">)</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"Build Number: %S\n"</span><span class="plain">, </span><span class="identifier">bfd</span><span class="plain">.</span><span class="element">build_code</span><span class="plain">);</span>
<span class="functiontext">Streams::close</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function BuildFiles::write is used in <a href="#SP7">&#167;7</a>.</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. Bibliographic implications. </b>Whenever a web is read in by Inweb, its build file is looked at in order to
set some bibliographic data.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">BuildFiles::set_bibliographic_data_for</span><span class="plain">(</span><span class="reserved">web_md</span><span class="plain"> *</span><span class="identifier">WS</span><span class="plain">) {</span>
<span class="reserved">filename</span><span class="plain"> *</span><span class="identifier">F</span><span class="plain"> = </span><span class="functiontext">BuildFiles::build_file_for_web</span><span class="plain">(</span><span class="identifier">WS</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">F</span><span class="plain">) {</span>
<span class="reserved">build_file_data</span><span class="plain"> </span><span class="identifier">bfd</span><span class="plain"> = </span><span class="functiontext">BuildFiles::read</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Str::len</span><span class="plain">(</span><span class="identifier">bfd</span><span class="plain">.</span><span class="element">prerelease_text</span><span class="plain">) &gt; </span><span class="constant">0</span><span class="plain">)</span>
<span class="functiontext">Bibliographic::set_datum</span><span class="plain">(</span><span class="identifier">WS</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Prerelease"</span><span class="plain">, </span><span class="identifier">bfd</span><span class="plain">.</span><span class="element">prerelease_text</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Str::len</span><span class="plain">(</span><span class="identifier">bfd</span><span class="plain">.</span><span class="element">build_code</span><span class="plain">) &gt; </span><span class="constant">0</span><span class="plain">)</span>
<span class="functiontext">Bibliographic::set_datum</span><span class="plain">(</span><span class="identifier">WS</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Build Number"</span><span class="plain">, </span><span class="identifier">bfd</span><span class="plain">.</span><span class="element">build_code</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Str::len</span><span class="plain">(</span><span class="identifier">bfd</span><span class="plain">.</span><span class="element">build_date</span><span class="plain">) &gt; </span><span class="constant">0</span><span class="plain">)</span>
<span class="functiontext">Bibliographic::set_datum</span><span class="plain">(</span><span class="identifier">WS</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Build Date"</span><span class="plain">, </span><span class="identifier">bfd</span><span class="plain">.</span><span class="element">build_date</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function BuildFiles::set_bibliographic_data_for is used in 8/ws (<a href="8-ws.html#SP5_3">&#167;5.3</a>).</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. </b>A little later on, i.e., once the Contents page has been read, we want to
synthesize the semantic version number for the project. Note that this is
called even if no build file had ever been found, so it's quite legal for
the Contents page to specify all of this.
</p>
<p class="inwebparagraph">If no error occurs, then the expansion <code class="display"><span class="extract">[[Semantic Version Number]]</span></code> is
guaranteed to produce a semver-legal version number.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">BuildFiles::deduce_semver</span><span class="plain">(</span><span class="reserved">web_md</span><span class="plain"> *</span><span class="identifier">WS</span><span class="plain">) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">combined</span><span class="plain">);</span>
<span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">s</span><span class="plain"> = </span><span class="functiontext">Bibliographic::get_datum</span><span class="plain">(</span><span class="identifier">WS</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Semantic Version Number"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Str::len</span><span class="plain">(</span><span class="identifier">s</span><span class="plain">) &gt; </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">combined</span><span class="plain">, </span><span class="string">"%S"</span><span class="plain">, </span><span class="identifier">s</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">v</span><span class="plain"> = </span><span class="functiontext">Bibliographic::get_datum</span><span class="plain">(</span><span class="identifier">WS</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Version Number"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Str::len</span><span class="plain">(</span><span class="identifier">v</span><span class="plain">) &gt; </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">combined</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="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain"> = </span><span class="functiontext">Bibliographic::get_datum</span><span class="plain">(</span><span class="identifier">WS</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Prerelease"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Str::len</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">) &gt; </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">combined</span><span class="plain">, </span><span class="string">"-%S"</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">);</span>
<span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">b</span><span class="plain"> = </span><span class="functiontext">Bibliographic::get_datum</span><span class="plain">(</span><span class="identifier">WS</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Build Number"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Str::len</span><span class="plain">(</span><span class="identifier">b</span><span class="plain">) &gt; </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">combined</span><span class="plain">, </span><span class="string">"+%S"</span><span class="plain">, </span><span class="identifier">b</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Str::len</span><span class="plain">(</span><span class="identifier">combined</span><span class="plain">) &gt; </span><span class="constant">0</span><span class="plain">) {</span>
<span class="identifier">WS</span><span class="plain">-&gt;</span><span class="element">version_number</span><span class="plain"> = </span><span class="functiontext">VersionNumbers::from_text</span><span class="plain">(</span><span class="identifier">combined</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">VersionNumbers::is_null</span><span class="plain">(</span><span class="identifier">WS</span><span class="plain">-&gt;</span><span class="element">version_number</span><span class="plain">)) {</span>
<span class="functiontext">Errors::fatal_with_text</span><span class="plain">(</span>
<span class="string">"Combined version '%S' does not comply with the semver standard"</span><span class="plain">,</span>
<span class="identifier">combined</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="functiontext">Bibliographic::set_datum</span><span class="plain">(</span><span class="identifier">WS</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Semantic Version Number"</span><span class="plain">, </span><span class="identifier">combined</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">combined</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function BuildFiles::deduce_semver is used in 8/ws (<a href="8-ws.html#SP5_3">&#167;5.3</a>).</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. Advancing. </b>We update the build date to today and, if supplied, also increment the build
number if we find that the date has changed.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">BuildFiles::advance_for_web</span><span class="plain">(</span><span class="reserved">web_md</span><span class="plain"> *</span><span class="identifier">WS</span><span class="plain">) {</span>
<span class="reserved">filename</span><span class="plain"> *</span><span class="identifier">F</span><span class="plain"> = </span><span class="functiontext">BuildFiles::build_file_for_web</span><span class="plain">(</span><span class="identifier">WS</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">F</span><span class="plain">) </span><span class="functiontext">BuildFiles::advance</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="functiontext">Errors::fatal</span><span class="plain">(</span><span class="string">"web has no build file"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">BuildFiles::advance</span><span class="plain">(</span><span class="reserved">filename</span><span class="plain"> *</span><span class="identifier">F</span><span class="plain">) {</span>
<span class="reserved">build_file_data</span><span class="plain"> </span><span class="identifier">bfd</span><span class="plain"> = </span><span class="functiontext">BuildFiles::read</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">BuildFiles::dated_today</span><span class="plain">(</span><span class="identifier">bfd</span><span class="plain">.</span><span class="element">build_date</span><span class="plain">) == </span><span class="constant">FALSE</span><span class="plain">) {</span>
<span class="functiontext">BuildFiles::increment</span><span class="plain">(</span><span class="identifier">bfd</span><span class="plain">.</span><span class="element">build_code</span><span class="plain">);</span>
<span class="functiontext">BuildFiles::write</span><span class="plain">(</span><span class="identifier">bfd</span><span class="plain">, </span><span class="identifier">F</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function BuildFiles::advance_for_web appears nowhere else.</p>
<p class="endnote">The function BuildFiles::advance appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. </b>The standard date format we use is "26 February 2018". If the contents of
<code class="display"><span class="extract">dateline</span></code> match today's date in this format, we return <code class="display"><span class="extract">TRUE</span></code>; otherwise we
rewrite <code class="display"><span class="extract">dateline</span></code> to today and return <code class="display"><span class="extract">FALSE</span></code>.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">BuildFiles::dated_today</span><span class="plain">(</span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">dateline</span><span class="plain">) {</span>
<span class="reserved">char</span><span class="plain"> *</span><span class="identifier">monthname</span><span class="plain">[12] = { </span><span class="string">"January"</span><span class="plain">, </span><span class="string">"February"</span><span class="plain">, </span><span class="string">"March"</span><span class="plain">, </span><span class="string">"April"</span><span class="plain">, </span><span class="string">"May"</span><span class="plain">, </span><span class="string">"June"</span><span class="plain">,</span>
<span class="string">"July"</span><span class="plain">, </span><span class="string">"August"</span><span class="plain">, </span><span class="string">"September"</span><span class="plain">, </span><span class="string">"October"</span><span class="plain">, </span><span class="string">"November"</span><span class="plain">, </span><span class="string">"December"</span><span class="plain"> };</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">today</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">today</span><span class="plain">, </span><span class="string">"%d %s %d"</span><span class="plain">,</span>
<span class="identifier">the_present</span><span class="plain">-&gt;</span><span class="identifier">tm_mday</span><span class="plain">, </span><span class="identifier">monthname</span><span class="plain">[</span><span class="identifier">the_present</span><span class="plain">-&gt;</span><span class="identifier">tm_mon</span><span class="plain">], </span><span class="identifier">the_present</span><span class="plain">-&gt;</span><span class="identifier">tm_year</span><span class="plain">+1900);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Str::ne</span><span class="plain">(</span><span class="identifier">dateline</span><span class="plain">, </span><span class="identifier">today</span><span class="plain">)) {</span>
<span class="identifier">rv</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
<span class="functiontext">Str::clear</span><span class="plain">(</span><span class="identifier">dateline</span><span class="plain">);</span>
<span class="functiontext">Str::copy</span><span class="plain">(</span><span class="identifier">dateline</span><span class="plain">, </span><span class="identifier">today</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">today</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 BuildFiles::dated_today is used in <a href="#SP7">&#167;7</a>.</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. </b>Traditional Inform build codes are four-character, e.g., <code class="display"><span class="extract">3Q27</span></code>. Here, we
read such a code and increase it by one. The two-digit code at the back is
incremented, but rolls around from <code class="display"><span class="extract">99</span></code> to <code class="display"><span class="extract">01</span></code>, in which case the letter is
advanced, except that <code class="display"><span class="extract">I</span></code> and <code class="display"><span class="extract">O</span></code> are skipped, and if the letter passes <code class="display"><span class="extract">Z</span></code>
then it rolls back around to <code class="display"><span class="extract">A</span></code> and the initial digit is incremented.
</p>
<p class="inwebparagraph">This allows for 21384 distinct build codes, enough to use one each day for
some 58 years.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">BuildFiles::increment</span><span class="plain">(</span><span class="reserved">text_stream</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">Str::len</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">) != </span><span class="constant">4</span><span class="plain">) </span><span class="functiontext">Errors::with_text</span><span class="plain">(</span><span class="string">"build code malformed: %S"</span><span class="plain">, </span><span class="identifier">T</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">N</span><span class="plain"> = </span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="constant">0</span><span class="plain">) - </span><span class="character">'0'</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">L</span><span class="plain"> = </span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="constant">1</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">M1</span><span class="plain"> = </span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="constant">2</span><span class="plain">) - </span><span class="character">'0'</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">M2</span><span class="plain"> = </span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="constant">3</span><span class="plain">) - </span><span class="character">'0'</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">N</span><span class="plain"> &lt; </span><span class="constant">0</span><span class="plain">) || (</span><span class="identifier">N</span><span class="plain"> &gt; </span><span class="constant">9</span><span class="plain">) || (</span><span class="identifier">L</span><span class="plain"> &lt; </span><span class="character">'A'</span><span class="plain">) || (</span><span class="identifier">L</span><span class="plain"> &gt; </span><span class="character">'Z'</span><span class="plain">) ||</span>
<span class="plain">(</span><span class="identifier">M1</span><span class="plain"> &lt; </span><span class="constant">0</span><span class="plain">) || (</span><span class="identifier">M1</span><span class="plain"> &gt; </span><span class="constant">9</span><span class="plain">) || (</span><span class="identifier">M2</span><span class="plain"> &lt; </span><span class="constant">0</span><span class="plain">) || (</span><span class="identifier">M2</span><span class="plain"> &gt; </span><span class="constant">9</span><span class="plain">)) {</span>
<span class="functiontext">Errors::with_text</span><span class="plain">(</span><span class="string">"build code malformed: %S"</span><span class="plain">, </span><span class="identifier">T</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">M2</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">M2</span><span class="plain"> == </span><span class="constant">10</span><span class="plain">) { </span><span class="identifier">M2</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">; </span><span class="identifier">M1</span><span class="plain">++; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">M1</span><span class="plain"> == </span><span class="constant">10</span><span class="plain">) { </span><span class="identifier">M1</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">; </span><span class="identifier">M2</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">; </span><span class="identifier">L</span><span class="plain">++; }</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">L</span><span class="plain"> == </span><span class="character">'I'</span><span class="plain">) || (</span><span class="identifier">L</span><span class="plain"> == </span><span class="character">'O'</span><span class="plain">)) </span><span class="identifier">L</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">L</span><span class="plain"> &gt; </span><span class="character">'Z'</span><span class="plain">) { </span><span class="identifier">L</span><span class="plain"> = </span><span class="character">'A'</span><span class="plain">; </span><span class="identifier">N</span><span class="plain">++; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">N</span><span class="plain"> == </span><span class="constant">10</span><span class="plain">) </span><span class="functiontext">Errors::with_text</span><span class="plain">(</span><span class="string">"build code overflowed: %S"</span><span class="plain">, </span><span class="identifier">T</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> {</span>
<span class="functiontext">Str::clear</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="string">"%d%c%d%d"</span><span class="plain">, </span><span class="identifier">N</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">, </span><span class="identifier">M1</span><span class="plain">, </span><span class="identifier">M2</span><span class="plain">);</span>
<span class="identifier">PRINT</span><span class="plain">(</span><span class="string">"Build code advanced to %S\n"</span><span class="plain">, </span><span class="identifier">T</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function BuildFiles::increment is used in <a href="#SP7">&#167;7</a>.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="8-wm.html">Back to 'Web Modules'</a></li><li><i>(This section ends Chapter 8: Literate Programming.)</i></li></ul><hr class="tocbar">
<!--End of weave-->
</main>
</body>
</html>