<!--Weave of 'What This Module Does' generated by Inweb-->
<divclass="breadcrumbs">
<ulclass="crumbs"><li><ahref="../index.html">Home</a></li><li><ahref="../compiler.html">Services</a></li><li><ahref="index.html">problems</a></li><li><ahref="index.html#P">Preliminaries</a></li><li><b>What This Module Does</b></li></ul></div>
<pclass="purpose">An overview of the problems module's role and abilities.</p>
<ulclass="toc"><li><ahref="P-wtmd.html#SP1">§1. Prerequisites</a></li><li><ahref="P-wtmd.html#SP2">§2. Problems and their sigils</a></li><li><ahref="P-wtmd.html#SP4">§4. The story of a non-fatal problem message</a></li><li><ahref="P-wtmd.html#SP10">§10. Telemetry</a></li></ul><hrclass="tocbar">
<pclass="commentary firstcommentary"><aid="SP1"class="paragraph-anchor"></a><b>§1. Prerequisites. </b>The problems module is a part of the Inform compiler toolset. It is
presented as a literate program or "web". Before diving in:
</p>
<ulclass="items"><li>(a) It helps to have some experience of reading webs: see <ahref="../../../inweb/docs/index.html"class="internal">inweb</a> for more.
</li><li>(b) The module is written in C, in fact ANSI C99, but this is disguised by the
fact that it uses some extension syntaxes provided by the <ahref="../../../inweb/docs/index.html"class="internal">inweb</a> literate
programming tool, making it a dialect of C called InC. See <ahref="../../../inweb/docs/index.html"class="internal">inweb</a> for
full details, but essentially: it's C without predeclarations or header files,
and where functions have names like <spanclass="extract"><spanclass="extract-syntax">Tags::add_by_name</span></span> rather than <spanclass="extract"><spanclass="extract-syntax">add_by_name</span></span>.
</li><li>(c) This module uses other modules drawn from the <ahref="../compiler.html"class="internal">compiler</a>, and also
uses a module of utility functions called <ahref="../../../inweb/docs/foundation-module/index.html"class="internal">foundation</a>.
For more, see <ahref="../../../inweb/docs/foundation-module/P-abgtf.html"class="internal">A Brief Guide to Foundation (in foundation)</a>.
<pclass="commentary firstcommentary"><aid="SP2"class="paragraph-anchor"></a><b>§2. Problems and their sigils. </b>The task of this module is to issue error messages which may be lengthy and
<pclass="commentary">Sigils are <spanclass="extract"><spanclass="extract-syntax">char *</span></span> constants. The Inform modules use the following naming
conventions for sigils:
</p>
<ulclass="items"><li>(a) A problem which is thought never to be generated has the sigil
<spanclass="extract"><spanclass="extract-syntax">BelievedImpossible</span></span>. Inform is quite defensively coded, so there are several
dozen of these — they are safety nets to catch cases we didn't think of.
</li><li>(b) A problem which either cannot be tested by <ahref="../../../intest/docs/index.html"class="internal">intest</a>, or is just
impracticable to do so, has the sigil <spanclass="extract"><spanclass="extract-syntax">Untestable</span></span>.
</li><li>(c) A problem which can be tested, but for which nobody has yet written a
test case, has the sigil <spanclass="extract"><spanclass="extract-syntax">...</span></span>.
</li><li>(d) Otherwise a problem should have a unique alphanumeric name beginning with
<spanclass="extract"><spanclass="extract-syntax">PM_</span></span>, for "problem message": for example, <spanclass="extract"><spanclass="extract-syntax">PM_NoSuchHieroglyph</span></span>. This should
be the same name as that of the test case which exercises it.
</li></ul>
<pclass="commentary">Because sigils correspond to test case names, they also have to follow the
conventions on test case naming: in particular, the suffix <spanclass="extract"><spanclass="extract-syntax">-G</span></span> means "for
the Glulx virtual machine only", and similarly for <spanclass="extract"><spanclass="extract-syntax">-Z</span></span>.
<pclass="commentary firstcommentary"><aid="SP3"class="paragraph-anchor"></a><b>§3. </b>In general problems are a bad thing, of course, but a call to
<ahref="2-pl0.html#SP3"class="internal">ProblemSigils::require</a> tells <ahref="index.html"class="internal">problems</a> that the parent tool positively
<pclass="commentary">The parent can also configure <ahref="index.html"class="internal">problems</a> by calling <ahref="2-pl0.html#SP4"class="internal">ProblemSigils::echo_sigils</a>
or <ahref="2-pl0.html#SP5"class="internal">ProblemSigils::crash_on_problems</a>.
<pclass="commentary firstcommentary"><aid="SP4"class="paragraph-anchor"></a><b>§4. The story of a non-fatal problem message. </b>Suppose that the <ahref="../core-module/index.html"class="internal">core</a> module wants to issue a problem message: what
<spanclass="plain-syntax"></span><spanclass="string-syntax">"Inform does not support standing desks"</span><spanclass="plain-syntax">,</span>
<spanclass="plain-syntax"></span><spanclass="string-syntax">"and needs your laptop to be lower than your ribcage at all times."</span><spanclass="plain-syntax">);</span>
</pre>
<pclass="commentary">The sigil for this (hypothetical) problem message is <spanclass="extract"><spanclass="extract-syntax">PM_BadDesk</span></span>, and note the
use of the <spanclass="extract"><spanclass="extract-syntax">_p_</span></span> macro to refer to it: see <ahref="2-pl0.html"class="internal">Problems, Level 0</a> for more. The
first piece of text is always produced, and the second added only on the first
occurrence. <ahref="../core-module/index.html"class="internal">core</a> doesn't need to do anything more than make this one
function call to Level 3, and <ahref="index.html"class="internal">problems</a> does everything else.
</p>
<pclass="commentary">But a significant number of problems are less standard in shape and are
called "handmade", meaning that <ahref="../core-module/index.html"class="internal">core</a> has to call some Level 2 functions.
<pclass="commentary">What happens, in sequence, is that we
</p>
<ulclass="items"><li>(a) Establish what material should go into the placeholders <spanclass="extract"><spanclass="extract-syntax">%1</span></span> and <spanclass="extract"><spanclass="extract-syntax">%2</span></span>,
</li><li>(b) Call <ahref="2-pl3.html#SP10"class="internal">StandardProblems::handmade_problem</a> to begin work,
</li><li>(c) Call <ahref="2-pl2.html#SP12"class="internal">Problems::issue_problem_segment</a> a number of times — though often
just once — to put some text into the problem, and
</li><li>(d) Call <ahref="2-pl2.html#SP9"class="internal">Problems::issue_problem_end</a> to signal that we are done.
<pclass="commentary firstcommentary"><aid="SP5"class="paragraph-anchor"></a><b>§5. </b>As this demonstrates, problem messages are expanded from prototypes using
a <spanclass="extract"><spanclass="extract-syntax">printf</span></span>-like formatting system. Unlike <spanclass="extract"><spanclass="extract-syntax">printf</span></span>, though, where <spanclass="extract"><spanclass="extract-syntax">%s</span></span> means
a string and <spanclass="extract"><spanclass="extract-syntax">%d</span></span> a number, here the escape codes do not indicate the type of
the data: they are simply <spanclass="extract"><spanclass="extract-syntax">%1</span></span>, <spanclass="extract"><spanclass="extract-syntax">%2</span></span>, <spanclass="extract"><spanclass="extract-syntax">%3</span></span>, ..., <spanclass="extract"><spanclass="extract-syntax">%9</span></span>. 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>
<pclass="commentary">The placeholders do not need to be used contiguously — if you want to use
just <spanclass="extract"><spanclass="extract-syntax">%4</span></span> and <spanclass="extract"><spanclass="extract-syntax">%7</span></span>, feel free.
</p>
<pclass="commentary">Four further escape codes switch between problem message versions, as follows:
</p>
<ulclass="items"><li>●<spanclass="extract"><spanclass="extract-syntax">%L</span></span> means "long form", the version used the first time this message is
generated,
</li><li>●<spanclass="extract"><spanclass="extract-syntax">%S</span></span> means "short form", for subsequent times,
</li><li>●<spanclass="extract"><spanclass="extract-syntax">%A</span></span> means "both long and short", which is the situation at the start,
</li></ul>
<pclass="commentary">Note that the form is reset to <spanclass="extract"><spanclass="extract-syntax">%A</span></span> when a new problem message begins, but not
in between calls to <ahref="2-pl2.html#SP12"class="internal">Problems::issue_problem_segment</a>: i.e., if one segment
leaves things in <spanclass="extract"><spanclass="extract-syntax">%L</span></span>, the next segment, if there is one, resumes that way.
</p>
<pclass="commentary">For example, <spanclass="extract"><spanclass="extract-syntax">"You wrote %1: %Sagain, %2.%Lbut %2, %3"</span></span> is the message
text used by <ahref="2-pl3.html#SP14"class="internal">StandardProblems::sentence_problem</a>.
<spanclass="plain-syntax"> "You wrote %1: %Sagain, %2.%Lbut %2, %3"</span>
<spanclass="plain-syntax"> on first use --> "You wrote %1: but %2, %3"</span>
<spanclass="plain-syntax"> subsequently --> "You wrote %1: again, %2."</span>
</pre>
<pclass="commentary">Here the punctuation; <spanclass="extract"><spanclass="extract-syntax">%3</span></span> is expected to end with a full stop and <spanclass="extract"><spanclass="extract-syntax">%2</span></span> not to.
</p>
<pclass="commentary">Finally, the escape <spanclass="extract"><spanclass="extract-syntax">%P</span></span> means "poragraph break here", and is used for adding
subsequent clarifications to long or complicated problems.
A significant amount of this section also deals with internal errors, that is,
failed assertions; while <ahref="../../../inweb/docs/foundation-module/index.html"class="internal">foundation</a> provides the basic system for handling
those — i.e., print and then exit the program —<ahref="../core-module/index.html"class="internal">core</a> redirects all
internal errors to <ahref="2-pl3.html#SP4"class="internal">StandardProblems::internal_error_fn</a>, which ensures that
they pass through our problems machinery here, and are thus properly recorded
in the HTML problems report in the Inform app (if that's what the user is
<pclass="commentary firstcommentary"><aid="SP7"class="paragraph-anchor"></a><b>§7. </b><ahref="2-pl2.html"class="internal">Problems, Level 2</a> contains functions for making quotations to fill the
placeholders with content — see <ahref="2-pl2.html#SP4"class="internal">problem_quotation</a>.
</p>
<pclass="commentary">The mechanism for determining whether an explanation has been given before is
<ahref="2-pl2.html#SP8"class="internal">Problems::explained_before</a>. The obvious thing would be to go by the sigils
of previously issued messages, but it actually uses the textual token supplied
on the call to <ahref="2-pl2.html#SP9"class="internal">Problems::issue_problem_begin</a>, which allows for some
variations — Level 3 functions are able to use this to ensure that particular
kinds of message are always, or are never, explained.
</p>
<pclass="commentary">As Level 2 generates problem text, it calls down into <ahref="2-pl1.html#SP6"class="internal">ProblemBuffer::output_problem_buffer</a>
at Level 1.
</p>
<pclass="commentary">Just a few functions at Level 2 issue fatal errors — that is, problems which
cause an immediate exit of the program as soon as they are issued, and are
typically used for filing-system disasters or failed assertions (so-called
<pclass="commentary firstcommentary"><aid="SP8"class="paragraph-anchor"></a><b>§8. </b><ahref="2-pl1.html"class="internal">Problems, Level 1</a> is concerned with the "problem buffer" <spanclass="extract"><spanclass="extract-syntax">PBUFF</span></span>.
This is a text used to hold the problem message as it is assembled from pieces,
and only Level 2 functions should print to it. Even they should call down to
two Level 1 functions when they want to write something other than straightforward
text:
</p>
<ulclass="items"><li>● Source text from the lexer can be quoted into it with <ahref="2-pl1.html#SP2"class="internal">ProblemBuffer::copy_text</a>,
which automatically trims excessive quotes for length.
</li><li>● References to positions in the source text can be inserted with
<ahref="2-pl1.html#SP4"class="internal">ProblemBuffer::copy_source_reference</a>: there is a sort of protocol for how
this is done, with use of the magic <spanclass="extract"><spanclass="extract-syntax">SOURCE_REF_CHAR</span></span> which will be
intercepted later on when the problems file is written out as HTML (see
<ahref="../../../inweb/docs/foundation-module/5-htm.html"class="internal">HTML (in foundation)</a> for details).
<pclass="commentary firstcommentary"><aid="SP9"class="paragraph-anchor"></a><b>§9. </b>When a portion of text has been buffered which Level 2 wants to get shot of,
<pclass="commentary firstcommentary"><aid="SP10"class="paragraph-anchor"></a><b>§10. Telemetry. </b>The <ahref="1-tlm.html"class="internal">Telemetry</a> system isn't really to do with problems, except that it