1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-08 18:14:21 +03:00
inform7/docs/inbuild-module/1-ic.html

796 lines
101 KiB
HTML
Raw Normal View History

2020-02-27 13:18:25 +02:00
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>1/im</title>
<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>
<!--Weave of '1/ic' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">inbuild</a></li><li><a href="index.html#1">Chapter 1: Setting Up</a></li><li><b>Inbuild Control</b></li></ul><p class="purpose">The top-level controller through which client tools use this module.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Phases</a></li><li><a href="#SP5">&#167;5. The nest list</a></li><li><a href="#SP10">&#167;10. The shared project</a></li><li><a href="#SP14">&#167;14. Kit requests</a></li><li><a href="#SP15">&#167;15. Installation</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Phases. </b>Although nothing at all clever happens in this section, it requires careful
sequencing to avoid invisible errors coming in because function X assumes
that function Y has already been called, or perhaos that it never will
be again. The client tool ("the tool") has to work in the following way
to avoid those problems.
</p>
<p class="inwebparagraph">Firstly, the inbuild module runs through the following phases in sequence:
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">CONFIGURATION_INBUILD_PHASE</span><span class="definitionkeyword"> from </span><span class="constant">1</span>
<span class="definitionkeyword">enum</span> <span class="constant">PRETINKERING_INBUILD_PHASE</span>
<span class="definitionkeyword">enum</span> <span class="constant">TINKERING_INBUILD_PHASE</span>
<span class="definitionkeyword">enum</span> <span class="constant">NESTED_INBUILD_PHASE</span>
<span class="definitionkeyword">enum</span> <span class="constant">PROJECTED_INBUILD_PHASE</span>
<span class="definitionkeyword">enum</span> <span class="constant">GOING_OPERATIONAL_INBUILD_PHASE</span>
<span class="definitionkeyword">enum</span> <span class="constant">OPERATIONAL_INBUILD_PHASE</span>
</pre>
<pre class="display">
<span class="definitionkeyword">define</span> <span class="identifier">RUN_ONLY_IN_PHASE</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">inbuild_phase</span><span class="plain"> &lt; </span><span class="identifier">P</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"too soon"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">inbuild_phase</span><span class="plain"> &gt; </span><span class="identifier">P</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"too late"</span><span class="plain">);</span>
<span class="definitionkeyword">define</span> <span class="identifier">RUN_ONLY_FROM_PHASE</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">inbuild_phase</span><span class="plain"> &lt; </span><span class="identifier">P</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"too soon"</span><span class="plain">);</span>
<span class="definitionkeyword">define</span> <span class="identifier">RUN_ONLY_BEFORE_PHASE</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">inbuild_phase</span><span class="plain"> &gt;= </span><span class="identifier">P</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"too late"</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">inbuild_phase</span><span class="plain"> = </span><span class="constant">CONFIGURATION_INBUILD_PHASE</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>Initially, then, we are in the configuration phase. This is when command
line processing should be done, and the tool should use the following routines
to add and process command line switches handled by inbuild:
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">INBUILD_INFORM_CLSG</span>
<span class="definitionkeyword">enum</span> <span class="constant">INBUILD_RESOURCES_CLSG</span>
<span class="definitionkeyword">enum</span> <span class="constant">INBUILD_INTER_CLSG</span>
<span class="definitionkeyword">enum</span> <span class="constant">INBUILD_CLSG</span>
<span class="definitionkeyword">enum</span> <span class="constant">NEST_CLSW</span>
<span class="definitionkeyword">enum</span> <span class="constant">INTERNAL_CLSW</span>
<span class="definitionkeyword">enum</span> <span class="constant">EXTERNAL_CLSW</span>
<span class="definitionkeyword">enum</span> <span class="constant">TRANSIENT_CLSW</span>
<span class="definitionkeyword">enum</span> <span class="constant">KIT_CLSW</span>
<span class="definitionkeyword">enum</span> <span class="constant">PROJECT_CLSW</span>
<span class="definitionkeyword">enum</span> <span class="constant">SOURCE_CLSW</span>
<span class="definitionkeyword">enum</span> <span class="constant">DEBUG_CLSW</span>
<span class="definitionkeyword">enum</span> <span class="constant">FORMAT_CLSW</span>
<span class="definitionkeyword">enum</span> <span class="constant">RELEASE_CLSW</span>
<span class="definitionkeyword">enum</span> <span class="constant">CENSUS_CLSW</span>
<span class="definitionkeyword">enum</span> <span class="constant">PIPELINE_CLSW</span>
<span class="definitionkeyword">enum</span> <span class="constant">PIPELINE_FILE_CLSW</span>
<span class="definitionkeyword">enum</span> <span class="constant">PIPELINE_VARIABLE_CLSW</span>
<span class="definitionkeyword">enum</span> <span class="constant">RNG_CLSW</span>
<span class="definitionkeyword">enum</span> <span class="constant">CASE_CLSW</span>
</pre>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Inbuild::declare_options</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">RUN_ONLY_IN_PHASE</span><span class="plain">(</span><span class="constant">CONFIGURATION_INBUILD_PHASE</span><span class="plain">)</span>
<span class="identifier">CommandLine::begin_group</span><span class="plain">(</span><span class="constant">INBUILD_INFORM_CLSG</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"for translating Inform source text to Inter"</span><span class="plain">);</span>
<span class="identifier">CommandLine::declare_switch</span><span class="plain">(</span><span class="constant">PROJECT_CLSW</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"project"</span><span class="plain">, 2,</span>
<span class="identifier">L</span><span class="string">"work within the Inform project X"</span><span class="plain">);</span>
<span class="identifier">CommandLine::declare_boolean_switch</span><span class="plain">(</span><span class="constant">DEBUG_CLSW</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"debug"</span><span class="plain">, 1,</span>
<span class="identifier">L</span><span class="string">"compile with debugging features even on a Release"</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="identifier">CommandLine::declare_boolean_switch</span><span class="plain">(</span><span class="constant">RELEASE_CLSW</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"release"</span><span class="plain">, 1,</span>
<span class="identifier">L</span><span class="string">"compile a version suitable for a Release build"</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="identifier">CommandLine::declare_textual_switch</span><span class="plain">(</span><span class="constant">FORMAT_CLSW</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"format"</span><span class="plain">, 1,</span>
<span class="identifier">L</span><span class="string">"compile I6 code suitable for the virtual machine X"</span><span class="plain">);</span>
<span class="identifier">CommandLine::declare_switch</span><span class="plain">(</span><span class="constant">SOURCE_CLSW</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"source"</span><span class="plain">, 2,</span>
<span class="identifier">L</span><span class="string">"use file X as the Inform source text"</span><span class="plain">);</span>
<span class="identifier">CommandLine::declare_boolean_switch</span><span class="plain">(</span><span class="constant">CENSUS_CLSW</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"census"</span><span class="plain">, 1,</span>
<span class="identifier">L</span><span class="string">"perform an extensions census"</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="identifier">CommandLine::declare_boolean_switch</span><span class="plain">(</span><span class="constant">RNG_CLSW</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"rng"</span><span class="plain">, 1,</span>
<span class="identifier">L</span><span class="string">"fix the random number generator of the story file (for testing)"</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="identifier">CommandLine::declare_switch</span><span class="plain">(</span><span class="constant">CASE_CLSW</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"case"</span><span class="plain">, 2,</span>
<span class="identifier">L</span><span class="string">"make any source links refer to the source in extension example X"</span><span class="plain">);</span>
<span class="identifier">CommandLine::end_group</span><span class="plain">();</span>
<span class="identifier">CommandLine::begin_group</span><span class="plain">(</span><span class="constant">INBUILD_RESOURCES_CLSG</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"for locating resources in the file system"</span><span class="plain">);</span>
<span class="identifier">CommandLine::declare_switch</span><span class="plain">(</span><span class="constant">NEST_CLSW</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"nest"</span><span class="plain">, 2,</span>
<span class="identifier">L</span><span class="string">"add the nest at pathname X to the search list"</span><span class="plain">);</span>
<span class="identifier">CommandLine::declare_switch</span><span class="plain">(</span><span class="constant">INTERNAL_CLSW</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"internal"</span><span class="plain">, 2,</span>
<span class="identifier">L</span><span class="string">"use X as the location of built-in material such as the Standard Rules"</span><span class="plain">);</span>
<span class="identifier">CommandLine::declare_switch</span><span class="plain">(</span><span class="constant">EXTERNAL_CLSW</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"external"</span><span class="plain">, 2,</span>
<span class="identifier">L</span><span class="string">"use X as the user's home for installed material such as extensions"</span><span class="plain">);</span>
<span class="identifier">CommandLine::declare_switch</span><span class="plain">(</span><span class="constant">TRANSIENT_CLSW</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"transient"</span><span class="plain">, 2,</span>
<span class="identifier">L</span><span class="string">"use X for transient data such as the extensions census"</span><span class="plain">);</span>
<span class="identifier">CommandLine::end_group</span><span class="plain">();</span>
<span class="identifier">CommandLine::begin_group</span><span class="plain">(</span><span class="constant">INBUILD_INTER_CLSG</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"for tweaking code generation from Inter"</span><span class="plain">);</span>
<span class="identifier">CommandLine::declare_switch</span><span class="plain">(</span><span class="constant">KIT_CLSW</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"kit"</span><span class="plain">, 2,</span>
<span class="identifier">L</span><span class="string">"include Inter code from the kit called X"</span><span class="plain">);</span>
<span class="identifier">CommandLine::declare_switch</span><span class="plain">(</span><span class="constant">PIPELINE_CLSW</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"pipeline"</span><span class="plain">, 2,</span>
<span class="identifier">L</span><span class="string">"specify code-generation pipeline"</span><span class="plain">);</span>
<span class="identifier">CommandLine::declare_switch</span><span class="plain">(</span><span class="constant">PIPELINE_FILE_CLSW</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"pipeline-file"</span><span class="plain">, 2,</span>
<span class="identifier">L</span><span class="string">"specify code-generation pipeline from file X"</span><span class="plain">);</span>
<span class="identifier">CommandLine::declare_switch</span><span class="plain">(</span><span class="constant">PIPELINE_VARIABLE_CLSW</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"variable"</span><span class="plain">, 2,</span>
<span class="identifier">L</span><span class="string">"set pipeline variable X (in form name=value)"</span><span class="plain">);</span>
<span class="identifier">CommandLine::end_group</span><span class="plain">();</span>
<span class="functiontext">Inbuild::set_defaults</span><span class="plain">();</span>
<span class="plain">}</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">inter_processing_file</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">inter_processing_pipeline</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">dictionary</span><span class="plain"> *</span><span class="identifier">pipeline_vars</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">shared_transient_resources</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">this_is_a_debug_compile</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">; </span> <span class="comment">Destined to be compiled with debug features</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">this_is_a_release_compile</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">; </span> <span class="comment">Omit sections of source text marked not for release</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">story_filename_extension</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span> <span class="comment">What story file we will eventually have</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">census_mode</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">; </span> <span class="comment">Running only to update extension documentation</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">rng_seed_at_start_of_play</span><span class="plain"> = 0; </span> <span class="comment">The seed value, or 0 if not seeded</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Inbuild::set_defaults</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">inter_processing_pipeline</span><span class="plain"> = </span><span class="identifier">Str::new</span><span class="plain">();</span>
<span class="identifier">inter_processing_file</span><span class="plain"> = </span><span class="identifier">I</span><span class="string">"compile"</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Inbuild::set_inter_pipeline</span><span class="plain">(</span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) {</span>
<span class="identifier">inter_processing_pipeline</span><span class="plain"> = </span><span class="identifier">Str::new</span><span class="plain">();</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">inter_processing_pipeline</span><span class="plain">, </span><span class="string">"%W"</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
<span class="identifier">Str::delete_first_character</span><span class="plain">(</span><span class="identifier">inter_processing_pipeline</span><span class="plain">);</span>
<span class="identifier">Str::delete_last_character</span><span class="plain">(</span><span class="identifier">inter_processing_pipeline</span><span class="plain">);</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Setting pipeline %S\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">inter_processing_pipeline</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Inbuild::option</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">id</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">val</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="reserved">void</span><span class="plain"> *</span><span class="identifier">state</span><span class="plain">) {</span>
<span class="identifier">RUN_ONLY_IN_PHASE</span><span class="plain">(</span><span class="constant">CONFIGURATION_INBUILD_PHASE</span><span class="plain">)</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">id</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">DEBUG_CLSW</span><span class="plain">: </span><span class="identifier">this_is_a_debug_compile</span><span class="plain"> = </span><span class="identifier">val</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">FORMAT_CLSW</span><span class="plain">: </span><span class="identifier">story_filename_extension</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">RELEASE_CLSW</span><span class="plain">: </span><span class="identifier">this_is_a_release_compile</span><span class="plain"> = </span><span class="identifier">val</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">NEST_CLSW</span><span class="plain">: </span><span class="functiontext">Inbuild::add_nest</span><span class="plain">(</span><span class="identifier">Pathnames::from_text</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">), </span><span class="constant">GENERIC_NEST_TAG</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">INTERNAL_CLSW</span><span class="plain">: </span><span class="functiontext">Inbuild::add_nest</span><span class="plain">(</span><span class="identifier">Pathnames::from_text</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">), </span><span class="constant">INTERNAL_NEST_TAG</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">EXTERNAL_CLSW</span><span class="plain">: </span><span class="functiontext">Inbuild::add_nest</span><span class="plain">(</span><span class="identifier">Pathnames::from_text</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">), </span><span class="constant">EXTERNAL_NEST_TAG</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">TRANSIENT_CLSW</span><span class="plain">: </span><span class="identifier">shared_transient_resources</span><span class="plain"> = </span><span class="identifier">Pathnames::from_text</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">KIT_CLSW</span><span class="plain">: </span><span class="functiontext">Inbuild::request_kit</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">PROJECT_CLSW</span><span class="plain">:</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Inbuild::set_I7_bundle</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">)</span>
<span class="identifier">Errors::fatal_with_text</span><span class="plain">(</span><span class="string">"can't specify the project twice: '%S'"</span><span class="plain">, </span><span class="identifier">arg</span><span class="plain">);</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">SOURCE_CLSW</span><span class="plain">:</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Inbuild::set_I7_source</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">)</span>
<span class="identifier">Errors::fatal_with_text</span><span class="plain">(</span><span class="string">"can't specify the source file twice: '%S'"</span><span class="plain">, </span><span class="identifier">arg</span><span class="plain">);</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">CENSUS_CLSW</span><span class="plain">: </span><span class="identifier">census_mode</span><span class="plain"> = </span><span class="identifier">val</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">PIPELINE_CLSW</span><span class="plain">: </span><span class="identifier">inter_processing_pipeline</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">PIPELINE_FILE_CLSW</span><span class="plain">: </span><span class="identifier">inter_processing_file</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">PIPELINE_VARIABLE_CLSW</span><span class="plain">: {</span>
<span class="identifier">match_results</span><span class="plain"> </span><span class="identifier">mr</span><span class="plain"> = </span><span class="identifier">Regexp::create_mr</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Regexp::match</span><span class="plain">(&amp;</span><span class="identifier">mr</span><span class="plain">, </span><span class="identifier">arg</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"(%c+)=(%c+)"</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::get_first_char</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">) != </span><span class="character">'*'</span><span class="plain">) {</span>
<span class="identifier">Errors::fatal</span><span class="plain">(</span><span class="string">"-variable names must begin with '*'"</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">CODEGEN_MODULE</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pipeline_vars</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)</span>
<span class="identifier">pipeline_vars</span><span class="plain"> = </span><span class="identifier">CodeGen::Pipeline::basic_dictionary</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"output.z8"</span><span class="plain">);</span>
<span class="identifier">Str::copy</span><span class="plain">(</span><span class="identifier">Dictionaries::create_text</span><span class="plain">(</span><span class="identifier">pipeline_vars</span><span class="plain">, </span><span class="identifier">mr</span><span class="plain">.</span><span class="identifier">exp</span><span class="plain">[0]), </span><span class="identifier">mr</span><span class="plain">.</span><span class="identifier">exp</span><span class="plain">[1]);</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="plain">}</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Errors::fatal</span><span class="plain">(</span><span class="string">"-variable should take the form 'name=value'"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">Regexp::dispose_of</span><span class="plain">(&amp;</span><span class="identifier">mr</span><span class="plain">);</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">RNG_CLSW</span><span class="plain">:</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">val</span><span class="plain">) </span><span class="identifier">rng_seed_at_start_of_play</span><span class="plain"> = -16339;</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">rng_seed_at_start_of_play</span><span class="plain"> = 0;</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">CASE_CLSW</span><span class="plain">: </span><span class="identifier">HTMLFiles::set_source_link_case</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Inbuild::declare_options appears nowhere else.</p>
<p class="endnote">The function Inbuild::set_defaults appears nowhere else.</p>
<p class="endnote">The function Inbuild::set_inter_pipeline appears nowhere else.</p>
<p class="endnote">The function Inbuild::option appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>Once the tool has finished with the command line, it should call this
function. Inbuild rapidly runs through the next few phases as it does so.
From the "nested" phase, the final list of nests in the search path for
finding kits, extensions and so on exists; from the "projected" phase,
the main Inform project exists. As we shall see, Inbuild deals with only
one Inform project at a time, though it may be handling many kits and
extensions, and so on, which are needed by that project.
</p>
2020-03-11 02:21:09 +02:00
<p class="inwebparagraph">A delicacy of timing is that we can only read the Preform grammar in once
the nest list has been read in, since it may need language definitions held
in the internal nest (which the command line has given the location of); but
that we have to do it before reading the source text of the project.
</p>
2020-02-27 13:18:25 +02:00
<pre class="display">
<span class="identifier">target_vm</span><span class="plain"> *</span><span class="identifier">current_target_VM</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">Inbuild::optioneering_complete</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">int</span><span class="plain"> </span><span class="identifier">compile_only</span><span class="plain">) {</span>
<span class="identifier">RUN_ONLY_IN_PHASE</span><span class="plain">(</span><span class="constant">CONFIGURATION_INBUILD_PHASE</span><span class="plain">)</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">CODEGEN_MODULE</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pipeline_vars</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)</span>
<span class="identifier">pipeline_vars</span><span class="plain"> = </span><span class="identifier">CodeGen::Pipeline::basic_dictionary</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"output.z8"</span><span class="plain">);</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="identifier">target_vm</span><span class="plain"> *</span><span class="identifier">VM</span><span class="plain"> = </span><span class="identifier">NULL</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="identifier">story_filename_extension</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">ext</span><span class="plain">) == 0) </span><span class="identifier">ext</span><span class="plain"> = </span><span class="identifier">I</span><span class="string">"ulx"</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">with_debugging</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">this_is_a_release_compile</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) || (</span><span class="identifier">this_is_a_debug_compile</span><span class="plain">))</span>
<span class="identifier">with_debugging</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">VM</span><span class="plain"> = </span><span class="identifier">TargetVMs::find</span><span class="plain">(</span><span class="identifier">ext</span><span class="plain">, </span><span class="identifier">with_debugging</span><span class="plain">);</span>
<span class="identifier">inbuild_phase</span><span class="plain"> = </span><span class="constant">PRETINKERING_INBUILD_PHASE</span><span class="plain">;</span>
<span class="reserved">inform_project</span><span class="plain"> *</span><span class="identifier">project</span><span class="plain"> = </span><span class="functiontext">Inbuild::create_shared_project</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">);</span>
<span class="identifier">inbuild_phase</span><span class="plain"> = </span><span class="constant">TINKERING_INBUILD_PHASE</span><span class="plain">;</span>
<span class="functiontext">Inbuild::sort_nest_list</span><span class="plain">();</span>
<span class="identifier">inbuild_phase</span><span class="plain"> = </span><span class="constant">NESTED_INBUILD_PHASE</span><span class="plain">;</span>
2020-03-11 02:21:09 +02:00
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">CORE_MODULE</span>
<span class="identifier">NaturalLanguages::scan</span><span class="plain">();</span>
<span class="plain">#</span><span class="identifier">endif</span>
2020-02-27 13:18:25 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">project</span><span class="plain">) </span><span class="functiontext">Projects::set_to_English</span><span class="plain">(</span><span class="identifier">project</span><span class="plain">);</span>
2020-03-11 02:21:09 +02:00
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">CORE_MODULE</span>
<span class="identifier">Semantics::read_preform</span><span class="plain">(</span><span class="functiontext">Projects::get_language_of_syntax</span><span class="plain">(</span><span class="identifier">project</span><span class="plain">));</span>
<span class="plain">#</span><span class="identifier">endif</span>
2020-02-27 13:18:25 +02:00
<span class="functiontext">Inbuild::pass_kit_requests</span><span class="plain">();</span>
2020-03-11 02:21:09 +02:00
<span class="identifier">current_target_VM</span><span class="plain"> = </span><span class="identifier">VM</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">project</span><span class="plain">) </span><span class="functiontext">Copies::read_source_text_for</span><span class="plain">(</span><span class="identifier">project</span><span class="plain">-</span><span class="element">&gt;as_copy</span><span class="plain">);</span>
2020-02-27 13:18:25 +02:00
<span class="identifier">inbuild_phase</span><span class="plain"> = </span><span class="constant">PROJECTED_INBUILD_PHASE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">project</span><span class="plain">) {</span>
<span class="functiontext">Projects::construct_build_target</span><span class="plain">(</span><span class="identifier">project</span><span class="plain">, </span><span class="identifier">VM</span><span class="plain">, </span><span class="identifier">this_is_a_release_compile</span><span class="plain">, </span><span class="identifier">compile_only</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">project</span><span class="plain">-</span><span class="element">&gt;as_copy</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</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="plain">}</span>
<span class="identifier">target_vm</span><span class="plain"> *</span><span class="functiontext">Inbuild::current_vm</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">current_target_VM</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Inbuild::currently_releasing</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">this_is_a_release_compile</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Inbuild::optioneering_complete appears nowhere else.</p>
2020-03-11 02:21:09 +02:00
<p class="endnote">The function Inbuild::current_vm is used in 6/hdn (<a href="6-hdn.html#SP13">&#167;13</a>), 6/inc (<a href="6-inc.html#SP6_1">&#167;6.1</a>).</p>
2020-02-27 13:18:25 +02:00
2020-03-11 02:21:09 +02:00
<p class="endnote">The function Inbuild::currently_releasing is used in 6/hdn (<a href="6-hdn.html#SP17">&#167;17</a>).</p>
2020-02-27 13:18:25 +02:00
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>Inbuild is now in the "projected" phase, then. The idea is that this
is a short interval during which the tool can if it wishes add further
kit dependencies to the main project. Once that sort of thing is done,
the tool should call the following, which puts Inbuild into its
final "operational" phase &mdash; at this point Inbuild is fully configured
and ready for use.
</p>
<p class="inwebparagraph">The brief "going operational" phase is used, for example, to build out
dependency graphs.
</p>
<pre class="display">
<span class="reserved">inform_project</span><span class="plain"> *</span><span class="functiontext">Inbuild::go_operational</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">RUN_ONLY_IN_PHASE</span><span class="plain">(</span><span class="constant">PROJECTED_INBUILD_PHASE</span><span class="plain">)</span>
<span class="identifier">inbuild_phase</span><span class="plain"> = </span><span class="constant">GOING_OPERATIONAL_INBUILD_PHASE</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">LOOP_OVER</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="reserved">inbuild_copy</span><span class="plain">)</span>
<span class="functiontext">Copies::go_operational</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">);</span>
<span class="identifier">inbuild_phase</span><span class="plain"> = </span><span class="constant">OPERATIONAL_INBUILD_PHASE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">census_mode</span><span class="plain">) </span><span class="functiontext">Extensions::Census::handle_census_mode</span><span class="plain">();</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Inbuild::project</span><span class="plain">();</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Inbuild::go_operational appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. The nest list. </b>Nests are directories which hold resources to be used by the Intools, and
one of Inbuild's main roles is to search and manage nests. All nests can
hold extensions, kits, language definitions, and so on.
</p>
<p class="inwebparagraph">But among nests three are special, and can hold other things as well.
</p>
<p class="inwebparagraph"></p>
<ul class="items"><li>(a) The "internal" nest is part of the installation of Inform as software.
It contains, for example, the build-in extensions. But it also contains
miscellaneous other files needed by Infomr (see below).
</li></ul>
<ul class="items"><li>(b) The "external" nest is the one to which the user installs her own
selection of extensions, and so on. On most platforms, the external nest
is also the default home of "transient" storage, for more ephemeral content,
such as the mechanically generated extension documentation. Some mobile
operating systems are aggressive about wanting to delete ephemeral files
used by applications, so <code class="display"><span class="extract">-transient</span></code> can be used to divert these.
</li></ul>
<ul class="items"><li>(c) Every project has its own private nest, in the form of its associated
Materials folder. For example, in <code class="display"><span class="extract">Jane Eyre.inform</span></code> is a project, then
alongside it is <code class="display"><span class="extract">Jane Eyre.materials</span></code> and this is a nest.
</li></ul>
<p class="inwebparagraph">Nests used by the Inform and Inbuild tools are tagged with the following
comstamts, except that no nest is ever tagged <code class="display"><span class="extract">NOT_A_NEST_TAG</span></code>.
(There used to be quite a good joke here, but refactoring of the
code removed its premiss. Literate programming is like that sometimes.)
</p>
2020-03-11 02:21:09 +02:00
<p class="inwebparagraph">The sequence of the following enumerated values is significant: lower
origins are better than later ones, when choosing the best result of
a search for resources.
</p>
2020-02-27 13:18:25 +02:00
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">NOT_A_NEST_TAG</span><span class="definitionkeyword"> from </span><span class="constant">0</span>
<span class="definitionkeyword">enum</span> <span class="constant">MATERIALS_NEST_TAG</span>
<span class="definitionkeyword">enum</span> <span class="constant">EXTERNAL_NEST_TAG</span>
<span class="definitionkeyword">enum</span> <span class="constant">GENERIC_NEST_TAG</span>
<span class="definitionkeyword">enum</span> <span class="constant">INTERNAL_NEST_TAG</span>
</pre>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. </b>Inform customarily has exactly one <code class="display"><span class="extract">-internal</span></code> and one <code class="display"><span class="extract">-external</span></code> nest,
but in fact any number of each are allowed, including none. However, the
first to be declared are used by the compiler as "the" internal and external
nests, respectively.
</p>
<p class="inwebparagraph">The following hold the nests in declaration order.
</p>
<pre class="display">
<span class="identifier">linked_list</span><span class="plain"> *</span><span class="identifier">unsorted_nest_list</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">inbuild_nest</span><span class="plain"> *</span><span class="identifier">shared_internal_nest</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">inbuild_nest</span><span class="plain"> *</span><span class="identifier">shared_external_nest</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">inbuild_nest</span><span class="plain"> *</span><span class="identifier">shared_materials_nest</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">inbuild_nest</span><span class="plain"> *</span><span class="functiontext">Inbuild::add_nest</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">int</span><span class="plain"> </span><span class="identifier">tag</span><span class="plain">) {</span>
<span class="identifier">RUN_ONLY_BEFORE_PHASE</span><span class="plain">(</span><span class="constant">TINKERING_INBUILD_PHASE</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">unsorted_nest_list</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)</span>
<span class="identifier">unsorted_nest_list</span><span class="plain"> = </span><span class="identifier">NEW_LINKED_LIST</span><span class="plain">(</span><span class="reserved">inbuild_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="functiontext">Nests::new</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">);</span>
<span class="functiontext">Nests::set_tag</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">, </span><span class="identifier">tag</span><span class="plain">);</span>
<span class="identifier">ADD_TO_LINKED_LIST</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">, </span><span class="reserved">inbuild_nest</span><span class="plain">, </span><span class="identifier">unsorted_nest_list</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">tag</span><span class="plain"> == </span><span class="constant">EXTERNAL_NEST_TAG</span><span class="plain">) &amp;&amp; (</span><span class="identifier">shared_external_nest</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">))</span>
<span class="identifier">shared_external_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">tag</span><span class="plain"> == </span><span class="constant">INTERNAL_NEST_TAG</span><span class="plain">) &amp;&amp; (</span><span class="identifier">shared_internal_nest</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">))</span>
<span class="identifier">shared_internal_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">tag</span><span class="plain"> == </span><span class="constant">INTERNAL_NEST_TAG</span><span class="plain">) </span><span class="functiontext">Nests::protect</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">N</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Inbuild::add_nest is used in <a href="#SP2">&#167;2</a>, <a href="#SP11_1">&#167;11.1</a>, <a href="#SP11_2">&#167;11.2</a>.</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. </b>It is then sorted in tag order. This is so that if we look for, say, an
extension with a given name, then results in a project's materials folder
are given precedence over those in the external folder, and so on.
</p>
<pre class="display">
<span class="identifier">linked_list</span><span class="plain"> *</span><span class="identifier">shared_nest_list</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Inbuild::sort_nest_list</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">RUN_ONLY_IN_PHASE</span><span class="plain">(</span><span class="constant">TINKERING_INBUILD_PHASE</span><span class="plain">)</span>
<span class="identifier">shared_nest_list</span><span class="plain"> = </span><span class="identifier">NEW_LINKED_LIST</span><span class="plain">(</span><span class="reserved">inbuild_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="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">, </span><span class="reserved">inbuild_nest</span><span class="plain">, </span><span class="identifier">unsorted_nest_list</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Nests::get_tag</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">) == </span><span class="constant">MATERIALS_NEST_TAG</span><span class="plain">)</span>
<span class="identifier">ADD_TO_LINKED_LIST</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">, </span><span class="reserved">inbuild_nest</span><span class="plain">, </span><span class="identifier">shared_nest_list</span><span class="plain">);</span>
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">, </span><span class="reserved">inbuild_nest</span><span class="plain">, </span><span class="identifier">unsorted_nest_list</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Nests::get_tag</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">) == </span><span class="constant">EXTERNAL_NEST_TAG</span><span class="plain">)</span>
<span class="identifier">ADD_TO_LINKED_LIST</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">, </span><span class="reserved">inbuild_nest</span><span class="plain">, </span><span class="identifier">shared_nest_list</span><span class="plain">);</span>
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">, </span><span class="reserved">inbuild_nest</span><span class="plain">, </span><span class="identifier">unsorted_nest_list</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Nests::get_tag</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">) == </span><span class="constant">GENERIC_NEST_TAG</span><span class="plain">)</span>
<span class="identifier">ADD_TO_LINKED_LIST</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">, </span><span class="reserved">inbuild_nest</span><span class="plain">, </span><span class="identifier">shared_nest_list</span><span class="plain">);</span>
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">, </span><span class="reserved">inbuild_nest</span><span class="plain">, </span><span class="identifier">unsorted_nest_list</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Nests::get_tag</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">) == </span><span class="constant">INTERNAL_NEST_TAG</span><span class="plain">)</span>
<span class="identifier">ADD_TO_LINKED_LIST</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">, </span><span class="reserved">inbuild_nest</span><span class="plain">, </span><span class="identifier">shared_nest_list</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Inbuild::sort_nest_list is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. </b>And the rest of Inform or Inbuild can now use:
</p>
<pre class="display">
<span class="identifier">linked_list</span><span class="plain"> *</span><span class="functiontext">Inbuild::nest_list</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">RUN_ONLY_FROM_PHASE</span><span class="plain">(</span><span class="constant">NESTED_INBUILD_PHASE</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">shared_nest_list</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">"nest list never sorted"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">shared_nest_list</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">inbuild_nest</span><span class="plain"> *</span><span class="functiontext">Inbuild::internal</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">RUN_ONLY_FROM_PHASE</span><span class="plain">(</span><span class="constant">NESTED_INBUILD_PHASE</span><span class="plain">)</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">shared_internal_nest</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">inbuild_nest</span><span class="plain"> *</span><span class="functiontext">Inbuild::external</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">RUN_ONLY_FROM_PHASE</span><span class="plain">(</span><span class="constant">NESTED_INBUILD_PHASE</span><span class="plain">)</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">shared_external_nest</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">pathname</span><span class="plain"> *</span><span class="functiontext">Inbuild::materials</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">RUN_ONLY_FROM_PHASE</span><span class="plain">(</span><span class="constant">NESTED_INBUILD_PHASE</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">shared_materials_nest</span><span class="plain"> == </span><span class="identifier">NULL</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">return</span><span class="plain"> </span><span class="identifier">shared_materials_nest</span><span class="plain">-</span><span class="element">&gt;location</span><span class="plain">;</span>
<span class="plain">}</span>
2020-03-11 02:21:09 +02:00
<span class="reserved">inbuild_nest</span><span class="plain"> *</span><span class="functiontext">Inbuild::materials_nest</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">RUN_ONLY_FROM_PHASE</span><span class="plain">(</span><span class="constant">NESTED_INBUILD_PHASE</span><span class="plain">)</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">shared_materials_nest</span><span class="plain">;</span>
<span class="plain">}</span>
2020-02-27 13:18:25 +02:00
</pre>
<p class="inwebparagraph"></p>
2020-03-11 02:21:09 +02:00
<p class="endnote">The function Inbuild::nest_list is used in 3/is (<a href="3-is.html#SP1">&#167;1</a>), 5/kts (<a href="5-kts.html#SP1">&#167;1</a>, <a href="5-kts.html#SP2">&#167;2</a>), 5/ed2 (<a href="5-ed2.html#SP4">&#167;4</a>), 5/ec (<a href="5-ec.html#SP1">&#167;1</a>), 5/ps (<a href="5-ps.html#SP1">&#167;1</a>, <a href="5-ps.html#SP3">&#167;3</a>), 6/inc (<a href="6-inc.html#SP6_1">&#167;6.1</a>, <a href="6-inc.html#SP6_1_2">&#167;6.1.2</a>).</p>
2020-02-27 13:18:25 +02:00
2020-03-11 02:21:09 +02:00
<p class="endnote">The function Inbuild::internal is used in <a href="#SP15">&#167;15</a>, 5/ps (<a href="5-ps.html#SP1">&#167;1</a>).</p>
2020-02-27 13:18:25 +02:00
<p class="endnote">The function Inbuild::external is used in 5/ps (<a href="5-ps.html#SP4">&#167;4</a>).</p>
<p class="endnote">The function Inbuild::materials appears nowhere else.</p>
2020-03-11 02:21:09 +02:00
<p class="endnote">The function Inbuild::materials_nest appears nowhere else.</p>
2020-02-27 13:18:25 +02:00
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. </b>As noted above, the transient area is used for ephemera such as dynamically
written documentation and telemetry files. <code class="display"><span class="extract">-transient</span></code> sets it, but otherwise
the external nest is used.
</p>
<pre class="display">
<span class="identifier">pathname</span><span class="plain"> *</span><span class="functiontext">Inbuild::transient</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">RUN_ONLY_FROM_PHASE</span><span class="plain">(</span><span class="constant">PROJECTED_INBUILD_PHASE</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">shared_transient_resources</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">shared_external_nest</span><span class="plain">)</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">shared_external_nest</span><span class="plain">-</span><span class="element">&gt;location</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">shared_transient_resources</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Inbuild::transient is used in 5/ed (<a href="5-ed.html#SP11">&#167;11</a>), 5/ed2 (<a href="5-ed2.html#SP3">&#167;3</a>), 5/ec (<a href="5-ec.html#SP15">&#167;15</a>), 5/ps (<a href="5-ps.html#SP3">&#167;3</a>).</p>
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. The shared project. </b>In any single run, each of the Inform tools concerns itself with a single
Inform 7 program. This can be presented to it either in a project bundle
(a directory which contains source, settings, space for an index and for
temporary build files), or as a single file (just a text file containing
source text).
</p>
<p class="inwebparagraph">It is also possible o set a folder to be the project bundle, and nevertheless
specify a file somewhere else to be the source text. What you can't do is
specify the bundle twice, or specify the file twice.
</p>
<pre class="display">
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">project_bundle_request</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">project_file_request</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Inbuild::set_I7_source</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">loc</span><span class="plain">) {</span>
<span class="identifier">RUN_ONLY_FROM_PHASE</span><span class="plain">(</span><span class="constant">CONFIGURATION_INBUILD_PHASE</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">project_file_request</span><span class="plain">) &gt; 0) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">project_file_request</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">loc</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Inbuild::set_I7_bundle</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">loc</span><span class="plain">) {</span>
<span class="identifier">RUN_ONLY_FROM_PHASE</span><span class="plain">(</span><span class="constant">CONFIGURATION_INBUILD_PHASE</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">project_bundle_request</span><span class="plain">) &gt; 0) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">project_bundle_request</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">loc</span><span class="plain">);</span>
<span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">pathname_of_bundle</span><span class="plain"> = </span><span class="identifier">Pathnames::from_text</span><span class="plain">(</span><span class="identifier">project_bundle_request</span><span class="plain">);</span>
<span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">materials</span><span class="plain"> = </span><span class="functiontext">Inbuild::pathname_of_materials</span><span class="plain">(</span><span class="identifier">pathname_of_bundle</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="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">leaf</span><span class="plain">, </span><span class="string">"%s-settings.txt"</span><span class="plain">, </span><span class="identifier">INTOOL_NAME</span><span class="plain">);</span>
<span class="identifier">filename</span><span class="plain"> *</span><span class="identifier">expert_settings</span><span class="plain"> = </span><span class="identifier">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">materials</span><span class="plain">, </span><span class="identifier">leaf</span><span class="plain">);</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Speculatively %f\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">expert_settings</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">expert_settings</span><span class="plain">))</span>
<span class="identifier">CommandLine::also_read_file</span><span class="plain">(</span><span class="identifier">expert_settings</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">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Inbuild::set_I7_source is used in <a href="#SP2">&#167;2</a>.</p>
<p class="endnote">The function Inbuild::set_I7_bundle is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP11"></a><b>&#167;11. </b>If a bundle is found, then by default the source text within it is called
<code class="display"><span class="extract">story.ni</span></code>. The <code class="display"><span class="extract">.ni</span></code> is an anachronism now, but at one time stood for
"natural Inform", the working title for Inform 7 in the early 2000s.
</p>
<pre class="display">
<span class="reserved">inform_project</span><span class="plain"> *</span><span class="identifier">shared_project</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">inform_project</span><span class="plain"> *</span><span class="functiontext">Inbuild::create_shared_project</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">RUN_ONLY_IN_PHASE</span><span class="plain">(</span><span class="constant">PRETINKERING_INBUILD_PHASE</span><span class="plain">)</span>
<span class="identifier">filename</span><span class="plain"> *</span><span class="identifier">filename_of_i7_source</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">pathname_of_bundle</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">Str::len</span><span class="plain">(</span><span class="identifier">project_bundle_request</span><span class="plain">) &gt; 0) {</span>
<span class="identifier">pathname_of_bundle</span><span class="plain"> = </span><span class="identifier">Pathnames::from_text</span><span class="plain">(</span><span class="identifier">project_bundle_request</span><span class="plain">);</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">project_file_request</span><span class="plain">) &gt; 0) {</span>
<span class="identifier">filename_of_i7_source</span><span class="plain"> = </span><span class="identifier">Filenames::from_text</span><span class="plain">(</span><span class="identifier">project_file_request</span><span class="plain">);</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">pathname_of_bundle</span><span class="plain"> = </span><span class="identifier">C</span><span class="plain">-</span><span class="element">&gt;location_if_path</span><span class="plain">;</span>
<span class="identifier">filename_of_i7_source</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="plain">}</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">pathname_of_bundle</span><span class="plain">) &amp;&amp; (</span><span class="identifier">filename_of_i7_source</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">))</span>
<span class="identifier">filename_of_i7_source</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">pathname_of_bundle</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Source"</span><span class="plain">),</span>
<span class="identifier">I</span><span class="string">"story.ni"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pathname_of_bundle</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">ProjectBundleManager::claim_folder_as_copy</span><span class="plain">(</span><span class="identifier">pathname_of_bundle</span><span class="plain">);</span>
<span class="identifier">shared_project</span><span class="plain"> = </span><span class="functiontext">ProjectBundleManager::from_copy</span><span class="plain">(</span><span class="identifier">C</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">filename_of_i7_source</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">ProjectFileManager::claim_file_as_copy</span><span class="plain">(</span><span class="identifier">filename_of_i7_source</span><span class="plain">);</span>
<span class="identifier">shared_project</span><span class="plain"> = </span><span class="functiontext">ProjectFileManager::from_copy</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">);</span>
<span class="plain">}</span>
&lt;<span class="cwebmacro">Create the default externals nest</span> <span class="cwebmacronumber">11.1</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Create the materials nest</span> <span class="cwebmacronumber">11.2</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">shared_project</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="identifier">shared_materials_nest</span><span class="plain">)?(</span><span class="identifier">shared_materials_nest</span><span class="plain">-</span><span class="element">&gt;location</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">P</span><span class="plain">) </span><span class="identifier">P</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">I</span><span class="string">"Source"</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">project_file_request</span><span class="plain">) &gt; 0) </span><span class="identifier">P</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="functiontext">Projects::set_source_filename</span><span class="plain">(</span><span class="identifier">shared_project</span><span class="plain">, </span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">filename_of_i7_source</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rng_seed_at_start_of_play</span><span class="plain"> != 0)</span>
<span class="functiontext">Projects::fix_rng</span><span class="plain">(</span><span class="identifier">shared_project</span><span class="plain">, </span><span class="identifier">rng_seed_at_start_of_play</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">shared_project</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Inbuild::create_shared_project is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP11_1"></a><b>&#167;11.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Create the default externals nest</span> <span class="cwebmacronumber">11.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">inbuild_nest</span><span class="plain"> *</span><span class="identifier">E</span><span class="plain"> = </span><span class="identifier">shared_external_nest</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">E</span><span class="plain"> == </span><span class="identifier">NULL</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="identifier">home_path</span><span class="plain">;</span>
<span class="reserved">char</span><span class="plain"> *</span><span class="identifier">subfolder_within</span><span class="plain"> = </span><span class="identifier">INFORM_FOLDER_RELATIVE_TO_HOME</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">subfolder_within</span><span class="plain">[0]) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">SF</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">SF</span><span class="plain">, </span><span class="string">"%s"</span><span class="plain">, </span><span class="identifier">subfolder_within</span><span class="plain">);</span>
<span class="identifier">P</span><span class="plain"> = </span><span class="identifier">Pathnames::subfolder</span><span class="plain">(</span><span class="identifier">home_path</span><span class="plain">, </span><span class="identifier">SF</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">SF</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">P</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">I</span><span class="string">"Inform"</span><span class="plain">);</span>
<span class="identifier">E</span><span class="plain"> = </span><span class="functiontext">Inbuild::add_nest</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">, </span><span class="constant">EXTERNAL_NEST_TAG</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP11">&#167;11</a>.</p>
<p class="inwebparagraph"><a id="SP11_2"></a><b>&#167;11.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Create the materials nest</span> <span class="cwebmacronumber">11.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">materials</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">pathname_of_bundle</span><span class="plain">) {</span>
<span class="identifier">materials</span><span class="plain"> = </span><span class="functiontext">Inbuild::pathname_of_materials</span><span class="plain">(</span><span class="identifier">pathname_of_bundle</span><span class="plain">);</span>
<span class="identifier">Pathnames::create_in_file_system</span><span class="plain">(</span><span class="identifier">materials</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">filename_of_i7_source</span><span class="plain">) {</span>
<span class="identifier">materials</span><span class="plain"> = </span><span class="identifier">Pathnames::from_text</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"inform.materials"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">materials</span><span class="plain">) {</span>
<span class="identifier">shared_materials_nest</span><span class="plain"> = </span><span class="functiontext">Inbuild::add_nest</span><span class="plain">(</span><span class="identifier">materials</span><span class="plain">, </span><span class="constant">MATERIALS_NEST_TAG</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP11">&#167;11</a>.</p>
<p class="inwebparagraph"><a id="SP12"></a><b>&#167;12. </b>And the rest of Inform or Inbuild can now use:
</p>
<pre class="display">
<span class="reserved">inform_project</span><span class="plain"> *</span><span class="functiontext">Inbuild::project</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
2020-03-11 02:21:09 +02:00
<span class="identifier">RUN_ONLY_FROM_PHASE</span><span class="plain">(</span><span class="constant">TINKERING_INBUILD_PHASE</span><span class="plain">)</span>
2020-02-27 13:18:25 +02:00
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">shared_project</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
2020-03-11 02:21:09 +02:00
<p class="endnote">The function Inbuild::project is used in <a href="#SP4">&#167;4</a>, 3/is (<a href="3-is.html#SP1">&#167;1</a>), 5/es (<a href="5-es.html#SP5">&#167;5</a>).</p>
2020-02-27 13:18:25 +02:00
<p class="inwebparagraph"><a id="SP13"></a><b>&#167;13. </b>The materials folder sits alongside the project folder and has the same name,
but ending <code class="display"><span class="extract">.materials</span></code> instead of <code class="display"><span class="extract">.inform</span></code>.
</p>
<pre class="display">
<span class="identifier">pathname</span><span class="plain"> *</span><span class="functiontext">Inbuild::pathname_of_materials</span><span class="plain">(</span><span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">pathname_of_bundle</span><span class="plain">) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">mf</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">mf</span><span class="plain">, </span><span class="string">"%S"</span><span class="plain">, </span><span class="identifier">Pathnames::directory_name</span><span class="plain">(</span><span class="identifier">pathname_of_bundle</span><span class="plain">));</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> = </span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">mf</span><span class="plain">)-1;</span>
<span class="reserved">while</span><span class="plain"> ((</span><span class="identifier">i</span><span class="plain">&gt;0) &amp;&amp; (</span><span class="identifier">Str::get_at</span><span class="plain">(</span><span class="identifier">mf</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">) != </span><span class="character">'.'</span><span class="plain">)) </span><span class="identifier">i</span><span class="plain">--;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">&gt;0) {</span>
<span class="identifier">Str::truncate</span><span class="plain">(</span><span class="identifier">mf</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">mf</span><span class="plain">, </span><span class="string">".materials"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">materials</span><span class="plain"> = </span><span class="identifier">Pathnames::subfolder</span><span class="plain">(</span><span class="identifier">Pathnames::up</span><span class="plain">(</span><span class="identifier">pathname_of_bundle</span><span class="plain">), </span><span class="identifier">mf</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">mf</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">materials</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Inbuild::pathname_of_materials is used in <a href="#SP10">&#167;10</a>, <a href="#SP11_2">&#167;11.2</a>.</p>
<p class="inwebparagraph"><a id="SP14"></a><b>&#167;14. Kit requests. </b>These are triggered by, for example, <code class="display"><span class="extract">-kit MyFancyKit</span></code> at the command line.
For timing reasons, we store those up in the configuration phase and then
add them as dependencies only when a project exists.
</p>
<pre class="display">
<span class="identifier">linked_list</span><span class="plain"> *</span><span class="identifier">kits_requested_at_command_line</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Inbuild::request_kit</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">name</span><span class="plain">) {</span>
<span class="identifier">RUN_ONLY_IN_PHASE</span><span class="plain">(</span><span class="constant">CONFIGURATION_INBUILD_PHASE</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">kits_requested_at_command_line</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)</span>
<span class="identifier">kits_requested_at_command_line</span><span class="plain"> = </span><span class="identifier">NEW_LINKED_LIST</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain">);</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">kit_name</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">kit_name</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain">, </span><span class="identifier">kits_requested_at_command_line</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::eq</span><span class="plain">(</span><span class="identifier">kit_name</span><span class="plain">, </span><span class="identifier">name</span><span class="plain">))</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="identifier">ADD_TO_LINKED_LIST</span><span class="plain">(</span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">), </span><span class="identifier">text_stream</span><span class="plain">, </span><span class="identifier">kits_requested_at_command_line</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Inbuild::pass_kit_requests</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">RUN_ONLY_IN_PHASE</span><span class="plain">(</span><span class="constant">NESTED_INBUILD_PHASE</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">shared_project</span><span class="plain">) &amp;&amp; (</span><span class="identifier">kits_requested_at_command_line</span><span class="plain">)) {</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">kit_name</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">kit_name</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain">, </span><span class="identifier">kits_requested_at_command_line</span><span class="plain">) {</span>
2020-03-11 02:21:09 +02:00
<span class="functiontext">Projects::add_kit_dependency</span><span class="plain">(</span><span class="identifier">shared_project</span><span class="plain">, </span><span class="identifier">kit_name</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
2020-02-27 13:18:25 +02:00
<span class="functiontext">Projects::not_necessarily_parser_IF</span><span class="plain">(</span><span class="identifier">shared_project</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Inbuild::request_kit is used in <a href="#SP2">&#167;2</a>.</p>
<p class="endnote">The function Inbuild::pass_kit_requests is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP15"></a><b>&#167;15. Installation. </b>Inform needs a whole pile of files to have been installed on the host computer
before it can run: everything from the Standard Rules to a PDF file explaining
what interactive fiction is. They're never written to, only read. They are
referred to as "internal" or "built-in", and they occupy a folder called the
"internal resources" folder.
</p>
<p class="inwebparagraph">Unfortunately we don't know where it is. Typically this compiler will be an
executable sitting somewhere inside a user interface application, and the
internal resources folder will be somewhere else inside it. But we don't
know how to find that folder, and we don't want to make any assumptions.
This is the purpose of the internal nest, and this is why inform7 can only
be run if an <code class="display"><span class="extract">-internal</span></code> switch has been used specifying where it is.
</p>
<p class="inwebparagraph">The internal nest has two additional subfolders (additional in that they
don't hold copies in the Inbuild sense, just a bunch of loose odds and ends):
<code class="display"><span class="extract">Miscellany</span></code> and <code class="display"><span class="extract">HTML</span></code>. Many of these files are to help Inblorb to perform
a release.
</p>
<p class="inwebparagraph">The documentation snippets file is generated by <code class="display"><span class="extract">indoc</span></code> and contains
brief specifications of phrases, extracted from the manual "Writing with
Inform". This is used to generate the Phrasebook index.
</p>
<p class="inwebparagraph">Anyway, Inform and its associated tools can then access these files using the
following routine:
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">CBLORB_REPORT_MODEL_IRES</span><span class="definitionkeyword"> from </span><span class="constant">1</span>
<span class="definitionkeyword">enum</span> <span class="constant">DOCUMENTATION_SNIPPETS_IRES</span>
<span class="definitionkeyword">enum</span> <span class="constant">INTRO_BOOKLET_IRES</span>
<span class="definitionkeyword">enum</span> <span class="constant">INTRO_POSTCARD_IRES</span>
<span class="definitionkeyword">enum</span> <span class="constant">LARGE_DEFAULT_COVER_ART_IRES</span>
<span class="definitionkeyword">enum</span> <span class="constant">SMALL_DEFAULT_COVER_ART_IRES</span>
<span class="definitionkeyword">enum</span> <span class="constant">DOCUMENTATION_XREFS_IRES</span>
<span class="definitionkeyword">enum</span> <span class="constant">JAVASCRIPT_FOR_STANDARD_PAGES_IRES</span>
<span class="definitionkeyword">enum</span> <span class="constant">JAVASCRIPT_FOR_EXTENSIONS_IRES</span>
<span class="definitionkeyword">enum</span> <span class="constant">JAVASCRIPT_FOR_ONE_EXTENSION_IRES</span>
<span class="definitionkeyword">enum</span> <span class="constant">CSS_FOR_STANDARD_PAGES_IRES</span>
<span class="definitionkeyword">enum</span> <span class="constant">EXTENSION_DOCUMENTATION_MODEL_IRES</span>
</pre>
<pre class="display">
<span class="identifier">filename</span><span class="plain"> *</span><span class="functiontext">Inbuild::file_from_installation</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">ires</span><span class="plain">) {</span>
<span class="reserved">inbuild_nest</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain"> = </span><span class="functiontext">Inbuild::internal</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">I</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">Errors::fatal</span><span class="plain">(</span><span class="string">"Did not set -internal when calling"</span><span class="plain">);</span>
<span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">misc</span><span class="plain"> = </span><span class="identifier">Pathnames::subfolder</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">-</span><span class="element">&gt;location</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Miscellany"</span><span class="plain">);</span>
<span class="identifier">pathname</span><span class="plain"> *</span><span class="identifier">models</span><span class="plain"> = </span><span class="identifier">Pathnames::subfolder</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">-</span><span class="element">&gt;location</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"HTML"</span><span class="plain">);</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">ires</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">DOCUMENTATION_SNIPPETS_IRES</span><span class="plain">: </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">misc</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"definitions.html"</span><span class="plain">);</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">INTRO_BOOKLET_IRES</span><span class="plain">: </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">misc</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"IntroductionToIF.pdf"</span><span class="plain">);</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">INTRO_POSTCARD_IRES</span><span class="plain">: </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">misc</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Postcard.pdf"</span><span class="plain">);</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">LARGE_DEFAULT_COVER_ART_IRES</span><span class="plain">: </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">misc</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Cover.jpg"</span><span class="plain">);</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">SMALL_DEFAULT_COVER_ART_IRES</span><span class="plain">: </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">misc</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Small Cover.jpg"</span><span class="plain">);</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">CBLORB_REPORT_MODEL_IRES</span><span class="plain">: </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">models</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"CblorbModel.html"</span><span class="plain">);</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">DOCUMENTATION_XREFS_IRES</span><span class="plain">: </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">models</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"xrefs.txt"</span><span class="plain">);</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">JAVASCRIPT_FOR_STANDARD_PAGES_IRES</span><span class="plain">: </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">models</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"main.js"</span><span class="plain">);</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">JAVASCRIPT_FOR_EXTENSIONS_IRES</span><span class="plain">: </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">models</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"extensions.js"</span><span class="plain">);</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">JAVASCRIPT_FOR_ONE_EXTENSION_IRES</span><span class="plain">: </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">models</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"extensionfile.js"</span><span class="plain">);</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">CSS_FOR_STANDARD_PAGES_IRES</span><span class="plain">: </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">models</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"main.css"</span><span class="plain">);</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">EXTENSION_DOCUMENTATION_MODEL_IRES</span><span class="plain">: </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">models</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"extensionfile.html"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"unknown installation resource file"</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>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Inbuild::file_from_installation is used in 5/ed2 (<a href="5-ed2.html#SP3_2">&#167;3.2</a>), 5/ec (<a href="5-ec.html#SP15">&#167;15</a>).</p>
<hr class="tocbar">
<ul class="toc"><li><a href="1-im.html">Back to 'Inter Module'</a></li><li><i>(This section ends Chapter 1: Setting Up.)</i></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>