inweb-bootstrap/docs/foundation-module/P-abgtf.html

545 lines
49 KiB
HTML
Raw Normal View History

2020-04-15 22:45:08 +00:00
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>A Brief Guide to Foundation</title>
2020-04-23 22:23:44 +00:00
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
2020-04-15 22:45:08 +00:00
<meta name="viewport" content="width=device-width initial-scale=1">
<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>
MathJax = {
2020-04-21 23:52:25 +00:00
tex: {
inlineMath: '$', '$'], ['\\(', '\\)'
},
svg: {
fontCache: 'global'
}
2020-04-20 22:26:08 +00:00
};
</script>
<script type="text/javascript" id="MathJax-script" async
2020-04-21 23:52:25 +00:00
src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js">
2020-04-20 22:26:08 +00:00
</script>
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
2020-04-15 22:45:08 +00:00
</head>
2020-04-25 10:33:39 +00:00
<body class="commentary-font">
2020-04-15 22:45:08 +00:00
<nav role="navigation">
<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-15 22:45:08 +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>
</ul><h2>Example Webs</h2><ul>
<li><a href="../goldbach/index.html">goldbach</a></li>
<li><a href="../twinprimes/twinprimes.html">twinprimes</a></li>
<li><a href="../eastertide/index.html">eastertide</a></li>
</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-15 22:45:08 +00:00
</ul><h2>Related Projects</h2><ul>
<li><a href="../../../inform/docs/index.html">inform</a></li>
<li><a href="../../../intest/docs/index.html">intest</a></li>
</ul>
</nav>
<main role="main">
2020-04-23 22:23:44 +00:00
<!--Weave of 'A Brief Guide to Foundation' 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#P">Preliminaries</a></li><li><b>A Brief Guide to Foundation</b></li></ul></div>
<p class="purpose">Notes on getting started with the Foundation library.</p>
2020-04-15 22:45:08 +00:00
<ul class="toc"><li><a href="P-abgtf.html#SP1">&#167;1. Introduction</a></li><li><a href="P-abgtf.html#SP3">&#167;3. Truth</a></li><li><a href="P-abgtf.html#SP4">&#167;4. Text streams and formatted output</a></li><li><a href="P-abgtf.html#SP10">&#167;10. Objects</a></li><li><a href="P-abgtf.html#SP11">&#167;11. Methods</a></li><li><a href="P-abgtf.html#SP13">&#167;13. Collections</a></li><li><a href="P-abgtf.html#SP15">&#167;15. Files and paths</a></li><li><a href="P-abgtf.html#SP19">&#167;19. Handling webs</a></li><li><a href="P-abgtf.html#SP20">&#167;20. Miscellaneous other features</a></li></ul><hr class="tocbar">
2020-04-15 22:45:08 +00:00
2020-08-16 17:39:53 +00:00
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. Introduction. </b>The Foundation module supplies some of the conveniences of more modern
2020-04-15 22:45:08 +00:00
programming languages to ANSI C. It offers the usual stuff of standard
libraries everywhere: memory management, collection classes, filename and file
2022-03-05 21:36:26 +00:00
system access, regular-expression matching and so on, and it does so while
2020-04-15 22:45:08 +00:00
abstracting away differences between operating systems (Windows, Linux,
Unix, MacOS, Android and so on).
</p>
2020-04-24 23:06:02 +00:00
<p class="commentary">Almost all functionality is optional and can be ignored if not wanted. With a
2020-04-15 22:45:08 +00:00
few provisos, the code is thread-safe, sturdy and well tested, since it forms
the support code for the Inform programming language's compiler and outlying
tools, including Inweb itself. If you need to write a command-line utility in
ANSI C with no dependencies on other tools or libraries to speak of, you could
2020-04-21 23:52:25 +00:00
do worse. But you certainly don't need it to use <a href="../inweb/index.html" class="internal">inweb</a>, even if you're
2020-04-15 22:45:08 +00:00
writing in C.
</p>
2020-04-24 23:06:02 +00:00
<p class="commentary">For a brief example of a command-line utility using some of the commoner
2020-04-21 23:52:25 +00:00
features of Foundation in a simple way, see <a href="../eastertide/index.html" class="internal">eastertide</a>. Further exercises
can be found in <a href="../foundation-test/index.html" class="internal">foundation-test</a>.
2020-04-15 22:45:08 +00:00
</p>
2020-08-16 17:39:53 +00:00
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b>To use <a href="index.html" class="internal">foundation</a>, a program must at minimum do three things.
2020-04-15 22:45:08 +00:00
</p>
2020-04-24 23:06:02 +00:00
<p class="commentary">1. The Contents section of its web must import Foundation as a module, thus:
2020-04-15 22:45:08 +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"> </span><span class="element-syntax">Import</span><span class="plain-syntax">:</span><span class="string-syntax"> foundation</span>
2020-04-15 22:45:08 +00:00
</pre>
2020-04-24 23:06:02 +00:00
<p class="commentary">Import lines appear after the metadata, but before the roster of sections
2020-04-15 22:45:08 +00:00
and chapters.
</p>
2020-04-24 23:06:02 +00:00
<p class="commentary">2. The constant <span class="extract"><span class="extract-syntax">PROGRAM_NAME</span></span> must be defined equal to a C string with a
2020-04-15 22:45:08 +00:00
brief version of the program's name. For example,
</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="function-syntax">@d</span><span class="plain-syntax"> PROGRAM_NAME "declutter"</span>
2020-04-15 22:45:08 +00:00
</pre>
2020-04-24 23:06:02 +00:00
<p class="commentary">3. The <span class="extract"><span class="extract-syntax">main</span></span> function for the client should, as one of its very first acts,
2020-04-22 22:57:09 +00:00
call <span class="extract"><span class="extract-syntax">Foundation::start()</span></span>, and should similarly, just before it exits, call
<span class="extract"><span class="extract-syntax">Foundation::end()</span></span>. Any other module used should be started after Foundation
2020-04-15 22:45:08 +00:00
starts, and ended before Foundation ends.
</p>
2020-08-16 17:39:53 +00:00
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. Truth. </b>Every large C program starts by defining constants for truth and falsity. So
2020-04-22 22:57:09 +00:00
does Foundation: <span class="extract"><span class="extract-syntax">TRUE</span></span>, <span class="extract"><span class="extract-syntax">FALSE</span></span>, and a third state <span class="extract"><span class="extract-syntax">NOT_APPLICABLE</span></span>.
2020-04-15 22:45:08 +00:00
</p>
2020-08-16 17:39:53 +00:00
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. Text streams and formatted output. </b>Perhaps the most useful feature of Foundation is that it provides for
2020-04-15 22:45:08 +00:00
memory-managed strings of Unicode text. These are unified with text files
2020-04-21 23:52:25 +00:00
which are open for output, in a type called <a href="2-str.html#SP15" class="internal">text_stream</a>. It's expected
2020-04-15 22:45:08 +00:00
that they may be very large indeed, and appending text to or finding the
length of a text in memory runs in \(O(1)\) time.
</p>
2020-04-24 23:06:02 +00:00
<p class="commentary">A typical function writing to one of these might be:
2020-04-15 22:45:08 +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"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="identifier-syntax">Hypothetical::writer</span><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">authority</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">N</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"According to %S, the square of %d is %d.\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">authority</span><span class="plain-syntax">, </span><span class="identifier-syntax">N</span><span class="plain-syntax">, </span><span class="identifier-syntax">N</span><span class="plain-syntax">*</span><span class="identifier-syntax">N</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
2020-04-15 22:45:08 +00:00
</pre>
2020-04-24 23:06:02 +00:00
<p class="commentary">Here <span class="extract"><span class="extract-syntax">WRITE</span></span> is a variadic macro rather like <span class="extract"><span class="extract-syntax">printf</span></span>, and note the use of
2020-04-22 22:57:09 +00:00
the escape <span class="extract"><span class="extract-syntax">%S</span></span> to write a text stream. It writes formatted output into the
stream <span class="extract"><span class="extract-syntax">OUT</span></span>, and is actually an abbreviation for this:
2020-04-15 22:45:08 +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"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="identifier-syntax">Hypothetical::writer</span><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">authority</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">N</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">OUT</span><span class="plain-syntax">, </span><span class="string-syntax">"According to %S, the square of %d is %d.\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">authority</span><span class="plain-syntax">, </span><span class="identifier-syntax">N</span><span class="plain-syntax">, </span><span class="identifier-syntax">N</span><span class="plain-syntax">*</span><span class="identifier-syntax">N</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
2020-04-15 22:45:08 +00:00
</pre>
2020-04-24 23:06:02 +00:00
<p class="commentary">The function <span class="extract"><span class="extract-syntax">Hypothetical::writer</span></span> can write equally to a text file or to a
2020-04-15 22:45:08 +00:00
string, whichever it's given, and doesn't need to worry about memory management
or text encodings.
</p>
2020-04-24 23:06:02 +00:00
<p class="commentary">The standard output and standard error "files" on Unix-based systems are
2020-04-22 22:57:09 +00:00
referred to as <span class="extract"><span class="extract-syntax">STDOUT</span></span> and <span class="extract"><span class="extract-syntax">STDERR</span></span>, both constants of type <span class="extract"><span class="extract-syntax">text_stream *</span></span>
defined by Foundation. The value <span class="extract"><span class="extract-syntax">NULL</span></span>, used as a text stream, is valid and
2020-04-15 22:45:08 +00:00
prints as the empty string, while ignoring any content written to it.
2020-04-21 23:52:25 +00:00
All of these capitalised macros are defined in <a href="2-str.html" class="internal">Streams</a>.
2020-04-15 22:45:08 +00:00
</p>
2020-04-24 23:06:02 +00:00
<p class="commentary"><span class="extract"><span class="extract-syntax">PRINT("...")</span></span> is an abbreviation for <span class="extract"><span class="extract-syntax">WRITE_TO(STDOUT, "...")</span></span>, and
2020-04-22 22:57:09 +00:00
<span class="extract"><span class="extract-syntax">LOG("...")</span></span> similarly writes to the log file. (See <a href="2-dl.html" class="internal">Debugging Log</a>.)
2020-04-15 22:45:08 +00:00
</p>
2020-08-16 17:39:53 +00:00
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. </b>If you're using <a href="../inweb/M-tid.html" class="internal">The InC Dialect (in inweb)</a>, the slight extension to C made
2020-04-15 22:45:08 +00:00
by Inweb, there's a simple notation for constants of this type:
</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">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">error_message</span><span class="plain-syntax"> = </span><span class="identifier-syntax">I</span><span class="string-syntax">"quadro-triticale stocks depleted"</span><span class="plain-syntax">;</span>
2020-04-15 22:45:08 +00:00
</pre>
2020-04-24 23:06:02 +00:00
<p class="commentary">The <span class="extract"><span class="extract-syntax">I</span></span> prefix is meant to imitate the <span class="extract"><span class="extract-syntax">L</span></span> used in standard C99 for long string
2020-04-21 23:52:25 +00:00
constants. But this is a feature of <a href="../inweb/index.html" class="internal">inweb</a> rather than of Foundation.
2020-04-15 22:45:08 +00:00
</p>
2020-08-16 17:39:53 +00:00
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>&#167;6. </b>Programs doing a lot of parsing need to create and throw away strings all
2020-04-15 22:45:08 +00:00
of the time, so we shouldn't be too casual about memory management for them.
2020-04-21 23:52:25 +00:00
<a href="4-sm.html#SP2" class="internal">Str::new</a> creates a new empty string; <a href="4-sm.html#SP3" class="internal">Str::duplicate</a> duplicates an
2020-04-15 22:45:08 +00:00
existing one. But these are permanent creations, and not easy to deallocate
2020-04-21 23:52:25 +00:00
(though calling <a href="4-sm.html#SP15" class="internal">Str::clear</a> to empty out their text will free any large
2020-04-15 22:45:08 +00:00
amount of memory they might be using). If you want a string just for a
momentary period, do this:
</p>
2020-04-25 10:33:39 +00:00
<pre class="displayed-code all-displayed-code code-font">
2020-06-27 22:03:14 +00:00
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">alpha</span><span class="plain-syntax">)</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">alpha</span><span class="plain-syntax">, </span><span class="string-syntax">"This is temporary"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> ...</span>
2020-06-27 22:03:14 +00:00
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">alpha</span><span class="plain-syntax">)</span>
2020-04-15 22:45:08 +00:00
</pre>
2020-04-24 23:06:02 +00:00
<p class="commentary">Between the use of these two macros, <span class="extract"><span class="extract-syntax">alpha</span></span> is a valid <span class="extract"><span class="extract-syntax">text_stream *</span></span>,
2020-04-15 22:45:08 +00:00
and is a string capable of growing to arbitrary size.
</p>
2020-08-16 17:39:53 +00:00
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>&#167;7. </b>Foundation provides an elaborate system for providing new string escapes
2020-04-22 22:57:09 +00:00
like <span class="extract"><span class="extract-syntax">%S</span></span>: see <a href="2-wal.html" class="internal">Writers and Loggers</a>. A similar system manages a debugging
2020-04-15 22:45:08 +00:00
log, to which it's easy to make "dollar escapes" for pretty-printing internal
2020-04-22 22:57:09 +00:00
data structures: for example, if you've made a structure called <span class="extract"><span class="extract-syntax">recipe</span></span>, you
could make <span class="extract"><span class="extract-syntax">$R</span></span> pretty-print one.
2020-04-15 22:45:08 +00:00
</p>
2020-08-16 17:39:53 +00:00
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>&#167;8. </b>Foundation also has an extensive library of string-handling routines,
2020-04-15 22:45:08 +00:00
providing the sort of facilities you would expect in a typical scripting
2020-04-21 23:52:25 +00:00
language. See <a href="4-sm.html" class="internal">String Manipulation</a> and <a href="4-pm.html" class="internal">Pattern Matching</a>, which can
2020-04-15 22:45:08 +00:00
match text streams against regular expressions, though note that the latter
use an idiosyncratic notation.
</p>
2020-04-24 23:06:02 +00:00
<p class="commentary">There's also <a href="4-taa.html" class="internal">Tries and Avinues</a> for rapid character sequence parsing.
2020-04-15 22:45:08 +00:00
</p>
2020-04-24 23:06:02 +00:00
<p class="commentary">For slicing, see the <a href="4-sm.html#SP9" class="internal">string_position</a> type, representing positions for the
2020-04-21 23:52:25 +00:00
benefit of functions like <a href="4-sm.html#SP26" class="internal">Str::substr</a>.
2020-04-15 22:45:08 +00:00
</p>
2020-08-16 17:39:53 +00:00
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>&#167;9. </b>Individual characters are represented in Foundation using the standard
2020-04-22 22:57:09 +00:00
POSIX type <span class="extract"><span class="extract-syntax">wchar_t</span></span>, which on all modern systems is a very wide integer,
2020-04-15 22:45:08 +00:00
whether or not signed. It's safe to assume it can hold all normal Unicode
2020-04-21 23:52:25 +00:00
code points. See <a href="4-chr.html" class="internal">Characters</a> for class functions like <a href="4-chr.html#SP1" class="internal">Characters::isdigit</a>,
2020-04-15 22:45:08 +00:00
which have been carefully written to work equivalently on either Windows or
Unix-based systems.
</p>
2020-04-24 23:06:02 +00:00
<p class="commentary"><a href="4-cst.html" class="internal">C Strings</a> and <a href="4-ws.html" class="internal">Wide Strings</a> provide bare-minimum facilities for handling
2020-04-22 22:57:09 +00:00
traditional null-terminated <span class="extract"><span class="extract-syntax">char</span></span> and <span class="extract"><span class="extract-syntax">wchar_t</span></span> arrays, but don't use these.
2020-04-15 22:45:08 +00:00
Texts are just better.
</p>
2020-08-16 17:39:53 +00:00
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>&#167;10. Objects. </b>To a very limited extent, Foundation enables C programs to have "classes",
2020-05-09 12:05:00 +00:00
"objects" and "methods", and it makes use of that ability itself, too. (See
<a href="2-fc.html" class="internal">Foundation Classes</a> for the list of classes made by <a href="index.html" class="internal">foundation</a>.) For
example, suppose we are writing a program to store recipes, and we want
something in C which corresponds to objects of the class <span class="extract"><span class="extract-syntax">recipe</span></span>. We need to
do three things:
2020-04-15 22:45:08 +00:00
</p>
2020-05-09 12:05:00 +00:00
<p class="commentary">1. Declare an enumerated constant ending <span class="extract"><span class="extract-syntax">_CLASS</span></span> to represent this type in the
2020-04-15 22:45:08 +00:00
memory manager, and then make a matching use of a macro to define some associated
functions, which we never see or think about. For example:
2020-05-09 12:05:00 +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"> </span><span class="function-syntax">@</span><span class="plain-syntax"> Here are my classes...</span>
2020-04-15 22:45:08 +00:00
2020-05-09 12:05:00 +00:00
<span class="plain-syntax"> </span><span class="function-syntax">@e</span><span class="plain-syntax"> recipe_CLASS</span>
2020-04-15 22:45:08 +00:00
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> =</span>
2020-05-09 12:05:00 +00:00
<span class="plain-syntax"> DECLARE_CLASS(recipe)</span>
2020-04-15 22:45:08 +00:00
</pre>
2020-04-24 23:06:02 +00:00
<p class="commentary">The mention of "individually" is because this is for data structures where
2020-04-15 22:45:08 +00:00
we expect to have relatively few instances. If we expect to have huge numbers
of throwaway instances, we would instead write:
</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="function-syntax">@</span><span class="plain-syntax"> Here are my classes...</span>
2020-04-15 22:45:08 +00:00
2020-05-09 13:14:45 +00:00
<span class="plain-syntax"> </span><span class="function-syntax">@e</span><span class="plain-syntax"> salt_grain_CLASS</span>
2020-04-15 22:45:08 +00:00
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> =</span>
2020-05-09 12:05:00 +00:00
<span class="plain-syntax"> DECLARE_CLASS_ALLOCATED_IN_ARRAYS(salt_grain, 1000)</span>
2020-04-15 22:45:08 +00:00
</pre>
2020-04-24 23:06:02 +00:00
<p class="commentary">The memory manager then claims these in blocks of 1000. Use this only if it's
2020-05-09 13:14:45 +00:00
actually needed; note that <span class="extract"><span class="extract-syntax">DESTROY</span></span> cannot be used with objects created
this way.
2020-04-15 22:45:08 +00:00
</p>
2020-05-09 12:05:00 +00:00
<p class="commentary">2. We have to declare the actual structure, and <span class="extract"><span class="extract-syntax">typedef</span></span> the name to it. For
2020-04-15 22:45:08 +00:00
example:
2020-05-09 12:05:00 +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"> </span><span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">recipe</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name_of_dish</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">oven_temperature</span><span class="plain-syntax">;</span>
2020-05-09 12:05:00 +00:00
<span class="plain-syntax"> </span><span class="constant-syntax">CLASS_DEFINITION</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> } </span><span class="identifier-syntax">recipe</span><span class="plain-syntax">;</span>
2020-04-15 22:45:08 +00:00
</pre>
2020-05-09 12:05:00 +00:00
<p class="commentary">Here <span class="extract"><span class="extract-syntax">CLASS_DEFINITION</span></span> is a macro defined in <a href="2-mmr.html" class="internal">Memory</a> which expands to the
2020-04-15 22:45:08 +00:00
necessary field(s) to keep track of this. We won't use those fields, or ever
think about them.
</p>
2020-05-09 12:05:00 +00:00
<p class="commentary">3. In fact we've now finished. The macro <span class="extract"><span class="extract-syntax">CREATE(recipe)</span></span> returns a new
2020-04-22 22:57:09 +00:00
instance, and <span class="extract"><span class="extract-syntax">DESTROY(R)</span></span> would destroy an existing one, <span class="extract"><span class="extract-syntax">R</span></span>. Unless manually
2020-04-15 22:45:08 +00:00
destroyed, objects last forever; there is no garbage collection. In practice
the Inform tools suite, for which Foundation was written, almost never destroy
objects.
2020-05-09 12:05:00 +00:00
</p>
2020-04-24 23:06:02 +00:00
<p class="commentary">Customarily, though, we wrap the use of <span class="extract"><span class="extract-syntax">CREATE</span></span> in a constructor function:
</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">recipe</span><span class="plain-syntax"> *</span><span class="identifier-syntax">Recipes::new</span><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">recipe</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="identifier-syntax">recipe</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">name_of_dish</span><span class="plain-syntax"> = </span><span class="function-syntax">Str::duplicate</span><span class="plain-syntax">(</span><span class="identifier-syntax">name</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">oven_temperature</span><span class="plain-syntax"> = </span><span class="constant-syntax">200</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">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
2020-04-15 22:45:08 +00:00
</pre>
2020-04-24 23:06:02 +00:00
<p class="commentary">We also often use the convenient <span class="extract"><span class="extract-syntax">LOOP_OVER</span></span> macro:
2020-04-15 22:45:08 +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"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="identifier-syntax">Recipes::list_all</span><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"I know about the following recipes:\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">recipe</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">recipe</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"- %S\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">name_of_dish</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
2020-04-15 22:45:08 +00:00
</pre>
2020-05-09 12:05:00 +00:00
<p class="commentary"><span class="extract"><span class="extract-syntax">LOOP_OVER</span></span> loops through all created <span class="extract"><span class="extract-syntax">recipe</span></span> instances (which have not been
2020-04-15 22:45:08 +00:00
destroyed).
</p>
2020-04-24 23:06:02 +00:00
<p class="commentary">There are a few other facilities, for which see <a href="2-mmr.html" class="internal">Memory</a>, and also ways to
2020-05-09 12:05:00 +00:00
allocate memory for arrays &mdash; see <a href="2-mmr.html#SP24" class="internal">Memory::calloc</a> and <a href="2-mmr.html#SP24" class="internal">Memory::malloc</a>.
2020-04-15 22:45:08 +00:00
</p>
2020-08-16 17:39:53 +00:00
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>&#167;11. Methods. </b>It's also possible to have method calls on object instances, though the
2020-04-15 22:45:08 +00:00
syntax is not as tidy as it would be in an object-oriented language. To allow
2020-04-22 22:57:09 +00:00
this for <span class="extract"><span class="extract-syntax">recipe</span></span>, we would have to add another line to the structure:
2020-04-15 22:45:08 +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"> </span><span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">recipe</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name_of_dish</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">oven_temperature</span><span class="plain-syntax">;</span>
2020-05-09 12:05:00 +00:00
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">method_set</span><span class="plain-syntax"> *</span><span class="identifier-syntax">methods</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="constant-syntax">CLASS_DEFINITION</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> } </span><span class="identifier-syntax">recipe</span><span class="plain-syntax">;</span>
2020-04-15 22:45:08 +00:00
</pre>
2020-04-24 23:06:02 +00:00
<p class="commentary">and another line to the constructor function:
2020-04-15 22:45:08 +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"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">methods</span><span class="plain-syntax"> = </span><span class="function-syntax">Methods::new_set</span><span class="plain-syntax">();</span>
2020-04-15 22:45:08 +00:00
</pre>
2020-04-24 23:06:02 +00:00
<p class="commentary">The object <span class="extract"><span class="extract-syntax">R</span></span> is then ready to receive method calls. Each different call needs
2020-04-22 22:57:09 +00:00
an enumerated constant ending <span class="extract"><span class="extract-syntax">_MTID</span></span> to identify it, and an indication of the
2020-04-15 22:45:08 +00:00
type of the function call involved:
</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="function-syntax">@</span><span class="plain-syntax"> Here is my "cook the recipe" method call:</span>
2020-04-15 22:45:08 +00:00
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="function-syntax">@e</span><span class="plain-syntax"> COOK_MTID</span>
2020-04-15 22:45:08 +00:00
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> =</span>
2020-05-09 12:05:00 +00:00
<span class="plain-syntax"> VOID_METHOD_TYPE(COOK_MTID, recipe *R, int time_in_oven)</span>
2020-04-15 22:45:08 +00:00
</pre>
2020-05-09 12:05:00 +00:00
<p class="commentary">It's now possible to call this on any recipe:
2020-04-15 22:45:08 +00:00
</p>
2020-04-25 10:33:39 +00:00
<pre class="displayed-code all-displayed-code code-font">
2020-05-09 12:05:00 +00:00
<span class="plain-syntax"> </span><span class="identifier-syntax">VOID_METHOD_CALL</span><span class="plain-syntax">(</span><span class="identifier-syntax">duck_a_l_orange</span><span class="plain-syntax">, </span><span class="identifier-syntax">COOK_MTID</span><span class="plain-syntax">, </span><span class="constant-syntax">45</span><span class="plain-syntax">);</span>
2020-04-15 22:45:08 +00:00
</pre>
2020-04-24 23:06:02 +00:00
<p class="commentary">What then happens? Nothing at all, unless the recipe instance in question &mdash;
2020-04-22 22:57:09 +00:00
here, <span class="extract"><span class="extract-syntax">duck_a_l_orange</span></span> &mdash; has been given a receiver function. Let's revisit
2020-04-15 22:45:08 +00:00
the constructor function for recipes:
</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">recipe</span><span class="plain-syntax"> *</span><span class="identifier-syntax">Recipes::new</span><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">recipe</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="identifier-syntax">recipe</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">name_of_dish</span><span class="plain-syntax"> = </span><span class="function-syntax">Str::duplicate</span><span class="plain-syntax">(</span><span class="identifier-syntax">name</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">oven_temperature</span><span class="plain-syntax"> = </span><span class="constant-syntax">200</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">methods</span><span class="plain-syntax"> = </span><span class="function-syntax">Methods::new_set</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">METHOD_ADD</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">COOK_MTID</span><span class="plain-syntax">, </span><span class="identifier-syntax">Recipes::cook</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">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
2020-04-15 22:45:08 +00:00
</pre>
2020-04-24 23:06:02 +00:00
<p class="commentary">and now add:
2020-04-15 22:45:08 +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"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="identifier-syntax">Recipes::cook</span><span class="plain-syntax">(</span><span class="identifier-syntax">recipe</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">time_in_oven</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> ...</span>
<span class="plain-syntax"> }</span>
2020-04-15 22:45:08 +00:00
</pre>
2020-04-24 23:06:02 +00:00
<p class="commentary">using the arguments promised in the declaration above. With all this done,
2020-04-15 22:45:08 +00:00
the effect of
</p>
2020-04-25 10:33:39 +00:00
<pre class="displayed-code all-displayed-code code-font">
2020-05-09 12:05:00 +00:00
<span class="plain-syntax"> </span><span class="identifier-syntax">VOID_METHOD_CALL</span><span class="plain-syntax">(</span><span class="identifier-syntax">duck_a_l_orange</span><span class="plain-syntax">, </span><span class="identifier-syntax">COOK_MTID</span><span class="plain-syntax">, </span><span class="constant-syntax">45</span><span class="plain-syntax">);</span>
2020-04-15 22:45:08 +00:00
</pre>
2020-04-24 23:06:02 +00:00
<p class="commentary">is to call:
2020-04-15 22:45:08 +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"> </span><span class="identifier-syntax">Recipes::cook</span><span class="plain-syntax">(</span><span class="identifier-syntax">duck_a_l_orange</span><span class="plain-syntax">, </span><span class="constant-syntax">45</span><span class="plain-syntax">);</span>
</pre>
2020-08-16 17:39:53 +00:00
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>&#167;12. </b>In fact it's possible to attach multiple receivers to the same object, in
2020-04-15 22:45:08 +00:00
which case they each run in turn. As a variant on this, methods can also return
2020-04-22 22:57:09 +00:00
their "success". If multiple receivers run, the first to return <span class="extract"><span class="extract-syntax">TRUE</span></span> has
2020-04-15 22:45:08 +00:00
claimed the right to act, and subsequent receivers aren't consulted.
</p>
2020-05-09 12:05:00 +00:00
<p class="commentary">Such methods must be defined with <span class="extract"><span class="extract-syntax">INT_METHOD_CALL</span></span> and are rarely needed. See
2020-04-21 23:52:25 +00:00
<a href="2-mth.html" class="internal">Methods</a> for more.
2020-04-15 22:45:08 +00:00
</p>
2020-08-16 17:39:53 +00:00
<p class="commentary firstcommentary"><a id="SP13" class="paragraph-anchor"></a><b>&#167;13. Collections. </b>Foundation provides three sorts of "collection": see <a href="2-llas.html" class="internal">Linked Lists and Stacks</a>,
2020-04-21 23:52:25 +00:00
and also <a href="2-dct.html" class="internal">Dictionaries</a>. These all collect values which are expected to be
2020-04-22 22:57:09 +00:00
pointers: for example, text streams (of type <span class="extract"><span class="extract-syntax">text_stream *</span></span>) or objects like
2020-04-15 22:45:08 +00:00
the ones created above. For example,
</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">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cookbook</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEW_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">recipe</span><span class="plain-syntax">);</span>
2020-04-15 22:45:08 +00:00
</pre>
2020-04-24 23:06:02 +00:00
<p class="commentary">initialises a list as ready to use. It's then accessed by macros:
2020-04-15 22:45:08 +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"> </span><span class="identifier-syntax">recipe</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lobster_thermidor</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Recipes::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"lobster thermidor"</span><span class="plain-syntax">, </span><span class="constant-syntax">200</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ADD_TO_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">lobster_thermidor</span><span class="plain-syntax">, </span><span class="identifier-syntax">recipe</span><span class="plain-syntax">, </span><span class="identifier-syntax">cookbook</span><span class="plain-syntax">);</span>
2020-04-15 22:45:08 +00:00
</pre>
2020-04-24 23:06:02 +00:00
<p class="commentary">Similarly:
2020-04-15 22:45:08 +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"> </span><span class="identifier-syntax">recipe</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">recipe</span><span class="plain-syntax">, </span><span class="identifier-syntax">cookbook</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PRINT</span><span class="plain-syntax">(</span><span class="string-syntax">"I can make %S.\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">name_of_dish</span><span class="plain-syntax">);</span>
2020-04-15 22:45:08 +00:00
</pre>
2020-04-24 23:06:02 +00:00
<p class="commentary">That's about all you can do with linked lists: they are not nearly so well
2020-04-15 22:45:08 +00:00
worked-through as texts.
</p>
2020-04-24 23:06:02 +00:00
<p class="commentary">A dictionary is an associative hash which relates key names (which are text
2020-04-15 22:45:08 +00:00
streams) to values (which are usually, but not always, also text streams).
They behave very like hashes in Perl and, as the name suggests, use hashing
2020-04-21 23:52:25 +00:00
to make access rapid. See <a href="2-dct.html" class="internal">Dictionaries</a>.
2020-04-15 22:45:08 +00:00
</p>
2020-08-16 17:39:53 +00:00
<p class="commentary firstcommentary"><a id="SP14" class="paragraph-anchor"></a><b>&#167;14. </b>Foundation also provides for <a href="2-trs.html#SP1" class="internal">heterogeneous_tree</a>, which is a structure
able to hold a rooted tree in which nodes can be a variety of different
objects, rather than having to be uniform. Functions are provided to
build and verify such trees.
</p>
2020-08-16 17:39:53 +00:00
<p class="commentary firstcommentary"><a id="SP15" class="paragraph-anchor"></a><b>&#167;15. Files and paths. </b>Filenames and pathnames are, perhaps controversially, represented by two
2020-04-21 23:52:25 +00:00
different types: <a href="3-fln.html#SP1" class="internal">filename</a> and <a href="3-pth.html#SP1" class="internal">pathname</a>. The latter should perhaps
2020-04-15 22:45:08 +00:00
have been called "directoryname", but that ship has sailed.
</p>
2020-04-24 23:06:02 +00:00
<p class="commentary">Foundation does not have a unified type for URLs, as most modern libraries do.
2020-04-15 22:45:08 +00:00
But there are some advantages to that, in that the type-checker forces us to
be clear which we intend at any given time. Anyway, that vessel is also now
well out to sea.
</p>
2020-04-24 23:06:02 +00:00
<p class="commentary">These both hold names, not actual files: they are places where files or
2020-04-15 22:45:08 +00:00
directories might be.
</p>
2020-04-24 23:06:02 +00:00
<p class="commentary">Both tend to refer relative to the current working directory, represented by
2020-04-22 22:57:09 +00:00
the null <span class="extract"><span class="extract-syntax">pathname</span></span> pointer. <a href="3-pth.html#SP7" class="internal">Pathnames::up</a> and <a href="3-pth.html#SP4" class="internal">Pathnames::down</a> go
2020-04-15 22:45:08 +00:00
to parent or subdirectories, respectively. A filename cannot exist without
a pathname; for example,
</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">pathname</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax"> = </span><span class="function-syntax">Pathnames::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"App"</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">P</span><span class="plain-syntax"> = </span><span class="function-syntax">Pathnames::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"Config"</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax"> = </span><span class="function-syntax">Filenames::in</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"options.txt"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PRINT</span><span class="plain-syntax">(</span><span class="string-syntax">"I have arrived at %f.\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">);</span>
2020-04-15 22:45:08 +00:00
</pre>
2020-04-24 23:06:02 +00:00
<p class="commentary">produces, on platforms where <span class="extract"><span class="extract-syntax">/</span></span> is used as the file system dividing character,
2020-04-15 22:45:08 +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"> I have arrived at App/Config/options.txt.</span>
2020-04-15 22:45:08 +00:00
</pre>
2020-04-24 23:06:02 +00:00
<p class="commentary">Note the use of the escape <span class="extract"><span class="extract-syntax">%f</span></span> for printing filenames; there's also <span class="extract"><span class="extract-syntax">%p</span></span> for
2020-04-15 22:45:08 +00:00
pathnames.
</p>
2020-04-24 23:06:02 +00:00
<p class="commentary">See <a href="3-fln.html" class="internal">Filenames</a> and <a href="3-pth.html" class="internal">Pathnames</a> for more.
2020-04-15 22:45:08 +00:00
</p>
2020-08-16 17:39:53 +00:00
<p class="commentary firstcommentary"><a id="SP16" class="paragraph-anchor"></a><b>&#167;16. </b>If you need to iterate over the contents of a directory in the file system,
2020-04-21 23:52:25 +00:00
see <a href="3-drc.html" class="internal">Directories</a>. But to create a directory, call <a href="3-pth.html#SP9" class="internal">Pathnames::create_in_file_system</a>.
For synchronisation, try <a href="3-pth.html#SP10" class="internal">Pathnames::rsync</a>, but don't expect too much.
2020-04-15 22:45:08 +00:00
</p>
2020-04-24 23:06:02 +00:00
<p class="commentary">See <a href="3-pth.html" class="internal">Pathnames</a> for how to access the user's home directory, the current
2020-04-15 22:45:08 +00:00
working directory, and the installation directory for a program.
</p>
2020-08-16 17:39:53 +00:00
<p class="commentary firstcommentary"><a id="SP17" class="paragraph-anchor"></a><b>&#167;17. </b><a href="6-bf.html" class="internal">Binary Files</a> does the tedious work of writing binary data while allowing
2022-03-05 21:36:26 +00:00
for endian-ness; and it can also compute md5 hashes of binary files, which is
useful for testing the correctness of our tools.
2020-04-15 22:45:08 +00:00
</p>
2020-08-16 17:39:53 +00:00
<p class="commentary firstcommentary"><a id="SP18" class="paragraph-anchor"></a><b>&#167;18. </b><a href="4-tf.html" class="internal">Text Files</a> allows us to read text files. Its most useful function is
2020-04-21 23:52:25 +00:00
<a href="4-tf.html#SP5" class="internal">TextFiles::read</a>, which opens a file, can print an error if it doesn't
2020-04-15 22:45:08 +00:00
exist, and if it does, then feeds the lines one at a time to an iterator.
2020-04-22 22:57:09 +00:00
For example, if <span class="extract"><span class="extract-syntax">F</span></span> is a filename, the following reads the file into a
2020-04-15 22:45:08 +00:00
linked list of texts:
</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">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">Hypothetical::list_from_file</span><span class="plain-syntax">(</span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><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="function-syntax">TextFiles::read</span><span class="plain-syntax">(</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">, </span><span class="string-syntax">"can't open colony file"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">, </span><span class="identifier-syntax">Hypothetical::helper</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, (</span><span class="reserved-syntax">void</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">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
2020-04-20 22:26:08 +00:00
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="identifier-syntax">Hypothetical::helper</span><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">line</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">v_L</span><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="reserved-syntax">linked_list</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">v_L</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ADD_TO_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="identifier-syntax">line</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
2020-04-15 22:45:08 +00:00
</pre>
2020-04-24 23:06:02 +00:00
<p class="commentary">The <a href="4-tf.html#SP2" class="internal">text_file_position</a> here keeps track of where we are, and in particular,
2020-04-21 23:52:25 +00:00
functions from <a href="3-em.html" class="internal">Error Messages</a> can then report errors where they occur:
2020-04-15 22:45:08 +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"> </span><span class="function-syntax">Errors::in_text_file</span><span class="plain-syntax">(</span><span class="string-syntax">"bad syntax here"</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
</pre>
2020-08-16 17:39:53 +00:00
<p class="commentary firstcommentary"><a id="SP19" class="paragraph-anchor"></a><b>&#167;19. Handling webs. </b>Foundation provides routines which can read the metadata of a web, i.e., a
2020-04-21 23:52:25 +00:00
literate program in the <a href="../inweb/index.html" class="internal">inweb</a> format, from a copy in the file system.
The main function here is <a href="8-ws.html#SP5" class="internal">WebMetadata::get</a>, which returns a <a href="8-ws.html#SP2" class="internal">web_md</a>
2020-04-15 22:45:08 +00:00
object. You can then access its bibliographic data using
2020-04-21 23:52:25 +00:00
<a href="8-bdfw.html#SP6" class="internal">Bibliographic::get_datum</a>, or look at the web MD object directly to see
its modules (instances of <a href="8-wm.html#SP1" class="internal">module</a>), chapters (of <a href="8-ws.html#SP3" class="internal">chapter_md</a>) and
sections (of <a href="8-ws.html#SP4" class="internal">section_md</a>).
2020-04-15 22:45:08 +00:00
</p>
2020-08-16 17:39:53 +00:00
<p class="commentary firstcommentary"><a id="SP20" class="paragraph-anchor"></a><b>&#167;20. Miscellaneous other features. </b>What else? Well:
2020-04-15 22:45:08 +00:00
</p>
2020-05-17 22:05:11 +00:00
<ul class="items"><li>(a) <a href="3-tm.html" class="internal">Time</a> for the time of day and the date of Easter (no, really), and
for timing internal program activity using <a href="3-tm.html#SP6" class="internal">Time::start_stopwatch</a> and
<a href="3-tm.html#SP7" class="internal">Time::stop_stopwatch</a>;
2020-04-24 23:06:02 +00:00
</li><li>(b) <a href="3-shl.html" class="internal">Shell</a> for issuing shell commands via the C library's <span class="extract"><span class="extract-syntax">system</span></span> function,
2020-04-15 22:45:08 +00:00
or its equivalent;
2020-04-24 23:06:02 +00:00
</li><li>(c) <a href="5-htm.html" class="internal">HTML</a> and <a href="5-ee.html" class="internal">Epub Ebooks</a> for generating web pages and ebooks;
</li><li>(d) <a href="6-id.html" class="internal">Image Dimensions</a> and <a href="6-sd.html" class="internal">Sound Durations</a> for handling videos and music;
</li><li>(e) <a href="7-vn.html" class="internal">Version Numbers</a> and <a href="7-vnr.html" class="internal">Version Number Ranges</a> for managing version
2020-04-15 22:45:08 +00:00
numbers of software according to the Semantic Versioning standard.
2020-04-24 23:06:02 +00:00
</li></ul>
2020-04-30 22:36:38 +00:00
<nav role="progress"><div class="progresscontainer">
2020-05-01 21:51:33 +00:00
<ul class="progressbar"><li class="progressprevoff">&#10094;</li><li class="progresscurrentchapter">P</li><li class="progresscurrent">abgtf</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="progresschapter"><a href="3-em.html">3</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="1-fm.html">&#10095;</a></li></ul></div>
2020-04-30 22:36:38 +00:00
</nav><!--End of weave-->
2020-04-23 22:23:44 +00:00
2020-04-15 22:45:08 +00:00
</main>
</body>
</html>