1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-08 18:14:21 +03:00
inform7/docs/problems-module/2-pl1.html
2019-10-02 23:04:15 +01:00

442 lines
57 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>2/pl0</title>
<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>
<!--Weave of '2/pl1' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</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 1</b></li></ul><p class="purpose">To render problem messages either as plain text or HTML, and write them out to files.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Buffering</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Buffering. </b>Only one error text needs to be stored in memory at any one time, so we keep
it in a single text stream:
</p>
<pre class="display">
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">PBUFF</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::Buffer::clear</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">PBUFF</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">PBUFF</span><span class="plain"> = </span><span class="identifier">Str::new</span><span class="plain">();</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">Str::clear</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Problems::Buffer::clear is used in 2/pl2 (<a href="2-pl2.html#SP3_1">&#167;3.1</a>, <a href="2-pl2.html#SP9">&#167;9</a>).</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>Roughly speaking, text for problem messages comes from two possible sources:
fairly short standard texts inside NI, and quotations (direct or indirect)
from the source text. The latter are inserted by the routines in this section,
and they are the ones we should be wary of, since bizarre input might cause
absurdly long quotations to be made. A quotation involves copying text from
word <code class="display"><span class="extract">w1</span></code> to <code class="display"><span class="extract">w2</span></code>, so there are two dangers: copying a single very long word,
or copying too many of them. We protect against the first by using the
<code class="display"><span class="extract">%&lt;W</span></code> escape, which truncates long literals. We protect against the second
overflow hazard by limiting the amount of text we are prepared to quote from
any sentence in one go:
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">QUOTATION_TOLERANCE_LIMIT</span><span class="plain"> 100</span>
</pre>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::Buffer::copy_text_into_problem_buffer</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_TO</span><span class="plain">(</span><span class="identifier">PBUFF</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>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Problems::Buffer::copy_text_into_problem_buffer is used in <a href="#SP4">&#167;4</a>, 2/pl2 (<a href="2-pl2.html#SP3_1">&#167;3.1</a>, <a href="2-pl2.html#SP11_1_1">&#167;11.1.1</a>).</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>Diverting source quotes.
</p>
<pre class="display">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">redirected_sentence</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">redirected_to_A</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">redirected_to_B</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::Buffer::redirect_problem_sentence</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">A</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">B</span><span class="plain">) {</span>
<span class="identifier">redirected_sentence</span><span class="plain"> = </span><span class="identifier">from</span><span class="plain">; </span><span class="identifier">redirected_to_A</span><span class="plain"> = </span><span class="identifier">A</span><span class="plain">; </span><span class="identifier">redirected_to_B</span><span class="plain"> = </span><span class="identifier">B</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Problems::Buffer::redirect_problem_sentence appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>A special escape sequence, marked by starting and finishing with a character
which otherwise can never occur, is expanded to a source code link. If we used
an asterisk to denote this, then a source reference is fed into
<code class="display"><span class="extract">HTMLFiles::char_out</span></code> as the following stream of characters:
</p>
<p class="inwebparagraph"><code class="display"><span class="extract">*source text*Source/story.ni*14*</span></code>
</p>
<p class="inwebparagraph">(with <code class="display"><span class="extract">SOURCE_REF_CHAR</span></code> used in place of the asterisk).
</p>
<p class="inwebparagraph">But of course we don't use an asterisk as trigger &mdash; we use character <code class="display"><span class="extract">F0</span></code>.
Arguably this is dodgy, since the character is legal in ISO Latin-1. But it
is a lower-case Icelandic eth, which is not allowed in unquoted Inform 7 source
text (because of being absent from the ZSCII character set).
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">SOURCE_REF_CHAR</span><span class="plain"> </span><span class="identifier">L</span><span class="character">'\</span><span class="plain">x</span><span class="character">f0'</span>
<span class="definitionkeyword">define</span> <span class="constant">FORCE_NEW_PARA_CHAR</span><span class="plain"> </span><span class="identifier">L</span><span class="character">'\</span><span class="plain">x</span><span class="character">d0'</span>
<span class="definitionkeyword">define</span> <span class="constant">PROTECTED_LT_CHAR</span><span class="plain"> </span><span class="identifier">L</span><span class="character">'\</span><span class="plain">x</span><span class="character">01'</span>
<span class="definitionkeyword">define</span> <span class="constant">PROTECTED_GT_CHAR</span><span class="plain"> </span><span class="identifier">L</span><span class="character">'\</span><span class="plain">x</span><span class="character">02'</span>
</pre>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::Buffer::copy_source_reference_into_problem_buffer</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">Wordings::empty</span><span class="plain">(</span><span class="identifier">W</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">"&lt;no text&gt;"</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">; }</span>
<span class="identifier">source_file</span><span class="plain"> *</span><span class="identifier">referred</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="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">file</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">referred</span><span class="plain">) {</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">file</span><span class="plain">, </span><span class="string">"%f"</span><span class="plain">, </span><span class="identifier">TextFromFiles::get_filename</span><span class="plain">(</span><span class="identifier">referred</span><span class="plain">));</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">REDIRECT_PROBLEM_SOURCE_TO</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">REDIRECT_PROBLEM_SOURCE_TO</span><span class="plain">) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">project_prefix</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">project_prefix</span><span class="plain">, </span><span class="string">"%p"</span><span class="plain">, </span><span class="identifier">pathname_of_project</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::prefix_eq</span><span class="plain">(</span><span class="identifier">file</span><span class="plain">, </span><span class="identifier">project_prefix</span><span class="plain">, </span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">project_prefix</span><span class="plain">)))</span>
<span class="identifier">Str::delete_n_characters</span><span class="plain">(</span><span class="identifier">file</span><span class="plain">, </span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">project_prefix</span><span class="plain">));</span>
<span class="plain">}</span>
<span class="plain">#</span><span class="identifier">endif</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">file</span><span class="plain">, </span><span class="string">"(no file)"</span><span class="plain">);</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">Problems::Buffer::copy_text_into_problem_buffer</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">);</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">paraphrase</span><span class="plain"> = </span><span class="identifier">file</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">EXTENSIONS_PRESENT</span>
<span class="identifier">paraphrase</span><span class="plain"> = </span><span class="identifier">I</span><span class="string">"source text"</span><span class="plain">;</span>
<span class="identifier">extension_file</span><span class="plain"> *</span><span class="identifier">ef</span><span class="plain"> = </span><span class="identifier">SourceFiles::get_extension_corresponding</span><span class="plain">(</span><span class="identifier">referred</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ef</span><span class="plain">) {</span>
<span class="identifier">extension_identifier</span><span class="plain"> *</span><span class="identifier">eid</span><span class="plain"> = </span><span class="identifier">Extensions::Files::get_eid</span><span class="plain">(</span><span class="identifier">ef</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">eid</span><span class="plain">) &amp;&amp; (</span><span class="identifier">Extensions::IDs::is_standard_rules</span><span class="plain">(</span><span class="identifier">eid</span><span class="plain">)))</span>
<span class="identifier">paraphrase</span><span class="plain"> = </span><span class="identifier">I</span><span class="string">"the Standard Rules"</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">eid</span><span class="plain">) &amp;&amp; (</span><span class="identifier">Extensions::IDs::is_basic_inform</span><span class="plain">(</span><span class="identifier">eid</span><span class="plain">)))</span>
<span class="identifier">paraphrase</span><span class="plain"> = </span><span class="identifier">I</span><span class="string">"Basic Inform"</span><span class="plain">;</span>
<span class="reserved">else</span>
<span class="identifier">paraphrase</span><span class="plain"> = </span><span class="identifier">file</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="string">"' %c%S%c%S%c%d%c"</span><span class="plain">,</span>
<span class="constant">SOURCE_REF_CHAR</span><span class="plain">, </span><span class="identifier">paraphrase</span><span class="plain">,</span>
<span class="constant">SOURCE_REF_CHAR</span><span class="plain">, </span><span class="identifier">file</span><span class="plain">,</span>
<span class="constant">SOURCE_REF_CHAR</span><span class="plain">, </span><span class="identifier">Wordings::location</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">).</span><span class="identifier">line_number</span><span class="plain">,</span>
<span class="constant">SOURCE_REF_CHAR</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">redirected_sentence</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">redirected_to_A</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">redirected_to_B</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">Wordings::eq</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">redirected_sentence</span><span class="plain">), </span><span class="identifier">W</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">" (which asserts that "</span><span class="plain">);</span>
<span class="functiontext">Problems::Buffer::copy_source_reference_into_problem_buffer</span><span class="plain">(</span>
<span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">redirected_to_A</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">" is/are "</span><span class="plain">);</span>
<span class="functiontext">Problems::Buffer::copy_source_reference_into_problem_buffer</span><span class="plain">(</span>
<span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">redirected_to_B</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="plain">}</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">file</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Problems::Buffer::copy_source_reference_into_problem_buffer is used in 2/pl2 (<a href="2-pl2.html#SP10">&#167;10</a>, <a href="2-pl2.html#SP11_1_1">&#167;11.1.1</a>).</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b>Once the error message is fully constructed, we will want to output it
to a file: in fact, by default it will go in three directions, to
<code class="display"><span class="extract">stderr</span></code>, to the debugging log and of course to the error log. The main
thing is to word-wrap it, since it is likely to be a paragraph-sized
chunk of text, not a single line. The unprintable <code class="display"><span class="extract">SOURCE_REF_CHAR</span></code> and
<code class="display"><span class="extract">FORCE_NEW_PARA_CHAR</span></code> are simply filtered out for plain text output: for
HTML, they are dealt with elsewhere.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">problem_count_at_last_in</span><span class="plain"> = 1;</span>
<span class="plain">#</span><span class="identifier">ifndef</span><span class="plain"> </span><span class="identifier">PROBLEMS_HTML_EMITTER</span>
<span class="plain">#</span><span class="identifier">define</span><span class="plain"> </span><span class="identifier">PROBLEMS_HTML_EMITTER</span><span class="plain"> </span><span class="identifier">PUT_TO</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::Buffer::output_problem_buffer_to</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">indentation</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">line_width</span><span class="plain"> = 0, </span><span class="identifier">html_flag</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">OUT</span><span class="plain"> == </span><span class="identifier">problems_file</span><span class="plain">) </span><span class="identifier">html_flag</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="reserved">int</span><span class="plain"> </span><span class="identifier">k</span><span class="plain">=0; </span><span class="identifier">k</span><span class="plain">&lt;</span><span class="identifier">indentation</span><span class="plain">; </span><span class="identifier">k</span><span class="plain">++) { </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" "</span><span class="plain">); </span><span class="identifier">line_width</span><span class="plain">+=2; }</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">L</span><span class="plain">=</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">); </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">L</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">c</span><span class="plain"> = </span><span class="identifier">Str::get_at</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">);</span>
&lt;<span class="cwebmacro">In HTML mode, convert drawing-your-attention arrows</span> <span class="cwebmacronumber">5.1</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">In plain text mode, remove bold and italic HTML tags</span> <span class="cwebmacronumber">5.2</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">html_flag</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) &amp;&amp; (</span><span class="identifier">c</span><span class="plain"> == </span><span class="constant">SOURCE_REF_CHAR</span><span class="plain">))</span>
&lt;<span class="cwebmacro">Issue plain text paraphrase of source reference</span> <span class="cwebmacronumber">5.3</span>&gt;
<span class="reserved">else</span><span class="plain"> </span>&lt;<span class="cwebmacro">Output single character of problem message</span> <span class="cwebmacronumber">5.4</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">html_flag</span><span class="plain">) </span><span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">)</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Problems::Buffer::output_problem_buffer_to is used in <a href="#SP6">&#167;6</a>.</p>
<p class="inwebparagraph"><a id="SP5_1"></a><b>&#167;5.1. </b>The plain text "may I draw your attention to the following paragraph"
marker,
</p>
<p class="inwebparagraph"><code class="display"><span class="extract">&gt;--&gt; Which looks like this.</span></code>
</p>
<p class="inwebparagraph">is converted into a suitable CSS-styled HTML paragraph with hanging
indentation. And similarly for <code class="display"><span class="extract">&gt;++&gt;</span></code>, used to mark continuations.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">In HTML mode, convert drawing-your-attention arrows</span> <span class="cwebmacronumber">5.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">html_flag</span><span class="plain">) &amp;&amp; (</span><span class="identifier">Str::includes_wide_string_at</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"&gt;--&gt;"</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_count</span><span class="plain"> &gt; </span><span class="identifier">problem_count_at_last_in</span><span class="plain">) {</span>
<span class="identifier">HTML_TAG</span><span class="plain">(</span><span class="string">"hr"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">HTML_OPEN_WITH</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">, </span><span class="string">"class=\</span><span class="plain">"</span><span class="string">hang\</span><span class="plain">"</span><span class="string">"</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&lt;b&gt;Problem.&lt;/b&gt; "</span><span class="plain">);</span>
<span class="identifier">i</span><span class="plain">+=3; </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">Str::includes_wide_string_at</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"&gt;++&gt;"</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">html_flag</span><span class="plain">) </span><span class="identifier">HTML_OPEN_WITH</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">, </span><span class="string">"class=\</span><span class="plain">"</span><span class="string">in2\</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</span><span class="plain">(</span><span class="string">" "</span><span class="plain">);</span>
<span class="identifier">i</span><span class="plain">+=3; </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">Str::includes_wide_string_at</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"&gt;---&gt;"</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">html_flag</span><span class="plain">) {</span>
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">); </span><span class="identifier">HTML_TAG</span><span class="plain">(</span><span class="string">"hr"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">problem_count_at_last_in</span><span class="plain"> = </span><span class="identifier">problem_count</span><span class="plain">+1;</span>
<span class="identifier">i</span><span class="plain">+=4; </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">Str::includes_wide_string_at</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"&gt;+++&gt;"</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">html_flag</span><span class="plain">) </span><span class="identifier">HTML_OPEN_WITH</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">, </span><span class="string">"halftightin3\</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</span><span class="plain">(</span><span class="string">" "</span><span class="plain">);</span>
<span class="identifier">i</span><span class="plain">+=4; </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">Str::includes_wide_string_at</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"&gt;++++&gt;"</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">html_flag</span><span class="plain">) </span><span class="identifier">HTML_OPEN_WITH</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">, </span><span class="string">"class=\</span><span class="plain">"</span><span class="string">tightin3\</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</span><span class="plain">(</span><span class="string">" "</span><span class="plain">);</span>
<span class="identifier">i</span><span class="plain">+=5; </span><span class="reserved">continue</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5">&#167;5</a>.</p>
<p class="inwebparagraph"><a id="SP5_2"></a><b>&#167;5.2. </b>The problem messages are put together (by Level 2 below) in a plain text
way, but with a little formatting included: in particular, they contain
HTML-style <code class="display"><span class="extract">&lt;i&gt;</span></code>, <code class="display"><span class="extract">&lt;b&gt;</span></code> and <code class="display"><span class="extract">&lt;span&gt;</span></code> tags, which the following code strips
out when writing to plain text format.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">In plain text mode, remove bold and italic HTML tags</span> <span class="cwebmacronumber">5.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">html_flag</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">c</span><span class="plain"> == </span><span class="constant">PROTECTED_LT_CHAR</span><span class="plain">) {</span>
<span class="reserved">while</span><span class="plain"> ((</span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">L</span><span class="plain">) &amp;&amp; (</span><span class="identifier">Str::get_at</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">) != </span><span class="constant">PROTECTED_GT_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">c</span><span class="plain"> == </span><span class="character">'&lt;'</span><span class="plain">) &amp;&amp;</span>
<span class="plain">((</span><span class="identifier">Str::includes_wide_string_at_insensitive</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"&lt;i&gt;"</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">)) ||</span>
<span class="plain">(</span><span class="identifier">Str::includes_wide_string_at_insensitive</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"&lt;b&gt;"</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">)) ||</span>
<span class="plain">(</span><span class="identifier">Str::includes_wide_string_at_insensitive</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"&lt;img&gt;"</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">)) ||</span>
<span class="plain">(</span><span class="identifier">Str::includes_wide_string_at_insensitive</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"&lt;a&gt;"</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">)) ||</span>
<span class="plain">(</span><span class="identifier">Str::includes_wide_string_at_insensitive</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"&lt;font&gt;"</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">)) ||</span>
<span class="plain">(</span><span class="identifier">Str::includes_wide_string_at_insensitive</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"&lt;i "</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">)) ||</span>
<span class="plain">(</span><span class="identifier">Str::includes_wide_string_at_insensitive</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"&lt;b "</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">)) ||</span>
<span class="plain">(</span><span class="identifier">Str::includes_wide_string_at_insensitive</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"&lt;img "</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">)) ||</span>
<span class="plain">(</span><span class="identifier">Str::includes_wide_string_at_insensitive</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"&lt;a "</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">)) ||</span>
<span class="plain">(</span><span class="identifier">Str::includes_wide_string_at_insensitive</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"&lt;font "</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">)) ||</span>
<span class="plain">(</span><span class="identifier">Str::includes_wide_string_at_insensitive</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"&lt;span "</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">)) ||</span>
<span class="plain">(</span><span class="identifier">Str::includes_wide_string_at_insensitive</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"&lt;/i&gt;"</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">)) ||</span>
<span class="plain">(</span><span class="identifier">Str::includes_wide_string_at_insensitive</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"&lt;/b&gt;"</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">)) ||</span>
<span class="plain">(</span><span class="identifier">Str::includes_wide_string_at_insensitive</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"&lt;/img&gt;"</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">)) ||</span>
<span class="plain">(</span><span class="identifier">Str::includes_wide_string_at_insensitive</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"&lt;/a&gt;"</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">)) ||</span>
<span class="plain">(</span><span class="identifier">Str::includes_wide_string_at_insensitive</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"&lt;/span&gt;"</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">)) ||</span>
<span class="plain">(</span><span class="identifier">Str::includes_wide_string_at_insensitive</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"&lt;/font&gt;"</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">)))) {</span>
<span class="reserved">while</span><span class="plain"> ((</span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">L</span><span class="plain">) &amp;&amp; (</span><span class="identifier">Str::get_at</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">) != </span><span class="character">'&gt;'</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>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5">&#167;5</a>.</p>
<p class="inwebparagraph"><a id="SP5_3"></a><b>&#167;5.3. </b>Okay, so the format for a source reference here is:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">XparaphraseXfilenameXnumberX</span>
</pre>
<p class="inwebparagraph">e.g., <code class="display"><span class="extract">Xmain textXsource/story.niX102</span></code>, where <code class="display"><span class="extract">X</span></code> is the unprintable
<code class="display"><span class="extract">SOURCE_REF_CHAR</span></code>. The counter <code class="display"><span class="extract">i</span></code> is at the first <code class="display"><span class="extract">X</span></code>, and we must now
convert this to something fit for printing to <code class="display"><span class="extract">stdout</span></code>, finishing up with <code class="display"><span class="extract">i</span></code>
pointing to the last <code class="display"><span class="extract">X</span></code>.
</p>
<p class="inwebparagraph">We always use the paraphrase, not the filename, on <code class="display"><span class="extract">stdout</span></code> because (i) that's
slightly easier to understand for the user, but more importantly (ii) it
makes the output the same on all platforms when only main text and Standard
Rules are referred to, and that simplifies <code class="display"><span class="extract">intest</span></code> and the Test Suite quite
a bit, because we don't have to worry about trivial differences between OS X
and Windows caused by the slashes going the wrong way, and so on.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Issue plain text paraphrase of source reference</span> <span class="cwebmacronumber">5.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"("</span><span class="plain">); </span><span class="identifier">line_width</span><span class="plain">++;</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">Str::get_at</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, ++</span><span class="identifier">i</span><span class="plain">) != </span><span class="constant">SOURCE_REF_CHAR</span><span class="plain">) </span>&lt;<span class="cwebmacro">Output single character of problem message</span> <span class="cwebmacronumber">5.4</span>&gt;<span class="plain">;</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">Str::get_at</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, ++</span><span class="identifier">i</span><span class="plain">) != </span><span class="constant">SOURCE_REF_CHAR</span><span class="plain">) ;</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">", line "</span><span class="plain">); </span><span class="identifier">line_width</span><span class="plain"> += 7;</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">Str::get_at</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, ++</span><span class="identifier">i</span><span class="plain">) != </span><span class="constant">SOURCE_REF_CHAR</span><span class="plain">) </span>&lt;<span class="cwebmacro">Output single character of problem message</span> <span class="cwebmacronumber">5.4</span>&gt;<span class="plain">;</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">")"</span><span class="plain">); </span><span class="identifier">line_width</span><span class="plain">++;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5">&#167;5</a>.</p>
<p class="inwebparagraph"><a id="SP5_4"></a><b>&#167;5.4. </b><code class="display">
&lt;<span class="cwebmacrodefn">Output single character of problem message</span> <span class="cwebmacronumber">5.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">c</span><span class="plain"> = </span><span class="identifier">Str::get_at</span><span class="plain">(</span><span class="identifier">PBUFF</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">Characters::is_whitespace</span><span class="plain">(</span><span class="identifier">c</span><span class="plain">)) { </span> <span class="comment">this starts a run of whitespace</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">l</span><span class="plain"> = </span><span class="identifier">i</span><span class="plain">; </span><span class="reserved">while</span><span class="plain"> (</span><span class="identifier">Characters::is_whitespace</span><span class="plain">(</span><span class="identifier">Str::get_at</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="identifier">l</span><span class="plain">))) </span><span class="identifier">l</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::get_at</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="identifier">l</span><span class="plain">) == 0) </span><span class="reserved">break</span><span class="plain">; </span> <span class="comment">omit any trailing spaces</span>
<span class="identifier">i</span><span class="plain"> = </span><span class="identifier">l</span><span class="plain"> - 1; </span> <span class="comment">skip to final whitespace character of the run</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">html_flag</span><span class="plain">) </span><span class="identifier">PROBLEMS_HTML_EMITTER</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="character">' '</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span>&lt;<span class="cwebmacro">In plain text mode, wrap the line or print a space as necessary</span> <span class="cwebmacronumber">5.4.1</span>&gt;<span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">line_width</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="constant">PROTECTED_LT_CHAR</span><span class="plain">) </span><span class="identifier">PUT</span><span class="plain">(</span><span class="character">'&lt;'</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">c</span><span class="plain"> == </span><span class="constant">PROTECTED_GT_CHAR</span><span class="plain">) </span><span class="identifier">PUT</span><span class="plain">(</span><span class="character">'&gt;'</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">html_flag</span><span class="plain">) </span><span class="identifier">PROBLEMS_HTML_EMITTER</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">c</span><span class="plain">);</span>
<span class="reserved">else</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="constant">SOURCE_REF_CHAR</span><span class="plain">) &amp;&amp; (</span><span class="identifier">c</span><span class="plain"> != </span><span class="constant">FORCE_NEW_PARA_CHAR</span><span class="plain">)) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%c"</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="#SP5">&#167;5</a>, <a href="#SP5_3">&#167;5.3</a> (twice).</p>
<p class="inwebparagraph"><a id="SP5_4_1"></a><b>&#167;5.4.1. </b>At this point, <code class="display"><span class="extract">l</span></code> is the position of the first non-whitespace character
after the sequence of whitespace.
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">PROBLEM_WORD_WRAP_WIDTH</span><span class="plain"> 80</span>
</pre>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">In plain text mode, wrap the line or print a space as necessary</span> <span class="cwebmacronumber">5.4.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">word_width</span><span class="plain"> = 0;</span>
<span class="reserved">while</span><span class="plain"> ((!</span><span class="identifier">Characters::is_whitespace</span><span class="plain">(</span><span class="identifier">Str::get_at</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="identifier">l</span><span class="plain">))) &amp;&amp; (</span><span class="identifier">Str::get_at</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="identifier">l</span><span class="plain">) != 0)</span>
<span class="plain">&amp;&amp; (</span><span class="identifier">Str::get_at</span><span class="plain">(</span><span class="identifier">PBUFF</span><span class="plain">, </span><span class="identifier">l</span><span class="plain">) != </span><span class="constant">SOURCE_REF_CHAR</span><span class="plain">))</span>
<span class="identifier">l</span><span class="plain">++, </span><span class="identifier">word_width</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">line_width</span><span class="plain"> + </span><span class="identifier">word_width</span><span class="plain"> + 1 &gt;= </span><span class="constant">PROBLEM_WORD_WRAP_WIDTH</span><span class="plain">) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"\</span><span class="plain">n</span><span class="string">"</span><span class="plain">); </span><span class="identifier">line_width</span><span class="plain"> = 0;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">l</span><span class="plain">=0; </span><span class="identifier">l</span><span class="plain">&lt;</span><span class="identifier">indentation</span><span class="plain">+1; </span><span class="identifier">l</span><span class="plain">++) { </span><span class="identifier">line_width</span><span class="plain">+=2; </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" "</span><span class="plain">); }</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" "</span><span class="plain">); </span><span class="identifier">line_width</span><span class="plain">++;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5_4">&#167;5.4</a>.</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. </b>The following handles the three-way distribution of problems, but also
allows us to route individual messages to only one output of our choice by
temporarily setting the <code class="display"><span class="extract">probl</span></code> variable: which is a convenience for
informational messages such as appear in index files, for instance.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::Buffer::redirect_problem_stream</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">) {</span>
<span class="identifier">probl</span><span class="plain"> = </span><span class="identifier">S</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">telemetry_recording</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::Buffer::output_problem_buffer</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">indentation</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">probl</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
<span class="functiontext">Problems::Buffer::output_problem_buffer_to</span><span class="plain">(</span><span class="identifier">problems_file</span><span class="plain">, </span><span class="identifier">indentation</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">problems_file</span><span class="plain">, </span><span class="string">"\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
<span class="functiontext">Problems::Buffer::output_problem_buffer_to</span><span class="plain">(</span><span class="identifier">STDERR</span><span class="plain">, </span><span class="identifier">indentation</span><span class="plain">);</span>
<span class="identifier">STREAM_FLUSH</span><span class="plain">(</span><span class="identifier">STDERR</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">DL</span><span class="plain">, </span><span class="string">"\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
<span class="functiontext">Problems::Buffer::output_problem_buffer_to</span><span class="plain">(</span><span class="identifier">DL</span><span class="plain">, </span><span class="identifier">indentation</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">DL</span><span class="plain">, </span><span class="string">"\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">telemetry_recording</span><span class="plain">) {</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">telmy</span><span class="plain">, </span><span class="string">"\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
<span class="functiontext">Problems::Buffer::output_problem_buffer_to</span><span class="plain">(</span><span class="identifier">telmy</span><span class="plain">, </span><span class="identifier">indentation</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">telmy</span><span class="plain">, </span><span class="string">"\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="functiontext">Problems::Buffer::output_problem_buffer_to</span><span class="plain">(</span><span class="identifier">probl</span><span class="plain">, </span><span class="identifier">indentation</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Problems::Buffer::redirect_problem_stream appears nowhere else.</p>
<p class="endnote">The function Problems::Buffer::output_problem_buffer is used in 2/pl2 (<a href="2-pl2.html#SP3_1">&#167;3.1</a>, <a href="2-pl2.html#SP9">&#167;9</a>).</p>
<hr class="tocbar">
<ul class="toc"><li><a href="2-pl0.html">Back to 'Problems, Level 0'</a></li><li><a href="2-pl2.html">Continue with 'Problems, Level 2'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>