1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-05-21 02:18:40 +03:00

Completed transition to JSON metadata for kits

This commit is contained in:
Graham Nelson 2022-06-04 13:20:45 +01:00
parent 958c286566
commit 307c937eba
21 changed files with 1076 additions and 615 deletions

View file

@ -1,6 +1,6 @@
# Inform 7
v10.1.0-beta+6V20 'Krypton' (3 June 2022)
v10.1.0-beta+6V21 'Krypton' (4 June 2022)
## About Inform 7

View file

@ -1,3 +1,3 @@
Prerelease: beta
Build Date: 3 June 2022
Build Number: 6V20
Build Date: 4 June 2022
Build Number: 6V21

View file

@ -89,14 +89,14 @@ group.
<span class="plain-syntax"> </span><span class="string-syntax">"Specifically, %2."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">KIT_MISWORDED_CE:</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">METADATA_MALFORMED_CE:</span>
<span class="plain-syntax"> </span><a href="2-sq.html#SP1" class="function-link"><span class="function-syntax">Problems::quote_work</span></a><span class="plain-syntax">(1, </span><span class="identifier-syntax">CE</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">copy</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">found_by</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">work</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_stream</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">CE</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">details</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_stream</span><span class="plain-syntax">(3, </span><span class="identifier-syntax">CE</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">copy</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">edition</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">work</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">genre</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">genre_name</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><a href="1-wtc.html#SP6" class="function-link"><span class="function-syntax">Task::syntax_tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">Untestable</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"The kit %1, which your source text makes use of, seems to be "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"damaged or incorrect: its identifying opening line is wrong. "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"Specifically, %2."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="string-syntax">"The %3 %1, which your source text makes use of, seems to have "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"metadata problems. Specifically: %2."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">EXT_TITLE_TOO_LONG_CE:</span><span class="plain-syntax"> {</span>

View file

@ -57,7 +57,7 @@
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="index.html">inbuild</a></li><li><a href="index.html#M">Manual</a></li><li><b>A Guide to Kits</b></li></ul></div>
<p class="purpose">Provisional documentation on how to make and build new kits.</p>
<ul class="toc"><li><a href="M-agtk.html#SP1">&#167;1. Historical note</a></li><li><a href="M-agtk.html#SP2">&#167;2. Exactly how kit dependencies are worked out</a></li><li><a href="M-agtk.html#SP12">&#167;12. Full specification of the kit metadata file</a></li><li><a href="M-agtk.html#SP24">&#167;24. Future directions</a></li></ul><hr class="tocbar">
<ul class="toc"><li><a href="M-agtk.html#SP1">&#167;1. Historical note</a></li><li><a href="M-agtk.html#SP2">&#167;2. Exactly how kit dependencies are worked out</a></li><li><a href="M-agtk.html#SP14">&#167;14. Other ingredients of the kit metadata file</a></li><li><a href="M-agtk.html#SP17">&#167;17. Future directions</a></li></ul><hr class="tocbar">
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. Historical note. </b>Inform 7 projects have always needed an underpinning of low-level code, in the
same way that all C programs can use standard library functions like <span class="extract"><span class="extract-syntax">printf</span></span>.
@ -141,18 +141,35 @@ for CommandParserKit includes:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">dependency: if CommandParserKit then WorldModelKit</span>
<span class="plain-syntax"> {</span>
<span class="plain-syntax"> "need": {</span>
<span class="plain-syntax"> "type": "kit",</span>
<span class="plain-syntax"> "title": "WorldModelKit"</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
</pre>
<p class="commentary">This means that any project depending on CommandParserKit automatically depends
<p class="commentary">Never mind the JSON syntax (all that punctuation) for now: what this is saying
is that CommandParserKit always needs WorldModelKit in order to function.
This means that any project depending on CommandParserKit automatically depends
on WorldModelKit too. BasicInformKit uses this facility as well, but in a
negative way. Its own metadata file says:
conditional way. Its own metadata file includes:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">dependency: if not WorldModelKit then BasicInformExtrasKit</span>
<span class="plain-syntax"> {</span>
<span class="plain-syntax"> "unless": {</span>
<span class="plain-syntax"> "type": "kit",</span>
<span class="plain-syntax"> "title": "WorldModelKit"</span>
<span class="plain-syntax"> },</span>
<span class="plain-syntax"> "need": {</span>
<span class="plain-syntax"> "type": "kit",</span>
<span class="plain-syntax"> "title": "BasicInformExtrasKit"</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
</pre>
<p class="commentary">It follows that if WorldModelKit is not present, then BasicInformExtrasKit is
automatically added instead.
<p class="commentary">Inbuild acts on this by checking to see if WorldModelKit is not present, and
in that case BasicInformExtrasKit is automatically added instead. (Positive
conditions can also be made, with "if" instead of "unless".)
</p>
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. </b>Kits can also use their metadata to specify that associated extensions should
@ -161,9 +178,17 @@ for BasicInformKit includes the lines:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">extension: Basic Inform by Graham Nelson</span>
<span class="plain-syntax">extension: English Language by Graham Nelson</span>
<span class="plain-syntax"> {</span>
<span class="plain-syntax"> "need": {</span>
<span class="plain-syntax"> "type": "extension",</span>
<span class="plain-syntax"> "title": "Basic Inform",</span>
<span class="plain-syntax"> "author": "Graham Nelson"</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
</pre>
<p class="commentary">...and similarly for another extension called English Language.
</p>
<ul class="footnotetexts"><li class="footnote" id="fn:2"><p class="inwebfootnote"><sup id="fnref:2"><a href="#fn:2" rel="footnote">2</a></sup> This in fact is the mechanism by which Inform decides which extensions
should be implicitly included in a project. Other extensions are included only
because of explicit "Include..." sentences in the source text.
@ -263,10 +288,6 @@ we next look at the build requirements for the project, we see:
<p class="commentary">So now BalloonKit is indeed a dependency.
</p>
<p class="commentary">See <a href="M-ui.html" class="internal">Manual (in inbuild)</a> for the full story on where the compiler expects to
find kits, but basically, they're managed much the way extensions are.
</p>
<ul class="footnotetexts"><li class="footnote" id="fn:3"><p class="inwebfootnote"><sup id="fnref:3"><a href="#fn:3" rel="footnote">3</a></sup> Both, so that whether the executable looking at the project is inbuild or
inform7, it will use the same set of kits. You want this.
<a href="#fnref:3" title="return to text"> &#x21A9;</a></p></li></ul>
@ -337,15 +358,127 @@ but the experience would have been painful. Even in its textual form, Inter is n
very legible, and it is highly verbose.
<a href="#fnref:4" title="return to text"> &#x21A9;</a></p></li><li class="footnote" id="fn:5"><p class="inwebfootnote"><sup id="fnref:5"><a href="#fn:5" rel="footnote">5</a></sup> At some point it may be developed out a little, but there's no great need.
<a href="#fnref:5" title="return to text"> &#x21A9;</a></p></li></ul>
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>&#167;10. </b>The metadata file at <span class="extract"><span class="extract-syntax">BalloonKit/kit_metadata.json</span></span> is going to be simple:
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>&#167;10. </b>The metadata file at <span class="extract"><span class="extract-syntax">BalloonKit/kit_metadata.json</span></span> is required to exist in
order for Inbuild to recognise this as being a kit at all; even if it doesn't
say very much, as in this example. This is (almost) minimal:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">extension: Party Balloons by Joseph-Michel Montgolfier</span>
<span class="plain-syntax">{</span>
<span class="plain-syntax"> "is": {</span>
<span class="plain-syntax"> "type": "kit",</span>
<span class="plain-syntax"> "title": "BalloonKit",</span>
<span class="plain-syntax"> "author": "Jacques-Étienne Montgolfier"</span>
<span class="plain-syntax"> "version": "3.2.7"</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary">In fact we don't really need this line at all (a kit does not need to have any
associated extensions), but it makes for a more interesting demonstration. We
can see an effect at once:
<p class="commentary">This is a JSON-format file: JSON, standing for Javascript Object Notation, is
now nothing really to do with the language Javascript and has instead become
an Internet standard for small packets of descriptive data, like ours. Many
full descriptions of JSON are available, but here are some brief notes:
</p>
<ul class="items"><li>&#9679; This is a UTF-8 plain text file. The acute accent in "Jacques-Étienne Montgolfier"
causes no problems, but quoted text is well advised to confine itself to the Unicode
Basic Multilingual Plane characters (with code-points 0 to 65535). Inside
quotation marks, <span class="extract"><span class="extract-syntax">\n</span></span> and <span class="extract"><span class="extract-syntax">\t</span></span> can be used for newlines and tabs, but a kit
shouldn't ever need them. <span class="extract"><span class="extract-syntax">\uDDDD</span></span> can be used to mean "the Unicode character
whose code is <span class="extract"><span class="extract-syntax">DDDD</span></span> in hexadecimal".
</li><li>&#9679; Braces <span class="extract"><span class="extract-syntax">{</span></span> and <span class="extract"><span class="extract-syntax">}</span></span> begin and end "objects". The whole set of metadata on
the kit is such an object, so the file has to open and close with <span class="extract"><span class="extract-syntax">{</span></span> and <span class="extract"><span class="extract-syntax">}</span></span>.
Inside such braces, we have a list of named values, divided by commas. Each
entry takes the form <span class="extract"><span class="extract-syntax">"name": value</span></span>. The name is in quotes, but the value
will only be quoted if it happens to be a string.
</li><li>&#9679; Square brackets <span class="extract"><span class="extract-syntax">[</span></span> and <span class="extract"><span class="extract-syntax">]</span></span> begin and end lists, with the entries in the
list divided by commas. For example, <span class="extract"><span class="extract-syntax">[ 1, 2, 17 ]</span></span> is a valid list of three
numbers.
</li><li>&#9679; Numbers are written in decimal, possibly with a minus sign: for example,
<span class="extract"><span class="extract-syntax">24</span></span> or <span class="extract"><span class="extract-syntax">-120</span></span>. (JSON also allows floating-point numbers, which Inbuild does
read, and stores to double precision, but kit metadata never needs these.)
</li><li>&#9679; The special notations <span class="extract"><span class="extract-syntax">true</span></span> and <span class="extract"><span class="extract-syntax">false</span></span> are used for so-called boolean
values, i.e., those which are either true or false.
</li><li>&#9679; The special notation <span class="extract"><span class="extract-syntax">null</span></span> is used to mean "I am not saying what this is",
but kit metadata never needs this.
</li><li>&#9679; JSON files are forbidden to contain comments, and Inbuild is very strict
about what hierarchies of objects it will read without errors.
</li></ul>
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>&#167;11. </b>Looking again at the minimal example, what do we have?
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">{</span>
<span class="plain-syntax"> "is": {</span>
<span class="plain-syntax"> "type": "kit",</span>
<span class="plain-syntax"> "title": "BalloonKit",</span>
<span class="plain-syntax"> "author": "Jacques-Étienne Montgolfier"</span>
<span class="plain-syntax"> "version": "3.2.7"</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary">The metadata is one big object. That object has a single named value, <span class="extract"><span class="extract-syntax">"is"</span></span>.
</p>
<p class="commentary">The value of <span class="extract"><span class="extract-syntax">"is"</span></span> is another object &mdash; hence the second pair of <span class="extract"><span class="extract-syntax">{</span></span> ... <span class="extract"><span class="extract-syntax">}</span></span> after
the colon. This second object gives the identity of the kit &mdash; says what it is,
in other words. That has four values:
</p>
<ul class="items"><li>(1) <span class="extract"><span class="extract-syntax">"type"</span></span>, which has to be <span class="extract"><span class="extract-syntax">"kit"</span></span>;
</li><li>(2) <span class="extract"><span class="extract-syntax">"title"</span></span>, which has to match the kit's name &mdash; Inbuild will throw an error
if BalloonKit's metadata file claims that its title is actually <span class="extract"><span class="extract-syntax">"AerostatiqueKit"</span></span>;
</li><li>(3) <span class="extract"><span class="extract-syntax">"author"</span></span>, which is optional, but which if given should follow the usual
conventions for author names of Inform extensions; and
</li><li>(4) <span class="extract"><span class="extract-syntax">"version"</span></span>, which is also optional, but whose use is strongly recommended.
This has to be a semantic version number. This follows Inbuild's usual semantic
version numbering conventions, so for example <span class="extract"><span class="extract-syntax">"5"</span></span> and <span class="extract"><span class="extract-syntax">"1.5.6-alpha.12"</span></span> would
both be valid. Note that in JSON terms it's a string, despite the word "number"
in the phrase "semantic version number", so it goes in double-quotes. This is
the version number which Inbuild will use to resolve dependencies. If a project
needs v1.7 or better, for example, Inbuild will not allow it to use
version 1.5.6-alpha.12 of a kit.
</li></ul>
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>&#167;12. </b>To make for a more interesting demonstration, now suppose that the kit
wants to require the use of an associated extension. We extend the metadata file to:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">{</span>
<span class="plain-syntax"> "is": {</span>
<span class="plain-syntax"> "type": "kit",</span>
<span class="plain-syntax"> "title": "BalloonKit",</span>
<span class="plain-syntax"> "author": "Jacques-Étienne Montgolfier"</span>
<span class="plain-syntax"> "version": "3.2.7"</span>
<span class="plain-syntax"> },</span>
<span class="plain-syntax"> "needs": [</span>
<span class="plain-syntax"> {</span>
<span class="plain-syntax"> "need": {</span>
<span class="plain-syntax"> "type": "extension",</span>
<span class="plain-syntax"> "title": "Party Balloons",</span>
<span class="plain-syntax"> "author": "Joseph-Michel Montgolfier"</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> ]</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary">Now our metadata object has a second named value, <span class="extract"><span class="extract-syntax">"needs"</span></span>. This has to be
a list, which in JSON is written in square brackets <span class="extract"><span class="extract-syntax">[ X, Y, Z, ... ]</span></span>. Here
the list has just one entry, in fact. The entries in the list all have to be
objects, which can have three possible values:
</p>
<ul class="items"><li>(1) <span class="extract"><span class="extract-syntax">"if"</span></span>, saying that the dependency is conditional on another kit being used &mdash;
see above for examples;
</li><li>(2) <span class="extract"><span class="extract-syntax">"unless"</span></span>, similarly but making the condition on another kit not being used;
</li><li>(3) <span class="extract"><span class="extract-syntax">"need"</span></span>, which says what the dependency is on.
</li></ul>
<p class="commentary">The <span class="extract"><span class="extract-syntax">"if"</span></span> and <span class="extract"><span class="extract-syntax">"unless"</span></span> clauses are optional. (And only one can be given.)
The <span class="extract"><span class="extract-syntax">"need"</span></span> clause is compulsory. This can say that the kit needs another
kit (there are examples above), but in this case it says the kit needs a
particular extension to be present.
</p>
<p class="commentary">We can see an effect at once:
</p>
<pre class="ConsoleText-displayed-code all-displayed-code code-font">
@ -383,7 +516,12 @@ it has not got. So suppose we provide one:
<span class="identifier-syntax">When</span><span class="plain-syntax"> </span><span class="identifier-syntax">play</span><span class="plain-syntax"> </span><span class="identifier-syntax">begins</span><span class="plain-syntax">:</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">perform</span><span class="plain-syntax"> </span><span class="identifier-syntax">an</span><span class="plain-syntax"> </span><span class="identifier-syntax">inflation</span><span class="plain-syntax"> </span><span class="identifier-syntax">with</span><span class="plain-syntax"> </span><span class="constant-syntax">3</span><span class="plain-syntax"> </span><span class="identifier-syntax">puffs</span><span class="plain-syntax">.</span>
</pre>
<p class="commentary">Now Inbuild is happier:
<p class="commentary">Note that this text does not explicitly say "Include Party Balloons by Joseph-Michel
Montgolfier" &mdash; it doesn't need to: the extension is automatically included by
the kit.
</p>
<p class="commentary">And now Inbuild is happier:
</p>
<pre class="ConsoleText-displayed-code all-displayed-code code-font">
@ -394,7 +532,7 @@ it has not got. So suppose we provide one:
<span class="ConsoleText-plain-syntax"> extension: Party Balloons by Joseph-Michel Montgolfier v2</span>
<span class="ConsoleText-plain-syntax"> ...</span>
</pre>
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>&#167;11. </b>The whole point of a kit is to be precompiled code, so we had better compile it.
<p class="commentary firstcommentary"><a id="SP13" class="paragraph-anchor"></a><b>&#167;13. </b>The whole point of a kit is to be precompiled code, so we had better compile it.
There are several ways to do this. One is to tell Inbuild directly:
</p>
@ -424,152 +562,101 @@ project is compiled in the Inform apps, by clicking "Go" in the usual way. Any
of its kits which need rebuilding are automatically rebuilt as part of the process.
</p>
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>&#167;12. Full specification of the kit metadata file. </b>This is a UTF-8 encoded Unicode text file, consisting of a sequence of commands
in any order, one per line. No commands are compulsory. An empty file is legal.
<p class="commentary firstcommentary"><a id="SP14" class="paragraph-anchor"></a><b>&#167;14. Other ingredients of the kit metadata file. </b>As noted above, <span class="extract"><span class="ConsoleText-extract-syntax">kit_metadata.json</span></span> must be a valid JSON file which encodes a
single object. The following are the legal member names; only <span class="extract"><span class="ConsoleText-extract-syntax">"is"</span></span> is mandatory,
and the rest sensibly default if not given.
</p>
<p class="commentary">Blank lines are ignored, as are lines whose first non-white-space character is <span class="extract"><span class="ConsoleText-extract-syntax">#</span></span>,
which are considered comments.
</p>
<p class="commentary firstcommentary"><a id="SP13" class="paragraph-anchor"></a><b>&#167;13. </b><span class="extract"><span class="ConsoleText-extract-syntax">version: V</span></span> gives the kit's version number. This follows Inbuild's usual semantic
version numbering conventions, so for example:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> version: 5</span>
<span class="plain-syntax"> version: 1.5.6-alpha.12</span>
</pre>
<p class="commentary">This is the version number which Inbuild will use to resolve dependencies. If a
project needs v1.7 or better, for example, Inbuild will not allow it to use
version 1.5.6-alpha.12 of a kit.
</p>
<p class="commentary firstcommentary"><a id="SP14" class="paragraph-anchor"></a><b>&#167;14. </b><span class="extract"><span class="extract-syntax">compatibility: C</span></span> allows us to say which architectures or final targets
<ul class="items"><li>&#9679; <span class="extract"><span class="ConsoleText-extract-syntax">"is"</span></span>, an object identifying what kit this is. See above.
</li><li>&#9679; <span class="extract"><span class="ConsoleText-extract-syntax">"needs"</span></span>, a list of objects each of which specifies a possibly conditional
dependency on other resources. See above.
</li><li>&#9679; <span class="extract"><span class="ConsoleText-extract-syntax">"compatibility"</span></span>, a string which describes which architectures or final targets
the kit is compatible with. By default, Inbuild assumes it will work with anything,
equivalent to <span class="extract"><span class="extract-syntax">compatibility: all</span></span>. But for example:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> compatibility: for 16-bit with debugging only</span>
<span class="plain-syntax"> compatibility: not for 32-bit</span>
<span class="plain-syntax"> compatibility: for Inform6 version 8</span>
<span class="plain-syntax"> compatibility: not for C</span>
</pre>
<p class="commentary">In general, it's best to stick to architectural constraints (i.e. 16 or 32 bit,
with or without debugging support) and not to constrain the final target unless
really necessary.
</p>
<p class="commentary firstcommentary"><a id="SP15" class="paragraph-anchor"></a><b>&#167;15. </b><span class="extract"><span class="extract-syntax">defines Main: yes</span></span> or <span class="extract"><span class="extract-syntax">defines Main: no</span></span>. The default is <span class="extract"><span class="extract-syntax">no</span></span>, so use this
only to specify that the kit contains within it a definition of the <span class="extract"><span class="extract-syntax">Main</span></span>
function. But only the shipped-with-Inform kits should ever do this.
</p>
<p class="commentary firstcommentary"><a id="SP16" class="paragraph-anchor"></a><b>&#167;16. </b><span class="extract"><span class="extract-syntax">natural language: yes</span></span> or <span class="extract"><span class="extract-syntax">natural language: no</span></span>. The default is <span class="extract"><span class="extract-syntax">no</span></span>; use
this only to say that the kit is a language support kit, like EnglishLanguageKit.
</p>
<p class="commentary firstcommentary"><a id="SP17" class="paragraph-anchor"></a><b>&#167;17. </b><span class="extract"><span class="extract-syntax">insert: X</span></span>. This sneakily allows a sentence of Inform 7 source text to be
inserted into any project using the kit. For example:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> insert: Use maximum inflation level of 20.</span>
</pre>
<p class="commentary">But in general it's better not to use this at all, and to put any such material
in an associated extension which is automatically included.
</p>
<p class="commentary firstcommentary"><a id="SP18" class="paragraph-anchor"></a><b>&#167;18. </b><span class="extract"><span class="extract-syntax">kinds: F</span></span>, where <span class="extract"><span class="extract-syntax">F</span></span> is the name of a Neptune file. Neptune is a mini-language
for setting up kinds and kind constructors inside the compiler: see
<a href="../kinds-module/4-abgtn.html" class="internal">A Brief Guide to Neptune (in kinds)</a> for much more on this. The file <span class="extract"><span class="extract-syntax">F</span></span> should
be placed as <span class="extract"><span class="extract-syntax">BalloonKit/kinds/F</span></span>. For example:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">kinds: Protocols.neptune</span>
<span class="plain-syntax">kinds: Core.neptune</span>
</pre>
<p class="commentary firstcommentary"><a id="SP19" class="paragraph-anchor"></a><b>&#167;19. </b><span class="extract"><span class="extract-syntax">extension: E</span></span>, where <span class="extract"><span class="extract-syntax">E</span></span> is the name of an extension. A version number
can optionally be given, too. For example:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">extension: Party Balloons by Joseph-Michel Montgolfier</span>
<span class="plain-syntax">extension: version 2.1 of Party Balloons by Joseph-Michel Montgolfier</span>
</pre>
<p class="commentary">Inbuild will now automatically include this extension if it can find it; if
not, the build will halt. Compatibility with the version number is done by
semantic version numbering rules, so v2.1.67 would be fine, but not v2.2, v1,
v3, and so forth. Note that kits can mandate multiple extensions, not just one.
</p>
<p class="commentary firstcommentary"><a id="SP20" class="paragraph-anchor"></a><b>&#167;20. </b><span class="extract"><span class="extract-syntax">activate: F</span></span> and <span class="extract"><span class="extract-syntax">deactivate: F</span></span>. This says that if the kit is present, then
a given feature inside the compiler <span class="extract"><span class="extract-syntax">F</span></span> should be switched on or off. For
example, the metadata for CommandParserKit includes:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">activate: command</span>
</pre>
<p class="commentary">which enables command grammar to be part of the Inform language. WorldModelKit
more ambitiously says:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">activate: interactive fiction</span>
<span class="plain-syntax">activate: multimedia</span>
</pre>
<p class="commentary">It is these activation lines, in WorldModelKit and CommandParserKit, which cause
the Inform language to have IF-specific features during a compilation. Without
them, the language would just be Basic Inform.
</p>
<p class="commentary">The feature names <span class="extract"><span class="extract-syntax">F</span></span> are the names of plugins inside the compiler, and this is
not the place to document that. See the implementation at <a href="../core-module/3-pm.html" class="internal">Chapter 3: Plugins (in core)</a>.
But in general, unless you are performing wild experiments with new language
features inside the compiler, never use <span class="extract"><span class="extract-syntax">activate</span></span> or <span class="extract"><span class="extract-syntax">deactivate</span></span>.
</p>
<p class="commentary firstcommentary"><a id="SP21" class="paragraph-anchor"></a><b>&#167;21. </b><span class="extract"><span class="extract-syntax">dependency: if X then Y</span></span> and <span class="extract"><span class="extract-syntax">dependency: if not X then Y</span></span>. This specifies
dependencies between kits; often <span class="extract"><span class="extract-syntax">X</span></span> or <span class="extract"><span class="extract-syntax">Y</span></span> will be the kit you are currently
defining, but not necessarily. Rules are considered for all kits currently loaded.
For example, this is part of the metadata for CommandParserKit:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">dependency: if CommandParserKit then WorldModelKit</span>
</pre>
<p class="commentary">A few points to note:
</p>
<ul class="items"><li>&#9679; Rules are considered only for kits which are loaded. There is no way to
make BalloonKit parasitically attach to all projects by giving it the rule
<span class="extract"><span class="extract-syntax">if not BalloonKit then BalloonKit</span></span>, because this rule will only be looked at
if BalloonKit has already loaded.
</li><li>&#9679; The outcome cannot be <span class="extract"><span class="extract-syntax">... then not Y</span></span>; once loaded, a kit cannot be
unloaded. So these dependency rules can only cause extra kits to be added.
</li><li>&#9679; Positive rules <span class="extract"><span class="extract-syntax">if ...</span></span> are considered first, and only then negative ones
<span class="extract"><span class="extract-syntax">if not ...</span></span>. Within each category, kits have their rules looked at in order
of their priority (see below).
</li><li>&#9679; Version number requirements cannot be specified for either <span class="extract"><span class="extract-syntax">X</span></span> or <span class="extract"><span class="extract-syntax">Y</span></span>
at present.
equivalent to <span class="extract"><span class="ConsoleText-extract-syntax">"compatibility": "all"</span></span>. In general, it's best to stick to purely
architectural constraints (i.e. 16 or 32 bit, with or without debugging support)
and not to constrain the final target unless really necessary. But the following
are all legal:
</li></ul>
<p class="commentary firstcommentary"><a id="SP22" class="paragraph-anchor"></a><b>&#167;22. </b><span class="extract"><span class="extract-syntax">priority: N</span></span>, where <span class="extract"><span class="extract-syntax">N</span></span> is a number from 0 to 100. This is used only to
decide whose wishes get priority when Inbuild is performing if-this-then-that
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> "compatibility": "for 16-bit with debugging only"</span>
<span class="plain-syntax"> "compatibility": "not for 32-bit"</span>
<span class="plain-syntax"> "compatibility": "for Inform6 version 8"</span>
<span class="plain-syntax"> "compatibility": "not for C"</span>
</pre>
<ul class="items"><li>&#9679; <span class="extract"><span class="extract-syntax">"activates"</span></span> is a list of strings describing optional features of the Inform
compiler to switch on if this kit is being used. The feature names are the names
of plugins inside the compiler, and this is not the place to document that. See
the implementation at <a href="../core-module/3-pm.html" class="internal">Chapter 3: Plugins (in core)</a>. But in general, unless you are performing
wild experiments with new language features inside the compiler, you will never
need <span class="extract"><span class="extract-syntax">"activates"</span></span>. It really exists for the benefit of the built-in kits. For
example, WorldModelKit does the following:
</li></ul>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> "activates": [ "interactive fiction", "multimedia" ]</span>
</pre>
<ul class="items"><li>&#9679; <span class="extract"><span class="extract-syntax">"deactivates"</span></span> is a similar list describing what to turn off.
</li><li>&#9679; <span class="extract"><span class="extract-syntax">"kit-details"</span></span> is a set of oddball settings which make sense only for kits.
The reason these are hived off in their own sub-object is so that the same
basic file format can be used for JSON describing other resources, too.
<span class="extract"><span class="extract-syntax">"kit-details"</span></span> can only legally be used if the <span class="extract"><span class="extract-syntax">"type"</span></span> in the <span class="extract"><span class="extract-syntax">"is"</span></span> object
is set to <span class="extract"><span class="extract-syntax">"kit"</span></span>.
</li></ul>
<p class="commentary firstcommentary"><a id="SP15" class="paragraph-anchor"></a><b>&#167;15. </b>The <span class="extract"><span class="extract-syntax">"kit-details"</span></span> object can contain the following, all of which are
optional. Only the first is likely to be useful for a kit other than one of
those built in to the Inform installation.
</p>
<ul class="items"><li>&#9679; <span class="extract"><span class="extract-syntax">"provides-kinds"</span></span> is a list of strings. These are the names of Neptune
files to read in. Neptune is a mini-language for setting up kinds and kind
constructors inside the Inform compiler: see <a href="../kinds-module/4-abgtn.html" class="internal">A Brief Guide to Neptune (in kinds)</a>
for much more on this. Each named file <span class="extract"><span class="extract-syntax">F</span></span> should be placed as <span class="extract"><span class="extract-syntax">BalloonKit/kinds/F</span></span>.
For example, WorldModelKit does this:
</li></ul>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">"provides-kinds": [ "Actions.neptune", "Times.neptune", "Scenes.neptune", "Figures.neptune", "Sounds.neptune" ]</span>
</pre>
<ul class="items"><li>&#9679; <span class="extract"><span class="extract-syntax">"has-priority"</span></span> is a number, from 0 to 100. This is used only to decide
whose wishes get priority when Inbuild is performing if-this-then-that
decisions to sort out which kits are present in a project. The default is 10,
and for almost all kits it should stay that way. Lower-numbered kits have
"more important" wishes than higher-numbered ones.
</li><li>&#9679; <span class="extract"><span class="extract-syntax">"defines-Main"</span></span> is a boolean, so its value has to be <span class="extract"><span class="extract-syntax">true</span></span> or <span class="extract"><span class="extract-syntax">false</span></span>.
If it isn't given, the value will be <span class="extract"><span class="extract-syntax">false</span></span>. This is useful only for the
built-in kits supplied with Inform, and indicates whether or not they define
a <span class="extract"><span class="extract-syntax">Main</span></span> function in Inter.
</li><li>&#9679; <span class="extract"><span class="extract-syntax">"indexes-with-structure"</span></span> is a string. This is useful only for the
built-in kits supplied with Inform, and indicates which structure file should
be used to generate the Index of a project. (There are two versions of the
index, one for Basic Inform projects, the other for interactive-fiction ones.)
</li><li>&#9679; <span class="extract"><span class="extract-syntax">"inserts-source-text"</span></span> is a string. This sneakily allows a sentence of
Inform 7 source text to be inserted into any project using the kit. Its use
is very much a last resort: if at all possible, put such material in an
associated extension, and then auto-include that extension using a <span class="extract"><span class="extract-syntax">"needs"</span></span>
dependency (see above). But, for example:
</li></ul>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> "inserts-source-text": "Use maximum inflation level of 20."</span>
</pre>
<p class="commentary firstcommentary"><a id="SP16" class="paragraph-anchor"></a><b>&#167;16. </b>Here are a few footnotes on how Inbuild resolves the "needs" requirements
of multiple kits, which may clarify what happens in apparently ambiguous
situations.
</p>
<p class="commentary firstcommentary"><a id="SP23" class="paragraph-anchor"></a><b>&#167;23. </b><span class="extract"><span class="extract-syntax">index from: C</span></span> can change the structure of the Index for a project using
this kit, but in practice this should be done only by BasicInformKit or by
WorldModelKit. (There are two versions of the index, one for Basic Inform
projects, the other for interactive-fiction ones.)
</p>
<p class="commentary firstcommentary"><a id="SP24" class="paragraph-anchor"></a><b>&#167;24. Future directions. </b>It will be noted that a kit can include an extension automatically, but not
<ul class="items"><li>&#9679; Needs are considered only for kits which are loaded. There is no way to
make BalloonKit parasitically attach to all projects by giving it a rule
saying in effect "unless you have BalloonKit then you need BalloonKit",
because although you could write such a rule, it would only be processed
when BalloonKit had already loaded &mdash; and would then have no effect.
</li><li>&#9679; A kit cannot be unloaded once loaded. So "needs" rules can only cause
extra kits to be added. It follows that there can never be a loop caused
by kits repeatedly loading and unloading each other through irresolvable
constraints. But it also follows that the outcome in such a case can depend
on the order in which rules are considered.
</li><li>&#9679; Positive needs using "if" (or unconditional needs) are considered first,
and only then negative ones using "unless". Within each category, kits have
their needs looked at in order of their priority numbers (see above).
</li></ul>
<p class="commentary firstcommentary"><a id="SP17" class="paragraph-anchor"></a><b>&#167;17. Future directions. </b>It will be noted that a kit can include an extension automatically, but not
vice versa. Indeed, at present there is no way for Inform 7 source text to ask
for a kit to be included. This limitation is intentional for now.
</p>

View file

@ -72,7 +72,7 @@ fields are blank.
</p>
<pre class="definitions code-font"><span class="definition-keyword">enum</span> <span class="constant-syntax">OPEN_FAILED_CE</span><span class="plain-syntax"> </span><span class="identifier-syntax">from</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">KIT_MISWORDED_CE</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">METADATA_MALFORMED_CE</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">EXT_MISWORDED_CE</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">EXT_TITLE_TOO_LONG_CE</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">EXT_AUTHOR_TOO_LONG_CE</span>
@ -121,7 +121,7 @@ fields are blank.
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">CE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">copy_error</span><span class="plain-syntax"> *</span><span class="function-syntax">CopyErrors::new_T</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">CopyErrors::new_T</span></span>:<br/>JSON Metadata - <a href="2-jm.html#SP1_1">&#167;1.1</a>, <a href="2-jm.html#SP1_2">&#167;1.2</a>, <a href="2-jm.html#SP1_3_1">&#167;1.3.1</a>, <a href="2-jm.html#SP1_3_2">&#167;1.3.2</a>, <a href="2-jm.html#SP1_3_3">&#167;1.3.3</a>, <a href="2-jm.html#SP1_3_4">&#167;1.3.4</a>, <a href="2-jm.html#SP1_3_5">&#167;1.3.5</a><br/>Extension Services - <a href="5-es.html#SP2_2">&#167;2.2</a>, <a href="5-es.html#SP2_2_3">&#167;2.2.3</a>, <a href="5-es.html#SP2_2_3_2">&#167;2.2.3.2</a>, <a href="5-es.html#SP2_3">&#167;2.3</a><br/>Kit Services - <a href="5-ks.html#SP4_1">&#167;4.1</a>, <a href="5-ks.html#SP4_1_1">&#167;4.1.1</a>, <a href="5-ks.html#SP4_1_3">&#167;4.1.3</a><br/>Project Services - <a href="5-ps2.html#SP28">&#167;28</a><br/>Headings - <a href="6-hdn.html#SP22_2">&#167;22.2</a><br/>Inclusions - <a href="6-inc.html#SP5_1_1">&#167;5.1.1</a>, <a href="6-inc.html#SP5_1_2">&#167;5.1.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">cat</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">subcat</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">NB</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">copy_error</span><span class="plain-syntax"> *</span><span class="function-syntax">CopyErrors::new_T</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">CopyErrors::new_T</span></span>:<br/>JSON Metadata - <a href="2-jm.html#SP1_1">&#167;1.1</a>, <a href="2-jm.html#SP1_2">&#167;1.2</a>, <a href="2-jm.html#SP1_3_1">&#167;1.3.1</a>, <a href="2-jm.html#SP1_3_2">&#167;1.3.2</a>, <a href="2-jm.html#SP1_3_3">&#167;1.3.3</a>, <a href="2-jm.html#SP1_3_4">&#167;1.3.4</a>, <a href="2-jm.html#SP1_3_5">&#167;1.3.5</a>, <a href="2-jm.html#SP1_4">&#167;1.4</a>, <a href="2-jm.html#SP2">&#167;2</a><br/>Extension Services - <a href="5-es.html#SP2_2">&#167;2.2</a>, <a href="5-es.html#SP2_2_3">&#167;2.2.3</a>, <a href="5-es.html#SP2_2_3_2">&#167;2.2.3.2</a>, <a href="5-es.html#SP2_3">&#167;2.3</a><br/>Kit Services - <a href="5-ks.html#SP4_1">&#167;4.1</a>, <a href="5-ks.html#SP4_4">&#167;4.4</a>, <a href="5-ks.html#SP4_4_1">&#167;4.4.1</a>, <a href="5-ks.html#SP4_4_1_1">&#167;4.4.1.1</a>, <a href="5-ks.html#SP4_4_2">&#167;4.4.2</a><br/>Project Services - <a href="5-ps2.html#SP28">&#167;28</a><br/>Headings - <a href="6-hdn.html#SP22_2">&#167;22.2</a><br/>Inclusions - <a href="6-inc.html#SP5_1_1">&#167;5.1.1</a>, <a href="6-inc.html#SP5_1_2">&#167;5.1.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">cat</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">subcat</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">NB</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">copy_error</span><span class="plain-syntax"> *</span><span class="identifier-syntax">CE</span><span class="plain-syntax"> = </span><a href="2-ce.html#SP2" class="function-link"><span class="function-syntax">CopyErrors::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cat</span><span class="plain-syntax">, </span><span class="identifier-syntax">subcat</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CE</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">details</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::duplicate</span><span class="plain-syntax">(</span><span class="identifier-syntax">NB</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">CE</span><span class="plain-syntax">;</span>
@ -191,7 +191,8 @@ output.
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">CE</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">error_category</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">OPEN_FAILED_CE:</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"unable to open file %f"</span><span class="plain-syntax">, </span><span class="identifier-syntax">CE</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">details_file</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">EXT_MISWORDED_CE:</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"extension misworded: %S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">CE</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">details</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">KIT_MISWORDED_CE:</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"kit has incorrect metadata: %S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">CE</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">details</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">METADATA_MALFORMED_CE:</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%S has incorrect metadata: %S"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CE</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">copy</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">edition</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">work</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">genre</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">genre_name</span><span class="plain-syntax">, </span><span class="identifier-syntax">CE</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">details</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">EXT_TITLE_TOO_LONG_CE:</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"title too long: %d characters (max is %d)"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CE</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">details_N</span><span class="plain-syntax">, </span><span class="constant-syntax">MAX_EXTENSION_TITLE_LENGTH</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">EXT_AUTHOR_TOO_LONG_CE:</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"author name too long: %d characters (max is %d)"</span><span class="plain-syntax">,</span>

View file

@ -89,7 +89,7 @@ stored here.
<span class="plain-syntax"> </span><span class="identifier-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">inbuild_copy</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure inbuild_copy is accessed in 1/ic, 2/nst, 2/jm, 3/bg, 3/ib, 3/bs2, 3/is, 3/is2, 3/is3, 3/is4, 4/em, 4/km, 4/lm, 4/pm, 4/pbm, 4/pfm, 4/tm, 5/es, 5/ks, 5/ls, 5/ps2, 6/st, 6/hdn, 6/tbs, 6/inc, 7/dct, 7/cns, 7/ip, 7/ip2 and here.</li></ul>
<ul class="endnotetexts"><li>The structure inbuild_copy is accessed in 1/ic, 2/ce, 2/nst, 2/jm, 3/bg, 3/ib, 3/bs2, 3/is, 3/is2, 3/is3, 3/is4, 4/em, 4/km, 4/lm, 4/pm, 4/pbm, 4/pfm, 4/tm, 5/es, 5/ks, 5/ls, 5/ps2, 6/st, 6/hdn, 6/tbs, 6/inc, 7/dct, 7/cns, 7/ip, 7/ip2 and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b>Copies are created by the managers for the respective genres, usually when
claiming. If you are a manager, do not call this...
</p>
@ -141,7 +141,7 @@ for later reporting. These are stored in a list.
</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">Copies::attach_error</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">Copies::attach_error</span></span>:<br/>JSON Metadata - <a href="2-jm.html#SP1_1">&#167;1.1</a>, <a href="2-jm.html#SP1_2">&#167;1.2</a>, <a href="2-jm.html#SP1_3_1">&#167;1.3.1</a>, <a href="2-jm.html#SP1_3_2">&#167;1.3.2</a>, <a href="2-jm.html#SP1_3_3">&#167;1.3.3</a>, <a href="2-jm.html#SP1_3_4">&#167;1.3.4</a>, <a href="2-jm.html#SP1_3_5">&#167;1.3.5</a><br/>Extension Services - <a href="5-es.html#SP2_2">&#167;2.2</a>, <a href="5-es.html#SP2_2_3">&#167;2.2.3</a>, <a href="5-es.html#SP2_2_3_2">&#167;2.2.3.2</a>, <a href="5-es.html#SP2_3">&#167;2.3</a><br/>Kit Services - <a href="5-ks.html#SP4_1">&#167;4.1</a>, <a href="5-ks.html#SP4_1_1">&#167;4.1.1</a>, <a href="5-ks.html#SP4_1_3">&#167;4.1.3</a><br/>Project Services - <a href="5-ps2.html#SP28">&#167;28</a><br/>Source Text - <a href="6-st.html#SP2">&#167;2</a>, <a href="6-st.html#SP3">&#167;3</a>, <a href="6-st.html#SP6">&#167;6</a>, <a href="6-st.html#SP14">&#167;14</a><br/>Headings - <a href="6-hdn.html#SP12_1">&#167;12.1</a>, <a href="6-hdn.html#SP12_2">&#167;12.2</a>, <a href="6-hdn.html#SP22_1">&#167;22.1</a>, <a href="6-hdn.html#SP23_2">&#167;23.2</a>, <a href="6-hdn.html#SP22_2">&#167;22.2</a>, <a href="6-hdn.html#SP22_3">&#167;22.3</a><br/>The Bibliographic Sentence - <a href="6-tbs.html#SP1">&#167;1</a><br/>Inclusions - <a href="6-inc.html#SP2_1">&#167;2.1</a>, <a href="6-inc.html#SP5_1_1">&#167;5.1.1</a>, <a href="6-inc.html#SP5_1_2">&#167;5.1.2</a>, <a href="6-inc.html#SP6_1">&#167;6.1</a>, <a href="6-inc.html#SP8_1">&#167;8.1</a>, <a href="6-inc.html#SP10">&#167;10</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inbuild_copy</span><span class="plain-syntax"> *</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="reserved-syntax">copy_error</span><span class="plain-syntax"> *</span><span class="identifier-syntax">CE</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Copies::attach_error</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">Copies::attach_error</span></span>:<br/>JSON Metadata - <a href="2-jm.html#SP1_1">&#167;1.1</a>, <a href="2-jm.html#SP1_2">&#167;1.2</a>, <a href="2-jm.html#SP1_3_1">&#167;1.3.1</a>, <a href="2-jm.html#SP1_3_2">&#167;1.3.2</a>, <a href="2-jm.html#SP1_3_3">&#167;1.3.3</a>, <a href="2-jm.html#SP1_3_4">&#167;1.3.4</a>, <a href="2-jm.html#SP1_3_5">&#167;1.3.5</a>, <a href="2-jm.html#SP1_4">&#167;1.4</a>, <a href="2-jm.html#SP2">&#167;2</a><br/>Extension Services - <a href="5-es.html#SP2_2">&#167;2.2</a>, <a href="5-es.html#SP2_2_3">&#167;2.2.3</a>, <a href="5-es.html#SP2_2_3_2">&#167;2.2.3.2</a>, <a href="5-es.html#SP2_3">&#167;2.3</a><br/>Kit Services - <a href="5-ks.html#SP4_1">&#167;4.1</a>, <a href="5-ks.html#SP4_4">&#167;4.4</a>, <a href="5-ks.html#SP4_4_1">&#167;4.4.1</a>, <a href="5-ks.html#SP4_4_1_1">&#167;4.4.1.1</a>, <a href="5-ks.html#SP4_4_2">&#167;4.4.2</a><br/>Project Services - <a href="5-ps2.html#SP28">&#167;28</a><br/>Source Text - <a href="6-st.html#SP2">&#167;2</a>, <a href="6-st.html#SP3">&#167;3</a>, <a href="6-st.html#SP6">&#167;6</a>, <a href="6-st.html#SP14">&#167;14</a><br/>Headings - <a href="6-hdn.html#SP12_1">&#167;12.1</a>, <a href="6-hdn.html#SP12_2">&#167;12.2</a>, <a href="6-hdn.html#SP22_1">&#167;22.1</a>, <a href="6-hdn.html#SP23_2">&#167;23.2</a>, <a href="6-hdn.html#SP22_2">&#167;22.2</a>, <a href="6-hdn.html#SP22_3">&#167;22.3</a><br/>The Bibliographic Sentence - <a href="6-tbs.html#SP1">&#167;1</a><br/>Inclusions - <a href="6-inc.html#SP2_1">&#167;2.1</a>, <a href="6-inc.html#SP5_1_1">&#167;5.1.1</a>, <a href="6-inc.html#SP5_1_2">&#167;5.1.2</a>, <a href="6-inc.html#SP6_1">&#167;6.1</a>, <a href="6-inc.html#SP8_1">&#167;8.1</a>, <a href="6-inc.html#SP10">&#167;10</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inbuild_copy</span><span class="plain-syntax"> *</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="reserved-syntax">copy_error</span><span class="plain-syntax"> *</span><span class="identifier-syntax">CE</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">C</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">"no copy to attach to"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-ce.html#SP4" class="function-link"><span class="function-syntax">CopyErrors::supply_attached_copy</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">CE</span><span class="plain-syntax">, </span><span class="identifier-syntax">C</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">CE</span><span class="plain-syntax">, </span><span class="reserved-syntax">copy_error</span><span class="plain-syntax">, </span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">errors_reading_source_text</span><span class="plain-syntax">);</span>

View file

@ -95,7 +95,7 @@ might work with all VMs, while version 8 required a 32-bit architecture.
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>The structure inbuild_edition is accessed in 1/ic, 2/cps, 2/rqr, 2/nst, 2/jm, 3/bg, 3/ib, 3/is2, 4/em, 4/km, 4/lm, 4/pm, 4/pbm, 4/pfm, 4/tm, 5/es, 5/ks, 5/ls, 5/ps, 5/ps2, 5/ts, 6/st, 6/hdn, 6/tbs, 6/inc, 6/vmg, 7/dct, 7/cns, 7/ip, 7/ip2 and here.</li></ul>
<ul class="endnotetexts"><li>The structure inbuild_edition is accessed in 1/ic, 2/cps, 2/ce, 2/rqr, 2/nst, 2/jm, 3/bg, 3/ib, 3/is2, 4/em, 4/km, 4/lm, 4/pm, 4/pbm, 4/pfm, 4/tm, 5/es, 5/ks, 5/ls, 5/ps, 5/ps2, 5/ts, 6/st, 6/hdn, 6/tbs, 6/inc, 6/vmg, 7/dct, 7/cns, 7/ip, 7/ip2 and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b>When a copy is to be duplicated into a nest <span class="extract"><span class="extract-syntax">N</span></span>, we need to work out where
to put it. For example, version 2.1 of the extension Marbles by Steve Hogarth
would go into <span class="extract"><span class="extract-syntax">N/Extensions/Steve Hogarth/Marbles-v2_1.i7x</span></span>. The following

View file

@ -96,7 +96,7 @@ the instance <span class="extract"><span class="extract-syntax">kit_genre</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">G</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">genre_name</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>The structure inbuild_genre is accessed in 2/rqr, 3/bg, 3/bs2 and here.</li></ul>
<ul class="endnotetexts"><li>The structure inbuild_genre is accessed in 2/ce, 2/rqr, 3/bg, 3/bs2 and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b>Some genres of work, such as kits and extensions, can be stored in nests;
others, such as Inform projects, cannot. Whether a copy can be stored in a
nest depends only on its genre.

View file

@ -71,21 +71,22 @@ identifying the copy which it purports to identify.
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">JSONMetadata::read_metadata_file</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">JSONMetadata::read_metadata_file</span></span>:<br/>Kit Services - <a href="5-ks.html#SP4">&#167;4</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inbuild_copy</span><span class="plain-syntax"> *</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-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="identifier-syntax">JSON_requirement</span><span class="plain-syntax"> *</span><span class="identifier-syntax">req</span><span class="plain-syntax"> = </span><a href="2-jm.html#SP2" class="function-link"><span class="function-syntax">JSONMetadata::requirements</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_requirement</span><span class="plain-syntax"> *</span><span class="identifier-syntax">req</span><span class="plain-syntax"> = </span><a href="2-jm.html#SP3" class="function-link"><span class="function-syntax">JSONMetadata::requirements</span></a><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">contents</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TextFiles::read</span><span class="plain-syntax">(</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="string-syntax">"unable to read file of JSON metadata"</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> &amp;</span><a href="2-jm.html#SP1" class="function-link"><span class="function-syntax">JSONMetadata::read_metadata_file_helper</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">contents</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">text_file_position</span><span class="plain-syntax"> </span><span class="identifier-syntax">tfp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TextFiles::at</span><span class="plain-syntax">(</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">value</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::decode</span><span class="plain-syntax">(</span><span class="identifier-syntax">contents</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">tfp</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">value</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">value</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">JSON_type</span><span class="plain-syntax"> == </span><span class="identifier-syntax">ERROR_JSONTYPE</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">obj</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::decode</span><span class="plain-syntax">(</span><span class="identifier-syntax">contents</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">tfp</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">obj</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">obj</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">JSON_type</span><span class="plain-syntax"> == </span><span class="identifier-syntax">ERROR_JSONTYPE</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-jm.html#SP1_1" class="named-paragraph-link"><span class="named-paragraph">Report a syntax error in JSON</span><span class="named-paragraph-number">1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-jm.html#SP1_2" class="named-paragraph-link"><span class="named-paragraph">Validate the JSON read in</span><span class="named-paragraph-number">1.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">contents</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">metadata_record</span><span class="plain-syntax"> = </span><span class="identifier-syntax">value</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">metadata_record</span><span class="plain-syntax"> = </span><span class="identifier-syntax">obj</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-jm.html#SP1_3" class="named-paragraph-link"><span class="named-paragraph">Examine the "is" member of the metadata object</span><span class="named-paragraph-number">1.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-jm.html#SP1_4" class="named-paragraph-link"><span class="named-paragraph">Police the "needs"</span><span class="named-paragraph-number">1.4</span></a></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">JSONMetadata::read_metadata_file_helper</span><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">,</span>
@ -99,8 +100,8 @@ identifying the copy which it purports to identify.
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">err</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">err</span><span class="plain-syntax">, </span><span class="string-syntax">"the metadata contains a syntax error: '%S'"</span><span class="plain-syntax">, </span><span class="identifier-syntax">value</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_error</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-cps.html#SP5" class="function-link"><span class="function-syntax">Copies::attach_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><a href="2-ce.html#SP2" class="function-link"><span class="function-syntax">CopyErrors::new_T</span></a><span class="plain-syntax">(</span><span class="constant-syntax">KIT_MISWORDED_CE</span><span class="plain-syntax">, -1, </span><span class="identifier-syntax">err</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">err</span><span class="plain-syntax">, </span><span class="string-syntax">"the metadata contains a syntax error: '%S'"</span><span class="plain-syntax">, </span><span class="identifier-syntax">obj</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_error</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-cps.html#SP5" class="function-link"><span class="function-syntax">Copies::attach_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><a href="2-ce.html#SP2" class="function-link"><span class="function-syntax">CopyErrors::new_T</span></a><span class="plain-syntax">(</span><span class="constant-syntax">METADATA_MALFORMED_CE</span><span class="plain-syntax">, -1, </span><span class="identifier-syntax">err</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">err</span><span class="plain-syntax">)</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-jm.html#SP1">&#167;1</a>.</li></ul>
@ -109,12 +110,12 @@ identifying the copy which it purports to identify.
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">validation_errors</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEW_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</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">JSON::validate</span><span class="plain-syntax">(</span><span class="identifier-syntax">value</span><span class="plain-syntax">, </span><span class="identifier-syntax">req</span><span class="plain-syntax">, </span><span class="identifier-syntax">validation_errors</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</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">JSON::validate</span><span class="plain-syntax">(</span><span class="identifier-syntax">obj</span><span class="plain-syntax">, </span><span class="identifier-syntax">req</span><span class="plain-syntax">, </span><span class="identifier-syntax">validation_errors</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">err</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">err</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax">, </span><span class="identifier-syntax">validation_errors</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">msg</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">msg</span><span class="plain-syntax">, </span><span class="string-syntax">"the metadata did not validate: '%S'"</span><span class="plain-syntax">, </span><span class="identifier-syntax">err</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-cps.html#SP5" class="function-link"><span class="function-syntax">Copies::attach_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><a href="2-ce.html#SP2" class="function-link"><span class="function-syntax">CopyErrors::new_T</span></a><span class="plain-syntax">(</span><span class="constant-syntax">KIT_MISWORDED_CE</span><span class="plain-syntax">, -1, </span><span class="identifier-syntax">msg</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><a href="2-cps.html#SP5" class="function-link"><span class="function-syntax">Copies::attach_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><a href="2-ce.html#SP2" class="function-link"><span class="function-syntax">CopyErrors::new_T</span></a><span class="plain-syntax">(</span><span class="constant-syntax">METADATA_MALFORMED_CE</span><span class="plain-syntax">, -1, </span><span class="identifier-syntax">msg</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">msg</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
@ -125,7 +126,7 @@ identifying the copy which it purports to identify.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">is</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">metadata_record</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"is"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">is</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">obj</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"is"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">type</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">is</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"type"</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">type</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="2-jm.html#SP1_3_1" class="named-paragraph-link"><span class="named-paragraph">Make sure the type is correct</span><span class="named-paragraph-number">1.3.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">title</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">is</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"title"</span><span class="plain-syntax">);</span>
@ -155,9 +156,23 @@ to say that <span class="extract"><span class="extract-syntax">is.type</span></s
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">msg</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">msg</span><span class="plain-syntax">, </span><span class="string-syntax">"the metadata misidentifies the type as '%S', but it should be '%S'"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">type_text</span><span class="plain-syntax">, </span><span class="identifier-syntax">required_text</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-cps.html#SP5" class="function-link"><span class="function-syntax">Copies::attach_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><a href="2-ce.html#SP2" class="function-link"><span class="function-syntax">CopyErrors::new_T</span></a><span class="plain-syntax">(</span><span class="constant-syntax">KIT_MISWORDED_CE</span><span class="plain-syntax">, -1, </span><span class="identifier-syntax">msg</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><a href="2-cps.html#SP5" class="function-link"><span class="function-syntax">Copies::attach_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><a href="2-ce.html#SP2" class="function-link"><span class="function-syntax">CopyErrors::new_T</span></a><span class="plain-syntax">(</span><span class="constant-syntax">METADATA_MALFORMED_CE</span><span class="plain-syntax">, -1, </span><span class="identifier-syntax">msg</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">msg</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kit_details</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">obj</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"kit-details"</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">kit_details</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Str::ne</span><span class="plain-syntax">(</span><span class="identifier-syntax">type_text</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"kit"</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">err</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">err</span><span class="plain-syntax">, </span><span class="string-syntax">"the metadata contains kit-details but is not for a kit"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-cps.html#SP5" class="function-link"><span class="function-syntax">Copies::attach_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><a href="2-ce.html#SP2" class="function-link"><span class="function-syntax">CopyErrors::new_T</span></a><span class="plain-syntax">(</span><span class="constant-syntax">METADATA_MALFORMED_CE</span><span class="plain-syntax">, -1, </span><span class="identifier-syntax">err</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">err</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">extension_details</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">obj</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"extension-details"</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">extension_details</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Str::ne</span><span class="plain-syntax">(</span><span class="identifier-syntax">type_text</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"extension"</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">err</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">err</span><span class="plain-syntax">, </span><span class="string-syntax">"the metadata contains extension-details but is not for an extension"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-cps.html#SP5" class="function-link"><span class="function-syntax">Copies::attach_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><a href="2-ce.html#SP2" class="function-link"><span class="function-syntax">CopyErrors::new_T</span></a><span class="plain-syntax">(</span><span class="constant-syntax">METADATA_MALFORMED_CE</span><span class="plain-syntax">, -1, </span><span class="identifier-syntax">err</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">err</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-jm.html#SP1_3">&#167;1.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_3_2" class="paragraph-anchor"></a><b>&#167;1.3.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Make sure the title is correct</span><span class="named-paragraph-number">1.3.2</span></span><span class="comment-syntax"> =</span>
@ -168,7 +183,7 @@ to say that <span class="extract"><span class="extract-syntax">is.type</span></s
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">err</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">err</span><span class="plain-syntax">, </span><span class="string-syntax">"the metadata says the title is '%S' when it should be '%S'"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">title</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_string</span><span class="plain-syntax">, </span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">edition</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">work</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">title</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-cps.html#SP5" class="function-link"><span class="function-syntax">Copies::attach_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><a href="2-ce.html#SP2" class="function-link"><span class="function-syntax">CopyErrors::new_T</span></a><span class="plain-syntax">(</span><span class="constant-syntax">KIT_MISWORDED_CE</span><span class="plain-syntax">, -1, </span><span class="identifier-syntax">err</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><a href="2-cps.html#SP5" class="function-link"><span class="function-syntax">Copies::attach_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><a href="2-ce.html#SP2" class="function-link"><span class="function-syntax">CopyErrors::new_T</span></a><span class="plain-syntax">(</span><span class="constant-syntax">METADATA_MALFORMED_CE</span><span class="plain-syntax">, -1, </span><span class="identifier-syntax">err</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">err</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> }</span>
</pre>
@ -181,7 +196,7 @@ to say that <span class="extract"><span class="extract-syntax">is.type</span></s
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">err</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">err</span><span class="plain-syntax">, </span><span class="string-syntax">"the metadata says the author is '%S' when it should be '%S'"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">author</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_string</span><span class="plain-syntax">, </span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">edition</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">work</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">author_name</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-cps.html#SP5" class="function-link"><span class="function-syntax">Copies::attach_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><a href="2-ce.html#SP2" class="function-link"><span class="function-syntax">CopyErrors::new_T</span></a><span class="plain-syntax">(</span><span class="constant-syntax">KIT_MISWORDED_CE</span><span class="plain-syntax">, -1, </span><span class="identifier-syntax">err</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><a href="2-cps.html#SP5" class="function-link"><span class="function-syntax">Copies::attach_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><a href="2-ce.html#SP2" class="function-link"><span class="function-syntax">CopyErrors::new_T</span></a><span class="plain-syntax">(</span><span class="constant-syntax">METADATA_MALFORMED_CE</span><span class="plain-syntax">, -1, </span><span class="identifier-syntax">err</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">err</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> }</span>
</pre>
@ -198,7 +213,7 @@ a version number.
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">VersionNumbers::is_null</span><span class="plain-syntax">(</span><span class="identifier-syntax">V</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">err</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">err</span><span class="plain-syntax">, </span><span class="string-syntax">"cannot read version number '%S'"</span><span class="plain-syntax">, </span><span class="identifier-syntax">version</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_string</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-cps.html#SP5" class="function-link"><span class="function-syntax">Copies::attach_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><a href="2-ce.html#SP2" class="function-link"><span class="function-syntax">CopyErrors::new_T</span></a><span class="plain-syntax">(</span><span class="constant-syntax">KIT_MISWORDED_CE</span><span class="plain-syntax">, -1, </span><span class="identifier-syntax">err</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><a href="2-cps.html#SP5" class="function-link"><span class="function-syntax">Copies::attach_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><a href="2-ce.html#SP2" class="function-link"><span class="function-syntax">CopyErrors::new_T</span></a><span class="plain-syntax">(</span><span class="constant-syntax">METADATA_MALFORMED_CE</span><span class="plain-syntax">, -1, </span><span class="identifier-syntax">err</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">err</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">edition</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">version</span><span class="plain-syntax"> = </span><span class="identifier-syntax">VersionNumbers::from_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">version</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_string</span><span class="plain-syntax">);</span>
@ -211,11 +226,72 @@ a version number.
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">err</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">err</span><span class="plain-syntax">, </span><span class="string-syntax">"the metadata should specify an exact version, not a range"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-cps.html#SP5" class="function-link"><span class="function-syntax">Copies::attach_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><a href="2-ce.html#SP2" class="function-link"><span class="function-syntax">CopyErrors::new_T</span></a><span class="plain-syntax">(</span><span class="constant-syntax">KIT_MISWORDED_CE</span><span class="plain-syntax">, -1, </span><span class="identifier-syntax">err</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><a href="2-cps.html#SP5" class="function-link"><span class="function-syntax">Copies::attach_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><a href="2-ce.html#SP2" class="function-link"><span class="function-syntax">CopyErrors::new_T</span></a><span class="plain-syntax">(</span><span class="constant-syntax">METADATA_MALFORMED_CE</span><span class="plain-syntax">, -1, </span><span class="identifier-syntax">err</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">err</span><span class="plain-syntax">)</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-jm.html#SP1_3">&#167;1.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b>The following returns the schema needed for (b); we will load it in from a file
<p class="commentary firstcommentary"><a id="SP1_4" class="paragraph-anchor"></a><b>&#167;1.4. </b>It would have been possible to write the schema in a way which would exclude
the possibilities blocked here, but only by making it cumbersome. Besides,
checking here results in more explicit error messages.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Police the "needs"</span><span class="named-paragraph-number">1.4</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">needs</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">obj</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"needs"</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">needs</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">E</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">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">needs</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_list</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">if_clause</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"if"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">unless_clause</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"unless"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">needs_clause</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"needs"</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">if_clause</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">unless_clause</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">err</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">err</span><span class="plain-syntax">, </span><span class="string-syntax">"cannot give both 'if' and 'unless' in same requirement"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-cps.html#SP5" class="function-link"><span class="function-syntax">Copies::attach_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><a href="2-ce.html#SP2" class="function-link"><span class="function-syntax">CopyErrors::new_T</span></a><span class="plain-syntax">(</span><span class="constant-syntax">METADATA_MALFORMED_CE</span><span class="plain-syntax">, -1, </span><span class="identifier-syntax">err</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">err</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="2-jm.html#SP2" class="function-link"><span class="function-syntax">JSONMetadata::not_both</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">if_clause</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"'if' clause of a requirement"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-jm.html#SP2" class="function-link"><span class="function-syntax">JSONMetadata::not_both</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">unless_clause</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"'unless' clause of a requirement"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-jm.html#SP2" class="function-link"><span class="function-syntax">JSONMetadata::not_both</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">needs_clause</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"'needs' clause of a requirement"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-jm.html#SP1">&#167;1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b>All very pedantic, but:
</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">JSONMetadata::not_both</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">JSONMetadata::not_both</span></span>:<br/><a href="2-jm.html#SP1_4">&#167;1.4</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inbuild_copy</span><span class="plain-syntax"> *</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">clause</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">where</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">clause</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">version</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">clause</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"version"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">version_range</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">clause</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"version-range"</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">version</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">version_range</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">err</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">err</span><span class="plain-syntax">, </span><span class="string-syntax">"%S specifies both a version and a version-range"</span><span class="plain-syntax">, </span><span class="identifier-syntax">where</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-cps.html#SP5" class="function-link"><span class="function-syntax">Copies::attach_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><a href="2-ce.html#SP2" class="function-link"><span class="function-syntax">CopyErrors::new_T</span></a><span class="plain-syntax">(</span><span class="constant-syntax">METADATA_MALFORMED_CE</span><span class="plain-syntax">, -1, </span><span class="identifier-syntax">err</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">err</span><span class="plain-syntax">)</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">version</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">semantic_version_number</span><span class="plain-syntax"> </span><span class="identifier-syntax">V</span><span class="plain-syntax"> = </span><span class="identifier-syntax">VersionNumbers::from_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">version</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_string</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">VersionNumbers::is_null</span><span class="plain-syntax">(</span><span class="identifier-syntax">V</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">err</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">err</span><span class="plain-syntax">, </span><span class="string-syntax">"cannot read version '%S' in %S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">version</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_string</span><span class="plain-syntax">, </span><span class="identifier-syntax">where</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-cps.html#SP5" class="function-link"><span class="function-syntax">Copies::attach_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><a href="2-ce.html#SP2" class="function-link"><span class="function-syntax">CopyErrors::new_T</span></a><span class="plain-syntax">(</span><span class="constant-syntax">METADATA_MALFORMED_CE</span><span class="plain-syntax">, -1, </span><span class="identifier-syntax">err</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">err</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">version_range</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">err</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">err</span><span class="plain-syntax">, </span><span class="string-syntax">"'version-range' is not yet supported in %S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">where</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-cps.html#SP5" class="function-link"><span class="function-syntax">Copies::attach_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><a href="2-ce.html#SP2" class="function-link"><span class="function-syntax">CopyErrors::new_T</span></a><span class="plain-syntax">(</span><span class="constant-syntax">METADATA_MALFORMED_CE</span><span class="plain-syntax">, -1, </span><span class="identifier-syntax">err</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">err</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. </b>The following returns the schema needed for (b); we will load it in from a file
in the Inform/Inbuild installation, but will then cache the result so that it
loads only once.
</p>
@ -223,7 +299,7 @@ loads only once.
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">dictionary</span><span class="plain-syntax"> *</span><span class="identifier-syntax">JSON_resource_metadata_requirements</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="identifier-syntax">JSON_requirement</span><span class="plain-syntax"> *</span><span class="function-syntax">JSONMetadata::requirements</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">JSONMetadata::requirements</span></span>:<br/><a href="2-jm.html#SP1">&#167;1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="identifier-syntax">JSON_requirement</span><span class="plain-syntax"> *</span><span class="function-syntax">JSONMetadata::requirements</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">JSONMetadata::requirements</span></span>:<br/><a href="2-jm.html#SP1">&#167;1</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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">JSON_resource_metadata_requirements</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InstalledFiles::filename</span><span class="plain-syntax">(</span><span class="identifier-syntax">JSON_REQUIREMENTS_IRES</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_resource_metadata_requirements</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::read_requirements_file</span><span class="plain-syntax">(</span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">);</span>

View file

@ -74,19 +74,19 @@ we can give a semantic version number range:
<span class="plain-syntax"> </span><span class="identifier-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">inbuild_requirement</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure inbuild_requirement is accessed in 1/ic, 2/edt, 2/cps, 2/jm, 3/bg, 3/ib, 3/is2, 4/em, 4/km, 4/lm, 4/pm, 4/pbm, 4/pfm, 4/tm, 5/es, 5/ks, 5/ls, 5/ps2, 6/st, 6/hdn, 6/tbs, 6/inc, 7/dct, 7/cns, 7/ip, 7/ip2 and here.</li></ul>
<ul class="endnotetexts"><li>The structure inbuild_requirement is accessed in 1/ic, 2/edt, 2/cps, 2/ce, 2/jm, 3/bg, 3/ib, 3/is2, 4/em, 4/km, 4/lm, 4/pm, 4/pbm, 4/pfm, 4/tm, 5/es, 5/ks, 5/ls, 5/ps2, 6/st, 6/hdn, 6/tbs, 6/inc, 7/dct, 7/cns, 7/ip, 7/ip2 and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b>Here are some creators:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">inbuild_requirement</span><span class="plain-syntax"> *</span><span class="function-syntax">Requirements::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">Requirements::new</span></span>:<br/>Kit Services - <a href="5-ks.html#SP4_1_3">&#167;4.1.3</a><br/>Inclusions - <a href="6-inc.html#SP4_1">&#167;4.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inbuild_work</span><span class="plain-syntax"> *</span><span class="identifier-syntax">work</span><span class="plain-syntax">, </span><span class="identifier-syntax">semver_range</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">inbuild_requirement</span><span class="plain-syntax"> *</span><span class="function-syntax">Requirements::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">Requirements::new</span></span>:<br/>Kit Services - <a href="5-ks.html#SP4_4_1_1">&#167;4.4.1.1</a><br/>Inclusions - <a href="6-inc.html#SP4_1">&#167;4.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inbuild_work</span><span class="plain-syntax"> *</span><span class="identifier-syntax">work</span><span class="plain-syntax">, </span><span class="identifier-syntax">semver_range</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">inbuild_requirement</span><span class="plain-syntax"> *</span><span class="identifier-syntax">req</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">inbuild_requirement</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">work</span><span class="plain-syntax"> = </span><span class="identifier-syntax">work</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">req</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">version_range</span><span class="plain-syntax"> = </span><span class="identifier-syntax">R</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">req</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">inbuild_requirement</span><span class="plain-syntax"> *</span><span class="function-syntax">Requirements::any_version_of</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">Requirements::any_version_of</span></span>:<br/>Inter Skill - <a href="3-is.html#SP3">&#167;3</a>, <a href="3-is.html#SP4">&#167;4</a><br/>Kit Services - <a href="5-ks.html#SP4_1_4">&#167;4.1.4</a>, <a href="5-ks.html#SP7">&#167;7</a><br/>Language Services - <a href="5-ls.html#SP10">&#167;10</a><br/>Inclusions - <a href="6-inc.html#SP5_1_2">&#167;5.1.2</a><br/>Dictionary - <a href="7-dct.html#SP9">&#167;9</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inbuild_work</span><span class="plain-syntax"> *</span><span class="identifier-syntax">work</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">inbuild_requirement</span><span class="plain-syntax"> *</span><span class="function-syntax">Requirements::any_version_of</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">Requirements::any_version_of</span></span>:<br/>Inter Skill - <a href="3-is.html#SP3">&#167;3</a>, <a href="3-is.html#SP4">&#167;4</a><br/>Kit Services - <a href="5-ks.html#SP4_4_1_2">&#167;4.4.1.2</a>, <a href="5-ks.html#SP7">&#167;7</a><br/>Language Services - <a href="5-ls.html#SP10">&#167;10</a><br/>Inclusions - <a href="6-inc.html#SP5_1_2">&#167;5.1.2</a><br/>Dictionary - <a href="7-dct.html#SP9">&#167;9</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inbuild_work</span><span class="plain-syntax"> *</span><span class="identifier-syntax">work</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-rqr.html#SP2" class="function-link"><span class="function-syntax">Requirements::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">work</span><span class="plain-syntax">, </span><span class="identifier-syntax">VersionNumberRanges::any_range</span><span class="plain-syntax">());</span>
<span class="plain-syntax">}</span>

View file

@ -86,13 +86,13 @@ combination of the textual names and the hash code:
<span class="plain-syntax"> </span><span class="identifier-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">inbuild_work</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure inbuild_work is accessed in 1/ic, 2/edt, 2/cps, 2/rqr, 2/jm, 3/bg, 3/ib, 3/is2, 4/em, 4/km, 4/lm, 4/pm, 4/pbm, 4/pfm, 4/tm, 5/es, 5/ks, 5/ls, 5/ps2, 6/tbs, 6/inc, 7/tm, 7/dct, 7/ip and here.</li></ul>
<ul class="endnotetexts"><li>The structure inbuild_work is accessed in 1/ic, 2/edt, 2/cps, 2/ce, 2/rqr, 2/jm, 3/bg, 3/ib, 3/is2, 4/em, 4/km, 4/lm, 4/pm, 4/pbm, 4/pfm, 4/tm, 5/es, 5/ks, 5/ls, 5/ps2, 6/tbs, 6/inc, 7/tm, 7/dct, 7/ip and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b>Each work structure is written only once, and its title and author name are
not subsequently altered.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">inbuild_work</span><span class="plain-syntax"> *</span><span class="function-syntax">Works::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">Works::new</span></span>:<br/><a href="2-wrk.html#SP11">&#167;11</a><br/>Requirements - <a href="2-rqr.html#SP2">&#167;2</a><br/>Inter Skill - <a href="3-is.html#SP3">&#167;3</a>, <a href="3-is.html#SP4">&#167;4</a><br/>Extension Manager - <a href="4-em.html#SP4">&#167;4</a><br/>Language Manager - <a href="4-lm.html#SP3">&#167;3</a><br/>Project Bundle Manager - <a href="4-pbm.html#SP2">&#167;2</a><br/>Project File Manager - <a href="4-pfm.html#SP2">&#167;2</a><br/>Template Manager - <a href="4-tm.html#SP3">&#167;3</a><br/>Kit Services - <a href="5-ks.html#SP4_1_3">&#167;4.1.3</a>, <a href="5-ks.html#SP4_1_4">&#167;4.1.4</a>, <a href="5-ks.html#SP7">&#167;7</a><br/>Language Services - <a href="5-ls.html#SP10">&#167;10</a><br/>Headings - <a href="6-hdn.html#SP12_3">&#167;12.3</a><br/>Inclusions - <a href="6-inc.html#SP4_1">&#167;4.1</a><br/>Dictionary - <a href="7-dct.html#SP9">&#167;9</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inbuild_genre</span><span class="plain-syntax"> *</span><span class="identifier-syntax">genre</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ti</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">an</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">inbuild_work</span><span class="plain-syntax"> *</span><span class="function-syntax">Works::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">Works::new</span></span>:<br/><a href="2-wrk.html#SP11">&#167;11</a><br/>Requirements - <a href="2-rqr.html#SP2">&#167;2</a><br/>Inter Skill - <a href="3-is.html#SP3">&#167;3</a>, <a href="3-is.html#SP4">&#167;4</a><br/>Extension Manager - <a href="4-em.html#SP4">&#167;4</a><br/>Language Manager - <a href="4-lm.html#SP3">&#167;3</a><br/>Project Bundle Manager - <a href="4-pbm.html#SP2">&#167;2</a><br/>Project File Manager - <a href="4-pfm.html#SP2">&#167;2</a><br/>Template Manager - <a href="4-tm.html#SP3">&#167;3</a><br/>Kit Services - <a href="5-ks.html#SP4_4_1">&#167;4.4.1</a>, <a href="5-ks.html#SP7">&#167;7</a><br/>Language Services - <a href="5-ls.html#SP10">&#167;10</a><br/>Headings - <a href="6-hdn.html#SP12_3">&#167;12.3</a><br/>Inclusions - <a href="6-inc.html#SP4_1">&#167;4.1</a><br/>Dictionary - <a href="7-dct.html#SP9">&#167;9</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inbuild_genre</span><span class="plain-syntax"> *</span><span class="identifier-syntax">genre</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ti</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">an</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-wrk.html#SP3" class="function-link"><span class="function-syntax">Works::new_inner</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">genre</span><span class="plain-syntax">, </span><span class="identifier-syntax">ti</span><span class="plain-syntax">, </span><span class="identifier-syntax">an</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">inbuild_work</span><span class="plain-syntax"> *</span><span class="function-syntax">Works::new_raw</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">Works::new_raw</span></span>:<br/>Kit Manager - <a href="4-km.html#SP3">&#167;3</a><br/>Pipeline Manager - <a href="4-pm.html#SP4">&#167;4</a><br/>Extension Services - <a href="5-es.html#SP2_3">&#167;2.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inbuild_genre</span><span class="plain-syntax"> *</span><span class="identifier-syntax">genre</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ti</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">an</span><span class="plain-syntax">) {</span>

View file

@ -152,104 +152,24 @@ interactive fiction features of the compiler, but BasicInformKit does not.
<span class="plain-syntax"> </span><span class="identifier-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Filenames::in</span><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">location_if_path</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"kit_metadata.json"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-jm.html#SP1" class="function-link"><span class="function-syntax">JSONMetadata::read_metadata_file</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">metadata_record</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="5-ks.html#SP4_1" class="named-paragraph-link"><span class="named-paragraph">Extract what we need</span><span class="named-paragraph-number">4.1</span></a></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">C</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">metadata_record</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">compatibility</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">metadata_record</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"compatibility"</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">compatibility</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="5-ks.html#SP4_1" class="named-paragraph-link"><span class="named-paragraph">Extract compatibility</span><span class="named-paragraph-number">4.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-ks.html#SP4_2" class="named-paragraph-link"><span class="named-paragraph">Extract activations</span><span class="named-paragraph-number">4.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kit_details</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">metadata_record</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"kit-details"</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">kit_details</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="5-ks.html#SP4_3" class="named-paragraph-link"><span class="named-paragraph">Extract the kit details</span><span class="named-paragraph-number">4.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">needs</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">metadata_record</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"needs"</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">needs</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">E</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">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">needs</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_list</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-ks.html#SP4_4" class="named-paragraph-link"><span class="named-paragraph">Extract this possibly conditional requirement</span><span class="named-paragraph-number">4.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP4_1" class="paragraph-anchor"></a><b>&#167;4.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Extract what we need</span><span class="named-paragraph-number">4.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">compatibility</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">metadata_record</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"compatibility"</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">compatibility</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="5-ks.html#SP4_1_1" class="named-paragraph-link"><span class="named-paragraph">Add compatibility</span><span class="named-paragraph-number">4.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">activate</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">metadata_record</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"activates"</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">activate</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">E</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">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">activate</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_list</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="5-ks.html#SP6" class="function-link"><span class="function-syntax">Kits::activation</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">E</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_string</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">deactivate</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">metadata_record</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"deactivates"</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">deactivate</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">E</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">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">deactivate</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_list</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="5-ks.html#SP6" class="function-link"><span class="function-syntax">Kits::activation</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">E</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_string</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kit_details</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">metadata_record</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"kit-details"</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">kit_details</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">priority</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">kit_details</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"has-priority"</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">priority</span><span class="plain-syntax">) </span><span class="identifier-syntax">K</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">priority</span><span class="plain-syntax"> = </span><span class="identifier-syntax">priority</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_integer</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">defines_Main</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">kit_details</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"defines-Main"</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">defines_Main</span><span class="plain-syntax">) </span><span class="identifier-syntax">K</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">defines_Main</span><span class="plain-syntax"> = </span><span class="identifier-syntax">defines_Main</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_boolean</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">is_language_kit</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">kit_details</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"is-language-kit"</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">is_language_kit</span><span class="plain-syntax">) </span><span class="identifier-syntax">K</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">supports_nl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">is_language_kit</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_boolean</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">index</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">kit_details</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"indexes-with-structure"</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">index</span><span class="plain-syntax">) </span><span class="identifier-syntax">K</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">index_structure</span><span class="plain-syntax"> = </span><span class="identifier-syntax">index</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_string</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kinds</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">kit_details</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"provides-kinds"</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">kinds</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">E</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">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">kinds</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_list</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">E</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_string</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">kind_definitions</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">dependencies</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">metadata_record</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"needs"</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">dependencies</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">E</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">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">dependencies</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_list</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">loaded</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">if_clause</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"if"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">unless_clause</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"unless"</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">if_clause</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">unless_clause</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">err</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">err</span><span class="plain-syntax">, </span><span class="string-syntax">"cannot give both 'if' and 'unless' in same requirement"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-cps.html#SP5" class="function-link"><span class="function-syntax">Copies::attach_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><a href="2-ce.html#SP2" class="function-link"><span class="function-syntax">CopyErrors::new_T</span></a><span class="plain-syntax">(</span><span class="constant-syntax">KIT_MISWORDED_CE</span><span class="plain-syntax">, -1, </span><span class="identifier-syntax">err</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">err</span><span class="plain-syntax">)</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">unless_clause</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">if_clause</span><span class="plain-syntax"> = </span><span class="identifier-syntax">unless_clause</span><span class="plain-syntax">; </span><span class="identifier-syntax">loaded</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">then_clause</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"need"</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">then_clause</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">type</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">then_clause</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"type"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">title</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">then_clause</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"title"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">author</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">then_clause</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"author"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">then_version</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">then_clause</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"version"</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">Str::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">type</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_string</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"extension"</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">if_clause</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">err</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">err</span><span class="plain-syntax">, </span><span class="string-syntax">"a kit can only have an extension as a dependency unconditionally"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-cps.html#SP5" class="function-link"><span class="function-syntax">Copies::attach_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><a href="2-ce.html#SP2" class="function-link"><span class="function-syntax">CopyErrors::new_T</span></a><span class="plain-syntax">(</span><span class="constant-syntax">KIT_MISWORDED_CE</span><span class="plain-syntax">, -1, </span><span class="identifier-syntax">err</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">err</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">extension_title</span><span class="plain-syntax"> = </span><span class="identifier-syntax">title</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_string</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">extension_author</span><span class="plain-syntax"> = </span><span class="identifier-syntax">author</span><span class="plain-syntax">?(</span><span class="identifier-syntax">author</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_string</span><span class="plain-syntax">):</span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">then_version</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="5-ks.html#SP4_1_3" class="named-paragraph-link"><span class="named-paragraph">Add versioned extension</span><span class="named-paragraph-number">4.1.3</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-ks.html#SP4_1_4" class="named-paragraph-link"><span class="named-paragraph">Add unversioned extension</span><span class="named-paragraph-number">4.1.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">type</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_string</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"kit"</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">if_kit</span><span class="plain-syntax"> = </span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">edition</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">work</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">title</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">if_clause</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">if_type</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">if_clause</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"type"</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">Str::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">if_type</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_string</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"kit"</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</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">err</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">err</span><span class="plain-syntax">, </span><span class="string-syntax">"a kit dependency can only be conditional on other kits"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-cps.html#SP5" class="function-link"><span class="function-syntax">Copies::attach_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><a href="2-ce.html#SP2" class="function-link"><span class="function-syntax">CopyErrors::new_T</span></a><span class="plain-syntax">(</span><span class="constant-syntax">KIT_MISWORDED_CE</span><span class="plain-syntax">, -1, </span><span class="identifier-syntax">err</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">err</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">if_title</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">if_clause</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"title"</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">if_title</span><span class="plain-syntax">) </span><span class="identifier-syntax">if_kit</span><span class="plain-syntax"> = </span><span class="identifier-syntax">if_title</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_string</span><span class="plain-syntax">; </span><span class="comment-syntax"> a line for IF fans</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="5-ks.html#SP5" class="function-link"><span class="function-syntax">Kits::dependency</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">if_kit</span><span class="plain-syntax">, </span><span class="identifier-syntax">loaded</span><span class="plain-syntax">, </span><span class="identifier-syntax">title</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_string</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</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">err</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">err</span><span class="plain-syntax">, </span><span class="string-syntax">"a kit can only have extensions and kits as dependencies"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-cps.html#SP5" class="function-link"><span class="function-syntax">Copies::attach_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><a href="2-ce.html#SP2" class="function-link"><span class="function-syntax">CopyErrors::new_T</span></a><span class="plain-syntax">(</span><span class="constant-syntax">KIT_MISWORDED_CE</span><span class="plain-syntax">, -1, </span><span class="identifier-syntax">err</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">err</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-ks.html#SP4">&#167;4</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP4_1_1" class="paragraph-anchor"></a><b>&#167;4.1.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Add compatibility</span><span class="named-paragraph-number">4.1.1</span></span><span class="comment-syntax"> =</span>
<p class="commentary firstcommentary"><a id="SP4_1" class="paragraph-anchor"></a><b>&#167;4.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Extract compatibility</span><span class="named-paragraph-number">4.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
@ -258,29 +178,110 @@ interactive fiction features of the compiler, but BasicInformKit does not.
<span class="plain-syntax"> </span><span class="reserved-syntax">else</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">err</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">err</span><span class="plain-syntax">, </span><span class="string-syntax">"cannot read compatibility '%S'"</span><span class="plain-syntax">, </span><span class="identifier-syntax">compatibility</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_string</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-cps.html#SP5" class="function-link"><span class="function-syntax">Copies::attach_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><a href="2-ce.html#SP2" class="function-link"><span class="function-syntax">CopyErrors::new_T</span></a><span class="plain-syntax">(</span><span class="constant-syntax">KIT_MISWORDED_CE</span><span class="plain-syntax">, -1, </span><span class="identifier-syntax">err</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><a href="2-cps.html#SP5" class="function-link"><span class="function-syntax">Copies::attach_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><a href="2-ce.html#SP2" class="function-link"><span class="function-syntax">CopyErrors::new_T</span></a><span class="plain-syntax">(</span><span class="constant-syntax">METADATA_MALFORMED_CE</span><span class="plain-syntax">, -1, </span><span class="identifier-syntax">err</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">err</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-ks.html#SP4_1">&#167;4.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP4_1_2" class="paragraph-anchor"></a><b>&#167;4.1.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Add early source</span><span class="named-paragraph-number">4.1.2</span></span><span class="comment-syntax"> =</span>
<ul class="endnotetexts"><li>This code is used in <a href="5-ks.html#SP4">&#167;4</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP4_2" class="paragraph-anchor"></a><b>&#167;4.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Extract activations</span><span class="named-paragraph-number">4.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">K</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">early_source</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::duplicate</span><span class="plain-syntax">(</span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="identifier-syntax">exp</span><span class="plain-syntax">[0]);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">early_source</span><span class="plain-syntax">, </span><span class="string-syntax">"\n\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">activates</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">metadata_record</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"activates"</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">activates</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">E</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">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">activates</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_list</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="5-ks.html#SP6" class="function-link"><span class="function-syntax">Kits::activation</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">E</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_string</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">deactivates</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">metadata_record</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"deactivates"</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">deactivates</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">E</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">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">deactivates</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_list</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="5-ks.html#SP6" class="function-link"><span class="function-syntax">Kits::activation</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">E</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_string</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is never used.</li></ul>
<p class="commentary firstcommentary"><a id="SP4_1_3" class="paragraph-anchor"></a><b>&#167;4.1.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Add versioned extension</span><span class="named-paragraph-number">4.1.3</span></span><span class="comment-syntax"> =</span>
<ul class="endnotetexts"><li>This code is used in <a href="5-ks.html#SP4">&#167;4</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP4_3" class="paragraph-anchor"></a><b>&#167;4.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Extract the kit details</span><span class="named-paragraph-number">4.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">has_priority</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">kit_details</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"has-priority"</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">has_priority</span><span class="plain-syntax">) </span><span class="identifier-syntax">K</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">priority</span><span class="plain-syntax"> = </span><span class="identifier-syntax">has_priority</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_integer</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">defines_Main</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">kit_details</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"defines-Main"</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">defines_Main</span><span class="plain-syntax">) </span><span class="identifier-syntax">K</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">defines_Main</span><span class="plain-syntax"> = </span><span class="identifier-syntax">defines_Main</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_boolean</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">is_language_kit</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">kit_details</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"is-language-kit"</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">is_language_kit</span><span class="plain-syntax">) </span><span class="identifier-syntax">K</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">supports_nl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">is_language_kit</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_boolean</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">indexes_with_structure</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">kit_details</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"indexes-with-structure"</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">indexes_with_structure</span><span class="plain-syntax">) </span><span class="identifier-syntax">K</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">index_structure</span><span class="plain-syntax"> = </span><span class="identifier-syntax">indexes_with_structure</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_string</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">provides_kinds</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">kit_details</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"provides-kinds"</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">provides_kinds</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">E</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">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">provides_kinds</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_list</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">E</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_string</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">kind_definitions</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">inserts_source_text</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">kit_details</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"inserts-source-text"</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">inserts_source_text</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">K</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">early_source</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::duplicate</span><span class="plain-syntax">(</span><span class="identifier-syntax">inserts_source_text</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_string</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">K</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">early_source</span><span class="plain-syntax">, </span><span class="string-syntax">"\n\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-ks.html#SP4">&#167;4</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP4_4" class="paragraph-anchor"></a><b>&#167;4.4. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Extract this possibly conditional requirement</span><span class="named-paragraph-number">4.4</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">parity</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">if_clause</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"if"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">unless_clause</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"unless"</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">unless_clause</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">if_clause</span><span class="plain-syntax"> = </span><span class="identifier-syntax">unless_clause</span><span class="plain-syntax">; </span><span class="identifier-syntax">parity</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">need_clause</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"need"</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">need_clause</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">need_type</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">need_clause</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"type"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">need_title</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">need_clause</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"title"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">need_author</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">need_clause</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"author"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">need_version</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">need_clause</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"version"</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">Str::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">need_type</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_string</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"extension"</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-ks.html#SP4_4_1" class="named-paragraph-link"><span class="named-paragraph">Deal with an extension dependency</span><span class="named-paragraph-number">4.4.1</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">need_type</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_string</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"kit"</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-ks.html#SP4_4_2" class="named-paragraph-link"><span class="named-paragraph">Deal with a kit dependency</span><span class="named-paragraph-number">4.4.2</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</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">err</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">err</span><span class="plain-syntax">, </span><span class="string-syntax">"a kit can only have extensions and kits as dependencies"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-cps.html#SP5" class="function-link"><span class="function-syntax">Copies::attach_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><a href="2-ce.html#SP2" class="function-link"><span class="function-syntax">CopyErrors::new_T</span></a><span class="plain-syntax">(</span><span class="constant-syntax">METADATA_MALFORMED_CE</span><span class="plain-syntax">, -1, </span><span class="identifier-syntax">err</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">err</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-ks.html#SP4">&#167;4</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP4_4_1" class="paragraph-anchor"></a><b>&#167;4.4.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Deal with an extension dependency</span><span class="named-paragraph-number">4.4.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">if_clause</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">err</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">err</span><span class="plain-syntax">, </span><span class="string-syntax">"a kit can only have an extension as a dependency unconditionally"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-cps.html#SP5" class="function-link"><span class="function-syntax">Copies::attach_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><a href="2-ce.html#SP2" class="function-link"><span class="function-syntax">CopyErrors::new_T</span></a><span class="plain-syntax">(</span><span class="constant-syntax">METADATA_MALFORMED_CE</span><span class="plain-syntax">, -1, </span><span class="identifier-syntax">err</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">err</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">extension_title</span><span class="plain-syntax"> = </span><span class="identifier-syntax">need_title</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_string</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">extension_author</span><span class="plain-syntax"> = </span><span class="identifier-syntax">need_author</span><span class="plain-syntax">?(</span><span class="identifier-syntax">need_author</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_string</span><span class="plain-syntax">):</span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">inbuild_work</span><span class="plain-syntax"> *</span><span class="identifier-syntax">work</span><span class="plain-syntax"> = </span><a href="2-wrk.html#SP2" class="function-link"><span class="function-syntax">Works::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">extension_genre</span><span class="plain-syntax">, </span><span class="identifier-syntax">extension_title</span><span class="plain-syntax">, </span><span class="identifier-syntax">extension_author</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">semantic_version_number</span><span class="plain-syntax"> </span><span class="identifier-syntax">V</span><span class="plain-syntax"> = </span><span class="identifier-syntax">VersionNumbers::from_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">then_version</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_string</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">need_version</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="5-ks.html#SP4_4_1_1" class="named-paragraph-link"><span class="named-paragraph">Add versioned extension</span><span class="named-paragraph-number">4.4.1.1</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-ks.html#SP4_4_1_2" class="named-paragraph-link"><span class="named-paragraph">Add unversioned extension</span><span class="named-paragraph-number">4.4.1.2</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-ks.html#SP4_4">&#167;4.4</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP4_4_1_1" class="paragraph-anchor"></a><b>&#167;4.4.1.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Add versioned extension</span><span class="named-paragraph-number">4.4.1.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">semantic_version_number</span><span class="plain-syntax"> </span><span class="identifier-syntax">V</span><span class="plain-syntax"> = </span><span class="identifier-syntax">VersionNumbers::from_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">need_version</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_string</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">VersionNumbers::is_null</span><span class="plain-syntax">(</span><span class="identifier-syntax">V</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">err</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">err</span><span class="plain-syntax">, </span><span class="string-syntax">"cannot read version number '%S'"</span><span class="plain-syntax">, </span><span class="identifier-syntax">then_version</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_string</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-cps.html#SP5" class="function-link"><span class="function-syntax">Copies::attach_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><a href="2-ce.html#SP2" class="function-link"><span class="function-syntax">CopyErrors::new_T</span></a><span class="plain-syntax">(</span><span class="constant-syntax">KIT_MISWORDED_CE</span><span class="plain-syntax">, -1, </span><span class="identifier-syntax">err</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">err</span><span class="plain-syntax">, </span><span class="string-syntax">"cannot read version number '%S'"</span><span class="plain-syntax">, </span><span class="identifier-syntax">need_version</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_string</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-cps.html#SP5" class="function-link"><span class="function-syntax">Copies::attach_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><a href="2-ce.html#SP2" class="function-link"><span class="function-syntax">CopyErrors::new_T</span></a><span class="plain-syntax">(</span><span class="constant-syntax">METADATA_MALFORMED_CE</span><span class="plain-syntax">, -1, </span><span class="identifier-syntax">err</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">err</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">inbuild_requirement</span><span class="plain-syntax"> *</span><span class="identifier-syntax">req</span><span class="plain-syntax"> = </span><a href="2-rqr.html#SP2" class="function-link"><span class="function-syntax">Requirements::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">work</span><span class="plain-syntax">,</span>
@ -288,22 +289,41 @@ interactive fiction features of the compiler, but BasicInformKit does not.
<span class="plain-syntax"> </span><span class="identifier-syntax">ADD_TO_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">req</span><span class="plain-syntax">, </span><span class="reserved-syntax">inbuild_requirement</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">extensions</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-ks.html#SP4_1">&#167;4.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP4_1_4" class="paragraph-anchor"></a><b>&#167;4.1.4. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Add unversioned extension</span><span class="named-paragraph-number">4.1.4</span></span><span class="comment-syntax"> =</span>
<ul class="endnotetexts"><li>This code is used in <a href="5-ks.html#SP4_4_1">&#167;4.4.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP4_4_1_2" class="paragraph-anchor"></a><b>&#167;4.4.1.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Add unversioned extension</span><span class="named-paragraph-number">4.4.1.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">inbuild_work</span><span class="plain-syntax"> *</span><span class="identifier-syntax">work</span><span class="plain-syntax"> = </span><a href="2-wrk.html#SP2" class="function-link"><span class="function-syntax">Works::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">extension_genre</span><span class="plain-syntax">, </span><span class="identifier-syntax">extension_title</span><span class="plain-syntax">, </span><span class="identifier-syntax">extension_author</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">inbuild_requirement</span><span class="plain-syntax"> *</span><span class="identifier-syntax">req</span><span class="plain-syntax"> = </span><a href="2-rqr.html#SP2" class="function-link"><span class="function-syntax">Requirements::any_version_of</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">work</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">req</span><span class="plain-syntax">, </span><span class="reserved-syntax">inbuild_requirement</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">extensions</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-ks.html#SP4_1">&#167;4.1</a>.</li></ul>
<ul class="endnotetexts"><li>This code is used in <a href="5-ks.html#SP4_4_1">&#167;4.4.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP4_4_2" class="paragraph-anchor"></a><b>&#167;4.4.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Deal with a kit dependency</span><span class="named-paragraph-number">4.4.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">if_kit</span><span class="plain-syntax"> = </span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">edition</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">work</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">title</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">if_clause</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">if_type</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">if_clause</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"type"</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">Str::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">if_type</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_string</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"kit"</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</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">err</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">err</span><span class="plain-syntax">, </span><span class="string-syntax">"a kit dependency can only be conditional on other kits"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-cps.html#SP5" class="function-link"><span class="function-syntax">Copies::attach_error</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><a href="2-ce.html#SP2" class="function-link"><span class="function-syntax">CopyErrors::new_T</span></a><span class="plain-syntax">(</span><span class="constant-syntax">METADATA_MALFORMED_CE</span><span class="plain-syntax">, -1, </span><span class="identifier-syntax">err</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">err</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">if_title</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">if_clause</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"title"</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">if_title</span><span class="plain-syntax">) </span><span class="identifier-syntax">if_kit</span><span class="plain-syntax"> = </span><span class="identifier-syntax">if_title</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_string</span><span class="plain-syntax">; </span><span class="comment-syntax"> a line for IF fans</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="5-ks.html#SP5" class="function-link"><span class="function-syntax">Kits::dependency</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">if_kit</span><span class="plain-syntax">, </span><span class="identifier-syntax">parity</span><span class="plain-syntax">, </span><span class="identifier-syntax">need_title</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_string</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-ks.html#SP4_4">&#167;4.4</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. </b>We provide if this then that, where <span class="extract"><span class="extract-syntax">inc</span></span> is true, and if this then not that,
where it's false.
</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">Kits::dependency</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">Kits::dependency</span></span>:<br/><a href="5-ks.html#SP4_1">&#167;4.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inform_kit</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">if_text</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">inc</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">then_text</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Kits::dependency</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">Kits::dependency</span></span>:<br/><a href="5-ks.html#SP4_4_2">&#167;4.4.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inform_kit</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">if_text</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">inc</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">then_text</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">inform_kit_ittt</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ITTT</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">inform_kit_ittt</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ITTT</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_name</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::duplicate</span><span class="plain-syntax">(</span><span class="identifier-syntax">if_text</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ITTT</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_included</span><span class="plain-syntax"> = </span><span class="identifier-syntax">inc</span><span class="plain-syntax">;</span>
@ -316,7 +336,7 @@ latter may not be useful in practice:
</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">Kits::activation</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">Kits::activation</span></span>:<br/><a href="5-ks.html#SP4_1">&#167;4.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inform_kit</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">act</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Kits::activation</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">Kits::activation</span></span>:<br/><a href="5-ks.html#SP4_2">&#167;4.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inform_kit</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">act</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">element_activation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">EA</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">element_activation</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EA</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">element_name</span><span class="plain-syntax"> = </span><span class="identifier-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">EA</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">activate</span><span class="plain-syntax"> = </span><span class="identifier-syntax">act</span><span class="plain-syntax">;</span>

View file

@ -72,24 +72,47 @@ the project in an ITTT, "if-this-then-that", way. As we shall see, every kit
contains a file called |kit_metadata.json| describing its needs. The metadata
for CommandParserKit includes:
= (text)
dependency: if CommandParserKit then WorldModelKit
{
"need": {
"type": "kit",
"title": "WorldModelKit"
}
}
=
Never mind the JSON syntax (all that punctuation) for now: what this is saying
is that CommandParserKit always needs WorldModelKit in order to function.
This means that any project depending on CommandParserKit automatically depends
on WorldModelKit too. BasicInformKit uses this facility as well, but in a
negative way. Its own metadata file says:
conditional way. Its own metadata file includes:
= (text)
dependency: if not WorldModelKit then BasicInformExtrasKit
{
"unless": {
"type": "kit",
"title": "WorldModelKit"
},
"need": {
"type": "kit",
"title": "BasicInformExtrasKit"
}
}
=
It follows that if WorldModelKit is not present, then BasicInformExtrasKit is
automatically added instead.
Inbuild acts on this by checking to see if WorldModelKit is not present, and
in that case BasicInformExtrasKit is automatically added instead. (Positive
conditions can also be made, with "if" instead of "unless".)
@ Kits can also use their metadata to specify that associated extensions should
automatically be loaded into the project.[1] For example, the |kit_metadata.json|
for BasicInformKit includes the lines:
= (text)
extension: Basic Inform by Graham Nelson
extension: English Language by Graham Nelson
{
"need": {
"type": "extension",
"title": "Basic Inform",
"author": "Graham Nelson"
}
}
=
...and similarly for another extension called English Language.
[1] This in fact is the mechanism by which Inform decides which extensions
should be implicitly included in a project. Other extensions are included only
@ -176,9 +199,6 @@ we next look at the build requirements for the project, we see:
=
So now BalloonKit is indeed a dependency.
See //inbuild: Manual// for the full story on where the compiler expects to
find kits, but basically, they're managed much the way extensions are.
[1] Both, so that whether the executable looking at the project is inbuild or
inform7, it will use the same set of kits. You want this.
@ -245,13 +265,122 @@ very legible, and it is highly verbose.
[2] At some point it may be developed out a little, but there's no great need.
@ The metadata file at |BalloonKit/kit_metadata.json| is going to be simple:
@ The metadata file at |BalloonKit/kit_metadata.json| is required to exist in
order for Inbuild to recognise this as being a kit at all; even if it doesn't
say very much, as in this example. This is (almost) minimal:
= (text)
extension: Party Balloons by Joseph-Michel Montgolfier
{
"is": {
"type": "kit",
"title": "BalloonKit",
"author": "Jacques-Étienne Montgolfier"
"version": "3.2.7"
}
}
=
In fact we don't really need this line at all (a kit does not need to have any
associated extensions), but it makes for a more interesting demonstration. We
can see an effect at once:
This is a JSON-format file: JSON, standing for Javascript Object Notation, is
now nothing really to do with the language Javascript and has instead become
an Internet standard for small packets of descriptive data, like ours. Many
full descriptions of JSON are available, but here are some brief notes:
(*) This is a UTF-8 plain text file. The acute accent in "Jacques-Étienne Montgolfier"
causes no problems, but quoted text is well advised to confine itself to the Unicode
Basic Multilingual Plane characters (with code-points 0 to 65535). Inside
quotation marks, |\n| and |\t| can be used for newlines and tabs, but a kit
shouldn't ever need them. |\uDDDD| can be used to mean "the Unicode character
whose code is |DDDD| in hexadecimal".
(*) Braces |{| and |}| begin and end "objects". The whole set of metadata on
the kit is such an object, so the file has to open and close with |{| and |}|.
Inside such braces, we have a list of named values, divided by commas. Each
entry takes the form |"name": value|. The name is in quotes, but the value
will only be quoted if it happens to be a string.
(*) Square brackets |[| and |]| begin and end lists, with the entries in the
list divided by commas. For example, |[ 1, 2, 17 ]| is a valid list of three
numbers.
(*) Numbers are written in decimal, possibly with a minus sign: for example,
|24| or |-120|. (JSON also allows floating-point numbers, which Inbuild does
read, and stores to double precision, but kit metadata never needs these.)
(*) The special notations |true| and |false| are used for so-called boolean
values, i.e., those which are either true or false.
(*) The special notation |null| is used to mean "I am not saying what this is",
but kit metadata never needs this.
(*) JSON files are forbidden to contain comments, and Inbuild is very strict
about what hierarchies of objects it will read without errors.
@ Looking again at the minimal example, what do we have?
= (text)
{
"is": {
"type": "kit",
"title": "BalloonKit",
"author": "Jacques-Étienne Montgolfier"
"version": "3.2.7"
}
}
=
The metadata is one big object. That object has a single named value, |"is"|.
The value of |"is"| is another object -- hence the second pair of |{| ... |}| after
the colon. This second object gives the identity of the kit -- says what it is,
in other words. That has four values:
(1) |"type"|, which has to be |"kit"|;
(2) |"title"|, which has to match the kit's name -- Inbuild will throw an error
if BalloonKit's metadata file claims that its title is actually |"AerostatiqueKit"|;
(3) |"author"|, which is optional, but which if given should follow the usual
conventions for author names of Inform extensions; and
(4) |"version"|, which is also optional, but whose use is strongly recommended.
This has to be a semantic version number. This follows Inbuild's usual semantic
version numbering conventions, so for example |"5"| and |"1.5.6-alpha.12"| would
both be valid. Note that in JSON terms it's a string, despite the word "number"
in the phrase "semantic version number", so it goes in double-quotes. This is
the version number which Inbuild will use to resolve dependencies. If a project
needs v1.7 or better, for example, Inbuild will not allow it to use
version 1.5.6-alpha.12 of a kit.
@ To make for a more interesting demonstration, now suppose that the kit
wants to require the use of an associated extension. We extend the metadata file to:
= (text)
{
"is": {
"type": "kit",
"title": "BalloonKit",
"author": "Jacques-Étienne Montgolfier"
"version": "3.2.7"
},
"needs": [
{
"need": {
"type": "extension",
"title": "Party Balloons",
"author": "Joseph-Michel Montgolfier"
}
}
]
}
=
Now our metadata object has a second named value, |"needs"|. This has to be
a list, which in JSON is written in square brackets |[ X, Y, Z, ... ]|. Here
the list has just one entry, in fact. The entries in the list all have to be
objects, which can have three possible values:
(1) |"if"|, saying that the dependency is conditional on another kit being used --
see above for examples;
(2) |"unless"|, similarly but making the condition on another kit not being used;
(3) |"need"|, which says what the dependency is on.
The |"if"| and |"unless"| clauses are optional. (And only one can be given.)
The |"need"| clause is compulsory. This can say that the kit needs another
kit (there are examples above), but in this case it says the kit needs a
particular extension to be present.
We can see an effect at once:
= (text as ConsoleText)
$ inbuild/Tangled/inbuild -project 'French Laundry.inform' -build-needs
projectbundle: French Laundry.inform
@ -281,8 +410,11 @@ become a haunt of the pioneers of aeronautics."
When play begins:
perform an inflation with 3 puffs.
=
Note that this text does not explicitly say "Include Party Balloons by Joseph-Michel
Montgolfier" -- it doesn't need to: the extension is automatically included by
the kit.
Now Inbuild is happier:
And now Inbuild is happier:
= (text as ConsoleText)
$ inbuild/Tangled/inbuild -project 'French Laundry.inform' -build-needs
projectbundle: French Laundry.inform
@ -315,122 +447,105 @@ And this incremental building is also what happens if the "French Laundry"
project is compiled in the Inform apps, by clicking "Go" in the usual way. Any
of its kits which need rebuilding are automatically rebuilt as part of the process.
@h Full specification of the kit metadata file.
This is a UTF-8 encoded Unicode text file, consisting of a sequence of commands
in any order, one per line. No commands are compulsory. An empty file is legal.
@h Other ingredients of the kit metadata file.
As noted above, |kit_metadata.json| must be a valid JSON file which encodes a
single object. The following are the legal member names; only |"is"| is mandatory,
and the rest sensibly default if not given.
Blank lines are ignored, as are lines whose first non-white-space character is |#|,
which are considered comments.
(*) |"is"|, an object identifying what kit this is. See above.
@ |version: V| gives the kit's version number. This follows Inbuild's usual semantic
version numbering conventions, so for example:
= (text)
version: 5
version: 1.5.6-alpha.12
=
This is the version number which Inbuild will use to resolve dependencies. If a
project needs v1.7 or better, for example, Inbuild will not allow it to use
version 1.5.6-alpha.12 of a kit.
(*) |"needs"|, a list of objects each of which specifies a possibly conditional
dependency on other resources. See above.
@ |compatibility: C| allows us to say which architectures or final targets
(*) |"compatibility"|, a string which describes which architectures or final targets
the kit is compatible with. By default, Inbuild assumes it will work with anything,
equivalent to |compatibility: all|. But for example:
equivalent to |"compatibility": "all"|. In general, it's best to stick to purely
architectural constraints (i.e. 16 or 32 bit, with or without debugging support)
and not to constrain the final target unless really necessary. But the following
are all legal:
= (text)
compatibility: for 16-bit with debugging only
compatibility: not for 32-bit
compatibility: for Inform6 version 8
compatibility: not for C
=
In general, it's best to stick to architectural constraints (i.e. 16 or 32 bit,
with or without debugging support) and not to constrain the final target unless
really necessary.
@ |defines Main: yes| or |defines Main: no|. The default is |no|, so use this
only to specify that the kit contains within it a definition of the |Main|
function. But only the shipped-with-Inform kits should ever do this.
@ |natural language: yes| or |natural language: no|. The default is |no|; use
this only to say that the kit is a language support kit, like EnglishLanguageKit.
@ |insert: X|. This sneakily allows a sentence of Inform 7 source text to be
inserted into any project using the kit. For example:
= (text)
insert: Use maximum inflation level of 20.
=
But in general it's better not to use this at all, and to put any such material
in an associated extension which is automatically included.
@ |kinds: F|, where |F| is the name of a Neptune file. Neptune is a mini-language
for setting up kinds and kind constructors inside the compiler: see
//kinds: A Brief Guide to Neptune// for much more on this. The file |F| should
be placed as |BalloonKit/kinds/F|. For example:
= (text)
kinds: Protocols.neptune
kinds: Core.neptune
"compatibility": "for 16-bit with debugging only"
"compatibility": "not for 32-bit"
"compatibility": "for Inform6 version 8"
"compatibility": "not for C"
=
@ |extension: E|, where |E| is the name of an extension. A version number
can optionally be given, too. For example:
(*) |"activates"| is a list of strings describing optional features of the Inform
compiler to switch on if this kit is being used. The feature names are the names
of plugins inside the compiler, and this is not the place to document that. See
the implementation at //core: Plugins//. But in general, unless you are performing
wild experiments with new language features inside the compiler, you will never
need |"activates"|. It really exists for the benefit of the built-in kits. For
example, WorldModelKit does the following:
= (text)
extension: Party Balloons by Joseph-Michel Montgolfier
extension: version 2.1 of Party Balloons by Joseph-Michel Montgolfier
"activates": [ "interactive fiction", "multimedia" ]
=
Inbuild will now automatically include this extension if it can find it; if
not, the build will halt. Compatibility with the version number is done by
semantic version numbering rules, so v2.1.67 would be fine, but not v2.2, v1,
v3, and so forth. Note that kits can mandate multiple extensions, not just one.
@ |activate: F| and |deactivate: F|. This says that if the kit is present, then
a given feature inside the compiler |F| should be switched on or off. For
example, the metadata for CommandParserKit includes:
(*) |"deactivates"| is a similar list describing what to turn off.
(*) |"kit-details"| is a set of oddball settings which make sense only for kits.
The reason these are hived off in their own sub-object is so that the same
basic file format can be used for JSON describing other resources, too.
|"kit-details"| can only legally be used if the |"type"| in the |"is"| object
is set to |"kit"|.
@ The |"kit-details"| object can contain the following, all of which are
optional. Only the first is likely to be useful for a kit other than one of
those built in to the Inform installation.
(*) |"provides-kinds"| is a list of strings. These are the names of Neptune
files to read in. Neptune is a mini-language for setting up kinds and kind
constructors inside the Inform compiler: see //kinds: A Brief Guide to Neptune//
for much more on this. Each named file |F| should be placed as |BalloonKit/kinds/F|.
For example, WorldModelKit does this:
= (text)
activate: command
"provides-kinds": [ "Actions.neptune", "Times.neptune", "Scenes.neptune", "Figures.neptune", "Sounds.neptune" ]
=
which enables command grammar to be part of the Inform language. WorldModelKit
more ambitiously says:
= (text)
activate: interactive fiction
activate: multimedia
=
It is these activation lines, in WorldModelKit and CommandParserKit, which cause
the Inform language to have IF-specific features during a compilation. Without
them, the language would just be Basic Inform.
The feature names |F| are the names of plugins inside the compiler, and this is
not the place to document that. See the implementation at //core: Plugins//.
But in general, unless you are performing wild experiments with new language
features inside the compiler, never use |activate| or |deactivate|.
@ |dependency: if X then Y| and |dependency: if not X then Y|. This specifies
dependencies between kits; often |X| or |Y| will be the kit you are currently
defining, but not necessarily. Rules are considered for all kits currently loaded.
For example, this is part of the metadata for CommandParserKit:
= (text)
dependency: if CommandParserKit then WorldModelKit
=
A few points to note:
(*) Rules are considered only for kits which are loaded. There is no way to
make BalloonKit parasitically attach to all projects by giving it the rule
|if not BalloonKit then BalloonKit|, because this rule will only be looked at
if BalloonKit has already loaded.
(*) The outcome cannot be |... then not Y|; once loaded, a kit cannot be
unloaded. So these dependency rules can only cause extra kits to be added.
(*) Positive rules |if ...| are considered first, and only then negative ones
|if not ...|. Within each category, kits have their rules looked at in order
of their priority (see below).
(*) Version number requirements cannot be specified for either |X| or |Y|
at present.
@ |priority: N|, where |N| is a number from 0 to 100. This is used only to
decide whose wishes get priority when Inbuild is performing if-this-then-that
(*) |"has-priority"| is a number, from 0 to 100. This is used only to decide
whose wishes get priority when Inbuild is performing if-this-then-that
decisions to sort out which kits are present in a project. The default is 10,
and for almost all kits it should stay that way. Lower-numbered kits have
"more important" wishes than higher-numbered ones.
@ |index from: C| can change the structure of the Index for a project using
this kit, but in practice this should be done only by BasicInformKit or by
WorldModelKit. (There are two versions of the index, one for Basic Inform
projects, the other for interactive-fiction ones.)
(*) |"defines-Main"| is a boolean, so its value has to be |true| or |false|.
If it isn't given, the value will be |false|. This is useful only for the
built-in kits supplied with Inform, and indicates whether or not they define
a |Main| function in Inter.
(*) |"indexes-with-structure"| is a string. This is useful only for the
built-in kits supplied with Inform, and indicates which structure file should
be used to generate the Index of a project. (There are two versions of the
index, one for Basic Inform projects, the other for interactive-fiction ones.)
(*) |"inserts-source-text"| is a string. This sneakily allows a sentence of
Inform 7 source text to be inserted into any project using the kit. Its use
is very much a last resort: if at all possible, put such material in an
associated extension, and then auto-include that extension using a |"needs"|
dependency (see above). But, for example:
= (text)
"inserts-source-text": "Use maximum inflation level of 20."
=
@ Here are a few footnotes on how Inbuild resolves the "needs" requirements
of multiple kits, which may clarify what happens in apparently ambiguous
situations.
(*) Needs are considered only for kits which are loaded. There is no way to
make BalloonKit parasitically attach to all projects by giving it a rule
saying in effect "unless you have BalloonKit then you need BalloonKit",
because although you could write such a rule, it would only be processed
when BalloonKit had already loaded -- and would then have no effect.
(*) A kit cannot be unloaded once loaded. So "needs" rules can only cause
extra kits to be added. It follows that there can never be a loop caused
by kits repeatedly loading and unloading each other through irresolvable
constraints. But it also follows that the outcome in such a case can depend
on the order in which rules are considered.
(*) Positive needs using "if" (or unconditional needs) are considered first,
and only then negative ones using "unless". Within each category, kits have
their needs looked at in order of their priority numbers (see above).
@h Future directions.
It will be noted that a kit can include an extension automatically, but not

View file

@ -13,7 +13,7 @@ sentence is which is mis-punctuated, and such. In every case most of these
fields are blank.
@e OPEN_FAILED_CE from 1
@e KIT_MISWORDED_CE
@e METADATA_MALFORMED_CE
@e EXT_MISWORDED_CE
@e EXT_TITLE_TOO_LONG_CE
@e EXT_AUTHOR_TOO_LONG_CE
@ -127,7 +127,8 @@ void CopyErrors::write(OUTPUT_STREAM, copy_error *CE) {
switch (CE->error_category) {
case OPEN_FAILED_CE: WRITE("unable to open file %f", CE->details_file); break;
case EXT_MISWORDED_CE: WRITE("extension misworded: %S", CE->details); break;
case KIT_MISWORDED_CE: WRITE("kit has incorrect metadata: %S", CE->details); break;
case METADATA_MALFORMED_CE: WRITE("%S has incorrect metadata: %S",
CE->copy->edition->work->genre->genre_name, CE->details); break;
case EXT_TITLE_TOO_LONG_CE: WRITE("title too long: %d characters (max is %d)",
CE->details_N, MAX_EXTENSION_TITLE_LENGTH); break;
case EXT_AUTHOR_TOO_LONG_CE: WRITE("author name too long: %d characters (max is %d)",

View file

@ -17,16 +17,17 @@ void JSONMetadata::read_metadata_file(inbuild_copy *C, filename *F) {
TextFiles::read(F, FALSE, "unable to read file of JSON metadata", TRUE,
&JSONMetadata::read_metadata_file_helper, NULL, contents);
text_file_position tfp = TextFiles::at(F, 1);
JSON_value *value = JSON::decode(contents, &tfp);
if ((value) && (value->JSON_type == ERROR_JSONTYPE)) {
JSON_value *obj = JSON::decode(contents, &tfp);
if ((obj) && (obj->JSON_type == ERROR_JSONTYPE)) {
@<Report a syntax error in JSON@>;
return;
} else {
@<Validate the JSON read in@>;
}
DISCARD_TEXT(contents)
C->metadata_record = value;
C->metadata_record = obj;
@<Examine the "is" member of the metadata object@>;
@<Police the "needs"@>;
}
void JSONMetadata::read_metadata_file_helper(text_stream *text, text_file_position *tfp,
@ -37,25 +38,25 @@ void JSONMetadata::read_metadata_file_helper(text_stream *text, text_file_positi
@<Report a syntax error in JSON@> =
TEMPORARY_TEXT(err)
WRITE_TO(err, "the metadata contains a syntax error: '%S'", value->if_error);
Copies::attach_error(C, CopyErrors::new_T(KIT_MISWORDED_CE, -1, err));
WRITE_TO(err, "the metadata contains a syntax error: '%S'", obj->if_error);
Copies::attach_error(C, CopyErrors::new_T(METADATA_MALFORMED_CE, -1, err));
DISCARD_TEXT(err)
@<Validate the JSON read in@> =
linked_list *validation_errors = NEW_LINKED_LIST(text_stream);
if (JSON::validate(value, req, validation_errors) == FALSE) {
if (JSON::validate(obj, req, validation_errors) == FALSE) {
text_stream *err;
LOOP_OVER_LINKED_LIST(err, text_stream, validation_errors) {
TEMPORARY_TEXT(msg)
WRITE_TO(msg, "the metadata did not validate: '%S'", err);
Copies::attach_error(C, CopyErrors::new_T(KIT_MISWORDED_CE, -1, msg));
Copies::attach_error(C, CopyErrors::new_T(METADATA_MALFORMED_CE, -1, msg));
DISCARD_TEXT(msg)
}
return;
}
@<Examine the "is" member of the metadata object@> =
JSON_value *is = JSON::look_up_object(C->metadata_record, I"is");
JSON_value *is = JSON::look_up_object(obj, I"is");
JSON_value *type = JSON::look_up_object(is, I"type");
if (type) @<Make sure the type is correct@>;
JSON_value *title = JSON::look_up_object(is, I"title");
@ -80,16 +81,30 @@ to say that |is.type| is |"kit"|.
TEMPORARY_TEXT(msg)
WRITE_TO(msg, "the metadata misidentifies the type as '%S', but it should be '%S'",
type_text, required_text);
Copies::attach_error(C, CopyErrors::new_T(KIT_MISWORDED_CE, -1, msg));
Copies::attach_error(C, CopyErrors::new_T(METADATA_MALFORMED_CE, -1, msg));
DISCARD_TEXT(msg)
}
JSON_value *kit_details = JSON::look_up_object(obj, I"kit-details");
if ((kit_details) && (Str::ne(type_text, I"kit"))) {
TEMPORARY_TEXT(err)
WRITE_TO(err, "the metadata contains kit-details but is not for a kit");
Copies::attach_error(C, CopyErrors::new_T(METADATA_MALFORMED_CE, -1, err));
DISCARD_TEXT(err)
}
JSON_value *extension_details = JSON::look_up_object(obj, I"extension-details");
if ((extension_details) && (Str::ne(type_text, I"extension"))) {
TEMPORARY_TEXT(err)
WRITE_TO(err, "the metadata contains extension-details but is not for an extension");
Copies::attach_error(C, CopyErrors::new_T(METADATA_MALFORMED_CE, -1, err));
DISCARD_TEXT(err)
}
@<Make sure the title is correct@> =
if (Str::ne(title->if_string, C->edition->work->title)) {
TEMPORARY_TEXT(err)
WRITE_TO(err, "the metadata says the title is '%S' when it should be '%S'",
title->if_string, C->edition->work->title);
Copies::attach_error(C, CopyErrors::new_T(KIT_MISWORDED_CE, -1, err));
Copies::attach_error(C, CopyErrors::new_T(METADATA_MALFORMED_CE, -1, err));
DISCARD_TEXT(err)
}
@ -98,7 +113,7 @@ to say that |is.type| is |"kit"|.
TEMPORARY_TEXT(err)
WRITE_TO(err, "the metadata says the author is '%S' when it should be '%S'",
author->if_string, C->edition->work->author_name);
Copies::attach_error(C, CopyErrors::new_T(KIT_MISWORDED_CE, -1, err));
Copies::attach_error(C, CopyErrors::new_T(METADATA_MALFORMED_CE, -1, err));
DISCARD_TEXT(err)
}
@ -110,7 +125,7 @@ a version number.
if (VersionNumbers::is_null(V)) {
TEMPORARY_TEXT(err)
WRITE_TO(err, "cannot read version number '%S'", version->if_string);
Copies::attach_error(C, CopyErrors::new_T(KIT_MISWORDED_CE, -1, err));
Copies::attach_error(C, CopyErrors::new_T(METADATA_MALFORMED_CE, -1, err));
DISCARD_TEXT(err)
} else {
C->edition->version = VersionNumbers::from_text(version->if_string);
@ -119,9 +134,64 @@ a version number.
@<Forbid the use of a version range@> =
TEMPORARY_TEXT(err)
WRITE_TO(err, "the metadata should specify an exact version, not a range");
Copies::attach_error(C, CopyErrors::new_T(KIT_MISWORDED_CE, -1, err));
Copies::attach_error(C, CopyErrors::new_T(METADATA_MALFORMED_CE, -1, err));
DISCARD_TEXT(err)
@ It would have been possible to write the schema in a way which would exclude
the possibilities blocked here, but only by making it cumbersome. Besides,
checking here results in more explicit error messages.
@<Police the "needs"@> =
JSON_value *needs = JSON::look_up_object(obj, I"needs");
if (needs) {
JSON_value *E;
LOOP_OVER_LINKED_LIST(E, JSON_value, needs->if_list) {
JSON_value *if_clause = JSON::look_up_object(E, I"if");
JSON_value *unless_clause = JSON::look_up_object(E, I"unless");
JSON_value *needs_clause = JSON::look_up_object(E, I"needs");
if ((if_clause) && (unless_clause)) {
TEMPORARY_TEXT(err)
WRITE_TO(err, "cannot give both 'if' and 'unless' in same requirement");
Copies::attach_error(C, CopyErrors::new_T(METADATA_MALFORMED_CE, -1, err));
DISCARD_TEXT(err)
}
JSONMetadata::not_both(C, if_clause, I"'if' clause of a requirement");
JSONMetadata::not_both(C, unless_clause, I"'unless' clause of a requirement");
JSONMetadata::not_both(C, needs_clause, I"'needs' clause of a requirement");
}
}
@ All very pedantic, but:
=
void JSONMetadata::not_both(inbuild_copy *C, JSON_value *clause, text_stream *where) {
if (clause) {
JSON_value *version = JSON::look_up_object(clause, I"version");
JSON_value *version_range = JSON::look_up_object(clause, I"version-range");
if ((version) && (version_range)) {
TEMPORARY_TEXT(err)
WRITE_TO(err, "%S specifies both a version and a version-range", where);
Copies::attach_error(C, CopyErrors::new_T(METADATA_MALFORMED_CE, -1, err));
DISCARD_TEXT(err)
}
if (version) {
semantic_version_number V = VersionNumbers::from_text(version->if_string);
if (VersionNumbers::is_null(V)) {
TEMPORARY_TEXT(err)
WRITE_TO(err, "cannot read version '%S' in %S", version->if_string, where);
Copies::attach_error(C, CopyErrors::new_T(METADATA_MALFORMED_CE, -1, err));
DISCARD_TEXT(err)
}
}
if (version_range) {
TEMPORARY_TEXT(err)
WRITE_TO(err, "'version-range' is not yet supported in %S", where);
Copies::attach_error(C, CopyErrors::new_T(METADATA_MALFORMED_CE, -1, err));
DISCARD_TEXT(err)
}
}
}
@ The following returns the schema needed for (b); we will load it in from a file
in the Inform/Inbuild installation, but will then cache the result so that it
loads only once.

View file

@ -73,120 +73,113 @@ void Kits::scan(inbuild_copy *C) {
filename *F = Filenames::in(C->location_if_path, I"kit_metadata.json");
JSONMetadata::read_metadata_file(C, F);
if (C->metadata_record) @<Extract what we need@>;
if (C->metadata_record) {
JSON_value *compatibility =
JSON::look_up_object(C->metadata_record, I"compatibility");
if (compatibility) @<Extract compatibility@>;
@<Extract activations@>;
JSON_value *kit_details =
JSON::look_up_object(C->metadata_record, I"kit-details");
if (kit_details) @<Extract the kit details@>;
JSON_value *needs = JSON::look_up_object(C->metadata_record, I"needs");
if (needs) {
JSON_value *E;
LOOP_OVER_LINKED_LIST(E, JSON_value, needs->if_list)
@<Extract this possibly conditional requirement@>;
}
}
}
@<Extract what we need@> =
JSON_value *compatibility = JSON::look_up_object(C->metadata_record, I"compatibility");
if (compatibility) @<Add compatibility@>;
JSON_value *activate = JSON::look_up_object(C->metadata_record, I"activates");
if (activate) {
JSON_value *E;
LOOP_OVER_LINKED_LIST(E, JSON_value, activate->if_list)
Kits::activation(K, E->if_string, TRUE);
}
JSON_value *deactivate = JSON::look_up_object(C->metadata_record, I"deactivates");
if (deactivate) {
JSON_value *E;
LOOP_OVER_LINKED_LIST(E, JSON_value, deactivate->if_list)
Kits::activation(K, E->if_string, FALSE);
}
JSON_value *kit_details = JSON::look_up_object(C->metadata_record, I"kit-details");
if (kit_details) {
JSON_value *priority = JSON::look_up_object(kit_details, I"has-priority");
if (priority) K->priority = priority->if_integer;
JSON_value *defines_Main = JSON::look_up_object(kit_details, I"defines-Main");
if (defines_Main) K->defines_Main = defines_Main->if_boolean;
JSON_value *is_language_kit = JSON::look_up_object(kit_details, I"is-language-kit");
if (is_language_kit) K->supports_nl = is_language_kit->if_boolean;
JSON_value *index = JSON::look_up_object(kit_details, I"indexes-with-structure");
if (index) K->index_structure = index->if_string;
JSON_value *kinds = JSON::look_up_object(kit_details, I"provides-kinds");
if (kinds) {
JSON_value *E;
LOOP_OVER_LINKED_LIST(E, JSON_value, kinds->if_list)
ADD_TO_LINKED_LIST(E->if_string, text_stream, K->kind_definitions);
}
}
JSON_value *dependencies = JSON::look_up_object(C->metadata_record, I"needs");
if (dependencies) {
JSON_value *E;
LOOP_OVER_LINKED_LIST(E, JSON_value, dependencies->if_list) {
int loaded = TRUE;
JSON_value *if_clause = JSON::look_up_object(E, I"if");
JSON_value *unless_clause = JSON::look_up_object(E, I"unless");
if ((if_clause) && (unless_clause)) {
TEMPORARY_TEXT(err)
WRITE_TO(err, "cannot give both 'if' and 'unless' in same requirement");
Copies::attach_error(C, CopyErrors::new_T(KIT_MISWORDED_CE, -1, err));
DISCARD_TEXT(err)
}
if (unless_clause) {
if_clause = unless_clause; loaded = FALSE;
}
JSON_value *then_clause = JSON::look_up_object(E, I"need");
if (then_clause) {
JSON_value *type = JSON::look_up_object(then_clause, I"type");
JSON_value *title = JSON::look_up_object(then_clause, I"title");
JSON_value *author = JSON::look_up_object(then_clause, I"author");
JSON_value *then_version = JSON::look_up_object(then_clause, I"version");
if (Str::eq(type->if_string, I"extension")) {
if (if_clause) {
TEMPORARY_TEXT(err)
WRITE_TO(err, "a kit can only have an extension as a dependency unconditionally");
Copies::attach_error(C, CopyErrors::new_T(KIT_MISWORDED_CE, -1, err));
DISCARD_TEXT(err)
}
text_stream *extension_title = title->if_string;
text_stream *extension_author = author?(author->if_string):NULL;
if (then_version) @<Add versioned extension@>
else @<Add unversioned extension@>;
} else if (Str::eq(type->if_string, I"kit")) {
text_stream *if_kit = C->edition->work->title;
if (if_clause) {
JSON_value *if_type = JSON::look_up_object(if_clause, I"type");
if (Str::eq(if_type->if_string, I"kit") == FALSE) {
TEMPORARY_TEXT(err)
WRITE_TO(err, "a kit dependency can only be conditional on other kits");
Copies::attach_error(C, CopyErrors::new_T(KIT_MISWORDED_CE, -1, err));
DISCARD_TEXT(err)
} else {
JSON_value *if_title = JSON::look_up_object(if_clause, I"title");
if (if_title) if_kit = if_title->if_string; /* a line for IF fans */
}
}
Kits::dependency(K, if_kit, loaded, title->if_string);
} else {
TEMPORARY_TEXT(err)
WRITE_TO(err, "a kit can only have extensions and kits as dependencies");
Copies::attach_error(C, CopyErrors::new_T(KIT_MISWORDED_CE, -1, err));
DISCARD_TEXT(err)
}
}
}
}
@<Add compatibility@> =
@<Extract compatibility@> =
compatibility_specification *CS = Compatibility::from_text(compatibility->if_string);
if (CS) C->edition->compatibility = CS;
else {
TEMPORARY_TEXT(err)
WRITE_TO(err, "cannot read compatibility '%S'", compatibility->if_string);
Copies::attach_error(C, CopyErrors::new_T(KIT_MISWORDED_CE, -1, err));
Copies::attach_error(C, CopyErrors::new_T(METADATA_MALFORMED_CE, -1, err));
DISCARD_TEXT(err)
}
@<Add early source@> =
K->early_source = Str::duplicate(mr.exp[0]);
WRITE_TO(K->early_source, "\n\n");
@<Extract activations@> =
JSON_value *activates = JSON::look_up_object(C->metadata_record, I"activates");
if (activates) {
JSON_value *E;
LOOP_OVER_LINKED_LIST(E, JSON_value, activates->if_list)
Kits::activation(K, E->if_string, TRUE);
}
JSON_value *deactivates = JSON::look_up_object(C->metadata_record, I"deactivates");
if (deactivates) {
JSON_value *E;
LOOP_OVER_LINKED_LIST(E, JSON_value, deactivates->if_list)
Kits::activation(K, E->if_string, FALSE);
}
@<Extract the kit details@> =
JSON_value *has_priority = JSON::look_up_object(kit_details, I"has-priority");
if (has_priority) K->priority = has_priority->if_integer;
JSON_value *defines_Main = JSON::look_up_object(kit_details, I"defines-Main");
if (defines_Main) K->defines_Main = defines_Main->if_boolean;
JSON_value *is_language_kit = JSON::look_up_object(kit_details, I"is-language-kit");
if (is_language_kit) K->supports_nl = is_language_kit->if_boolean;
JSON_value *indexes_with_structure =
JSON::look_up_object(kit_details, I"indexes-with-structure");
if (indexes_with_structure) K->index_structure = indexes_with_structure->if_string;
JSON_value *provides_kinds = JSON::look_up_object(kit_details, I"provides-kinds");
if (provides_kinds) {
JSON_value *E;
LOOP_OVER_LINKED_LIST(E, JSON_value, provides_kinds->if_list)
ADD_TO_LINKED_LIST(E->if_string, text_stream, K->kind_definitions);
}
JSON_value *inserts_source_text = JSON::look_up_object(kit_details, I"inserts-source-text");
if (inserts_source_text) {
K->early_source = Str::duplicate(inserts_source_text->if_string);
WRITE_TO(K->early_source, "\n\n");
}
@<Extract this possibly conditional requirement@> =
int parity = TRUE;
JSON_value *if_clause = JSON::look_up_object(E, I"if");
JSON_value *unless_clause = JSON::look_up_object(E, I"unless");
if (unless_clause) {
if_clause = unless_clause; parity = FALSE;
}
JSON_value *need_clause = JSON::look_up_object(E, I"need");
if (need_clause) {
JSON_value *need_type = JSON::look_up_object(need_clause, I"type");
JSON_value *need_title = JSON::look_up_object(need_clause, I"title");
JSON_value *need_author = JSON::look_up_object(need_clause, I"author");
JSON_value *need_version = JSON::look_up_object(need_clause, I"version");
if (Str::eq(need_type->if_string, I"extension"))
@<Deal with an extension dependency@>
else if (Str::eq(need_type->if_string, I"kit"))
@<Deal with a kit dependency@>
else {
TEMPORARY_TEXT(err)
WRITE_TO(err, "a kit can only have extensions and kits as dependencies");
Copies::attach_error(C, CopyErrors::new_T(METADATA_MALFORMED_CE, -1, err));
DISCARD_TEXT(err)
}
}
@<Deal with an extension dependency@> =
if (if_clause) {
TEMPORARY_TEXT(err)
WRITE_TO(err, "a kit can only have an extension as a dependency unconditionally");
Copies::attach_error(C, CopyErrors::new_T(METADATA_MALFORMED_CE, -1, err));
DISCARD_TEXT(err)
}
text_stream *extension_title = need_title->if_string;
text_stream *extension_author = need_author?(need_author->if_string):NULL;
inbuild_work *work = Works::new(extension_genre, extension_title, extension_author);
if (need_version) @<Add versioned extension@>
else @<Add unversioned extension@>;
@<Add versioned extension@> =
inbuild_work *work = Works::new(extension_genre, extension_title, extension_author);
semantic_version_number V = VersionNumbers::from_text(then_version->if_string);
semantic_version_number V = VersionNumbers::from_text(need_version->if_string);
if (VersionNumbers::is_null(V)) {
TEMPORARY_TEXT(err)
WRITE_TO(err, "cannot read version number '%S'", then_version->if_string);
Copies::attach_error(C, CopyErrors::new_T(KIT_MISWORDED_CE, -1, err));
WRITE_TO(err, "cannot read version number '%S'", need_version->if_string);
Copies::attach_error(C, CopyErrors::new_T(METADATA_MALFORMED_CE, -1, err));
DISCARD_TEXT(err)
} else {
inbuild_requirement *req = Requirements::new(work,
@ -195,10 +188,25 @@ void Kits::scan(inbuild_copy *C) {
}
@<Add unversioned extension@> =
inbuild_work *work = Works::new(extension_genre, extension_title, extension_author);
inbuild_requirement *req = Requirements::any_version_of(work);
ADD_TO_LINKED_LIST(req, inbuild_requirement, K->extensions);
@<Deal with a kit dependency@> =
text_stream *if_kit = C->edition->work->title;
if (if_clause) {
JSON_value *if_type = JSON::look_up_object(if_clause, I"type");
if (Str::eq(if_type->if_string, I"kit") == FALSE) {
TEMPORARY_TEXT(err)
WRITE_TO(err, "a kit dependency can only be conditional on other kits");
Copies::attach_error(C, CopyErrors::new_T(METADATA_MALFORMED_CE, -1, err));
DISCARD_TEXT(err)
} else {
JSON_value *if_title = JSON::look_up_object(if_clause, I"title");
if (if_title) if_kit = if_title->if_string; /* a line for IF fans */
}
}
Kits::dependency(K, if_kit, parity, need_title->if_string);
@ We provide if this then that, where |inc| is true, and if this then not that,
where it's false.

View file

@ -1,47 +1,47 @@
Total memory consumption was 129501K = 126 MB
Total memory consumption was 123446K = 121 MB
---- was used for 2045713 objects, in 363240 frames in 0 x 800K = 0K = 0 MB:
---- was used for 2045718 objects, in 363245 frames in 0 x 800K = 0K = 0 MB:
31.5% inter_tree_node_array 58 x 8192 = 475136 objects, 41813824 bytes
19.5% text_stream_array 4609 x 100 = 460900 objects, 25957888 bytes
18.3% linked_list 43563 objects, 24395280 bytes
10.6% inter_symbol_array 132 x 1024 = 135168 objects, 14061696 bytes
9.9% inter_error_stash_array 101 x 1024 = 103424 objects, 13241504 bytes
7.8% parse_node 129706 objects, 10376480 bytes
5.5% verb_conjugation 160 objects, 7425280 bytes
4.1% parse_node_annotation_array 346 x 500 = 173000 objects, 5547072 bytes
2.5% pcalc_prop_array 25 x 1000 = 25000 objects, 3400800 bytes
2.4% inter_name_array 67 x 1000 = 67000 objects, 3218144 bytes
1.9% kind_array 66 x 1000 = 66000 objects, 2642112 bytes
1.5% inter_name_generator_array 51 x 1000 = 51000 objects, 2041632 bytes
33.0% inter_tree_node_array 58 x 8192 = 475136 objects, 41813824 bytes
20.5% text_stream_array 4609 x 100 = 460900 objects, 25957888 bytes
19.2% linked_list 43564 objects, 24395840 bytes
11.1% inter_symbol_array 132 x 1024 = 135168 objects, 14061696 bytes
10.4% inter_error_stash_array 101 x 1024 = 103424 objects, 13241504 bytes
8.2% parse_node 129706 objects, 10376480 bytes
5.8% verb_conjugation 160 objects, 7425280 bytes
4.3% parse_node_annotation_array 346 x 500 = 173000 objects, 5547072 bytes
2.6% pcalc_prop_array 25 x 1000 = 25000 objects, 3400800 bytes
2.5% inter_name_array 67 x 1000 = 67000 objects, 3218144 bytes
2.0% kind_array 66 x 1000 = 66000 objects, 2642112 bytes
1.6% inter_name_generator_array 51 x 1000 = 51000 objects, 2041632 bytes
1.5% inter_schema_token 13964 objects, 2010816 bytes
1.4% package_request 21153 objects, 1861464 bytes
1.3% vocabulary_entry_array 161 x 100 = 16100 objects, 1808352 bytes
1.1% dict_entry_array 470 x 100 = 47000 objects, 1519040 bytes
1.4% vocabulary_entry_array 161 x 100 = 16100 objects, 1808352 bytes
1.2% dict_entry_array 470 x 100 = 47000 objects, 1519040 bytes
1.1% match_trie_array 11 x 1000 = 11000 objects, 1496352 bytes
1.1% inter_symbols_table 26592 objects, 1489152 bytes
1.0% i6_schema_array 23 x 100 = 2300 objects, 1380736 bytes
0.9% scan_directory 314 objects, 1296192 bytes
0.9% inter_package 26592 objects, 1276416 bytes
1.0% scan_directory 314 objects, 1296192 bytes
1.0% inter_package 26592 objects, 1276416 bytes
0.8% map_data 671 objects, 1127280 bytes
0.8% id_body 942 objects, 1077648 bytes
0.7% adjective_meaning 202 objects, 1000304 bytes
0.7% excerpt_meaning 3102 objects, 967824 bytes
0.6% production 3882 objects, 900624 bytes
0.7% production 3882 objects, 900624 bytes
0.6% ptoken 8414 objects, 875056 bytes
0.6% grammatical_usage 3613 objects, 867120 bytes
0.6% individual_form 2563 objects, 861168 bytes
0.6% inter_schema_node 8917 objects, 856032 bytes
0.4% unary_predicate_array 16 x 1000 = 16000 objects, 640512 bytes
0.5% unary_predicate_array 16 x 1000 = 16000 objects, 640512 bytes
0.3% local_variable_array 47 x 100 = 4700 objects, 452704 bytes
0.2% verb_usage 1128 objects, 388032 bytes
0.3% verb_usage 1128 objects, 388032 bytes
0.2% rule 470 objects, 368480 bytes
0.2% dictionary 7557 objects, 362736 bytes
0.2% verb_form 386 objects, 348944 bytes
0.2% noun 2382 objects, 285840 bytes
0.2% compilation_subtask 3355 objects, 268400 bytes
0.1% inter_annotation_array 2 x 8192 = 16384 objects, 262208 bytes
0.1% inference_subject 666 objects, 261072 bytes
0.2% inter_annotation_array 2 x 8192 = 16384 objects, 262208 bytes
0.2% inference_subject 666 objects, 261072 bytes
0.1% vanilla_function 3683 objects, 235712 bytes
0.1% binary_predicate 322 objects, 170016 bytes
0.1% hierarchy_location 1122 objects, 161568 bytes
@ -147,16 +147,16 @@ Total memory consumption was 129501K = 126 MB
---- either_or_property_data 62 objects, 2976 bytes
---- target_vm 20 objects, 2880 bytes
---- use_option 29 objects, 2552 bytes
---- parentage_inference_data 79 objects, 2528 bytes
---- part_of_inference_data 79 objects, 2528 bytes
---- kind_constructor_instance_array 1 x 100 objects, 2432 bytes
---- parentage_inference_data 79 objects, 2528 bytes
---- kind_constructor_casting_rule_array 1 x 100 objects, 2432 bytes
---- kind_constructor_instance_array 1 x 100 objects, 2432 bytes
---- equation_symbol 30 objects, 2400 bytes
---- scene 1 object, 2096 bytes
---- build_script 60 objects, 1920 bytes
---- JSON_type 25 objects, 1800 bytes
---- JSON_type 26 objects, 1872 bytes
---- JSON_single_requirement 36 objects, 1728 bytes
---- pronoun_usage 42 objects, 1680 bytes
---- JSON_single_requirement 35 objects, 1680 bytes
---- table_contribution_array 1 x 100 objects, 1632 bytes
---- plugin 25 objects, 1600 bytes
---- inform_pipeline 24 objects, 1536 bytes
@ -172,17 +172,17 @@ Total memory consumption was 129501K = 126 MB
---- quantifier 16 objects, 1024 bytes
---- inbuild_requirement 25 objects, 1000 bytes
---- submodule_identity 31 objects, 992 bytes
---- pipeline_stage 20 objects, 960 bytes
---- named_rulebook_outcome 15 objects, 960 bytes
---- JSON_requirement 29 objects, 928 bytes
---- JSON_requirement 30 objects, 960 bytes
---- pipeline_stage 20 objects, 960 bytes
---- control_structure_phrase 12 objects, 864 bytes
---- cached_understanding 21 objects, 840 bytes
---- phrase_option_array 1 x 100 objects, 824 bytes
---- internal_test 15 objects, 720 bytes
---- inbuild_search_result 18 objects, 720 bytes
---- JSON_pair_requirement 21 objects, 672 bytes
---- inform_language 6 objects, 672 bytes
---- relation_guard 5 objects, 640 bytes
---- JSON_pair_requirement 20 objects, 640 bytes
---- implication 13 objects, 624 bytes
---- code_generation 1 object, 576 bytes
---- inter_warehouse_room 10 objects, 560 bytes
@ -197,25 +197,25 @@ Total memory consumption was 129501K = 126 MB
---- article_usage 8 objects, 384 bytes
---- source_file 5 objects, 360 bytes
---- inbuild_genre 7 objects, 336 bytes
---- pronoun 8 objects, 320 bytes
---- door_dir_notice 5 objects, 320 bytes
---- cached_kind_declaration 8 objects, 320 bytes
---- module_request 8 objects, 320 bytes
---- grammatical_category 8 objects, 320 bytes
---- cached_kind_declaration 8 objects, 320 bytes
---- pronoun 8 objects, 320 bytes
---- door_dir_notice 5 objects, 320 bytes
---- inter_pipeline 1 object, 312 bytes
---- tree_inventory 1 object, 312 bytes
---- build_step 4 objects, 288 bytes
---- up_family 9 objects, 288 bytes
---- door_to_notice 5 objects, 280 bytes
---- build_step 4 objects, 288 bytes
---- contents_entry 7 objects, 280 bytes
---- door_to_notice 5 objects, 280 bytes
---- compilation_unit 5 objects, 280 bytes
---- explicit_bp_data 5 objects, 280 bytes
---- verb_usage_tier 5 objects, 240 bytes
---- adjective_meaning_family 7 objects, 224 bytes
---- test_scenario 1 object, 216 bytes
---- release_instructions 1 object, 208 bytes
---- code_generator 5 objects, 200 bytes
---- build_skill 5 objects, 200 bytes
---- code_generator 5 objects, 200 bytes
---- plural_dictionary_entry 4 objects, 192 bytes
---- inform_project 1 object, 192 bytes
---- kit_dependency 4 objects, 192 bytes
@ -242,23 +242,23 @@ Total memory consumption was 129501K = 126 MB
100.0% was used for memory not allocated for objects:
59.7% text stream storage 79187908 bytes in 478847 claims
3.9% dictionary storage 5248000 bytes in 7557 claims
57.7% text stream storage 72987552 bytes in 478411 claims
4.1% dictionary storage 5248000 bytes in 7557 claims
---- sorting 1448 bytes in 149 claims
5.4% source text 7200000 bytes in 3 claims
8.1% source text details 10800000 bytes in 2 claims
0.1% documentation fragments 262144 bytes in 1 claim
5.6% source text 7200000 bytes in 3 claims
8.5% source text details 10800000 bytes in 2 claims
0.2% documentation fragments 262144 bytes in 1 claim
---- linguistic stock array 81920 bytes in 2 claims
---- small word set array 105600 bytes in 22 claims
3.4% inter symbols storage 4520768 bytes in 27950 claims
12.6% inter bytecode storage 16767568 bytes in 14 claims
4.6% inter links storage 6222976 bytes in 11 claims
3.5% inter symbols storage 4520768 bytes in 27950 claims
13.2% inter bytecode storage 16767568 bytes in 14 claims
4.9% inter links storage 6222976 bytes in 11 claims
0.1% inter tree location list storage 191232 bytes in 32 claims
1.2% instance-of-kind counting 1700416 bytes in 1 claim
1.3% instance-of-kind counting 1700416 bytes in 1 claim
---- compilation workspace for objects 21896 bytes in 25 claims
---- lists for type-checking invocations 16000 bytes in 1 claim
---- code generation workspace for objects 1336 bytes in 4 claims
0.2% emitter array storage 280288 bytes in 1999 claims
-139.-3% was overhead - -184753344 bytes = -180423K = -176 MB
-146.-1% was overhead - -184754088 bytes = -180423K = -176 MB

View file

@ -1,32 +1,33 @@
100.0% in inform7 run
71.7% in compilation to Inter
50.4% in //Sequence::undertake_queued_tasks//
4.7% in //MajorNodes::pre_pass//
71.0% in compilation to Inter
50.0% in //Sequence::undertake_queued_tasks//
4.8% in //MajorNodes::pre_pass//
3.5% in //MajorNodes::pass_1//
2.4% in //RTPhrasebook::compile_entries//
1.8% in //ImperativeDefinitions::assess_all//
1.4% in //RTKindConstructors::compile//
1.0% in //Sequence::lint_inter//
0.6% in //MajorNodes::pass_2//
0.6% in //World::stage_V//
0.4% in //ImperativeDefinitions::compile_first_block//
0.4% in //Sequence::undertake_queued_tasks//
0.4% in //Sequence::undertake_queued_tasks//
0.2% in //CompletionModule::compile//
0.2% in //InferenceSubjects::emit_all//
0.2% in //RTKindConstructors::compile_permissions//
0.2% in //Task::make_built_in_kind_constructors//
2.9% not specifically accounted for
25.5% in running Inter pipeline
1.9% in //RTPhrasebook::compile_entries//
1.7% in //ImperativeDefinitions::assess_all//
1.3% in //RTKindConstructors::compile//
1.1% in //Sequence::lint_inter//
0.5% in //MajorNodes::pass_2//
0.5% in //Sequence::undertake_queued_tasks//
0.5% in //World::stage_V//
0.3% in //ImperativeDefinitions::compile_first_block//
0.3% in //Sequence::undertake_queued_tasks//
0.1% in //CompletionModule::compile//
0.1% in //InferenceSubjects::emit_all//
0.1% in //RTKindConstructors::compile_permissions//
0.1% in //Task::make_built_in_kind_constructors//
0.1% in //World::stages_II_and_III//
2.8% not specifically accounted for
26.2% in running Inter pipeline
9.9% in step 14/15: generate inform6 -> auto.inf
5.6% in step 5/15: load-binary-kits
5.3% in step 6/15: make-synoptic-module
1.4% in step 9/15: make-identifiers-unique
0.4% in step 12/15: eliminate-redundant-operations
0.4% in step 4/15: compile-splats
0.4% in step 7/15: shorten-wiring
0.2% in step 11/15: eliminate-redundant-labels
0.2% in step 8/15: detect-indirect-calls
1.5% not specifically accounted for
2.2% in supervisor
0.5% not specifically accounted for
5.8% in step 5/15: load-binary-kits
5.6% in step 6/15: make-synoptic-module
1.3% in step 9/15: make-identifiers-unique
0.3% in step 12/15: eliminate-redundant-operations
0.3% in step 4/15: compile-splats
0.3% in step 7/15: shorten-wiring
0.3% in step 8/15: detect-indirect-calls
0.1% in step 11/15: eliminate-redundant-labels
1.6% not specifically accounted for
2.5% in supervisor
0.2% not specifically accounted for

View file

@ -10,7 +10,8 @@
?"has-priority": number,
?"provides-kinds": [ string* ],
?"defines-Main": boolean,
?"indexes-with-structure": string
?"indexes-with-structure": string,
?"inserts-source-text": string
}
<extension-metadata> ::= {

View file

@ -33,14 +33,14 @@ void SourceProblems::issue_problems_arising(inbuild_copy *C) {
"Specifically, %2.");
Problems::issue_problem_end();
break;
case KIT_MISWORDED_CE:
case METADATA_MALFORMED_CE:
Problems::quote_work(1, CE->copy->found_by->work);
Problems::quote_stream(2, CE->details);
Problems::quote_stream(3, CE->copy->edition->work->genre->genre_name);
StandardProblems::handmade_problem(Task::syntax_tree(), _p_(Untestable));
Problems::issue_problem_segment(
"The kit %1, which your source text makes use of, seems to be "
"damaged or incorrect: its identifying opening line is wrong. "
"Specifically, %2.");
"The %3 %1, which your source text makes use of, seems to have "
"metadata problems. Specifically: %2.");
Problems::issue_problem_end();
break;
case EXT_TITLE_TOO_LONG_CE: {

81
working_notes.md Normal file
View file

@ -0,0 +1,81 @@
# Ongoing work: a few notes
This rudimentary blog-like page is to provide brief notes on changes to the
Inform code base made between formal releases, and is only likely to be useful
to people experimenting with unreleased builds of Inform.
## Current status
The next formal release is v10.1.0. We are coming to the end of the beta period
for that, and are concentrating on bug fixes, improvements to compatibility
with old extensions, and making sure that concepts being introduced by 10.1
are set up in a way we can live with. Work also continues on the GUI apps,
notably the MacOS app, which is being modernised to support Dark Mode.
## News items
### Kit metadata respecified as JSON (4 June 2022)
Kits are new in 10.1, and are documented in the Inbuild manual, which has been
rewritten today: see [A Guide to Kits](https://ganelson.github.io/inform/inbuild/M-agtk.html)
The change today is that the "kit_metadata.txt" file has now changed format and
name, to become "kit_metadata.json". This JSON format is a work in progress and
is likely to become a uniform way to describe resources used by Inbuild (extensions,
language bundles, interpreters, website templates, and so on): the point of having
such a format is to prepare the way for Inbuild to understand remote resources
somewhere on the Internet. For now JSON metadata files exist only for kits, but
some of the plumbing has been put in for general resources to have them.
This required new APIs in the foundation library at the Inweb repository to
read, write and validate JSON files: see the new section [JSON](https://ganelson.github.io/inweb/foundation-module/4-jsn.html).
You'll therefore need to pull the latest Inweb in order to build the latest Inform.
The current set of requirements for what Inbuild will read as resource metadata is
at [inform7/Internal/Miscellany/metadata.jsonr]. There are also a few semantic
constraints: see [JSON Metadata](https://ganelson.github.io/inform/supervisor-module/2-jm.html)
### Versioning policy for the built-in kits (4 June 2022)
There are currently five kits supplied in the Inform installation:
WorldModelKit
EnglishLanguageKit
CommandParserKit
BasicInformKit
BasicInformExtrasKit
Up to now these had no version numbers, but we want to encourage all kits to
have semantic version numbers, so we should comply with that ourselves.
In practice these kits are tightly coupled to the main compiler: (a) many bug fixes
in Inform which users think of as compiler fixes are in fact changes to these kits;
and (b) in normal circumstances people will never want to use the kits from one
build with the compiler from another. So the most useful way to describe the version
of a built-in kit is to identify which compiler release it came with.
As a policy decision, the version numbers of these five kits are therefore going
to be the same as those of the main compiler. (Today, that's "10.1.0-beta+6V21".)
This is enforced by changes to the makescript used when updating the main compiler's
version number, which uses a new feature |-sync-kit-versions| of the Inpolicy tool.
For its implementation, see: [[Kit Versioning](https://ganelson.github.io/inform/inpolicy/2-kv.html)
User-written kits not included in the Inform installation should not do this.
They won't be tied to particular compiler releases, and should have their own
semantic version numbers reflecting their own history of development.
### Incorporation of "6M62 Patches" (31 May 2022)
In recent years Inform users have been keeping an extension called "6M62 Patches",
which contained a small selection of bug fixes to the template files of Inform 6
code in build 6M62 (i.e., Inform version 9.3). Those template files have now
become kits, the Inform 6 code has become Inter code, and changes to the way the
"Include..." sentence works mean that "6M62 Patches" is not compatible with v10.1.
It would be easy enough to fix that, but there is now no need: all bug fixes
in "6M62 Patches" have been adopted in the kits for v10.1. Any old project which
included "6M62 Patches" can now stop doing so.
It was a real public service to create and maintain "6M62 Patches", and we thank
everyone who contributed to it: their work lives on.