1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-08 10:04:21 +03:00
inform7/docs/index-module/2-dr.html

485 lines
57 KiB
HTML
Raw Normal View History

2020-02-27 03:43:11 +02:00
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>2/ifs</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/dr' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">index</a></li><li><a href="index.html#2">Chapter 2: Indexing</a></li><li><b>Documentation References</b></li></ul><p class="purpose">To enable index or results pages to link into documentation.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Definitions</a></li><li><a href="#SP12">&#167;12. Fragments</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Definitions. </b></p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>Documentation is arranged in a series of HTML pages identified by
section number 0, 1, 2, ..., and the index contains little blue help
icons which link into this. In order to give these links the correct
destinations, Inform needs to know which section number contains what:
but section numbering moves around a lot as the documentation is
written.
</p>
<p class="inwebparagraph">To avoid needlessly recompiling Inform when documentation changes, we
give certain sections aliases called "symbols" which are rather
more lasting than the section numbering. These are read in from a file
of cross-references generated by Indoc.
</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">documentation_ref</span><span class="plain"> {</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">doc_symbol</span><span class="plain">; </span> <span class="comment">Reference is by this piece of text</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">section</span><span class="plain">; </span> <span class="comment">HTML page number</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">used_already</span><span class="plain">; </span> <span class="comment">Has this been used in a problem message already?</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">usage_count</span><span class="plain">; </span> <span class="comment">For statistical purposes</span>
<span class="reserved">char</span><span class="plain"> *</span><span class="identifier">fragment_at</span><span class="plain">; </span> <span class="comment">Pointer to HTML documentation fragment in memory</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">fragment_length</span><span class="plain">; </span> <span class="comment">Number of bytes of fragment</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">sr_usage_count</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">ext_usage_count</span><span class="plain">;</span>
<span class="identifier">wchar_t</span><span class="plain"> *</span><span class="identifier">chapter_reference</span><span class="plain">; </span> <span class="comment">Or <code class="display"><span class="extract">NULL</span></code> if no chapter name supplied</span>
<span class="identifier">wchar_t</span><span class="plain"> *</span><span class="identifier">section_reference</span><span class="plain">; </span> <span class="comment">Or <code class="display"><span class="extract">NULL</span></code> if no section name supplied</span>
<span class="identifier">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">documentation_ref</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The structure documentation_ref is private to this section.</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b></p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">DOCUMENTATION_REFERENCES_PRESENT</span>
</pre>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>The blue query icons link to pages in the documentation, as described above.
Documentation references are used to match the documentation text against
the compiler so that each can be changed independently of the other.
First, here's the code to read the Indoc-generated cross-references. The
file is read on demand; in some runs, it won't be needed.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">xrefs_read</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">Index::DocReferences::read_xrefs</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">xrefs_read</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<span class="identifier">xrefs_read</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">TextFiles::read</span><span class="plain">(</span><span class="identifier">Inbuild::file_from_installation</span><span class="plain">(</span><span class="identifier">DOCUMENTATION_XREFS_IRES</span><span class="plain">), </span><span class="identifier">TRUE</span><span class="plain">,</span>
<span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="functiontext">Index::DocReferences::read_xrefs_helper</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">NULL</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">Index::DocReferences::read_xrefs_helper</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">line</span><span class="plain">,</span>
<span class="identifier">text_file_position</span><span class="plain"> *</span><span class="identifier">tfp</span><span class="plain">, </span><span class="reserved">void</span><span class="plain"> *</span><span class="identifier">unused_state</span><span class="plain">) {</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">line</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">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain"> = </span><span class="identifier">Feeds::feed_stream</span><span class="plain">(</span><span class="identifier">line</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::length</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">) &lt; 2) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">from</span><span class="plain"> = -1;</span>
<span class="identifier">LOOP_THROUGH_WORDING</span><span class="plain">(</span><span class="identifier">i</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">Lexer::word</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">) == </span><span class="identifier">UNDERSCORE_V</span><span class="plain">) </span><span class="identifier">from</span><span class="plain"> = </span><span class="identifier">i</span><span class="plain">+1;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">from</span><span class="plain"> == -1) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"malformed cross-references file"</span><span class="plain">);</span>
<span class="identifier">wchar_t</span><span class="plain"> *</span><span class="identifier">chap</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">sect</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">Wordings::last_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">) &gt;= </span><span class="identifier">from</span><span class="plain">+1) &amp;&amp; (</span><span class="identifier">Vocabulary::test_flags</span><span class="plain">(</span><span class="identifier">from</span><span class="plain">+1, </span><span class="identifier">TEXT_MC</span><span class="plain">))) {</span>
<span class="identifier">Word::dequote</span><span class="plain">(</span><span class="identifier">from</span><span class="plain">+1);</span>
<span class="identifier">chap</span><span class="plain"> = </span><span class="identifier">Lexer::word_text</span><span class="plain">(</span><span class="identifier">from</span><span class="plain">+1);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Wordings::last_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">) &gt;= </span><span class="identifier">from</span><span class="plain">+2) &amp;&amp; (</span><span class="identifier">Vocabulary::test_flags</span><span class="plain">(</span><span class="identifier">from</span><span class="plain">+2, </span><span class="identifier">TEXT_MC</span><span class="plain">))) {</span>
<span class="identifier">Word::dequote</span><span class="plain">(</span><span class="identifier">from</span><span class="plain">+2);</span>
<span class="identifier">sect</span><span class="plain"> = </span><span class="identifier">Lexer::word_text</span><span class="plain">(</span><span class="identifier">from</span><span class="plain">+2);</span>
<span class="plain">}</span>
<span class="identifier">LOOP_THROUGH_WORDING</span><span class="plain">(</span><span class="identifier">i</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">i</span><span class="plain"> == </span><span class="identifier">from</span><span class="plain">) </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">documentation_ref</span><span class="plain"> *</span><span class="identifier">dr</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">documentation_ref</span><span class="plain">);</span>
<span class="identifier">dr</span><span class="plain">-</span><span class="element">&gt;doc_symbol</span><span class="plain"> = </span><span class="identifier">Str::new</span><span class="plain">();</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">dr</span><span class="plain">-</span><span class="element">&gt;doc_symbol</span><span class="plain">, </span><span class="string">"%+W"</span><span class="plain">, </span><span class="identifier">Wordings::one_word</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">));</span>
<span class="identifier">dr</span><span class="plain">-</span><span class="element">&gt;section</span><span class="plain"> = </span><span class="identifier">from</span><span class="plain">;</span>
<span class="identifier">dr</span><span class="plain">-</span><span class="element">&gt;used_already</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">dr</span><span class="plain">-</span><span class="element">&gt;usage_count</span><span class="plain"> = 0;</span>
<span class="identifier">dr</span><span class="plain">-</span><span class="element">&gt;sr_usage_count</span><span class="plain"> = 0;</span>
<span class="identifier">dr</span><span class="plain">-</span><span class="element">&gt;ext_usage_count</span><span class="plain"> = 0;</span>
<span class="identifier">dr</span><span class="plain">-</span><span class="element">&gt;chapter_reference</span><span class="plain"> = </span><span class="identifier">chap</span><span class="plain">;</span>
<span class="identifier">dr</span><span class="plain">-</span><span class="element">&gt;section_reference</span><span class="plain"> = </span><span class="identifier">sect</span><span class="plain">;</span>
<span class="identifier">dr</span><span class="plain">-</span><span class="element">&gt;fragment_at</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">dr</span><span class="plain">-</span><span class="element">&gt;fragment_length</span><span class="plain"> = 0;</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Index::DocReferences::read_xrefs is used in <a href="#SP5">&#167;5</a>, <a href="#SP6">&#167;6</a>, <a href="#SP9">&#167;9</a>, <a href="#SP10">&#167;10</a>, <a href="#SP13">&#167;13</a>, <a href="#SP13_1">&#167;13.1</a>.</p>
<p class="endnote">The function Index::DocReferences::read_xrefs_helper appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b>The following routine is used to verify that a given text is, or is not,
a valid documentation reference symbol. (For instance, we might look up
<code class="display"><span class="extract">kind_vehicle</span></code> to see if any section of documentation has been flagged
as giving information on vehicles.) If our speculative link symbol exists,
we return the leafname for this documentation page, without filename
extension (say <code class="display"><span class="extract">doc24</span></code>); if it does not exist, we return NULL.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Index::DocReferences::validate_if_possible</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">temp</span><span class="plain">) {</span>
<span class="functiontext">Index::DocReferences::read_xrefs</span><span class="plain">();</span>
<span class="reserved">documentation_ref</span><span class="plain"> *</span><span class="identifier">dr</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">dr</span><span class="plain">, </span><span class="reserved">documentation_ref</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::eq</span><span class="plain">(</span><span class="identifier">dr</span><span class="plain">-</span><span class="element">&gt;doc_symbol</span><span class="plain">, </span><span class="identifier">temp</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">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="endnote">The function Index::DocReferences::validate_if_possible appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. </b>And similarly, returning the page we link to:
</p>
<pre class="display">
<span class="identifier">wchar_t</span><span class="plain"> *</span><span class="functiontext">Index::DocReferences::link_if_possible_once</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">temp</span><span class="plain">, </span><span class="identifier">wchar_t</span><span class="plain"> **</span><span class="identifier">chap</span><span class="plain">, </span><span class="identifier">wchar_t</span><span class="plain"> **</span><span class="identifier">sec</span><span class="plain">) {</span>
<span class="functiontext">Index::DocReferences::read_xrefs</span><span class="plain">();</span>
<span class="reserved">documentation_ref</span><span class="plain"> *</span><span class="identifier">dr</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">dr</span><span class="plain">, </span><span class="reserved">documentation_ref</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::eq</span><span class="plain">(</span><span class="identifier">dr</span><span class="plain">-</span><span class="element">&gt;doc_symbol</span><span class="plain">, </span><span class="identifier">temp</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">dr</span><span class="plain">-</span><span class="element">&gt;used_already</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<span class="identifier">wchar_t</span><span class="plain"> *</span><span class="identifier">leaf</span><span class="plain"> = </span><span class="identifier">Lexer::word_text</span><span class="plain">(</span><span class="identifier">dr</span><span class="plain">-</span><span class="element">&gt;section</span><span class="plain">);</span>
<span class="plain">*</span><span class="identifier">chap</span><span class="plain"> = </span><span class="identifier">dr</span><span class="plain">-</span><span class="element">&gt;chapter_reference</span><span class="plain">;</span>
<span class="plain">*</span><span class="identifier">sec</span><span class="plain"> = </span><span class="identifier">dr</span><span class="plain">-</span><span class="element">&gt;section_reference</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">dr</span><span class="plain">, </span><span class="reserved">documentation_ref</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wide::cmp</span><span class="plain">(</span><span class="identifier">leaf</span><span class="plain">, </span><span class="identifier">Lexer::word_text</span><span class="plain">(</span><span class="identifier">dr</span><span class="plain">-</span><span class="element">&gt;section</span><span class="plain">)) == 0)</span>
<span class="identifier">dr</span><span class="plain">-</span><span class="element">&gt;used_already</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">leaf</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Index::DocReferences::link_if_possible_once appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. </b>In the Standard Rules, a number of phrases (and other constructs) are
defined along with markers to sections in the documentation: here we parse
these markers, returning either the word number of the documentation symbol
in question, or -1 if there is none. Since this is used only with the
Standard Rules, which are in English, there's no point in translating it
to other natural languages.
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">documentation</span><span class="plain">-</span><span class="identifier">symbol</span><span class="plain">-</span><span class="identifier">tail</span><span class="plain">&gt; ::=</span>
<span class="plain">... ( &lt;</span><span class="identifier">documentation</span><span class="plain">-</span><span class="identifier">symbol</span><span class="plain">&gt; ) | ==&gt; </span><span class="identifier">R</span><span class="plain">[1]</span>
<span class="plain">... -- &lt;</span><span class="identifier">documentation</span><span class="plain">-</span><span class="identifier">symbol</span><span class="plain">&gt; -- ==&gt; </span><span class="identifier">R</span><span class="plain">[1]</span>
<span class="plain">&lt;</span><span class="identifier">documentation</span><span class="plain">-</span><span class="identifier">symbol</span><span class="plain">&gt; ::=</span>
<span class="identifier">documented</span><span class="plain"> </span><span class="identifier">at</span><span class="plain"> ### ==&gt; </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">WR</span><span class="plain">[1])</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. </b></p>
<pre class="display">
<span class="identifier">wording</span><span class="plain"> </span><span class="functiontext">Index::DocReferences::position_of_symbol</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"> (&lt;</span><span class="identifier">documentation</span><span class="plain">-</span><span class="identifier">symbol</span><span class="plain">-</span><span class="identifier">tail</span><span class="plain">&gt;(*</span><span class="identifier">W</span><span class="plain">)) {</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">documentation</span><span class="plain">-</span><span class="identifier">symbol</span><span class="plain">-</span><span class="identifier">tail</span><span class="plain">&gt;, 1);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">Wordings::one_word</span><span class="plain">(&lt;&lt;</span><span class="identifier">r</span><span class="plain">&gt;&gt;);</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Index::DocReferences::position_of_symbol appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. </b>It's convenient to associate a usage count to each symbol, since every
built-in documented phrase has a symbol. Every time Inform successfully uses
such a phrase, it increments the usage count by calling the following:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Index::DocReferences::doc_mark_used</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">symb</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">at_word</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Log::aspect_switched_on</span><span class="plain">(</span><span class="identifier">PHRASE_USAGE_DA</span><span class="plain">)) {</span>
<span class="functiontext">Index::DocReferences::read_xrefs</span><span class="plain">();</span>
<span class="reserved">documentation_ref</span><span class="plain"> *</span><span class="identifier">dr</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">dr</span><span class="plain">, </span><span class="reserved">documentation_ref</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::eq</span><span class="plain">(</span><span class="identifier">dr</span><span class="plain">-</span><span class="element">&gt;doc_symbol</span><span class="plain">, </span><span class="identifier">symb</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">at_word</span><span class="plain"> &gt;= 0) {</span>
<span class="identifier">source_file</span><span class="plain"> *</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">at_word</span><span class="plain">);</span>
2020-03-11 02:21:09 +02:00
<span class="identifier">inform_extension</span><span class="plain"> *</span><span class="identifier">loc</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>
2020-02-27 03:43:11 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">loc</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">dr</span><span class="plain">-</span><span class="element">&gt;usage_count</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">Extensions::is_standard</span><span class="plain">(</span><span class="identifier">loc</span><span class="plain">)) </span><span class="identifier">dr</span><span class="plain">-</span><span class="element">&gt;sr_usage_count</span><span class="plain">++;</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">dr</span><span class="plain">-</span><span class="element">&gt;ext_usage_count</span><span class="plain">++;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">dr</span><span class="plain">-</span><span class="element">&gt;sr_usage_count</span><span class="plain">++;</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"unable to update usage count"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Index::DocReferences::doc_mark_used appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. </b>The following dumps the result. This is not useful for a single run,
especially, but to be accumulated over a whole corpus of source texts, e.g.:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">intest --keep-log=USAGE -log=phrase-usage examples</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Index::DocReferences::log_statistics</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">PHRASE_USAGE</span><span class="plain">, </span><span class="string">"The following shows how often each built-in phrase was used:\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
<span class="functiontext">Index::DocReferences::read_xrefs</span><span class="plain">();</span>
<span class="reserved">documentation_ref</span><span class="plain"> *</span><span class="identifier">dr</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">dr</span><span class="plain">, </span><span class="reserved">documentation_ref</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::begins_with_wide_string</span><span class="plain">(</span><span class="identifier">dr</span><span class="plain">-</span><span class="element">&gt;doc_symbol</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"ph"</span><span class="plain">))</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">PHRASE_USAGE</span><span class="plain">, </span><span class="string">"USAGE: %S %d %d %d\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">dr</span><span class="plain">-</span><span class="element">&gt;doc_symbol</span><span class="plain">,</span>
<span class="identifier">dr</span><span class="plain">-</span><span class="element">&gt;usage_count</span><span class="plain">, </span><span class="identifier">dr</span><span class="plain">-</span><span class="element">&gt;sr_usage_count</span><span class="plain">, </span><span class="identifier">dr</span><span class="plain">-</span><span class="element">&gt;ext_usage_count</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Index::DocReferences::log_statistics appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP11"></a><b>&#167;11. </b>Finally, the blue "see relevant help page" icon links are placed by the
following routine.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Index::DocReferences::link_to</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">fn</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">full</span><span class="plain">) {</span>
<span class="reserved">documentation_ref</span><span class="plain"> *</span><span class="identifier">dr</span><span class="plain"> = </span><span class="functiontext">Index::DocReferences::name_to_dr</span><span class="plain">(</span><span class="identifier">fn</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">dr</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">full</span><span class="plain"> &gt;= 0) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&amp;nbsp;"</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">HTML_OPEN_WITH</span><span class="plain">(</span><span class="string">"a"</span><span class="plain">, </span><span class="string">"href=inform:/%N.html"</span><span class="plain">, </span><span class="identifier">dr</span><span class="plain">-</span><span class="element">&gt;section</span><span class="plain">);</span>
<span class="identifier">HTML_TAG_WITH</span><span class="plain">(</span><span class="string">"img"</span><span class="plain">, </span><span class="string">"border=0 src=inform:/doc_images/help.png"</span><span class="plain">);</span>
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"a"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">full</span><span class="plain"> &gt; 0) &amp;&amp; (</span><span class="identifier">dr</span><span class="plain">-</span><span class="element">&gt;chapter_reference</span><span class="plain">) &amp;&amp; (</span><span class="identifier">dr</span><span class="plain">-</span><span class="element">&gt;section_reference</span><span class="plain">)) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&amp;nbsp;%w. %w"</span><span class="plain">, </span><span class="identifier">dr</span><span class="plain">-</span><span class="element">&gt;chapter_reference</span><span class="plain">, </span><span class="identifier">dr</span><span class="plain">-</span><span class="element">&gt;section_reference</span><span class="plain">);</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">Index::DocReferences::link</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">fn</span><span class="plain">) {</span>
<span class="functiontext">Index::DocReferences::link_to_S</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">fn</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">Index::DocReferences::fully_link</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">fn</span><span class="plain">) {</span>
<span class="functiontext">Index::DocReferences::link_to_S</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">fn</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Index::DocReferences::link_to_S</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">fn</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">full</span><span class="plain">) {</span>
<span class="reserved">documentation_ref</span><span class="plain"> *</span><span class="identifier">dr</span><span class="plain"> = </span><span class="functiontext">Index::DocReferences::name_to_dr</span><span class="plain">(</span><span class="identifier">fn</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">dr</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">full</span><span class="plain"> &gt;= 0) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&amp;nbsp;"</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">HTML_OPEN_WITH</span><span class="plain">(</span><span class="string">"a"</span><span class="plain">, </span><span class="string">"href=inform:/%N.html"</span><span class="plain">, </span><span class="identifier">dr</span><span class="plain">-</span><span class="element">&gt;section</span><span class="plain">);</span>
<span class="identifier">HTML_TAG_WITH</span><span class="plain">(</span><span class="string">"img"</span><span class="plain">, </span><span class="string">"border=0 src=inform:/doc_images/help.png"</span><span class="plain">);</span>
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"a"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">full</span><span class="plain"> &gt; 0) &amp;&amp; (</span><span class="identifier">dr</span><span class="plain">-</span><span class="element">&gt;chapter_reference</span><span class="plain">) &amp;&amp; (</span><span class="identifier">dr</span><span class="plain">-</span><span class="element">&gt;section_reference</span><span class="plain">)) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&amp;nbsp;%w. %w"</span><span class="plain">, </span><span class="identifier">dr</span><span class="plain">-</span><span class="element">&gt;chapter_reference</span><span class="plain">, </span><span class="identifier">dr</span><span class="plain">-</span><span class="element">&gt;section_reference</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Index::DocReferences::link_to appears nowhere else.</p>
<p class="endnote">The function Index::DocReferences::link is used in 2/ifs (<a href="2-ifs.html#SP8">&#167;8</a>), 2/li (<a href="2-li.html#SP8_11_2">&#167;8.11.2</a>).</p>
<p class="endnote">The function Index::DocReferences::fully_link appears nowhere else.</p>
<p class="endnote">The function Index::DocReferences::link_to_S appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP12"></a><b>&#167;12. Fragments. </b>These are short pieces of documentation, which <code class="display"><span class="extract">indoc</span></code> has copied into a special
file so that we can paste them into the index at appropriate places. Note that
if the file can't be found, or contains nothing germane, we fail safe by doing
nothing at all &mdash; not issuing any internal errors.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Index::DocReferences::doc_fragment</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">fn</span><span class="plain">) {</span>
<span class="functiontext">Index::DocReferences::doc_fragment_to</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">fn</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">fragments_loaded</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">Index::DocReferences::doc_fragment_to</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">fn</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">fragments_loaded</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
&lt;<span class="cwebmacro">Load in the documentation fragments file</span> <span class="cwebmacronumber">12.1</span>&gt;<span class="plain">;</span>
<span class="identifier">fragments_loaded</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">documentation_ref</span><span class="plain"> *</span><span class="identifier">dr</span><span class="plain"> = </span><span class="functiontext">Index::DocReferences::name_to_dr</span><span class="plain">(</span><span class="identifier">fn</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">dr</span><span class="plain">) &amp;&amp; (</span><span class="identifier">dr</span><span class="plain">-</span><span class="element">&gt;fragment_at</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="identifier">dr</span><span class="plain">-</span><span class="element">&gt;fragment_at</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">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">dr</span><span class="plain">-</span><span class="element">&gt;fragment_length</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">PUT</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Index::DocReferences::doc_fragment appears nowhere else.</p>
<p class="endnote">The function Index::DocReferences::doc_fragment_to appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP12_1"></a><b>&#167;12.1. </b></p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">MAX_EXTENT_OF_FRAGMENTS</span><span class="plain"> 256*1024</span>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Load in the documentation fragments file</span> <span class="cwebmacronumber">12.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">FILE</span><span class="plain"> *</span><span class="identifier">FRAGMENTS</span><span class="plain"> = </span><span class="identifier">Filenames::fopen</span><span class="plain">(</span><span class="identifier">Inbuild::file_from_installation</span><span class="plain">(</span><span class="identifier">DOCUMENTATION_SNIPPETS_IRES</span><span class="plain">), </span><span class="string">"r"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">FRAGMENTS</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="identifier">Memory::I7_malloc</span><span class="plain">(</span><span class="constant">MAX_EXTENT_OF_FRAGMENTS</span><span class="plain">, </span><span class="identifier">DOC_FRAGMENT_MREASON</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Scan the file into memory, translating from UTF-8</span> <span class="cwebmacronumber">12.1.1</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Work out where the documentation fragments occur</span> <span class="cwebmacronumber">12.1.2</span>&gt;<span class="plain">;</span>
<span class="identifier">fclose</span><span class="plain">(</span><span class="identifier">FRAGMENTS</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP12">&#167;12</a>.</p>
<p class="inwebparagraph"><a id="SP12_1_1"></a><b>&#167;12.1.1. </b>We scan to one long C string:
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Scan the file into memory, translating from UTF-8</span> <span class="cwebmacronumber">12.1.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> = 0;</span>
<span class="identifier">p</span><span class="plain">[0] = 0;</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">TRUE</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">TextFiles::utf8_fgetc</span><span class="plain">(</span><span class="identifier">FRAGMENTS</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">FALSE</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">c</span><span class="plain"> == </span><span class="identifier">EOF</span><span class="plain">) </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">c</span><span class="plain"> == 0</span><span class="identifier">xFEFF</span><span class="plain">) </span><span class="reserved">continue</span><span class="plain">; </span> <span class="comment">the Unicode BOM non-character</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"> == </span><span class="constant">MAX_EXTENT_OF_FRAGMENTS</span><span class="plain">) </span><span class="reserved">break</span><span class="plain">;</span>
<span class="identifier">p</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">++] = (</span><span class="reserved">char</span><span class="plain">) </span><span class="identifier">c</span><span class="plain">;</span>
<span class="identifier">p</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] = 0;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP12_1">&#167;12.1</a>.</p>
<p class="inwebparagraph"><a id="SP12_1_2"></a><b>&#167;12.1.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Work out where the documentation fragments occur</span> <span class="cwebmacronumber">12.1.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> = 0;</span>
<span class="reserved">documentation_ref</span><span class="plain"> *</span><span class="identifier">tracking</span><span class="plain"> = </span><span class="identifier">NULL</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">p</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">p</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] == </span><span class="character">'*'</span><span class="plain">) &amp;&amp; (</span><span class="identifier">p</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">+1] == </span><span class="character">'='</span><span class="plain">)) {</span>
<span class="identifier">i</span><span class="plain"> += 2;</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">rn</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">j</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">=0; </span><span class="identifier">p</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">+</span><span class="identifier">j</span><span class="plain">]; </span><span class="identifier">j</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">i</span><span class="plain">+</span><span class="identifier">j</span><span class="plain">] == </span><span class="character">'='</span><span class="plain">) &amp;&amp; (</span><span class="identifier">p</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">+</span><span class="identifier">j</span><span class="plain">+1] == </span><span class="character">'*'</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="identifier">j</span><span class="plain">+1;</span>
<span class="identifier">tracking</span><span class="plain"> = </span><span class="functiontext">Index::DocReferences::name_to_dr</span><span class="plain">(</span><span class="identifier">rn</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">tracking</span><span class="plain">) </span><span class="identifier">tracking</span><span class="plain">-</span><span class="element">&gt;fragment_at</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">+</span><span class="identifier">i</span><span class="plain">+1;</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">PUT_TO</span><span class="plain">(</span><span class="identifier">rn</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">+</span><span class="identifier">j</span><span class="plain">]);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">rn</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">tracking</span><span class="plain">) </span><span class="identifier">tracking</span><span class="plain">-</span><span class="element">&gt;fragment_length</span><span class="plain">++;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP12_1">&#167;12.1</a>.</p>
<p class="inwebparagraph"><a id="SP13"></a><b>&#167;13. </b>This is a slow search, of course, but the number of DRs is relatively low,
and we need to search fairly seldom:
</p>
<pre class="display">
<span class="reserved">documentation_ref</span><span class="plain"> *</span><span class="functiontext">Index::DocReferences::name_to_dr</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">fn</span><span class="plain">) {</span>
<span class="functiontext">Index::DocReferences::read_xrefs</span><span class="plain">();</span>
<span class="reserved">documentation_ref</span><span class="plain"> *</span><span class="identifier">dr</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">dr</span><span class="plain">, </span><span class="reserved">documentation_ref</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::eq</span><span class="plain">(</span><span class="identifier">dr</span><span class="plain">-</span><span class="element">&gt;doc_symbol</span><span class="plain">, </span><span class="identifier">fn</span><span class="plain">))</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">dr</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Complain about a bad documentation reference</span> <span class="cwebmacronumber">13.1</span>&gt;<span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Index::DocReferences::name_to_dr is used in <a href="#SP11">&#167;11</a>, <a href="#SP12">&#167;12</a>, <a href="#SP12_1_2">&#167;12.1.2</a>.</p>
<p class="inwebparagraph"><a id="SP13_1"></a><b>&#167;13.1. </b>You and I could write a bad reference:
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Complain about a bad documentation reference</span> <span class="cwebmacronumber">13.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_count</span><span class="plain"> == 0) {</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Bad ref was &lt;%S&gt;. Known references are:\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">fn</span><span class="plain">);</span>
<span class="functiontext">Index::DocReferences::read_xrefs</span><span class="plain">();</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">dr</span><span class="plain">, </span><span class="reserved">documentation_ref</span><span class="plain">)</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"%S = %+N\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">dr</span><span class="plain">-</span><span class="element">&gt;doc_symbol</span><span class="plain">, </span><span class="identifier">dr</span><span class="plain">-</span><span class="element">&gt;section</span><span class="plain">);</span>
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"Bad index documentation reference"</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP13">&#167;13</a>.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="2-ifs.html">Back to 'Index File Services'</a></li><li><a href="2-li.html">Continue with 'Lexicon Index'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>