Scanning directories in alphabetical order
This commit is contained in:
parent
7d1fcb2260
commit
3adb9a7dfa
8 changed files with 154 additions and 13 deletions
|
@ -1,6 +1,6 @@
|
|||
# Inweb 7
|
||||
|
||||
v7-alpha.1+1A89 'Escape to Danger' (15 April 2022)
|
||||
v7-alpha.1+1A90 'Escape to Danger' (19 April 2022)
|
||||
|
||||
## About Inweb
|
||||
|
||||
|
|
|
@ -3138,6 +3138,10 @@ scan_directory * Directories__open(pathname *P) ;
|
|||
int Directories__next(scan_directory *D, text_stream *leafname) ;
|
||||
#line 42 "inweb/foundation-module/Chapter 3/Directories.w"
|
||||
void Directories__close(scan_directory *D) ;
|
||||
#line 58 "inweb/foundation-module/Chapter 3/Directories.w"
|
||||
linked_list * Directories__listing(pathname *P) ;
|
||||
#line 86 "inweb/foundation-module/Chapter 3/Directories.w"
|
||||
int Directories__compare_names(const void *ent1, const void *ent2) ;
|
||||
#line 13 "inweb/foundation-module/Chapter 3/Time.w"
|
||||
void Time__begin(void) ;
|
||||
#line 26 "inweb/foundation-module/Chapter 3/Time.w"
|
||||
|
@ -8621,11 +8625,11 @@ int CommandLine__read_pair_p(text_stream *opt, text_stream *opt_val, int N,
|
|||
; innocuous = TRUE; break;
|
||||
case VERSION_CLSW: {
|
||||
PRINT("inweb");
|
||||
char *svn = "7-alpha.1+1A88";
|
||||
char *svn = "7-alpha.1+1A89";
|
||||
if (svn[0]) PRINT(" version %s", svn);
|
||||
char *vname = "Escape to Danger";
|
||||
if (vname[0]) PRINT(" '%s'", vname);
|
||||
char *d = "13 April 2022";
|
||||
char *d = "15 April 2022";
|
||||
if (d[0]) PRINT(" (%s)", d);
|
||||
PRINT("\n");
|
||||
innocuous = TRUE; break;
|
||||
|
@ -9856,6 +9860,41 @@ void Directories__close(scan_directory *D) {
|
|||
Platform__closedir(D->directory_handle);
|
||||
}
|
||||
|
||||
#line 58 "inweb/foundation-module/Chapter 3/Directories.w"
|
||||
linked_list *Directories__listing(pathname *P) {
|
||||
int capacity = 4, used = 0;
|
||||
text_stream **listing_array = (text_stream **)
|
||||
(Memory__calloc(capacity, sizeof(text_stream *), ARRAY_SORTING_MREASON));
|
||||
scan_directory *D = Directories__open(P);
|
||||
if (D) {
|
||||
text_stream *entry = Str__new();
|
||||
while (Directories__next(D, entry)) {
|
||||
if (used == capacity) {
|
||||
int new_capacity = 4*capacity;
|
||||
text_stream **new_listing_array = (text_stream **)
|
||||
(Memory__calloc(new_capacity, sizeof(text_stream *), ARRAY_SORTING_MREASON));
|
||||
for (int i=0; i<used; i++) new_listing_array[i] = listing_array[i];
|
||||
listing_array = new_listing_array;
|
||||
capacity = new_capacity;
|
||||
}
|
||||
listing_array[used++] = entry;
|
||||
entry = Str__new();
|
||||
}
|
||||
Directories__close(D);
|
||||
}
|
||||
qsort(listing_array, (size_t) used, sizeof(text_stream *), Directories__compare_names);
|
||||
linked_list *L = NEW_LINKED_LIST(text_stream);
|
||||
for (int i=0; i<used; i++) ADD_TO_LINKED_LIST(listing_array[i], text_stream, L);
|
||||
Memory__I7_free(listing_array, ARRAY_SORTING_MREASON, capacity*((int) sizeof(text_stream *)));
|
||||
return L;
|
||||
}
|
||||
|
||||
int Directories__compare_names(const void *ent1, const void *ent2) {
|
||||
text_stream *tx1 = *((text_stream **) ent1);
|
||||
text_stream *tx2 = *((text_stream **) ent2);
|
||||
return Str__cmp_insensitive(tx1, tx2);
|
||||
}
|
||||
|
||||
#line 9 "inweb/foundation-module/Chapter 3/Time.w"
|
||||
time_t right_now;
|
||||
struct tm *the_present = NULL;
|
||||
|
@ -30963,7 +31002,7 @@ void Ctags__write(web *W, filename *F) {
|
|||
WRITE("!_TAG_FILE_SORTED\t0\t/0=unsorted, 1=sorted, 2=foldcase/\n");
|
||||
WRITE("!_TAG_PROGRAM_AUTHOR\tGraham Nelson\t/graham.nelson@mod-langs.ox.ac.uk/\n");
|
||||
WRITE("!_TAG_PROGRAM_NAME\tinweb\t//\n");
|
||||
WRITE("!_TAG_PROGRAM_VERSION\t7-alpha.1+1A88\t/built 13 April 2022/\n");
|
||||
WRITE("!_TAG_PROGRAM_VERSION\t7-alpha.1+1A89\t/built 15 April 2022/\n");
|
||||
|
||||
}
|
||||
#line 47 "inweb/Chapter 6/Ctags Support.w"
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Prerelease: alpha.1
|
||||
Build Date: 15 April 2022
|
||||
Build Number: 1A89
|
||||
Build Date: 19 April 2022
|
||||
Build Number: 1A90
|
||||
|
|
|
@ -622,7 +622,7 @@ values of these functions are always non-<span class="extract"><span class="extr
|
|||
</p>
|
||||
|
||||
<pre class="displayed-code all-displayed-code code-font">
|
||||
<span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="function-syntax">Memory::calloc</span><button class="popup" onclick="togglePopup('usagePopup9')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup9">Usage of <span class="code-font"><span class="function-syntax">Memory::calloc</span></span>:<br/>Streams - <a href="2-str.html#SP26">§26</a><br/>Dictionaries - <a href="2-dct.html#SP2">§2</a><br/>Command Line Arguments - <a href="3-cla.html#SP14">§14</a><br/>Time - <a href="3-tm.html#SP7_1">§7.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">how_many</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">size_in_bytes</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">reason</span><span class="plain-syntax">) {</span>
|
||||
<span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="function-syntax">Memory::calloc</span><button class="popup" onclick="togglePopup('usagePopup9')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup9">Usage of <span class="code-font"><span class="function-syntax">Memory::calloc</span></span>:<br/>Streams - <a href="2-str.html#SP26">§26</a><br/>Dictionaries - <a href="2-dct.html#SP2">§2</a><br/>Command Line Arguments - <a href="3-cla.html#SP14">§14</a><br/>Directories - <a href="3-drc.html#SP3">§3</a><br/>Time - <a href="3-tm.html#SP7_1">§7.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">how_many</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">size_in_bytes</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">reason</span><span class="plain-syntax">) {</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="2-mmr.html#SP25" class="function-link"><span class="function-syntax">Memory::alloc_inner</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">how_many</span><span class="plain-syntax">, </span><span class="identifier-syntax">size_in_bytes</span><span class="plain-syntax">, </span><span class="identifier-syntax">reason</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax">}</span>
|
||||
<span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="function-syntax">Memory::malloc</span><button class="popup" onclick="togglePopup('usagePopup10')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup10">Usage of <span class="code-font"><span class="function-syntax">Memory::malloc</span></span>:<br/>Streams - <a href="2-str.html#SP35_3">§35.3</a><br/>C Strings - <a href="4-cst.html#SP11">§11</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">size_in_bytes</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">reason</span><span class="plain-syntax">) {</span>
|
||||
|
@ -699,7 +699,7 @@ rarely and to allocate large blocks of memory.
|
|||
</p>
|
||||
|
||||
<pre class="displayed-code all-displayed-code code-font">
|
||||
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Memory::I7_free</span><button class="popup" onclick="togglePopup('usagePopup12')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup12">Usage of <span class="code-font"><span class="function-syntax">Memory::I7_free</span></span>:<br/>Streams - <a href="2-str.html#SP34_2">§34.2</a><br/>Dictionaries - <a href="2-dct.html#SP7_2">§7.2</a>, <a href="2-dct.html#SP11">§11</a><br/>Command Line Arguments - <a href="3-cla.html#SP14">§14</a><br/>C Strings - <a href="4-cst.html#SP12">§12</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pointer</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">bytes_freed</span><span class="plain-syntax">) {</span>
|
||||
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Memory::I7_free</span><button class="popup" onclick="togglePopup('usagePopup12')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup12">Usage of <span class="code-font"><span class="function-syntax">Memory::I7_free</span></span>:<br/>Streams - <a href="2-str.html#SP34_2">§34.2</a><br/>Dictionaries - <a href="2-dct.html#SP7_2">§7.2</a>, <a href="2-dct.html#SP11">§11</a><br/>Command Line Arguments - <a href="3-cla.html#SP14">§14</a><br/>Directories - <a href="3-drc.html#SP3">§3</a><br/>C Strings - <a href="4-cst.html#SP12">§12</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pointer</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">bytes_freed</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">R</span><span class="plain-syntax"> < </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">R</span><span class="plain-syntax"> >= </span><span class="identifier-syntax">NO_DEFINED_MREASON_VALUES</span><span class="plain-syntax">)) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"no such memory reason"</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">pointer</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"can't free NULL memory"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">LOCK_MUTEX</span><span class="plain-syntax">(</span><span class="identifier-syntax">memory_statistics_mutex</span><span class="plain-syntax">);</span>
|
||||
|
|
|
@ -12,6 +12,14 @@
|
|||
<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">
|
||||
<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">
|
||||
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
||||
|
||||
</head>
|
||||
|
@ -59,7 +67,7 @@ transcoded the other way.
|
|||
</p>
|
||||
|
||||
<pre class="displayed-code all-displayed-code code-font">
|
||||
<span class="reserved-syntax">scan_directory</span><span class="plain-syntax"> *</span><span class="function-syntax">Directories::open</span><span class="plain-syntax">(</span><span class="reserved-syntax">pathname</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax">) {</span>
|
||||
<span class="reserved-syntax">scan_directory</span><span class="plain-syntax"> *</span><span class="function-syntax">Directories::open</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">Directories::open</span></span>:<br/><a href="3-drc.html#SP3">§3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">pathname</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">scan_directory</span><span class="plain-syntax"> *</span><span class="identifier-syntax">D</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">scan_directory</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">)</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">, </span><span class="string-syntax">"%p"</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">);</span>
|
||||
|
@ -70,7 +78,7 @@ transcoded the other way.
|
|||
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">D</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax">}</span>
|
||||
|
||||
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Directories::next</span><span class="plain-syntax">(</span><span class="reserved-syntax">scan_directory</span><span class="plain-syntax"> *</span><span class="identifier-syntax">D</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">leafname</span><span class="plain-syntax">) {</span>
|
||||
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Directories::next</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">Directories::next</span></span>:<br/><a href="3-drc.html#SP3">§3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">scan_directory</span><span class="plain-syntax"> *</span><span class="identifier-syntax">D</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">leafname</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">leafname_Cs</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_FILENAME_LENGTH</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">rv</span><span class="plain-syntax"> = </span><span class="constant-syntax">TRUE</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">rv</span><span class="plain-syntax">) {</span>
|
||||
|
@ -82,10 +90,58 @@ transcoded the other way.
|
|||
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">rv</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax">}</span>
|
||||
|
||||
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Directories::close</span><span class="plain-syntax">(</span><span class="reserved-syntax">scan_directory</span><span class="plain-syntax"> *</span><span class="identifier-syntax">D</span><span class="plain-syntax">) {</span>
|
||||
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Directories::close</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">Directories::close</span></span>:<br/><a href="3-drc.html#SP3">§3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">scan_directory</span><span class="plain-syntax"> *</span><span class="identifier-syntax">D</span><span class="plain-syntax">) {</span>
|
||||
<span class="plain-syntax"> </span><a href="1-wp.html#SP9" class="function-link"><span class="function-syntax">Platform::closedir</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">D</span><span class="plain-syntax">-></span><span class="element-syntax">directory_handle</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax">}</span>
|
||||
</pre>
|
||||
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>§3. </b>It turns out to be useful to scan the contents of a directory in an order
|
||||
which is predictable regardless of platform — <span class="extract"><span class="extract-syntax">Platform::readdir</span></span> works in a
|
||||
different order on MacOS, Windows and Linux, even given the same directory
|
||||
of files to work on. So the following returns a linked list of the contents,
|
||||
sorted into alphabetical order, but case-insensitively. For the Inform project,
|
||||
at least, we don't anticipate ever dealing with files whose names disagree only
|
||||
in casing, so this ordering is effectively deterministic.
|
||||
</p>
|
||||
|
||||
<p class="commentary">There's some time and memory overhead here, but unless we're dealing with
|
||||
directories holding upwards of 10,000 files or so, it'll be trivial.
|
||||
</p>
|
||||
|
||||
<pre class="displayed-code all-displayed-code code-font">
|
||||
<span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="function-syntax">Directories::listing</span><span class="plain-syntax">(</span><span class="reserved-syntax">pathname</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">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">capacity</span><span class="plain-syntax"> = </span><span class="constant-syntax">4</span><span class="plain-syntax">, </span><span class="identifier-syntax">used</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">text_stream</span><span class="plain-syntax"> **</span><span class="identifier-syntax">listing_array</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> **)</span>
|
||||
<span class="plain-syntax"> (</span><a href="2-mmr.html#SP24" class="function-link"><span class="function-syntax">Memory::calloc</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">capacity</span><span class="plain-syntax">, </span><span class="reserved-syntax">sizeof</span><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *), </span><span class="constant-syntax">ARRAY_SORTING_MREASON</span><span class="plain-syntax">));</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">scan_directory</span><span class="plain-syntax"> *</span><span class="identifier-syntax">D</span><span class="plain-syntax"> = </span><a href="3-drc.html#SP2" class="function-link"><span class="function-syntax">Directories::open</span></a><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><span class="identifier-syntax">D</span><span class="plain-syntax">) {</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">entry</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP2" class="function-link"><span class="function-syntax">Str::new</span></a><span class="plain-syntax">();</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><a href="3-drc.html#SP2" class="function-link"><span class="function-syntax">Directories::next</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">D</span><span class="plain-syntax">, </span><span class="identifier-syntax">entry</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">used</span><span class="plain-syntax"> == </span><span class="identifier-syntax">capacity</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">new_capacity</span><span class="plain-syntax"> = </span><span class="constant-syntax">4</span><span class="plain-syntax">*</span><span class="identifier-syntax">capacity</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> **</span><span class="identifier-syntax">new_listing_array</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> **)</span>
|
||||
<span class="plain-syntax"> (</span><a href="2-mmr.html#SP24" class="function-link"><span class="function-syntax">Memory::calloc</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new_capacity</span><span class="plain-syntax">, </span><span class="reserved-syntax">sizeof</span><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *), </span><span class="constant-syntax">ARRAY_SORTING_MREASON</span><span class="plain-syntax">));</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax"><</span><span class="identifier-syntax">used</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) </span><span class="identifier-syntax">new_listing_array</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = </span><span class="identifier-syntax">listing_array</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">];</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">listing_array</span><span class="plain-syntax"> = </span><span class="identifier-syntax">new_listing_array</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">capacity</span><span class="plain-syntax"> = </span><span class="identifier-syntax">new_capacity</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> }</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">listing_array</span><span class="plain-syntax">[</span><span class="identifier-syntax">used</span><span class="plain-syntax">++] = </span><span class="identifier-syntax">entry</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">entry</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP2" class="function-link"><span class="function-syntax">Str::new</span></a><span class="plain-syntax">();</span>
|
||||
<span class="plain-syntax"> }</span>
|
||||
<span class="plain-syntax"> </span><a href="3-drc.html#SP2" class="function-link"><span class="function-syntax">Directories::close</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">D</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> }</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">qsort</span><span class="plain-syntax">(</span><span class="identifier-syntax">listing_array</span><span class="plain-syntax">, (</span><span class="identifier-syntax">size_t</span><span class="plain-syntax">) </span><span class="identifier-syntax">used</span><span class="plain-syntax">, </span><span class="reserved-syntax">sizeof</span><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *), </span><a href="3-drc.html#SP3" class="function-link"><span class="function-syntax">Directories::compare_names</span></a><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEW_LINKED_LIST</span><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax"><</span><span class="identifier-syntax">used</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) </span><span class="identifier-syntax">ADD_TO_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">listing_array</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">], </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><a href="2-mmr.html#SP26" class="function-link"><span class="function-syntax">Memory::I7_free</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">listing_array</span><span class="plain-syntax">, </span><span class="constant-syntax">ARRAY_SORTING_MREASON</span><span class="plain-syntax">, </span><span class="identifier-syntax">capacity</span><span class="plain-syntax">*((</span><span class="reserved-syntax">int</span><span class="plain-syntax">) </span><span class="reserved-syntax">sizeof</span><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</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">L</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax">}</span>
|
||||
|
||||
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Directories::compare_names</span><span class="plain-syntax">(</span><span class="reserved-syntax">const</span><span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ent1</span><span class="plain-syntax">, </span><span class="reserved-syntax">const</span><span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ent2</span><span class="plain-syntax">) {</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tx1</span><span class="plain-syntax"> = *((</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> **) </span><span class="identifier-syntax">ent1</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tx2</span><span class="plain-syntax"> = *((</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> **) </span><span class="identifier-syntax">ent2</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="4-sm.html#SP20" class="function-link"><span class="function-syntax">Str::cmp_insensitive</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">tx1</span><span class="plain-syntax">, </span><span class="identifier-syntax">tx2</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax">}</span>
|
||||
</pre>
|
||||
<nav role="progress"><div class="progresscontainer">
|
||||
<ul class="progressbar"><li class="progressprev"><a href="3-shl.html">❮</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="progresssection"><a href="3-cf.html">cf</a></li><li class="progresssection"><a href="3-shl.html">shl</a></li><li class="progresscurrent">drc</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-tm.html">❯</a></li></ul></div>
|
||||
</nav><!--End of weave-->
|
||||
|
|
|
@ -88,7 +88,7 @@ access.
|
|||
</p>
|
||||
|
||||
<pre class="displayed-code all-displayed-code code-font">
|
||||
<span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="function-syntax">Str::new</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">Str::new</span></span>:<br/><a href="4-sm.html#SP3">§3</a><br/>Debugging Log - <a href="2-dl.html#SP4_1">§4.1</a><br/>Dictionaries - <a href="2-dct.html#SP7_3_1">§7.3.1</a><br/>Command Line Arguments - <a href="3-cla.html#SP6">§6</a>, <a href="3-cla.html#SP11">§11</a><br/>HTML - <a href="5-htm.html#SP27_2">§27.2</a><br/>Epub Ebooks - <a href="5-ee.html#SP5">§5</a><br/>Version Numbers - <a href="7-vn.html#SP7">§7</a><br/>Web Structure - <a href="8-ws.html#SP5_2">§5.2</a>, <a href="8-ws.html#SP6_1">§6.1</a>, <a href="8-ws.html#SP7_2_1">§7.2.1</a>, <a href="8-ws.html#SP7_2_2_1">§7.2.2.1</a><br/>Build Files - <a href="8-bf.html#SP3">§3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
|
||||
<span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="function-syntax">Str::new</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">Str::new</span></span>:<br/><a href="4-sm.html#SP3">§3</a><br/>Debugging Log - <a href="2-dl.html#SP4_1">§4.1</a><br/>Dictionaries - <a href="2-dct.html#SP7_3_1">§7.3.1</a><br/>Command Line Arguments - <a href="3-cla.html#SP6">§6</a>, <a href="3-cla.html#SP11">§11</a><br/>Directories - <a href="3-drc.html#SP3">§3</a><br/>HTML - <a href="5-htm.html#SP27_2">§27.2</a><br/>Epub Ebooks - <a href="5-ee.html#SP5">§5</a><br/>Version Numbers - <a href="7-vn.html#SP7">§7</a><br/>Web Structure - <a href="8-ws.html#SP5_2">§5.2</a>, <a href="8-ws.html#SP6_1">§6.1</a>, <a href="8-ws.html#SP7_2_1">§7.2.1</a>, <a href="8-ws.html#SP7_2_2_1">§7.2.2.1</a><br/>Build Files - <a href="8-bf.html#SP3">§3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="4-sm.html#SP2" class="function-link"><span class="function-syntax">Str::new_with_capacity</span></a><span class="plain-syntax">(32);</span>
|
||||
<span class="plain-syntax">}</span>
|
||||
|
||||
|
@ -462,7 +462,7 @@ around 1%.
|
|||
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">L1</span><span class="plain-syntax"> - </span><span class="identifier-syntax">L2</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax">}</span>
|
||||
|
||||
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Str::cmp_insensitive</span><button class="popup" onclick="togglePopup('usagePopup29')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup29">Usage of <span class="code-font"><span class="function-syntax">Str::cmp_insensitive</span></span>:<br/><a href="4-sm.html#SP19">§19</a><br/>Command Line Arguments - <a href="3-cla.html#SP15">§15</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S1</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S2</span><span class="plain-syntax">) {</span>
|
||||
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Str::cmp_insensitive</span><button class="popup" onclick="togglePopup('usagePopup29')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup29">Usage of <span class="code-font"><span class="function-syntax">Str::cmp_insensitive</span></span>:<br/><a href="4-sm.html#SP19">§19</a><br/>Command Line Arguments - <a href="3-cla.html#SP15">§15</a><br/>Directories - <a href="3-drc.html#SP3">§3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S1</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S2</span><span class="plain-syntax">) {</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">string_position</span><span class="plain-syntax"> </span><span class="identifier-syntax">P</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP10" class="function-link"><span class="function-syntax">Str::start</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">S1</span><span class="plain-syntax">), </span><span class="identifier-syntax">Q</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP10" class="function-link"><span class="function-syntax">Str::start</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">S2</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> (</span><span class="identifier-syntax">P</span><span class="plain-syntax">.</span><span class="identifier-syntax">index</span><span class="plain-syntax"> < </span><a href="4-sm.html#SP8" class="function-link"><span class="function-syntax">Str::len</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">S1</span><span class="plain-syntax">)) && (</span><span class="identifier-syntax">Q</span><span class="plain-syntax">.</span><span class="element-syntax">index</span><span class="plain-syntax"> < </span><a href="4-sm.html#SP8" class="function-link"><span class="function-syntax">Str::len</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">S2</span><span class="plain-syntax">));</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">P</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP11" class="function-link"><span class="function-syntax">Str::forward</span></a><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><a href="4-sm.html#SP11" class="function-link"><span class="function-syntax">Str::forward</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Q</span><span class="plain-syntax">)) {</span>
|
||||
|
|
Binary file not shown.
|
@ -42,3 +42,49 @@ int Directories::next(scan_directory *D, text_stream *leafname) {
|
|||
void Directories::close(scan_directory *D) {
|
||||
Platform::closedir(D->directory_handle);
|
||||
}
|
||||
|
||||
@ It turns out to be useful to scan the contents of a directory in an order
|
||||
which is predictable regardless of platform -- |Platform::readdir| works in a
|
||||
different order on MacOS, Windows and Linux, even given the same directory
|
||||
of files to work on. So the following returns a linked list of the contents,
|
||||
sorted into alphabetical order, but case-insensitively. For the Inform project,
|
||||
at least, we don't anticipate ever dealing with files whose names disagree only
|
||||
in casing, so this ordering is effectively deterministic.
|
||||
|
||||
There's some time and memory overhead here, but unless we're dealing with
|
||||
directories holding upwards of 10,000 files or so, it'll be trivial.
|
||||
|
||||
=
|
||||
linked_list *Directories::listing(pathname *P) {
|
||||
int capacity = 4, used = 0;
|
||||
text_stream **listing_array = (text_stream **)
|
||||
(Memory::calloc(capacity, sizeof(text_stream *), ARRAY_SORTING_MREASON));
|
||||
scan_directory *D = Directories::open(P);
|
||||
if (D) {
|
||||
text_stream *entry = Str::new();
|
||||
while (Directories::next(D, entry)) {
|
||||
if (used == capacity) {
|
||||
int new_capacity = 4*capacity;
|
||||
text_stream **new_listing_array = (text_stream **)
|
||||
(Memory::calloc(new_capacity, sizeof(text_stream *), ARRAY_SORTING_MREASON));
|
||||
for (int i=0; i<used; i++) new_listing_array[i] = listing_array[i];
|
||||
listing_array = new_listing_array;
|
||||
capacity = new_capacity;
|
||||
}
|
||||
listing_array[used++] = entry;
|
||||
entry = Str::new();
|
||||
}
|
||||
Directories::close(D);
|
||||
}
|
||||
qsort(listing_array, (size_t) used, sizeof(text_stream *), Directories::compare_names);
|
||||
linked_list *L = NEW_LINKED_LIST(text_stream);
|
||||
for (int i=0; i<used; i++) ADD_TO_LINKED_LIST(listing_array[i], text_stream, L);
|
||||
Memory::I7_free(listing_array, ARRAY_SORTING_MREASON, capacity*((int) sizeof(text_stream *)));
|
||||
return L;
|
||||
}
|
||||
|
||||
int Directories::compare_names(const void *ent1, const void *ent2) {
|
||||
text_stream *tx1 = *((text_stream **) ent1);
|
||||
text_stream *tx2 = *((text_stream **) ent2);
|
||||
return Str::cmp_insensitive(tx1, tx2);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue