1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-05-19 09:28:51 +03:00
inform7/docs/inblorb/3-sd.html
2023-09-10 23:46:39 +01:00

540 lines
109 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Solution Deviser</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
<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="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
function togglePopup(material_id) {
var popup = document.getElementById(material_id);
popup.classList.toggle("show");
}
</script>
<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body class="commentary-font">
<nav role="navigation">
<h1><a href="../index.html">
<img src="../docs-assets/Inform.png" height=72">
</a></h1>
<ul><li><a href="../index.html">home</a></li>
</ul><h2>Compiler</h2><ul>
<li><a href="../structure.html">structure</a></li>
<li><a href="../inbuildn.html">inbuild</a></li>
<li><a href="../inform7n.html">inform7</a></li>
<li><a href="../intern.html">inter</a></li>
<li><a href="../services.html">services</a></li>
<li><a href="../secrets.html">secrets</a></li>
</ul><h2>Other Tools</h2><ul>
<li><a href="../inblorbn.html">inblorb</a></li>
<li><a href="../indocn.html">indoc</a></li>
<li><a href="../inform6.html">inform6</a></li>
<li><a href="../inpolicyn.html">inpolicy</a></li>
</ul><h2>Resources</h2><ul>
<li><a href="../extensions.html">extensions</a></li>
<li><a href="../kits.html">kits</a></li>
</ul><h2>Repository</h2><ul>
<li><a href="https://github.com/ganelson/inform"><img src="../docs-assets/github.png" height=18> github</a></li>
</ul><h2>Related Projects</h2><ul>
<li><a href="../../../inweb/index.html">inweb</a></li>
<li><a href="../../../intest/index.html">intest</a></li>
</ul>
</nav>
<main role="main">
<!--Weave of 'Solution Deviser' generated by Inweb-->
<div class="breadcrumbs">
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="index.html">inblorb</a></li><li><a href="index.html#3">Chapter 3: Other Material</a></li><li><b>Solution Deviser</b></li></ul></div>
<p class="purpose">To make a solution (.sol) file accompanying a release, if requested.</p>
<ul class="toc"><li><a href="3-sd.html#SP1">&#167;1. Skein storage</a></li><li><a href="3-sd.html#SP3">&#167;3. Walking through</a></li><li><a href="3-sd.html#SP4">&#167;4. Step 1: building the Skein tree</a></li><li><a href="3-sd.html#SP10">&#167;10. Step 2: identify the relevant lines</a></li><li><a href="3-sd.html#SP11">&#167;11. Step 3: pruning irrelevant lines out of the tree</a></li><li><a href="3-sd.html#SP12">&#167;12. Step 4: writing the solution file</a></li><li><a href="3-sd.html#SP14">&#167;14. Writing individual commands and branch descriptions</a></li></ul><hr class="tocbar">
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. Skein storage. </b>A solution file is simply a list of commands which will win a work of IF,
starting from turn 1. In this section we will generate this list given the
Skein file for an Inform 7 project: to follow this code, it's useful first
to read the "Walkthrough solutions" section of the "Releasing" chapter
in the main Inform documentation.
</p>
<p class="commentary">We will need to parse the entire skein into a tree structure, in which each
node (including leaves) is one of the following structures. We expect the
Inform user to have annotated certain nodes with the text <span class="extract"><span class="extract-syntax">***</span></span> (three
asterisks); the solution file will ignore all paths in the skein which do
not lead to one of these <span class="extract"><span class="extract-syntax">***</span></span> nodes. The surviving nodes, those in lines
which do lead to <span class="extract"><span class="extract-syntax">***</span></span> endings, are called "relevant".
</p>
<p class="commentary">Some knots have "branch descriptions", others do not. These are the
options where choices have to be made. The <span class="extract"><span class="extract-syntax">branch_parent</span></span> and <span class="extract"><span class="extract-syntax">branch_count</span></span>
fields are used to keep these labels: see below.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">skein_node</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">id</span><span class="plain-syntax">; </span><span class="comment-syntax"> uniquely identifying ID used within the Skein file</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">command</span><span class="plain-syntax">; </span><span class="comment-syntax"> text of the command at this node</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">annotation</span><span class="plain-syntax">; </span><span class="comment-syntax"> text of any annotation added by the user</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">relevant</span><span class="plain-syntax">; </span><span class="comment-syntax"> is this node within one of the "relevant" lines in the skein?</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">skein_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">branch_parent</span><span class="plain-syntax">; </span><span class="comment-syntax"> the trunk of the branch description, if any, is this way</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">branch_count</span><span class="plain-syntax">; </span><span class="comment-syntax"> the leaf of the branch description, if any, is this number</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">skein_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">parent</span><span class="plain-syntax">; </span><span class="comment-syntax"> within the Skein tree: </span><span class="extract"><span class="extract-syntax">NULL</span></span><span class="comment-syntax"> for the root only</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">skein_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">child</span><span class="plain-syntax">; </span><span class="comment-syntax"> within the Skein tree: </span><span class="extract"><span class="extract-syntax">NULL</span></span><span class="comment-syntax"> if a leaf</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">skein_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sibling</span><span class="plain-syntax">; </span><span class="comment-syntax"> within the Skein tree: </span><span class="extract"><span class="extract-syntax">NULL</span></span><span class="comment-syntax"> if the final option from its parent</span>
<span class="plain-syntax"> </span><span class="constant-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">skein_node</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure skein_node is accessed in 2/trs, 5/mrk, 5/mv, 9/pl and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b>The root of the Skein, representing the start position before any command
is typed, lives here:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">skein_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">root_skn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="comment-syntax"> only </span><span class="extract"><span class="extract-syntax">NULL</span></span><span class="comment-syntax"> when the tree is empty</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. Walking through. </b>This section provides just one function to the rest of Inblorb: this one,
which implements the Blurb <span class="extract"><span class="extract-syntax">solution</span></span> command.
</p>
<p class="commentary">Our method works in four steps. Steps 1 to 3 have a running time of O(K^2),
where K is the number of knots in the Skein, and step 4 is O(K log K),
so the process as a whole is O(K^2).
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Solution::walkthrough</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">Solution::walkthrough</span></span>:<br/>Releaser - <a href="3-rls.html#SP6">&#167;6</a>, <a href="3-rls.html#SP6_1">&#167;6.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">Skein_filename</span><span class="plain-syntax">, </span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">walkthrough_filename</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="3-sd.html#SP4" class="function-link"><span class="function-syntax">Solution::build_skein_tree</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Skein_filename</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">root_skn</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="1-be.html#SP3" class="function-link"><span class="function-syntax">BlorbErrors::error</span></a><span class="plain-syntax">(</span><span class="string-syntax">"there appear to be no threads in the Skein"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="3-sd.html#SP10" class="function-link"><span class="function-syntax">Solution::identify_relevant_lines</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">root_skn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">relevant</span><span class="plain-syntax"> == </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="1-be.html#SP3" class="function-link"><span class="function-syntax">BlorbErrors::error</span></a><span class="plain-syntax">(</span><span class="string-syntax">"no threads in the Skein have been marked '***'"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="3-sd.html#SP11" class="function-link"><span class="function-syntax">Solution::prune_irrelevant_lines</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><a href="3-sd.html#SP12" class="function-link"><span class="function-syntax">Solution::write_solution_file</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">walkthrough_filename</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. Step 1: building the Skein tree. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">skein_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">current_skein_node</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Solution::build_skein_tree</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">Solution::build_skein_tree</span></span>:<br/><a href="3-sd.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">Skein_filename</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">root_skn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_skein_node</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="../../../inweb/foundation-module/4-tf.html#SP5" class="function-link"><span class="function-syntax">TextFiles::read</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Skein_filename</span><span class="plain-syntax">, </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">, </span><span class="string-syntax">"can't open skein file"</span><span class="plain-syntax">, </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">, </span><a href="3-sd.html#SP4" class="function-link"><span class="function-syntax">Solution::read_skein_pass_1</span></a><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_skein_node</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="../../../inweb/foundation-module/4-tf.html#SP5" class="function-link"><span class="function-syntax">TextFiles::read</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Skein_filename</span><span class="plain-syntax">, </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">, </span><span class="string-syntax">"can't open skein file"</span><span class="plain-syntax">, </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">, </span><a href="3-sd.html#SP4" class="function-link"><span class="function-syntax">Solution::read_skein_pass_2</span></a><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Solution::read_skein_pass_1</span><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">line</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">state</span><span class="plain-syntax">) { </span><a href="3-sd.html#SP5" class="function-link"><span class="function-syntax">Solution::read_skein_line</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">line</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">); }</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Solution::read_skein_pass_2</span><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">line</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">state</span><span class="plain-syntax">) { </span><a href="3-sd.html#SP5" class="function-link"><span class="function-syntax">Solution::read_skein_line</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">line</span><span class="plain-syntax">, </span><span class="constant-syntax">2</span><span class="plain-syntax">); }</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. </b>The Skein is stored as an XML file. Its format was devised by Andrew Hunter
in the early days of the Inform user interface for Mac OS X, and this was
then adopted by the user interface on other platforms, so that projects could
be freely exchanged between users regardless of their platforms. That makes
it a kind of standard, but it isn't at present a public or documented one.
We shall therefore make few assumptions about it.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Solution::read_skein_line</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">Solution::read_skein_line</span></span>:<br/><a href="3-sd.html#SP4">&#167;4</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">line</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">pass</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">node_id</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="3-sd.html#SP6" class="function-link"><span class="function-syntax">Solution::find_node_ID_in_tag</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">node_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">line</span><span class="plain-syntax">, </span><span class="string-syntax">"item"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pass</span><span class="plain-syntax"> == </span><span class="constant-syntax">1</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="../../../inweb/foundation-module/4-sm.html#SP8" class="function-link"><span class="function-syntax">Str::len</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">node_id</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="3-sd.html#SP5_1" class="named-paragraph-link"><span class="named-paragraph">Create a new skein tree node with this node ID</span><span class="named-paragraph-number">5.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">current_skein_node</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-sd.html#SP5_3" class="named-paragraph-link"><span class="named-paragraph">Look for a "command" tag and set the command text from it</span><span class="named-paragraph-number">5.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-sd.html#SP5_4" class="named-paragraph-link"><span class="named-paragraph">Look for an "annotation" tag and set the annotation text from it</span><span class="named-paragraph-number">5.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="../../../inweb/foundation-module/4-sm.html#SP8" class="function-link"><span class="function-syntax">Str::len</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">node_id</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_skein_node</span><span class="plain-syntax"> = </span><a href="3-sd.html#SP8" class="function-link"><span class="function-syntax">Solution::find_node_with_ID</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">node_id</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">current_skein_node</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">child_node_id</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="3-sd.html#SP6" class="function-link"><span class="function-syntax">Solution::find_node_ID_in_tag</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">child_node_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">line</span><span class="plain-syntax">, </span><span class="string-syntax">"child"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="../../../inweb/foundation-module/4-sm.html#SP8" class="function-link"><span class="function-syntax">Str::len</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">child_node_id</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">skein_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">new_child</span><span class="plain-syntax"> = </span><a href="3-sd.html#SP8" class="function-link"><span class="function-syntax">Solution::find_node_with_ID</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">child_node_id</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">new_child</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="1-be.html#SP3" class="function-link"><span class="function-syntax">BlorbErrors::error</span></a><span class="plain-syntax">(</span><span class="string-syntax">"the skein file is malformed (B)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-sd.html#SP5_2" class="named-paragraph-link"><span class="named-paragraph">Make the parent-child relationship</span><span class="named-paragraph-number">5.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">child_node_id</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">node_id</span><span class="plain-syntax">)</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5_1" class="paragraph-anchor"></a><b>&#167;5.1. </b>Note that the root is the first knot in the Skein file.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Create a new skein tree node with this node ID</span><span class="named-paragraph-number">5.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">current_skein_node</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">skein_node</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">root_skn</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">root_skn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">current_skein_node</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_skein_node</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">id</span><span class="plain-syntax"> = </span><a href="../../../inweb/foundation-module/4-sm.html#SP3" class="function-link"><span class="function-syntax">Str::duplicate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">node_id</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_skein_node</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">command</span><span class="plain-syntax"> = </span><a href="../../../inweb/foundation-module/4-sm.html#SP2" class="function-link"><span class="function-syntax">Str::new</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_skein_node</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">annotation</span><span class="plain-syntax"> = </span><a href="../../../inweb/foundation-module/4-sm.html#SP2" class="function-link"><span class="function-syntax">Str::new</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_skein_node</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">branch_count</span><span class="plain-syntax"> = -1;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_skein_node</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">branch_parent</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_skein_node</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">parent</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_skein_node</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">child</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_skein_node</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sibling</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_skein_node</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">relevant</span><span class="plain-syntax"> = </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">verbose_mode</span><span class="plain-syntax">) </span><span class="identifier-syntax">PRINT</span><span class="plain-syntax">(</span><span class="string-syntax">"Creating knot with ID '%S'\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">node_id</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-sd.html#SP5">&#167;5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_2" class="paragraph-anchor"></a><b>&#167;5.2. </b>We make <span class="extract"><span class="extract-syntax">new_child</span></span> the youngest child of <span class="extract"><span class="extract-syntax">current_skein_mode</span></span>:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Make the parent-child relationship</span><span class="named-paragraph-number">5.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">new_child</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">parent</span><span class="plain-syntax"> = </span><span class="identifier-syntax">current_skein_node</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">new_child</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sibling</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">current_skein_node</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">child</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_skein_node</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">child</span><span class="plain-syntax"> = </span><span class="identifier-syntax">new_child</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">skein_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">familial</span><span class="plain-syntax"> = </span><span class="identifier-syntax">current_skein_node</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">child</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">familial</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sibling</span><span class="plain-syntax">) </span><span class="identifier-syntax">familial</span><span class="plain-syntax"> = </span><span class="identifier-syntax">familial</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sibling</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">familial</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sibling</span><span class="plain-syntax"> = </span><span class="identifier-syntax">new_child</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-sd.html#SP5">&#167;5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_3" class="paragraph-anchor"></a><b>&#167;5.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Look for a "command" tag and set the command text from it</span><span class="named-paragraph-number">5.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">current_skein_node</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">command</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="../../../inweb/foundation-module/4-sm.html#SP8" class="function-link"><span class="function-syntax">Str::len</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><a href="3-sd.html#SP7" class="function-link"><span class="function-syntax">Solution::find_text_of_tag</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">line</span><span class="plain-syntax">, </span><span class="string-syntax">"command"</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">verbose_mode</span><span class="plain-syntax">) </span><span class="identifier-syntax">PRINT</span><span class="plain-syntax">(</span><span class="string-syntax">"Raw command '%S'\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-sd.html#SP9" class="function-link"><span class="function-syntax">Solution::undo_XML_escapes_in_string</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_THROUGH_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="../../../inweb/foundation-module/4-sm.html#SP14" class="function-link"><span class="function-syntax">Str::put</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><a href="../../../inweb/foundation-module/4-chr.html#SP1" class="function-link"><span class="function-syntax">Characters::toupper</span></a><span class="plain-syntax">(</span><a href="../../../inweb/foundation-module/4-sm.html#SP13" class="function-link"><span class="function-syntax">Str::get</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">)));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">verbose_mode</span><span class="plain-syntax">) </span><span class="identifier-syntax">PRINT</span><span class="plain-syntax">(</span><span class="string-syntax">"Processed command '%S'\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-sd.html#SP5">&#167;5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_4" class="paragraph-anchor"></a><b>&#167;5.4. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Look for an "annotation" tag and set the annotation text from it</span><span class="named-paragraph-number">5.4</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">current_skein_node</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">annotation</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="../../../inweb/foundation-module/4-sm.html#SP8" class="function-link"><span class="function-syntax">Str::len</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><a href="3-sd.html#SP7" class="function-link"><span class="function-syntax">Solution::find_text_of_tag</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">line</span><span class="plain-syntax">, </span><span class="string-syntax">"annotation"</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">verbose_mode</span><span class="plain-syntax">) </span><span class="identifier-syntax">PRINT</span><span class="plain-syntax">(</span><span class="string-syntax">"Raw annotation '%S'\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-sd.html#SP9" class="function-link"><span class="function-syntax">Solution::undo_XML_escapes_in_string</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">verbose_mode</span><span class="plain-syntax">) </span><span class="identifier-syntax">PRINT</span><span class="plain-syntax">(</span><span class="string-syntax">"Processed annotation of %S = '%S'\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_skein_node</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">id</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-sd.html#SP5">&#167;5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>&#167;6. </b>Try to find a node ID element attached to a particular tag on the line:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Solution::find_node_ID_in_tag</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">Solution::find_node_ID_in_tag</span></span>:<br/><a href="3-sd.html#SP5">&#167;5</a></span></button><span class="plain-syntax">(</span><span class="constant-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">line</span><span class="plain-syntax">, </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tag</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">prototype</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">prototype</span><span class="plain-syntax">, </span><span class="string-syntax">"%%c*?&lt;%s nodeId=\"(%%c*?)\"%%c*"</span><span class="plain-syntax">, </span><span class="identifier-syntax">tag</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inchar32_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">prototype_Cs</span><span class="plain-syntax">[128];</span>
<span class="plain-syntax"> </span><a href="../../../inweb/foundation-module/4-sm.html#SP6" class="function-link"><span class="function-syntax">Str::copy_to_wide_string</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">prototype_Cs</span><span class="plain-syntax">, </span><span class="identifier-syntax">prototype</span><span class="plain-syntax">, </span><span class="constant-syntax">128</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">match_results</span><span class="plain-syntax"> </span><span class="identifier-syntax">mr</span><span class="plain-syntax"> = </span><a href="../../../inweb/foundation-module/4-pm.html#SP9" class="function-link"><span class="function-syntax">Regexp::create_mr</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="../../../inweb/foundation-module/4-pm.html#SP10" class="function-link"><span class="function-syntax">Regexp::match</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr</span><span class="plain-syntax">, </span><span class="identifier-syntax">line</span><span class="plain-syntax">, </span><span class="identifier-syntax">prototype_Cs</span><span class="plain-syntax">)) </span><a href="../../../inweb/foundation-module/4-sm.html#SP17" class="function-link"><span class="function-syntax">Str::copy</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="element-syntax">exp</span><span class="plain-syntax">[0]);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><a href="../../../inweb/foundation-module/4-sm.html#SP15" class="function-link"><span class="function-syntax">Str::clear</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="../../../inweb/foundation-module/4-pm.html#SP9" class="function-link"><span class="function-syntax">Regexp::dispose_of</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">prototype</span><span class="plain-syntax">)</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>&#167;7. </b>Try to find the text of a particular tag on the line:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Solution::find_text_of_tag</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">Solution::find_text_of_tag</span></span>:<br/><a href="3-sd.html#SP5_3">&#167;5.3</a>, <a href="3-sd.html#SP5_4">&#167;5.4</a></span></button><span class="plain-syntax">(</span><span class="constant-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">line</span><span class="plain-syntax">, </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tag</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">prototype</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">prototype</span><span class="plain-syntax">, </span><span class="string-syntax">"%%c*?&gt;(%%c*?)&lt;/%s%%c*"</span><span class="plain-syntax">, </span><span class="identifier-syntax">tag</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">match_results</span><span class="plain-syntax"> </span><span class="identifier-syntax">mr</span><span class="plain-syntax"> = </span><a href="../../../inweb/foundation-module/4-pm.html#SP9" class="function-link"><span class="function-syntax">Regexp::create_mr</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inchar32_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">prototype_Cs</span><span class="plain-syntax">[128];</span>
<span class="plain-syntax"> </span><a href="../../../inweb/foundation-module/4-sm.html#SP6" class="function-link"><span class="function-syntax">Str::copy_to_wide_string</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">prototype_Cs</span><span class="plain-syntax">, </span><span class="identifier-syntax">prototype</span><span class="plain-syntax">, </span><span class="constant-syntax">128</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="../../../inweb/foundation-module/4-pm.html#SP10" class="function-link"><span class="function-syntax">Regexp::match</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr</span><span class="plain-syntax">, </span><span class="identifier-syntax">line</span><span class="plain-syntax">, </span><span class="identifier-syntax">prototype_Cs</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">prototype</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="../../../inweb/foundation-module/4-sm.html#SP17" class="function-link"><span class="function-syntax">Str::copy</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="element-syntax">exp</span><span class="plain-syntax">[0]);</span>
<span class="plain-syntax"> </span><a href="../../../inweb/foundation-module/4-pm.html#SP9" class="function-link"><span class="function-syntax">Regexp::dispose_of</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">prototype</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="../../../inweb/foundation-module/4-sm.html#SP15" class="function-link"><span class="function-syntax">Str::clear</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>&#167;8. </b>This is not very efficient, but:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">skein_node</span><span class="plain-syntax"> *</span><span class="function-syntax">Solution::find_node_with_ID</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">Solution::find_node_with_ID</span></span>:<br/><a href="3-sd.html#SP5">&#167;5</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">id</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">skein_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">skn</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">skn</span><span class="plain-syntax">, </span><span class="reserved-syntax">skein_node</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="../../../inweb/foundation-module/4-sm.html#SP19" class="function-link"><span class="function-syntax">Str::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">id</span><span class="plain-syntax">, </span><span class="identifier-syntax">skn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">id</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">skn</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>&#167;9. </b>Finally, we needed the following string hackery:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Solution::undo_XML_escapes_in_string</span><button class="popup" onclick="togglePopup('usagePopup7')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup7">Usage of <span class="code-font"><span class="function-syntax">Solution::undo_XML_escapes_in_string</span></span>:<br/><a href="3-sd.html#SP5_3">&#167;5.3</a>, <a href="3-sd.html#SP5_4">&#167;5.4</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">j</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><a href="../../../inweb/foundation-module/4-sm.html#SP13" class="function-link"><span class="function-syntax">Str::get_at</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="../../../inweb/foundation-module/4-sm.html#SP13" class="function-link"><span class="function-syntax">Str::get_at</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">) == </span><span class="character-syntax">'&amp;'</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">xml_escape</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">k</span><span class="plain-syntax">=0;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> ((</span><a href="../../../inweb/foundation-module/4-sm.html#SP13" class="function-link"><span class="function-syntax">Str::get_at</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">+</span><span class="identifier-syntax">k</span><span class="plain-syntax">) != </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><a href="../../../inweb/foundation-module/4-sm.html#SP13" class="function-link"><span class="function-syntax">Str::get_at</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">+</span><span class="identifier-syntax">k</span><span class="plain-syntax">) != </span><span class="character-syntax">';'</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">xml_escape</span><span class="plain-syntax">, </span><a href="../../../inweb/foundation-module/4-chr.html#SP1" class="function-link"><span class="function-syntax">Characters::tolower</span></a><span class="plain-syntax">(</span><a href="../../../inweb/foundation-module/4-sm.html#SP13" class="function-link"><span class="function-syntax">Str::get_at</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax"> + </span><span class="identifier-syntax">k</span><span class="plain-syntax">++)));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">xml_escape</span><span class="plain-syntax">, </span><a href="../../../inweb/foundation-module/4-sm.html#SP13" class="function-link"><span class="function-syntax">Str::get_at</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">+</span><span class="identifier-syntax">k</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-sd.html#SP9_1" class="named-paragraph-link"><span class="named-paragraph">We have identified an XML escape</span><span class="named-paragraph-number">9.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">xml_escape</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="../../../inweb/foundation-module/4-sm.html#SP14" class="function-link"><span class="function-syntax">Str::put_at</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">j</span><span class="plain-syntax">++, </span><a href="../../../inweb/foundation-module/4-sm.html#SP13" class="function-link"><span class="function-syntax">Str::get_at</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">++));</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="../../../inweb/foundation-module/4-sm.html#SP14" class="function-link"><span class="function-syntax">Str::put_at</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">j</span><span class="plain-syntax">++, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP9_1" class="paragraph-anchor"></a><b>&#167;9.1. </b>Note that all other ampersand-escapes are passed through verbatim.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">We have identified an XML escape</span><span class="named-paragraph-number">9.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">inchar32_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="../../../inweb/foundation-module/4-sm.html#SP22" class="function-link"><span class="function-syntax">Str::eq_wide_string</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">xml_escape</span><span class="plain-syntax">, </span><span class="identifier-syntax">U</span><span class="string-syntax">"&amp;lt;"</span><span class="plain-syntax">)) </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><span class="character-syntax">'&lt;'</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="../../../inweb/foundation-module/4-sm.html#SP22" class="function-link"><span class="function-syntax">Str::eq_wide_string</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">xml_escape</span><span class="plain-syntax">, </span><span class="identifier-syntax">U</span><span class="string-syntax">"&amp;gt;"</span><span class="plain-syntax">)) </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><span class="character-syntax">'&gt;'</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="../../../inweb/foundation-module/4-sm.html#SP22" class="function-link"><span class="function-syntax">Str::eq_wide_string</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">xml_escape</span><span class="plain-syntax">, </span><span class="identifier-syntax">U</span><span class="string-syntax">"&amp;amp;"</span><span class="plain-syntax">)) </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><span class="character-syntax">'&amp;'</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="../../../inweb/foundation-module/4-sm.html#SP22" class="function-link"><span class="function-syntax">Str::eq_wide_string</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">xml_escape</span><span class="plain-syntax">, </span><span class="identifier-syntax">U</span><span class="string-syntax">"&amp;apos;"</span><span class="plain-syntax">)) </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><span class="character-syntax">'\''</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="../../../inweb/foundation-module/4-sm.html#SP22" class="function-link"><span class="function-syntax">Str::eq_wide_string</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">xml_escape</span><span class="plain-syntax">, </span><span class="identifier-syntax">U</span><span class="string-syntax">"&amp;quot;"</span><span class="plain-syntax">)) </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><span class="character-syntax">'\"'</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax">) { </span><a href="../../../inweb/foundation-module/4-sm.html#SP14" class="function-link"><span class="function-syntax">Str::put_at</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">j</span><span class="plain-syntax">++, </span><span class="identifier-syntax">c</span><span class="plain-syntax">); </span><span class="identifier-syntax">i</span><span class="plain-syntax"> += </span><a href="../../../inweb/foundation-module/4-sm.html#SP8" class="function-link"><span class="function-syntax">Str::len</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">xml_escape</span><span class="plain-syntax">); </span><span class="reserved-syntax">continue</span><span class="plain-syntax">; }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-sd.html#SP9">&#167;9</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>&#167;10. Step 2: identify the relevant lines. </b>We aim to show how to reach all knots in the Skein annotated with text which
begins with three asterisks. (We trim those asterisks away from the annotation
once we spot them: they have served their purpose.) A knot is "relevant"
if and only if one of its (direct or indirect) children is marked with three
asterisks in this way.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Solution::identify_relevant_lines</span><button class="popup" onclick="togglePopup('usagePopup8')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup8">Usage of <span class="code-font"><span class="function-syntax">Solution::identify_relevant_lines</span></span>:<br/><a href="3-sd.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">skein_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">skn</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">skn</span><span class="plain-syntax">, </span><span class="reserved-syntax">skein_node</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">skn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">annotation</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">verbose_mode</span><span class="plain-syntax">) &amp;&amp; (</span><a href="../../../inweb/foundation-module/4-sm.html#SP8" class="function-link"><span class="function-syntax">Str::len</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PRINT</span><span class="plain-syntax">(</span><span class="string-syntax">"Knot %S is annotated '%S'\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">skn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">id</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="../../../inweb/foundation-module/4-sm.html#SP13" class="function-link"><span class="function-syntax">Str::get_at</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">) == </span><span class="character-syntax">'*'</span><span class="plain-syntax">) &amp;&amp; (</span><a href="../../../inweb/foundation-module/4-sm.html#SP13" class="function-link"><span class="function-syntax">Str::get_at</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">) == </span><span class="character-syntax">'*'</span><span class="plain-syntax">) &amp;&amp; (</span><a href="../../../inweb/foundation-module/4-sm.html#SP13" class="function-link"><span class="function-syntax">Str::get_at</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="constant-syntax">2</span><span class="plain-syntax">) == </span><span class="character-syntax">'*'</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="constant-syntax">3</span><span class="plain-syntax">, </span><span class="identifier-syntax">j</span><span class="plain-syntax">; </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><a href="../../../inweb/foundation-module/4-sm.html#SP13" class="function-link"><span class="function-syntax">Str::get_at</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">) == </span><span class="character-syntax">' '</span><span class="plain-syntax">) </span><span class="identifier-syntax">i</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">j</span><span class="plain-syntax">=0; </span><a href="../../../inweb/foundation-module/4-sm.html#SP13" class="function-link"><span class="function-syntax">Str::get_at</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">); </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) </span><a href="../../../inweb/foundation-module/4-sm.html#SP14" class="function-link"><span class="function-syntax">Str::put_at</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">j</span><span class="plain-syntax">++, </span><a href="../../../inweb/foundation-module/4-sm.html#SP13" class="function-link"><span class="function-syntax">Str::get_at</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)); </span><a href="../../../inweb/foundation-module/4-sm.html#SP14" class="function-link"><span class="function-syntax">Str::put_at</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">j</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">skein_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">knot</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">knot</span><span class="plain-syntax"> = </span><span class="identifier-syntax">skn</span><span class="plain-syntax">; </span><span class="identifier-syntax">knot</span><span class="plain-syntax">; </span><span class="identifier-syntax">knot</span><span class="plain-syntax"> = </span><span class="identifier-syntax">knot</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">parent</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">knot</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">relevant</span><span class="plain-syntax"> = </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">verbose_mode</span><span class="plain-syntax">) </span><span class="identifier-syntax">PRINT</span><span class="plain-syntax">(</span><span class="string-syntax">"Knot %S is relevant\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">knot</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">id</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>&#167;11. Step 3: pruning irrelevant lines out of the tree. </b>When the loop below concludes, the relevant nodes are exactly those in the
component of the tree root, because:
</p>
<ul class="items"><li>(a) No irrelevant node can be the child of a relevant one; and no
relevant node can be the child of an irrelevant one by definition. So the
tree falls into components each of which is fully relevant or fully not.
</li><li>(b) Since we never break any relevant-parent-relevant-child relationships, the
number of components containing at least one relevant node is unchanged.
</li><li>(c) Since the Skein is initially a tree and not a forest, we start with
just one component, and it contains the tree root, which is known to be
relevant (we would have given up with an error message if not).
</li><li>(d) And therefore at the end of the loop the "tree" consists of a single
component headed by the tree root and containing all of the relevant nodes,
together with any number of other components each of which contains only
irrelevant ones.
</li></ul>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Solution::prune_irrelevant_lines</span><button class="popup" onclick="togglePopup('usagePopup9')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup9">Usage of <span class="code-font"><span class="function-syntax">Solution::prune_irrelevant_lines</span></span>:<br/><a href="3-sd.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">skein_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">skn</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">skn</span><span class="plain-syntax">, </span><span class="reserved-syntax">skein_node</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">skn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">relevant</span><span class="plain-syntax"> == </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">skn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">parent</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-sd.html#SP11_1" class="named-paragraph-link"><span class="named-paragraph">Delete this node from its parent</span><span class="named-paragraph-number">11.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP11_1" class="paragraph-anchor"></a><b>&#167;11.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Delete this node from its parent</span><span class="named-paragraph-number">11.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">skn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">parent</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">child</span><span class="plain-syntax"> == </span><span class="identifier-syntax">skn</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">skn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">parent</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">child</span><span class="plain-syntax"> = </span><span class="identifier-syntax">skn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sibling</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">skein_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">skn2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">skn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">parent</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">child</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">skn2</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">skn2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sibling</span><span class="plain-syntax"> != </span><span class="identifier-syntax">skn</span><span class="plain-syntax">)) </span><span class="identifier-syntax">skn2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">skn2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sibling</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">skn2</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">skn2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sibling</span><span class="plain-syntax"> == </span><span class="identifier-syntax">skn</span><span class="plain-syntax">)) </span><span class="identifier-syntax">skn2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sibling</span><span class="plain-syntax"> = </span><span class="identifier-syntax">skn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sibling</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">skn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">parent</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">skn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sibling</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-sd.html#SP11">&#167;11</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>&#167;12. Step 4: writing the solution file. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Solution::write_solution_file</span><button class="popup" onclick="togglePopup('usagePopup10')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup10">Usage of <span class="code-font"><span class="function-syntax">Solution::write_solution_file</span></span>:<br/><a href="3-sd.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">walkthrough_filename</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> </span><span class="identifier-syntax">TO_struct</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">SOL</span><span class="plain-syntax"> = &amp;</span><span class="identifier-syntax">TO_struct</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">STREAM_OPEN_TO_FILE</span><span class="plain-syntax">(</span><span class="identifier-syntax">SOL</span><span class="plain-syntax">, </span><span class="identifier-syntax">walkthrough_filename</span><span class="plain-syntax">, </span><span class="constant-syntax">UTF8_ENC</span><span class="plain-syntax">) == </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="1-be.html#SP2" class="function-link"><span class="function-syntax">BlorbErrors::fatal_fs</span></a><span class="plain-syntax">(</span><span class="string-syntax">"can't open solution text file for output"</span><span class="plain-syntax">, </span><span class="identifier-syntax">walkthrough_filename</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">SOL</span><span class="plain-syntax">, </span><span class="string-syntax">"Solution to \""</span><span class="plain-syntax">); </span><a href="3-plc.html#SP7" class="function-link"><span class="function-syntax">Placeholders::write</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">SOL</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"TITLE"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">SOL</span><span class="plain-syntax">, </span><span class="string-syntax">"\" by "</span><span class="plain-syntax">); </span><a href="3-plc.html#SP7" class="function-link"><span class="function-syntax">Placeholders::write</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">SOL</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"AUTHOR"</span><span class="plain-syntax">); </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">SOL</span><span class="plain-syntax">, </span><span class="string-syntax">"\n\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-sd.html#SP13" class="function-link"><span class="function-syntax">Solution::recursively_solve</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">SOL</span><span class="plain-syntax">, </span><span class="identifier-syntax">root_skn</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">STREAM_CLOSE</span><span class="plain-syntax">(</span><span class="identifier-syntax">SOL</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP13" class="paragraph-anchor"></a><b>&#167;13. </b>The following prints commands to the solution file from the position <span class="extract"><span class="extract-syntax">skn</span></span> &mdash;
which means just after typing its command &mdash; with the aim of reaching all
relevant endings we can get to from there.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Solution::recursively_solve</span><button class="popup" onclick="togglePopup('usagePopup11')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup11">Usage of <span class="code-font"><span class="function-syntax">Solution::recursively_solve</span></span>:<br/><a href="3-sd.html#SP12">&#167;12</a>, <a href="3-sd.html#SP13_3">&#167;13.3</a></span></button><span class="plain-syntax">(</span><span class="constant-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">skein_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">skn</span><span class="plain-syntax">, </span><span class="reserved-syntax">skein_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">last_branch</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">verbose_mode</span><span class="plain-syntax">) </span><span class="identifier-syntax">PRINT</span><span class="plain-syntax">(</span><span class="string-syntax">"recursively_solve at node %S, last branch %S\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">skn</span><span class="plain-syntax">?(</span><span class="identifier-syntax">skn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">id</span><span class="plain-syntax">):</span><span class="identifier-syntax">I</span><span class="string-syntax">"NONE"</span><span class="plain-syntax">, (</span><span class="identifier-syntax">last_branch</span><span class="plain-syntax">)?</span><span class="identifier-syntax">last_branch</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">id:I</span><span class="string-syntax">"NONE"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-sd.html#SP13_1" class="named-paragraph-link"><span class="named-paragraph">Follow the skein down until we reach a divergence, if we do</span><span class="named-paragraph-number">13.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-sd.html#SP13_2" class="named-paragraph-link"><span class="named-paragraph">Print the various alternatives from this knot where the threads diverge</span><span class="named-paragraph-number">13.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-sd.html#SP13_3" class="named-paragraph-link"><span class="named-paragraph">Show the solutions down each of these alternative lines in turn</span><span class="named-paragraph-number">13.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP13_1" class="paragraph-anchor"></a><b>&#167;13.1. </b>If there's only a single option from here, we could print it and then
call <span class="extract"><span class="extract-syntax">Solution::recursively_solve</span></span> down from it. That would make the code shorter and
clearer, perhaps, but it would clobber the C stack: our recursion depth
might be into the tens of thousands on long solution files. So we tail-recurse
instead of calling ourselves, so to speak, and just run down the thread
until we reach a choice. (If we never do reach a choice, we can return &mdash;
there is nowhere else to reach.)
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Follow the skein down until we reach a divergence, if we do</span><span class="named-paragraph-number">13.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">skn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">child</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">skn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">child</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sibling</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">skn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">skn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">child</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="3-sd.html#SP14" class="function-link"><span class="function-syntax">Solution::write_command</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">skn</span><span class="plain-syntax">, </span><span class="constant-syntax">NORMAL_COMMAND</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">skn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">child</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-sd.html#SP13">&#167;13</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP13_2" class="paragraph-anchor"></a><b>&#167;13.2. </b>Thus we are here only when there are at least two alternative commands
we might use from position <span class="extract"><span class="extract-syntax">skn</span></span>.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Print the various alternatives from this knot where the threads diverge</span><span class="named-paragraph-number">13.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"Choice:\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">branch_counter</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">skein_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">option</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">option</span><span class="plain-syntax"> = </span><span class="identifier-syntax">skn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">child</span><span class="plain-syntax">; </span><span class="identifier-syntax">option</span><span class="plain-syntax">; </span><span class="identifier-syntax">option</span><span class="plain-syntax"> = </span><span class="identifier-syntax">option</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sibling</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">option</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">child</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="3-sd.html#SP14" class="function-link"><span class="function-syntax">Solution::write_command</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">option</span><span class="plain-syntax">, </span><span class="constant-syntax">BRANCH_TO_END_COMMAND</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">option</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">branch_count</span><span class="plain-syntax"> = </span><span class="identifier-syntax">branch_counter</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">option</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">branch_parent</span><span class="plain-syntax"> = </span><span class="identifier-syntax">last_branch</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="3-sd.html#SP14" class="function-link"><span class="function-syntax">Solution::write_command</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">option</span><span class="plain-syntax">, </span><span class="constant-syntax">BRANCH_TO_LINE_COMMAND</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-sd.html#SP13">&#167;13</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP13_3" class="paragraph-anchor"></a><b>&#167;13.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Show the solutions down each of these alternative lines in turn</span><span class="named-paragraph-number">13.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">skein_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">option</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">option</span><span class="plain-syntax"> = </span><span class="identifier-syntax">skn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">child</span><span class="plain-syntax">; </span><span class="identifier-syntax">option</span><span class="plain-syntax">; </span><span class="identifier-syntax">option</span><span class="plain-syntax"> = </span><span class="identifier-syntax">option</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sibling</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">option</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">child</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"\nBranch ("</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-sd.html#SP15" class="function-link"><span class="function-syntax">Solution::write_branch_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">option</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">")\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-sd.html#SP13" class="function-link"><span class="function-syntax">Solution::recursively_solve</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">option</span><span class="plain-syntax">, </span><span class="identifier-syntax">option</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-sd.html#SP13">&#167;13</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP14" class="paragraph-anchor"></a><b>&#167;14. Writing individual commands and branch descriptions. </b></p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">NORMAL_COMMAND</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">BRANCH_TO_END_COMMAND</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">BRANCH_TO_LINE_COMMAND</span><span class="plain-syntax"> </span><span class="constant-syntax">3</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Solution::write_command</span><button class="popup" onclick="togglePopup('usagePopup12')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup12">Usage of <span class="code-font"><span class="function-syntax">Solution::write_command</span></span>:<br/><a href="3-sd.html#SP13_1">&#167;13.1</a>, <a href="3-sd.html#SP13_2">&#167;13.2</a></span></button><span class="plain-syntax">(</span><span class="constant-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">skein_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cmd_skn</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">form</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">verbose_mode</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">form</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">NORMAL_COMMAND:</span><span class="plain-syntax"> </span><span class="identifier-syntax">PRINT</span><span class="plain-syntax">(</span><span class="string-syntax">"NORMAL_COMMAND: "</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">BRANCH_TO_END_COMMAND:</span><span class="plain-syntax"> </span><span class="identifier-syntax">PRINT</span><span class="plain-syntax">(</span><span class="string-syntax">"BRANCH_TO_END_COMMAND: "</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">BRANCH_TO_LINE_COMMAND:</span><span class="plain-syntax"> </span><span class="identifier-syntax">PRINT</span><span class="plain-syntax">(</span><span class="string-syntax">"BRANCH_TO_LINE_COMMAND: "</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PRINT</span><span class="plain-syntax">(</span><span class="string-syntax">"%S\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">cmd_skn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">command</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">form</span><span class="plain-syntax"> != </span><span class="constant-syntax">NORMAL_COMMAND</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">cmd_skn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">command</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">form</span><span class="plain-syntax"> != </span><span class="constant-syntax">NORMAL_COMMAND</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" -&gt; "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">form</span><span class="plain-syntax"> == </span><span class="constant-syntax">BRANCH_TO_LINE_COMMAND</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"go to branch ("</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-sd.html#SP15" class="function-link"><span class="function-syntax">Solution::write_branch_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">cmd_skn</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">")"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"end"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="../../../inweb/foundation-module/4-sm.html#SP8" class="function-link"><span class="function-syntax">Str::len</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cmd_skn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">annotation</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" ... %S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">cmd_skn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">annotation</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP15" class="paragraph-anchor"></a><b>&#167;15. </b>For instance, at the third option from a thread which ran back to being
the second option from a thread which ran back to being the seventh option
from the original position, the following would print "7.2.3". Note that
only the knots representing the positions after commands which make a choice
are labelled in this way.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Solution::write_branch_name</span><button class="popup" onclick="togglePopup('usagePopup13')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup13">Usage of <span class="code-font"><span class="function-syntax">Solution::write_branch_name</span></span>:<br/><a href="3-sd.html#SP13_3">&#167;13.3</a>, <a href="3-sd.html#SP14">&#167;14</a></span></button><span class="plain-syntax">(</span><span class="constant-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">skein_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">skn</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">skn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">branch_parent</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="3-sd.html#SP15" class="function-link"><span class="function-syntax">Solution::write_branch_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">skn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">branch_parent</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">skn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">branch_count</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="3-rls.html">&#10094;</a></li><li class="progresschapter"><a href="M-ui.html">M</a></li><li class="progresschapter"><a href="1-bsc.html">1</a></li><li class="progresschapter"><a href="2-bw.html">2</a></li><li class="progresscurrentchapter">3</li><li class="progresssection"><a href="3-rls.html">rls</a></li><li class="progresscurrent">sd</li><li class="progresssection"><a href="3-laaf.html">laaf</a></li><li class="progresssection"><a href="3-plc.html">plc</a></li><li class="progresssection"><a href="3-tmp.html">tmp</a></li><li class="progresssection"><a href="3-wm.html">wm</a></li><li class="progresssection"><a href="3-bs6.html">bs6</a></li><li class="progressnext"><a href="3-laaf.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>
</body>
</html>