354 lines
50 KiB
HTML
354 lines
50 KiB
HTML
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||
|
<html>
|
||
|
<head>
|
||
|
<title>3/pth</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/fln' generated by inweb 6P91-->
|
||
|
<ul class="crumbs"><li><a href="../webs.html">★</a></li><li><a href="index.html">foundation</a></li><li><a href="index.html#3">Chapter 3: The Operating System</a></li><li><b>Filenames</b></li></ul><p class="purpose">Given the different environments in which we might be running, and the large range of files we may need from within a project folder, it's useful to have a section of code simply to deduce filenames.</p>
|
||
|
|
||
|
<ul class="toc"><li><a href="#SP1">§1. Storage</a></li><li><a href="#SP2">§2. Creation</a></li><li><a href="#SP3">§3. Strings to filenames</a></li><li><a href="#SP4">§4. The writer</a></li><li><a href="#SP6">§6. Reading off the folder</a></li><li><a href="#SP7">§7. Reading off the leafname</a></li><li><a href="#SP8">§8. Filename extensions</a></li><li><a href="#SP9">§9. Guessing file formats</a></li><li><a href="#SP10">§10. Opening</a></li><li><a href="#SP11">§11. Comparing</a></li></ul><hr class="tocbar">
|
||
|
|
||
|
<p class="inwebparagraph"><a id="SP1"></a><b>§1. Storage. </b>Filename objects behave much like pathname ones, but they have their own
|
||
|
structure in order that the two are distinct C types. Individual filenames
|
||
|
are a single instance of the following. (Note that the text part is stored
|
||
|
as Unicode code points, regardless of what text encoding the locale has.)
|
||
|
</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">filename</span><span class="plain"> {</span>
|
||
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">pathname</span><span class="plain"> *</span><span class="identifier">pathname_of_location</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">leafname</span><span class="plain">;</span>
|
||
|
<span class="constant">MEMORY_MANAGEMENT</span>
|
||
|
<span class="plain">} </span><span class="reserved">filename</span><span class="plain">;</span>
|
||
|
</pre>
|
||
|
|
||
|
<p class="inwebparagraph"></p>
|
||
|
|
||
|
<p class="endnote">The structure filename is private to this section.</p>
|
||
|
|
||
|
<p class="inwebparagraph"><a id="SP2"></a><b>§2. Creation. </b>A filename is made by supplying a pathname and a leafname.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<pre class="display">
|
||
|
<span class="reserved">filename</span><span class="plain"> *</span><span class="functiontext">Filenames::in_folder</span><span class="plain">(</span><span class="reserved">pathname</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">file_name</span><span class="plain">) {</span>
|
||
|
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Filenames::primitive</span><span class="plain">(</span><span class="identifier">file_name</span><span class="plain">, 0, </span><span class="functiontext">Str::len</span><span class="plain">(</span><span class="identifier">file_name</span><span class="plain">), </span><span class="identifier">P</span><span class="plain">);</span>
|
||
|
<span class="plain">}</span>
|
||
|
|
||
|
<span class="reserved">filename</span><span class="plain"> *</span><span class="functiontext">Filenames::primitive</span><span class="plain">(</span><span class="reserved">text_stream</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">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="reserved">pathname</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain">) {</span>
|
||
|
<span class="reserved">filename</span><span class="plain"> *</span><span class="identifier">F</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">filename</span><span class="plain">);</span>
|
||
|
<span class="identifier">F</span><span class="plain">-</span><span class="element">>pathname_of_location</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="identifier">to</span><span class="plain">-</span><span class="identifier">from</span><span class="plain"> <= 0)</span>
|
||
|
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"empty intermediate pathname"</span><span class="plain">);</span>
|
||
|
<span class="identifier">F</span><span class="plain">-</span><span class="element">>leafname</span><span class="plain"> = </span><span class="functiontext">Str::new_with_capacity</span><span class="plain">(</span><span class="identifier">to</span><span class="plain">-</span><span class="identifier">from</span><span class="plain">+1);</span>
|
||
|
<span class="reserved">string_position</span><span class="plain"> </span><span class="identifier">pos</span><span class="plain"> = </span><span class="functiontext">Str::at</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">from</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">from</span><span class="plain">; </span><span class="identifier">i</span><span class="plain"> < </span><span class="identifier">to</span><span class="plain">; </span><span class="identifier">i</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>
|
||
|
<span class="identifier">PUT_TO</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">-</span><span class="element">>leafname</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="reserved">return</span><span class="plain"> </span><span class="identifier">F</span><span class="plain">;</span>
|
||
|
<span class="plain">}</span>
|
||
|
</pre>
|
||
|
|
||
|
<p class="inwebparagraph"></p>
|
||
|
|
||
|
<p class="endnote">The function Filenames::in_folder is used in <a href="#SP7">§7</a>, <a href="#SP8">§8</a>, 3/cla (<a href="3-cla.html#SP8_1_1">§8.1.1</a>), 5/ee (<a href="5-ee.html#SP6">§6</a>, <a href="5-ee.html#SP6_1">§6.1</a>, <a href="5-ee.html#SP6_2">§6.2</a>, <a href="5-ee.html#SP6_3">§6.3</a>, <a href="5-ee.html#SP7_2">§7.2</a>, <a href="5-ee.html#SP7_3">§7.3</a>, <a href="5-ee.html#SP7_4">§7.4</a>).</p>
|
||
|
|
||
|
<p class="endnote">The function Filenames::primitive is used in <a href="#SP3">§3</a>.</p>
|
||
|
|
||
|
<p class="inwebparagraph"><a id="SP3"></a><b>§3. Strings to filenames. </b>The following takes a textual name and returns a filename.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<pre class="display">
|
||
|
<span class="reserved">filename</span><span class="plain"> *</span><span class="functiontext">Filenames::from_text</span><span class="plain">(</span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">path</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">pos</span><span class="plain"> = -1;</span>
|
||
|
<span class="identifier">LOOP_THROUGH_TEXT</span><span class="plain">(</span><span class="identifier">at</span><span class="plain">, </span><span class="identifier">path</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">at</span><span class="plain">) == </span><span class="constant">FOLDER_SEPARATOR</span><span class="plain">) </span><span class="identifier">pos</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="reserved">pathname</span><span class="plain"> *</span><span class="identifier">P</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">pos</span><span class="plain"> > 0) </span><span class="identifier">P</span><span class="plain"> = </span><span class="functiontext">Pathnames::primitive</span><span class="plain">(</span><span class="identifier">path</span><span class="plain">, 0, </span><span class="identifier">pos</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="functiontext">Filenames::primitive</span><span class="plain">(</span><span class="identifier">path</span><span class="plain">, </span><span class="identifier">pos</span><span class="plain">+1, </span><span class="functiontext">Str::len</span><span class="plain">(</span><span class="identifier">path</span><span class="plain">), </span><span class="identifier">P</span><span class="plain">);</span>
|
||
|
<span class="plain">}</span>
|
||
|
|
||
|
<span class="reserved">filename</span><span class="plain"> *</span><span class="functiontext">Filenames::from_text_relative</span><span class="plain">(</span><span class="reserved">pathname</span><span class="plain"> *</span><span class="identifier">from</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">path</span><span class="plain">) {</span>
|
||
|
<span class="reserved">filename</span><span class="plain"> *</span><span class="identifier">F</span><span class="plain"> = </span><span class="functiontext">Filenames::from_text</span><span class="plain">(</span><span class="identifier">path</span><span class="plain">);</span>
|
||
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">from</span><span class="plain">) {</span>
|
||
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">F</span><span class="plain">-</span><span class="element">>pathname_of_location</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">F</span><span class="plain">-</span><span class="element">>pathname_of_location</span><span class="plain"> = </span><span class="identifier">from</span><span class="plain">;</span>
|
||
|
<span class="reserved">else</span><span class="plain"> {</span>
|
||
|
<span class="reserved">pathname</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain"> = </span><span class="identifier">F</span><span class="plain">-</span><span class="element">>pathname_of_location</span><span class="plain">;</span>
|
||
|
<span class="reserved">while</span><span class="plain"> ((</span><span class="identifier">P</span><span class="plain">) && (</span><span class="identifier">P</span><span class="plain">-</span><span class="element">>pathname_of_parent</span><span class="plain">)) </span><span class="identifier">P</span><span class="plain"> = </span><span class="identifier">P</span><span class="plain">-</span><span class="element">>pathname_of_parent</span><span class="plain">;</span>
|
||
|
<span class="identifier">P</span><span class="plain">-</span><span class="element">>pathname_of_parent</span><span class="plain"> = </span><span class="identifier">from</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">F</span><span class="plain">;</span>
|
||
|
<span class="plain">}</span>
|
||
|
</pre>
|
||
|
|
||
|
<p class="inwebparagraph"></p>
|
||
|
|
||
|
<p class="endnote">The function Filenames::from_text is used in 3/pth (<a href="3-pth.html#SP3">§3</a>).</p>
|
||
|
|
||
|
<p class="endnote">The function Filenames::from_text_relative appears nowhere else.</p>
|
||
|
|
||
|
<p class="inwebparagraph"><a id="SP4"></a><b>§4. The writer. </b>And conversely:
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<pre class="display">
|
||
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Filenames::writer</span><span class="plain">(</span><span class="constant">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">format_string</span><span class="plain">, </span><span class="reserved">void</span><span class="plain"> *</span><span class="identifier">vF</span><span class="plain">) {</span>
|
||
|
<span class="reserved">filename</span><span class="plain"> *</span><span class="identifier">F</span><span class="plain"> = (</span><span class="reserved">filename</span><span class="plain"> *) </span><span class="identifier">vF</span><span class="plain">;</span>
|
||
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">F</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"<no file>"</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">F</span><span class="plain">-</span><span class="element">>pathname_of_location</span><span class="plain">) {</span>
|
||
|
<span class="functiontext">Pathnames::writer</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">format_string</span><span class="plain">, (</span><span class="reserved">void</span><span class="plain"> *) </span><span class="identifier">F</span><span class="plain">-</span><span class="element">>pathname_of_location</span><span class="plain">);</span>
|
||
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">format_string</span><span class="plain">[0] == </span><span class="character">'/'</span><span class="plain">) </span><span class="identifier">PUT</span><span class="plain">(</span><span class="character">'/'</span><span class="plain">);</span>
|
||
|
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">PUT</span><span class="plain">(</span><span class="constant">FOLDER_SEPARATOR</span><span class="plain">);</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">F</span><span class="plain">-</span><span class="element">>leafname</span><span class="plain">);</span>
|
||
|
<span class="plain">}</span>
|
||
|
<span class="plain">}</span>
|
||
|
</pre>
|
||
|
|
||
|
<p class="inwebparagraph"></p>
|
||
|
|
||
|
<p class="endnote">The function Filenames::writer is used in 1/fnd (<a href="1-fnd.html#SP8_1">§8.1</a>).</p>
|
||
|
|
||
|
<p class="inwebparagraph"><a id="SP5"></a><b>§5. </b>And again relative to a given pathname:
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<pre class="display">
|
||
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Filenames::to_text_relative</span><span class="plain">(</span><span class="constant">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">filename</span><span class="plain"> *</span><span class="identifier">F</span><span class="plain">, </span><span class="reserved">pathname</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain">) {</span>
|
||
|
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">ft</span><span class="plain">);</span>
|
||
|
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">pt</span><span class="plain">);</span>
|
||
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">ft</span><span class="plain">, </span><span class="string">"%f"</span><span class="plain">, </span><span class="identifier">F</span><span class="plain">);</span>
|
||
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">pt</span><span class="plain">, </span><span class="string">"%p"</span><span class="plain">, </span><span class="identifier">P</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">Str::len</span><span class="plain">(</span><span class="identifier">pt</span><span class="plain">);</span>
|
||
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Str::prefix_eq</span><span class="plain">(</span><span class="identifier">ft</span><span class="plain">, </span><span class="identifier">pt</span><span class="plain">, </span><span class="identifier">n</span><span class="plain">)) && (</span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">ft</span><span class="plain">, </span><span class="identifier">n</span><span class="plain">)==</span><span class="constant">FOLDER_SEPARATOR</span><span class="plain">)) {</span>
|
||
|
<span class="functiontext">Str::delete_n_characters</span><span class="plain">(</span><span class="identifier">ft</span><span class="plain">, </span><span class="identifier">n</span><span class="plain">+1);</span>
|
||
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%S"</span><span class="plain">, </span><span class="identifier">ft</span><span class="plain">);</span>
|
||
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"filename not relative to pathname"</span><span class="plain">);</span>
|
||
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">ft</span><span class="plain">);</span>
|
||
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">pt</span><span class="plain">);</span>
|
||
|
<span class="plain">}</span>
|
||
|
</pre>
|
||
|
|
||
|
<p class="inwebparagraph"></p>
|
||
|
|
||
|
<p class="endnote">The function Filenames::to_text_relative appears nowhere else.</p>
|
||
|
|
||
|
<p class="inwebparagraph"><a id="SP6"></a><b>§6. Reading off the folder. </b></p>
|
||
|
|
||
|
|
||
|
<pre class="display">
|
||
|
<span class="reserved">pathname</span><span class="plain"> *</span><span class="functiontext">Filenames::get_path_to</span><span class="plain">(</span><span class="reserved">filename</span><span class="plain"> *</span><span class="identifier">F</span><span class="plain">) {</span>
|
||
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">F</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">return</span><span class="plain"> </span><span class="identifier">F</span><span class="plain">-</span><span class="element">>pathname_of_location</span><span class="plain">;</span>
|
||
|
<span class="plain">}</span>
|
||
|
</pre>
|
||
|
|
||
|
<p class="inwebparagraph"></p>
|
||
|
|
||
|
<p class="endnote">The function Filenames::get_path_to is used in 3/pth (<a href="3-pth.html#SP3">§3</a>).</p>
|
||
|
|
||
|
<p class="inwebparagraph"><a id="SP7"></a><b>§7. Reading off the leafname. </b></p>
|
||
|
|
||
|
|
||
|
<pre class="display">
|
||
|
<span class="reserved">filename</span><span class="plain"> *</span><span class="functiontext">Filenames::without_path</span><span class="plain">(</span><span class="reserved">filename</span><span class="plain"> *</span><span class="identifier">F</span><span class="plain">) {</span>
|
||
|
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">F</span><span class="plain">-</span><span class="element">>leafname</span><span class="plain">);</span>
|
||
|
<span class="plain">}</span>
|
||
|
|
||
|
<span class="reserved">text_stream</span><span class="plain"> *</span><span class="functiontext">Filenames::get_leafname</span><span class="plain">(</span><span class="reserved">filename</span><span class="plain"> *</span><span class="identifier">F</span><span class="plain">) {</span>
|
||
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">F</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">return</span><span class="plain"> </span><span class="identifier">F</span><span class="plain">-</span><span class="element">>leafname</span><span class="plain">;</span>
|
||
|
<span class="plain">}</span>
|
||
|
|
||
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Filenames::write_unextended_leafname</span><span class="plain">(</span><span class="constant">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">filename</span><span class="plain"> *</span><span class="identifier">F</span><span class="plain">) {</span>
|
||
|
<span class="identifier">LOOP_THROUGH_TEXT</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">, </span><span class="identifier">F</span><span class="plain">-</span><span class="element">>leafname</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</span><span class="plain">(</span><span class="identifier">pos</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="reserved">return</span><span class="plain">;</span>
|
||
|
<span class="identifier">PUT</span><span class="plain">(</span><span class="identifier">c</span><span class="plain">);</span>
|
||
|
<span class="plain">}</span>
|
||
|
<span class="plain">}</span>
|
||
|
</pre>
|
||
|
|
||
|
<p class="inwebparagraph"></p>
|
||
|
|
||
|
<p class="endnote">The function Filenames::without_path appears nowhere else.</p>
|
||
|
|
||
|
<p class="endnote">The function Filenames::get_leafname is used in 5/ee (<a href="5-ee.html#SP7_2_2_1">§7.2.2.1</a>, <a href="5-ee.html#SP7_2_2_2">§7.2.2.2</a>, <a href="5-ee.html#SP7_2_4">§7.2.4</a>, <a href="5-ee.html#SP7_3_2">§7.3.2</a>, <a href="5-ee.html#SP7_3_2_1">§7.3.2.1</a>, <a href="5-ee.html#SP7_3_2_2_1">§7.3.2.2.1</a>, <a href="5-ee.html#SP7_4">§7.4</a>).</p>
|
||
|
|
||
|
<p class="endnote">The function Filenames::write_unextended_leafname is used in 5/ee (<a href="5-ee.html#SP5">§5</a>).</p>
|
||
|
|
||
|
<p class="inwebparagraph"><a id="SP8"></a><b>§8. Filename extensions. </b>The following is cautiously written because of an oddity in Windows's handling
|
||
|
of filenames, which are allowed to have trailing dots or spaces, in a way
|
||
|
which isn't necessarily visible to the user, who may have added these by
|
||
|
an accidental brush of the keyboard. Thus <code class="display"><span class="extract">frog.jpg .</span></code> should be treated
|
||
|
as equivalent to <code class="display"><span class="extract">frog.jpg</span></code> when deciding the likely file format.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<pre class="display">
|
||
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Filenames::write_extension</span><span class="plain">(</span><span class="constant">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">filename</span><span class="plain"> *</span><span class="identifier">F</span><span class="plain">) {</span>
|
||
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">on</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
|
||
|
<span class="identifier">LOOP_THROUGH_TEXT</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">, </span><span class="identifier">F</span><span class="plain">-</span><span class="element">>leafname</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</span><span class="plain">(</span><span class="identifier">pos</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">on</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">on</span><span class="plain">) </span><span class="identifier">PUT</span><span class="plain">(</span><span class="identifier">c</span><span class="plain">);</span>
|
||
|
<span class="plain">}</span>
|
||
|
<span class="plain">}</span>
|
||
|
|
||
|
<span class="reserved">filename</span><span class="plain"> *</span><span class="functiontext">Filenames::set_extension</span><span class="plain">(</span><span class="reserved">filename</span><span class="plain"> *</span><span class="identifier">F</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">extension</span><span class="plain">) {</span>
|
||
|
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">NEWLEAF</span><span class="plain">);</span>
|
||
|
<span class="identifier">LOOP_THROUGH_TEXT</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">, </span><span class="identifier">F</span><span class="plain">-</span><span class="element">>leafname</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</span><span class="plain">(</span><span class="identifier">pos</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="reserved">break</span><span class="plain">;</span>
|
||
|
<span class="identifier">PUT_TO</span><span class="plain">(</span><span class="identifier">NEWLEAF</span><span class="plain">, </span><span class="identifier">c</span><span class="plain">);</span>
|
||
|
<span class="plain">}</span>
|
||
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">extension</span><span class="plain">) {</span>
|
||
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">extension</span><span class="plain">[0] == </span><span class="character">'.'</span><span class="plain">) </span><span class="identifier">extension</span><span class="plain">++;</span>
|
||
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">extension</span><span class="plain">[0]) </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">NEWLEAF</span><span class="plain">, </span><span class="string">".%s"</span><span class="plain">, </span><span class="identifier">extension</span><span class="plain">);</span>
|
||
|
<span class="plain">}</span>
|
||
|
<span class="reserved">filename</span><span class="plain"> *</span><span class="identifier">N</span><span class="plain"> = </span><span class="functiontext">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">-</span><span class="element">>pathname_of_location</span><span class="plain">, </span><span class="identifier">NEWLEAF</span><span class="plain">);</span>
|
||
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">NEWLEAF</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 Filenames::write_extension is used in <a href="#SP9">§9</a>.</p>
|
||
|
|
||
|
<p class="endnote">The function Filenames::set_extension appears nowhere else.</p>
|
||
|
|
||
|
<p class="inwebparagraph"><a id="SP9"></a><b>§9. Guessing file formats. </b>The following guesses the file format from its file extension:
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<pre class="definitions">
|
||
|
<span class="definitionkeyword">define</span> <span class="constant">FORMAT_PERHAPS_HTML</span><span class="plain"> 1</span>
|
||
|
<span class="definitionkeyword">define</span> <span class="constant">FORMAT_PERHAPS_JPEG</span><span class="plain"> 2</span>
|
||
|
<span class="definitionkeyword">define</span> <span class="constant">FORMAT_PERHAPS_PNG</span><span class="plain"> 3</span>
|
||
|
<span class="definitionkeyword">define</span> <span class="constant">FORMAT_PERHAPS_OGG</span><span class="plain"> 4</span>
|
||
|
<span class="definitionkeyword">define</span> <span class="constant">FORMAT_PERHAPS_AIFF</span><span class="plain"> 5</span>
|
||
|
<span class="definitionkeyword">define</span> <span class="constant">FORMAT_PERHAPS_MIDI</span><span class="plain"> 6</span>
|
||
|
<span class="definitionkeyword">define</span> <span class="constant">FORMAT_PERHAPS_MOD</span><span class="plain"> 7</span>
|
||
|
<span class="definitionkeyword">define</span> <span class="constant">FORMAT_PERHAPS_GLULX</span><span class="plain"> 8</span>
|
||
|
<span class="definitionkeyword">define</span> <span class="constant">FORMAT_PERHAPS_ZCODE</span><span class="plain"> 9</span>
|
||
|
<span class="definitionkeyword">define</span> <span class="constant">FORMAT_PERHAPS_SVG</span><span class="plain"> 10</span>
|
||
|
<span class="definitionkeyword">define</span> <span class="constant">FORMAT_PERHAPS_GIF</span><span class="plain"> 11</span>
|
||
|
<span class="definitionkeyword">define</span> <span class="constant">FORMAT_UNRECOGNISED</span><span class="plain"> 0</span>
|
||
|
</pre>
|
||
|
|
||
|
<pre class="display">
|
||
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Filenames::guess_format</span><span class="plain">(</span><span class="reserved">filename</span><span class="plain"> *</span><span class="identifier">F</span><span class="plain">) {</span>
|
||
|
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">EXT</span><span class="plain">);</span>
|
||
|
<span class="functiontext">Filenames::write_extension</span><span class="plain">(</span><span class="identifier">EXT</span><span class="plain">, </span><span class="identifier">F</span><span class="plain">);</span>
|
||
|
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">NORMALISED</span><span class="plain">);</span>
|
||
|
<span class="identifier">LOOP_THROUGH_TEXT</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">, </span><span class="identifier">EXT</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</span><span class="plain">(</span><span class="identifier">pos</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">PUT_TO</span><span class="plain">(</span><span class="identifier">NORMALISED</span><span class="plain">, </span><span class="functiontext">Characters::tolower</span><span class="plain">(</span><span class="identifier">c</span><span class="plain">));</span>
|
||
|
<span class="plain">}</span>
|
||
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">EXT</span><span class="plain">);</span>
|
||
|
|
||
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">verdict</span><span class="plain"> = </span><span class="constant">FORMAT_UNRECOGNISED</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">NORMALISED</span><span class="plain">, </span><span class="identifier">L</span><span class="string">".html"</span><span class="plain">)) </span><span class="identifier">verdict</span><span class="plain"> = </span><span class="constant">FORMAT_PERHAPS_HTML</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">NORMALISED</span><span class="plain">, </span><span class="identifier">L</span><span class="string">".htm"</span><span class="plain">)) </span><span class="identifier">verdict</span><span class="plain"> = </span><span class="constant">FORMAT_PERHAPS_HTML</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">NORMALISED</span><span class="plain">, </span><span class="identifier">L</span><span class="string">".jpg"</span><span class="plain">)) </span><span class="identifier">verdict</span><span class="plain"> = </span><span class="constant">FORMAT_PERHAPS_JPEG</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">NORMALISED</span><span class="plain">, </span><span class="identifier">L</span><span class="string">".jpeg"</span><span class="plain">)) </span><span class="identifier">verdict</span><span class="plain"> = </span><span class="constant">FORMAT_PERHAPS_JPEG</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">NORMALISED</span><span class="plain">, </span><span class="identifier">L</span><span class="string">".png"</span><span class="plain">)) </span><span class="identifier">verdict</span><span class="plain"> = </span><span class="constant">FORMAT_PERHAPS_PNG</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">NORMALISED</span><span class="plain">, </span><span class="identifier">L</span><span class="string">".ogg"</span><span class="plain">)) </span><span class="identifier">verdict</span><span class="plain"> = </span><span class="constant">FORMAT_PERHAPS_OGG</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">NORMALISED</span><span class="plain">, </span><span class="identifier">L</span><span class="string">".aiff"</span><span class="plain">)) </span><span class="identifier">verdict</span><span class="plain"> = </span><span class="constant">FORMAT_PERHAPS_AIFF</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">NORMALISED</span><span class="plain">, </span><span class="identifier">L</span><span class="string">".aif"</span><span class="plain">)) </span><span class="identifier">verdict</span><span class="plain"> = </span><span class="constant">FORMAT_PERHAPS_AIFF</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">NORMALISED</span><span class="plain">, </span><span class="identifier">L</span><span class="string">".midi"</span><span class="plain">)) </span><span class="identifier">verdict</span><span class="plain"> = </span><span class="constant">FORMAT_PERHAPS_MIDI</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">NORMALISED</span><span class="plain">, </span><span class="identifier">L</span><span class="string">".mid"</span><span class="plain">)) </span><span class="identifier">verdict</span><span class="plain"> = </span><span class="constant">FORMAT_PERHAPS_MIDI</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">NORMALISED</span><span class="plain">, </span><span class="identifier">L</span><span class="string">".mod"</span><span class="plain">)) </span><span class="identifier">verdict</span><span class="plain"> = </span><span class="constant">FORMAT_PERHAPS_MOD</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">NORMALISED</span><span class="plain">, </span><span class="identifier">L</span><span class="string">".svg"</span><span class="plain">)) </span><span class="identifier">verdict</span><span class="plain"> = </span><span class="constant">FORMAT_PERHAPS_SVG</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">NORMALISED</span><span class="plain">, </span><span class="identifier">L</span><span class="string">".gif"</span><span class="plain">)) </span><span class="identifier">verdict</span><span class="plain"> = </span><span class="constant">FORMAT_PERHAPS_GIF</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">NORMALISED</span><span class="plain">) > 0) {</span>
|
||
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Str::get</span><span class="plain">(</span><span class="functiontext">Str::at</span><span class="plain">(</span><span class="identifier">NORMALISED</span><span class="plain">, 0)) == </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="functiontext">Str::at</span><span class="plain">(</span><span class="identifier">NORMALISED</span><span class="plain">, 1)) == </span><span class="character">'z'</span><span class="plain">) &&</span>
|
||
|
<span class="plain">(</span><span class="functiontext">Characters::isdigit</span><span class="plain">(</span><span class="functiontext">Str::get</span><span class="plain">(</span><span class="functiontext">Str::at</span><span class="plain">(</span><span class="identifier">NORMALISED</span><span class="plain">, 2)))) &&</span>
|
||
|
<span class="plain">(</span><span class="functiontext">Str::len</span><span class="plain">(</span><span class="identifier">NORMALISED</span><span class="plain">) == 3))</span>
|
||
|
<span class="identifier">verdict</span><span class="plain"> = </span><span class="constant">FORMAT_PERHAPS_ZCODE</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</span><span class="plain">(</span><span class="functiontext">Str::back</span><span class="plain">(</span><span class="functiontext">Str::end</span><span class="plain">(</span><span class="identifier">NORMALISED</span><span class="plain">))) == </span><span class="character">'x'</span><span class="plain">)</span>
|
||
|
<span class="identifier">verdict</span><span class="plain"> = </span><span class="constant">FORMAT_PERHAPS_GLULX</span><span class="plain">;</span>
|
||
|
<span class="plain">}</span>
|
||
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">NORMALISED</span><span class="plain">);</span>
|
||
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">verdict</span><span class="plain">;</span>
|
||
|
<span class="plain">}</span>
|
||
|
</pre>
|
||
|
|
||
|
<p class="inwebparagraph"></p>
|
||
|
|
||
|
<p class="endnote">The function Filenames::guess_format is used in 5/ee (<a href="5-ee.html#SP7_2_2_3">§7.2.2.3</a>).</p>
|
||
|
|
||
|
<p class="inwebparagraph"><a id="SP10"></a><b>§10. Opening. </b>These files are wrappers for <code class="display"><span class="extract">fopen</span></code>, the traditional C library call, but
|
||
|
referring to the file by filename structure rather than a textual name. Note
|
||
|
that we must transcode the filename to whatever the locale expects before
|
||
|
we call <code class="display"><span class="extract">fopen</span></code>, which is the main reason for the wrapper.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<pre class="display">
|
||
|
<span class="reserved">FILE</span><span class="plain"> *</span><span class="functiontext">Filenames::fopen</span><span class="plain">(</span><span class="reserved">filename</span><span class="plain"> *</span><span class="identifier">F</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">usage</span><span class="plain">) {</span>
|
||
|
<span class="reserved">char</span><span class="plain"> </span><span class="identifier">transcoded_pathname</span><span class="plain">[4*</span><span class="constant">MAX_FILENAME_LENGTH</span><span class="plain">];</span>
|
||
|
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">FN</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="string">"%f"</span><span class="plain">, </span><span class="identifier">F</span><span class="plain">);</span>
|
||
|
<span class="functiontext">Str::copy_to_locale_string</span><span class="plain">(</span><span class="identifier">transcoded_pathname</span><span class="plain">, </span><span class="identifier">FN</span><span class="plain">, 4*</span><span class="constant">MAX_FILENAME_LENGTH</span><span class="plain">);</span>
|
||
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">FN</span><span class="plain">);</span>
|
||
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">fopen</span><span class="plain">(</span><span class="identifier">transcoded_pathname</span><span class="plain">, </span><span class="identifier">usage</span><span class="plain">);</span>
|
||
|
<span class="plain">}</span>
|
||
|
|
||
|
<span class="reserved">FILE</span><span class="plain"> *</span><span class="functiontext">Filenames::fopen_caseless</span><span class="plain">(</span><span class="reserved">filename</span><span class="plain"> *</span><span class="identifier">F</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">usage</span><span class="plain">) {</span>
|
||
|
<span class="reserved">char</span><span class="plain"> </span><span class="identifier">transcoded_pathname</span><span class="plain">[4*</span><span class="constant">MAX_FILENAME_LENGTH</span><span class="plain">];</span>
|
||
|
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">FN</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="string">"%f"</span><span class="plain">, </span><span class="identifier">F</span><span class="plain">);</span>
|
||
|
<span class="functiontext">Str::copy_to_locale_string</span><span class="plain">(</span><span class="identifier">transcoded_pathname</span><span class="plain">, </span><span class="identifier">FN</span><span class="plain">, 4*</span><span class="constant">MAX_FILENAME_LENGTH</span><span class="plain">);</span>
|
||
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">FN</span><span class="plain">);</span>
|
||
|
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">CIFilingSystem::fopen</span><span class="plain">(</span><span class="identifier">transcoded_pathname</span><span class="plain">, </span><span class="identifier">usage</span><span class="plain">);</span>
|
||
|
<span class="plain">}</span>
|
||
|
</pre>
|
||
|
|
||
|
<p class="inwebparagraph"></p>
|
||
|
|
||
|
<p class="endnote">The function Filenames::fopen is used in 2/str (<a href="2-str.html#SP24">§24</a>, <a href="2-str.html#SP25">§25</a>), 4/tf (<a href="4-tf.html#SP1">§1</a>, <a href="4-tf.html#SP5_1">§5.1</a>), 6/bf (<a href="6-bf.html#SP8">§8</a>).</p>
|
||
|
|
||
|
<p class="endnote">The function Filenames::fopen_caseless appears nowhere else.</p>
|
||
|
|
||
|
<p class="inwebparagraph"><a id="SP11"></a><b>§11. Comparing. </b>Not as easy as it seems. The following is a slow but effective way to
|
||
|
compare two filenames by seeing if they have the same canonical form
|
||
|
when printed out.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<pre class="display">
|
||
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Filenames::eq</span><span class="plain">(</span><span class="reserved">filename</span><span class="plain"> *</span><span class="identifier">F1</span><span class="plain">, </span><span class="reserved">filename</span><span class="plain"> *</span><span class="identifier">F2</span><span class="plain">) {</span>
|
||
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">F1</span><span class="plain"> == </span><span class="identifier">F2</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="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">T1</span><span class="plain">);</span>
|
||
|
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">T2</span><span class="plain">);</span>
|
||
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">T1</span><span class="plain">, </span><span class="string">"%f"</span><span class="plain">, </span><span class="identifier">F1</span><span class="plain">);</span>
|
||
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">T2</span><span class="plain">, </span><span class="string">"%f"</span><span class="plain">, </span><span class="identifier">F2</span><span class="plain">);</span>
|
||
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain"> = </span><span class="functiontext">Str::eq</span><span class="plain">(</span><span class="identifier">T1</span><span class="plain">, </span><span class="identifier">T2</span><span class="plain">);</span>
|
||
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">T1</span><span class="plain">);</span>
|
||
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">T2</span><span class="plain">);</span>
|
||
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain">;</span>
|
||
|
<span class="plain">}</span>
|
||
|
</pre>
|
||
|
|
||
|
<p class="inwebparagraph"></p>
|
||
|
|
||
|
<p class="endnote">The function Filenames::eq appears nowhere else.</p>
|
||
|
|
||
|
<!--End of weave: 259 lines from a web of 9228-->
|
||
|
</body>
|
||
|
</html>
|
||
|
|