inweb-bootstrap/docs/inweb/4-cl.html

1531 lines
196 KiB
HTML
Raw Normal View History

2019-02-04 22:26:45 +00:00
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>4/pl</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>
2019-02-09 12:33:40 +00:00
<!--Weave of '4/cl' generated by 7-->
2019-02-04 22:26:45 +00:00
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">inweb 7</a></li><li><a href="index.html#4">Chapter 4: Languages</a></li><li><b>C-Like Languages</b></li></ul><p class="purpose">To provide special features for the whole C family of languages.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Creation</a></li><li><a href="#SP2">&#167;2. </a></li><li><a href="#SP3">&#167;3. Parsing</a></li><li><a href="#SP3_2">&#167;3.2. Structures</a></li><li><a href="#SP3_3">&#167;3.3. Structure dependency</a></li><li><a href="#SP3_4">&#167;3.4. Functions</a></li><li><a href="#SP5">&#167;5. Subcategorisation</a></li><li><a href="#SP6">&#167;6. Tangling extras</a></li><li><a href="#SP9">&#167;9. Tangling predeclarations</a></li><li><a href="#SP10">&#167;10. Line markers</a></li><li><a href="#SP11">&#167;11. Comments</a></li><li><a href="#SP13">&#167;13. Ifdefs</a></li><li><a href="#SP14">&#167;14. Before and after expansion</a></li><li><a href="#SP15">&#167;15. Begin weave</a></li><li><a href="#SP16">&#167;16. Syntax colouring</a></li><li><a href="#SP19">&#167;19. Overriding regular code weaving</a></li><li><a href="#SP20">&#167;20. Analysis</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Creation. </b></p>
<pre class="display">
<span class="reserved">programming_language</span><span class="plain"> *</span><span class="functiontext">CLike::create_C</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain"> = </span><span class="functiontext">Languages::new_language</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"C"</span><span class="plain">, </span><span class="identifier">I</span><span class="string">".c"</span><span class="plain">);</span>
<span class="functiontext">CLike::make_c_like</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">pl</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">programming_language</span><span class="plain"> *</span><span class="functiontext">CLike::create_CPP</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain"> = </span><span class="functiontext">Languages::new_language</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"C++"</span><span class="plain">, </span><span class="identifier">I</span><span class="string">".cpp"</span><span class="plain">);</span>
<span class="functiontext">CLike::make_c_like</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">pl</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function CLike::create_C is used in 4/pl (<a href="4-pl.html#SP3">&#167;3</a>).</p>
<p class="endnote">The function CLike::create_CPP is used in 4/pl (<a href="4-pl.html#SP3">&#167;3</a>).</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>What makes a language C-like?
This does:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CLike::make_c_like</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">) {</span>
<span class="identifier">pl</span><span class="plain">-</span><span class="element">&gt;supports_enumerations</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">;</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">FURTHER_PARSING_PAR_MTID</span><span class="plain">, </span><span class="functiontext">CLike::further_parsing</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">SUBCATEGORISE_LINE_PAR_MTID</span><span class="plain">, </span><span class="functiontext">CLike::subcategorise_code</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">SHEBANG_TAN_MTID</span><span class="plain">, </span><span class="functiontext">CLike::shebang</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">ADDITIONAL_EARLY_MATTER_TAN_MTID</span><span class="plain">, </span><span class="functiontext">CLike::additional_early_matter</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">START_DEFN_TAN_MTID</span><span class="plain">, </span><span class="functiontext">CLike::start_definition</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">PROLONG_DEFN_TAN_MTID</span><span class="plain">, </span><span class="functiontext">CLike::prolong_definition</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">END_DEFN_TAN_MTID</span><span class="plain">, </span><span class="functiontext">CLike::end_definition</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">ADDITIONAL_PREDECLARATIONS_TAN_MTID</span><span class="plain">, </span><span class="functiontext">CLike::additional_predeclarations</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">INSERT_LINE_MARKER_TAN_MTID</span><span class="plain">, </span><span class="functiontext">CLike::insert_line_marker</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">BEFORE_MACRO_EXPANSION_TAN_MTID</span><span class="plain">, </span><span class="functiontext">CLike::before_macro_expansion</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">AFTER_MACRO_EXPANSION_TAN_MTID</span><span class="plain">, </span><span class="functiontext">CLike::after_macro_expansion</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">COMMENT_TAN_MTID</span><span class="plain">, </span><span class="functiontext">CLike::comment</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">OPEN_IFDEF_TAN_MTID</span><span class="plain">, </span><span class="functiontext">CLike::open_ifdef</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">CLOSE_IFDEF_TAN_MTID</span><span class="plain">, </span><span class="functiontext">CLike::close_ifdef</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">PARSE_COMMENT_TAN_MTID</span><span class="plain">, </span><span class="functiontext">CLike::parse_comment</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">BEGIN_WEAVE_WEA_MTID</span><span class="plain">, </span><span class="functiontext">CLike::begin_weave</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">RESET_SYNTAX_COLOURING_WEA_MTID</span><span class="plain">, </span><span class="functiontext">CLike::reset_syntax_colouring</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">SYNTAX_COLOUR_WEA_MTID</span><span class="plain">, </span><span class="functiontext">CLike::syntax_colour</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">CATALOGUE_ANA_MTID</span><span class="plain">, </span><span class="functiontext">CLike::catalogue</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">EARLY_PREWEAVE_ANALYSIS_ANA_MTID</span><span class="plain">, </span><span class="functiontext">CLike::analyse_code</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">LATE_PREWEAVE_ANALYSIS_ANA_MTID</span><span class="plain">, </span><span class="functiontext">CLike::post_analysis</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function CLike::make_c_like is used in <a href="#SP1">&#167;1</a>, 4/is (<a href="4-is.html#SP1">&#167;1</a>).</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. Parsing. </b>After a web has been read in and then parsed, code supporting its language
is then called to do any further parsing it might want to. The code below
is run if the language is "C-like": regular C and InC both qualify.
</p>
<p class="inwebparagraph">In scanning the web, we need to keep track of <code class="display"><span class="extract">#ifdef</span></code> and <code class="display"><span class="extract">#endif</span></code> pairs
in the source. This matters because we will want to predeclare functions;
but if functions are declared in conditional compilation, then their
predeclarations have to be made under the same conditions.
</p>
<p class="inwebparagraph">The following stack holds the current set of conditional compilations which the
source line being scanned lies within.
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">MAX_CONDITIONAL_COMPILATION_STACK</span><span class="plain"> 8</span>
</pre>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">cc_sp</span><span class="plain"> = 0;</span>
<span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">cc_stack</span><span class="plain">[</span><span class="constant">MAX_CONDITIONAL_COMPILATION_STACK</span><span class="plain">];</span>
<span class="reserved">c_structure</span><span class="plain"> *</span><span class="identifier">first_cst_alphabetically</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">CLike::further_parsing</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">self</span><span class="plain">, </span><span class="reserved">web</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">) {</span>
&lt;<span class="cwebmacro">Find every typedef struct in the tangle</span> <span class="cwebmacronumber">3.2</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Work out which structs contain which others</span> <span class="cwebmacronumber">3.3</span>&gt;<span class="plain">;</span>
<span class="identifier">cc_sp</span><span class="plain"> = 0;</span>
<span class="reserved">chapter</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain">;</span>
<span class="reserved">section</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">;</span>
<span class="identifier">LOOP_WITHIN_TANGLE</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">S</span><span class="plain">, </span><span class="functiontext">Tangler::primary_target</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">L</span><span class="plain">-</span><span class="element">&gt;category</span><span class="plain"> == </span><span class="constant">CODE_BODY_LCAT</span><span class="plain">) ||</span>
<span class="plain">(</span><span class="identifier">L</span><span class="plain">-</span><span class="element">&gt;category</span><span class="plain"> == </span><span class="constant">BEGIN_DEFINITION_LCAT</span><span class="plain">) ||</span>
<span class="plain">(</span><span class="identifier">L</span><span class="plain">-</span><span class="element">&gt;category</span><span class="plain"> == </span><span class="constant">CONT_DEFINITION_LCAT</span><span class="plain">)) {</span>
&lt;<span class="cwebmacro">Look for conditional compilation on this line</span> <span class="cwebmacronumber">3.1</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Look for a function definition on this line</span> <span class="cwebmacronumber">3.4</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">cc_sp</span><span class="plain"> &gt; 0)</span>
<span class="functiontext">Main::error_in_web</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"program ended with conditional compilation open"</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 CLike::further_parsing is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP3_1"></a><b>&#167;3.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Look for conditional compilation on this line</span> <span class="cwebmacronumber">3.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">match_results</span><span class="plain"> </span><span class="identifier">mr</span><span class="plain"> = </span><span class="functiontext">Regexp::create_mr</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Regexp::match</span><span class="plain">(&amp;</span><span class="identifier">mr</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">-</span><span class="element">&gt;text</span><span class="plain">, </span><span class="identifier">L</span><span class="string">" *#ifn*def %c+"</span><span class="plain">)) ||</span>
<span class="plain">(</span><span class="functiontext">Regexp::match</span><span class="plain">(&amp;</span><span class="identifier">mr</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">-</span><span class="element">&gt;text</span><span class="plain">, </span><span class="identifier">L</span><span class="string">" *#IFN*DEF %c+"</span><span class="plain">))) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">cc_sp</span><span class="plain"> &gt;= </span><span class="constant">MAX_CONDITIONAL_COMPILATION_STACK</span><span class="plain">)</span>
<span class="functiontext">Main::error_in_web</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"conditional compilation too deeply nested"</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">);</span>
<span class="reserved">else</span>
<span class="identifier">cc_stack</span><span class="plain">[</span><span class="identifier">cc_sp</span><span class="plain">++] = </span><span class="identifier">L</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Regexp::match</span><span class="plain">(&amp;</span><span class="identifier">mr</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">-</span><span class="element">&gt;text</span><span class="plain">, </span><span class="identifier">L</span><span class="string">" *#endif *"</span><span class="plain">)) ||</span>
<span class="plain">(</span><span class="functiontext">Regexp::match</span><span class="plain">(&amp;</span><span class="identifier">mr</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">-</span><span class="element">&gt;text</span><span class="plain">, </span><span class="identifier">L</span><span class="string">" *#ENDIF *"</span><span class="plain">))) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">cc_sp</span><span class="plain"> &lt;= 0)</span>
<span class="functiontext">Main::error_in_web</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"found #endif without #ifdef or #ifndef"</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">);</span>
<span class="reserved">else</span>
<span class="identifier">cc_sp</span><span class="plain">--;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP3_2"></a><b>&#167;3.2. Structures. </b>We're going to assume that the C source code uses structures looking
something like this:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">typedef struct fruit {</span>
<span class="plain"> struct pip the_pips[5];</span>
<span class="plain"> struct fruit *often_confused_with;</span>
<span class="plain"> struct tree_species *grows_on;</span>
<span class="plain"> int typical_weight;</span>
<span class="plain">} fruit;</span>
</pre>
<p class="inwebparagraph">which adopts the traditional layout conventions of Kernighan and Ritchie.
The structure definitions in this Inweb web all take the required form,
of course, and provide many more examples.
</p>
<p class="inwebparagraph">Note that a <code class="display"><span class="extract">fruit</span></code> structure contains a <code class="display"><span class="extract">pip</span></code> structure (in fact, five of
them), but only contains pointers to <code class="display"><span class="extract">tree_species</span></code> structures and itself.
C requires therefore that the structure definition for <code class="display"><span class="extract">pip</span></code> must occur
earlier in the code than that for <code class="display"><span class="extract">fruit</span></code>. This is a nuisance, so Inweb
takes care of it automatically.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Find every typedef struct in the tangle</span> <span class="cwebmacronumber">3.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">c_structure</span><span class="plain"> *</span><span class="identifier">current_str</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">chapter</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain">;</span>
<span class="reserved">section</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">;</span>
<span class="identifier">LOOP_WITHIN_TANGLE</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">S</span><span class="plain">, </span><span class="functiontext">Tangler::primary_target</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) {</span>
<span class="reserved">match_results</span><span class="plain"> </span><span class="identifier">mr</span><span class="plain"> = </span><span class="functiontext">Regexp::create_mr</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Regexp::match</span><span class="plain">(&amp;</span><span class="identifier">mr</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">-</span><span class="element">&gt;text</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"typedef struct (%i+) %c*{%c*"</span><span class="plain">)) {</span>
&lt;<span class="cwebmacro">Attach a structure to this source line</span> <span class="cwebmacronumber">3.2.2</span>&gt;<span class="plain">;</span>
<span class="functiontext">Tags::add_by_name</span><span class="plain">(</span><span class="identifier">L</span><span class="plain">-</span><span class="element">&gt;owning_paragraph</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Structures"</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="functiontext">Str::get_first_char</span><span class="plain">(</span><span class="identifier">L</span><span class="plain">-</span><span class="element">&gt;text</span><span class="plain">) == </span><span class="character">'}'</span><span class="plain">) &amp;&amp; (</span><span class="identifier">current_str</span><span class="plain">)) {</span>
<span class="identifier">current_str</span><span class="plain">-</span><span class="element">&gt;typedef_ends</span><span class="plain"> = </span><span class="identifier">L</span><span class="plain">;</span>
<span class="identifier">current_str</span><span class="plain"> = </span><span class="identifier">NULL</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">current_str</span><span class="plain">) &amp;&amp; (</span><span class="identifier">current_str</span><span class="plain">-</span><span class="element">&gt;typedef_ends</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)) {</span>
&lt;<span class="cwebmacro">Work through the a line in the structure definition</span> <span class="cwebmacronumber">3.2.3</span>&gt;<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="functiontext">Regexp::match</span><span class="plain">(&amp;</span><span class="identifier">mr</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">-</span><span class="element">&gt;text</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"typedef %c+"</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Regexp::match</span><span class="plain">(&amp;</span><span class="identifier">mr</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">-</span><span class="element">&gt;text</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"%c+##%c+"</span><span class="plain">) == </span><span class="constant">FALSE</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">L</span><span class="plain">-</span><span class="element">&gt;owning_paragraph</span><span class="plain">-</span><span class="element">&gt;placed_very_early</span><span class="plain"> == </span><span class="constant">FALSE</span><span class="plain">)</span>
<span class="identifier">L</span><span class="plain">-</span><span class="element">&gt;category</span><span class="plain"> = </span><span class="constant">TYPEDEF_LCAT</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="functiontext">Regexp::dispose_of</span><span class="plain">(&amp;</span><span class="identifier">mr</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP3_2_1"></a><b>&#167;3.2.1. </b>For each <code class="display"><span class="extract">typedef struct</span></code> we find, we will make one of these:
</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">c_structure</span><span class="plain"> {</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">structure_name</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">tangled</span><span class="plain">; </span> <span class="comment">whether the structure definition has been tangled out</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">typedef_begins</span><span class="plain">; </span> <span class="comment">opening line of <code class="display"><span class="extract">typedef</span></code></span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">typedef_ends</span><span class="plain">; </span> <span class="comment">closing line, where <code class="display"><span class="extract">}</span></code> appears</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">linked_list</span><span class="plain"> *</span><span class="identifier">incorporates</span><span class="plain">; </span> <span class="comment">of <code class="display"><span class="extract">c_structure</span></code></span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">linked_list</span><span class="plain"> *</span><span class="identifier">elements</span><span class="plain">; </span> <span class="comment">of <code class="display"><span class="extract">structure_element</span></code></span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">c_structure</span><span class="plain"> *</span><span class="identifier">next_cst_alphabetically</span><span class="plain">;</span>
<span class="constant">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">c_structure</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The structure c_structure is accessed in 3/tw and here.</p>
<p class="inwebparagraph"><a id="SP3_2_2"></a><b>&#167;3.2.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Attach a structure to this source line</span> <span class="cwebmacronumber">3.2.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">c_structure</span><span class="plain"> *</span><span class="identifier">str</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">c_structure</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Initialise the C structure structure</span> <span class="cwebmacronumber">3.2.2.1</span>&gt;<span class="plain">;</span>
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">L</span><span class="plain">-</span><span class="element">&gt;owning_section</span><span class="plain">, </span><span class="identifier">str</span><span class="plain">-</span><span class="element">&gt;structure_name</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Add this to the lists for its web and its paragraph</span> <span class="cwebmacronumber">3.2.2.2</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Insertion-sort this into the alphabetical list of all structures found</span> <span class="cwebmacronumber">3.2.2.3</span>&gt;<span class="plain">;</span>
<span class="identifier">current_str</span><span class="plain"> = </span><span class="identifier">str</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_2">&#167;3.2</a>.</p>
<p class="inwebparagraph"><a id="SP3_2_2_1"></a><b>&#167;3.2.2.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Initialise the C structure structure</span> <span class="cwebmacronumber">3.2.2.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">str</span><span class="plain">-</span><span class="element">&gt;structure_name</span><span class="plain"> = </span><span class="functiontext">Str::duplicate</span><span class="plain">(</span><span class="identifier">mr</span><span class="element">.exp</span><span class="plain">[0]);</span>
<span class="identifier">str</span><span class="plain">-</span><span class="element">&gt;typedef_begins</span><span class="plain"> = </span><span class="identifier">L</span><span class="plain">;</span>
<span class="identifier">str</span><span class="plain">-</span><span class="element">&gt;tangled</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
<span class="identifier">str</span><span class="plain">-</span><span class="element">&gt;typedef_ends</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">str</span><span class="plain">-</span><span class="element">&gt;incorporates</span><span class="plain"> = </span><span class="identifier">NEW_LINKED_LIST</span><span class="plain">(</span><span class="reserved">c_structure</span><span class="plain">);</span>
<span class="identifier">str</span><span class="plain">-</span><span class="element">&gt;elements</span><span class="plain"> = </span><span class="identifier">NEW_LINKED_LIST</span><span class="plain">(</span><span class="reserved">structure_element</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_2_2">&#167;3.2.2</a>.</p>
<p class="inwebparagraph"><a id="SP3_2_2_2"></a><b>&#167;3.2.2.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Add this to the lists for its web and its paragraph</span> <span class="cwebmacronumber">3.2.2.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">ADD_TO_LINKED_LIST</span><span class="plain">(</span><span class="identifier">str</span><span class="plain">, </span><span class="reserved">c_structure</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">-</span><span class="element">&gt;c_structures</span><span class="plain">);</span>
<span class="identifier">ADD_TO_LINKED_LIST</span><span class="plain">(</span><span class="identifier">str</span><span class="plain">, </span><span class="reserved">c_structure</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">-</span><span class="element">&gt;owning_paragraph</span><span class="plain">-</span><span class="element">&gt;structures</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_2_2">&#167;3.2.2</a>.</p>
<p class="inwebparagraph"><a id="SP3_2_2_3"></a><b>&#167;3.2.2.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">Insertion-sort this into the alphabetical list of all structures found</span> <span class="cwebmacronumber">3.2.2.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">str</span><span class="plain">-</span><span class="element">&gt;next_cst_alphabetically</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">first_cst_alphabetically</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">first_cst_alphabetically</span><span class="plain"> = </span><span class="identifier">str</span><span class="plain">;</span>
<span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">placed</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
<span class="reserved">c_structure</span><span class="plain"> *</span><span class="identifier">last</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="reserved">c_structure</span><span class="plain"> *</span><span class="identifier">seq</span><span class="plain"> = </span><span class="identifier">first_cst_alphabetically</span><span class="plain">; </span><span class="identifier">seq</span><span class="plain">;</span>
<span class="identifier">seq</span><span class="plain"> = </span><span class="identifier">seq</span><span class="plain">-</span><span class="element">&gt;next_cst_alphabetically</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Str::cmp</span><span class="plain">(</span><span class="identifier">str</span><span class="plain">-</span><span class="element">&gt;structure_name</span><span class="plain">, </span><span class="identifier">seq</span><span class="plain">-</span><span class="element">&gt;structure_name</span><span class="plain">) &lt; 0) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">seq</span><span class="plain"> == </span><span class="identifier">first_cst_alphabetically</span><span class="plain">) {</span>
<span class="identifier">str</span><span class="plain">-</span><span class="element">&gt;next_cst_alphabetically</span><span class="plain"> = </span><span class="identifier">first_cst_alphabetically</span><span class="plain">;</span>
<span class="identifier">first_cst_alphabetically</span><span class="plain"> = </span><span class="identifier">str</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">last</span><span class="plain">-</span><span class="element">&gt;next_cst_alphabetically</span><span class="plain"> = </span><span class="identifier">str</span><span class="plain">;</span>
<span class="identifier">str</span><span class="plain">-</span><span class="element">&gt;next_cst_alphabetically</span><span class="plain"> = </span><span class="identifier">seq</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">placed</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">;</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">last</span><span class="plain"> = </span><span class="identifier">seq</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">placed</span><span class="plain"> == </span><span class="constant">FALSE</span><span class="plain">) </span><span class="identifier">last</span><span class="plain">-</span><span class="element">&gt;next_cst_alphabetically</span><span class="plain"> = </span><span class="identifier">str</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_2_2">&#167;3.2.2</a>.</p>
<p class="inwebparagraph"><a id="SP3_2_3"></a><b>&#167;3.2.3. </b>At this point we're reading a line within the structure's definition; for
the sake of an illustrative example, let's suppose that line is:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain"> unsigned long long int *val;</span>
</pre>
<p class="inwebparagraph">We need to extract the element name, <code class="display"><span class="extract">val</span></code>, and make a note of it.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Work through the a line in the structure definition</span> <span class="cwebmacronumber">3.2.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">);</span>
<span class="functiontext">Str::copy</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">-</span><span class="element">&gt;text</span><span class="plain">);</span>
<span class="functiontext">Str::trim_white_space</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Remove C type modifiers from the front of p</span> <span class="cwebmacronumber">3.2.3.1</span>&gt;<span class="plain">;</span>
<span class="reserved">string_position</span><span class="plain"> </span><span class="identifier">pos</span><span class="plain"> = </span><span class="functiontext">Str::start</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Str::get</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">) != </span><span class="character">'/'</span><span class="plain">) { </span> <span class="comment">a slash must introduce a comment here</span>
&lt;<span class="cwebmacro">Move pos past the type name</span> <span class="cwebmacronumber">3.2.3.2</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Move pos past any typographical type modifiers</span> <span class="cwebmacronumber">3.2.3.3</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Str::in_range</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">)) {</span>
<span class="reserved">match_results</span><span class="plain"> </span><span class="identifier">mr</span><span class="plain"> = </span><span class="functiontext">Regexp::create_mr</span><span class="plain">();</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">elname</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Copy the element name into elname</span> <span class="cwebmacronumber">3.2.3.4</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Record the element</span> <span class="cwebmacronumber">3.2.3.6</span>&gt;<span class="plain">;</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">elname</span><span class="plain">);</span>
<span class="functiontext">Regexp::dispose_of</span><span class="plain">(&amp;</span><span class="identifier">mr</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">p</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_2">&#167;3.2</a>.</p>
<p class="inwebparagraph"><a id="SP3_2_3_1"></a><b>&#167;3.2.3.1. </b>The following reduces <code class="display"><span class="extract">unsigned long long int *val;</span></code> to just <code class="display"><span class="extract">int *val;</span></code>.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Remove C type modifiers from the front of p</span> <span class="cwebmacronumber">3.2.3.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">wchar_t</span><span class="plain"> *</span><span class="identifier">modifier_patterns</span><span class="plain">[] = {</span>
<span class="identifier">L</span><span class="string">"(struct )(%C%c*)"</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"(signed )(%C%c*)"</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"(unsigned )(%C%c*)"</span><span class="plain">,</span>
<span class="identifier">L</span><span class="string">"(short )(%C%c*)"</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"(long )(%C%c*)"</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"(static )(%C%c*)"</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain"> };</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">seek_modifiers</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">;</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">seek_modifiers</span><span class="plain">) {</span>
<span class="identifier">seek_modifiers</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> = 0; </span><span class="identifier">modifier_patterns</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="functiontext">Regexp::match</span><span class="plain">(&amp;</span><span class="identifier">mr</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">modifier_patterns</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">])) {</span>
<span class="functiontext">Str::copy</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">mr</span><span class="element">.exp</span><span class="plain">[1]);</span>
<span class="identifier">seek_modifiers</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">;</span>
<span class="reserved">break</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="#SP3_2_3">&#167;3.2.3</a>.</p>
<p class="inwebparagraph"><a id="SP3_2_3_2"></a><b>&#167;3.2.3.2. </b>At this point <code class="display"><span class="extract">p</span></code> has been reduced to <code class="display"><span class="extract">int *val;</span></code>, but the following moves
<code class="display"><span class="extract">pos</span></code> to point to the <code class="display"><span class="extract">*</span></code>:
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Move pos past the type name</span> <span class="cwebmacronumber">3.2.3.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">while</span><span class="plain"> ((</span><span class="functiontext">Str::get</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">)) &amp;&amp; (</span><span class="functiontext">Characters::is_space_or_tab</span><span class="plain">(</span><span class="functiontext">Str::get</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">)) == </span><span class="constant">FALSE</span><span class="plain">))</span>
<span class="identifier">pos</span><span class="plain"> = </span><span class="functiontext">Str::forward</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_2_3">&#167;3.2.3</a>.</p>
<p class="inwebparagraph"><a id="SP3_2_3_3"></a><b>&#167;3.2.3.3. </b>And this moves it past the <code class="display"><span class="extract">*</span></code> to point to the <code class="display"><span class="extract">v</span></code> in <code class="display"><span class="extract">int *val;</span></code>:
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Move pos past any typographical type modifiers</span> <span class="cwebmacronumber">3.2.3.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">while</span><span class="plain"> ((</span><span class="functiontext">Characters::is_space_or_tab</span><span class="plain">(</span><span class="functiontext">Str::get</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">))) || (</span><span class="functiontext">Str::get</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">) == </span><span class="character">'*'</span><span class="plain">) ||</span>
<span class="plain">(</span><span class="functiontext">Str::get</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">) == </span><span class="character">'('</span><span class="plain">) || (</span><span class="functiontext">Str::get</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">) == </span><span class="character">')'</span><span class="plain">)) </span><span class="identifier">pos</span><span class="plain"> = </span><span class="functiontext">Str::forward</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_2_3">&#167;3.2.3</a>.</p>
<p class="inwebparagraph"><a id="SP3_2_3_4"></a><b>&#167;3.2.3.4. </b>This then first copies the substring <code class="display"><span class="extract">val;</span></code> into <code class="display"><span class="extract">elname</span></code>, then cuts that
down to just the identifier characters at the front, i.e., to <code class="display"><span class="extract">val</span></code>.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Copy the element name into elname</span> <span class="cwebmacronumber">3.2.3.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="functiontext">Str::substr</span><span class="plain">(</span><span class="identifier">elname</span><span class="plain">, </span><span class="identifier">pos</span><span class="plain">, </span><span class="functiontext">Str::end</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Regexp::match</span><span class="plain">(&amp;</span><span class="identifier">mr</span><span class="plain">, </span><span class="identifier">elname</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"(%i+)%c*"</span><span class="plain">)) </span><span class="functiontext">Str::copy</span><span class="plain">(</span><span class="identifier">elname</span><span class="plain">, </span><span class="identifier">mr</span><span class="element">.exp</span><span class="plain">[0]);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_2_3">&#167;3.2.3</a>.</p>
<p class="inwebparagraph"><a id="SP3_2_3_5"></a><b>&#167;3.2.3.5. </b>Now we create an instance of <code class="display"><span class="extract">structure_element</span></code> to record the existence
of the element <code class="display"><span class="extract">val</span></code>, and add it to the linked list of elements of the
structure being defined.
</p>
<p class="inwebparagraph">In InC, only, certain element names used often in Inform's source code are
given mildly special treatment. This doesn't amount to much. <code class="display"><span class="extract">allow_sharing</span></code>
has no effect on tangling, so it doesn't change the program. It simply
affects the reports in the woven code about where structures are used.
</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">structure_element</span><span class="plain"> {</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">element_name</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">element_created_at</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">allow_sharing</span><span class="plain">;</span>
<span class="constant">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">structure_element</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The structure structure_element is accessed in 3/tw and here.</p>
<p class="inwebparagraph"><a id="SP3_2_3_6"></a><b>&#167;3.2.3.6. </b><code class="display">
&lt;<span class="cwebmacrodefn">Record the element</span> <span class="cwebmacronumber">3.2.3.6</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">L</span><span class="plain">-</span><span class="element">&gt;owning_section</span><span class="plain">, </span><span class="identifier">elname</span><span class="plain">, </span><span class="constant">ELEMENT_COLOUR</span><span class="plain">);</span>
<span class="reserved">structure_element</span><span class="plain"> *</span><span class="identifier">elt</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">structure_element</span><span class="plain">);</span>
<span class="identifier">elt</span><span class="plain">-</span><span class="element">&gt;element_name</span><span class="plain"> = </span><span class="functiontext">Str::duplicate</span><span class="plain">(</span><span class="identifier">elname</span><span class="plain">);</span>
<span class="identifier">elt</span><span class="plain">-</span><span class="element">&gt;allow_sharing</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
<span class="identifier">elt</span><span class="plain">-</span><span class="element">&gt;element_created_at</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="functiontext">Languages::share_element</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">-</span><span class="element">&gt;main_language</span><span class="plain">, </span><span class="identifier">elname</span><span class="plain">)) </span><span class="identifier">elt</span><span class="plain">-</span><span class="element">&gt;allow_sharing</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">;</span>
<span class="identifier">ADD_TO_LINKED_LIST</span><span class="plain">(</span><span class="identifier">elt</span><span class="plain">, </span><span class="reserved">structure_element</span><span class="plain">, </span><span class="identifier">current_str</span><span class="plain">-</span><span class="element">&gt;elements</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_2_3">&#167;3.2.3</a>.</p>
<p class="inwebparagraph"><a id="SP3_3"></a><b>&#167;3.3. Structure dependency. </b>We say that S depends on T if <code class="display"><span class="extract">struct S</span></code> has an element whose type is
<code class="display"><span class="extract">struct T</span></code>. That matters because if so then <code class="display"><span class="extract">struct T</span></code> has to be defined
before <code class="display"><span class="extract">struct S</span></code> in the tangled output.
</p>
<p class="inwebparagraph">It's important to note that <code class="display"><span class="extract">struct S</span></code> merely having a member of type
<code class="display"><span class="extract">struct *T</span></code> does not create a dependency. In the code below, because <code class="display"><span class="extract">%i</span></code>
matches only identifier characters and <code class="display"><span class="extract">*</span></code> is not one of those, a line like
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain"> struct fruit *often_confused_with;</span>
</pre>
<p class="inwebparagraph">will not trip the switch here.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Work out which structs contain which others</span> <span class="cwebmacronumber">3.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">c_structure</span><span class="plain"> *</span><span class="identifier">current_str</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">current_str</span><span class="plain">, </span><span class="reserved">c_structure</span><span class="plain">) {</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain"> = </span><span class="identifier">current_str</span><span class="plain">-</span><span class="element">&gt;typedef_begins</span><span class="plain">;</span>
<span class="plain">((</span><span class="identifier">L</span><span class="plain">) &amp;&amp; (</span><span class="identifier">L</span><span class="plain"> != </span><span class="identifier">current_str</span><span class="plain">-</span><span class="element">&gt;typedef_ends</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="element">&gt;next_line</span><span class="plain">) {</span>
<span class="reserved">match_results</span><span class="plain"> </span><span class="identifier">mr</span><span class="plain"> = </span><span class="functiontext">Regexp::create_mr</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Regexp::match</span><span class="plain">(&amp;</span><span class="identifier">mr</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">-</span><span class="element">&gt;text</span><span class="plain">, </span><span class="identifier">L</span><span class="string">" struct (%i+) %i%c*"</span><span class="plain">))</span>
&lt;<span class="cwebmacro">One structure appears to contain a copy of another one</span> <span class="cwebmacronumber">3.3.1</span>&gt;<span class="plain">;</span>
<span class="functiontext">Regexp::dispose_of</span><span class="plain">(&amp;</span><span class="identifier">mr</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="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP3_3_1"></a><b>&#167;3.3.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">One structure appears to contain a copy of another one</span> <span class="cwebmacronumber">3.3.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">used_structure</span><span class="plain"> = </span><span class="identifier">mr</span><span class="element">.exp</span><span class="plain">[0];</span>
<span class="reserved">c_structure</span><span class="plain"> *</span><span class="identifier">str</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">str</span><span class="plain">, </span><span class="reserved">c_structure</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">-</span><span class="element">&gt;c_structures</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">str</span><span class="plain"> != </span><span class="identifier">current_str</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Str::eq</span><span class="plain">(</span><span class="identifier">used_structure</span><span class="plain">, </span><span class="identifier">str</span><span class="plain">-</span><span class="element">&gt;structure_name</span><span class="plain">)))</span>
<span class="identifier">ADD_TO_LINKED_LIST</span><span class="plain">(</span><span class="identifier">str</span><span class="plain">, </span><span class="reserved">c_structure</span><span class="plain">, </span><span class="identifier">current_str</span><span class="plain">-</span><span class="element">&gt;incorporates</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_3">&#167;3.3</a>.</p>
<p class="inwebparagraph"><a id="SP3_4"></a><b>&#167;3.4. Functions. </b>Second round: we recognise a C function as being a line which takes the form
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">type identifier(args...</span>
</pre>
<p class="inwebparagraph">where we parse <code class="display"><span class="extract">type</span></code> only minimally. In InC (only), the identifier can
contain namespace dividers written <code class="display"><span class="extract">::</span></code>. Function declarations, we will assume,
always begin on column 1 of their source files, and we expect them to take
modern ANSI C style, not the long-deprecated late 1970s C style.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Look for a function definition on this line</span> <span class="cwebmacronumber">3.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (!(</span><span class="functiontext">Characters::is_space_or_tab</span><span class="plain">(</span><span class="functiontext">Str::get_first_char</span><span class="plain">(</span><span class="identifier">L</span><span class="plain">-</span><span class="element">&gt;text</span><span class="plain">)))) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">qualifiers</span><span class="plain">);</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">modified</span><span class="plain">);</span>
<span class="functiontext">Str::copy</span><span class="plain">(</span><span class="identifier">modified</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">-</span><span class="element">&gt;text</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Parse past any type modifiers</span> <span class="cwebmacronumber">3.4.1</span>&gt;<span class="plain">;</span>
<span class="reserved">match_results</span><span class="plain"> </span><span class="identifier">mr</span><span class="plain"> = </span><span class="functiontext">Regexp::create_mr</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Regexp::match</span><span class="plain">(&amp;</span><span class="identifier">mr</span><span class="plain">, </span><span class="identifier">modified</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"(%i+) (%**)(%i+)%((%c*)"</span><span class="plain">)) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">ftype</span><span class="plain">); </span><span class="functiontext">Str::copy</span><span class="plain">(</span><span class="identifier">ftype</span><span class="plain">, </span><span class="identifier">mr</span><span class="element">.exp</span><span class="plain">[0]);</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">asts</span><span class="plain">); </span><span class="functiontext">Str::copy</span><span class="plain">(</span><span class="identifier">asts</span><span class="plain">, </span><span class="identifier">mr</span><span class="element">.exp</span><span class="plain">[1]);</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">fname</span><span class="plain">); </span><span class="functiontext">Str::copy</span><span class="plain">(</span><span class="identifier">fname</span><span class="plain">, </span><span class="identifier">mr</span><span class="element">.exp</span><span class="plain">[2]);</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">arguments</span><span class="plain">); </span><span class="functiontext">Str::copy</span><span class="plain">(</span><span class="identifier">arguments</span><span class="plain">, </span><span class="identifier">mr</span><span class="element">.exp</span><span class="plain">[3]);</span>
&lt;<span class="cwebmacro">A function definition was found</span> <span class="cwebmacronumber">3.4.2</span>&gt;<span class="plain">;</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">ftype</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">asts</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">fname</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">arguments</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">qualifiers</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">modified</span><span class="plain">);</span>
<span class="functiontext">Regexp::dispose_of</span><span class="plain">(&amp;</span><span class="identifier">mr</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP3_4_1"></a><b>&#167;3.4.1. </b>C has a whole soup of reserved words applying to types, but most of them
can't apply to the return type of a function. We do, however, iterate so that
forms like <code class="display"><span class="extract">static long long int</span></code> will work.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Parse past any type modifiers</span> <span class="cwebmacronumber">3.4.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">wchar_t</span><span class="plain"> *</span><span class="identifier">modifier_patterns</span><span class="plain">[] = {</span>
<span class="identifier">L</span><span class="string">"(signed )(%C%c*)"</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"(unsigned )(%C%c*)"</span><span class="plain">,</span>
<span class="identifier">L</span><span class="string">"(short )(%C%c*)"</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"(long )(%C%c*)"</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"(static )(%C%c*)"</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain"> };</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">seek_modifiers</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">;</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">seek_modifiers</span><span class="plain">) {</span>
<span class="identifier">seek_modifiers</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
<span class="reserved">match_results</span><span class="plain"> </span><span class="identifier">mr</span><span class="plain"> = </span><span class="functiontext">Regexp::create_mr</span><span class="plain">();</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> = 0; </span><span class="identifier">modifier_patterns</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="functiontext">Regexp::match</span><span class="plain">(&amp;</span><span class="identifier">mr</span><span class="plain">, </span><span class="identifier">modified</span><span class="plain">, </span><span class="identifier">modifier_patterns</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">])) {</span>
<span class="functiontext">Str::concatenate</span><span class="plain">(</span><span class="identifier">qualifiers</span><span class="plain">, </span><span class="identifier">mr</span><span class="element">.exp</span><span class="plain">[0]);</span>
<span class="functiontext">Str::copy</span><span class="plain">(</span><span class="identifier">modified</span><span class="plain">, </span><span class="identifier">mr</span><span class="element">.exp</span><span class="plain">[1]);</span>
<span class="identifier">seek_modifiers</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="functiontext">Regexp::dispose_of</span><span class="plain">(&amp;</span><span class="identifier">mr</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_4">&#167;3.4</a>.</p>
<p class="inwebparagraph"><a id="SP3_4_2"></a><b>&#167;3.4.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">A function definition was found</span> <span class="cwebmacronumber">3.4.2</span>&gt; =
</code></p>
<pre class="displaydefn">
&lt;<span class="cwebmacro">Soak up further arguments from continuation lines after the declaration</span> <span class="cwebmacronumber">3.4.2.1</span>&gt;<span class="plain">;</span>
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">L</span><span class="plain">-</span><span class="element">&gt;owning_section</span><span class="plain">, </span><span class="identifier">fname</span><span class="plain">, </span><span class="constant">FUNCTION_COLOUR</span><span class="plain">);</span>
<span class="reserved">function</span><span class="plain"> *</span><span class="identifier">fn</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">function</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Initialise the function structure</span> <span class="cwebmacronumber">3.4.2.3</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Add the function to its paragraph and line</span> <span class="cwebmacronumber">3.4.2.4</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">W</span><span class="plain">-</span><span class="element">&gt;main_language</span><span class="plain">-</span><span class="element">&gt;supports_namespaces</span><span class="plain">)</span>
&lt;<span class="cwebmacro">Check that the function has its namespace correctly declared</span> <span class="cwebmacronumber">3.4.2.5</span>&gt;<span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_4">&#167;3.4</a>.</p>
<p class="inwebparagraph"><a id="SP3_4_2_1"></a><b>&#167;3.4.2.1. </b>In some cases the function's declaration runs over several lines:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">void World::Subjects::make_adj_const_domain(inference_subject *infs,</span>
<span class="plain"> instance *nc, property *prn) {</span>
</pre>
<p class="inwebparagraph">Having read the first line, <code class="display"><span class="extract">arguments</span></code> would contain <code class="display"><span class="extract">inference_subject *infs,</span></code>
and would thus be incomplete. We continue across subsequent lines until we
reach an open brace <code class="display"><span class="extract">{</span></code>.
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">MAX_ARG_LINES</span><span class="plain"> 8 </span> <span class="comment">maximum number of lines over which a function's header can extend</span>
</pre>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Soak up further arguments from continuation lines after the declaration</span> <span class="cwebmacronumber">3.4.2.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">AL</span><span class="plain"> = </span><span class="identifier">L</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">arg_lc</span><span class="plain"> = 1;</span>
<span class="reserved">while</span><span class="plain"> ((</span><span class="identifier">AL</span><span class="plain">) &amp;&amp; (</span><span class="identifier">arg_lc</span><span class="plain"> &lt;= </span><span class="constant">MAX_ARG_LINES</span><span class="plain">) &amp;&amp; (</span><span class="functiontext">Regexp::find_open_brace</span><span class="plain">(</span><span class="identifier">arguments</span><span class="plain">) == -1)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">AL</span><span class="plain">-</span><span class="element">&gt;next_line</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">err_mess</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">err_mess</span><span class="plain">, </span><span class="string">"Function '%S' has a malformed declaration"</span><span class="plain">, </span><span class="identifier">fname</span><span class="plain">);</span>
<span class="functiontext">Main::error_in_web</span><span class="plain">(</span><span class="identifier">err_mess</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">err_mess</span><span class="plain">);</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">AL</span><span class="plain"> = </span><span class="identifier">AL</span><span class="plain">-</span><span class="element">&gt;next_line</span><span class="plain">;</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">arguments</span><span class="plain">, </span><span class="string">" %S"</span><span class="plain">, </span><span class="identifier">AL</span><span class="plain">-</span><span class="element">&gt;text</span><span class="plain">);</span>
<span class="identifier">arg_lc</span><span class="plain">++;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">n</span><span class="plain"> = </span><span class="functiontext">Regexp::find_open_brace</span><span class="plain">(</span><span class="identifier">arguments</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">n</span><span class="plain"> &gt;= 0) </span><span class="functiontext">Str::truncate</span><span class="plain">(</span><span class="identifier">arguments</span><span class="plain">, </span><span class="identifier">n</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_4_2">&#167;3.4.2</a>.</p>
<p class="inwebparagraph"><a id="SP3_4_2_2"></a><b>&#167;3.4.2.2. </b>Each function definition found results in one of these structures being made:
</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">function</span><span class="plain"> {</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">function_name</span><span class="plain">; </span> <span class="comment">e.g., <code class="display"><span class="extract">"cultivate"</span></code></span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">function_type</span><span class="plain">; </span> <span class="comment">e.g., <code class="display"><span class="extract">"tree *"</span></code></span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">function_arguments</span><span class="plain">; </span> <span class="comment">e.g., <code class="display"><span class="extract">"int rainfall)"</span></code>: note <code class="display"><span class="extract">)</span></code></span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">function_header_at</span><span class="plain">; </span> <span class="comment">where the first line of the header begins</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">within_namespace</span><span class="plain">; </span> <span class="comment">written using InC namespace dividers</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">called_from_other_sections</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">call_freely</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">no_conditionals</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">within_conditionals</span><span class="plain">[</span><span class="constant">MAX_CONDITIONAL_COMPILATION_STACK</span><span class="plain">];</span>
<span class="constant">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">function</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The structure function is accessed in 3/tw and here.</p>
<p class="inwebparagraph"><a id="SP3_4_2_3"></a><b>&#167;3.4.2.3. </b>Note that we take a snapshot of the conditional compilation stack as
part of the function structure. We'll need it when predeclaring the function.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Initialise the function structure</span> <span class="cwebmacronumber">3.4.2.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">fn</span><span class="plain">-</span><span class="element">&gt;function_name</span><span class="plain"> = </span><span class="functiontext">Str::duplicate</span><span class="plain">(</span><span class="identifier">fname</span><span class="plain">);</span>
<span class="identifier">fn</span><span class="plain">-</span><span class="element">&gt;function_arguments</span><span class="plain"> = </span><span class="functiontext">Str::duplicate</span><span class="plain">(</span><span class="identifier">arguments</span><span class="plain">);</span>
<span class="identifier">fn</span><span class="plain">-</span><span class="element">&gt;function_type</span><span class="plain"> = </span><span class="functiontext">Str::new</span><span class="plain">();</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">fn</span><span class="plain">-</span><span class="element">&gt;function_type</span><span class="plain">, </span><span class="string">"%S%S %S"</span><span class="plain">, </span><span class="identifier">qualifiers</span><span class="plain">, </span><span class="identifier">ftype</span><span class="plain">, </span><span class="identifier">asts</span><span class="plain">);</span>
<span class="identifier">fn</span><span class="plain">-</span><span class="element">&gt;within_namespace</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
<span class="identifier">fn</span><span class="plain">-</span><span class="element">&gt;called_from_other_sections</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
<span class="identifier">fn</span><span class="plain">-</span><span class="element">&gt;call_freely</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Str::eq_wide_string</span><span class="plain">(</span><span class="identifier">fn</span><span class="plain">-</span><span class="element">&gt;function_name</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"isdigit"</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">W</span><span class="plain">-</span><span class="element">&gt;main_language</span><span class="plain">-</span><span class="element">&gt;supports_namespaces</span><span class="plain">))</span>
<span class="identifier">fn</span><span class="plain">-</span><span class="element">&gt;call_freely</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">;</span>
<span class="identifier">fn</span><span class="plain">-</span><span class="element">&gt;function_header_at</span><span class="plain"> = </span><span class="identifier">L</span><span class="plain">;</span>
<span class="identifier">fn</span><span class="plain">-</span><span class="element">&gt;no_conditionals</span><span class="plain"> = </span><span class="identifier">cc_sp</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">cc_sp</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">fn</span><span class="plain">-</span><span class="element">&gt;within_conditionals</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] = </span><span class="identifier">cc_stack</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_4_2">&#167;3.4.2</a>.</p>
<p class="inwebparagraph"><a id="SP3_4_2_4"></a><b>&#167;3.4.2.4. </b><code class="display">
&lt;<span class="cwebmacrodefn">Add the function to its paragraph and line</span> <span class="cwebmacronumber">3.4.2.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">paragraph</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain"> = </span><span class="identifier">L</span><span class="plain">-</span><span class="element">&gt;owning_paragraph</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">ADD_TO_LINKED_LIST</span><span class="plain">(</span><span class="identifier">fn</span><span class="plain">, </span><span class="reserved">function</span><span class="plain">, </span><span class="identifier">P</span><span class="plain">-</span><span class="element">&gt;functions</span><span class="plain">);</span>
<span class="identifier">L</span><span class="plain">-</span><span class="element">&gt;function_defined</span><span class="plain"> = </span><span class="identifier">fn</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_4_2">&#167;3.4.2</a>.</p>
<p class="inwebparagraph"><a id="SP3_4_2_5"></a><b>&#167;3.4.2.5. </b><code class="display">
&lt;<span class="cwebmacrodefn">Check that the function has its namespace correctly declared</span> <span class="cwebmacronumber">3.4.2.5</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">declared_namespace</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">match_results</span><span class="plain"> </span><span class="identifier">mr</span><span class="plain"> = </span><span class="functiontext">Regexp::create_mr</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Regexp::match</span><span class="plain">(&amp;</span><span class="identifier">mr</span><span class="plain">, </span><span class="identifier">fname</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"(%c+::)%c*"</span><span class="plain">)) {</span>
<span class="identifier">declared_namespace</span><span class="plain"> = </span><span class="identifier">mr</span><span class="element">.exp</span><span class="plain">[0];</span>
<span class="identifier">fn</span><span class="plain">-</span><span class="element">&gt;within_namespace</span><span class="plain"> = </span><span class="constant">TRUE</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="functiontext">Str::eq_wide_string</span><span class="plain">(</span><span class="identifier">fname</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"main"</span><span class="plain">)) &amp;&amp; (</span><span class="functiontext">Str::eq_wide_string</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">-</span><span class="element">&gt;sect_namespace</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"Main::"</span><span class="plain">)))</span>
<span class="identifier">declared_namespace</span><span class="plain"> = </span><span class="identifier">I</span><span class="string">"Main::"</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Str::ne</span><span class="plain">(</span><span class="identifier">declared_namespace</span><span class="plain">, </span><span class="identifier">S</span><span class="plain">-</span><span class="element">&gt;sect_namespace</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">L</span><span class="plain">-</span><span class="element">&gt;owning_paragraph</span><span class="plain">-</span><span class="element">&gt;placed_very_early</span><span class="plain"> == </span><span class="constant">FALSE</span><span class="plain">)) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">err_mess</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Str::len</span><span class="plain">(</span><span class="identifier">declared_namespace</span><span class="plain">) == 0)</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">err_mess</span><span class="plain">, </span><span class="string">"Function '%S' should have namespace prefix '%S'"</span><span class="plain">,</span>
<span class="identifier">fname</span><span class="plain">, </span><span class="identifier">S</span><span class="plain">-</span><span class="element">&gt;sect_namespace</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="functiontext">Str::len</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">-</span><span class="element">&gt;sect_namespace</span><span class="plain">) == 0)</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">err_mess</span><span class="plain">, </span><span class="string">"Function '%S' declared in a section with no namespace"</span><span class="plain">,</span>
<span class="identifier">fname</span><span class="plain">);</span>
<span class="reserved">else</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">err_mess</span><span class="plain">, </span><span class="string">"Function '%S' declared in a section with the wrong namespace '%S'"</span><span class="plain">,</span>
<span class="identifier">fname</span><span class="plain">, </span><span class="identifier">S</span><span class="plain">-</span><span class="element">&gt;sect_namespace</span><span class="plain">);</span>
<span class="functiontext">Main::error_in_web</span><span class="plain">(</span><span class="identifier">err_mess</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">err_mess</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="functiontext">Regexp::dispose_of</span><span class="plain">(&amp;</span><span class="identifier">mr</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_4_2">&#167;3.4.2</a>.</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>The following
</p>
<pre class="display">
<span class="reserved">c_structure</span><span class="plain"> *</span><span class="functiontext">CLike::find_structure</span><span class="plain">(</span><span class="reserved">web</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">name</span><span class="plain">) {</span>
<span class="reserved">c_structure</span><span class="plain"> *</span><span class="identifier">str</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">str</span><span class="plain">, </span><span class="reserved">c_structure</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">-</span><span class="element">&gt;c_structures</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Str::eq</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">, </span><span class="identifier">str</span><span class="plain">-</span><span class="element">&gt;structure_name</span><span class="plain">))</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">str</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 CLike::find_structure appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. Subcategorisation. </b>The following is called after the parser gives every line in the web a
category; we can, if we wish, change that for a more exotic one. We simply
look for a <code class="display"><span class="extract">#include</span></code> of one of the ANSI C standard libraries.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CLike::subcategorise_code</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">self</span><span class="plain">, </span><span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain">) {</span>
<span class="reserved">match_results</span><span class="plain"> </span><span class="identifier">mr</span><span class="plain"> = </span><span class="functiontext">Regexp::create_mr</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Regexp::match</span><span class="plain">(&amp;</span><span class="identifier">mr</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">-</span><span class="element">&gt;text</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"#include &lt;(%C+)&gt;%c*"</span><span class="plain">)) {</span>
<span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">library_file</span><span class="plain"> = </span><span class="identifier">mr</span><span class="element">.exp</span><span class="plain">[0];</span>
<span class="identifier">wchar_t</span><span class="plain"> *</span><span class="identifier">ansi_libs</span><span class="plain">[] = {</span>
<span class="identifier">L</span><span class="string">"assert.h"</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"ctype.h"</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"errno.h"</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"float.h"</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"limits.h"</span><span class="plain">,</span>
<span class="identifier">L</span><span class="string">"locale.h"</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"math.h"</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"setjmp.h"</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"signal.h"</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"stdarg.h"</span><span class="plain">,</span>
<span class="identifier">L</span><span class="string">"stddef.h"</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"stdio.h"</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"stdlib.h"</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"string.h"</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"time.h"</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="reserved">int</span><span class="plain"> </span><span class="identifier">j</span><span class="plain"> = 0; </span><span class="identifier">ansi_libs</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="functiontext">Str::eq_wide_string</span><span class="plain">(</span><span class="identifier">library_file</span><span class="plain">, </span><span class="identifier">ansi_libs</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">]))</span>
<span class="identifier">L</span><span class="plain">-</span><span class="element">&gt;category</span><span class="plain"> = </span><span class="constant">C_LIBRARY_INCLUDE_LCAT</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="functiontext">Regexp::dispose_of</span><span class="plain">(&amp;</span><span class="identifier">mr</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function CLike::subcategorise_code is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. Tangling extras. </b>The "shebang" routine for a language is called to add anything it wants to
at the very top of the tangled code. (For a scripting language such as
Perl or Python, that might be a shebang: hence the name.)
</p>
<p class="inwebparagraph">But we will use it to defime the constant <code class="display"><span class="extract">PLATFORM_POSIX</span></code> everywhere except
Windows. This needs to happen right at the top, because the "very early
code" may contain material conditional on whether it is defined.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CLike::shebang</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">self</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">OUT</span><span class="plain">, </span><span class="reserved">web</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">, </span><span class="reserved">tangle_target</span><span class="plain"> *</span><span class="identifier">target</span><span class="plain">) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"#ifndef PLATFORM_WINDOWS\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"#define PLATFORM_POSIX\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"#endif\</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 CLike::shebang is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. </b>"Additional early matter" is used for the inclusions of the ANSI library
files. We need to do that early, because otherwise types declared in them
(such as <code class="display"><span class="extract">FILE</span></code>) won't exist in time for the structure definitions we will
be tangling next.
</p>
<p class="inwebparagraph">It might seem reasonable to move all <code class="display"><span class="extract">#include</span></code> files up front this way,
not just the ANSI ones. But that would defeat any conditional compilation
around the inclusions; which Inform (for instance) needs in order to make
platform-specific details to handle directories without POSIX in Windows.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CLike::additional_early_matter</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">self</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">OUT</span><span class="plain">, </span><span class="reserved">web</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">, </span><span class="reserved">tangle_target</span><span class="plain"> *</span><span class="identifier">target</span><span class="plain">) {</span>
<span class="reserved">chapter</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain">;</span>
<span class="reserved">section</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">;</span>
<span class="identifier">LOOP_WITHIN_TANGLE</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">target</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">L</span><span class="plain">-</span><span class="element">&gt;category</span><span class="plain"> == </span><span class="constant">C_LIBRARY_INCLUDE_LCAT</span><span class="plain">) {</span>
<span class="functiontext">Tags::open_ifdefs</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">-</span><span class="element">&gt;owning_paragraph</span><span class="plain">);</span>
<span class="functiontext">Tangler::tangle_code</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">-</span><span class="element">&gt;text</span><span class="plain">, </span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">L</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="functiontext">Tags::close_ifdefs</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">-</span><span class="element">&gt;owning_paragraph</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function CLike::additional_early_matter is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. </b></p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">CLike::start_definition</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">self</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">OUT</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">term</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">start</span><span class="plain">, </span><span class="reserved">section</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">, </span><span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain">) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"#define %S "</span><span class="plain">, </span><span class="identifier">term</span><span class="plain">);</span>
<span class="functiontext">Tangler::tangle_code</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">start</span><span class="plain">, </span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="constant">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">CLike::prolong_definition</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">self</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">OUT</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">more</span><span class="plain">, </span><span class="reserved">section</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">, </span><span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain">) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"\</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">Tangler::tangle_code</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">more</span><span class="plain">, </span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="constant">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">CLike::end_definition</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">self</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">OUT</span><span class="plain">, </span><span class="reserved">section</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">, </span><span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">L</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="reserved">return</span><span class="plain"> </span><span class="constant">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function CLike::start_definition is used in <a href="#SP2">&#167;2</a>.</p>
<p class="endnote">The function CLike::prolong_definition is used in <a href="#SP2">&#167;2</a>.</p>
<p class="endnote">The function CLike::end_definition is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. Tangling predeclarations. </b>This is where a language gets the chance to tangle predeclarations, early
on in the file. We use it first for the structures, and then the functions &mdash;
2019-02-04 22:26:45 +00:00
in that order since the function types likely involve the typedef names for the
structures.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CLike::additional_predeclarations</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">self</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">OUT</span><span class="plain">, </span><span class="reserved">web</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">) {</span>
&lt;<span class="cwebmacro">Predeclare the structures in a well-founded order</span> <span class="cwebmacronumber">9.2</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Predeclare simple typedefs</span> <span class="cwebmacronumber">9.1</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Predeclare the functions</span> <span class="cwebmacronumber">9.4</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function CLike::additional_predeclarations is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP9_1"></a><b>&#167;9.1. </b>A "simple typedef" here means one that is aliasing something other than
a structure: for example <code class="display"><span class="extract">typedef unsigned int uint;</span></code> would be a simple typedef.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Predeclare simple typedefs</span> <span class="cwebmacronumber">9.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">chapter</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain">;</span>
<span class="reserved">section</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">;</span>
<span class="identifier">LOOP_WITHIN_TANGLE</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">S</span><span class="plain">, </span><span class="functiontext">Tangler::primary_target</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">L</span><span class="plain">-</span><span class="element">&gt;category</span><span class="plain"> == </span><span class="constant">TYPEDEF_LCAT</span><span class="plain">) {</span>
<span class="functiontext">Tags::open_ifdefs</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">-</span><span class="element">&gt;owning_paragraph</span><span class="plain">);</span>
<span class="functiontext">Languages::tangle_code</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">-</span><span class="element">&gt;main_language</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">-</span><span class="element">&gt;text</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="functiontext">Tags::close_ifdefs</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">-</span><span class="element">&gt;owning_paragraph</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP9_2"></a><b>&#167;9.2. </b>It's easy enough to make sure structures are tangled so that inner ones
precede outer, but we need to be careful to be terminating if the source
code we're given is not well founded because of an error by its programmer:
for example, that structure A contains B contains C contains A. We do this
with the <code class="display"><span class="extract">tangled</span></code> flag, which is <code class="display"><span class="extract">FALSE</span></code> if a structure hasn't been
started yet, <code class="display"><span class="extract">NOT_APPLICABLE</span></code> if it's in progress, and <code class="display"><span class="extract">TRUE</span></code> if it's
finished.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Predeclare the structures in a well-founded order</span> <span class="cwebmacronumber">9.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">c_structure</span><span class="plain"> *</span><span class="identifier">str</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">str</span><span class="plain">, </span><span class="reserved">c_structure</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">-</span><span class="element">&gt;c_structures</span><span class="plain">)</span>
<span class="identifier">str</span><span class="plain">-</span><span class="element">&gt;tangled</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">str</span><span class="plain">, </span><span class="reserved">c_structure</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">-</span><span class="element">&gt;c_structures</span><span class="plain">)</span>
<span class="functiontext">CLike::tangle_structure</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">self</span><span class="plain">, </span><span class="identifier">str</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP9_3"></a><b>&#167;9.3. </b>Using the following recursion, which is therefore terminating:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CLike::tangle_structure</span><span class="plain">(</span><span class="constant">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">self</span><span class="plain">, </span><span class="reserved">c_structure</span><span class="plain"> *</span><span class="identifier">str</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">str</span><span class="plain">-</span><span class="element">&gt;tangled</span><span class="plain"> != </span><span class="constant">FALSE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="identifier">str</span><span class="plain">-</span><span class="element">&gt;tangled</span><span class="plain"> = </span><span class="constant">NOT_APPLICABLE</span><span class="plain">;</span>
<span class="reserved">c_structure</span><span class="plain"> *</span><span class="identifier">embodied</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">embodied</span><span class="plain">, </span><span class="reserved">c_structure</span><span class="plain">, </span><span class="identifier">str</span><span class="plain">-</span><span class="element">&gt;incorporates</span><span class="plain">)</span>
<span class="functiontext">CLike::tangle_structure</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">self</span><span class="plain">, </span><span class="identifier">embodied</span><span class="plain">);</span>
<span class="identifier">str</span><span class="plain">-</span><span class="element">&gt;tangled</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">;</span>
<span class="functiontext">Tags::open_ifdefs</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">str</span><span class="plain">-</span><span class="element">&gt;typedef_begins</span><span class="plain">-</span><span class="element">&gt;owning_paragraph</span><span class="plain">);</span>
<span class="functiontext">Languages::insert_line_marker</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">self</span><span class="plain">, </span><span class="identifier">str</span><span class="plain">-</span><span class="element">&gt;typedef_begins</span><span class="plain">);</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain"> = </span><span class="identifier">str</span><span class="plain">-</span><span class="element">&gt;typedef_begins</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="identifier">L</span><span class="plain">-</span><span class="element">&gt;next_line</span><span class="plain">) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%S\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">-</span><span class="element">&gt;text</span><span class="plain">);</span>
<span class="identifier">L</span><span class="plain">-</span><span class="element">&gt;suppress_tangling</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">L</span><span class="plain"> == </span><span class="identifier">str</span><span class="plain">-</span><span class="element">&gt;typedef_ends</span><span class="plain">) </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="functiontext">Tags::close_ifdefs</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">str</span><span class="plain">-</span><span class="element">&gt;typedef_begins</span><span class="plain">-</span><span class="element">&gt;owning_paragraph</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function CLike::tangle_structure is used in <a href="#SP9_2">&#167;9.2</a>.</p>
<p class="inwebparagraph"><a id="SP9_4"></a><b>&#167;9.4. </b>Functions are rather easier to deal with. In general, if a function was
defined within some number of nested <code class="display"><span class="extract">#ifdef</span></code> or <code class="display"><span class="extract">#ifndef</span></code> directives, then
we reproduce those around the predeclaration: except, as a special trick,
if the line contains a particular comment. For example:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">#ifdef SOLARIS /* inweb: always predeclare */</span>
</pre>
<p class="inwebparagraph">That exempts any functions inside this condition from meeting the condition
in order to be predeclared. It's a trick used in the foundation module just
a couple of times: the idea is that although a definition of the functions
is given which only works under SOLARIS, an external piece of code will
provide alternative function definitions which would work without SOLARIS.
The functions therefore need predeclaration regardless, because they will
exist either way.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Predeclare the functions</span> <span class="cwebmacronumber">9.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">chapter</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain">;</span>
<span class="reserved">section</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">;</span>
<span class="identifier">LOOP_WITHIN_TANGLE</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">S</span><span class="plain">, </span><span class="functiontext">Tangler::primary_target</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">L</span><span class="plain">-</span><span class="element">&gt;function_defined</span><span class="plain">) &amp;&amp; (</span><span class="identifier">L</span><span class="plain">-</span><span class="element">&gt;owning_paragraph</span><span class="plain">-</span><span class="element">&gt;placed_very_early</span><span class="plain"> == </span><span class="constant">FALSE</span><span class="plain">)) {</span>
<span class="reserved">function</span><span class="plain"> *</span><span class="identifier">fn</span><span class="plain"> = </span><span class="identifier">L</span><span class="plain">-</span><span class="element">&gt;function_defined</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">to_close</span><span class="plain"> = 0;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">fn</span><span class="plain">-</span><span class="element">&gt;no_conditionals</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) {</span>
<span class="reserved">match_results</span><span class="plain"> </span><span class="identifier">mr</span><span class="plain"> = </span><span class="functiontext">Regexp::create_mr</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (!(</span><span class="functiontext">Regexp::match</span><span class="plain">(&amp;</span><span class="identifier">mr</span><span class="plain">, </span><span class="identifier">fn</span><span class="plain">-</span><span class="element">&gt;within_conditionals</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]-</span><span class="element">&gt;text</span><span class="plain">,</span>
<span class="identifier">L</span><span class="string">"%c*inweb: always predeclare%c*"</span><span class="plain">))) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%S\</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="element">&gt;within_conditionals</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]-</span><span class="element">&gt;text</span><span class="plain">);</span>
<span class="identifier">to_close</span><span class="plain">++;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="functiontext">Tags::open_ifdefs</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">-</span><span class="element">&gt;owning_paragraph</span><span class="plain">);</span>
<span class="functiontext">Languages::insert_line_marker</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">-</span><span class="element">&gt;main_language</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%S "</span><span class="plain">, </span><span class="identifier">fn</span><span class="plain">-</span><span class="element">&gt;function_type</span><span class="plain">);</span>
<span class="functiontext">Languages::tangle_code</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">-</span><span class="element">&gt;main_language</span><span class="plain">, </span><span class="identifier">fn</span><span class="plain">-</span><span class="element">&gt;function_name</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"(%S;\</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="element">&gt;function_arguments</span><span class="plain">);</span>
<span class="functiontext">Tags::close_ifdefs</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">-</span><span class="element">&gt;owning_paragraph</span><span class="plain">);</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">to_close</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"#endif\</span><span class="plain">n</span><span class="string">"</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="#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. Line markers. </b>In order for C compilers to report C syntax errors on the correct line,
despite rearranging by automatic tools, C conventionally recognises the
preprocessor directive <code class="display"><span class="extract">#line</span></code> to tell it that a contiguous extract follows
from the given file; we generate this automatically.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CLike::insert_line_marker</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">self</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">OUT</span><span class="plain">, </span><span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain">) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"#line %d \</span><span class="plain">"</span><span class="string">%/f\</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">L</span><span class="plain">-</span><span class="element">&gt;source.line_count</span><span class="plain">,</span>
<span class="identifier">L</span><span class="plain">-</span><span class="element">&gt;source.text_file_filename</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function CLike::insert_line_marker is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP11"></a><b>&#167;11. Comments. </b>We write comments the old-fashioned way, that is, not using <code class="display"><span class="extract">//</span></code>.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CLike::comment</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">self</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">OUT</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">comm</span><span class="plain">) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"/* %S */\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">comm</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function CLike::comment is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP12"></a><b>&#167;12. </b>When parsing, we do recognise <code class="display"><span class="extract">//</span></code> comments, but we have to be careful not to
react to comment markers inside comments or double-qupted text which is outside
of comments, all of which makes this a little elaborate:
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">CLike::parse_comment</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">self</span><span class="plain">,</span>
<span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">line</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">part_before_comment</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">part_within_comment</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">q_mode</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">, </span><span class="identifier">c_mode</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">, </span><span class="identifier">non_white_space</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">, </span><span class="identifier">c_position</span><span class="plain"> = -1, </span><span class="identifier">c_end</span><span class="plain"> = -1;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="functiontext">Str::len</span><span class="plain">(</span><span class="identifier">line</span><span class="plain">); </span><span class="identifier">i</span><span class="plain">++) {</span>
<span class="identifier">wchar_t</span><span class="plain"> </span><span class="identifier">c</span><span class="plain"> = </span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">line</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">c_mode</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">'*'</span><span class="plain">) {</span>
<span class="identifier">wchar_t</span><span class="plain"> </span><span class="identifier">d</span><span class="plain"> = </span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">line</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">+1);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">d</span><span class="plain"> == </span><span class="character">'/'</span><span class="plain">) { </span><span class="identifier">c_mode</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">; </span><span class="identifier">c_end</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="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="functiontext">Characters::is_whitespace</span><span class="plain">(</span><span class="identifier">c</span><span class="plain">))) </span><span class="identifier">non_white_space</span><span class="plain"> = </span><span class="constant">TRUE</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">'\</span><span class="plain">\</span><span class="character">'</span><span class="plain">) &amp;&amp; (</span><span class="identifier">q_mode</span><span class="plain">)) </span><span class="identifier">i</span><span class="plain"> += 1;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">c</span><span class="plain"> == </span><span class="character">'"'</span><span class="plain">) </span><span class="identifier">q_mode</span><span class="plain"> = </span><span class="identifier">q_mode</span><span class="plain">?</span><span class="constant">FALSE</span><span class="plain">:</span><span class="constant">TRUE</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">'/'</span><span class="plain">) &amp;&amp; (!</span><span class="identifier">q_mode</span><span class="plain">)) {</span>
<span class="identifier">wchar_t</span><span class="plain"> </span><span class="identifier">d</span><span class="plain"> = </span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">line</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">+1);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">d</span><span class="plain"> == </span><span class="character">'/'</span><span class="plain">) { </span><span class="identifier">c_mode</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">; </span><span class="identifier">c_position</span><span class="plain"> = </span><span class="identifier">i</span><span class="plain">; </span><span class="identifier">c_end</span><span class="plain"> = </span><span class="functiontext">Str::len</span><span class="plain">(</span><span class="identifier">line</span><span class="plain">); </span><span class="identifier">non_white_space</span><span class="plain"> = </span><span class="constant">FALSE</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">d</span><span class="plain"> == </span><span class="character">'*'</span><span class="plain">) { </span><span class="identifier">c_mode</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">; </span><span class="identifier">c_position</span><span class="plain"> = </span><span class="identifier">i</span><span class="plain">; </span><span class="identifier">non_white_space</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">; }</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">c_position</span><span class="plain"> &gt;= 0) &amp;&amp; (</span><span class="identifier">non_white_space</span><span class="plain"> == </span><span class="constant">FALSE</span><span class="plain">)) {</span>
<span class="functiontext">Str::clear</span><span class="plain">(</span><span class="identifier">part_before_comment</span><span class="plain">);</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">c_position</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">PUT_TO</span><span class="plain">(</span><span class="identifier">part_before_comment</span><span class="plain">, </span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">line</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">));</span>
<span class="functiontext">Str::clear</span><span class="plain">(</span><span class="identifier">part_within_comment</span><span class="plain">);</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=</span><span class="identifier">c_position</span><span class="plain"> + 2; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">c_end</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">PUT_TO</span><span class="plain">(</span><span class="identifier">part_within_comment</span><span class="plain">, </span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">line</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">));</span>
<span class="functiontext">Str::trim_white_space</span><span class="plain">(</span><span class="identifier">part_within_comment</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="constant">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="constant">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function CLike::parse_comment is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP13"></a><b>&#167;13. Ifdefs. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CLike::open_ifdef</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">self</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">OUT</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">symbol</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">sense</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sense</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"#ifdef %S\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">symbol</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">"#ifndef %S\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">symbol</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CLike::close_ifdef</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">self</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">OUT</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">symbol</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">sense</span><span class="plain">) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"#endif /* %S */\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">symbol</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function CLike::open_ifdef is used in <a href="#SP2">&#167;2</a>.</p>
<p class="endnote">The function CLike::close_ifdef is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP14"></a><b>&#167;14. Before and after expansion. </b>Places braces before and after expanded paragraph macros ensures that code like
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">if (x == y) @&lt;Do something dramatic@&gt;;</span>
</pre>
<p class="inwebparagraph">tangles to something like this:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">if (x == y)</span>
<span class="plain">{</span>
<span class="plain">...</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph">so that the variables defined inside the macro have limited scope, and so that
multi-line macros are treated as a single statement by <code class="display"><span class="extract">if</span></code>, <code class="display"><span class="extract">while</span></code> and so on.
(The new-line before the opening brace protects us against problems with
Perl comments; Perl shares this code.)
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CLike::before_macro_expansion</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">self</span><span class="plain">, </span><span class="constant">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">para_macro</span><span class="plain"> *</span><span class="identifier">pmac</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">n</span><span class="string">"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CLike::after_macro_expansion</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">self</span><span class="plain">, </span><span class="constant">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">para_macro</span><span class="plain"> *</span><span class="identifier">pmac</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 CLike::before_macro_expansion is used in <a href="#SP2">&#167;2</a>.</p>
<p class="endnote">The function CLike::after_macro_expansion is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP15"></a><b>&#167;15. Begin weave. </b>We use this opportunity only to register C's usual set of reserved words as
being of interest for syntax colouring. <code class="display"><span class="extract">FILE</span></code> gets in even though it's not
technically reserved but only a type name, defined in the standard C library.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CLike::begin_weave</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">self</span><span class="plain">, </span><span class="reserved">section</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">, </span><span class="reserved">weave_target</span><span class="plain"> *</span><span class="identifier">wv</span><span class="plain">) {</span>
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"FILE"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"auto"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"break"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"case"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"char"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"const"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"continue"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"default"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"do"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"double"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"else"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"enum"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"extern"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"float"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"for"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"goto"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"if"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"int"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"long"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"register"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"return"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"short"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"signed"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"sizeof"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"static"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"struct"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"switch"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"typedef"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"union"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"unsigned"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"void"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"volatile"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"while"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function CLike::begin_weave is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP16"></a><b>&#167;16. Syntax colouring. </b>This is a very simple syntax colouring algorithm. The state at any given
time is a single variable, the current category of code being looked at:
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">colouring_state</span><span class="plain"> = </span><span class="constant">PLAIN_COLOUR</span><span class="plain">;</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CLike::reset_syntax_colouring</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">self</span><span class="plain">) {</span>
<span class="identifier">colouring_state</span><span class="plain"> = </span><span class="constant">PLAIN_COLOUR</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function CLike::reset_syntax_colouring is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP17"></a><b>&#167;17. </b></p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">CLike::syntax_colour</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">self</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">OUT</span><span class="plain">, </span><span class="reserved">weave_target</span><span class="plain"> *</span><span class="identifier">wv</span><span class="plain">,</span>
<span class="reserved">web</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">, </span><span class="reserved">chapter</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain">, </span><span class="reserved">section</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">, </span><span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">matter</span><span class="plain">,</span>
<span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">colouring</span><span class="plain">) {</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain"> &lt; </span><span class="functiontext">Str::len</span><span class="plain">(</span><span class="identifier">matter</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">skip</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">, </span><span class="identifier">one_off</span><span class="plain"> = -1, </span><span class="identifier">will_be</span><span class="plain"> = -1;</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">colouring_state</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">PLAIN_COLOUR</span><span class="plain">:</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">matter</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">)) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="character">'\</span><span class="plain">"</span><span class="character">'</span><span class="plain">: </span><span class="identifier">colouring_state</span><span class="plain"> = </span><span class="constant">STRING_COLOUR</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="character">'\</span><span class="plain">'</span><span class="character">'</span><span class="plain">: </span><span class="identifier">colouring_state</span><span class="plain"> = </span><span class="constant">CHAR_LITERAL_COLOUR</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Regexp::identifier_char</span><span class="plain">(</span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">matter</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">))) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">matter</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">) != </span><span class="character">':'</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> ((!(</span><span class="identifier">isdigit</span><span class="plain">(</span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">matter</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">)))) ||</span>
<span class="plain">((</span><span class="identifier">i</span><span class="plain">&gt;0) &amp;&amp; (</span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">colouring</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">-1) == </span><span class="constant">IDENTIFIER_COLOUR</span><span class="plain">)))</span>
<span class="identifier">one_off</span><span class="plain"> = </span><span class="constant">IDENTIFIER_COLOUR</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">CHAR_LITERAL_COLOUR</span><span class="plain">:</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">matter</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">)) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="character">'\</span><span class="plain">\</span><span class="character">'</span><span class="plain">: </span><span class="identifier">skip</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="character">'\</span><span class="plain">'</span><span class="character">'</span><span class="plain">: </span><span class="identifier">will_be</span><span class="plain"> = </span><span class="constant">PLAIN_COLOUR</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">STRING_COLOUR</span><span class="plain">:</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">matter</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">)) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="character">'\</span><span class="plain">\</span><span class="character">'</span><span class="plain">: </span><span class="identifier">skip</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="character">'\</span><span class="plain">"</span><span class="character">'</span><span class="plain">: </span><span class="identifier">will_be</span><span class="plain"> = </span><span class="constant">PLAIN_COLOUR</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">one_off</span><span class="plain"> &gt;= 0) </span><span class="functiontext">Str::put_at</span><span class="plain">(</span><span class="identifier">colouring</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">one_off</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="functiontext">Str::put_at</span><span class="plain">(</span><span class="identifier">colouring</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">colouring_state</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">will_be</span><span class="plain"> &gt;= 0) </span><span class="identifier">colouring_state</span><span class="plain"> = (</span><span class="reserved">char</span><span class="plain">) </span><span class="identifier">will_be</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">skip</span><span class="plain">) &amp;&amp; (</span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">matter</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">+1))) </span><span class="identifier">i</span><span class="plain">++;</span>
<span class="plain">}</span>
&lt;<span class="cwebmacro">Find identifiers and colour them appropriately</span> <span class="cwebmacronumber">17.1</span>&gt;<span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="constant">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function CLike::syntax_colour is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP17_1"></a><b>&#167;17.1. </b>Note that an identifier, followed by <code class="display"><span class="extract">::</span></code> and then another identifier, is
merged here into one long identifier. Thus in the code <code class="display"><span class="extract">r = X::Y(1);</span></code>, the
above routine would identify three identifiers, <code class="display"><span class="extract">r</span></code>, <code class="display"><span class="extract">X</span></code> and <code class="display"><span class="extract">Y</span></code>; but the
code below merges these into <code class="display"><span class="extract">r</span></code> and <code class="display"><span class="extract">X::Y</span></code>.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Find identifiers and colour them appropriately</span> <span class="cwebmacronumber">17.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">ident_from</span><span class="plain"> = -1;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain"> &lt; </span><span class="functiontext">Str::len</span><span class="plain">(</span><span class="identifier">matter</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="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">matter</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="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">matter</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">+1) == </span><span class="character">':'</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">colouring</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">-1) == </span><span class="constant">IDENTIFIER_COLOUR</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">colouring</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">+2) == </span><span class="constant">IDENTIFIER_COLOUR</span><span class="plain">)) {</span>
<span class="functiontext">Str::put_at</span><span class="plain">(</span><span class="identifier">colouring</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">, </span><span class="constant">IDENTIFIER_COLOUR</span><span class="plain">);</span>
<span class="functiontext">Str::put_at</span><span class="plain">(</span><span class="identifier">colouring</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">+1, </span><span class="constant">IDENTIFIER_COLOUR</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">colouring</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">) == </span><span class="constant">IDENTIFIER_COLOUR</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ident_from</span><span class="plain"> == -1) </span><span class="identifier">ident_from</span><span class="plain"> = </span><span class="identifier">i</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">ident_from</span><span class="plain"> &gt;= 0)</span>
<span class="functiontext">CLike::colour_ident</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">matter</span><span class="plain">, </span><span class="identifier">colouring</span><span class="plain">, </span><span class="identifier">ident_from</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">-1);</span>
<span class="identifier">ident_from</span><span class="plain"> = -1;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ident_from</span><span class="plain"> &gt;= 0)</span>
<span class="functiontext">CLike::colour_ident</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">matter</span><span class="plain">, </span><span class="identifier">colouring</span><span class="plain">, </span><span class="identifier">ident_from</span><span class="plain">, </span><span class="functiontext">Str::len</span><span class="plain">(</span><span class="identifier">matter</span><span class="plain">)-1);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP17">&#167;17</a>.</p>
<p class="inwebparagraph"><a id="SP18"></a><b>&#167;18. </b>Here we look at a word made up of identifier characters &mdash; such as <code class="display"><span class="extract">int</span></code>, <code class="display"><span class="extract">X</span></code>,
or <code class="display"><span class="extract">CLike::colour_ident</span></code> &mdash; and decide whether to recolour its characters on
the basis of what it means.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CLike::colour_ident</span><span class="plain">(</span><span class="reserved">section</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">matter</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">colouring</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">from</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">to</span><span class="plain">) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">id</span><span class="plain">);</span>
<span class="functiontext">Str::substr</span><span class="plain">(</span><span class="identifier">id</span><span class="plain">, </span><span class="functiontext">Str::at</span><span class="plain">(</span><span class="identifier">matter</span><span class="plain">, </span><span class="identifier">from</span><span class="plain">), </span><span class="functiontext">Str::at</span><span class="plain">(</span><span class="identifier">matter</span><span class="plain">, </span><span class="identifier">to</span><span class="plain">+1));</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">override</span><span class="plain"> = -1;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Analyser::is_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">id</span><span class="plain">, </span><span class="constant">FUNCTION_COLOUR</span><span class="plain">)) </span><span class="identifier">override</span><span class="plain"> = </span><span class="constant">FUNCTION_COLOUR</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Analyser::is_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">id</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">)) </span><span class="identifier">override</span><span class="plain"> = </span><span class="constant">RESERVED_COLOUR</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Analyser::is_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">id</span><span class="plain">, </span><span class="constant">CONSTANT_COLOUR</span><span class="plain">)) </span><span class="identifier">override</span><span class="plain"> = </span><span class="constant">CONSTANT_COLOUR</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Analyser::is_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">id</span><span class="plain">, </span><span class="constant">ELEMENT_COLOUR</span><span class="plain">)) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">at</span><span class="plain"> = --</span><span class="identifier">from</span><span class="plain">;</span>
<span class="reserved">while</span><span class="plain"> ((</span><span class="identifier">at</span><span class="plain"> &gt; 0) &amp;&amp; (</span><span class="functiontext">Characters::is_space_or_tab</span><span class="plain">(</span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">matter</span><span class="plain">, </span><span class="identifier">at</span><span class="plain">)))) </span><span class="identifier">at</span><span class="plain">--;</span>
<span class="reserved">if</span><span class="plain"> (((</span><span class="identifier">at</span><span class="plain"> &gt;= 0) &amp;&amp; (</span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">matter</span><span class="plain">, </span><span class="identifier">at</span><span class="plain">) == </span><span class="character">'.'</span><span class="plain">)) ||</span>
<span class="plain">((</span><span class="identifier">at</span><span class="plain"> &gt;= 0) &amp;&amp; (</span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">matter</span><span class="plain">, </span><span class="identifier">at</span><span class="plain">-1) == </span><span class="character">'-'</span><span class="plain">) &amp;&amp; (</span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">matter</span><span class="plain">, </span><span class="identifier">at</span><span class="plain">) == </span><span class="character">'&gt;'</span><span class="plain">)))</span>
<span class="identifier">override</span><span class="plain"> = </span><span class="constant">ELEMENT_COLOUR</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">override</span><span class="plain"> &gt;= 0)</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">=</span><span class="identifier">from</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">&lt;=</span><span class="identifier">to</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++)</span>
<span class="functiontext">Str::put_at</span><span class="plain">(</span><span class="identifier">colouring</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">override</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">id</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function CLike::colour_ident is used in <a href="#SP17_1">&#167;17.1</a>.</p>
<p class="inwebparagraph"><a id="SP19"></a><b>&#167;19. Overriding regular code weaving. </b>We have the opportunity here to sidestep the regular weaving algorithm, and do
our own thing. We decline.
</p>
<p class="inwebparagraph"><a id="SP20"></a><b>&#167;20. Analysis. </b>This implements the additional information in the <code class="display"><span class="extract">-structures</span></code> and <code class="display"><span class="extract">-functions</span></code>
fprms of section catalogue.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CLike::catalogue</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">self</span><span class="plain">, </span><span class="reserved">section</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">functions_too</span><span class="plain">) {</span>
<span class="reserved">c_structure</span><span class="plain"> *</span><span class="identifier">str</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">str</span><span class="plain">, </span><span class="reserved">c_structure</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">str</span><span class="plain">-</span><span class="element">&gt;typedef_begins</span><span class="plain">-</span><span class="element">&gt;owning_section</span><span class="plain"> == </span><span class="identifier">S</span><span class="plain">)</span>
<span class="identifier">PRINT</span><span class="plain">(</span><span class="string">" %S "</span><span class="plain">, </span><span class="identifier">str</span><span class="plain">-</span><span class="element">&gt;structure_name</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">functions_too</span><span class="plain">) {</span>
<span class="reserved">function</span><span class="plain"> *</span><span class="identifier">fn</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">fn</span><span class="plain">, </span><span class="reserved">function</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">fn</span><span class="plain">-</span><span class="element">&gt;function_header_at</span><span class="plain">-</span><span class="element">&gt;owning_section</span><span class="plain"> == </span><span class="identifier">S</span><span class="plain">)</span>
<span class="identifier">PRINT</span><span class="plain">(</span><span class="string">"\</span><span class="plain">n</span><span class="string"> %S"</span><span class="plain">, </span><span class="identifier">fn</span><span class="plain">-</span><span class="element">&gt;function_name</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function CLike::catalogue is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP21"></a><b>&#167;21. </b>Having found all those functions and structure elements, we make sure they
are all known to Inweb's hash table of interesting identifiers:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CLike::analyse_code</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">self</span><span class="plain">, </span><span class="reserved">web</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">) {</span>
<span class="reserved">function</span><span class="plain"> *</span><span class="identifier">fn</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">fn</span><span class="plain">, </span><span class="reserved">function</span><span class="plain">)</span>
<span class="functiontext">Analyser::find_hash_entry</span><span class="plain">(</span><span class="identifier">fn</span><span class="plain">-</span><span class="element">&gt;function_header_at</span><span class="plain">-</span><span class="element">&gt;owning_section</span><span class="plain">, </span><span class="identifier">fn</span><span class="plain">-</span><span class="element">&gt;function_name</span><span class="plain">, </span><span class="constant">TRUE</span><span class="plain">);</span>
<span class="reserved">c_structure</span><span class="plain"> *</span><span class="identifier">str</span><span class="plain">;</span>
<span class="reserved">structure_element</span><span class="plain"> *</span><span class="identifier">elt</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">str</span><span class="plain">, </span><span class="reserved">c_structure</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">-</span><span class="element">&gt;c_structures</span><span class="plain">)</span>
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">elt</span><span class="plain">, </span><span class="reserved">structure_element</span><span class="plain">, </span><span class="identifier">str</span><span class="plain">-</span><span class="element">&gt;elements</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">elt</span><span class="plain">-</span><span class="element">&gt;allow_sharing</span><span class="plain"> == </span><span class="constant">FALSE</span><span class="plain">)</span>
<span class="functiontext">Analyser::find_hash_entry</span><span class="plain">(</span><span class="identifier">elt</span><span class="plain">-</span><span class="element">&gt;element_created_at</span><span class="plain">-</span><span class="element">&gt;owning_section</span><span class="plain">,</span>
<span class="identifier">elt</span><span class="plain">-</span><span class="element">&gt;element_name</span><span class="plain">, </span><span class="constant">TRUE</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function CLike::analyse_code is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP22"></a><b>&#167;22. </b>The following is an opportunity for us to scold the author for any
specifically C-like errors. We're going to look for functions named
<code class="display"><span class="extract">Whatever::name()</span></code> whose definitions are not in the <code class="display"><span class="extract">Whatever::</span></code> section;
in other words, we police the rule that functions actually are defined in the
namespace which their names imply. This can be turned off with a special
bibliographic variable, but don't do that.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CLike::post_analysis</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">self</span><span class="plain">, </span><span class="reserved">web</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">check_namespaces</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Str::eq_wide_string</span><span class="plain">(</span><span class="functiontext">Bibliographic::get_datum</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Namespaces"</span><span class="plain">), </span><span class="identifier">L</span><span class="string">"On"</span><span class="plain">)) </span><span class="identifier">check_namespaces</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">;</span>
<span class="reserved">function</span><span class="plain"> *</span><span class="identifier">fn</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">fn</span><span class="plain">, </span><span class="reserved">function</span><span class="plain">) {</span>
<span class="reserved">hash_table_entry</span><span class="plain"> *</span><span class="identifier">hte</span><span class="plain"> =</span>
<span class="functiontext">Analyser::find_hash_entry</span><span class="plain">(</span><span class="identifier">fn</span><span class="plain">-</span><span class="element">&gt;function_header_at</span><span class="plain">-</span><span class="element">&gt;owning_section</span><span class="plain">, </span><span class="identifier">fn</span><span class="plain">-</span><span class="element">&gt;function_name</span><span class="plain">, </span><span class="constant">FALSE</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">hte</span><span class="plain">) {</span>
<span class="reserved">hash_table_entry_usage</span><span class="plain"> *</span><span class="identifier">hteu</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">hteu</span><span class="plain">, </span><span class="reserved">hash_table_entry_usage</span><span class="plain">, </span><span class="identifier">hte</span><span class="plain">-</span><span class="element">&gt;usages</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">hteu</span><span class="plain">-</span><span class="element">&gt;form_of_usage</span><span class="plain"> &amp; </span><span class="constant">FCALL_USAGE</span><span class="plain">) || (</span><span class="identifier">fn</span><span class="plain">-</span><span class="element">&gt;within_namespace</span><span class="plain">))</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">hteu</span><span class="plain">-</span><span class="element">&gt;usage_recorded_at</span><span class="plain">-</span><span class="element">&gt;under_section</span><span class="plain"> != </span><span class="identifier">fn</span><span class="plain">-</span><span class="element">&gt;function_header_at</span><span class="plain">-</span><span class="element">&gt;owning_section</span><span class="plain">)</span>
<span class="identifier">fn</span><span class="plain">-</span><span class="element">&gt;called_from_other_sections</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">fn</span><span class="plain">-</span><span class="element">&gt;within_namespace</span><span class="plain"> != </span><span class="identifier">fn</span><span class="plain">-</span><span class="element">&gt;called_from_other_sections</span><span class="plain">)</span>
<span class="plain">&amp;&amp; (</span><span class="identifier">check_namespaces</span><span class="plain">)</span>
<span class="plain">&amp;&amp; (</span><span class="identifier">fn</span><span class="plain">-</span><span class="element">&gt;call_freely</span><span class="plain"> == </span><span class="constant">FALSE</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">fn</span><span class="plain">-</span><span class="element">&gt;within_namespace</span><span class="plain">)</span>
<span class="functiontext">Main::error_in_web</span><span class="plain">(</span>
<span class="identifier">I</span><span class="string">"Being internally called, this function mustn't belong to a :: namespace"</span><span class="plain">,</span>
<span class="identifier">fn</span><span class="plain">-</span><span class="element">&gt;function_header_at</span><span class="plain">);</span>
<span class="reserved">else</span>
<span class="functiontext">Main::error_in_web</span><span class="plain">(</span>
<span class="identifier">I</span><span class="string">"Being externally called, this function must belong to a :: namespace"</span><span class="plain">,</span>
<span class="identifier">fn</span><span class="plain">-</span><span class="element">&gt;function_header_at</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 CLike::post_analysis is used in <a href="#SP2">&#167;2</a>.</p>
2019-03-12 23:32:12 +00:00
<hr class="tocbar">
<ul class="toc"><li><a href="4-pl.html">Back to 'Programming Languages'</a></li><li><a href="4-is.html">Continue with 'InC Support'</a></li></ul><hr class="tocbar">
2019-03-17 12:53:52 +00:00
<!--End of weave: 1014 lines from a web of 21211-->
2019-02-04 22:26:45 +00:00
</body>
</html>