1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-05 16:44:21 +03:00
inform7/docs/inbuild-module/4-em.html
2020-03-26 19:22:26 +00:00

379 lines
46 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>4/km</title>
<meta name="viewport" content="width=device-width initial-scale=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="../inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<nav role="navigation">
<h1><a href="../webs.html">Sources</a></h1>
<ul>
<li><a href="../compiler.html"><b>compiler</b></a></li>
<li><a href="../other.html">other tools</a></li>
<li><a href="../extensions.html">extensions and kits</a></li>
<li><a href="../units.html">unit test tools</a></li>
</ul>
<h2>Compiler Webs</h2>
<ul>
<li><a href="../inbuild/index.html">inbuild</a></li>
<li><a href="../inform7/index.html">inform7</a></li>
<li><a href="../inter/index.html">inter</a></li>
</ul>
<h2>Inbuild Modules</h2>
<ul>
<li><a href="../inbuild-module/index.html">inbuild</a></li>
<li><a href="../arch-module/index.html">arch</a></li>
<li><a href="../words-module/index.html">words</a></li>
<li><a href="../syntax-module/index.html">syntax</a></li>
<li><a href="../html-module/index.html">html</a></li>
</ul>
<h2>Inform7 Modules</h2>
<ul>
<li><a href="../core-module/index.html">core</a></li>
<li><a href="../problems-module/index.html">problems</a></li>
<li><a href="../inflections-module/index.html">inflections</a></li>
<li><a href="../linguistics-module/index.html">linguistics</a></li>
<li><a href="../kinds-module/index.html">kinds</a></li>
<li><a href="../if-module/index.html">if</a></li>
<li><a href="../multimedia-module/index.html">multimedia</a></li>
<li><a href="../index-module/index.html">index</a></li>
</ul>
<h2>Inter Modules</h2>
<ul>
<li><a href="../inter-module/index.html">inter</a></li>
<li><a href="../building-module/index.html">building</a></li>
<li><a href="../codegen-module/index.html">codegen</a></li>
</ul>
<h2>Foundation</h2>
<ul>
<li><a href="../../../inweb/docs/foundation-module/index.html">foundation</a></li>
</ul>
</nav>
<main role="main">
<!--Weave of '4/em' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">Source</a></li><li><a href="../compiler.html">Compiler Modules</a></li><li><a href="index.html">inbuild</a></li><li><a href="index.html#4">Chapter 4: Managing Genres of Work</a></li><li><b>Extension Manager</b></li></ul><p class="purpose">An Inform 7 extension.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Genre definition</a></li><li><a href="#SP6">&#167;6. Claiming</a></li><li><a href="#SP7">&#167;7. Searching</a></li><li><a href="#SP8">&#167;8. Copying</a></li><li><a href="#SP9">&#167;9. Build graph</a></li><li><a href="#SP10">&#167;10. Source text</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Genre definition. </b></p>
<pre class="display">
<span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">extension_genre</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>An extension has a title and an author name, each of which is limited in
length to one character less than the following constants:
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">MAX_EXTENSION_TITLE_LENGTH</span><span class="plain"> 51</span>
<span class="definitionkeyword">define</span> <span class="constant">MAX_EXTENSION_AUTHOR_LENGTH</span><span class="plain"> 51</span>
</pre>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">ExtensionManager::start</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">extension_genre</span><span class="plain"> = </span><span class="functiontext">Genres::new</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"extension"</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">extension_genre</span><span class="plain">, </span><span class="constant">GENRE_WRITE_WORK_MTID</span><span class="plain">, </span><span class="functiontext">ExtensionManager::write_work</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">extension_genre</span><span class="plain">, </span><span class="constant">GENRE_CLAIM_AS_COPY_MTID</span><span class="plain">, </span><span class="functiontext">ExtensionManager::claim_as_copy</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">extension_genre</span><span class="plain">, </span><span class="constant">GENRE_SCAN_COPY_MTID</span><span class="plain">, </span><span class="functiontext">Extensions::scan</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">extension_genre</span><span class="plain">, </span><span class="constant">GENRE_SEARCH_NEST_FOR_MTID</span><span class="plain">, </span><span class="functiontext">ExtensionManager::search_nest_for</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">extension_genre</span><span class="plain">, </span><span class="constant">GENRE_COPY_TO_NEST_MTID</span><span class="plain">, </span><span class="functiontext">ExtensionManager::copy_to_nest</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">extension_genre</span><span class="plain">, </span><span class="constant">GENRE_READ_SOURCE_TEXT_FOR_MTID</span><span class="plain">, </span><span class="functiontext">ExtensionManager::read_source_text_for</span><span class="plain">);</span>
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">extension_genre</span><span class="plain">, </span><span class="constant">GENRE_BUILD_COPY_MTID</span><span class="plain">, </span><span class="functiontext">ExtensionManager::build</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">ExtensionManager::write_work</span><span class="plain">(</span><span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">gen</span><span class="plain">, </span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">inbuild_work</span><span class="plain"> *</span><span class="identifier">work</span><span class="plain">) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%X"</span><span class="plain">, </span><span class="identifier">work</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function ExtensionManager::start is used in 1/im (<a href="1-im.html#SP3">&#167;3</a>).</p>
<p class="endnote">The function ExtensionManager::write_work appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>Extensions live in their namesake subdirectory of a nest:
</p>
<pre class="display">
<span class="identifier">pathname</span><span class="plain"> *</span><span class="functiontext">ExtensionManager::path_within_nest</span><span class="plain">(</span><span class="reserved">inbuild_nest</span><span class="plain"> *</span><span class="identifier">N</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">N</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"no nest"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">Pathnames::subfolder</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">-</span><span class="element">&gt;location</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Extensions"</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function ExtensionManager::path_within_nest is used in <a href="#SP7">&#167;7</a>, <a href="#SP8">&#167;8</a>, 5/ec (<a href="5-ec.html#SP1">&#167;1</a>, <a href="5-ec.html#SP6_7_4_3">&#167;6.7.4.3</a>).</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b>Extension copies are annotated with a structure called an <code class="display"><span class="extract">inform_extension</span></code>,
which stores data about extensions used by the Inform compiler.
</p>
<pre class="display">
<span class="reserved">inform_extension</span><span class="plain"> *</span><span class="functiontext">ExtensionManager::from_copy</span><span class="plain">(</span><span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">C</span><span class="plain">) &amp;&amp; (</span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;edition</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">-</span><span class="element">&gt;genre</span><span class="plain"> == </span><span class="identifier">extension_genre</span><span class="plain">)) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">RETRIEVE_POINTER_inform_extension</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;content</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">dictionary</span><span class="plain"> *</span><span class="identifier">ext_copy_cache</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="functiontext">ExtensionManager::new_copy</span><span class="plain">(</span><span class="identifier">filename</span><span class="plain"> *</span><span class="identifier">F</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ext_copy_cache</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">ext_copy_cache</span><span class="plain"> = </span><span class="identifier">Dictionaries::new</span><span class="plain">(16, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">key</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">key</span><span class="plain">, </span><span class="string">"%f"</span><span class="plain">, </span><span class="identifier">F</span><span class="plain">);</span>
<span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Dictionaries::find</span><span class="plain">(</span><span class="identifier">ext_copy_cache</span><span class="plain">, </span><span class="identifier">key</span><span class="plain">))</span>
<span class="identifier">C</span><span class="plain"> = </span><span class="identifier">Dictionaries::read_value</span><span class="plain">(</span><span class="identifier">ext_copy_cache</span><span class="plain">, </span><span class="identifier">key</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">C</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
<span class="identifier">C</span><span class="plain"> = </span><span class="functiontext">Copies::new_in_file</span><span class="plain">(</span>
<span class="functiontext">Editions::new</span><span class="plain">(</span><span class="functiontext">Works::new</span><span class="plain">(</span><span class="identifier">extension_genre</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Untitled"</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Anonymous"</span><span class="plain">),</span>
<span class="identifier">VersionNumbers::null</span><span class="plain">()), </span><span class="identifier">F</span><span class="plain">, </span><span class="identifier">NULL_GENERAL_POINTER</span><span class="plain">);</span>
<span class="functiontext">Copies::scan</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Works::is_standard_rules</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;edition</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">))</span>
<span class="functiontext">Extensions::make_standard</span><span class="plain">(</span><span class="functiontext">ExtensionManager::from_copy</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">));</span>
<span class="identifier">Dictionaries::create</span><span class="plain">(</span><span class="identifier">ext_copy_cache</span><span class="plain">, </span><span class="identifier">key</span><span class="plain">);</span>
<span class="identifier">Dictionaries::write_value</span><span class="plain">(</span><span class="identifier">ext_copy_cache</span><span class="plain">, </span><span class="identifier">key</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">key</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">C</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function ExtensionManager::from_copy is used in <a href="#SP9">&#167;9</a>, <a href="#SP10">&#167;10</a>, 5/es (<a href="5-es.html#SP5">&#167;5</a>), 5/ed2 (<a href="5-ed2.html#SP4">&#167;4</a>), 5/ec (<a href="5-ec.html#SP2">&#167;2</a>), 6/st (<a href="6-st.html#SP11">&#167;11</a>), 6/inc (<a href="6-inc.html#SP6_1">&#167;6.1</a>).</p>
<p class="endnote">The function ExtensionManager::new_copy is used in <a href="#SP6">&#167;6</a>.</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. Claiming. </b>Here <code class="display"><span class="extract">arg</span></code> is a textual form of a filename or pathname, such as may have been
supplied at the command line; <code class="display"><span class="extract">ext</span></code> is a substring of it, and is its extension
(e.g., <code class="display"><span class="extract">jpg</span></code> if <code class="display"><span class="extract">arg</span></code> is <code class="display"><span class="extract">Geraniums.jpg</span></code>), or is empty if there isn't one;
<code class="display"><span class="extract">directory_status</span></code> is true if we know for some reason that this is a directory
not a file, false if we know the reverse, and otherwise not applicable.
</p>
<p class="inwebparagraph">An extension, for us, needs to be a file with extension <code class="display"><span class="extract">i7x</span></code>, but it needs
also to scan properly &mdash; which means the top line of the file has to be right.
So we'll open it and look.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">ExtensionManager::claim_as_copy</span><span class="plain">(</span><span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">gen</span><span class="plain">, </span><span class="reserved">inbuild_copy</span><span class="plain"> **</span><span class="identifier">C</span><span class="plain">,</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">arg</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">ext</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">directory_status</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">directory_status</span><span class="plain"> == </span><span class="identifier">TRUE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::eq_insensitive</span><span class="plain">(</span><span class="identifier">ext</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"i7x"</span><span class="plain">)) {</span>
<span class="identifier">filename</span><span class="plain"> *</span><span class="identifier">F</span><span class="plain"> = </span><span class="identifier">Filenames::from_text</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">);</span>
<span class="plain">*</span><span class="identifier">C</span><span class="plain"> = </span><span class="functiontext">ExtensionManager::claim_file_as_copy</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="functiontext">ExtensionManager::claim_file_as_copy</span><span class="plain">(</span><span class="identifier">filename</span><span class="plain"> *</span><span class="identifier">F</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">TextFiles::exists</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain"> = </span><span class="functiontext">ExtensionManager::new_copy</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">);</span>
<span class="functiontext">ExtensionManager::build_vertex</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">);</span>
<span class="functiontext">Works::add_to_database</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;edition</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">, </span><span class="constant">CLAIMED_WDBC</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">C</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function ExtensionManager::claim_as_copy is used in <a href="#SP3">&#167;3</a>.</p>
<p class="endnote">The function ExtensionManager::claim_file_as_copy is used in <a href="#SP7">&#167;7</a>.</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. Searching. </b>Here we look through a nest to find all extensions matching the supplied
requirements.
</p>
<p class="inwebparagraph">For efficiency's sake, since the nest could contain many hundreds of
extensions, we narrow down to the author's subfolder if a specific
author is required.
</p>
<p class="inwebparagraph">Nobody should any longer be storing extension files without the file
extension <code class="display"><span class="extract">.i7x</span></code>, but this was allowed in the early days of Inform 7,
so we'll quietly allow for it.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">ExtensionManager::search_nest_for</span><span class="plain">(</span><span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">gen</span><span class="plain">, </span><span class="reserved">inbuild_nest</span><span class="plain"> *</span><span class="identifier">N</span><span class="plain">,</span>
<span class="reserved">inbuild_requirement</span><span class="plain"> *</span><span class="identifier">req</span><span class="plain">, </span><span class="identifier">linked_list</span><span class="plain"> *</span><span class="identifier">search_results</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">req</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">-</span><span class="element">&gt;genre</span><span class="plain">) &amp;&amp; (</span><span class="identifier">req</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">-</span><span class="element">&gt;genre</span><span class="plain"> != </span><span class="identifier">extension_genre</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain"> = </span><span class="functiontext">ExtensionManager::path_within_nest</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">req</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">-</span><span class="element">&gt;author_name</span><span class="plain">) &gt; 0) {</span>
<span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">Q</span><span class="plain"> = </span><span class="identifier">Pathnames::subfolder</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">req</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">-</span><span class="element">&gt;author_name</span><span class="plain">);</span>
<span class="functiontext">ExtensionManager::search_nest_for_r</span><span class="plain">(</span><span class="identifier">Q</span><span class="plain">, </span><span class="identifier">N</span><span class="plain">, </span><span class="identifier">req</span><span class="plain">, </span><span class="identifier">search_results</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="functiontext">ExtensionManager::search_nest_for_r</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">N</span><span class="plain">, </span><span class="identifier">req</span><span class="plain">, </span><span class="identifier">search_results</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">ExtensionManager::search_nest_for_r</span><span class="plain">(</span><span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain">, </span><span class="reserved">inbuild_nest</span><span class="plain"> *</span><span class="identifier">N</span><span class="plain">,</span>
<span class="reserved">inbuild_requirement</span><span class="plain"> *</span><span class="identifier">req</span><span class="plain">, </span><span class="identifier">linked_list</span><span class="plain"> *</span><span class="identifier">search_results</span><span class="plain">) {</span>
<span class="identifier">scan_directory</span><span class="plain"> *</span><span class="identifier">D</span><span class="plain"> = </span><span class="identifier">Directories::open</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">D</span><span class="plain">) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">LEAFNAME</span><span class="plain">);</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">Directories::next</span><span class="plain">(</span><span class="identifier">D</span><span class="plain">, </span><span class="identifier">LEAFNAME</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::get_last_char</span><span class="plain">(</span><span class="identifier">LEAFNAME</span><span class="plain">) == </span><span class="identifier">FOLDER_SEPARATOR</span><span class="plain">) {</span>
<span class="identifier">Str::delete_last_character</span><span class="plain">(</span><span class="identifier">LEAFNAME</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::ne</span><span class="plain">(</span><span class="identifier">LEAFNAME</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Reserved"</span><span class="plain">)) {</span>
<span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">Q</span><span class="plain"> = </span><span class="identifier">Pathnames::subfolder</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">LEAFNAME</span><span class="plain">);</span>
<span class="functiontext">ExtensionManager::search_nest_for_r</span><span class="plain">(</span><span class="identifier">Q</span><span class="plain">, </span><span class="identifier">N</span><span class="plain">, </span><span class="identifier">req</span><span class="plain">, </span><span class="identifier">search_results</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">filename</span><span class="plain"> *</span><span class="identifier">F</span><span class="plain"> = </span><span class="identifier">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">LEAFNAME</span><span class="plain">);</span>
<span class="functiontext">ExtensionManager::search_nest_for_single_file</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">, </span><span class="identifier">N</span><span class="plain">, </span><span class="identifier">req</span><span class="plain">, </span><span class="identifier">search_results</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">LEAFNAME</span><span class="plain">);</span>
<span class="identifier">Directories::close</span><span class="plain">(</span><span class="identifier">D</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">ExtensionManager::search_nest_for_single_file</span><span class="plain">(</span><span class="identifier">filename</span><span class="plain"> *</span><span class="identifier">F</span><span class="plain">, </span><span class="reserved">inbuild_nest</span><span class="plain"> *</span><span class="identifier">N</span><span class="plain">,</span>
<span class="reserved">inbuild_requirement</span><span class="plain"> *</span><span class="identifier">req</span><span class="plain">, </span><span class="identifier">linked_list</span><span class="plain"> *</span><span class="identifier">search_results</span><span class="plain">) {</span>
<span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain"> = </span><span class="functiontext">ExtensionManager::claim_file_as_copy</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">C</span><span class="plain">) &amp;&amp; (</span><span class="functiontext">Requirements::meets</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;edition</span><span class="plain">, </span><span class="identifier">req</span><span class="plain">))) {</span>
<span class="functiontext">Nests::add_search_result</span><span class="plain">(</span><span class="identifier">search_results</span><span class="plain">, </span><span class="identifier">N</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">req</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function ExtensionManager::search_nest_for is used in <a href="#SP3">&#167;3</a>.</p>
<p class="endnote">The function ExtensionManager::search_nest_for_r appears nowhere else.</p>
<p class="endnote">The function ExtensionManager::search_nest_for_single_file appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. Copying. </b>Now the task is to copy an extension into place in a nest. This is easy,
since an extension is a single file; to sync, we just overwrite.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">ExtensionManager::copy_to_nest</span><span class="plain">(</span><span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">gen</span><span class="plain">, </span><span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain">, </span><span class="reserved">inbuild_nest</span><span class="plain"> *</span><span class="identifier">N</span><span class="plain">,</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">syncing</span><span class="plain">, </span><span class="reserved">build_methodology</span><span class="plain"> *</span><span class="identifier">meth</span><span class="plain">) {</span>
<span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">E</span><span class="plain"> = </span><span class="functiontext">ExtensionManager::path_within_nest</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">);</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">leaf</span><span class="plain">);</span>
<span class="functiontext">Editions::write_canonical_leaf</span><span class="plain">(</span><span class="identifier">leaf</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;edition</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">leaf</span><span class="plain">, </span><span class="string">".i7x"</span><span class="plain">);</span>
<span class="identifier">filename</span><span class="plain"> *</span><span class="identifier">F</span><span class="plain"> = </span><span class="identifier">Filenames::in_folder</span><span class="plain">(</span>
<span class="identifier">Pathnames::subfolder</span><span class="plain">(</span><span class="identifier">E</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;edition</span><span class="plain">-</span><span class="element">&gt;work</span><span class="plain">-</span><span class="element">&gt;author_name</span><span class="plain">), </span><span class="identifier">leaf</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">leaf</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">TextFiles::exists</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">syncing</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) { </span><span class="functiontext">Nests::overwrite_error</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">; }</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">meth</span><span class="plain">-</span><span class="element">&gt;methodology</span><span class="plain"> == </span><span class="constant">DRY_RUN_METHODOLOGY</span><span class="plain">) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="string">"mkdir -p "</span><span class="plain">);</span>
<span class="identifier">Shell::quote_path</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="identifier">Filenames::get_path_to</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">));</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">STDOUT</span><span class="plain">, </span><span class="string">"%S\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">command</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Pathnames::create_in_file_system</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">-</span><span class="element">&gt;location</span><span class="plain">);</span>
<span class="identifier">Pathnames::create_in_file_system</span><span class="plain">(</span><span class="identifier">Pathnames::subfolder</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">-</span><span class="element">&gt;location</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Extensions"</span><span class="plain">));</span>
<span class="identifier">Pathnames::create_in_file_system</span><span class="plain">(</span><span class="identifier">Filenames::get_path_to</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">));</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="string">"cp -f "</span><span class="plain">);</span>
<span class="identifier">Shell::quote_file</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;location_if_file</span><span class="plain">);</span>
<span class="identifier">Shell::quote_file</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="identifier">F</span><span class="plain">);</span>
<span class="functiontext">BuildSteps::shell</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="identifier">meth</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function ExtensionManager::copy_to_nest is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. Build graph. </b>As far as building goes, the build graph for an extension is just a single node:
you don't need to build an extension at all. But it may well have use edges,
thanks to including other extensions, and because of that we have to read the
source text before we can do anything with the graph.
</p>
<p class="inwebparagraph">We don't do this at the going operational stage because that would be
inefficient and might cause VM-related problems &mdash; it would mean that many
extraneous extensions, discovered only when scanning some directory, would
be read in as source text; and some of those might not be compatible with
the current VM settings.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">ExtensionManager::build</span><span class="plain">(</span><span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">gen</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">OUT</span><span class="plain">, </span><span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain">,</span>
<span class="reserved">build_methodology</span><span class="plain"> *</span><span class="identifier">BM</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">build</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">rebuild</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">describe_only</span><span class="plain">) {</span>
<span class="functiontext">ExtensionManager::ensure_graphed</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">describe_only</span><span class="plain">) </span><span class="functiontext">Graphs::describe</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;vertex</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rebuild</span><span class="plain">) </span><span class="functiontext">Graphs::rebuild</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;vertex</span><span class="plain">, </span><span class="identifier">BM</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">build</span><span class="plain">) </span><span class="functiontext">Graphs::build</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;vertex</span><span class="plain">, </span><span class="identifier">BM</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">ExtensionManager::ensure_graphed</span><span class="plain">(</span><span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain">) {</span>
<span class="functiontext">Copies::read_source_text_for</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">);</span>
<span class="functiontext">Inclusions::traverse</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="functiontext">ExtensionManager::from_copy</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">)-</span><span class="element">&gt;syntax_tree</span><span class="plain">);</span>
<span class="reserved">build_vertex</span><span class="plain"> *</span><span class="identifier">V</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">, </span><span class="reserved">build_vertex</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;vertex</span><span class="plain">-</span><span class="element">&gt;use_edges</span><span class="plain">)</span>
<span class="functiontext">ExtensionManager::ensure_graphed</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">-</span><span class="element">&gt;buildable_if_copy</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">ExtensionManager::build_vertex</span><span class="plain">(</span><span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain">) {</span>
<span class="functiontext">Graphs::copy_vertex</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function ExtensionManager::build is used in <a href="#SP3">&#167;3</a>.</p>
<p class="endnote">The function ExtensionManager::ensure_graphed appears nowhere else.</p>
<p class="endnote">The function ExtensionManager::build_vertex is used in <a href="#SP6">&#167;6</a>.</p>
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. Source text. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">ExtensionManager::read_source_text_for</span><span class="plain">(</span><span class="reserved">inbuild_genre</span><span class="plain"> *</span><span class="identifier">G</span><span class="plain">, </span><span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain">) {</span>
<span class="functiontext">Extensions::read_source_text_for</span><span class="plain">(</span><span class="functiontext">ExtensionManager::from_copy</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">));</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function ExtensionManager::read_source_text_for is used in <a href="#SP3">&#167;3</a>.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="4-km.html">Back to 'Kit Manager'</a></li><li><a href="4-lm.html">Continue with 'Language Manager'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</main>
</body>
</html>