inweb-bootstrap/docs/foundation-module/3-cf.html

348 lines
60 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>
2020-04-08 22:41:00 +00:00
<title>Case-Insensitive Filenames</title>
2020-04-23 22:23:44 +00:00
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
<meta name="viewport" content="width=device-width initial-scale=1">
2019-02-04 22:26:45 +00:00
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
2020-04-20 22:26:08 +00:00
<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
2020-04-30 22:36:38 +00:00
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
2020-04-25 10:33:39 +00:00
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
2020-04-20 22:26:08 +00:00
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
function togglePopup(material_id) {
var popup = document.getElementById(material_id);
popup.classList.toggle("show");
}
</script>
<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
2020-04-21 16:55:17 +00:00
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
2020-04-23 22:23:44 +00:00
2019-02-04 22:26:45 +00:00
</head>
2020-04-25 10:33:39 +00:00
<body class="commentary-font">
<nav role="navigation">
2020-04-13 16:06:45 +00:00
<h1><a href="../index.html">
2020-04-20 22:26:08 +00:00
<img src="../docs-assets/Octagram.png" width=72 height=72">
2020-04-13 16:06:45 +00:00
</a></h1>
<ul><li><a href="../inweb/index.html">inweb</a></li>
</ul><h2>Foundation Module</h2><ul>
<li><a href="index.html"><span class="selectedlink">foundation</span></a></li>
<li><a href="../foundation-test/index.html">foundation-test</a></li>
2020-04-13 16:06:45 +00:00
</ul><h2>Example Webs</h2><ul>
2020-04-12 16:24:23 +00:00
<li><a href="../goldbach/index.html">goldbach</a></li>
<li><a href="../twinprimes/twinprimes.html">twinprimes</a></li>
2020-04-15 22:45:08 +00:00
<li><a href="../eastertide/index.html">eastertide</a></li>
2020-04-14 17:36:42 +00:00
</ul><h2>Repository</h2><ul>
2020-04-20 22:34:44 +00:00
<li><a href="https://github.com/ganelson/inweb"><img src="../docs-assets/github.png" height=18> github</a></li>
2020-04-14 17:36:42 +00:00
</ul><h2>Related Projects</h2><ul>
<li><a href="../../../inform/docs/overview.html">inform</a></li>
2020-04-14 17:36:42 +00:00
<li><a href="../../../intest/docs/index.html">intest</a></li>
2020-04-13 16:06:45 +00:00
</ul>
</nav>
<main role="main">
2020-04-23 22:23:44 +00:00
<!--Weave of 'Case-Insensitive Filenames' generated by Inweb-->
2020-04-30 22:36:38 +00:00
<div class="breadcrumbs">
<ul class="crumbs"><li><a href="../index.html">Home</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>Case-Insensitive Filenames</b></li></ul></div>
<p class="purpose">On some of the Unix-derived file systems on which Inform runs, filenames are case-sensitive, so that FISH and fish might be different files. This makes extension files, installed by the user, prone to being missed. The code in this section provides a routine to carry out file opening as if filenames are case-insensitive, and is used only for extensions.</p>
2019-02-04 22:26:45 +00:00
<ul class="toc"><li><a href="3-cf.html#SP3">&#167;3. The routine</a></li><li><a href="3-cf.html#SP3_1">&#167;3.1. Looking for case-insensitive matches instead</a></li><li><a href="3-cf.html#SP3_3">&#167;3.3. Allocation and deallocation</a></li><li><a href="3-cf.html#SP3_6">&#167;3.6. Pathname hacking</a></li><li><a href="3-cf.html#SP4">&#167;4. strrchr</a></li><li><a href="3-cf.html#SP5">&#167;5. Counting matches</a></li><li><a href="3-cf.html#SP6">&#167;6. Non-POSIX tail</a></li></ul><hr class="tocbar">
2019-02-04 22:26:45 +00:00
2020-08-16 17:39:53 +00:00
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. </b>This section contains a single utility routine, contributed by Adam
2020-04-22 22:57:09 +00:00
Thornton: a specialised, case-insensitive form of <span class="extract"><span class="extract-syntax">fopen()</span></span>. It is specialised
2019-02-04 22:26:45 +00:00
in that it is designed for opening extensions, where the file path will be
case-correct up to the last two components of the path (the leafname and the
immediately containing directory), but where the casing may be wrong in those
last two components.
</p>
2020-08-16 17:39:53 +00:00
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b>If the exact filename or extension directory (case-correct) exists,
2020-04-22 22:57:09 +00:00
<span class="extract"><span class="extract-syntax">CIFilingSystem::fopen()</span></span> will choose it to open. If not, it will
use <span class="extract"><span class="extract-syntax">strcasecmp()</span></span> to find a file or directory with the same name but
2019-02-04 22:26:45 +00:00
differing in case and use it instead. If it finds exactly one candidate file,
2020-04-22 22:57:09 +00:00
it will then attempt to <span class="extract"><span class="extract-syntax">fopen()</span></span> it and return the result.
2019-02-04 22:26:45 +00:00
</p>
2020-04-24 23:06:02 +00:00
<p class="commentary">If <span class="extract"><span class="extract-syntax">CIFilingSystem::fopen()</span></span> succeeds, it returns a <span class="extract"><span class="extract-syntax">FILE *</span></span>
2020-04-22 22:57:09 +00:00
(passed back to it from the underlying <span class="extract"><span class="extract-syntax">fopen()</span></span>). If
<span class="extract"><span class="extract-syntax">CIFilingSystem::fopen()</span></span> fails, it returns <span class="extract"><span class="extract-syntax">NULL</span></span>, and
<span class="extract"><span class="extract-syntax">errno</span></span> is set accordingly:
2019-02-04 22:26:45 +00:00
</p>
2020-04-24 23:06:02 +00:00
<ul class="items"><li>(a) If no suitable file was found, <span class="extract"><span class="extract-syntax">errno</span></span> is set to <span class="extract"><span class="extract-syntax">ENOENT</span></span>.
</li><li>(b) If more than one possibility was found, but none of them exactly match
2020-04-22 22:57:09 +00:00
the supplied case, <span class="extract"><span class="extract-syntax">errno</span></span> is set to <span class="extract"><span class="extract-syntax">EBADF</span></span>.
2020-04-24 23:06:02 +00:00
</li><li>(c) Note that if multiple directories which match case-insensitively are
2020-04-22 22:57:09 +00:00
found, but none is an exact match, <span class="extract"><span class="extract-syntax">EBADF</span></span> will be set regardless of the
2019-02-04 22:26:45 +00:00
contents of the directories.
2020-04-24 23:06:02 +00:00
</li><li>(d) If <span class="extract"><span class="extract-syntax">CIFilingSystem::fopen()</span></span> fails during its allocation of
2019-02-04 22:26:45 +00:00
space to hold its intermediate strings for comparison, or for its various
2020-04-22 22:57:09 +00:00
data structures, <span class="extract"><span class="extract-syntax">errno</span></span> is set to <span class="extract"><span class="extract-syntax">ENOMEM</span></span>.
2020-04-24 23:06:02 +00:00
</li><li>(e) If an unambiguous filename is found but the <span class="extract"><span class="extract-syntax">fopen()</span></span> fails, <span class="extract"><span class="extract-syntax">errno</span></span> is
2020-04-22 22:57:09 +00:00
left at whatever value the underlying <span class="extract"><span class="extract-syntax">fopen()</span></span> set it to.
2020-04-24 23:06:02 +00:00
</li></ul>
2020-08-16 17:39:53 +00:00
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. The routine. </b>The routine is available only on POSIX platforms where <span class="extract"><span class="extract-syntax">PLATFORM_POSIX</span></span>
2019-02-04 22:26:45 +00:00
is defined (see "Platform-Specific Definitions"). In practice this means
everywhere except Windows, but all Windows file systems are case-preserving
and case-insensitive in any case.
</p>
2020-04-24 23:06:02 +00:00
<p class="commentary">Briefly, we try to get the extension directory name right first, by looking
2019-02-04 22:26:45 +00:00
for the given casing, then if that fails, for a unique alternative with
different casing; and then repeat within that directory for the extension
file itself.
</p>
2020-04-25 10:33:39 +00:00
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">FILE</span><span class="plain-syntax"> *</span><a href="3-cf.html#SP6" class="function-link"><span class="function-syntax">CIFilingSystem::fopen</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">const</span><span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">path</span><span class="plain-syntax">, </span><span class="reserved-syntax">const</span><span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mode</span><span class="plain-syntax">) {</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">topdirpath</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, *</span><span class="identifier-syntax">ciextdirpath</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, *</span><span class="identifier-syntax">cistring</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, *</span><span class="identifier-syntax">ciextname</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">workstring</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, *</span><span class="identifier-syntax">workstring2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DIR</span><span class="plain-syntax"> *</span><span class="identifier-syntax">topdir</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, *</span><span class="identifier-syntax">extdir</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="reserved-syntax">FILE</span><span class="plain-syntax"> *</span><span class="identifier-syntax">handle</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">size_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">length</span><span class="plain-syntax">;</span>
2019-02-04 22:26:45 +00:00
2020-04-24 23:06:02 +00:00
<span class="plain-syntax"> </span><span class="comment-syntax"> for efficiency's sake, though it's logically equivalent, we try...</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">handle</span><span class="plain-syntax"> = </span><span class="identifier-syntax">fopen</span><span class="plain-syntax">(</span><span class="identifier-syntax">path</span><span class="plain-syntax">, </span><span class="identifier-syntax">mode</span><span class="plain-syntax">); </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">handle</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="3-cf.html#SP3_4" class="named-paragraph-link"><span class="named-paragraph">Happy ending to ci-fopen</span><span class="named-paragraph-number">3.4</span></a></span><span class="plain-syntax">;</span>
2019-02-04 22:26:45 +00:00
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-cf.html#SP3_6" class="named-paragraph-link"><span class="named-paragraph">Find the length of the path, giving an error if it is empty or NULL</span><span class="named-paragraph-number">3.6</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-cf.html#SP3_3" class="named-paragraph-link"><span class="named-paragraph">Allocate memory for strings large enough to hold any subpath of the path</span><span class="named-paragraph-number">3.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-cf.html#SP3_7" class="named-paragraph-link"><span class="named-paragraph">Parse the path to break it into topdir path, extension directory and leafname</span><span class="named-paragraph-number">3.7</span></a></span><span class="plain-syntax">;</span>
2019-02-04 22:26:45 +00:00
2020-04-24 23:06:02 +00:00
<span class="plain-syntax"> </span><span class="identifier-syntax">topdir</span><span class="plain-syntax"> = </span><span class="identifier-syntax">opendir</span><span class="plain-syntax">(</span><span class="identifier-syntax">topdirpath</span><span class="plain-syntax">); </span><span class="comment-syntax"> whose pathname is assumed case-correct...</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">topdir</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="3-cf.html#SP3_5" class="named-paragraph-link"><span class="named-paragraph">Sad ending to ci-fopen</span><span class="named-paragraph-number">3.5</span></a></span><span class="plain-syntax">; </span><span class="comment-syntax"> ...so that failure is fatal; </span><span class="extract"><span class="extract-syntax">errno</span></span><span class="comment-syntax"> is set by </span><span class="extract"><span class="extract-syntax">opendir</span></span>
2019-02-04 22:26:45 +00:00
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="identifier-syntax">sprintf</span><span class="plain-syntax">(</span><span class="identifier-syntax">workstring</span><span class="plain-syntax">, </span><span class="string-syntax">"%s%c%s"</span><span class="plain-syntax">, </span><span class="identifier-syntax">topdirpath</span><span class="plain-syntax">, </span><span class="constant-syntax">FOLDER_SEPARATOR</span><span class="plain-syntax">, </span><span class="identifier-syntax">ciextdirpath</span><span class="plain-syntax">);</span>
2020-04-24 23:06:02 +00:00
<span class="plain-syntax"> </span><span class="identifier-syntax">extdir</span><span class="plain-syntax"> = </span><span class="identifier-syntax">opendir</span><span class="plain-syntax">(</span><span class="identifier-syntax">workstring</span><span class="plain-syntax">); </span><span class="comment-syntax"> try with supplied extension directory name</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">extdir</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="3-cf.html#SP3_1" class="named-paragraph-link"><span class="named-paragraph">Try to find a unique insensitively matching directory name in topdir</span><span class="named-paragraph-number">3.1</span></a></span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">strcpy</span><span class="plain-syntax">(</span><span class="identifier-syntax">cistring</span><span class="plain-syntax">, </span><span class="identifier-syntax">workstring</span><span class="plain-syntax">);</span>
2019-02-04 22:26:45 +00:00
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="identifier-syntax">sprintf</span><span class="plain-syntax">(</span><span class="identifier-syntax">workstring</span><span class="plain-syntax">, </span><span class="string-syntax">"%s%c%s"</span><span class="plain-syntax">, </span><span class="identifier-syntax">cistring</span><span class="plain-syntax">, </span><span class="constant-syntax">FOLDER_SEPARATOR</span><span class="plain-syntax">, </span><span class="identifier-syntax">ciextname</span><span class="plain-syntax">);</span>
2020-04-24 23:06:02 +00:00
<span class="plain-syntax"> </span><span class="identifier-syntax">handle</span><span class="plain-syntax"> = </span><span class="identifier-syntax">fopen</span><span class="plain-syntax">(</span><span class="identifier-syntax">workstring</span><span class="plain-syntax">, </span><span class="identifier-syntax">mode</span><span class="plain-syntax">); </span><span class="comment-syntax"> try with supplied name</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">handle</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="3-cf.html#SP3_4" class="named-paragraph-link"><span class="named-paragraph">Happy ending to ci-fopen</span><span class="named-paragraph-number">3.4</span></a></span><span class="plain-syntax">;</span>
2019-02-04 22:26:45 +00:00
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-cf.html#SP3_2" class="named-paragraph-link"><span class="named-paragraph">Try to find a unique insensitively matching entry in extdir</span><span class="named-paragraph-number">3.2</span></a></span><span class="plain-syntax">;</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_POSIX is defined.</li><li>The function CIFilingSystem::fopen is used in <a href="3-cf.html#SP6">&#167;6</a>, Filenames (<a href="3-fln.html#SP10">&#167;10</a>).</li></ul>
2020-08-16 17:39:53 +00:00
<p class="commentary firstcommentary"><a id="SP3_1" class="paragraph-anchor"></a><b>&#167;3.1. Looking for case-insensitive matches instead. </b>We emerge from the following only in the happy case where a unique matching
2019-02-04 22:26:45 +00:00
directory name can be found.
</p>
2020-04-25 10:33:39 +00:00
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Try to find a unique insensitively matching directory name in topdir</span><span class="named-paragraph-number">3.1</span></span><span class="comment-syntax"> =</span>
</p>
2020-04-25 10:33:39 +00:00
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">rc</span><span class="plain-syntax"> = </span><a href="3-cf.html#SP5" class="function-link"><span class="function-syntax">CIFilingSystem::match_in_directory</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">topdir</span><span class="plain-syntax">, </span><span class="identifier-syntax">ciextdirpath</span><span class="plain-syntax">, </span><span class="identifier-syntax">workstring</span><span class="plain-syntax">);</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">rc</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">:</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">errno</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ENOENT</span><span class="plain-syntax">; </span><span class="named-paragraph-container code-font"><a href="3-cf.html#SP3_5" class="named-paragraph-link"><span class="named-paragraph">Sad ending to ci-fopen</span><span class="named-paragraph-number">3.5</span></a></span><span class="plain-syntax">;</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax">:</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sprintf</span><span class="plain-syntax">(</span><span class="identifier-syntax">cistring</span><span class="plain-syntax">, </span><span class="string-syntax">"%s%c%s"</span><span class="plain-syntax">, </span><span class="identifier-syntax">topdirpath</span><span class="plain-syntax">, </span><span class="constant-syntax">FOLDER_SEPARATOR</span><span class="plain-syntax">, </span><span class="identifier-syntax">workstring</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">extdir</span><span class="plain-syntax"> = </span><span class="identifier-syntax">opendir</span><span class="plain-syntax">(</span><span class="identifier-syntax">cistring</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">extdir</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">errno</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ENOENT</span><span class="plain-syntax">; </span><span class="named-paragraph-container code-font"><a href="3-cf.html#SP3_5" class="named-paragraph-link"><span class="named-paragraph">Sad ending to ci-fopen</span><span class="named-paragraph-number">3.5</span></a></span><span class="plain-syntax">;</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">default:</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">errno</span><span class="plain-syntax"> = </span><span class="identifier-syntax">EBADF</span><span class="plain-syntax">; </span><span class="named-paragraph-container code-font"><a href="3-cf.html#SP3_5" class="named-paragraph-link"><span class="named-paragraph">Sad ending to ci-fopen</span><span class="named-paragraph-number">3.5</span></a></span><span class="plain-syntax">;</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-cf.html#SP3">&#167;3</a>.</li></ul>
2020-08-16 17:39:53 +00:00
<p class="commentary firstcommentary"><a id="SP3_2" class="paragraph-anchor"></a><b>&#167;3.2. </b>More or less the same, but we never emerge at all: all cases of the switch
2019-02-04 22:26:45 +00:00
return from the function.
</p>
2020-04-25 10:33:39 +00:00
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Try to find a unique insensitively matching entry in extdir</span><span class="named-paragraph-number">3.2</span></span><span class="comment-syntax"> =</span>
</p>
2020-04-25 10:33:39 +00:00
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">rc</span><span class="plain-syntax"> = </span><a href="3-cf.html#SP5" class="function-link"><span class="function-syntax">CIFilingSystem::match_in_directory</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">extdir</span><span class="plain-syntax">, </span><span class="identifier-syntax">ciextname</span><span class="plain-syntax">, </span><span class="identifier-syntax">workstring</span><span class="plain-syntax">);</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">rc</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">:</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">errno</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ENOENT</span><span class="plain-syntax">; </span><span class="named-paragraph-container code-font"><a href="3-cf.html#SP3_5" class="named-paragraph-link"><span class="named-paragraph">Sad ending to ci-fopen</span><span class="named-paragraph-number">3.5</span></a></span><span class="plain-syntax">;</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax">:</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sprintf</span><span class="plain-syntax">(</span><span class="identifier-syntax">workstring2</span><span class="plain-syntax">, </span><span class="string-syntax">"%s%c%s"</span><span class="plain-syntax">, </span><span class="identifier-syntax">cistring</span><span class="plain-syntax">, </span><span class="constant-syntax">FOLDER_SEPARATOR</span><span class="plain-syntax">, </span><span class="identifier-syntax">workstring</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">workstring2</span><span class="plain-syntax">[</span><span class="identifier-syntax">length</span><span class="plain-syntax">] = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">handle</span><span class="plain-syntax"> = </span><span class="identifier-syntax">fopen</span><span class="plain-syntax">(</span><span class="identifier-syntax">workstring2</span><span class="plain-syntax">, </span><span class="identifier-syntax">mode</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">handle</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="3-cf.html#SP3_4" class="named-paragraph-link"><span class="named-paragraph">Happy ending to ci-fopen</span><span class="named-paragraph-number">3.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">errno</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ENOENT</span><span class="plain-syntax">; </span><span class="named-paragraph-container code-font"><a href="3-cf.html#SP3_5" class="named-paragraph-link"><span class="named-paragraph">Sad ending to ci-fopen</span><span class="named-paragraph-number">3.5</span></a></span><span class="plain-syntax">;</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="identifier-syntax">default:</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">errno</span><span class="plain-syntax"> = </span><span class="identifier-syntax">EBADF</span><span class="plain-syntax">; </span><span class="named-paragraph-container code-font"><a href="3-cf.html#SP3_5" class="named-paragraph-link"><span class="named-paragraph">Sad ending to ci-fopen</span><span class="named-paragraph-number">3.5</span></a></span><span class="plain-syntax">;</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-cf.html#SP3">&#167;3</a>.</li></ul>
2020-08-16 17:39:53 +00:00
<p class="commentary firstcommentary"><a id="SP3_3" class="paragraph-anchor"></a><b>&#167;3.3. Allocation and deallocation. </b>We use six strings to hold full or partial pathnames.
2019-02-04 22:26:45 +00:00
</p>
2020-04-25 10:33:39 +00:00
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Allocate memory for strings large enough to hold any subpath of the path</span><span class="named-paragraph-number">3.3</span></span><span class="comment-syntax"> =</span>
</p>
2020-04-25 10:33:39 +00:00
<pre class="displayed-code all-displayed-code code-font">
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="identifier-syntax">workstring</span><span class="plain-syntax"> = </span><span class="identifier-syntax">calloc</span><span class="plain-syntax">(</span><span class="identifier-syntax">length</span><span class="plain-syntax">+1, </span><span class="reserved-syntax">sizeof</span><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">workstring</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) { </span><span class="identifier-syntax">errno</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ENOMEM</span><span class="plain-syntax">; </span><span class="named-paragraph-container code-font"><a href="3-cf.html#SP3_5" class="named-paragraph-link"><span class="named-paragraph">Sad ending to ci-fopen</span><span class="named-paragraph-number">3.5</span></a></span><span class="plain-syntax">; }</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="identifier-syntax">workstring2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">calloc</span><span class="plain-syntax">(</span><span class="identifier-syntax">length</span><span class="plain-syntax">+1, </span><span class="reserved-syntax">sizeof</span><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">workstring2</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) { </span><span class="identifier-syntax">errno</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ENOMEM</span><span class="plain-syntax">; </span><span class="named-paragraph-container code-font"><a href="3-cf.html#SP3_5" class="named-paragraph-link"><span class="named-paragraph">Sad ending to ci-fopen</span><span class="named-paragraph-number">3.5</span></a></span><span class="plain-syntax">; }</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="identifier-syntax">topdirpath</span><span class="plain-syntax"> = </span><span class="identifier-syntax">calloc</span><span class="plain-syntax">(</span><span class="identifier-syntax">length</span><span class="plain-syntax">+1, </span><span class="reserved-syntax">sizeof</span><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">topdirpath</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) { </span><span class="identifier-syntax">errno</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ENOMEM</span><span class="plain-syntax">; </span><span class="named-paragraph-container code-font"><a href="3-cf.html#SP3_5" class="named-paragraph-link"><span class="named-paragraph">Sad ending to ci-fopen</span><span class="named-paragraph-number">3.5</span></a></span><span class="plain-syntax">; }</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="identifier-syntax">ciextdirpath</span><span class="plain-syntax"> = </span><span class="identifier-syntax">calloc</span><span class="plain-syntax">(</span><span class="identifier-syntax">length</span><span class="plain-syntax">+1, </span><span class="reserved-syntax">sizeof</span><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ciextdirpath</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) { </span><span class="identifier-syntax">errno</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ENOMEM</span><span class="plain-syntax">; </span><span class="named-paragraph-container code-font"><a href="3-cf.html#SP3_5" class="named-paragraph-link"><span class="named-paragraph">Sad ending to ci-fopen</span><span class="named-paragraph-number">3.5</span></a></span><span class="plain-syntax">; }</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="identifier-syntax">cistring</span><span class="plain-syntax"> = </span><span class="identifier-syntax">calloc</span><span class="plain-syntax">(</span><span class="identifier-syntax">length</span><span class="plain-syntax">+1, </span><span class="reserved-syntax">sizeof</span><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cistring</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) { </span><span class="identifier-syntax">errno</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ENOMEM</span><span class="plain-syntax">; </span><span class="named-paragraph-container code-font"><a href="3-cf.html#SP3_5" class="named-paragraph-link"><span class="named-paragraph">Sad ending to ci-fopen</span><span class="named-paragraph-number">3.5</span></a></span><span class="plain-syntax">; }</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="identifier-syntax">ciextname</span><span class="plain-syntax"> = </span><span class="identifier-syntax">calloc</span><span class="plain-syntax">(</span><span class="identifier-syntax">length</span><span class="plain-syntax">+1, </span><span class="reserved-syntax">sizeof</span><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ciextname</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) { </span><span class="identifier-syntax">errno</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ENOMEM</span><span class="plain-syntax">; </span><span class="named-paragraph-container code-font"><a href="3-cf.html#SP3_5" class="named-paragraph-link"><span class="named-paragraph">Sad ending to ci-fopen</span><span class="named-paragraph-number">3.5</span></a></span><span class="plain-syntax">; }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-cf.html#SP3">&#167;3</a>.</li></ul>
2020-08-16 17:39:53 +00:00
<p class="commentary firstcommentary"><a id="SP3_4" class="paragraph-anchor"></a><b>&#167;3.4. </b>If we are successful, we return a valid file handle...
2019-02-04 22:26:45 +00:00
</p>
2020-04-25 10:33:39 +00:00
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Happy ending to ci-fopen</span><span class="named-paragraph-number">3.4</span></span><span class="comment-syntax"> =</span>
</p>
2020-04-25 10:33:39 +00:00
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-cf.html#SP3_4_1" class="named-paragraph-link"><span class="named-paragraph">Prepare to exit ci-fopen cleanly</span><span class="named-paragraph-number">3.4.1</span></a></span><span class="plain-syntax">;</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">handle</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-cf.html#SP3">&#167;3</a> (twice), <a href="3-cf.html#SP3_2">&#167;3.2</a>.</li></ul>
2020-08-16 17:39:53 +00:00
<p class="commentary firstcommentary"><a id="SP3_5" class="paragraph-anchor"></a><b>&#167;3.5. </b>...and otherwise <span class="extract"><span class="extract-syntax">NULL</span></span>, having already set <span class="extract"><span class="extract-syntax">errno</span></span> with the reason why.
2019-02-04 22:26:45 +00:00
</p>
2020-04-25 10:33:39 +00:00
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Sad ending to ci-fopen</span><span class="named-paragraph-number">3.5</span></span><span class="comment-syntax"> =</span>
</p>
2020-04-25 10:33:39 +00:00
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-cf.html#SP3_4_1" class="named-paragraph-link"><span class="named-paragraph">Prepare to exit ci-fopen cleanly</span><span class="named-paragraph-number">3.4.1</span></a></span><span class="plain-syntax">;</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-cf.html#SP3">&#167;3</a>, <a href="3-cf.html#SP3_1">&#167;3.1</a> (three times), <a href="3-cf.html#SP3_2">&#167;3.2</a> (three times), <a href="3-cf.html#SP3_3">&#167;3.3</a> (6 times).</li></ul>
2020-08-16 17:39:53 +00:00
<p class="commentary firstcommentary"><a id="SP3_4_1" class="paragraph-anchor"></a><b>&#167;3.4.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Prepare to exit ci-fopen cleanly</span><span class="named-paragraph-number">3.4.1</span></span><span class="comment-syntax"> =</span>
</p>
2020-04-25 10:33:39 +00:00
<pre class="displayed-code all-displayed-code code-font">
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">workstring</span><span class="plain-syntax">) </span><span class="identifier-syntax">free</span><span class="plain-syntax">(</span><span class="identifier-syntax">workstring</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">workstring2</span><span class="plain-syntax">) </span><span class="identifier-syntax">free</span><span class="plain-syntax">(</span><span class="identifier-syntax">workstring2</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">topdirpath</span><span class="plain-syntax">) </span><span class="identifier-syntax">free</span><span class="plain-syntax">(</span><span class="identifier-syntax">topdirpath</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ciextdirpath</span><span class="plain-syntax">) </span><span class="identifier-syntax">free</span><span class="plain-syntax">(</span><span class="identifier-syntax">ciextdirpath</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cistring</span><span class="plain-syntax">) </span><span class="identifier-syntax">free</span><span class="plain-syntax">(</span><span class="identifier-syntax">cistring</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ciextname</span><span class="plain-syntax">) </span><span class="identifier-syntax">free</span><span class="plain-syntax">(</span><span class="identifier-syntax">ciextname</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">topdir</span><span class="plain-syntax">) </span><span class="identifier-syntax">closedir</span><span class="plain-syntax">(</span><span class="identifier-syntax">topdir</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">extdir</span><span class="plain-syntax">) </span><span class="identifier-syntax">closedir</span><span class="plain-syntax">(</span><span class="identifier-syntax">extdir</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-cf.html#SP3_4">&#167;3.4</a>, <a href="3-cf.html#SP3_5">&#167;3.5</a>.</li></ul>
2020-08-16 17:39:53 +00:00
<p class="commentary firstcommentary"><a id="SP3_6" class="paragraph-anchor"></a><b>&#167;3.6. Pathname hacking. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Find the length of the path, giving an error if it is empty or NULL</span><span class="named-paragraph-number">3.6</span></span><span class="comment-syntax"> =</span>
</p>
2020-04-25 10:33:39 +00:00
<pre class="displayed-code all-displayed-code code-font">
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="identifier-syntax">length</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">path</span><span class="plain-syntax">) </span><span class="identifier-syntax">length</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">size_t</span><span class="plain-syntax">) </span><span class="identifier-syntax">strlen</span><span class="plain-syntax">(</span><span class="identifier-syntax">path</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">length</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) { </span><span class="identifier-syntax">errno</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ENOENT</span><span class="plain-syntax">; </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-cf.html#SP3">&#167;3</a>.</li></ul>
2020-08-16 17:39:53 +00:00
<p class="commentary firstcommentary"><a id="SP3_7" class="paragraph-anchor"></a><b>&#167;3.7. </b>And here we break up a pathname like
2019-02-04 22:26:45 +00:00
</p>
2020-04-25 10:33:39 +00:00
<pre class="displayed-code all-displayed-code code-font">
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> /Users/bobama/Library/Inform/Extensions/Hillary Clinton/Health Care.i7x</span>
2019-02-04 22:26:45 +00:00
</pre>
2020-04-24 23:06:02 +00:00
<p class="commentary">into three components:
2019-02-04 22:26:45 +00:00
</p>
2020-04-24 23:06:02 +00:00
<ul class="items"><li>(a) <span class="extract"><span class="extract-syntax">topdirpath</span></span> is <span class="extract"><span class="extract-syntax">/Users/bobama/Library/Inform/Extensions</span></span>, and its casing is correct.
</li><li>(b) <span class="extract"><span class="extract-syntax">ciextdirpath</span></span> is <span class="extract"><span class="extract-syntax">Hillary Clinton</span></span>, but its casing may not be correct.
</li><li>(c) <span class="extract"><span class="extract-syntax">ciextname</span></span> is <span class="extract"><span class="extract-syntax">Health Care.i7x</span></span>, but its casing may not be correct.
</li></ul>
<p class="commentary">The contents of <span class="extract"><span class="extract-syntax">workstring</span></span> are not significant afterwards.
</p>
2020-04-25 10:33:39 +00:00
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Parse the path to break it into topdir path, extension directory and leafname</span><span class="named-paragraph-number">3.7</span></span><span class="comment-syntax"> =</span>
</p>
2020-04-25 10:33:39 +00:00
<pre class="displayed-code all-displayed-code code-font">
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">size_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">extdirindex</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">extindex</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">namelen</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">dirlen</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><a href="3-cf.html#SP4" class="function-link"><span class="function-syntax">CIFilingSystem::strrchr</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">path</span><span class="plain-syntax">);</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">extindex</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">size_t</span><span class="plain-syntax">) (</span><span class="identifier-syntax">p</span><span class="plain-syntax"> - </span><span class="identifier-syntax">path</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">namelen</span><span class="plain-syntax"> = </span><span class="identifier-syntax">length</span><span class="plain-syntax"> - </span><span class="identifier-syntax">extindex</span><span class="plain-syntax"> - </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">strncpy</span><span class="plain-syntax">(</span><span class="identifier-syntax">ciextname</span><span class="plain-syntax">, </span><span class="identifier-syntax">path</span><span class="plain-syntax"> + </span><span class="identifier-syntax">extindex</span><span class="plain-syntax"> + </span><span class="constant-syntax">1</span><span class="plain-syntax">, </span><span class="identifier-syntax">namelen</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ciextname</span><span class="plain-syntax">[</span><span class="identifier-syntax">namelen</span><span class="plain-syntax">] = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
2022-04-08 09:02:33 +00:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">extindex</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">strncpy</span><span class="plain-syntax">(</span><span class="identifier-syntax">workstring</span><span class="plain-syntax">, </span><span class="identifier-syntax">path</span><span class="plain-syntax">, </span><span class="identifier-syntax">extindex</span><span class="plain-syntax">);</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="identifier-syntax">workstring</span><span class="plain-syntax">[</span><span class="identifier-syntax">extindex</span><span class="plain-syntax">] = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><a href="3-cf.html#SP4" class="function-link"><span class="function-syntax">CIFilingSystem::strrchr</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">workstring</span><span class="plain-syntax">);</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">extdirindex</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">size_t</span><span class="plain-syntax">) (</span><span class="identifier-syntax">p</span><span class="plain-syntax"> - </span><span class="identifier-syntax">workstring</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">strncpy</span><span class="plain-syntax">(</span><span class="identifier-syntax">topdirpath</span><span class="plain-syntax">, </span><span class="identifier-syntax">path</span><span class="plain-syntax">, </span><span class="identifier-syntax">extdirindex</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">topdirpath</span><span class="plain-syntax">[</span><span class="identifier-syntax">extdirindex</span><span class="plain-syntax">] = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">dirlen</span><span class="plain-syntax"> = </span><span class="identifier-syntax">extindex</span><span class="plain-syntax"> - </span><span class="identifier-syntax">extdirindex</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">dirlen</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">dirlen</span><span class="plain-syntax"> -= </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">strncpy</span><span class="plain-syntax">(</span><span class="identifier-syntax">ciextdirpath</span><span class="plain-syntax">, </span><span class="identifier-syntax">path</span><span class="plain-syntax"> + </span><span class="identifier-syntax">extdirindex</span><span class="plain-syntax"> + </span><span class="constant-syntax">1</span><span class="plain-syntax">, </span><span class="identifier-syntax">dirlen</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ciextdirpath</span><span class="plain-syntax">[</span><span class="identifier-syntax">dirlen</span><span class="plain-syntax">] = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-cf.html#SP3">&#167;3</a>.</li></ul>
2020-08-16 17:39:53 +00:00
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. strrchr. </b>This is an elderly C library function, really, but rewritten so that it
can recognise any folder separator character.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="function-syntax">CIFilingSystem::strrchr</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">CIFilingSystem::strrchr</span></span>:<br/><a href="3-cf.html#SP3_7">&#167;3.7</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">const</span><span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">const</span><span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">q</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (*</span><span class="identifier-syntax">p</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="1-wp.html#SP4" class="function-link"><span class="function-syntax">Platform::is_folder_separator</span></a><span class="plain-syntax">((</span><span class="identifier-syntax">wchar_t</span><span class="plain-syntax">) (*</span><span class="identifier-syntax">p</span><span class="plain-syntax">))) </span><span class="identifier-syntax">q</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> (</span><span class="reserved-syntax">char</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">q</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
2020-08-16 17:39:53 +00:00
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. Counting matches. </b>We count the number of names within the directory which case-insensitively
2020-04-22 22:57:09 +00:00
match against <span class="extract"><span class="extract-syntax">name</span></span>, and copy the last which matches into <span class="extract"><span class="extract-syntax">last_match</span></span>.
This must be at least as long as <span class="extract"><span class="extract-syntax">name</span></span>. (We ought to be just a little careful
2019-02-04 22:26:45 +00:00
in case of improbable cases where the matched name contains a different
2020-04-22 22:57:09 +00:00
number of characters from <span class="extract"><span class="extract-syntax">name</span></span>, for instance because on a strict reading
2019-02-04 22:26:45 +00:00
of Unicode "SS" is casing-equivalent to the eszet, but it's unlikely
2020-04-22 22:57:09 +00:00
that many contemporary implementations of <span class="extract"><span class="extract-syntax">strcasecmp</span></span> are aware of this,
2019-02-04 22:26:45 +00:00
and in any case the code above contains much larger buffers than needed.)
</p>
2020-04-25 10:33:39 +00:00
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">CIFilingSystem::match_in_directory</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">CIFilingSystem::match_in_directory</span></span>:<br/><a href="3-cf.html#SP3_1">&#167;3.1</a>, <a href="3-cf.html#SP3_2">&#167;3.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">vd</span><span class="plain-syntax">,</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name</span><span class="plain-syntax">, </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">last_match</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DIR</span><span class="plain-syntax"> *</span><span class="identifier-syntax">d</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">DIR</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">vd</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">dirent</span><span class="plain-syntax"> *</span><span class="identifier-syntax">dirp</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">rc</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">last_match</span><span class="plain-syntax">[0] = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">dirp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">readdir</span><span class="plain-syntax">(</span><span class="identifier-syntax">d</span><span class="plain-syntax">)) != </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">strcasecmp</span><span class="plain-syntax">(</span><span class="identifier-syntax">name</span><span class="plain-syntax">, </span><span class="identifier-syntax">dirp</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">d_name</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">rc</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">strcpy</span><span class="plain-syntax">(</span><span class="identifier-syntax">last_match</span><span class="plain-syntax">, </span><span class="identifier-syntax">dirp</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">d_name</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">rc</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
2020-08-16 17:39:53 +00:00
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>&#167;6. Non-POSIX tail. </b>On platforms without POSIX directory handling, we revert to regular <span class="extract"><span class="extract-syntax">fopen</span></span>.
2019-02-04 22:26:45 +00:00
</p>
2020-04-25 10:33:39 +00:00
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">FILE</span><span class="plain-syntax"> *</span><span class="function-syntax">CIFilingSystem::fopen</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">CIFilingSystem::fopen</span></span>:<br/><a href="3-cf.html#SP3">&#167;3</a><br/>Filenames - <a href="3-fln.html#SP10">&#167;10</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">const</span><span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">path</span><span class="plain-syntax">, </span><span class="reserved-syntax">const</span><span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mode</span><span class="plain-syntax">) {</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">fopen</span><span class="plain-syntax">(</span><span class="identifier-syntax">path</span><span class="plain-syntax">, </span><span class="identifier-syntax">mode</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_POSIX is undefined.</li></ul>
2020-04-30 22:36:38 +00:00
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="3-fln.html">&#10094;</a></li><li class="progresschapter"><a href="P-abgtf.html">P</a></li><li class="progresschapter"><a href="1-fm.html">1</a></li><li class="progresschapter"><a href="2-dl.html">2</a></li><li class="progresscurrentchapter">3</li><li class="progresssection"><a href="3-em.html">em</a></li><li class="progresssection"><a href="3-cla.html">cla</a></li><li class="progresssection"><a href="3-pth.html">pth</a></li><li class="progresssection"><a href="3-fln.html">fln</a></li><li class="progresscurrent">cf</li><li class="progresssection"><a href="3-shl.html">shl</a></li><li class="progresssection"><a href="3-drc.html">drc</a></li><li class="progresssection"><a href="3-tm.html">tm</a></li><li class="progresschapter"><a href="4-chr.html">4</a></li><li class="progresschapter"><a href="5-htm.html">5</a></li><li class="progresschapter"><a href="6-bf.html">6</a></li><li class="progresschapter"><a href="7-vn.html">7</a></li><li class="progresschapter"><a href="8-ws.html">8</a></li><li class="progressnext"><a href="3-shl.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
2020-04-23 22:23:44 +00:00
</main>
2019-02-04 22:26:45 +00:00
</body>
</html>