1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-08 18:14:21 +03:00
inform7/docs/words-module/3-tff.html
2019-04-22 15:42:10 +01:00

238 lines
30 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>3/wrd</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<!--Weave of '3/tff' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">words</a></li><li><a href="index.html#3">Chapter 3: Words in Sequence</a></li><li><b>Text From Files</b></li></ul><p class="purpose">This is where source text is read in, whether from extension files or from the main source text file, and fed into the lexer.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Source files</a></li><li><a href="#SP2">&#167;2. Feeding whole files into the lexer</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Source files. </b>Each separate file of text read into the lexer has its identity docketed
in a <code class="display"><span class="extract">source_file</span></code> structure, as follows.
</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">source_file</span><span class="plain"> {</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">filename</span><span class="plain"> *</span><span class="identifier">name</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">words_of_source</span><span class="plain">; </span> <span class="comment">word count, omitting comments and verbatim matter</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">wording</span><span class="plain"> </span><span class="identifier">text_read</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">words_of_quoted_text</span><span class="plain">; </span> <span class="comment">word count for text in double-quotes</span>
<span class="reserved">FILE</span><span class="plain"> *</span><span class="identifier">handle</span><span class="plain">; </span> <span class="comment">file handle while open</span>
<span class="identifier">general_pointer</span><span class="plain"> </span><span class="identifier">your_ref</span><span class="plain">; </span> <span class="comment">for the client to attach some meaning</span>
<span class="identifier">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">source_file</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The structure source_file is private to this section.</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. Feeding whole files into the lexer. </b>This is one of the two feeder routines for the lexer, the other being in
Lexical Writing Back.w: see Lexer.w for its obligations.
</p>
<p class="inwebparagraph">We feed characters from an open file into the lexer, and continue until there
is nothing left in it. Inform is used on operating systems which between them
use all four of the sequences <code class="display"><span class="extract">0a</span></code>, <code class="display"><span class="extract">0d</span></code>, <code class="display"><span class="extract">0a0d</span></code> and <code class="display"><span class="extract">0d0a</span></code> to divide lines in
text files, so each of these is converted to a single <code class="display"><span class="extract">'\n'</span></code>. Tabs are treated
as if spaces in most contexts, but not when parsing formatted tables, for
instance, so they are not similarly converted.
</p>
<pre class="display">
<span class="reserved">source_file</span><span class="plain"> *</span><span class="functiontext">TextFromFiles::feed_open_file_into_lexer</span><span class="plain">(</span><span class="identifier">filename</span><span class="plain"> *</span><span class="identifier">F</span><span class="plain">, </span><span class="reserved">FILE</span><span class="plain"> *</span><span class="identifier">handle</span><span class="plain">,</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">leaf</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">documentation_only</span><span class="plain">, </span><span class="identifier">general_pointer</span><span class="plain"> </span><span class="identifier">ref</span><span class="plain">) {</span>
<span class="reserved">source_file</span><span class="plain"> *</span><span class="identifier">sf</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">source_file</span><span class="plain">);</span>
<span class="identifier">sf</span><span class="plain">-</span><span class="element">&gt;words_of_source</span><span class="plain"> = 0;</span>
<span class="identifier">sf</span><span class="plain">-</span><span class="element">&gt;words_of_quoted_text</span><span class="plain"> = 0;</span>
<span class="identifier">sf</span><span class="plain">-</span><span class="element">&gt;your_ref</span><span class="plain"> = </span><span class="identifier">ref</span><span class="plain">;</span>
<span class="identifier">sf</span><span class="plain">-</span><span class="element">&gt;name</span><span class="plain"> = </span><span class="identifier">F</span><span class="plain">;</span>
<span class="identifier">sf</span><span class="plain">-</span><span class="element">&gt;handle</span><span class="plain"> = </span><span class="identifier">handle</span><span class="plain">;</span>
<span class="reserved">source_location</span><span class="plain"> </span><span class="identifier">top_of_file</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">cr</span><span class="plain">, </span><span class="identifier">last_cr</span><span class="plain">, </span><span class="identifier">next_cr</span><span class="plain">, </span><span class="identifier">read_cr</span><span class="plain">, </span><span class="identifier">newline_char</span><span class="plain"> = 0;</span>
<span class="identifier">unicode_file_buffer</span><span class="plain"> </span><span class="identifier">ufb</span><span class="plain"> = </span><span class="identifier">TextFiles::create_ufb</span><span class="plain">();</span>
<span class="identifier">top_of_file</span><span class="element">.file_of_origin</span><span class="plain"> = </span><span class="identifier">sf</span><span class="plain">;</span>
<span class="identifier">top_of_file</span><span class="element">.line_number</span><span class="plain"> = 1;</span>
<span class="functiontext">Lexer::feed_begins</span><span class="plain">(</span><span class="identifier">top_of_file</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">documentation_only</span><span class="plain">) </span><span class="identifier">lexer_wait_for_dashes</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">last_cr</span><span class="plain"> = </span><span class="character">' '</span><span class="plain">; </span><span class="identifier">cr</span><span class="plain"> = </span><span class="character">' '</span><span class="plain">; </span><span class="identifier">next_cr</span><span class="plain"> = </span><span class="identifier">TextFiles::utf8_fgetc</span><span class="plain">(</span><span class="identifier">sf</span><span class="plain">-</span><span class="element">&gt;handle</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">, &amp;</span><span class="identifier">ufb</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">next_cr</span><span class="plain"> == 0</span><span class="identifier">xFEFF</span><span class="plain">) </span><span class="identifier">next_cr</span><span class="plain"> = </span><span class="identifier">TextFiles::utf8_fgetc</span><span class="plain">(</span><span class="identifier">sf</span><span class="plain">-</span><span class="element">&gt;handle</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">, &amp;</span><span class="identifier">ufb</span><span class="plain">); </span> <span class="comment">Unicode BOM code</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">next_cr</span><span class="plain"> != </span><span class="identifier">EOF</span><span class="plain">)</span>
<span class="reserved">while</span><span class="plain"> (((</span><span class="identifier">read_cr</span><span class="plain"> = </span><span class="identifier">TextFiles::utf8_fgetc</span><span class="plain">(</span><span class="identifier">sf</span><span class="plain">-</span><span class="element">&gt;handle</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">, &amp;</span><span class="identifier">ufb</span><span class="plain">)), </span><span class="identifier">next_cr</span><span class="plain">) != </span><span class="identifier">EOF</span><span class="plain">) {</span>
<span class="identifier">last_cr</span><span class="plain"> = </span><span class="identifier">cr</span><span class="plain">; </span><span class="identifier">cr</span><span class="plain"> = </span><span class="identifier">next_cr</span><span class="plain">; </span><span class="identifier">next_cr</span><span class="plain"> = </span><span class="identifier">read_cr</span><span class="plain">;</span>
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">cr</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="character">'\</span><span class="plain">x</span><span class="character">0a'</span><span class="plain">:</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">newline_char</span><span class="plain"> == </span><span class="character">'\</span><span class="plain">x</span><span class="character">0d'</span><span class="plain">) {</span>
<span class="identifier">newline_char</span><span class="plain"> = 0; </span><span class="reserved">continue</span><span class="plain">; </span> <span class="comment">suppress <code class="display"><span class="extract">0x000A</span></code> when it follows <code class="display"><span class="extract">0x000D</span></code></span>
<span class="plain">}</span>
<span class="identifier">newline_char</span><span class="plain"> = </span><span class="identifier">cr</span><span class="plain">; </span><span class="identifier">cr</span><span class="plain"> = </span><span class="character">'\</span><span class="plain">n</span><span class="character">'</span><span class="plain">; </span> <span class="comment">and otherwise convert to <code class="display"><span class="extract">'\n'</span></code></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">x</span><span class="character">0d'</span><span class="plain">:</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">newline_char</span><span class="plain"> == </span><span class="character">'\</span><span class="plain">x</span><span class="character">0a'</span><span class="plain">) {</span>
<span class="identifier">newline_char</span><span class="plain"> = 0; </span><span class="reserved">continue</span><span class="plain">; </span> <span class="comment">suppress <code class="display"><span class="extract">0x000D</span></code> when it follows <code class="display"><span class="extract">0x000A</span></code></span>
<span class="plain">}</span>
<span class="identifier">newline_char</span><span class="plain"> = </span><span class="identifier">cr</span><span class="plain">; </span><span class="identifier">cr</span><span class="plain"> = </span><span class="character">'\</span><span class="plain">n</span><span class="character">'</span><span class="plain">; </span> <span class="comment">and otherwise convert to <code class="display"><span class="extract">'\n'</span></code></span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">default</span><span class="plain">:</span>
<span class="identifier">newline_char</span><span class="plain"> = 0;</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="functiontext">Lexer::feed_triplet</span><span class="plain">(</span><span class="identifier">last_cr</span><span class="plain">, </span><span class="identifier">cr</span><span class="plain">, </span><span class="identifier">next_cr</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">sf</span><span class="plain">-</span><span class="element">&gt;text_read</span><span class="plain"> = </span><span class="functiontext">Lexer::feed_ends</span><span class="plain">(</span><span class="identifier">TRUE</span><span class="plain">, </span><span class="identifier">leaf</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Word count the new material</span> <span class="cwebmacronumber">2.1</span>&gt;<span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">sf</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function TextFromFiles::feed_open_file_into_lexer is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP2_1"></a><b>&#167;2.1. </b>We word count all source files, both as to their source text and their
quoted text (i.e., their text within double-quotes).
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Word count the new material</span> <span class="cwebmacronumber">2.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">LOOP_THROUGH_WORDING</span><span class="plain">(</span><span class="identifier">wc</span><span class="plain">, </span><span class="identifier">sf</span><span class="plain">-</span><span class="element">&gt;text_read</span><span class="plain">)</span>
<span class="identifier">sf</span><span class="plain">-</span><span class="element">&gt;words_of_source</span><span class="plain"> += </span><span class="functiontext">TextFromFiles::word_count</span><span class="plain">(</span><span class="identifier">wc</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>A much simpler version:
</p>
<pre class="display">
<span class="reserved">source_file</span><span class="plain"> *</span><span class="functiontext">TextFromFiles::feed_into_lexer</span><span class="plain">(</span><span class="identifier">filename</span><span class="plain"> *</span><span class="identifier">F</span><span class="plain">, </span><span class="identifier">general_pointer</span><span class="plain"> </span><span class="identifier">ref</span><span class="plain">) {</span>
<span class="reserved">FILE</span><span class="plain"> *</span><span class="identifier">handle</span><span class="plain"> = </span><span class="identifier">Filenames::fopen</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">, </span><span class="string">"r"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">handle</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">source_file</span><span class="plain"> *</span><span class="identifier">sf</span><span class="plain"> = </span><span class="functiontext">TextFromFiles::feed_open_file_into_lexer</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">, </span><span class="identifier">handle</span><span class="plain">,</span>
<span class="identifier">Filenames::get_leafname</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">), </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="identifier">ref</span><span class="plain">);</span>
<span class="identifier">fclose</span><span class="plain">(</span><span class="identifier">handle</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">sf</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function TextFromFiles::feed_into_lexer appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b></p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">TextFromFiles::word_count</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">wc</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">N</span><span class="plain"> = 0;</span>
<span class="identifier">wchar_t</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain"> = </span><span class="functiontext">Lexer::word_text</span><span class="plain">(</span><span class="identifier">wc</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="character">'"'</span><span class="plain">) {</span>
<span class="comment">inside quoted text, each run of non-whitespace counts as 1 word</span>
<span class="identifier">p</span><span class="plain">++; </span> <span class="comment">skip opening quotation mark</span>
<span class="reserved">while</span><span class="plain"> (*</span><span class="identifier">p</span><span class="plain"> != 0) {</span>
<span class="reserved">while</span><span class="plain"> ((*</span><span class="identifier">p</span><span class="plain"> == </span><span class="character">' '</span><span class="plain">) || (*</span><span class="identifier">p</span><span class="plain"> == </span><span class="identifier">NEWLINE_IN_STRING</span><span class="plain">)) </span><span class="identifier">p</span><span class="plain">++; </span> <span class="comment">move past white space</span>
<span class="reserved">if</span><span class="plain"> ((*</span><span class="identifier">p</span><span class="plain"> == </span><span class="character">'"'</span><span class="plain">) || (*</span><span class="identifier">p</span><span class="plain"> == 0)) </span><span class="reserved">break</span><span class="plain">; /* </span><span class="identifier">stop</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> </span><span class="identifier">this</span><span class="plain"> </span><span class="identifier">reaches</span><span class="plain"> </span><span class="identifier">the</span><span class="plain"> </span><span class="identifier">end</span><span class="plain"> */</span>
<span class="identifier">N</span><span class="plain">++; </span> <span class="comment">otherwise we have a word</span>
<span class="reserved">while</span><span class="plain"> ((*</span><span class="identifier">p</span><span class="plain"> != </span><span class="character">' '</span><span class="plain">) &amp;&amp; (*</span><span class="identifier">p</span><span class="plain"> != </span><span class="identifier">NEWLINE_IN_STRING</span><span class="plain">)</span>
<span class="plain">&amp;&amp; (*</span><span class="identifier">p</span><span class="plain"> != </span><span class="character">'"'</span><span class="plain">) &amp;&amp; (*</span><span class="identifier">p</span><span class="plain"> != 0)) </span><span class="identifier">p</span><span class="plain">++; /* </span><span class="identifier">move</span><span class="plain"> </span><span class="identifier">to</span><span class="plain"> </span><span class="identifier">white</span><span class="plain"> </span><span class="identifier">space</span><span class="plain"> </span><span class="identifier">or</span><span class="plain"> </span><span class="identifier">end</span><span class="plain"> */</span>
<span class="plain">}</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="comment">outside quoted text, each lexer word not wholly composed of punctuation scores 1</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Lexer::word</span><span class="plain">(</span><span class="identifier">wc</span><span class="plain">) != </span><span class="identifier">PARBREAK_V</span><span class="plain">)</span>
<span class="reserved">for</span><span class="plain"> (; *</span><span class="identifier">p</span><span class="plain"> != 0; </span><span class="identifier">p</span><span class="plain">++)</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Lexer::is_punctuation</span><span class="plain">(*</span><span class="identifier">p</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) &amp;&amp; (*</span><span class="identifier">p</span><span class="plain"> != </span><span class="character">'|'</span><span class="plain">)) {</span>
<span class="identifier">N</span><span class="plain">++;</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">N</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function TextFromFiles::word_count is used in <a href="#SP2_1">&#167;2.1</a>.</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b>At present, though, the only use made of these two word counts is via
the following routine, which combines them into one.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">TextFromFiles::total_word_count</span><span class="plain">(</span><span class="reserved">source_file</span><span class="plain"> *</span><span class="identifier">sf</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">sf</span><span class="plain">-</span><span class="element">&gt;words_of_source</span><span class="plain"> + </span><span class="identifier">sf</span><span class="plain">-</span><span class="element">&gt;words_of_quoted_text</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">TextFromFiles::last_lexed_word</span><span class="plain">(</span><span class="reserved">source_file</span><span class="plain"> *</span><span class="identifier">sf</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Wordings::last_wn</span><span class="plain">(</span><span class="identifier">sf</span><span class="plain">-</span><span class="element">&gt;text_read</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function TextFromFiles::total_word_count appears nowhere else.</p>
<p class="endnote">The function TextFromFiles::last_lexed_word appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. </b>Finally, we translate between the tiresomely many representations of
files we seem to be stuck with. The method used by <code class="display"><span class="extract">TextFromFiles::filename_to_source_file</span></code>
looks vulnerable to case-insensitive filename issues, but isn't, because
each filename is present in NI in only one form.
</p>
<pre class="display">
<span class="identifier">filename</span><span class="plain"> *</span><span class="functiontext">TextFromFiles::get_filename</span><span class="plain">(</span><span class="reserved">source_file</span><span class="plain"> *</span><span class="identifier">sf</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sf</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"tried to read filename of null source file"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">sf</span><span class="plain">-</span><span class="element">&gt;name</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">source_file</span><span class="plain"> *</span><span class="functiontext">TextFromFiles::filename_to_source_file</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">name2</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">l2</span><span class="plain"> = </span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">name2</span><span class="plain">);</span>
<span class="reserved">source_file</span><span class="plain"> *</span><span class="identifier">sf</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">sf</span><span class="plain">, </span><span class="reserved">source_file</span><span class="plain">) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">name1</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">name1</span><span class="plain">, </span><span class="string">"%f"</span><span class="plain">, </span><span class="identifier">sf</span><span class="plain">-</span><span class="element">&gt;name</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">l1</span><span class="plain"> = </span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">name1</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">minl</span><span class="plain"> = (</span><span class="identifier">l1</span><span class="plain">&lt;</span><span class="identifier">l2</span><span class="plain">)?</span><span class="identifier">l1</span><span class="plain">:</span><span class="identifier">l2</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::suffix_eq</span><span class="plain">(</span><span class="identifier">name1</span><span class="plain">, </span><span class="identifier">name2</span><span class="plain">, </span><span class="identifier">minl</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">sf</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function TextFromFiles::get_filename appears nowhere else.</p>
<p class="endnote">The function TextFromFiles::filename_to_source_file appears nowhere else.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="3-wrd.html">Back to 'Wordings'</a></li><li><a href="3-fds.html">Continue with 'Feeds'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>