1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-05 08:34:22 +03:00
inform7/docs/BasicInformKit/S-tt2.html

1187 lines
177 KiB
HTML
Raw Normal View History

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
2020-01-27 03:22:21 +02:00
<title>S/bt</title>
2020-03-19 02:11:25 +02:00
<meta name="viewport" content="width=device-width initial-scale=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
2020-03-19 02:11:25 +02:00
<link href="../inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
2020-03-19 02:11:25 +02:00
<nav role="navigation">
<h1><a href="../webs.html">Sources</a></h1>
<ul>
<li><a href="../compiler.html">compiler tools</a></li>
2020-03-19 02:11:25 +02:00
<li><a href="../other.html">other tools</a></li>
<li><a href="../extensions.html"><b>extensions and kits</b></a></li>
<li><a href="../units.html">unit test tools</a></li>
/ul>
<h2>Extensions</h2>
<ul>
<li><a href="../basic_inform/index.html">Basic Inform</a></li>
<li><a href="../standard_rules/index.html">Standard Rules</a></li>
</ul>
<h2>Kits</h2>
<ul>
<li><a href="../BasicInformKit/index.html">BasicInformKit</a></li>
<li><a href="../BasicInformExtrasKit/index.html">BasicInformExtrasKit</a></li>
<li><a href="../CommandParserKit/index.html">CommandParserKit</a></li>
<li><a href="../EnglishLanguageKit/index.html">EnglishLanguageKit</a></li>
<li><a href="../WorldModelKit/index.html">WorldModelKit</a></li>
</ul>
</nav>
<main role="main">
<!--Weave of 'S/tt2' generated by 7-->
2020-03-19 02:11:25 +02:00
<ul class="crumbs"><li><a href="../webs.html">Source</a></li><li><a href="../extensions.html">Kits</a></li><li><a href="index.html">BasicInformKit</a></li><li><b>Text Template</b></li></ul><p class="purpose">Code to support the text kind of value.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Block Format</a></li><li><a href="#SP2">&#167;2. Extent Of Long Block</a></li><li><a href="#SP3">&#167;3. Character Set</a></li><li><a href="#SP4">&#167;4. KOV Support</a></li><li><a href="#SP5">&#167;5. Debugging</a></li><li><a href="#SP6">&#167;6. Creation</a></li><li><a href="#SP7">&#167;7. Copy Short Block</a></li><li><a href="#SP8">&#167;8. Transmutation</a></li><li><a href="#SP9">&#167;9. Mutability</a></li><li><a href="#SP10">&#167;10. Casting</a></li><li><a href="#SP11">&#167;11. Data Conversion</a></li><li><a href="#SP12">&#167;12. Z Version</a></li><li><a href="#SP13">&#167;13. Glulx Version</a></li><li><a href="#SP14">&#167;14. Comparison</a></li><li><a href="#SP15">&#167;15. Hashing</a></li><li><a href="#SP16">&#167;16. Printing</a></li><li><a href="#SP17">&#167;17. Capitalised printing</a></li><li><a href="#SP18">&#167;18. Serialisation</a></li><li><a href="#SP19">&#167;19. Unserialisation</a></li><li><a href="#SP20">&#167;20. Substitution</a></li><li><a href="#SP21">&#167;21. Perishability</a></li><li><a href="#SP22">&#167;22. Blobs</a></li><li><a href="#SP23">&#167;23. Blob Access</a></li><li><a href="#SP24">&#167;24. Get Blob</a></li><li><a href="#SP25">&#167;25. Replace Blob</a></li><li><a href="#SP26">&#167;26. Replace Text</a></li><li><a href="#SP27">&#167;27. Character Length</a></li><li><a href="#SP28">&#167;28. Get Character</a></li><li><a href="#SP29">&#167;29. Casing</a></li><li><a href="#SP30">&#167;30. Change Case</a></li><li><a href="#SP31">&#167;31. Concatenation</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Block Format. </b>The short block for a text is two words long: the first word selects which
form of storage will be used to represent the content, and the second word
is a reference to that content. This reference is an I6 String or Routine
in all cases except one, when it's a pointer to a long block containing
a null-terminated array of characters, like a C string.
</p>
<p class="inwebparagraph">Clearly we need <code class="display"><span class="extract">PACKED_TEXT_STORAGE</span></code> and <code class="display"><span class="extract">UNPACKED_TEXT_STORAGE</span></code> to
distinguish between the two basic methods of text storage, roughly
equivalent to the pre-2013 kinds "text" and "indexed text". But why
do we need four?
</p>
<p class="inwebparagraph"><code class="display"><span class="extract">CONSTANT_PACKED_TEXT_STORAGE</span></code> is easy to explain: the BlkValue routines
normally detect constants using metadata in their long blocks, but of
course that won't work for values which haven't got any long blocks.
We use this instead. We don't need a <code class="display"><span class="extract">CONSTANT_UNPACKED_TEXT_STORAGE</span></code>
because I7 never compiles constant text in unpacked form.
</p>
<p class="inwebparagraph">The surprising one is <code class="display"><span class="extract">CONSTANT_PERISHABLE_TEXT_STORAGE</span></code>. This is a
constant created by the I7 compiler which is marked as being tricky
because its value is a text substitution containing references to local
variables. Unlike other text substitutions, this can't meaningfully be
stored away to be expanded later: it must be expanded into unpacked
text before it perishes.
</p>
<pre class="display">
2020-01-12 02:35:36 +02:00
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">CONSTANT_PACKED_TEXT_STORAGE</span><span class="plain"> = </span><span class="identifier">BLK_BVBITMAP_TEXT</span><span class="plain"> + </span><span class="identifier">BLK_BVBITMAP_CONSTANT</span><span class="plain"> + </span><span class="constant">1</span><span class="plain">;</span>
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">CONSTANT_PERISHABLE_TEXT_STORAGE</span><span class="plain"> = </span><span class="identifier">BLK_BVBITMAP_TEXT</span><span class="plain"> + </span><span class="identifier">BLK_BVBITMAP_CONSTANT</span><span class="plain"> + </span><span class="constant">2</span><span class="plain">;</span>
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">PACKED_TEXT_STORAGE</span><span class="plain"> = </span><span class="identifier">BLK_BVBITMAP_TEXT</span><span class="plain"> + </span><span class="constant">3</span><span class="plain">;</span>
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">UNPACKED_TEXT_STORAGE</span><span class="plain"> = </span><span class="identifier">BLK_BVBITMAP_TEXT</span><span class="plain"> + </span><span class="identifier">BLK_BVBITMAP_LONGBLOCK</span><span class="plain"> + </span><span class="constant">4</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. Extent Of Long Block. </b>When there's a long block, we need enough of the entries to store the
number of characters, plus one for the null terminator.
</p>
<pre class="display">
2020-01-12 02:35:36 +02:00
<span class="plain">[ </span><span class="identifier">TEXT_TY_Extent</span><span class="plain"> </span><span class="identifier">arg1</span><span class="plain"> </span><span class="identifier">x</span><span class="plain">;</span>
<span class="identifier">x</span><span class="plain"> = </span><span class="identifier">BlkValueSeekZeroEntry</span><span class="plain">(</span><span class="identifier">arg1</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">x</span><span class="plain"> &lt; </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">-1</span><span class="plain">; </span><span class="comment">! should not happen, of course</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">x</span><span class="plain">+1;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. Character Set. </b>On the Z-machine, we use the 8-bit ZSCII character set, stored in bytes;
on Glulx, we use the opening 16-bit subset of Unicode (which though only a
subset covers almost all letter forms used on Earth), stored in half-words.
</p>
<p class="inwebparagraph">The Z-machine does have very partial Unicode support, but not in a way that
can help us here. It is capable of printing a wide range of Unicode
characters, and on a good interpreter with a good font (such as Zoom for Mac
OS X, using the Lucida Grande font) can produce many thousands of glyphs. But
it is not capable of printing those characters into memory rather than the
screen, an essential technique for texts: it can only write each character to
a single byte, and it does so in ZSCII. That forces our hand when it comes to
choosing the indexed-text character set.
</p>
<pre class="display">
2020-01-12 02:35:36 +02:00
<span class="plain">#</span><span class="identifier">IFDEF</span><span class="plain"> </span><span class="identifier">TARGET_ZCODE</span><span class="plain">;</span>
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">TEXT_TY_Storage_Flags</span><span class="plain"> = </span><span class="identifier">BLK_FLAG_MULTIPLE</span><span class="plain">;</span>
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">ZSCII_Tables</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">IFNOT</span><span class="plain">;</span>
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">TEXT_TY_Storage_Flags</span><span class="plain"> = </span><span class="identifier">BLK_FLAG_MULTIPLE</span><span class="plain"> + </span><span class="identifier">BLK_FLAG_16_BIT</span><span class="plain">;</span>
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">Large_Unicode_Tables</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">ENDIF</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. KOV Support. </b>See the "BlockValues.i6t" segment for the specification of the following
routines. Because no block values are ever stored in a text, they can
freely be bitwise copied or forgotten, which is why we need do nothing
special to copy or destroy a text.
</p>
<pre class="display">
2020-01-12 02:35:36 +02:00
<span class="plain">[ </span><span class="identifier">TEXT_TY_Support</span><span class="plain"> </span><span class="identifier">task</span><span class="plain"> </span><span class="identifier">arg1</span><span class="plain"> </span><span class="identifier">arg2</span><span class="plain"> </span><span class="identifier">arg3</span><span class="plain">;</span>
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">task</span><span class="plain">) {</span>
<span class="identifier">CREATE_KOVS</span><span class="plain">: </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TEXT_TY_Create</span><span class="plain">(</span><span class="identifier">arg2</span><span class="plain">);</span>
<span class="identifier">CAST_KOVS</span><span class="plain">: </span><span class="identifier">TEXT_TY_Cast</span><span class="plain">(</span><span class="identifier">arg1</span><span class="plain">, </span><span class="identifier">arg2</span><span class="plain">, </span><span class="identifier">arg3</span><span class="plain">);</span>
<span class="identifier">MAKEMUTABLE_KOVS</span><span class="plain">: </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TEXT_TY_Mutable</span><span class="plain">(</span><span class="identifier">arg1</span><span class="plain">);</span>
<span class="identifier">COPYQUICK_KOVS</span><span class="plain">: </span><span class="reserved">rtrue</span><span class="plain">;</span>
<span class="identifier">COPYSB_KOVS</span><span class="plain">: </span><span class="identifier">TEXT_TY_CopySB</span><span class="plain">(</span><span class="identifier">arg1</span><span class="plain">, </span><span class="identifier">arg2</span><span class="plain">);</span>
<span class="identifier">KINDDATA_KOVS</span><span class="plain">: </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">EXTENT_KOVS</span><span class="plain">: </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TEXT_TY_Extent</span><span class="plain">(</span><span class="identifier">arg1</span><span class="plain">);</span>
<span class="identifier">COMPARE_KOVS</span><span class="plain">: </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TEXT_TY_Compare</span><span class="plain">(</span><span class="identifier">arg1</span><span class="plain">, </span><span class="identifier">arg2</span><span class="plain">);</span>
<span class="identifier">READ_FILE_KOVS</span><span class="plain">: </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">arg3</span><span class="plain"> == </span><span class="constant">-1</span><span class="plain">) </span><span class="reserved">rtrue</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TEXT_TY_ReadFile</span><span class="plain">(</span><span class="identifier">arg1</span><span class="plain">, </span><span class="identifier">arg2</span><span class="plain">, </span><span class="identifier">arg3</span><span class="plain">);</span>
<span class="identifier">WRITE_FILE_KOVS</span><span class="plain">: </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TEXT_TY_WriteFile</span><span class="plain">(</span><span class="identifier">arg1</span><span class="plain">);</span>
<span class="identifier">HASH_KOVS</span><span class="plain">: </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TEXT_TY_Hash</span><span class="plain">(</span><span class="identifier">arg1</span><span class="plain">);</span>
<span class="identifier">DEBUG_KOVS</span><span class="plain">: </span><span class="identifier">TEXT_TY_Debug</span><span class="plain">(</span><span class="identifier">arg1</span><span class="plain">);</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="comment">! We choose not to respond to: DESTROY_KOVS, COPYKIND_KOVS, COPY_KOVS</span>
<span class="reserved">rfalse</span><span class="plain">;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. Debugging. </b>This shows the various forms a text's short block can take:
</p>
<pre class="display">
2020-01-12 02:35:36 +02:00
<span class="plain">[ </span><span class="identifier">TEXT_TY_Debug</span><span class="plain"> </span><span class="identifier">txt</span><span class="plain">;</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">txt</span><span class="plain">--&gt;0) {</span>
<span class="identifier">CONSTANT_PACKED_TEXT_STORAGE</span><span class="plain">: </span><span class="reserved">print</span><span class="plain"> </span><span class="string">" = cp~"</span><span class="plain">, (</span><span class="identifier">PrintI6Text</span><span class="plain">) </span><span class="identifier">txt</span><span class="plain">--&gt;1, </span><span class="string">"~"</span><span class="plain">;</span>
<span class="identifier">CONSTANT_PERISHABLE_TEXT_STORAGE</span><span class="plain">: </span><span class="reserved">print</span><span class="plain"> </span><span class="string">" = cp~"</span><span class="plain">, (</span><span class="identifier">PrintI6Text</span><span class="plain">) </span><span class="identifier">txt</span><span class="plain">--&gt;1, </span><span class="string">"~"</span><span class="plain">;</span>
<span class="identifier">PACKED_TEXT_STORAGE</span><span class="plain">: </span><span class="reserved">print</span><span class="plain"> </span><span class="string">" = p~"</span><span class="plain">, (</span><span class="identifier">PrintI6Text</span><span class="plain">) </span><span class="identifier">txt</span><span class="plain">--&gt;1, </span><span class="string">"~"</span><span class="plain">;</span>
<span class="identifier">UNPACKED_TEXT_STORAGE</span><span class="plain">: </span><span class="reserved">print</span><span class="plain"> </span><span class="string">" = ~"</span><span class="plain">, (</span><span class="identifier">TEXT_TY_Say</span><span class="plain">) </span><span class="identifier">txt</span><span class="plain">, </span><span class="string">"~"</span><span class="plain">;</span>
<span class="reserved">default</span><span class="plain">: </span><span class="reserved">print</span><span class="plain"> </span><span class="string">" broken?"</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. Creation. </b>A newly created text is a two-word short block with no long block, like this:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">Array ThisIsAText --&gt; PACKED_TEXT_STORAGE EMPTY_TEXT_PACKED;</span>
2020-01-12 02:35:36 +02:00
<span class="plain">[ </span><span class="identifier">TEXT_TY_Create</span><span class="plain"> </span><span class="identifier">short_block</span><span class="plain"> </span><span class="identifier">x</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">BlkValueCreateSB2</span><span class="plain">(</span><span class="identifier">short_block</span><span class="plain">, </span><span class="identifier">PACKED_TEXT_STORAGE</span><span class="plain">, </span><span class="identifier">EMPTY_TEXT_PACKED</span><span class="plain">);</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. Copy Short Block. </b>When a short block for a constant is copied, the new copy isn't a constant
any more.
</p>
<pre class="display">
2020-01-12 02:35:36 +02:00
<span class="plain">[ </span><span class="identifier">TEXT_TY_CopySB</span><span class="plain"> </span><span class="identifier">to_bv</span><span class="plain"> </span><span class="identifier">from_bv</span><span class="plain">;</span>
<span class="identifier">BlkValueCopySB2</span><span class="plain">(</span><span class="identifier">to_bv</span><span class="plain">, </span><span class="identifier">from_bv</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">to_bv</span><span class="plain">--&gt;0 &amp; </span><span class="identifier">BLK_BVBITMAP_CONSTANTMASK</span><span class="plain">) </span><span class="identifier">to_bv</span><span class="plain">--&gt;0 = </span><span class="identifier">PACKED_TEXT_STORAGE</span><span class="plain">;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. Transmutation. </b>What happens if a text is stored in packed form, but we need to access or
change its individual characters? The answer is that we have to "transmute"
it into long block form. Sometimes this is a permanent change, but often
it's only temporary, and will soon be followed by an un-transmutation.
</p>
<pre class="display">
2020-01-12 02:35:36 +02:00
<span class="plain">[ </span><span class="identifier">TEXT_TY_Transmute</span><span class="plain"> </span><span class="identifier">txt</span><span class="plain">;</span>
<span class="identifier">TEXT_TY_Temporarily_Transmute</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">);</span>
<span class="plain">];</span>
2020-01-12 02:35:36 +02:00
<span class="plain">[ </span><span class="identifier">TEXT_TY_Temporarily_Transmute</span><span class="plain"> </span><span class="identifier">txt</span><span class="plain"> </span><span class="identifier">x</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">txt</span><span class="plain">) &amp;&amp; (</span><span class="identifier">txt</span><span class="plain">--&gt;0 &amp; </span><span class="identifier">BLK_BVBITMAP_LONGBLOCKMASK</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">)) {</span>
<span class="identifier">x</span><span class="plain"> = </span><span class="identifier">txt</span><span class="plain">--&gt;1; </span><span class="comment">! The old value was a packed string</span>
2020-01-12 02:35:36 +02:00
<span class="identifier">txt</span><span class="plain">--&gt;0 = </span><span class="identifier">UNPACKED_TEXT_STORAGE</span><span class="plain">;</span>
<span class="identifier">txt</span><span class="plain">--&gt;1 = </span><span class="identifier">FlexAllocate</span><span class="plain">(32, </span><span class="identifier">TEXT_TY</span><span class="plain">, </span><span class="identifier">TEXT_TY_Storage_Flags</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">x</span><span class="plain"> ~= </span><span class="identifier">EMPTY_TEXT_PACKED</span><span class="plain">) </span><span class="identifier">TEXT_TY_CastPrimitive</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">, </span><span class="reserved">false</span><span class="plain">, </span><span class="identifier">x</span><span class="plain">);</span>
2020-01-12 02:35:36 +02:00
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">x</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="reserved">return</span><span class="plain"> </span><span class="constant">0</span><span class="plain">;</span>
<span class="plain">];</span>
2020-01-12 02:35:36 +02:00
<span class="plain">[ </span><span class="identifier">TEXT_TY_Untransmute</span><span class="plain"> </span><span class="identifier">txt</span><span class="plain"> </span><span class="identifier">pk</span><span class="plain"> </span><span class="identifier">cp</span><span class="plain"> </span><span class="identifier">x</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">pk</span><span class="plain">) &amp;&amp; (</span><span class="identifier">txt</span><span class="plain">--&gt;0 == </span><span class="identifier">UNPACKED_TEXT_STORAGE</span><span class="plain">)) {</span>
<span class="identifier">x</span><span class="plain"> = </span><span class="identifier">txt</span><span class="plain">--&gt;1; </span><span class="comment">! The old value was an unpacked string</span>
<span class="identifier">FlexFree</span><span class="plain">(</span><span class="identifier">x</span><span class="plain">);</span>
<span class="identifier">txt</span><span class="plain">--&gt;0 = </span><span class="identifier">cp</span><span class="plain">;</span>
<span class="identifier">txt</span><span class="plain">--&gt;1 = </span><span class="identifier">pk</span><span class="plain">; </span><span class="comment">! The value earlier returned by TEXT_TY_Temporarily_Transmute</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">txt</span><span class="plain">;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. Mutability. </b>That neatly handles the question of how to make a text mutable. (Note that
constants are never created in unpacked form.)
</p>
<pre class="display">
2020-01-12 02:35:36 +02:00
<span class="plain">[ </span><span class="identifier">TEXT_TY_Mutable</span><span class="plain"> </span><span class="identifier">txt</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">txt</span><span class="plain">--&gt;0 &amp; </span><span class="identifier">BLK_BVBITMAP_LONGBLOCKMASK</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) {</span>
<span class="identifier">TEXT_TY_Transmute</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="constant">0</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="reserved">return</span><span class="plain"> </span><span class="constant">2</span><span class="plain">; </span><span class="comment">! Tell BlockValue there's a long block pointer</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. Casting. </b>In general computing, "casting" is the process of translating data in one
type into semantically equivalent data in another: the only interesting
cast here is that a snippet can be turned into a text.
</p>
<pre class="display">
2020-01-12 02:35:36 +02:00
<span class="plain">[ </span><span class="identifier">TEXT_TY_Cast</span><span class="plain"> </span><span class="identifier">to_txt</span><span class="plain"> </span><span class="identifier">from_kind</span><span class="plain"> </span><span class="identifier">from_value</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">from_kind</span><span class="plain"> == </span><span class="identifier">TEXT_TY</span><span class="plain">) {</span>
<span class="identifier">BlkValueCopy</span><span class="plain">(</span><span class="identifier">to_txt</span><span class="plain">, </span><span class="identifier">from_value</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">from_kind</span><span class="plain"> == </span><span class="identifier">SNIPPET_TY</span><span class="plain">) {</span>
<span class="identifier">TEXT_TY_Transmute</span><span class="plain">(</span><span class="identifier">to_txt</span><span class="plain">);</span>
<span class="identifier">TEXT_TY_CastPrimitive</span><span class="plain">(</span><span class="identifier">to_txt</span><span class="plain">, </span><span class="reserved">true</span><span class="plain">, </span><span class="identifier">from_value</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">BlkValueError</span><span class="plain">(</span><span class="string">"impossible cast to text"</span><span class="plain">);</span>
<span class="plain">];</span>
2020-01-12 02:35:36 +02:00
<span class="plain">[ </span><span class="identifier">SNIPPET_TY_to_TEXT_TY</span><span class="plain"> </span><span class="identifier">to_txt</span><span class="plain"> </span><span class="identifier">snippet</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">BlkValueCast</span><span class="plain">(</span><span class="identifier">to_txt</span><span class="plain">, </span><span class="identifier">SNIPPET_TY</span><span class="plain">, </span><span class="identifier">snippet</span><span class="plain">);</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP11"></a><b>&#167;11. Data Conversion. </b>We use a single routine to handle two kinds of format translation: a
packed I6 string into an unpacked text, or a snippet into an unpacked text.
</p>
<p class="inwebparagraph">In each case, what we do is simply to print out the value we have, but with
the output stream set to memory rather than the screen. That gives us the
character by character version, neatly laid out in an array, and all we have
to do is to copy it into the text and add a null termination byte.
</p>
<p class="inwebparagraph">What complicates things is that the two virtual machines handle printing
to memory quite differently, and that the original text has unpredictable
length. We are going to try printing it into the array <code class="display"><span class="extract">TEXT_TY_Buffers</span></code>,
but what if the text is too big? Disastrously, the Z-machine simply
writes on in memory, corrupting all subsequent arrays and almost certainly
causing the story file to crash soon after. There is nothing we can do
to predict or avoid this, or to repair the damage: this is why the Inform
documentation warns users to be wary of using text with large
strings in the Z-machine, and advises the use of Glulx instead. Glulx
does handle overruns safely, and indeed allows us to dynamically allocate
memory as necessary so that we can always avoid overruns entirely.
</p>
<pre class="display">
2020-01-12 02:35:36 +02:00
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">TEXT_TY_NoBuffers</span><span class="plain"> = </span><span class="constant">2</span><span class="plain">;</span>
2020-01-12 02:35:36 +02:00
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">TARGET_ZCODE</span><span class="plain">;</span>
<span class="reserved">Array</span><span class="plain"> </span><span class="identifier">TEXT_TY_Buffers</span><span class="plain"> </span><span class="constant">-</span><span class="plain">&gt; </span><span class="identifier">TEXT_TY_BufferSize</span><span class="plain">*</span><span class="identifier">TEXT_TY_NoBuffers</span><span class="plain">; </span><span class="comment">! Where characters are bytes</span>
<span class="plain">#</span><span class="identifier">ifnot</span><span class="plain">;</span>
<span class="reserved">Array</span><span class="plain"> </span><span class="identifier">TEXT_TY_Buffers</span><span class="plain"> </span><span class="constant">--</span><span class="plain">&gt; (</span><span class="identifier">TEXT_TY_BufferSize</span><span class="plain">+2)*</span><span class="identifier">TEXT_TY_NoBuffers</span><span class="plain">; </span><span class="comment">! Where characters are words</span>
<span class="plain">#</span><span class="identifier">endif</span><span class="plain">;</span>
2020-01-12 02:35:36 +02:00
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">RawBufferAddress</span><span class="plain"> = </span><span class="identifier">TEXT_TY_Buffers</span><span class="plain">;</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">RawBufferSize</span><span class="plain"> = </span><span class="identifier">TEXT_TY_BufferSize</span><span class="plain">;</span>
2020-01-12 02:35:36 +02:00
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">TEXT_TY_CastPrimitiveNesting</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP12"></a><b>&#167;12. Z Version. </b>The two versions of this routine, one for each virtual machine, are in all
important respects the same, but there are enough fiddly differences that
it's clearer to give two definitions, so:
</p>
<pre class="display">
2020-01-12 02:35:36 +02:00
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">TARGET_ZCODE</span><span class="plain">;</span>
<span class="plain">[ </span><span class="identifier">TEXT_TY_CastPrimitive</span><span class="plain"> </span><span class="identifier">to_txt</span><span class="plain"> </span><span class="identifier">from_snippet</span><span class="plain"> </span><span class="identifier">from_value</span><span class="plain"> </span><span class="identifier">len</span><span class="plain"> </span><span class="identifier">news</span><span class="plain"> </span><span class="identifier">buffer</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">to_txt</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">BlkValueError</span><span class="plain">(</span><span class="string">"no destination for cast"</span><span class="plain">);</span>
<span class="identifier">SuspendRTP</span><span class="plain">();</span>
<span class="identifier">buffer</span><span class="plain"> = </span><span class="identifier">RawBufferAddress</span><span class="plain"> + </span><span class="identifier">TEXT_TY_CastPrimitiveNesting</span><span class="plain">*</span><span class="identifier">TEXT_TY_BufferSize</span><span class="plain">;</span>
<span class="identifier">TEXT_TY_CastPrimitiveNesting</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">TEXT_TY_CastPrimitiveNesting</span><span class="plain"> &gt; </span><span class="identifier">TEXT_TY_NoBuffers</span><span class="plain">)</span>
<span class="identifier">FlexError</span><span class="plain">(</span><span class="string">"ran out with too many simultaneous text conversions"</span><span class="plain">);</span>
<span class="plain">@</span><span class="identifier">push</span><span class="plain"> </span><span class="identifier">say__p</span><span class="plain">; @</span><span class="identifier">push</span><span class="plain"> </span><span class="identifier">say__pc</span><span class="plain">;</span>
<span class="identifier">ClearParagraphing</span><span class="plain">(6);</span>
<span class="plain">@</span><span class="identifier">output_stream</span><span class="plain"> </span><span class="constant">3</span><span class="plain"> </span><span class="identifier">buffer</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">from_value</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">from_snippet</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> (</span><span class="identifier">PrintSnippet</span><span class="plain">) </span><span class="identifier">from_value</span><span class="plain">;</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">print</span><span class="plain"> (</span><span class="identifier">PrintI6Text</span><span class="plain">) </span><span class="identifier">from_value</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="plain">@</span><span class="identifier">output_stream</span><span class="plain"> </span><span class="constant">-3</span><span class="plain">;</span>
<span class="plain">@</span><span class="identifier">pull</span><span class="plain"> </span><span class="identifier">say__pc</span><span class="plain">; @</span><span class="identifier">pull</span><span class="plain"> </span><span class="identifier">say__p</span><span class="plain">;</span>
<span class="identifier">ResumeRTP</span><span class="plain">();</span>
2020-01-12 02:35:36 +02:00
<span class="identifier">len</span><span class="plain"> = </span><span class="identifier">buffer</span><span class="plain">--&gt;0;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">len</span><span class="plain"> &gt; </span><span class="identifier">RawBufferSize</span><span class="plain">-1) </span><span class="identifier">len</span><span class="plain"> = </span><span class="identifier">RawBufferSize</span><span class="plain">-1;</span>
<span class="identifier">buffer</span><span class="plain">-&gt;(</span><span class="identifier">len</span><span class="plain">+2) = </span><span class="constant">0</span><span class="plain">;</span>
2020-01-12 02:35:36 +02:00
<span class="identifier">TEXT_TY_CastPrimitiveNesting</span><span class="plain">--;</span>
<span class="identifier">BlkValueMassCopyFromArray</span><span class="plain">(</span><span class="identifier">to_txt</span><span class="plain">, </span><span class="identifier">buffer</span><span class="plain">+2, </span><span class="constant">1</span><span class="plain">, </span><span class="identifier">len</span><span class="plain">+1);</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP13"></a><b>&#167;13. Glulx Version. </b></p>
<pre class="display">
2020-01-12 02:35:36 +02:00
<span class="plain">#</span><span class="identifier">ifnot</span><span class="plain">; </span><span class="comment">! TARGET_ZCODE</span>
<span class="plain">[ </span><span class="identifier">TEXT_TY_CastPrimitive</span><span class="plain"> </span><span class="identifier">to_txt</span><span class="plain"> </span><span class="identifier">from_snippet</span><span class="plain"> </span><span class="identifier">from_value</span>
<span class="identifier">len</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> </span><span class="identifier">stream</span><span class="plain"> </span><span class="identifier">saved_stream</span><span class="plain"> </span><span class="identifier">news</span><span class="plain"> </span><span class="identifier">buffer</span><span class="plain"> </span><span class="identifier">buffer_size</span><span class="plain"> </span><span class="identifier">memory_to_free</span><span class="plain"> </span><span class="identifier">results</span><span class="plain">;</span>
2020-01-12 02:35:36 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">to_txt</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">BlkValueError</span><span class="plain">(</span><span class="string">"no destination for cast"</span><span class="plain">);</span>
2020-01-12 02:35:36 +02:00
<span class="identifier">buffer_size</span><span class="plain"> = (</span><span class="identifier">TEXT_TY_BufferSize</span><span class="plain"> + </span><span class="constant">2</span><span class="plain">)*</span><span class="identifier">WORDSIZE</span><span class="plain">;</span>
2020-01-12 02:35:36 +02:00
<span class="identifier">RawBufferSize</span><span class="plain"> = </span><span class="identifier">TEXT_TY_BufferSize</span><span class="plain">;</span>
<span class="identifier">buffer</span><span class="plain"> = </span><span class="identifier">RawBufferAddress</span><span class="plain"> + </span><span class="identifier">TEXT_TY_CastPrimitiveNesting</span><span class="plain">*</span><span class="identifier">buffer_size</span><span class="plain">;</span>
<span class="identifier">TEXT_TY_CastPrimitiveNesting</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">TEXT_TY_CastPrimitiveNesting</span><span class="plain"> &gt; </span><span class="identifier">TEXT_TY_NoBuffers</span><span class="plain">) {</span>
<span class="identifier">buffer</span><span class="plain"> = </span><span class="identifier">VM_AllocateMemory</span><span class="plain">(</span><span class="identifier">buffer_size</span><span class="plain">); </span><span class="identifier">memory_to_free</span><span class="plain"> = </span><span class="identifier">buffer</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">buffer</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">)</span>
<span class="identifier">FlexError</span><span class="plain">(</span><span class="string">"ran out with too many simultaneous text conversions"</span><span class="plain">);</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">unicode_gestalt_ok</span><span class="plain">) {</span>
<span class="identifier">SuspendRTP</span><span class="plain">();</span>
<span class="plain">.</span><span class="identifier">RetryWithLargerBuffer</span><span class="plain">;</span>
<span class="identifier">saved_stream</span><span class="plain"> = </span><span class="identifier">glk_stream_get_current</span><span class="plain">();</span>
<span class="identifier">stream</span><span class="plain"> = </span><span class="identifier">glk_stream_open_memory_uni</span><span class="plain">(</span><span class="identifier">buffer</span><span class="plain">, </span><span class="identifier">RawBufferSize</span><span class="plain">, </span><span class="identifier">filemode_Write</span><span class="plain">, </span><span class="constant">0</span><span class="plain">);</span>
<span class="identifier">glk_stream_set_current</span><span class="plain">(</span><span class="identifier">stream</span><span class="plain">);</span>
<span class="plain">@</span><span class="identifier">push</span><span class="plain"> </span><span class="identifier">say__p</span><span class="plain">; @</span><span class="identifier">push</span><span class="plain"> </span><span class="identifier">say__pc</span><span class="plain">;</span>
<span class="identifier">ClearParagraphing</span><span class="plain">(7);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">from_snippet</span><span class="plain">) </span><span class="reserved">print</span><span class="plain"> (</span><span class="identifier">PrintSnippet</span><span class="plain">) </span><span class="identifier">from_value</span><span class="plain">;</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">print</span><span class="plain"> (</span><span class="identifier">PrintI6Text</span><span class="plain">) </span><span class="identifier">from_value</span><span class="plain">;</span>
<span class="plain">@</span><span class="identifier">pull</span><span class="plain"> </span><span class="identifier">say__pc</span><span class="plain">; @</span><span class="identifier">pull</span><span class="plain"> </span><span class="identifier">say__p</span><span class="plain">;</span>
<span class="identifier">results</span><span class="plain"> = </span><span class="identifier">buffer</span><span class="plain"> + </span><span class="identifier">buffer_size</span><span class="plain"> </span><span class="constant">-</span><span class="plain"> </span><span class="constant">2</span><span class="plain">*</span><span class="identifier">WORDSIZE</span><span class="plain">;</span>
<span class="identifier">glk_stream_close</span><span class="plain">(</span><span class="identifier">stream</span><span class="plain">, </span><span class="identifier">results</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">saved_stream</span><span class="plain">) </span><span class="identifier">glk_stream_set_current</span><span class="plain">(</span><span class="identifier">saved_stream</span><span class="plain">);</span>
<span class="identifier">ResumeRTP</span><span class="plain">();</span>
<span class="identifier">len</span><span class="plain"> = </span><span class="identifier">results</span><span class="plain">--&gt;1;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">len</span><span class="plain"> &gt; </span><span class="identifier">RawBufferSize</span><span class="plain">-1) {</span>
<span class="comment">! Glulx had to truncate text output because the buffer ran out:</span>
<span class="comment">! len is the number of characters which it tried to print</span>
<span class="identifier">news</span><span class="plain"> = </span><span class="identifier">RawBufferSize</span><span class="plain">;</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">news</span><span class="plain"> &lt; </span><span class="identifier">len</span><span class="plain">) </span><span class="identifier">news</span><span class="plain">=</span><span class="identifier">news</span><span class="plain">*2;</span>
<span class="identifier">i</span><span class="plain"> = </span><span class="identifier">VM_AllocateMemory</span><span class="plain">(</span><span class="identifier">news</span><span class="plain">*</span><span class="identifier">WORDSIZE</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="constant">0</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">memory_to_free</span><span class="plain">) </span><span class="identifier">VM_FreeMemory</span><span class="plain">(</span><span class="identifier">memory_to_free</span><span class="plain">);</span>
<span class="identifier">memory_to_free</span><span class="plain"> = </span><span class="identifier">i</span><span class="plain">;</span>
<span class="identifier">buffer</span><span class="plain"> = </span><span class="identifier">i</span><span class="plain">;</span>
<span class="identifier">RawBufferSize</span><span class="plain"> = </span><span class="identifier">news</span><span class="plain">;</span>
<span class="identifier">buffer_size</span><span class="plain"> = (</span><span class="identifier">RawBufferSize</span><span class="plain"> + </span><span class="constant">2</span><span class="plain">)*</span><span class="identifier">WORDSIZE</span><span class="plain">;</span>
<span class="reserved">jump</span><span class="plain"> </span><span class="identifier">RetryWithLargerBuffer</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="comment">! Memory allocation refused: all we can do is to truncate the text</span>
<span class="identifier">len</span><span class="plain"> = </span><span class="identifier">RawBufferSize</span><span class="plain">-1;</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="identifier">buffer</span><span class="plain">--&gt;(</span><span class="identifier">len</span><span class="plain">) = </span><span class="constant">0</span><span class="plain">;</span>
2020-01-12 02:35:36 +02:00
<span class="identifier">TEXT_TY_CastPrimitiveNesting</span><span class="plain">--;</span>
<span class="identifier">BlkValueMassCopyFromArray</span><span class="plain">(</span><span class="identifier">to_txt</span><span class="plain">, </span><span class="identifier">buffer</span><span class="plain">, </span><span class="constant">4</span><span class="plain">, </span><span class="identifier">len</span><span class="plain">+1);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">RunTimeProblem</span><span class="plain">(</span><span class="identifier">RTP_NOGLULXUNICODE</span><span class="plain">);</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">memory_to_free</span><span class="plain">) </span><span class="identifier">VM_FreeMemory</span><span class="plain">(</span><span class="identifier">memory_to_free</span><span class="plain">);</span>
<span class="plain">];</span>
2020-01-12 02:35:36 +02:00
<span class="plain">#</span><span class="identifier">endif</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP14"></a><b>&#167;14. Comparison. </b>This is more or less <code class="display"><span class="extract">strcmp</span></code>, the traditional C library routine for comparing
strings, but it does pose a few interesting questions. The answers are:
</p>
<p class="inwebparagraph"></p>
<ul class="items"><li>(a) Two different unexpanded texts with substitutions are never equal, so
"[X]" and "[Y]" aren't equal as texts even if X and Y are equal.
</li><li>(b) Otherwise we test the current value of the text as expanded, so "[X]"
and "17" can be equal as texts if X is 17.
</li></ul>
<pre class="display">
2020-01-12 02:35:36 +02:00
<span class="plain">[ </span><span class="identifier">TEXT_TY_Compare</span><span class="plain"> </span><span class="identifier">left_txt</span><span class="plain"> </span><span class="identifier">right_txt</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain">;</span>
<span class="plain">@</span><span class="identifier">push</span><span class="plain"> </span><span class="identifier">say__comp</span><span class="plain">;</span>
<span class="identifier">say__comp</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">;</span>
<span class="identifier">rv</span><span class="plain"> = </span><span class="identifier">TEXT_TY_Compare_Inner</span><span class="plain">(</span><span class="identifier">left_txt</span><span class="plain">, </span><span class="identifier">right_txt</span><span class="plain">);</span>
<span class="plain">@</span><span class="identifier">pull</span><span class="plain"> </span><span class="identifier">say__comp</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain">;</span>
<span class="plain">];</span>
2020-01-12 02:35:36 +02:00
<span class="plain">[ </span><span class="identifier">TEXT_TY_Compare_Inner</span><span class="plain"> </span><span class="identifier">left_txt</span><span class="plain"> </span><span class="identifier">right_txt</span>
<span class="identifier">pos</span><span class="plain"> </span><span class="identifier">ch1</span><span class="plain"> </span><span class="identifier">ch2</span><span class="plain"> </span><span class="identifier">capacity_left</span><span class="plain"> </span><span class="identifier">capacity_right</span><span class="plain"> </span><span class="identifier">fl</span><span class="plain"> </span><span class="identifier">fr</span><span class="plain"> </span><span class="identifier">cl</span><span class="plain"> </span><span class="identifier">cr</span><span class="plain"> </span><span class="identifier">cpl</span><span class="plain"> </span><span class="identifier">cpr</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">left_txt</span><span class="plain">--&gt;0 &amp; </span><span class="identifier">BLK_BVBITMAP_LONGBLOCKMASK</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">fl</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">right_txt</span><span class="plain">--&gt;0 &amp; </span><span class="identifier">BLK_BVBITMAP_LONGBLOCKMASK</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">fr</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">fl</span><span class="plain"> &amp;&amp; </span><span class="identifier">fr</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">left_txt</span><span class="plain">--&gt;1 </span><span class="reserved">ofclass</span><span class="plain"> </span><span class="identifier">String</span><span class="plain">) &amp;&amp; (</span><span class="identifier">right_txt</span><span class="plain">--&gt;1 </span><span class="reserved">ofclass</span><span class="plain"> </span><span class="identifier">String</span><span class="plain">))</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">left_txt</span><span class="plain">--&gt;1 </span><span class="constant">-</span><span class="plain"> </span><span class="identifier">right_txt</span><span class="plain">--&gt;1;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">left_txt</span><span class="plain">--&gt;1 </span><span class="reserved">ofclass</span><span class="plain"> </span><span class="identifier">Routine</span><span class="plain">) &amp;&amp; (</span><span class="identifier">right_txt</span><span class="plain">--&gt;1 </span><span class="reserved">ofclass</span><span class="plain"> </span><span class="identifier">Routine</span><span class="plain">))</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">left_txt</span><span class="plain">--&gt;1 </span><span class="constant">-</span><span class="plain"> </span><span class="identifier">right_txt</span><span class="plain">--&gt;1;</span>
<span class="identifier">cpl</span><span class="plain"> = </span><span class="identifier">left_txt</span><span class="plain">--&gt;0; </span><span class="identifier">cl</span><span class="plain"> = </span><span class="identifier">TEXT_TY_Temporarily_Transmute</span><span class="plain">(</span><span class="identifier">left_txt</span><span class="plain">);</span>
<span class="identifier">cpr</span><span class="plain"> = </span><span class="identifier">right_txt</span><span class="plain">--&gt;0; </span><span class="identifier">cr</span><span class="plain"> = </span><span class="identifier">TEXT_TY_Temporarily_Transmute</span><span class="plain">(</span><span class="identifier">right_txt</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">fl</span><span class="plain">) {</span>
<span class="identifier">cpl</span><span class="plain"> = </span><span class="identifier">left_txt</span><span class="plain">--&gt;0; </span><span class="identifier">cl</span><span class="plain"> = </span><span class="identifier">TEXT_TY_Temporarily_Transmute</span><span class="plain">(</span><span class="identifier">left_txt</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">fr</span><span class="plain">) {</span>
<span class="identifier">cpr</span><span class="plain"> = </span><span class="identifier">right_txt</span><span class="plain">--&gt;0; </span><span class="identifier">cr</span><span class="plain"> = </span><span class="identifier">TEXT_TY_Temporarily_Transmute</span><span class="plain">(</span><span class="identifier">right_txt</span><span class="plain">);</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">cl</span><span class="plain">) || (</span><span class="identifier">cr</span><span class="plain">)) {</span>
<span class="identifier">pos</span><span class="plain"> = </span><span class="identifier">TEXT_TY_Compare</span><span class="plain">(</span><span class="identifier">left_txt</span><span class="plain">, </span><span class="identifier">right_txt</span><span class="plain">);</span>
<span class="identifier">TEXT_TY_Untransmute</span><span class="plain">(</span><span class="identifier">left_txt</span><span class="plain">, </span><span class="identifier">cl</span><span class="plain">, </span><span class="identifier">cpl</span><span class="plain">);</span>
<span class="identifier">TEXT_TY_Untransmute</span><span class="plain">(</span><span class="identifier">right_txt</span><span class="plain">, </span><span class="identifier">cr</span><span class="plain">, </span><span class="identifier">cpr</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">pos</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="identifier">capacity_left</span><span class="plain"> = </span><span class="identifier">BlkValueLBCapacity</span><span class="plain">(</span><span class="identifier">left_txt</span><span class="plain">);</span>
<span class="identifier">capacity_right</span><span class="plain"> = </span><span class="identifier">BlkValueLBCapacity</span><span class="plain">(</span><span class="identifier">right_txt</span><span class="plain">);</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">pos</span><span class="plain">=0:(</span><span class="identifier">pos</span><span class="plain">&lt;</span><span class="identifier">capacity_left</span><span class="plain">) &amp;&amp; (</span><span class="identifier">pos</span><span class="plain">&lt;</span><span class="identifier">capacity_right</span><span class="plain">):</span><span class="identifier">pos</span><span class="plain">++) {</span>
<span class="identifier">ch1</span><span class="plain"> = </span><span class="identifier">BlkValueRead</span><span class="plain">(</span><span class="identifier">left_txt</span><span class="plain">, </span><span class="identifier">pos</span><span class="plain">);</span>
<span class="identifier">ch2</span><span class="plain"> = </span><span class="identifier">BlkValueRead</span><span class="plain">(</span><span class="identifier">right_txt</span><span class="plain">, </span><span class="identifier">pos</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ch1</span><span class="plain"> ~= </span><span class="identifier">ch2</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">ch1</span><span class="plain">-</span><span class="identifier">ch2</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ch1</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">0</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pos</span><span class="plain"> == </span><span class="identifier">capacity_left</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">-1</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="constant">1</span><span class="plain">;</span>
<span class="plain">];</span>
2020-01-12 02:35:36 +02:00
<span class="plain">[ </span><span class="identifier">TEXT_TY_Distinguish</span><span class="plain"> </span><span class="identifier">left_txt</span><span class="plain"> </span><span class="identifier">right_txt</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">TEXT_TY_Compare</span><span class="plain">(</span><span class="identifier">left_txt</span><span class="plain">, </span><span class="identifier">right_txt</span><span class="plain">) == </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">rfalse</span><span class="plain">;</span>
<span class="reserved">rtrue</span><span class="plain">;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP15"></a><b>&#167;15. Hashing. </b>This calculates a hash value for the string, using Bernstein's algorithm.
</p>
<pre class="display">
2020-01-12 02:35:36 +02:00
<span class="plain">[ </span><span class="identifier">TEXT_TY_Hash</span><span class="plain"> </span><span class="identifier">txt</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain"> </span><span class="identifier">len</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> </span><span class="identifier">p</span><span class="plain"> </span><span class="identifier">cp</span><span class="plain">;</span>
<span class="identifier">cp</span><span class="plain"> = </span><span class="identifier">txt</span><span class="plain">--&gt;0; </span><span class="identifier">p</span><span class="plain"> = </span><span class="identifier">TEXT_TY_Temporarily_Transmute</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">);</span>
<span class="identifier">rv</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">len</span><span class="plain"> = </span><span class="identifier">BlkValueLBCapacity</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">);</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0: </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">len</span><span class="plain">: </span><span class="identifier">i</span><span class="plain">++)</span>
<span class="identifier">rv</span><span class="plain"> = </span><span class="identifier">rv</span><span class="plain"> * </span><span class="constant">33</span><span class="plain"> + </span><span class="identifier">BlkValueRead</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">);</span>
<span class="identifier">TEXT_TY_Untransmute</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">cp</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain">;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP16"></a><b>&#167;16. Printing. </b>Unicode is not the native character set on Glulx: it came along as a late
addition to Glulx's specification. The deal is that we have to explicitly
tell the Glk interface layer to perform certain operations in a Unicode way;
if we simply perform <code class="display"><span class="extract">print (char) ch;</span></code> then the character <code class="display"><span class="extract">ch</span></code> will be
printed in ZSCII rather than Unicode.
</p>
<pre class="display">
2020-01-12 02:35:36 +02:00
<span class="plain">[ </span><span class="identifier">TEXT_TY_Say</span><span class="plain"> </span><span class="identifier">txt</span><span class="plain"> </span><span class="identifier">ch</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> </span><span class="identifier">dsize</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">txt</span><span class="plain">==0) </span><span class="reserved">rfalse</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">txt</span><span class="plain">--&gt;0 &amp; </span><span class="identifier">BLK_BVBITMAP_LONGBLOCKMASK</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">PrintI6Text</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">--&gt;1);</span>
<span class="identifier">dsize</span><span class="plain"> = </span><span class="identifier">BlkValueLBCapacity</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">);</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0: </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">dsize</span><span class="plain">: </span><span class="identifier">i</span><span class="plain">++) {</span>
<span class="identifier">ch</span><span class="plain"> = </span><span class="identifier">BlkValueRead</span><span class="plain">(</span><span class="identifier">txt</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">ch</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">TARGET_ZCODE</span><span class="plain">;</span>
<span class="reserved">print</span><span class="plain"> (</span><span class="identifier">char</span><span class="plain">) </span><span class="identifier">ch</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">ifnot</span><span class="plain">; </span><span class="comment">! TARGET_ZCODE</span>
<span class="plain">@</span><span class="identifier">streamunichar</span><span class="plain"> </span><span class="identifier">ch</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">rfalse</span><span class="plain">;</span>
<span class="reserved">rtrue</span><span class="plain">;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP17"></a><b>&#167;17. Capitalised printing. </b>It turns out to be useful to have a variation on this:
</p>
<pre class="display">
2020-01-12 02:35:36 +02:00
<span class="plain">[ </span><span class="identifier">TEXT_TY_Say_Capitalised</span><span class="plain"> </span><span class="identifier">txt</span><span class="plain"> </span><span class="identifier">mod</span><span class="plain"> </span><span class="identifier">rc</span><span class="plain">;</span>
<span class="identifier">mod</span><span class="plain"> = </span><span class="identifier">BlkValueCreate</span><span class="plain">(</span><span class="identifier">TEXT_TY</span><span class="plain">);</span>
<span class="identifier">TEXT_TY_SubstitutedForm</span><span class="plain">(</span><span class="identifier">mod</span><span class="plain">, </span><span class="identifier">txt</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">TEXT_TY_CharacterLength</span><span class="plain">(</span><span class="identifier">mod</span><span class="plain">) &gt; </span><span class="constant">0</span><span class="plain">) {</span>
<span class="identifier">BlkValueWrite</span><span class="plain">(</span><span class="identifier">mod</span><span class="plain">, </span><span class="constant">0</span><span class="plain">, </span><span class="identifier">CharToCase</span><span class="plain">(</span><span class="identifier">BlkValueRead</span><span class="plain">(</span><span class="identifier">mod</span><span class="plain">, </span><span class="constant">0</span><span class="plain">), </span><span class="constant">1</span><span class="plain">));</span>
<span class="identifier">TEXT_TY_Say</span><span class="plain">(</span><span class="identifier">mod</span><span class="plain">);</span>
<span class="identifier">rc</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">;</span>
<span class="identifier">say__p</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="identifier">BlkValueFree</span><span class="plain">(</span><span class="identifier">mod</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">rc</span><span class="plain">;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP18"></a><b>&#167;18. Serialisation. </b>Here we print a serialised form of a text which can later be used
to reconstruct the original text. The printing is apparently to the screen,
but in fact always takes place when the output stream is a file.
</p>
<p class="inwebparagraph">The format chosen is a letter "S" for string, then a comma-separated list
of decimal character codes, ending with the null terminator, and followed by
a semicolon: thus <code class="display"><span class="extract">S65,66,67,0;</span></code> is the serialised form of the text "ABC".
</p>
<pre class="display">
2020-01-12 02:35:36 +02:00
<span class="plain">[ </span><span class="identifier">TEXT_TY_WriteFile</span><span class="plain"> </span><span class="identifier">txt</span><span class="plain"> </span><span class="identifier">len</span><span class="plain"> </span><span class="identifier">pos</span><span class="plain"> </span><span class="identifier">ch</span><span class="plain"> </span><span class="identifier">p</span><span class="plain"> </span><span class="identifier">cp</span><span class="plain">;</span>
<span class="identifier">cp</span><span class="plain"> = </span><span class="identifier">txt</span><span class="plain">--&gt;0; </span><span class="identifier">p</span><span class="plain"> = </span><span class="identifier">TEXT_TY_Temporarily_Transmute</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">);</span>
<span class="identifier">len</span><span class="plain"> = </span><span class="identifier">BlkValueLBCapacity</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">);</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">"S"</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">pos</span><span class="plain">=0: </span><span class="identifier">pos</span><span class="plain">&lt;=</span><span class="identifier">len</span><span class="plain">: </span><span class="identifier">pos</span><span class="plain">++) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pos</span><span class="plain"> == </span><span class="identifier">len</span><span class="plain">) </span><span class="identifier">ch</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">; </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">ch</span><span class="plain"> = </span><span class="identifier">BlkValueRead</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">, </span><span class="identifier">pos</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ch</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) {</span>
<span class="reserved">print</span><span class="plain"> </span><span class="string">"0;"</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">print</span><span class="plain"> </span><span class="identifier">ch</span><span class="plain">, </span><span class="string">","</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="identifier">TEXT_TY_Untransmute</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">cp</span><span class="plain">);</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP19"></a><b>&#167;19. Unserialisation. </b>If that's the word: the reverse process, in which we read a stream of
characters from a file and reconstruct the text which gave rise to
them.
</p>
<pre class="display">
2020-01-12 02:35:36 +02:00
<span class="plain">[ </span><span class="identifier">TEXT_TY_ReadFile</span><span class="plain"> </span><span class="identifier">txt</span><span class="plain"> </span><span class="identifier">auxf</span><span class="plain"> </span><span class="identifier">ch</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> </span><span class="identifier">v</span><span class="plain"> </span><span class="identifier">dg</span><span class="plain"> </span><span class="identifier">pos</span><span class="plain"> </span><span class="identifier">tsize</span><span class="plain"> </span><span class="identifier">p</span><span class="plain">;</span>
<span class="identifier">TEXT_TY_Transmute</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">);</span>
<span class="identifier">tsize</span><span class="plain"> = </span><span class="identifier">BlkValueLBCapacity</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">);</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">ch</span><span class="plain"> ~= </span><span class="constant">32</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="constant">9</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="constant">10</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="constant">13</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="constant">0</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="constant">-1</span><span class="plain">) {</span>
<span class="identifier">ch</span><span class="plain"> = </span><span class="identifier">FileIO_GetC</span><span class="plain">(</span><span class="identifier">auxf</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ch</span><span class="plain"> == </span><span class="character">','</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">';'</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pos</span><span class="plain">+1 &gt;= </span><span class="identifier">tsize</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">BlkValueSetLBCapacity</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">, </span><span class="constant">2</span><span class="plain">*</span><span class="identifier">pos</span><span class="plain">) == </span><span class="reserved">false</span><span class="plain">) </span><span class="reserved">break</span><span class="plain">;</span>
<span class="identifier">tsize</span><span class="plain"> = </span><span class="identifier">BlkValueLBCapacity</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">);</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="identifier">BlkValueWrite</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">, </span><span class="identifier">pos</span><span class="plain">++, </span><span class="identifier">v</span><span class="plain">);</span>
<span class="identifier">v</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ch</span><span class="plain"> == </span><span class="character">';'</span><span class="plain">) </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">dg</span><span class="plain"> = </span><span class="identifier">ch</span><span class="plain"> </span><span class="constant">-</span><span class="plain"> </span><span class="character">'0'</span><span class="plain">;</span>
<span class="identifier">v</span><span class="plain"> = </span><span class="identifier">v</span><span class="plain">*10 + </span><span class="identifier">dg</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="identifier">BlkValueWrite</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">, </span><span class="identifier">pos</span><span class="plain">, </span><span class="constant">0</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">txt</span><span class="plain">;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP20"></a><b>&#167;20. Substitution. </b></p>
<pre class="display">
2020-01-12 02:35:36 +02:00
<span class="plain">[ </span><span class="identifier">TEXT_TY_SubstitutedForm</span><span class="plain"> </span><span class="reserved">to</span><span class="plain"> </span><span class="identifier">txt</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">txt</span><span class="plain">) {</span>
<span class="identifier">BlkValueCopy</span><span class="plain">(</span><span class="reserved">to</span><span class="plain">, </span><span class="identifier">txt</span><span class="plain">);</span>
<span class="identifier">TEXT_TY_Transmute</span><span class="plain">(</span><span class="reserved">to</span><span class="plain">);</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="reserved">return</span><span class="plain"> </span><span class="reserved">to</span><span class="plain">;</span>
<span class="plain">];</span>
2020-01-12 02:35:36 +02:00
<span class="plain">[ </span><span class="identifier">TEXT_TY_IsSubstituted</span><span class="plain"> </span><span class="identifier">txt</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">txt</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">txt</span><span class="plain">--&gt;0 &amp; </span><span class="identifier">BLK_BVBITMAP_LONGBLOCKMASK</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">txt</span><span class="plain">--&gt;1 </span><span class="reserved">ofclass</span><span class="plain"> </span><span class="identifier">Routine</span><span class="plain">)) </span><span class="reserved">rfalse</span><span class="plain">;</span>
<span class="reserved">rtrue</span><span class="plain">;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP21"></a><b>&#167;21. Perishability. </b>As noted above, a perishable constant is one which must be expanded before
the values it refers to vanish from existence.
</p>
<pre class="display">
2020-01-12 02:35:36 +02:00
<span class="plain">[ </span><span class="identifier">TEXT_TY_ExpandIfPerishable</span><span class="plain"> </span><span class="reserved">to</span><span class="plain"> </span><span class="identifier">from</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">from</span><span class="plain">) &amp;&amp; (</span><span class="identifier">from</span><span class="plain">--&gt;0 == </span><span class="identifier">CONSTANT_PERISHABLE_TEXT_STORAGE</span><span class="plain">))</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TEXT_TY_SubstitutedForm</span><span class="plain">(</span><span class="reserved">to</span><span class="plain">, </span><span class="identifier">from</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">from</span><span class="plain">;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP22"></a><b>&#167;22. Blobs. </b>That completes the compulsory services required for this KOV to function:
from here on, the remaining routines provide definitions of text-related
phrases in the Standard Rules.
</p>
<p class="inwebparagraph">What are the basic operations of text-handling? Clearly we want to be able
to search, and replace, but that is left for the segment "RegExp.i6t"
to handle. More basically we would like to be able to read and write
characters from the text. But texts in I7 tend to be of natural language,
rather than containing arbitrary material &mdash; that's indeed why we call them
texts rather than strings. This means they are likely to be punctuated
sequences of words, divided up perhaps into sentences and even paragraphs.
</p>
<p class="inwebparagraph">So we provide facilities which regard a text as being an array of "blobs",
where a "blob" is a unit of text. The user can choose whether to see it
as an array of characters, or words (of three different sorts: see the
Inform documentation for details), or paragraphs, or lines.
</p>
<pre class="display">
2020-01-12 02:35:36 +02:00
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">CHR_BLOB</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">; </span><span class="comment">! Construe as an array of characters</span>
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">WORD_BLOB</span><span class="plain"> = </span><span class="constant">2</span><span class="plain">; </span><span class="comment">! Of words</span>
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">PWORD_BLOB</span><span class="plain"> = </span><span class="constant">3</span><span class="plain">; </span><span class="comment">! Of punctuated words</span>
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">UWORD_BLOB</span><span class="plain"> = </span><span class="constant">4</span><span class="plain">; </span><span class="comment">! Of unpunctuated words</span>
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">PARA_BLOB</span><span class="plain"> = </span><span class="constant">5</span><span class="plain">; </span><span class="comment">! Of paragraphs</span>
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">LINE_BLOB</span><span class="plain"> = </span><span class="constant">6</span><span class="plain">; </span><span class="comment">! Of lines</span>
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">REGEXP_BLOB</span><span class="plain"> = </span><span class="constant">7</span><span class="plain">; </span><span class="comment">! Not a blob type as such, but needed as a distinct value</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP23"></a><b>&#167;23. Blob Access. </b>The following routine runs a small finite-state-machine to count the number
of blobs in a text, using any of the above blob types (except
<code class="display"><span class="extract">REGEXP_BLOB</span></code>, which is used for other purposes). If the optional arguments
<code class="display"><span class="extract">ctxt</span></code> and <code class="display"><span class="extract">wanted</span></code> are supplied, it also copies the text of blob number
<code class="display"><span class="extract">wanted</span></code> (counting upwards from 1 at the start of the text) into the
text <code class="display"><span class="extract">ctxt</span></code>. If the further optional argument <code class="display"><span class="extract">rtxt</span></code> is supplied,
then <code class="display"><span class="extract">ctxt</span></code> is instead written with the original text <code class="display"><span class="extract">txt</span></code> as it would
read if the blob in question were replaced with the text in <code class="display"><span class="extract">rtxt</span></code>.
</p>
<pre class="display">
2020-01-12 02:35:36 +02:00
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">WS_BRM</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">;</span>
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">SKIPPED_BRM</span><span class="plain"> = </span><span class="constant">2</span><span class="plain">;</span>
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">ACCEPTED_BRM</span><span class="plain"> = </span><span class="constant">3</span><span class="plain">;</span>
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">ACCEPTEDP_BRM</span><span class="plain"> = </span><span class="constant">4</span><span class="plain">;</span>
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">ACCEPTEDN_BRM</span><span class="plain"> = </span><span class="constant">5</span><span class="plain">;</span>
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">ACCEPTEDPN_BRM</span><span class="plain"> = </span><span class="constant">6</span><span class="plain">;</span>
<span class="plain">[ </span><span class="identifier">TEXT_TY_BlobAccess</span><span class="plain"> </span><span class="identifier">txt</span><span class="plain"> </span><span class="identifier">blobtype</span><span class="plain"> </span><span class="identifier">ctxt</span><span class="plain"> </span><span class="identifier">wanted</span><span class="plain"> </span><span class="identifier">rtxt</span>
<span class="identifier">p1</span><span class="plain"> </span><span class="identifier">p2</span><span class="plain"> </span><span class="identifier">cp1</span><span class="plain"> </span><span class="identifier">cp2</span><span class="plain"> </span><span class="identifier">r</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">txt</span><span class="plain">==0) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">0</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">blobtype</span><span class="plain"> == </span><span class="identifier">CHR_BLOB</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TEXT_TY_CharacterLength</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">);</span>
<span class="identifier">cp1</span><span class="plain"> = </span><span class="identifier">txt</span><span class="plain">--&gt;0; </span><span class="identifier">p1</span><span class="plain"> = </span><span class="identifier">TEXT_TY_Temporarily_Transmute</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">);</span>
<span class="identifier">cp2</span><span class="plain"> = </span><span class="identifier">rtxt</span><span class="plain">--&gt;0; </span><span class="identifier">p2</span><span class="plain"> = </span><span class="identifier">TEXT_TY_Temporarily_Transmute</span><span class="plain">(</span><span class="identifier">rtxt</span><span class="plain">);</span>
<span class="identifier">TEXT_TY_Transmute</span><span class="plain">(</span><span class="identifier">ctxt</span><span class="plain">);</span>
<span class="identifier">r</span><span class="plain"> = </span><span class="identifier">TEXT_TY_BlobAccessI</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">, </span><span class="identifier">blobtype</span><span class="plain">, </span><span class="identifier">ctxt</span><span class="plain">, </span><span class="identifier">wanted</span><span class="plain">, </span><span class="identifier">rtxt</span><span class="plain">);</span>
<span class="identifier">TEXT_TY_Untransmute</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">, </span><span class="identifier">p1</span><span class="plain">, </span><span class="identifier">cp1</span><span class="plain">);</span>
<span class="identifier">TEXT_TY_Untransmute</span><span class="plain">(</span><span class="identifier">rtxt</span><span class="plain">, </span><span class="identifier">p2</span><span class="plain">, </span><span class="identifier">cp2</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">r</span><span class="plain">;</span>
<span class="plain">];</span>
2020-01-12 02:35:36 +02:00
<span class="plain">[ </span><span class="identifier">TEXT_TY_BlobAccessI</span><span class="plain"> </span><span class="identifier">txt</span><span class="plain"> </span><span class="identifier">blobtype</span><span class="plain"> </span><span class="identifier">ctxt</span><span class="plain"> </span><span class="identifier">wanted</span><span class="plain"> </span><span class="identifier">rtxt</span>
<span class="identifier">brm</span><span class="plain"> </span><span class="identifier">oldbrm</span><span class="plain"> </span><span class="identifier">ch</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> </span><span class="identifier">dsize</span><span class="plain"> </span><span class="identifier">csize</span><span class="plain"> </span><span class="identifier">blobcount</span><span class="plain"> </span><span class="identifier">gp</span><span class="plain"> </span><span class="identifier">cl</span><span class="plain"> </span><span class="identifier">j</span><span class="plain">;</span>
<span class="identifier">dsize</span><span class="plain"> = </span><span class="identifier">BlkValueLBCapacity</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ctxt</span><span class="plain">) </span><span class="identifier">csize</span><span class="plain"> = </span><span class="identifier">BlkValueLBCapacity</span><span class="plain">(</span><span class="identifier">ctxt</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">rtxt</span><span class="plain">) </span><span class="string">"*** rtxt without ctxt ***"</span><span class="plain">;</span>
<span class="identifier">brm</span><span class="plain"> = </span><span class="identifier">WS_BRM</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0:</span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">dsize</span><span class="plain">:</span><span class="identifier">i</span><span class="plain">++) {</span>
<span class="identifier">ch</span><span class="plain"> = </span><span class="identifier">BlkValueRead</span><span class="plain">(</span><span class="identifier">txt</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">ch</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">break</span><span class="plain">;</span>
<span class="identifier">oldbrm</span><span class="plain"> = </span><span class="identifier">brm</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ch</span><span class="plain"> == </span><span class="constant">10</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="constant">13</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="constant">32</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="constant">9</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">oldbrm</span><span class="plain"> ~= </span><span class="identifier">WS_BRM</span><span class="plain">) {</span>
<span class="identifier">gp</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">=</span><span class="identifier">i</span><span class="plain">:</span><span class="identifier">j</span><span class="plain">&lt;</span><span class="identifier">dsize</span><span class="plain">:</span><span class="identifier">j</span><span class="plain">++) {</span>
<span class="identifier">ch</span><span class="plain"> = </span><span class="identifier">BlkValueRead</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">, </span><span class="identifier">j</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ch</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) { </span><span class="identifier">brm</span><span class="plain"> = </span><span class="identifier">WS_BRM</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ch</span><span class="plain"> == </span><span class="constant">10</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="constant">13</span><span class="plain">) { </span><span class="identifier">gp</span><span class="plain">++; </span><span class="reserved">continue</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ch</span><span class="plain"> ~= </span><span class="constant">32</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="constant">9</span><span class="plain">) </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="identifier">ch</span><span class="plain"> = </span><span class="identifier">BlkValueRead</span><span class="plain">(</span><span class="identifier">txt</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">j</span><span class="plain"> == </span><span class="identifier">dsize</span><span class="plain">) </span><span class="identifier">brm</span><span class="plain"> = </span><span class="identifier">WS_BRM</span><span class="plain">;</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">blobtype</span><span class="plain">) {</span>
<span class="identifier">PARA_BLOB</span><span class="plain">: </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">gp</span><span class="plain"> &gt;= </span><span class="constant">2</span><span class="plain">) </span><span class="identifier">brm</span><span class="plain"> = </span><span class="identifier">WS_BRM</span><span class="plain">;</span>
<span class="identifier">LINE_BLOB</span><span class="plain">: </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">gp</span><span class="plain"> &gt;= </span><span class="constant">1</span><span class="plain">) </span><span class="identifier">brm</span><span class="plain"> = </span><span class="identifier">WS_BRM</span><span class="plain">;</span>
<span class="reserved">default</span><span class="plain">: </span><span class="identifier">brm</span><span class="plain"> = </span><span class="identifier">WS_BRM</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">gp</span><span class="plain"> = </span><span class="reserved">false</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">blobtype</span><span class="plain"> == </span><span class="identifier">WORD_BLOB</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">PWORD_BLOB</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">UWORD_BLOB</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">ch</span><span class="plain"> == </span><span class="character">'.'</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">','</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">'!'</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">'?'</span>
<span class="reserved">or</span><span class="plain"> </span><span class="character">'-'</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">'/'</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">'"'</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">':'</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">';'</span>
<span class="reserved">or</span><span class="plain"> </span><span class="character">'('</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">')'</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">'['</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">']'</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">'{'</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">'}'</span><span class="plain">))</span>
<span class="identifier">gp</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">;</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">oldbrm</span><span class="plain">) {</span>
<span class="identifier">WS_BRM</span><span class="plain">:</span>
<span class="identifier">brm</span><span class="plain"> = </span><span class="identifier">ACCEPTED_BRM</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">blobtype</span><span class="plain"> == </span><span class="identifier">WORD_BLOB</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">gp</span><span class="plain">) </span><span class="identifier">brm</span><span class="plain"> = </span><span class="identifier">SKIPPED_BRM</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">blobtype</span><span class="plain"> == </span><span class="identifier">PWORD_BLOB</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">gp</span><span class="plain">) </span><span class="identifier">brm</span><span class="plain"> = </span><span class="identifier">ACCEPTEDP_BRM</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="identifier">SKIPPED_BRM</span><span class="plain">:</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">blobtype</span><span class="plain"> == </span><span class="identifier">WORD_BLOB</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">gp</span><span class="plain"> == </span><span class="reserved">false</span><span class="plain">) </span><span class="identifier">brm</span><span class="plain"> = </span><span class="identifier">ACCEPTED_BRM</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="identifier">ACCEPTED_BRM</span><span class="plain">:</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">blobtype</span><span class="plain"> == </span><span class="identifier">WORD_BLOB</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">gp</span><span class="plain">) </span><span class="identifier">brm</span><span class="plain"> = </span><span class="identifier">SKIPPED_BRM</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">blobtype</span><span class="plain"> == </span><span class="identifier">PWORD_BLOB</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">gp</span><span class="plain">) </span><span class="identifier">brm</span><span class="plain"> = </span><span class="identifier">ACCEPTEDP_BRM</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="identifier">ACCEPTEDP_BRM</span><span class="plain">:</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">blobtype</span><span class="plain"> == </span><span class="identifier">PWORD_BLOB</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">gp</span><span class="plain"> == </span><span class="reserved">false</span><span class="plain">) </span><span class="identifier">brm</span><span class="plain"> = </span><span class="identifier">ACCEPTED_BRM</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">ch</span><span class="plain"> == </span><span class="identifier">BlkValueRead</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">-1)) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">ch</span><span class="plain"> == </span><span class="character">'-'</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">'.'</span><span class="plain">)) </span><span class="identifier">blobcount</span><span class="plain">--;</span>
<span class="identifier">blobcount</span><span class="plain">++;</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="identifier">ACCEPTEDN_BRM</span><span class="plain">:</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">blobtype</span><span class="plain"> == </span><span class="identifier">WORD_BLOB</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">gp</span><span class="plain">) </span><span class="identifier">brm</span><span class="plain"> = </span><span class="identifier">SKIPPED_BRM</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">blobtype</span><span class="plain"> == </span><span class="identifier">PWORD_BLOB</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">gp</span><span class="plain">) </span><span class="identifier">brm</span><span class="plain"> = </span><span class="identifier">ACCEPTEDP_BRM</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="identifier">ACCEPTEDPN_BRM</span><span class="plain">:</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">blobtype</span><span class="plain"> == </span><span class="identifier">PWORD_BLOB</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">gp</span><span class="plain"> == </span><span class="reserved">false</span><span class="plain">) </span><span class="identifier">brm</span><span class="plain"> = </span><span class="identifier">ACCEPTED_BRM</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">ch</span><span class="plain"> == </span><span class="identifier">BlkValueRead</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">-1)) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">ch</span><span class="plain"> == </span><span class="character">'-'</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">'.'</span><span class="plain">)) </span><span class="identifier">blobcount</span><span class="plain">--;</span>
<span class="identifier">blobcount</span><span class="plain">++;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">brm</span><span class="plain"> == </span><span class="identifier">ACCEPTED_BRM</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">ACCEPTEDP_BRM</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">oldbrm</span><span class="plain"> ~= </span><span class="identifier">brm</span><span class="plain">) </span><span class="identifier">blobcount</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">ctxt</span><span class="plain">) &amp;&amp; (</span><span class="identifier">blobcount</span><span class="plain"> == </span><span class="identifier">wanted</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rtxt</span><span class="plain">) {</span>
<span class="identifier">BlkValueWrite</span><span class="plain">(</span><span class="identifier">ctxt</span><span class="plain">, </span><span class="identifier">cl</span><span class="plain">, </span><span class="constant">0</span><span class="plain">);</span>
<span class="identifier">TEXT_TY_Concatenate</span><span class="plain">(</span><span class="identifier">ctxt</span><span class="plain">, </span><span class="identifier">rtxt</span><span class="plain">, </span><span class="identifier">CHR_BLOB</span><span class="plain">);</span>
<span class="identifier">csize</span><span class="plain"> = </span><span class="identifier">BlkValueLBCapacity</span><span class="plain">(</span><span class="identifier">ctxt</span><span class="plain">);</span>
<span class="identifier">cl</span><span class="plain"> = </span><span class="identifier">TEXT_TY_CharacterLength</span><span class="plain">(</span><span class="identifier">ctxt</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">brm</span><span class="plain"> == </span><span class="identifier">ACCEPTED_BRM</span><span class="plain">) </span><span class="identifier">brm</span><span class="plain"> = </span><span class="identifier">ACCEPTEDN_BRM</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">brm</span><span class="plain"> == </span><span class="identifier">ACCEPTEDP_BRM</span><span class="plain">) </span><span class="identifier">brm</span><span class="plain"> = </span><span class="identifier">ACCEPTEDPN_BRM</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">cl</span><span class="plain">+1 &gt;= </span><span class="identifier">csize</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">BlkValueSetLBCapacity</span><span class="plain">(</span><span class="identifier">ctxt</span><span class="plain">, </span><span class="constant">2</span><span class="plain">*</span><span class="identifier">cl</span><span class="plain">) == </span><span class="reserved">false</span><span class="plain">) </span><span class="reserved">break</span><span class="plain">;</span>
<span class="identifier">csize</span><span class="plain"> = </span><span class="identifier">BlkValueLBCapacity</span><span class="plain">(</span><span class="identifier">ctxt</span><span class="plain">);</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="identifier">BlkValueWrite</span><span class="plain">(</span><span class="identifier">ctxt</span><span class="plain">, </span><span class="identifier">cl</span><span class="plain">++, </span><span class="identifier">ch</span><span class="plain">);</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<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">rtxt</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">cl</span><span class="plain">+1 &gt;= </span><span class="identifier">csize</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">BlkValueSetLBCapacity</span><span class="plain">(</span><span class="identifier">ctxt</span><span class="plain">, </span><span class="constant">2</span><span class="plain">*</span><span class="identifier">cl</span><span class="plain">) == </span><span class="reserved">false</span><span class="plain">) </span><span class="reserved">break</span><span class="plain">;</span>
<span class="identifier">csize</span><span class="plain"> = </span><span class="identifier">BlkValueLBCapacity</span><span class="plain">(</span><span class="identifier">ctxt</span><span class="plain">);</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="identifier">BlkValueWrite</span><span class="plain">(</span><span class="identifier">ctxt</span><span class="plain">, </span><span class="identifier">cl</span><span class="plain">++, </span><span class="identifier">ch</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<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">rtxt</span><span class="plain">) &amp;&amp; (</span><span class="identifier">brm</span><span class="plain"> ~= </span><span class="identifier">ACCEPTEDN_BRM</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">ACCEPTEDPN_BRM</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">cl</span><span class="plain">+1 &gt;= </span><span class="identifier">csize</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">BlkValueSetLBCapacity</span><span class="plain">(</span><span class="identifier">ctxt</span><span class="plain">, </span><span class="constant">2</span><span class="plain">*</span><span class="identifier">cl</span><span class="plain">) == </span><span class="reserved">false</span><span class="plain">) </span><span class="reserved">break</span><span class="plain">;</span>
<span class="identifier">csize</span><span class="plain"> = </span><span class="identifier">BlkValueLBCapacity</span><span class="plain">(</span><span class="identifier">ctxt</span><span class="plain">);</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="identifier">BlkValueWrite</span><span class="plain">(</span><span class="identifier">ctxt</span><span class="plain">, </span><span class="identifier">cl</span><span class="plain">++, </span><span class="identifier">ch</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ctxt</span><span class="plain">) </span><span class="identifier">BlkValueWrite</span><span class="plain">(</span><span class="identifier">ctxt</span><span class="plain">, </span><span class="identifier">cl</span><span class="plain">++, </span><span class="constant">0</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">blobcount</span><span class="plain">;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP24"></a><b>&#167;24. Get Blob. </b>The front end which uses the above routine to read a blob. (Note that, for
efficiency's sake, we read characters more directly.)
</p>
<pre class="display">
2020-01-12 02:35:36 +02:00
<span class="plain">[ </span><span class="identifier">TEXT_TY_GetBlob</span><span class="plain"> </span><span class="identifier">ctxt</span><span class="plain"> </span><span class="identifier">txt</span><span class="plain"> </span><span class="identifier">wanted</span><span class="plain"> </span><span class="identifier">blobtype</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">txt</span><span class="plain">==0) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">blobtype</span><span class="plain"> == </span><span class="identifier">CHR_BLOB</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TEXT_TY_GetCharacter</span><span class="plain">(</span><span class="identifier">ctxt</span><span class="plain">, </span><span class="identifier">txt</span><span class="plain">, </span><span class="identifier">wanted</span><span class="plain">);</span>
<span class="identifier">TEXT_TY_BlobAccess</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">, </span><span class="identifier">blobtype</span><span class="plain">, </span><span class="identifier">ctxt</span><span class="plain">, </span><span class="identifier">wanted</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">ctxt</span><span class="plain">;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP25"></a><b>&#167;25. Replace Blob. </b>The front end which uses the above routine to replace a blob. (Once again,
characters are handled directly to avoid incurring all that overhead.)
</p>
<pre class="display">
2020-01-12 02:35:36 +02:00
<span class="plain">[ </span><span class="identifier">TEXT_TY_ReplaceBlob</span><span class="plain"> </span><span class="identifier">blobtype</span><span class="plain"> </span><span class="identifier">txt</span><span class="plain"> </span><span class="identifier">wanted</span><span class="plain"> </span><span class="identifier">rtxt</span><span class="plain"> </span><span class="identifier">ctxt</span><span class="plain"> </span><span class="identifier">ilen</span><span class="plain"> </span><span class="identifier">rlen</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> </span><span class="identifier">p</span><span class="plain"> </span><span class="identifier">cp</span><span class="plain">;</span>
<span class="identifier">TEXT_TY_Transmute</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">);</span>
<span class="identifier">cp</span><span class="plain"> = </span><span class="identifier">rtxt</span><span class="plain">--&gt;0; </span><span class="identifier">p</span><span class="plain"> = </span><span class="identifier">TEXT_TY_Temporarily_Transmute</span><span class="plain">(</span><span class="identifier">rtxt</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">blobtype</span><span class="plain"> == </span><span class="identifier">CHR_BLOB</span><span class="plain">) {</span>
<span class="identifier">ilen</span><span class="plain"> = </span><span class="identifier">TEXT_TY_CharacterLength</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">);</span>
<span class="identifier">rlen</span><span class="plain"> = </span><span class="identifier">TEXT_TY_CharacterLength</span><span class="plain">(</span><span class="identifier">rtxt</span><span class="plain">);</span>
<span class="identifier">wanted</span><span class="plain">--;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">wanted</span><span class="plain"> &gt;= </span><span class="constant">0</span><span class="plain">) &amp;&amp; (</span><span class="identifier">wanted</span><span class="plain">&lt;</span><span class="identifier">ilen</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rlen</span><span class="plain"> == </span><span class="constant">1</span><span class="plain">) {</span>
<span class="identifier">BlkValueWrite</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">, </span><span class="identifier">wanted</span><span class="plain">, </span><span class="identifier">BlkValueRead</span><span class="plain">(</span><span class="identifier">rtxt</span><span class="plain">, </span><span class="constant">0</span><span class="plain">));</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">ctxt</span><span class="plain"> = </span><span class="identifier">BlkValueCreate</span><span class="plain">(</span><span class="identifier">TEXT_TY</span><span class="plain">);</span>
<span class="identifier">TEXT_TY_Transmute</span><span class="plain">(</span><span class="identifier">ctxt</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">BlkValueSetLBCapacity</span><span class="plain">(</span><span class="identifier">ctxt</span><span class="plain">, </span><span class="identifier">ilen</span><span class="plain">+</span><span class="identifier">rlen</span><span class="plain">+1)) {</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0:</span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">wanted</span><span class="plain">:</span><span class="identifier">i</span><span class="plain">++)</span>
<span class="identifier">BlkValueWrite</span><span class="plain">(</span><span class="identifier">ctxt</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">BlkValueRead</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">));</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0:</span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">rlen</span><span class="plain">:</span><span class="identifier">i</span><span class="plain">++)</span>
<span class="identifier">BlkValueWrite</span><span class="plain">(</span><span class="identifier">ctxt</span><span class="plain">, </span><span class="identifier">wanted</span><span class="plain">+</span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">BlkValueRead</span><span class="plain">(</span><span class="identifier">rtxt</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">));</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=</span><span class="identifier">wanted</span><span class="plain">+1:</span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">ilen</span><span class="plain">:</span><span class="identifier">i</span><span class="plain">++)</span>
<span class="identifier">BlkValueWrite</span><span class="plain">(</span><span class="identifier">ctxt</span><span class="plain">, </span><span class="identifier">rlen</span><span class="plain">+</span><span class="identifier">i</span><span class="plain">-1, </span><span class="identifier">BlkValueRead</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">));</span>
<span class="identifier">BlkValueWrite</span><span class="plain">(</span><span class="identifier">ctxt</span><span class="plain">, </span><span class="identifier">rlen</span><span class="plain">+</span><span class="identifier">ilen</span><span class="plain">, </span><span class="constant">0</span><span class="plain">);</span>
<span class="identifier">BlkValueCopy</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">, </span><span class="identifier">ctxt</span><span class="plain">);</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="identifier">BlkValueFree</span><span class="plain">(</span><span class="identifier">ctxt</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">ctxt</span><span class="plain"> = </span><span class="identifier">BlkValueCreate</span><span class="plain">(</span><span class="identifier">TEXT_TY</span><span class="plain">);</span>
<span class="identifier">TEXT_TY_BlobAccess</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">, </span><span class="identifier">blobtype</span><span class="plain">, </span><span class="identifier">ctxt</span><span class="plain">, </span><span class="identifier">wanted</span><span class="plain">, </span><span class="identifier">rtxt</span><span class="plain">);</span>
<span class="identifier">BlkValueCopy</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">, </span><span class="identifier">ctxt</span><span class="plain">);</span>
<span class="identifier">BlkValueFree</span><span class="plain">(</span><span class="identifier">ctxt</span><span class="plain">);</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="identifier">TEXT_TY_Untransmute</span><span class="plain">(</span><span class="identifier">rtxt</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">cp</span><span class="plain">);</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP26"></a><b>&#167;26. Replace Text. </b>This is the general routine which searches for any instance of <code class="display"><span class="extract">ftxt</span></code>,
as a blob, in <code class="display"><span class="extract">txt</span></code>, and replaces it with the text <code class="display"><span class="extract">rtxt</span></code>. It works on
any of the above blob-types, but two cases are special: first, if the
blob-type is <code class="display"><span class="extract">CHR_BLOB</span></code>, then it can do more than search and replace
for any instance of a single character: it can search and replace any
instance of a substring, so that <code class="display"><span class="extract">ftxt</span></code> is not required to be only a
single character. Second, if the blob-type is the special value
<code class="display"><span class="extract">REGEXP_BLOB</span></code> then <code class="display"><span class="extract">ftxt</span></code> is interpreted as a regular expression rather
than something literal to find: see "RegExp.i6t" for what happens next.
</p>
<pre class="display">
2020-01-12 02:35:36 +02:00
<span class="plain">[ </span><span class="identifier">TEXT_TY_ReplaceText</span><span class="plain"> </span><span class="identifier">blobtype</span><span class="plain"> </span><span class="identifier">txt</span><span class="plain"> </span><span class="identifier">ftxt</span><span class="plain"> </span><span class="identifier">rtxt</span>
<span class="identifier">r</span><span class="plain"> </span><span class="identifier">p1</span><span class="plain"> </span><span class="identifier">p2</span><span class="plain"> </span><span class="identifier">cp1</span><span class="plain"> </span><span class="identifier">cp2</span><span class="plain">;</span>
<span class="identifier">TEXT_TY_Transmute</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">);</span>
<span class="identifier">cp1</span><span class="plain"> = </span><span class="identifier">ftxt</span><span class="plain">--&gt;0; </span><span class="identifier">p1</span><span class="plain"> = </span><span class="identifier">TEXT_TY_Temporarily_Transmute</span><span class="plain">(</span><span class="identifier">ftxt</span><span class="plain">);</span>
<span class="identifier">cp2</span><span class="plain"> = </span><span class="identifier">rtxt</span><span class="plain">--&gt;0; </span><span class="identifier">p2</span><span class="plain"> = </span><span class="identifier">TEXT_TY_Temporarily_Transmute</span><span class="plain">(</span><span class="identifier">rtxt</span><span class="plain">);</span>
<span class="identifier">r</span><span class="plain"> = </span><span class="identifier">TEXT_TY_ReplaceTextI</span><span class="plain">(</span><span class="identifier">blobtype</span><span class="plain">, </span><span class="identifier">txt</span><span class="plain">, </span><span class="identifier">ftxt</span><span class="plain">, </span><span class="identifier">rtxt</span><span class="plain">);</span>
<span class="identifier">TEXT_TY_Untransmute</span><span class="plain">(</span><span class="identifier">ftxt</span><span class="plain">, </span><span class="identifier">p1</span><span class="plain">, </span><span class="identifier">cp1</span><span class="plain">);</span>
<span class="identifier">TEXT_TY_Untransmute</span><span class="plain">(</span><span class="identifier">rtxt</span><span class="plain">, </span><span class="identifier">p2</span><span class="plain">, </span><span class="identifier">cp2</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">r</span><span class="plain">;</span>
<span class="plain">];</span>
2020-01-12 02:35:36 +02:00
<span class="plain">[ </span><span class="identifier">TEXT_TY_ReplaceTextI</span><span class="plain"> </span><span class="identifier">blobtype</span><span class="plain"> </span><span class="identifier">txt</span><span class="plain"> </span><span class="identifier">ftxt</span><span class="plain"> </span><span class="identifier">rtxt</span>
<span class="identifier">ctxt</span><span class="plain"> </span><span class="identifier">csize</span><span class="plain"> </span><span class="identifier">ilen</span><span class="plain"> </span><span class="identifier">flen</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> </span><span class="identifier">cl</span><span class="plain"> </span><span class="identifier">mpos</span><span class="plain"> </span><span class="identifier">ch</span><span class="plain"> </span><span class="identifier">chm</span><span class="plain"> </span><span class="identifier">whitespace</span><span class="plain"> </span><span class="identifier">punctuation</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">blobtype</span><span class="plain"> == </span><span class="identifier">REGEXP_BLOB</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="identifier">CHR_BLOB</span><span class="plain">)</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TEXT_TY_Replace_RE</span><span class="plain">(</span><span class="identifier">blobtype</span><span class="plain">, </span><span class="identifier">txt</span><span class="plain">, </span><span class="identifier">ftxt</span><span class="plain">, </span><span class="identifier">rtxt</span><span class="plain">);</span>
<span class="identifier">ilen</span><span class="plain"> = </span><span class="identifier">TEXT_TY_CharacterLength</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">);</span>
<span class="identifier">flen</span><span class="plain"> = </span><span class="identifier">TEXT_TY_CharacterLength</span><span class="plain">(</span><span class="identifier">ftxt</span><span class="plain">);</span>
<span class="identifier">ctxt</span><span class="plain"> = </span><span class="identifier">BlkValueCreate</span><span class="plain">(</span><span class="identifier">TEXT_TY</span><span class="plain">);</span>
<span class="identifier">TEXT_TY_Transmute</span><span class="plain">(</span><span class="identifier">ctxt</span><span class="plain">);</span>
<span class="identifier">csize</span><span class="plain"> = </span><span class="identifier">BlkValueLBCapacity</span><span class="plain">(</span><span class="identifier">ctxt</span><span class="plain">);</span>
<span class="identifier">mpos</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">whitespace</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">; </span><span class="identifier">punctuation</span><span class="plain"> = </span><span class="reserved">false</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0:</span><span class="identifier">i</span><span class="plain">&lt;=</span><span class="identifier">ilen</span><span class="plain">:</span><span class="identifier">i</span><span class="plain">++) {</span>
<span class="identifier">ch</span><span class="plain"> = </span><span class="identifier">BlkValueRead</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">);</span>
<span class="plain">.</span><span class="identifier">MoreMatching</span><span class="plain">;</span>
<span class="identifier">chm</span><span class="plain"> = </span><span class="identifier">BlkValueRead</span><span class="plain">(</span><span class="identifier">ftxt</span><span class="plain">, </span><span class="identifier">mpos</span><span class="plain">++);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">mpos</span><span class="plain"> == </span><span class="constant">1</span><span class="plain">) {</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">blobtype</span><span class="plain">) {</span>
<span class="identifier">WORD_BLOB</span><span class="plain">:</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">whitespace</span><span class="plain"> == </span><span class="reserved">false</span><span class="plain">) &amp;&amp; (</span><span class="identifier">punctuation</span><span class="plain"> == </span><span class="reserved">false</span><span class="plain">)) </span><span class="identifier">chm</span><span class="plain"> = </span><span class="constant">-1</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="identifier">whitespace</span><span class="plain"> = </span><span class="reserved">false</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ch</span><span class="plain"> == </span><span class="constant">10</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="constant">13</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="constant">32</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="constant">9</span><span class="plain">) </span><span class="identifier">whitespace</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">;</span>
<span class="identifier">punctuation</span><span class="plain"> = </span><span class="reserved">false</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ch</span><span class="plain"> == </span><span class="character">'.'</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">','</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">'!'</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">'?'</span>
<span class="reserved">or</span><span class="plain"> </span><span class="character">'-'</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">'/'</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">'"'</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">':'</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">';'</span>
<span class="reserved">or</span><span class="plain"> </span><span class="character">'('</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">')'</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">'['</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">']'</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">'{'</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">'}'</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">blobtype</span><span class="plain"> == </span><span class="identifier">WORD_BLOB</span><span class="plain">) </span><span class="identifier">chm</span><span class="plain"> = </span><span class="constant">-1</span><span class="plain">;</span>
<span class="identifier">punctuation</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ch</span><span class="plain"> == </span><span class="identifier">chm</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">mpos</span><span class="plain"> == </span><span class="identifier">flen</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">ilen</span><span class="plain">) </span><span class="identifier">chm</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">chm</span><span class="plain"> = </span><span class="identifier">BlkValueRead</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">+1);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">blobtype</span><span class="plain"> == </span><span class="identifier">CHR_BLOB</span><span class="plain">) ||</span>
<span class="plain">(</span><span class="identifier">chm</span><span class="plain"> == </span><span class="constant">0</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="constant">10</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="constant">13</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="constant">32</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="constant">9</span><span class="plain">) ||</span>
<span class="plain">(</span><span class="identifier">chm</span><span class="plain"> == </span><span class="character">'.'</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">','</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">'!'</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">'?'</span>
<span class="reserved">or</span><span class="plain"> </span><span class="character">'-'</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">'/'</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">'"'</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">':'</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">';'</span>
<span class="reserved">or</span><span class="plain"> </span><span class="character">'('</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">')'</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">'['</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">']'</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">'{'</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">'}'</span><span class="plain">)) {</span>
<span class="identifier">mpos</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">cl</span><span class="plain"> = </span><span class="identifier">cl</span><span class="plain"> </span><span class="constant">-</span><span class="plain"> (</span><span class="identifier">flen</span><span class="plain">-1);</span>
<span class="identifier">BlkValueWrite</span><span class="plain">(</span><span class="identifier">ctxt</span><span class="plain">, </span><span class="identifier">cl</span><span class="plain">, </span><span class="constant">0</span><span class="plain">);</span>
<span class="identifier">TEXT_TY_Concatenate</span><span class="plain">(</span><span class="identifier">ctxt</span><span class="plain">, </span><span class="identifier">rtxt</span><span class="plain">, </span><span class="identifier">CHR_BLOB</span><span class="plain">);</span>
<span class="identifier">csize</span><span class="plain"> = </span><span class="identifier">BlkValueLBCapacity</span><span class="plain">(</span><span class="identifier">ctxt</span><span class="plain">);</span>
<span class="identifier">cl</span><span class="plain"> = </span><span class="identifier">TEXT_TY_CharacterLength</span><span class="plain">(</span><span class="identifier">ctxt</span><span class="plain">);</span>
<span class="reserved">continue</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">mpos</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">cl</span><span class="plain">+1 &gt;= </span><span class="identifier">csize</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">BlkValueSetLBCapacity</span><span class="plain">(</span><span class="identifier">ctxt</span><span class="plain">, </span><span class="constant">2</span><span class="plain">*</span><span class="identifier">cl</span><span class="plain">) == </span><span class="reserved">false</span><span class="plain">) </span><span class="reserved">break</span><span class="plain">;</span>
<span class="identifier">csize</span><span class="plain"> = </span><span class="identifier">BlkValueLBCapacity</span><span class="plain">(</span><span class="identifier">ctxt</span><span class="plain">);</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="identifier">BlkValueWrite</span><span class="plain">(</span><span class="identifier">ctxt</span><span class="plain">, </span><span class="identifier">cl</span><span class="plain">++, </span><span class="identifier">ch</span><span class="plain">);</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="identifier">BlkValueCopy</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">, </span><span class="identifier">ctxt</span><span class="plain">);</span>
<span class="identifier">BlkValueFree</span><span class="plain">(</span><span class="identifier">ctxt</span><span class="plain">);</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP27"></a><b>&#167;27. Character Length. </b>When accessing at the character-by-character level, things are much easier
and we needn't go through any finite state machine palaver.
</p>
<pre class="display">
2020-01-12 02:35:36 +02:00
<span class="plain">[ </span><span class="identifier">TEXT_TY_CharacterLength</span><span class="plain"> </span><span class="identifier">txt</span><span class="plain"> </span><span class="identifier">ch</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> </span><span class="identifier">dsize</span><span class="plain"> </span><span class="identifier">p</span><span class="plain"> </span><span class="identifier">cp</span><span class="plain"> </span><span class="identifier">r</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">txt</span><span class="plain">==0) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">cp</span><span class="plain"> = </span><span class="identifier">txt</span><span class="plain">--&gt;0; </span><span class="identifier">p</span><span class="plain"> = </span><span class="identifier">TEXT_TY_Temporarily_Transmute</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">);</span>
<span class="identifier">dsize</span><span class="plain"> = </span><span class="identifier">BlkValueLBCapacity</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">); </span><span class="identifier">r</span><span class="plain"> = </span><span class="identifier">dsize</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0:</span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">dsize</span><span class="plain">:</span><span class="identifier">i</span><span class="plain">++) {</span>
<span class="identifier">ch</span><span class="plain"> = </span><span class="identifier">BlkValueRead</span><span class="plain">(</span><span class="identifier">txt</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">ch</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) { </span><span class="identifier">r</span><span class="plain"> = </span><span class="identifier">i</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">; }</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="identifier">TEXT_TY_Untransmute</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">cp</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">r</span><span class="plain">;</span>
<span class="plain">];</span>
2020-01-12 02:35:36 +02:00
<span class="plain">[ </span><span class="identifier">TEXT_TY_Empty</span><span class="plain"> </span><span class="identifier">txt</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">txt</span><span class="plain">==0) </span><span class="reserved">rtrue</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">txt</span><span class="plain">--&gt;0 &amp; </span><span class="identifier">BLK_BVBITMAP_LONGBLOCKMASK</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">txt</span><span class="plain">--&gt;1 == </span><span class="identifier">EMPTY_TEXT_PACKED</span><span class="plain">) </span><span class="reserved">rtrue</span><span class="plain">;</span>
<span class="reserved">rfalse</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">TEXT_TY_CharacterLength</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">) == </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">rtrue</span><span class="plain">;</span>
<span class="reserved">rfalse</span><span class="plain">;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP28"></a><b>&#167;28. Get Character. </b>Characters in a text are numbered upwards from 1 by the users of this
routine: which is why we subtract 1 when reading the array in the
block-value, which counts from 0.
</p>
<pre class="display">
2020-01-12 02:35:36 +02:00
<span class="plain">[ </span><span class="identifier">TEXT_TY_GetCharacter</span><span class="plain"> </span><span class="identifier">ctxt</span><span class="plain"> </span><span class="identifier">txt</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> </span><span class="identifier">ch</span><span class="plain"> </span><span class="identifier">p</span><span class="plain"> </span><span class="identifier">cp</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">txt</span><span class="plain">==0) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">cp</span><span class="plain"> = </span><span class="identifier">txt</span><span class="plain">--&gt;0; </span><span class="identifier">p</span><span class="plain"> = </span><span class="identifier">TEXT_TY_Temporarily_Transmute</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">);</span>
<span class="identifier">TEXT_TY_Transmute</span><span class="plain">(</span><span class="identifier">ctxt</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">i</span><span class="plain">&lt;=0) || (</span><span class="identifier">i</span><span class="plain">&gt;</span><span class="identifier">TEXT_TY_CharacterLength</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">))) </span><span class="identifier">ch</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">ch</span><span class="plain"> = </span><span class="identifier">BlkValueRead</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">-1);</span>
<span class="identifier">BlkValueWrite</span><span class="plain">(</span><span class="identifier">ctxt</span><span class="plain">, </span><span class="constant">0</span><span class="plain">, </span><span class="identifier">ch</span><span class="plain">);</span>
<span class="identifier">BlkValueWrite</span><span class="plain">(</span><span class="identifier">ctxt</span><span class="plain">, </span><span class="constant">1</span><span class="plain">, </span><span class="constant">0</span><span class="plain">);</span>
<span class="identifier">TEXT_TY_Untransmute</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">cp</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">ctxt</span><span class="plain">;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP29"></a><b>&#167;29. Casing. </b>In many programming languages, characters are a distinct data type from
strings, but not in I7. To I7, a character is simply a text which
happens to have length 1 &mdash; this has its inefficiencies, but is conceptually
easy for the user.
</p>
<p class="inwebparagraph"><code class="display"><span class="extract">TEXT_TY_CharactersOfCase(txt, case)</span></code> determines whether all the characters in <code class="display"><span class="extract">txt</span></code>
are letters of the given casing: 0 for lower case, 1 for upper case. In the
case of ZSCII, this is done correctly handling all of the European accented
letters; in the case of Unicode, it follows the Unicode standard.
</p>
<p class="inwebparagraph">Note that there is no requirement for <code class="display"><span class="extract">txt</span></code> to be only a single character
long.
</p>
<pre class="display">
2020-01-12 02:35:36 +02:00
<span class="plain">[ </span><span class="identifier">TEXT_TY_CharactersOfCase</span><span class="plain"> </span><span class="identifier">txt</span><span class="plain"> </span><span class="identifier">case</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> </span><span class="identifier">ch</span><span class="plain"> </span><span class="identifier">len</span><span class="plain"> </span><span class="identifier">p</span><span class="plain"> </span><span class="identifier">cp</span><span class="plain"> </span><span class="identifier">r</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">txt</span><span class="plain">==0) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">cp</span><span class="plain"> = </span><span class="identifier">txt</span><span class="plain">--&gt;0; </span><span class="identifier">p</span><span class="plain"> = </span><span class="identifier">TEXT_TY_Temporarily_Transmute</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">);</span>
<span class="identifier">len</span><span class="plain"> = </span><span class="identifier">TEXT_TY_CharacterLength</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">);</span>
<span class="identifier">r</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0:</span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">len</span><span class="plain">:</span><span class="identifier">i</span><span class="plain">++) {</span>
<span class="identifier">ch</span><span class="plain"> = </span><span class="identifier">BlkValueRead</span><span class="plain">(</span><span class="identifier">txt</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">ch</span><span class="plain">) &amp;&amp; (</span><span class="identifier">CharIsOfCase</span><span class="plain">(</span><span class="identifier">ch</span><span class="plain">, </span><span class="identifier">case</span><span class="plain">) == </span><span class="reserved">false</span><span class="plain">)) { </span><span class="identifier">r</span><span class="plain"> = </span><span class="reserved">false</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">; }</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="identifier">TEXT_TY_Untransmute</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">cp</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">r</span><span class="plain">;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP30"></a><b>&#167;30. Change Case. </b>We set <code class="display"><span class="extract">ctxt</span></code> to the text in <code class="display"><span class="extract">txt</span></code>, except that all the letters are
converted to the <code class="display"><span class="extract">case</span></code> given (0 for lower, 1 for upper). The definition
of what is a "letter", what case it has and what the other-case form is
are as specified in the ZSCII and Unicode standards.
</p>
<pre class="display">
2020-01-12 02:35:36 +02:00
<span class="plain">[ </span><span class="identifier">TEXT_TY_CharactersToCase</span><span class="plain"> </span><span class="identifier">ctxt</span><span class="plain"> </span><span class="identifier">txt</span><span class="plain"> </span><span class="identifier">case</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> </span><span class="identifier">ch</span><span class="plain"> </span><span class="identifier">len</span><span class="plain"> </span><span class="identifier">bnd</span><span class="plain"> </span><span class="identifier">pk</span><span class="plain"> </span><span class="identifier">cp</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">txt</span><span class="plain">==0) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">cp</span><span class="plain"> = </span><span class="identifier">txt</span><span class="plain">--&gt;0; </span><span class="identifier">pk</span><span class="plain"> = </span><span class="identifier">TEXT_TY_Temporarily_Transmute</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">);</span>
<span class="identifier">TEXT_TY_Transmute</span><span class="plain">(</span><span class="identifier">ctxt</span><span class="plain">);</span>
<span class="identifier">len</span><span class="plain"> = </span><span class="identifier">TEXT_TY_CharacterLength</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">BlkValueSetLBCapacity</span><span class="plain">(</span><span class="identifier">ctxt</span><span class="plain">, </span><span class="identifier">len</span><span class="plain">+1)) {</span>
<span class="identifier">bnd</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0:</span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">len</span><span class="plain">:</span><span class="identifier">i</span><span class="plain">++) {</span>
<span class="identifier">ch</span><span class="plain"> = </span><span class="identifier">BlkValueRead</span><span class="plain">(</span><span class="identifier">txt</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">case</span><span class="plain"> &lt; </span><span class="constant">2</span><span class="plain">) {</span>
<span class="identifier">BlkValueWrite</span><span class="plain">(</span><span class="identifier">ctxt</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">CharToCase</span><span class="plain">(</span><span class="identifier">ch</span><span class="plain">, </span><span class="identifier">case</span><span class="plain">));</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">BlkValueWrite</span><span class="plain">(</span><span class="identifier">ctxt</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">CharToCase</span><span class="plain">(</span><span class="identifier">ch</span><span class="plain">, </span><span class="identifier">bnd</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">case</span><span class="plain"> == </span><span class="constant">2</span><span class="plain">) {</span>
<span class="identifier">bnd</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ch</span><span class="plain"> == </span><span class="constant">0</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="constant">10</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="constant">13</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="constant">32</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="constant">9</span>
<span class="reserved">or</span><span class="plain"> </span><span class="character">'.'</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">','</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">'!'</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">'?'</span>
<span class="reserved">or</span><span class="plain"> </span><span class="character">'-'</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">'/'</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">'"'</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">':'</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">';'</span>
<span class="reserved">or</span><span class="plain"> </span><span class="character">'('</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">')'</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">'['</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">']'</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">'{'</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">'}'</span><span class="plain">) </span><span class="identifier">bnd</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">;</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">case</span><span class="plain"> == </span><span class="constant">3</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ch</span><span class="plain"> ~= </span><span class="constant">0</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="constant">10</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="constant">13</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="constant">32</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="constant">9</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bnd</span><span class="plain"> == </span><span class="constant">1</span><span class="plain">) </span><span class="identifier">bnd</span><span class="plain"> = </span><span class="constant">0</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">ch</span><span class="plain"> == </span><span class="character">'.'</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">'!'</span><span class="plain"> </span><span class="reserved">or</span><span class="plain"> </span><span class="character">'?'</span><span class="plain">) </span><span class="identifier">bnd</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="identifier">BlkValueWrite</span><span class="plain">(</span><span class="identifier">ctxt</span><span class="plain">, </span><span class="identifier">len</span><span class="plain">, </span><span class="constant">0</span><span class="plain">);</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="identifier">TEXT_TY_Untransmute</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">, </span><span class="identifier">pk</span><span class="plain">, </span><span class="identifier">cp</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">ctxt</span><span class="plain">;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP31"></a><b>&#167;31. Concatenation. </b>To concatenate two texts is to place one after the other: thus "green"
concatenated with "horn" makes "greenhorn". In this routine, <code class="display"><span class="extract">from_txt</span></code>
would be "horn", and is added at the end of <code class="display"><span class="extract">to_txt</span></code>, which is returned in
its expanded state.
</p>
<p class="inwebparagraph">When the blob type is <code class="display"><span class="extract">REGEXP_BLOB</span></code>, the routine is used not for simple
concatenation but to handle the concatenations occurring when a regular
expression search-and-replace is going on: see "RegExp.i6t".
</p>
<pre class="display">
2020-01-12 02:35:36 +02:00
<span class="plain">[ </span><span class="identifier">TEXT_TY_Concatenate</span><span class="plain"> </span><span class="identifier">to_txt</span><span class="plain"> </span><span class="identifier">from_txt</span><span class="plain"> </span><span class="identifier">blobtype</span><span class="plain"> </span><span class="identifier">ref_txt</span>
<span class="identifier">p</span><span class="plain"> </span><span class="identifier">cp</span><span class="plain"> </span><span class="identifier">r</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">to_txt</span><span class="plain">==0) </span><span class="reserved">rfalse</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">from_txt</span><span class="plain">==0) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">to_txt</span><span class="plain">;</span>
<span class="identifier">TEXT_TY_Transmute</span><span class="plain">(</span><span class="identifier">to_txt</span><span class="plain">);</span>
<span class="identifier">cp</span><span class="plain"> = </span><span class="identifier">from_txt</span><span class="plain">--&gt;0; </span><span class="identifier">p</span><span class="plain"> = </span><span class="identifier">TEXT_TY_Temporarily_Transmute</span><span class="plain">(</span><span class="identifier">from_txt</span><span class="plain">);</span>
<span class="identifier">r</span><span class="plain"> = </span><span class="identifier">TEXT_TY_ConcatenateI</span><span class="plain">(</span><span class="identifier">to_txt</span><span class="plain">, </span><span class="identifier">from_txt</span><span class="plain">, </span><span class="identifier">blobtype</span><span class="plain">, </span><span class="identifier">ref_txt</span><span class="plain">);</span>
<span class="identifier">TEXT_TY_Untransmute</span><span class="plain">(</span><span class="identifier">from_txt</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">cp</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">r</span><span class="plain">;</span>
<span class="plain">];</span>
2020-01-12 02:35:36 +02:00
<span class="plain">[ </span><span class="identifier">TEXT_TY_ConcatenateI</span><span class="plain"> </span><span class="identifier">to_txt</span><span class="plain"> </span><span class="identifier">from_txt</span><span class="plain"> </span><span class="identifier">blobtype</span><span class="plain"> </span><span class="identifier">ref_txt</span>
<span class="identifier">pos</span><span class="plain"> </span><span class="identifier">len</span><span class="plain"> </span><span class="identifier">ch</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> </span><span class="identifier">tosize</span><span class="plain"> </span><span class="identifier">x</span><span class="plain"> </span><span class="identifier">y</span><span class="plain"> </span><span class="identifier">case</span><span class="plain">;</span>
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">blobtype</span><span class="plain">) {</span>
<span class="identifier">CHR_BLOB</span><span class="plain">, </span><span class="constant">0</span><span class="plain">:</span>
<span class="identifier">pos</span><span class="plain"> = </span><span class="identifier">TEXT_TY_CharacterLength</span><span class="plain">(</span><span class="identifier">to_txt</span><span class="plain">);</span>
<span class="identifier">len</span><span class="plain"> = </span><span class="identifier">TEXT_TY_CharacterLength</span><span class="plain">(</span><span class="identifier">from_txt</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">BlkValueSetLBCapacity</span><span class="plain">(</span><span class="identifier">to_txt</span><span class="plain">, </span><span class="identifier">pos</span><span class="plain">+</span><span class="identifier">len</span><span class="plain">+1) == </span><span class="reserved">false</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">to_txt</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0:</span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">len</span><span class="plain">:</span><span class="identifier">i</span><span class="plain">++) {</span>
<span class="identifier">ch</span><span class="plain"> = </span><span class="identifier">BlkValueRead</span><span class="plain">(</span><span class="identifier">from_txt</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">);</span>
<span class="identifier">BlkValueWrite</span><span class="plain">(</span><span class="identifier">to_txt</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">+</span><span class="identifier">pos</span><span class="plain">, </span><span class="identifier">ch</span><span class="plain">);</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="identifier">BlkValueWrite</span><span class="plain">(</span><span class="identifier">to_txt</span><span class="plain">, </span><span class="identifier">len</span><span class="plain">+</span><span class="identifier">pos</span><span class="plain">, </span><span class="constant">0</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">to_txt</span><span class="plain">;</span>
<span class="identifier">REGEXP_BLOB</span><span class="plain">:</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TEXT_TY_RE_Concatenate</span><span class="plain">(</span><span class="identifier">to_txt</span><span class="plain">, </span><span class="identifier">from_txt</span><span class="plain">, </span><span class="identifier">blobtype</span><span class="plain">, </span><span class="identifier">ref_txt</span><span class="plain">);</span>
<span class="plain">}</span>
2020-01-12 02:35:36 +02:00
<span class="reserved">print</span><span class="plain"> </span><span class="string">"*** TEXT_TY_Concatenate used on impossible blob type ***^"</span><span class="plain">;</span>
<span class="reserved">rfalse</span><span class="plain">;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<hr class="tocbar">
2020-01-27 03:22:21 +02:00
<ul class="toc"><li><a href="S-bt.html">Back to 'BlockValues Template'</a></li><li><a href="S-ut2.html">Continue with 'UnicodeData Template'</a></li></ul><hr class="tocbar">
<!--End of weave-->
2020-03-19 02:11:25 +02:00
</main>
</body>
</html>