1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-03 07:24:58 +03:00
inform7/docs/problems-module/2-pl2.html
Graham Nelson 1268a0f40e Colonised
2020-04-14 17:56:54 +01:00

704 lines
91 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Problems, Level 2</title>
<meta name="viewport" content="width=device-width initial-scale=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="../inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<nav role="navigation">
<h1><a href="../index.html">
<img src="../docs-src/Figures/Inform.png" height=72">
</a></h1>
<ul><li><a href="../compiler.html">compiler tools</a></li>
<li><a href="../other.html">other tools</a></li>
<li><a href="../extensions.html">extensions and kits</a></li>
<li><a href="../units.html">unit test tools</a></li>
</ul><h2>Compiler Webs</h2><ul>
<li><a href="../inbuild/index.html">inbuild</a></li>
<li><a href="../inform7/index.html">inform7</a></li>
<li><a href="../inter/index.html">inter</a></li>
</ul><h2>Inbuild Modules</h2><ul>
<li><a href="../supervisor-module/index.html">supervisor</a></li>
</ul><h2>Inform7 Modules</h2><ul>
<li><a href="../core-module/index.html">core</a></li>
<li><a href="../inflections-module/index.html">inflections</a></li>
<li><a href="../linguistics-module/index.html">linguistics</a></li>
<li><a href="../kinds-module/index.html">kinds</a></li>
<li><a href="../if-module/index.html">if</a></li>
<li><a href="../multimedia-module/index.html">multimedia</a></li>
<li><a href="index.html"><span class="selectedlink">problems</span></a></li>
<li><a href="../index-module/index.html">index</a></li>
</ul><h2>Inter Modules</h2><ul>
<li><a href="../bytecode-module/index.html">bytecode</a></li>
<li><a href="../building-module/index.html">building</a></li>
<li><a href="../codegen-module/index.html">codegen</a></li>
</ul><h2>Shared Modules</h2><ul>
<li><a href="../arch-module/index.html">arch</a></li>
<li><a href="../syntax-module/index.html">syntax</a></li>
<li><a href="../words-module/index.html">words</a></li>
<li><a href="../html-module/index.html">html</a></li>
<li><a href="../../../inweb/docs/foundation-module/index.html">foundation</a></li>
</ul>
</nav>
<main role="main">
<!--Weave of 'Problems, Level 2' generated by 7-->
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../compiler.html">Inform7 Modules</a></li><li><a href="index.html">problems</a></li><li><a href="index.html#2">Chapter 2: Problems</a></li><li><b>Problems, Level 2</b></li></ul><p class="purpose">To assemble and format problem messages within the problem buffer.</p>
<ul class="toc"><li><a href="#SP4">&#167;4. Problem quotations</a></li><li><a href="#SP7">&#167;7. Short and long forms</a></li><li><a href="#SP9">&#167;9. How problems begin and end</a></li><li><a href="#SP10">&#167;10. Appending source</a></li><li><a href="#SP11">&#167;11. Issuing a segment of a problem message</a></li><li><a href="#SP13">&#167;13. Problems report and index</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. </b>Problem messages begin with an indication of where in the source text the
problem occurs, in terms of headings and subheadings written in the
source text, and it is this indication that we consider first. For
example,
</p>
<blockquote>
<p>In Part the First, Chapter 1 - Attic Area:</p>
</blockquote>
<p class="inwebparagraph">There can be up to 10 levels in the hierarchy of headings and
subheadings, with level 0 the top level and level 9 the lowest.
</p>
<p class="inwebparagraph">When we need to issue a problem at sentence <code class="display"><span class="extract">S</span></code>, we work out what the
current heading is (if any) at each of the 10 levels. We do this by
trekking right through the whole linked list of sentences until we reach
<code class="display"><span class="extract">S</span></code>, changing the current headings whenever we pass one. This sounds
inefficient, but of course few problems are issued, and in any case we
cannot optimise by simply cacheing the heading level from one problem to
the next because it is not true that problems are always issued in source
code order.
</p>
<pre class="definitions">
<span class="plain">@</span><span class="reserved">default</span><span class="plain"> </span><span class="constant">NO_HEADING_LEVELS</span><span class="plain"> </span><span class="constant">10</span>
</pre>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::find_headings_at<button class="popup" onclick="togglePopup('usagePopup18')">...<span class="popuptext" id="usagePopup18">Usage of <b>Problems::find_headings_at</b>:<br><a href="#SP3">&#167;3</a></span></button></span><span class="plain">(</span><span class="identifier">parse_node_tree</span><span class="plain"> *</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">sentence</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> **</span><span class="identifier">problem_headings</span><span class="plain">) {</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="constant">NO_HEADING_LEVELS</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">problem_headings</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sentence</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="identifier">ParseTree::traverse_ppn_nocs</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="functiontext"><a href="#SP1">Problems::visit_for_headings</a></span><span class="plain">, &amp;</span><span class="identifier">sentence</span><span class="plain">);</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain"> = </span><span class="identifier">ParseTree::get_problem_falls_under</span><span class="plain">(</span><span class="identifier">sentence</span><span class="plain">);</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">p</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">L</span><span class="plain"> = </span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">heading_level_ANNOT</span><span class="plain">);</span>
<span class="identifier">problem_headings</span><span class="plain">[</span><span class="identifier">L</span><span class="plain">] = </span><span class="identifier">p</span><span class="plain">;</span>
<span class="identifier">p</span><span class="plain"> = </span><span class="identifier">ParseTree::get_problem_falls_under</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Problems::visit_for_headings<button class="popup" onclick="togglePopup('usagePopup19')">...<span class="popuptext" id="usagePopup19">Usage of <b>Problems::visit_for_headings</b>:<br>none</span></button></span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">from</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> **</span><span class="identifier">sentence</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">p</span><span class="plain"> == *</span><span class="identifier">sentence</span><span class="plain">) {</span>
<span class="identifier">ParseTree::set_problem_falls_under</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">from</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">) == </span><span class="identifier">HEADING_NT</span><span class="plain">) {</span>
<span class="identifier">ParseTree::set_problem_falls_under</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">from</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>A further refinement is that we remember the last set of headings used
for an error message, and only mention what has changed about the location.
Thus we might next print:
</p>
<blockquote>
<p>In Chapter 2 - Cellar Area:</p>
</blockquote>
<p class="inwebparagraph">omitting to mention "Part the First" this time, since that part has not
changed. (And we never print internally made level 0, File, headings.)
</p>
<pre class="display">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">last_problem_headings</span><span class="plain">[</span><span class="constant">NO_HEADING_LEVELS</span><span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>Now for the actual displaying of the location text. The outcome image
is a trickier thing to get right than might appear. By being in this
routine, we know that a problem has been issued: the run will therefore
not have been a success, and we can issue the "Inform failed" outcome
image. A success image cannot be placed until right at the end of the
run, when all possibility of problems has been passed: so there's no
single point in Inform where a single line of code could choose between
the two possibilities.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">do_not_locate_problems</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::show_problem_location<button class="popup" onclick="togglePopup('usagePopup20')">...<span class="popuptext" id="usagePopup20">Usage of <b>Problems::show_problem_location</b>:<br><a href="#SP9">&#167;9</a></span></button></span><span class="plain">(</span><span class="identifier">parse_node_tree</span><span class="plain"> *</span><span class="identifier">T</span><span class="plain">) {</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">problem_headings</span><span class="plain">[</span><span class="constant">NO_HEADING_LEVELS</span><span class="plain">];</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">f</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_count</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) {</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">CORE_MODULE</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext"><a href="2-pl3.html#SP1">Problems::Issue::internal_errors_have_occurred</a></span><span class="plain">())</span>
<span class="identifier">HTMLFiles::html_outcome_image</span><span class="plain">(</span><span class="identifier">problems_file</span><span class="plain">, </span><span class="string">"ni_failed_badly"</span><span class="plain">, </span><span class="string">"Failed"</span><span class="plain">);</span>
<span class="reserved">else</span>
<span class="identifier">HTMLFiles::html_outcome_image</span><span class="plain">(</span><span class="identifier">problems_file</span><span class="plain">, </span><span class="string">"ni_failed"</span><span class="plain">, </span><span class="string">"Failed"</span><span class="plain">);</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="constant">NO_HEADING_LEVELS</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">last_problem_headings</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">do_not_locate_problems</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="functiontext"><a href="#SP1">Problems::find_headings_at</a></span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">current_sentence</span><span class="plain">, </span><span class="identifier">problem_headings</span><span class="plain">);</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="constant">NO_HEADING_LEVELS</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_headings</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] != </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">f</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">f</span><span class="plain">)</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=1; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="constant">NO_HEADING_LEVELS</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">last_problem_headings</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] != </span><span class="identifier">problem_headings</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]) {</span>
&lt;<span class="cwebmacro">Print the heading position</span> <span class="cwebmacronumber">3.1</span>&gt;<span class="plain">;</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="constant">NO_HEADING_LEVELS</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">last_problem_headings</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] = </span><span class="identifier">problem_headings</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">];</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP3_1"></a><b>&#167;3.1. </b>We print only the part of the heading position which differs from that
of the previous one quoted: <code class="display"><span class="extract">i</span></code> is at this point the highest level at
which they differ.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Print the heading position</span> <span class="cwebmacronumber">3.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">source_file</span><span class="plain"> *</span><span class="identifier">pos</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="functiontext"><a href="2-pl1.html#SP1">Problems::Buffer::clear</a></span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_count</span><span class="plain"> &gt; </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="string">"&gt;---&gt; "</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="string">"In"</span><span class="plain">);</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">f</span><span class="plain">=</span><span class="identifier">FALSE</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="constant">NO_HEADING_LEVELS</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_headings</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] != </span><span class="identifier">NULL</span><span class="plain">) {</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain"> = </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">problem_headings</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]);</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">SUPERVISOR_MODULE</span>
<span class="identifier">W</span><span class="plain"> = </span><span class="identifier">Headings::get_text</span><span class="plain">(</span><span class="identifier">Headings::from_node</span><span class="plain">(</span><span class="identifier">problem_headings</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]));</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="identifier">pos</span><span class="plain"> = </span><span class="identifier">Lexer::file_of_origin</span><span class="plain">(</span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">f</span><span class="plain">) </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="string">", "</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="string">" "</span><span class="plain">);</span>
<span class="identifier">f</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="functiontext"><a href="2-pl1.html#SP2">Problems::Buffer::copy_text_into_problem_buffer</a></span><span class="plain">(</span><span class="identifier">W</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">f</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="string">" the main source text"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pos</span><span class="plain">) {</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">SUPERVISOR_MODULE</span>
<span class="identifier">inform_extension</span><span class="plain"> *</span><span class="identifier">E</span><span class="plain"> = </span><span class="identifier">Extensions::corresponding_to</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">E</span><span class="plain">) </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="string">" in the extension %X"</span><span class="plain">, </span><span class="identifier">E</span><span class="plain">-&gt;</span><span class="identifier">as_copy</span><span class="plain">-&gt;</span><span class="identifier">edition</span><span class="plain">-&gt;</span><span class="identifier">work</span><span class="plain">);</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="plain">}</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="string">":"</span><span class="plain">);</span>
<span class="functiontext"><a href="2-pl1.html#SP6">Problems::Buffer::output_problem_buffer</a></span><span class="plain">(0);</span>
<span class="functiontext"><a href="2-pl1.html#SP1">Problems::Buffer::clear</a></span><span class="plain">();</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. Problem quotations. </b>Problem messages are printed using a printf-like formatting system.
Unlike printf, though, where <code class="display"><span class="extract">%s</span></code> means a string and <code class="display"><span class="extract">%d</span></code> a number, here
the escape codes do not indicate the type of the data: they are simply
<code class="display"><span class="extract">%1</span></code>, <code class="display"><span class="extract">%2</span></code>, <code class="display"><span class="extract">%3</span></code>, ..., <code class="display"><span class="extract">%9</span></code>. This is to prevent horrendous crashes when
type mismatches occur: using a pointer to a phrase when trying to print a
source code reference, for instance.
</p>
<p class="inwebparagraph">The texts to be substituted in place of <code class="display"><span class="extract">%1</span></code>, <code class="display"><span class="extract">%2</span></code>, ..., are called the
"quotations". The value is either a range of words in the source text, or
else a pointer to some data structure, depending on the type. The type is a
single character code. (This coding system is used only here, and could
easily be changed, but there seems no reason to.)
</p>
<p class="inwebparagraph">The type codes are S(ource), W(ords), B(inary predicate), E(xtension),
(p)H(rase), I(nvocation), N(umber), O(bject), P(roperty name), T(ext),
(t)Y(pe specification).
</p>
<pre class="display">
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">problem_quotation</span><span class="plain"> {</span>
<span class="reserved">char</span><span class="plain"> </span><span class="identifier">quotation_type</span><span class="plain">; </span><span class="comment"> one of the above</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">wording_based</span><span class="plain">; </span><span class="comment"> which of the following:</span>
<span class="reserved">void</span><span class="plain"> *</span><span class="identifier">structure_quoted</span><span class="plain">; </span><span class="comment"> if false</span>
<span class="reserved">void</span><span class="plain"> (*</span><span class="identifier">expander</span><span class="plain">)(</span><span class="identifier">text_stream</span><span class="plain"> *, </span><span class="reserved">void</span><span class="plain"> *); </span><span class="comment"> if false</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">text_quoted</span><span class="plain">; </span><span class="comment"> if true</span>
<span class="plain">} </span><span class="reserved">problem_quotation</span><span class="plain">;</span>
<span class="reserved">problem_quotation</span><span class="plain"> </span><span class="identifier">problem_quotations</span><span class="plain">[10];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The structure problem_quotation is private to this section.</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b>When some higher-level part of Inform wants to issue a formatted problem
message, it first declares the contents of any quotations it will make.
It does this using the routines <code class="display"><span class="extract">Problems::quote_object</span></code>, <code class="display"><span class="extract">Problems::quote_spec</span></code>, ...
below. Thus <code class="display"><span class="extract">Problems::quote_spec(2, SP)</span></code> specifies that <code class="display"><span class="extract">%2</span></code> should be
printed as the inference <code class="display"><span class="extract">SP</span></code>.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::problem_quote<button class="popup" onclick="togglePopup('usagePopup21')">...<span class="popuptext" id="usagePopup21">Usage of <b>Problems::problem_quote</b>:<br><a href="#SP6">&#167;6</a></span></button></span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">t</span><span class="plain">, </span><span class="reserved">void</span><span class="plain"> *</span><span class="identifier">v</span><span class="plain">, </span><span class="reserved">void</span><span class="plain"> (*</span><span class="identifier">f</span><span class="plain">)(</span><span class="identifier">text_stream</span><span class="plain"> *, </span><span class="reserved">void</span><span class="plain"> *)) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">t</span><span class="plain">&lt;0) || (</span><span class="identifier">t</span><span class="plain"> &gt; </span><span class="constant">10</span><span class="plain">)) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"problem quotation number out of range"</span><span class="plain">);</span>
<span class="identifier">problem_quotations</span><span class="plain">[</span><span class="identifier">t</span><span class="plain">].</span><span class="element">structure_quoted</span><span class="plain"> = </span><span class="identifier">v</span><span class="plain">;</span>
<span class="identifier">problem_quotations</span><span class="plain">[</span><span class="identifier">t</span><span class="plain">].</span><span class="element">expander</span><span class="plain"> = </span><span class="identifier">f</span><span class="plain">;</span>
<span class="identifier">problem_quotations</span><span class="plain">[</span><span class="identifier">t</span><span class="plain">].</span><span class="element">quotation_type</span><span class="plain"> = </span><span class="character">'?'</span><span class="plain">;</span>
<span class="identifier">problem_quotations</span><span class="plain">[</span><span class="identifier">t</span><span class="plain">].</span><span class="element">wording_based</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">problem_quotations</span><span class="plain">[</span><span class="identifier">t</span><span class="plain">].</span><span class="element">text_quoted</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::problem_quote_textual<button class="popup" onclick="togglePopup('usagePopup22')">...<span class="popuptext" id="usagePopup22">Usage of <b>Problems::problem_quote_textual</b>:<br><a href="#SP6">&#167;6</a></span></button></span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">t</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> </span><span class="identifier">type</span><span class="plain">, </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">t</span><span class="plain">&lt;0) || (</span><span class="identifier">t</span><span class="plain"> &gt; </span><span class="constant">10</span><span class="plain">)) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"problem quotation number out of range"</span><span class="plain">);</span>
<span class="identifier">problem_quotations</span><span class="plain">[</span><span class="identifier">t</span><span class="plain">].</span><span class="element">structure_quoted</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">problem_quotations</span><span class="plain">[</span><span class="identifier">t</span><span class="plain">].</span><span class="element">quotation_type</span><span class="plain"> = </span><span class="identifier">type</span><span class="plain">;</span>
<span class="identifier">problem_quotations</span><span class="plain">[</span><span class="identifier">t</span><span class="plain">].</span><span class="element">wording_based</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">problem_quotations</span><span class="plain">[</span><span class="identifier">t</span><span class="plain">].</span><span class="element">text_quoted</span><span class="plain"> = </span><span class="identifier">W</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. </b>Here are the three public routines for quoting from text: either via a node
in the parse tree, or with a literal word range.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::quote_source<button class="popup" onclick="togglePopup('usagePopup23')">...<span class="popuptext" id="usagePopup23">Usage of <b>Problems::quote_source</b>:<br>Problems, Level 3 - <a href="2-pl3.html#SP4">&#167;4</a>, <a href="2-pl3.html#SP14">&#167;14</a>, <a href="2-pl3.html#SP16">&#167;16</a>, <a href="2-pl3.html#SP17">&#167;17</a>, <a href="2-pl3.html#SP18">&#167;18</a>, <a href="2-pl3.html#SP20">&#167;20</a>, <a href="2-pl3.html#SP21">&#167;21</a></span></button></span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">t</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">p</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="functiontext"><a href="#SP5">Problems::problem_quote_textual</a></span><span class="plain">(</span><span class="identifier">t</span><span class="plain">, </span><span class="character">'S'</span><span class="plain">, </span><span class="identifier">EMPTY_WORDING</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="functiontext"><a href="#SP6">Problems::quote_wording_as_source</a></span><span class="plain">(</span><span class="identifier">t</span><span class="plain">, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">));</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::quote_source_eliding_begin<button class="popup" onclick="togglePopup('usagePopup24')">...<span class="popuptext" id="usagePopup24">Usage of <b>Problems::quote_source_eliding_begin</b>:<br>none</span></button></span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">t</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">p</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="functiontext"><a href="#SP5">Problems::problem_quote_textual</a></span><span class="plain">(</span><span class="identifier">t</span><span class="plain">, </span><span class="character">'S'</span><span class="plain">, </span><span class="identifier">EMPTY_WORDING</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain"> = </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">);</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">CORE_MODULE</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">phrase</span><span class="plain">-</span><span class="identifier">beginning</span><span class="plain">-</span><span class="identifier">block</span><span class="plain">&gt;(</span><span class="identifier">W</span><span class="plain">)) </span><span class="identifier">W</span><span class="plain"> = </span><span class="identifier">GET_RW</span><span class="plain">(&lt;</span><span class="identifier">phrase</span><span class="plain">-</span><span class="identifier">beginning</span><span class="plain">-</span><span class="identifier">block</span><span class="plain">&gt;, </span><span class="constant">1</span><span class="plain">);</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="functiontext"><a href="#SP5">Problems::problem_quote_textual</a></span><span class="plain">(</span><span class="identifier">t</span><span class="plain">, </span><span class="character">'S'</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::quote_wording<button class="popup" onclick="togglePopup('usagePopup25')">...<span class="popuptext" id="usagePopup25">Usage of <b>Problems::quote_wording</b>:<br>Problems, Level 3 - <a href="2-pl3.html#SP18">&#167;18</a>, <a href="2-pl3.html#SP20">&#167;20</a>, <a href="2-pl3.html#SP21">&#167;21</a></span></button></span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">t</span><span class="plain">, </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) { </span><span class="functiontext"><a href="#SP5">Problems::problem_quote_textual</a></span><span class="plain">(</span><span class="identifier">t</span><span class="plain">, </span><span class="character">'W'</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">); }</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::quote_wording_tinted_green<button class="popup" onclick="togglePopup('usagePopup26')">...<span class="popuptext" id="usagePopup26">Usage of <b>Problems::quote_wording_tinted_green</b>:<br>none</span></button></span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">t</span><span class="plain">, </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) { </span><span class="functiontext"><a href="#SP5">Problems::problem_quote_textual</a></span><span class="plain">(</span><span class="identifier">t</span><span class="plain">, </span><span class="character">'g'</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">); }</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::quote_wording_tinted_red<button class="popup" onclick="togglePopup('usagePopup27')">...<span class="popuptext" id="usagePopup27">Usage of <b>Problems::quote_wording_tinted_red</b>:<br>none</span></button></span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">t</span><span class="plain">, </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) { </span><span class="functiontext"><a href="#SP5">Problems::problem_quote_textual</a></span><span class="plain">(</span><span class="identifier">t</span><span class="plain">, </span><span class="character">'r'</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">); }</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::quote_wording_as_source<button class="popup" onclick="togglePopup('usagePopup28')">...<span class="popuptext" id="usagePopup28">Usage of <b>Problems::quote_wording_as_source</b>:<br>none</span></button></span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">t</span><span class="plain">, </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) { </span><span class="functiontext"><a href="#SP5">Problems::problem_quote_textual</a></span><span class="plain">(</span><span class="identifier">t</span><span class="plain">, </span><span class="character">'S'</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">); }</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::quote_text<button class="popup" onclick="togglePopup('usagePopup29')">...<span class="popuptext" id="usagePopup29">Usage of <b>Problems::quote_text</b>:<br>Problems, Level 3 - <a href="2-pl3.html#SP4">&#167;4</a>, <a href="2-pl3.html#SP13">&#167;13</a>, <a href="2-pl3.html#SP14">&#167;14</a>, <a href="2-pl3.html#SP16">&#167;16</a>, <a href="2-pl3.html#SP17">&#167;17</a>, <a href="2-pl3.html#SP18">&#167;18</a>, <a href="2-pl3.html#SP20">&#167;20</a>, <a href="2-pl3.html#SP21">&#167;21</a></span></button></span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">t</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">) {</span>
<span class="functiontext"><a href="#SP5">Problems::problem_quote</a></span><span class="plain">(</span><span class="identifier">t</span><span class="plain">, (</span><span class="reserved">void</span><span class="plain"> *) </span><span class="identifier">p</span><span class="plain">, </span><span class="functiontext"><a href="#SP6">Problems::expand_text</a></span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::expand_text<button class="popup" onclick="togglePopup('usagePopup30')">...<span class="popuptext" id="usagePopup30">Usage of <b>Problems::expand_text</b>:<br>none</span></button></span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">void</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%s"</span><span class="plain">, (</span><span class="reserved">char</span><span class="plain"> *) </span><span class="identifier">p</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::quote_wide_text<button class="popup" onclick="togglePopup('usagePopup31')">...<span class="popuptext" id="usagePopup31">Usage of <b>Problems::quote_wide_text</b>:<br>Problems, Level 3 - <a href="2-pl3.html#SP14">&#167;14</a></span></button></span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">t</span><span class="plain">, </span><span class="identifier">wchar_t</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">) {</span>
<span class="functiontext"><a href="#SP5">Problems::problem_quote</a></span><span class="plain">(</span><span class="identifier">t</span><span class="plain">, (</span><span class="reserved">void</span><span class="plain"> *) </span><span class="identifier">p</span><span class="plain">, </span><span class="functiontext"><a href="#SP6">Problems::expand_wide_text</a></span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::expand_wide_text<button class="popup" onclick="togglePopup('usagePopup32')">...<span class="popuptext" id="usagePopup32">Usage of <b>Problems::expand_wide_text</b>:<br>none</span></button></span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">void</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%w"</span><span class="plain">, (</span><span class="identifier">wchar_t</span><span class="plain"> *) </span><span class="identifier">p</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::quote_stream<button class="popup" onclick="togglePopup('usagePopup33')">...<span class="popuptext" id="usagePopup33">Usage of <b>Problems::quote_stream</b>:<br>Problems, Level 3 - <a href="2-pl3.html#SP4">&#167;4</a>, <a href="2-pl3.html#SP14">&#167;14</a>, <a href="2-pl3.html#SP15">&#167;15</a></span></button></span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">t</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">) {</span>
<span class="functiontext"><a href="#SP5">Problems::problem_quote</a></span><span class="plain">(</span><span class="identifier">t</span><span class="plain">, (</span><span class="reserved">void</span><span class="plain"> *) </span><span class="identifier">p</span><span class="plain">, </span><span class="functiontext"><a href="#SP6">Problems::expand_stream</a></span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::expand_stream<button class="popup" onclick="togglePopup('usagePopup34')">...<span class="popuptext" id="usagePopup34">Usage of <b>Problems::expand_stream</b>:<br>none</span></button></span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">void</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%S"</span><span class="plain">, (</span><span class="identifier">text_stream</span><span class="plain"> *) </span><span class="identifier">p</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::quote_wa<button class="popup" onclick="togglePopup('usagePopup35')">...<span class="popuptext" id="usagePopup35">Usage of <b>Problems::quote_wa</b>:<br>none</span></button></span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">t</span><span class="plain">, </span><span class="identifier">word_assemblage</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">) {</span>
<span class="functiontext"><a href="#SP5">Problems::problem_quote</a></span><span class="plain">(</span><span class="identifier">t</span><span class="plain">, (</span><span class="reserved">void</span><span class="plain"> *) </span><span class="identifier">p</span><span class="plain">, </span><span class="functiontext"><a href="#SP6">Problems::expand_wa</a></span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::expand_wa<button class="popup" onclick="togglePopup('usagePopup36')">...<span class="popuptext" id="usagePopup36">Usage of <b>Problems::expand_wa</b>:<br>none</span></button></span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">void</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%A"</span><span class="plain">, (</span><span class="identifier">word_assemblage</span><span class="plain"> *) </span><span class="identifier">p</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::expand_text_within_reason<button class="popup" onclick="togglePopup('usagePopup37')">...<span class="popuptext" id="usagePopup37">Usage of <b>Problems::expand_text_within_reason</b>:<br>none</span></button></span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) {</span>
<span class="identifier">W</span><span class="plain"> = </span><span class="identifier">Wordings::truncate</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">, </span><span class="constant">QUOTATION_TOLERANCE_LIMIT</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%&lt;W"</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::quote_number<button class="popup" onclick="togglePopup('usagePopup38')">...<span class="popuptext" id="usagePopup38">Usage of <b>Problems::quote_number</b>:<br>Problems, Level 3 - <a href="2-pl3.html#SP4">&#167;4</a>, <a href="2-pl3.html#SP13">&#167;13</a></span></button></span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">t</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">) {</span>
<span class="functiontext"><a href="#SP5">Problems::problem_quote</a></span><span class="plain">(</span><span class="identifier">t</span><span class="plain">, (</span><span class="reserved">void</span><span class="plain"> *) </span><span class="identifier">p</span><span class="plain">, </span><span class="functiontext"><a href="#SP6">Problems::expand_number</a></span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::expand_number<button class="popup" onclick="togglePopup('usagePopup39')">...<span class="popuptext" id="usagePopup39">Usage of <b>Problems::expand_number</b>:<br>none</span></button></span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">void</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%d"</span><span class="plain">, *((</span><span class="reserved">int</span><span class="plain"> *) </span><span class="identifier">p</span><span class="plain">));</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. Short and long forms. </b>Most of the error messages have a short form, giving the main factual
information, and a long form which also has an explanation attached.
Some of the text is common to both versions, but other parts are specific
to either one or the other, and variables record the status of our current
position in scanning and transcribing the problem message.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">shorten_problem_message</span><span class="plain">; </span><span class="comment"> give short form of this previously-seen problem</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">reading_text_specific_to_short_version</span><span class="plain">; </span><span class="comment"> modes during problem message writing</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">reading_text_specific_to_long_version</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. </b>We do not want to keep wittering on with the same old explanations,
so we remember which ones we've given before (i.e., in previous problem
messages during the same run of Inform). Eventually our patience is exhausted
and we give no further explanation in any circumstances.
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">PATIENCE_EXHAUSTION_POINT</span><span class="plain"> </span><span class="constant">100</span>
</pre>
<pre class="display">
<span class="reserved">char</span><span class="plain"> *</span><span class="identifier">explanations</span><span class="plain">[</span><span class="constant">PATIENCE_EXHAUSTION_POINT</span><span class="plain">];</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">no_explanations</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Problems::explained_before<button class="popup" onclick="togglePopup('usagePopup40')">...<span class="popuptext" id="usagePopup40">Usage of <b>Problems::explained_before</b>:<br><a href="#SP9">&#167;9</a></span></button></span><span class="plain">(</span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">explanation</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">no_explanations</span><span class="plain"> == </span><span class="constant">PATIENCE_EXHAUSTION_POINT</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">no_explanations</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">explanation</span><span class="plain"> == </span><span class="identifier">explanations</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">explanations</span><span class="plain">[</span><span class="identifier">no_explanations</span><span class="plain">++] = </span><span class="identifier">explanation</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. How problems begin and end. </b>During the construction of a problem message, we will be running through a
standard text, and at any point might be considering matter which should
appear only in the long form, or only in the short form.
</p>
<p class="inwebparagraph">If the text of a message begins with an asterisk, then it is a
continuation of a message already partly issued. Otherwise we can
sensibly find out whether this is one we've seen before. Either way, we
set <code class="display"><span class="extract">shorten_problem_message</span></code> to remember whether to use the short or long
form.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::issue_problem_begin<button class="popup" onclick="togglePopup('usagePopup41')">...<span class="popuptext" id="usagePopup41">Usage of <b>Problems::issue_problem_begin</b>:<br>Problems, Level 3 - <a href="2-pl3.html#SP4">&#167;4</a>, <a href="2-pl3.html#SP12">&#167;12</a>, <a href="2-pl3.html#SP13">&#167;13</a>, <a href="2-pl3.html#SP14">&#167;14</a>, <a href="2-pl3.html#SP15">&#167;15</a>, <a href="2-pl3.html#SP16">&#167;16</a>, <a href="2-pl3.html#SP17">&#167;17</a>, <a href="2-pl3.html#SP18">&#167;18</a>, <a href="2-pl3.html#SP20">&#167;20</a>, <a href="2-pl3.html#SP21">&#167;21</a></span></button></span><span class="plain">(</span><span class="identifier">parse_node_tree</span><span class="plain"> *</span><span class="identifier">T</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">message</span><span class="plain">) {</span>
<span class="functiontext"><a href="2-pl1.html#SP1">Problems::Buffer::clear</a></span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">strcmp</span><span class="plain">(</span><span class="identifier">message</span><span class="plain">, </span><span class="string">"*"</span><span class="plain">) == </span><span class="constant">0</span><span class="plain">) {</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="string">"&gt;++&gt;"</span><span class="plain">);</span>
<span class="identifier">shorten_problem_message</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">strcmp</span><span class="plain">(</span><span class="identifier">message</span><span class="plain">, </span><span class="string">"****"</span><span class="plain">) == </span><span class="constant">0</span><span class="plain">) {</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="string">"&gt;++++&gt;"</span><span class="plain">);</span>
<span class="identifier">shorten_problem_message</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">strcmp</span><span class="plain">(</span><span class="identifier">message</span><span class="plain">, </span><span class="string">"***"</span><span class="plain">) == </span><span class="constant">0</span><span class="plain">) {</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="string">"&gt;+++&gt;"</span><span class="plain">);</span>
<span class="identifier">shorten_problem_message</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">strcmp</span><span class="plain">(</span><span class="identifier">message</span><span class="plain">, </span><span class="string">"**"</span><span class="plain">) == </span><span class="constant">0</span><span class="plain">) {</span>
<span class="identifier">shorten_problem_message</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">T</span><span class="plain">) </span><span class="functiontext"><a href="#SP3">Problems::show_problem_location</a></span><span class="plain">(</span><span class="identifier">T</span><span class="plain">);</span>
<span class="identifier">problem_count</span><span class="plain">++;</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="string">"&gt;--&gt; "</span><span class="plain">);</span>
<span class="identifier">shorten_problem_message</span><span class="plain"> = </span><span class="functiontext"><a href="#SP8">Problems::explained_before</a></span><span class="plain">(</span><span class="identifier">message</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">reading_text_specific_to_short_version</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">reading_text_specific_to_long_version</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::issue_problem_end<button class="popup" onclick="togglePopup('usagePopup42')">...<span class="popuptext" id="usagePopup42">Usage of <b>Problems::issue_problem_end</b>:<br>Problems, Level 3 - <a href="2-pl3.html#SP3">&#167;3</a>, <a href="2-pl3.html#SP13">&#167;13</a>, <a href="2-pl3.html#SP14">&#167;14</a>, <a href="2-pl3.html#SP15">&#167;15</a>, <a href="2-pl3.html#SP16">&#167;16</a>, <a href="2-pl3.html#SP17">&#167;17</a>, <a href="2-pl3.html#SP18">&#167;18</a>, <a href="2-pl3.html#SP20">&#167;20</a>, <a href="2-pl3.html#SP21">&#167;21</a></span></button></span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">CORE_MODULE</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">compiling_text_routines_mode</span><span class="plain">) </span><span class="identifier">Strings::TextSubstitutions::append_text_substitution_proviso</span><span class="plain">();</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="functiontext"><a href="2-pl1.html#SP6">Problems::Buffer::output_problem_buffer</a></span><span class="plain">(1);</span>
<span class="functiontext"><a href="2-pl3.html#SP10">Problems::Issue::problem_documentation_links</a></span><span class="plain">(</span><span class="identifier">problems_file</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">crash_on_all_errors</span><span class="plain">) </span><span class="functiontext"><a href="2-pl0.html#SP2">Problems::Fatal::force_crash</a></span><span class="plain">();</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. Appending source. </b></p>
<pre class="display">
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">appended_source</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::append_source<button class="popup" onclick="togglePopup('usagePopup43')">...<span class="popuptext" id="usagePopup43">Usage of <b>Problems::append_source</b>:<br><a href="#SP11_1_2">&#167;11.1.2</a></span></button></span><span class="plain">(</span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) {</span>
<span class="identifier">appended_source</span><span class="plain"> = </span><span class="identifier">W</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::transcribe_appended_source<button class="popup" onclick="togglePopup('usagePopup44')">...<span class="popuptext" id="usagePopup44">Usage of <b>Problems::transcribe_appended_source</b>:<br><a href="#SP11_1_2">&#167;11.1.2</a></span></button></span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">appended_source</span><span class="plain">))</span>
<span class="functiontext"><a href="2-pl1.html#SP4">Problems::Buffer::copy_source_reference_into_problem_buffer</a></span><span class="plain">(</span><span class="identifier">appended_source</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP11"></a><b>&#167;11. Issuing a segment of a problem message. </b>Here is the routine which performs the substitution of quotations into
problem messages and sends them on their way: which is called
<code class="display"><span class="extract">Problems::issue_problem_segment</span></code> since it only appends a further piece of text, and may
be used several times to build up complicated messages.
</p>
<p class="inwebparagraph">We have seen that, within problem message texts, the escapes <code class="display"><span class="extract">%1</span></code> to <code class="display"><span class="extract">%9</span></code>
are to produce quotations. Four further escape codes switch between problem
message versions, as follows: we have <code class="display"><span class="extract">%L</span></code>, which indicates that the text
which follows should only be used in the long form of the error message;
<code class="display"><span class="extract">%S</span></code>, the same for the short form; <code class="display"><span class="extract">%%</span></code>, which cancels either of these
settings and restores the text to appearing in both forms, which is the
default. A percentage sign followed by a vertical stroke acts more simply
as a divider between the brief message and the explanation text in many
simple problem messages which do not use the elaborations of the other
three escapes.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::issue_problem_segment<button class="popup" onclick="togglePopup('usagePopup45')">...<span class="popuptext" id="usagePopup45">Usage of <b>Problems::issue_problem_segment</b>:<br>Problems, Level 3 - <a href="2-pl3.html#SP4">&#167;4</a>, <a href="2-pl3.html#SP13">&#167;13</a>, <a href="2-pl3.html#SP14">&#167;14</a>, <a href="2-pl3.html#SP15">&#167;15</a>, <a href="2-pl3.html#SP16">&#167;16</a>, <a href="2-pl3.html#SP17">&#167;17</a>, <a href="2-pl3.html#SP18">&#167;18</a>, <a href="2-pl3.html#SP20">&#167;20</a>, <a href="2-pl3.html#SP21">&#167;21</a></span></button></span><span class="plain">(</span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">message</span><span class="plain">) {</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">message</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]; </span><span class="identifier">i</span><span class="plain">++) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">message</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] == </span><span class="character">'%'</span><span class="plain">) {</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">message</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">+1]) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="character">'L'</span><span class="plain">: </span><span class="identifier">reading_text_specific_to_long_version</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++; </span><span class="reserved">continue</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="character">'S'</span><span class="plain">: </span><span class="identifier">reading_text_specific_to_short_version</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++; </span><span class="reserved">continue</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="character">'%'</span><span class="plain">: </span><span class="identifier">reading_text_specific_to_short_version</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">reading_text_specific_to_long_version</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++; </span><span class="reserved">continue</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="character">'|'</span><span class="plain">: </span><span class="identifier">reading_text_specific_to_short_version</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">reading_text_specific_to_long_version</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">shorten_problem_message</span><span class="plain">) </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="string">"."</span><span class="plain">);</span>
<span class="identifier">i</span><span class="plain">++; </span><span class="reserved">continue</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">reading_text_specific_to_short_version</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">shorten_problem_message</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">)) </span><span class="reserved">continue</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">reading_text_specific_to_long_version</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">shorten_problem_message</span><span class="plain"> == </span><span class="identifier">TRUE</span><span class="plain">)) </span><span class="reserved">continue</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Act on the problem message text, since it is now contextually allowed</span> <span class="cwebmacronumber">11.1</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP11_1"></a><b>&#167;11.1. </b>Ordinarily we just append the new character, but we also act on the escapes
<code class="display"><span class="extract">%P</span></code> and <code class="display"><span class="extract">%1</span></code> to <code class="display"><span class="extract">%9</span></code>. <code class="display"><span class="extract">%P</span></code> forces a paragraph break, or at any rate, it does
in the eventual HTML version of the problem message. Note that these escapes
are acted on only if they occur in a contextually allowed part of the problem
message (e.g., if they occur in the short form only, they will only be acted
on when the shortened form is the one being issued).
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Act on the problem message text, since it is now contextually allowed</span> <span class="cwebmacronumber">11.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">message</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] == </span><span class="character">'%'</span><span class="plain">) {</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">message</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">+1]) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="character">'P'</span><span class="plain">: </span><span class="identifier">PUT_TO</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="constant">FORCE_NEW_PARA_CHAR</span><span class="plain">);</span>
<span class="identifier">i</span><span class="plain">++; </span><span class="reserved">continue</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Characters::isdigit</span><span class="plain">(</span><span class="identifier">message</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">+1])) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">t</span><span class="plain"> = ((</span><span class="reserved">int</span><span class="plain">) (</span><span class="identifier">message</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">+1]))-((</span><span class="reserved">int</span><span class="plain">) </span><span class="character">'0'</span><span class="plain">); </span><span class="identifier">i</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">t</span><span class="plain">&gt;=1) &amp;&amp; (</span><span class="identifier">t</span><span class="plain">&lt;=9)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_quotations</span><span class="plain">[</span><span class="identifier">t</span><span class="plain">].</span><span class="element">wording_based</span><span class="plain">)</span>
&lt;<span class="cwebmacro">Expand wording-based escape</span> <span class="cwebmacronumber">11.1.1</span>&gt;
<span class="reserved">else</span>
&lt;<span class="cwebmacro">Expand structure-based escape</span> <span class="cwebmacronumber">11.1.2</span>&gt;
<span class="plain">}</span>
<span class="reserved">continue</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="identifier">PUT_TO</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="identifier">message</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP11">&#167;11</a>.</p>
<p class="inwebparagraph"><a id="SP11_1_1"></a><b>&#167;11.1.1. </b>This is where a quotation escape, such as <code class="display"><span class="extract">%2</span></code>, is expanded: by looking up
its type, stored internally as a single character.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Expand wording-based escape</span> <span class="cwebmacronumber">11.1.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">problem_quotations</span><span class="plain">[</span><span class="identifier">t</span><span class="plain">].</span><span class="element">quotation_type</span><span class="plain">) {</span>
<span class="comment"> Monochrome wording</span>
<span class="reserved">case</span><span class="plain"> </span><span class="character">'S'</span><span class="plain">: </span><span class="functiontext"><a href="2-pl1.html#SP4">Problems::Buffer::copy_source_reference_into_problem_buffer</a></span><span class="plain">(</span>
<span class="identifier">problem_quotations</span><span class="plain">[</span><span class="identifier">t</span><span class="plain">].</span><span class="element">text_quoted</span><span class="plain">);</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="character">'W'</span><span class="plain">: </span><span class="functiontext"><a href="2-pl1.html#SP2">Problems::Buffer::copy_text_into_problem_buffer</a></span><span class="plain">(</span>
<span class="identifier">problem_quotations</span><span class="plain">[</span><span class="identifier">t</span><span class="plain">].</span><span class="element">text_quoted</span><span class="plain">);</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="comment"> Tinted wording</span>
<span class="reserved">case</span><span class="plain"> </span><span class="character">'r'</span><span class="plain">: </span>&lt;<span class="cwebmacro">Quote a red-tinted word range in a problem message</span> <span class="cwebmacronumber">11.1.1.1</span>&gt;<span class="plain">;</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="character">'g'</span><span class="plain">: </span>&lt;<span class="cwebmacro">Quote a green-tinted word range in a problem message</span> <span class="cwebmacronumber">11.1.1.2</span>&gt;<span class="plain">;</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="identifier">default:</span><span class="plain"> </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"unknown error token type"</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP11_1">&#167;11.1</a>.</p>
<p class="inwebparagraph"><a id="SP11_1_1_1"></a><b>&#167;11.1.1.1. </b>Tinting text involves some HTML, of course:
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Quote a red-tinted word range in a problem message</span> <span class="cwebmacronumber">11.1.1.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
<span class="identifier">HTML::begin_colour</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"800000"</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%W"</span><span class="plain">, </span><span class="identifier">problem_quotations</span><span class="plain">[</span><span class="identifier">t</span><span class="plain">].</span><span class="element">text_quoted</span><span class="plain">);</span>
<span class="identifier">HTML::end_colour</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Spool temporary stream text to the problem buffer</span> <span class="cwebmacronumber">11.1.1.1.1</span>&gt;<span class="plain">;</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP11_1_1">&#167;11.1.1</a>.</p>
<p class="inwebparagraph"><a id="SP11_1_1_2"></a><b>&#167;11.1.1.2. </b>And:
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Quote a green-tinted word range in a problem message</span> <span class="cwebmacronumber">11.1.1.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
<span class="identifier">HTML::begin_colour</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"008000"</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%W"</span><span class="plain">, </span><span class="identifier">problem_quotations</span><span class="plain">[</span><span class="identifier">t</span><span class="plain">].</span><span class="element">text_quoted</span><span class="plain">);</span>
<span class="identifier">HTML::end_colour</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Spool temporary stream text to the problem buffer</span> <span class="cwebmacronumber">11.1.1.1.1</span>&gt;<span class="plain">;</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP11_1_1">&#167;11.1.1</a>.</p>
<p class="inwebparagraph"><a id="SP11_1_2"></a><b>&#167;11.1.2. </b>More generally, the reference is to some structure we can't write
ourselves, and must delegate to:
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Expand structure-based escape</span> <span class="cwebmacronumber">11.1.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="functiontext"><a href="#SP10">Problems::append_source</a></span><span class="plain">(</span><span class="identifier">EMPTY_WORDING</span><span class="plain">);</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
<span class="plain">(</span><span class="identifier">problem_quotations</span><span class="plain">[</span><span class="identifier">t</span><span class="plain">].</span><span class="element">expander</span><span class="plain">)(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">problem_quotations</span><span class="plain">[</span><span class="identifier">t</span><span class="plain">].</span><span class="element">structure_quoted</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Spool temporary stream text to the problem buffer</span> <span class="cwebmacronumber">11.1.1.1.1</span>&gt;<span class="plain">;</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
<span class="functiontext"><a href="#SP10">Problems::transcribe_appended_source</a></span><span class="plain">();</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP11_1">&#167;11.1</a>.</p>
<p class="inwebparagraph"><a id="SP11_1_1_1_1"></a><b>&#167;11.1.1.1.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Spool temporary stream text to the problem buffer</span> <span class="cwebmacronumber">11.1.1.1.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">LOOP_THROUGH_TEXT</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">, </span><span class="identifier">OUT</span><span class="plain">) {</span>
<span class="identifier">wchar_t</span><span class="plain"> </span><span class="identifier">c</span><span class="plain"> = </span><span class="identifier">Str::get</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">c</span><span class="plain"> == </span><span class="character">'&lt;'</span><span class="plain">) </span><span class="identifier">c</span><span class="plain"> = </span><span class="constant">PROTECTED_LT_CHAR</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">c</span><span class="plain"> == </span><span class="character">'&gt;'</span><span class="plain">) </span><span class="identifier">c</span><span class="plain"> = </span><span class="constant">PROTECTED_GT_CHAR</span><span class="plain">;</span>
<span class="identifier">PUT_TO</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="identifier">c</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP11_1_1_1">&#167;11.1.1.1</a>, <a href="#SP11_1_1_2">&#167;11.1.1.2</a>, <a href="#SP11_1_2">&#167;11.1.2</a>.</p>
<p class="inwebparagraph"><a id="SP12"></a><b>&#167;12. </b>This version is much shorter, since escapes aren't allowed:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::issue_problem_segment_from_stream<button class="popup" onclick="togglePopup('usagePopup46')">...<span class="popuptext" id="usagePopup46">Usage of <b>Problems::issue_problem_segment_from_stream</b>:<br>none</span></button></span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">message</span><span class="plain">) {</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="string">"%S"</span><span class="plain">, </span><span class="identifier">message</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP13"></a><b>&#167;13. Problems report and index. </b>That gives us enough infrastructure to produce the final report. Note the use
of error redirection to in order to put pseudo-problem messages &mdash; actually
informational &mdash; into the report. In the case where the run was successful and
there we no Problem messages, we have to be careful to reset <code class="display"><span class="extract">problem_count</span></code>
&mdash; it will have been increased by the issuing of these pseudo-problems, and we
need it to remain 0 so that <code class="display"><span class="extract">main()</span></code> can finally return back to the operating
system without an error code.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">tail_of_report_written</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::write_reports<button class="popup" onclick="togglePopup('usagePopup47')">...<span class="popuptext" id="usagePopup47">Usage of <b>Problems::write_reports</b>:<br>Problems, Level 3 - <a href="2-pl3.html#SP3">&#167;3</a>, <a href="2-pl3.html#SP13">&#167;13</a></span></button></span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">disaster_struck</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">tail_of_report_written</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="identifier">tail_of_report_written</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">crash_on_all_errors</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">PROBLEMS_FINAL_REPORTER</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">pc</span><span class="plain"> = </span><span class="identifier">problem_count</span><span class="plain">;</span>
<span class="identifier">PROBLEMS_FINAL_REPORTER</span><span class="plain">(</span><span class="identifier">disaster_struck</span><span class="plain">, </span><span class="identifier">problem_count</span><span class="plain">);</span>
<span class="identifier">problem_count</span><span class="plain"> = </span><span class="identifier">pc</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="identifier">HTML::end_body</span><span class="plain">(</span><span class="identifier">problems_file</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<hr class="tocbar">
<ul class="toc"><li><a href="2-pl1.html">Back to 'Problems, Level 1'</a></li><li><a href="2-pl3.html">Continue with 'Problems, Level 3'</a></li></ul><hr class="tocbar">
<!--End of weave-->
<script>
function togglePopup(material_id) {
var popup = document.getElementById(material_id);
popup.classList.toggle("show");
}
</script>
<link href="Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
</main>
</body>
</html>