Tidied up JSON code

This commit is contained in:
Graham Nelson 2022-06-03 12:18:18 +01:00
parent a0710cfef9
commit 3b87d62b42
19 changed files with 3724 additions and 2062 deletions

View file

@ -1,6 +1,6 @@
# Inweb 7.1.0
v7.1.0-beta+1B08 'Escape to Danger' (2 June 2022)
v7.1.0-beta+1B09 'Escape to Danger' (3 June 2022)
## About Inweb

File diff suppressed because it is too large Load diff

View file

@ -1,3 +1,3 @@
Prerelease: beta
Build Date: 2 June 2022
Build Number: 1B08
Build Date: 3 June 2022
Build Number: 1B09

View file

@ -80,7 +80,7 @@ efficiency's sake the caller can set them up with an initial size of her choice.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">dictionary</span><span class="plain-syntax"> *</span><span class="function-syntax">Dictionaries::new</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">Dictionaries::new</span></span>:<br/><a href="2-dct.html#SP7_2">&#167;7.2</a><br/>Command Line Arguments - <a href="3-cla.html#SP5">&#167;5</a><br/>String Manipulation - <a href="4-sm.html#SP27_1">&#167;27.1</a><br/>JSON - <a href="4-jsn.html#SP6">&#167;6</a>, <a href="4-jsn.html#SP20">&#167;20</a>, <a href="4-jsn.html#SP33">&#167;33</a><br/>HTML - <a href="5-htm.html#SP11">&#167;11</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">S</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">textual</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">dictionary</span><span class="plain-syntax"> *</span><span class="function-syntax">Dictionaries::new</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">Dictionaries::new</span></span>:<br/><a href="2-dct.html#SP7_2">&#167;7.2</a><br/>Command Line Arguments - <a href="3-cla.html#SP5">&#167;5</a><br/>String Manipulation - <a href="4-sm.html#SP27_1">&#167;27.1</a><br/>JSON - <a href="4-jsn.html#SP6">&#167;6</a>, <a href="4-jsn.html#SP22">&#167;22</a>, <a href="4-jsn.html#SP36">&#167;36</a><br/>HTML - <a href="5-htm.html#SP11">&#167;11</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">S</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">textual</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">S</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">2</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"dictionary too small"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">dictionary</span><span class="plain-syntax"> *</span><span class="identifier-syntax">D</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">dictionary</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">D</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">textual</span><span class="plain-syntax"> = </span><span class="identifier-syntax">textual</span><span class="plain-syntax">;</span>
@ -132,10 +132,10 @@ so be careful if thread safety's an issue.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">dict_entry</span><span class="plain-syntax"> *</span><span class="function-syntax">Dictionaries::find</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">Dictionaries::find</span></span>:<br/><a href="2-dct.html#SP6">&#167;6</a>, <a href="2-dct.html#SP8">&#167;8</a>, <a href="2-dct.html#SP10">&#167;10</a><br/>Command Line Arguments - <a href="3-cla.html#SP13">&#167;13</a><br/>JSON - <a href="4-jsn.html#SP7">&#167;7</a>, <a href="4-jsn.html#SP24">&#167;24</a>, <a href="4-jsn.html#SP29">&#167;29</a>, <a href="4-jsn.html#SP33">&#167;33</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">dictionary</span><span class="plain-syntax"> *</span><span class="identifier-syntax">D</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">dict_entry</span><span class="plain-syntax"> *</span><span class="function-syntax">Dictionaries::find</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">Dictionaries::find</span></span>:<br/><a href="2-dct.html#SP6">&#167;6</a>, <a href="2-dct.html#SP8">&#167;8</a>, <a href="2-dct.html#SP10">&#167;10</a><br/>Command Line Arguments - <a href="3-cla.html#SP13">&#167;13</a><br/>JSON - <a href="4-jsn.html#SP7">&#167;7</a>, <a href="4-jsn.html#SP26">&#167;26</a>, <a href="4-jsn.html#SP32_1">&#167;32.1</a>, <a href="4-jsn.html#SP37">&#167;37</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">dictionary</span><span class="plain-syntax"> *</span><span class="identifier-syntax">D</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="2-dct.html#SP7" class="function-link"><span class="function-syntax">Dictionaries::find_p</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">D</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">dict_entry</span><span class="plain-syntax"> *</span><span class="function-syntax">Dictionaries::create</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">Dictionaries::create</span></span>:<br/><a href="2-dct.html#SP6">&#167;6</a>, <a href="2-dct.html#SP9">&#167;9</a><br/>Command Line Arguments - <a href="3-cla.html#SP5">&#167;5</a><br/>JSON - <a href="4-jsn.html#SP6">&#167;6</a>, <a href="4-jsn.html#SP23">&#167;23</a>, <a href="4-jsn.html#SP33">&#167;33</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">dictionary</span><span class="plain-syntax"> *</span><span class="identifier-syntax">D</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">dict_entry</span><span class="plain-syntax"> *</span><span class="function-syntax">Dictionaries::create</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">Dictionaries::create</span></span>:<br/><a href="2-dct.html#SP6">&#167;6</a>, <a href="2-dct.html#SP9">&#167;9</a><br/>Command Line Arguments - <a href="3-cla.html#SP5">&#167;5</a><br/>JSON - <a href="4-jsn.html#SP6">&#167;6</a>, <a href="4-jsn.html#SP25">&#167;25</a>, <a href="4-jsn.html#SP37">&#167;37</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">dictionary</span><span class="plain-syntax"> *</span><span class="identifier-syntax">D</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="2-dct.html#SP7" class="function-link"><span class="function-syntax">Dictionaries::find_p</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">D</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Dictionaries::destroy</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">Dictionaries::destroy</span></span>:<br/><a href="2-dct.html#SP6">&#167;6</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">dictionary</span><span class="plain-syntax"> *</span><span class="identifier-syntax">D</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax">) {</span>
@ -280,7 +280,7 @@ values which are arbitrary pointers, so we have to use void pointers:
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="function-syntax">Dictionaries::read_value</span><button class="popup" onclick="togglePopup('usagePopup9')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup9">Usage of <span class="code-font"><span class="function-syntax">Dictionaries::read_value</span></span>:<br/>Command Line Arguments - <a href="3-cla.html#SP13">&#167;13</a><br/>JSON - <a href="4-jsn.html#SP17">&#167;17</a>, <a href="4-jsn.html#SP27_3">&#167;27.3</a>, <a href="4-jsn.html#SP32">&#167;32</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">dictionary</span><span class="plain-syntax"> *</span><span class="identifier-syntax">D</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">key</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="function-syntax">Dictionaries::read_value</span><button class="popup" onclick="togglePopup('usagePopup9')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup9">Usage of <span class="code-font"><span class="function-syntax">Dictionaries::read_value</span></span>:<br/>Command Line Arguments - <a href="3-cla.html#SP13">&#167;13</a><br/>JSON - <a href="4-jsn.html#SP17">&#167;17</a>, <a href="4-jsn.html#SP30_3_3">&#167;30.3.3</a>, <a href="4-jsn.html#SP30_3_3_1">&#167;30.3.3.1</a>, <a href="4-jsn.html#SP35">&#167;35</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">dictionary</span><span class="plain-syntax"> *</span><span class="identifier-syntax">D</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">key</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">D</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">D</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">textual</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"textual dictionary accessed as pointy"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">dict_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">E</span><span class="plain-syntax"> = </span><a href="2-dct.html#SP5" class="function-link"><span class="function-syntax">Dictionaries::find</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">D</span><span class="plain-syntax">, </span><span class="identifier-syntax">key</span><span class="plain-syntax">);</span>

View file

@ -68,6 +68,7 @@ here we are.
<span class="definition-keyword">enum</span> <span class="constant-syntax">JSON_pair_requirement_CLASS</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">JSON_requirement_CLASS</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">JSON_single_requirement_CLASS</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">JSON_type_CLASS</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">JSON_value_CLASS</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">linked_list_CLASS</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">linked_list_item_CLASS</span>
@ -113,6 +114,7 @@ here we are.
<span class="identifier-syntax">DECLARE_CLASS</span><span class="plain-syntax">(</span><span class="reserved-syntax">JSON_pair_requirement</span><span class="plain-syntax">)</span>
<span class="identifier-syntax">DECLARE_CLASS</span><span class="plain-syntax">(</span><span class="reserved-syntax">JSON_requirement</span><span class="plain-syntax">)</span>
<span class="identifier-syntax">DECLARE_CLASS</span><span class="plain-syntax">(</span><span class="reserved-syntax">JSON_single_requirement</span><span class="plain-syntax">)</span>
<span class="identifier-syntax">DECLARE_CLASS</span><span class="plain-syntax">(</span><span class="reserved-syntax">JSON_type</span><span class="plain-syntax">)</span>
<span class="identifier-syntax">DECLARE_CLASS</span><span class="plain-syntax">(</span><span class="reserved-syntax">JSON_value</span><span class="plain-syntax">)</span>
<span class="identifier-syntax">DECLARE_CLASS</span><span class="plain-syntax">(</span><span class="reserved-syntax">linked_list</span><span class="plain-syntax">)</span>
<span class="identifier-syntax">DECLARE_CLASS</span><span class="plain-syntax">(</span><span class="reserved-syntax">method_set</span><span class="plain-syntax">)</span>

View file

@ -193,7 +193,7 @@ of the list, <span class="extract"><span class="extract-syntax">N</span></span>
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>&#167;7. A function call API. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">LinkedLists::len</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">LinkedLists::len</span></span>:<br/><a href="2-llas.html#SP11">&#167;11</a><br/>Time - <a href="3-tm.html#SP7">&#167;7</a><br/>JSON - <a href="4-jsn.html#SP26">&#167;26</a>, <a href="4-jsn.html#SP32">&#167;32</a><br/>Epub Ebooks - <a href="5-ee.html#SP7_3">&#167;7.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">LinkedLists::len</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">LinkedLists::len</span></span>:<br/><a href="2-llas.html#SP11">&#167;11</a><br/>Time - <a href="3-tm.html#SP7">&#167;7</a><br/>JSON - <a href="4-jsn.html#SP28">&#167;28</a>, <a href="4-jsn.html#SP35">&#167;35</a><br/>Epub Ebooks - <a href="5-ee.html#SP7_3">&#167;7.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax">?(</span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">linked_list_length</span><span class="plain-syntax">):0;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">linked_list_item</span><span class="plain-syntax"> *</span><span class="function-syntax">LinkedLists::first</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">LinkedLists::first</span></span>:<br/><a href="2-llas.html#SP8">&#167;8</a><br/>Version Numbers - <a href="7-vn.html#SP8">&#167;8</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax">) {</span>

View file

@ -309,7 +309,7 @@ a single large object, or a single array of small objects.
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">; </span><span class="comment-syntax"> allocation ID number of object stored in this frame</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">memory_frame</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure memory_frame is accessed in 4/jsn and here.</li></ul>
<ul class="endnotetexts"><li>The structure memory_frame is private to this section.</li></ul>
<p class="commentary firstcommentary"><a id="SP14" class="paragraph-anchor"></a><b>&#167;14. </b>There is a single linked list of all the memory frames, perhaps of about
10000 entries in length, beginning here. (These frames live in different memory
blocks, but we don't need to worry about that.)

View file

@ -186,7 +186,7 @@ specify this at three levels of abstraction:
<span class="plain-syntax"> </span><a href="3-em.html#SP6" class="function-link"><span class="function-syntax">Errors::at_position</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">message</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Errors::in_text_file_S</span><button class="popup" onclick="togglePopup('usagePopup11')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup11">Usage of <span class="code-font"><span class="function-syntax">Errors::in_text_file_S</span></span>:<br/>Preprocessor - <a href="4-prp.html#SP4_1">&#167;4.1</a>, <a href="4-prp.html#SP4_1_2_1">&#167;4.1.2.1</a>, <a href="4-prp.html#SP4_1_3_1_1">&#167;4.1.3.1.1</a>, <a href="4-prp.html#SP4_1_3_1_2">&#167;4.1.3.1.2</a><br/>JSON - <a href="4-jsn.html#SP33">&#167;33</a><br/>Web Structure - <a href="8-ws.html#SP7_3_2">&#167;7.3.2</a>, <a href="8-ws.html#SP7_3_2_1">&#167;7.3.2.1</a>, <a href="8-ws.html#SP7_3_3_2">&#167;7.3.3.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">message</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">here</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Errors::in_text_file_S</span><button class="popup" onclick="togglePopup('usagePopup11')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup11">Usage of <span class="code-font"><span class="function-syntax">Errors::in_text_file_S</span></span>:<br/>Preprocessor - <a href="4-prp.html#SP4_1">&#167;4.1</a>, <a href="4-prp.html#SP4_1_2_1">&#167;4.1.2.1</a>, <a href="4-prp.html#SP4_1_3_1_1">&#167;4.1.3.1.1</a>, <a href="4-prp.html#SP4_1_3_1_2">&#167;4.1.3.1.2</a><br/>JSON - <a href="4-jsn.html#SP36">&#167;36</a>, <a href="4-jsn.html#SP37">&#167;37</a><br/>Web Structure - <a href="8-ws.html#SP7_3_2">&#167;7.3.2</a>, <a href="8-ws.html#SP7_3_2_1">&#167;7.3.2.1</a>, <a href="8-ws.html#SP7_3_3_2">&#167;7.3.3.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">message</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">here</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">here</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="3-em.html#SP6" class="function-link"><span class="function-syntax">Errors::at_position_S</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">message</span><span class="plain-syntax">, </span><span class="identifier-syntax">here</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">text_file_filename</span><span class="plain-syntax">, </span><span class="identifier-syntax">here</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">line_count</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>

View file

@ -64,7 +64,7 @@ function togglePopup(material_id) {
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Characters::isalpha</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">Characters::isalpha</span></span>:<br/><a href="4-chr.html#SP7">&#167;7</a><br/>Writers and Loggers - <a href="2-wal.html#SP5">&#167;5</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">isalpha</span><span class="plain-syntax">((</span><span class="reserved-syntax">int</span><span class="plain-syntax">) </span><span class="identifier-syntax">c</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Characters::isdigit</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">Characters::isdigit</span></span>:<br/>Writers and Loggers - <a href="2-wal.html#SP5">&#167;5</a><br/>Filenames - <a href="3-fln.html#SP9">&#167;9</a><br/>JSON - <a href="4-jsn.html#SP11">&#167;11</a>, <a href="4-jsn.html#SP15">&#167;15</a>, <a href="4-jsn.html#SP29">&#167;29</a><br/>Version Numbers - <a href="7-vn.html#SP7">&#167;7</a>, <a href="7-vn.html#SP10">&#167;10</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Characters::isdigit</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">Characters::isdigit</span></span>:<br/>Writers and Loggers - <a href="2-wal.html#SP5">&#167;5</a><br/>Filenames - <a href="3-fln.html#SP9">&#167;9</a><br/>JSON - <a href="4-jsn.html#SP11">&#167;11</a>, <a href="4-jsn.html#SP15">&#167;15</a>, <a href="4-jsn.html#SP32_1">&#167;32.1</a><br/>Version Numbers - <a href="7-vn.html#SP7">&#167;7</a>, <a href="7-vn.html#SP10">&#167;10</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">isdigit</span><span class="plain-syntax">((</span><span class="reserved-syntax">int</span><span class="plain-syntax">) </span><span class="identifier-syntax">c</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Characters::isupper</span><span class="plain-syntax">(</span><span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax">) {</span>
@ -89,7 +89,7 @@ function togglePopup(material_id) {
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">' '</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'\t'</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Characters::is_whitespace</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">Characters::is_whitespace</span></span>:<br/>Preprocessor - <a href="4-prp.html#SP3_1">&#167;3.1</a>, <a href="4-prp.html#SP4_1_3">&#167;4.1.3</a><br/>Pattern Matching - <a href="4-pm.html#SP13">&#167;13</a><br/>JSON - <a href="4-jsn.html#SP11_1">&#167;11.1</a>, <a href="4-jsn.html#SP12">&#167;12</a>, <a href="4-jsn.html#SP13">&#167;13</a>, <a href="4-jsn.html#SP14">&#167;14</a>, <a href="4-jsn.html#SP15">&#167;15</a>, <a href="4-jsn.html#SP29_1">&#167;29.1</a>, <a href="4-jsn.html#SP30">&#167;30</a>, <a href="4-jsn.html#SP31">&#167;31</a><br/>Web Structure - <a href="8-ws.html#SP7">&#167;7</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Characters::is_whitespace</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">Characters::is_whitespace</span></span>:<br/>Preprocessor - <a href="4-prp.html#SP3_1">&#167;3.1</a>, <a href="4-prp.html#SP4_1_3">&#167;4.1.3</a><br/>Pattern Matching - <a href="4-pm.html#SP13">&#167;13</a><br/>JSON - <a href="4-jsn.html#SP11_1">&#167;11.1</a>, <a href="4-jsn.html#SP12">&#167;12</a>, <a href="4-jsn.html#SP13">&#167;13</a>, <a href="4-jsn.html#SP14">&#167;14</a>, <a href="4-jsn.html#SP15">&#167;15</a>, <a href="4-jsn.html#SP32_2">&#167;32.2</a>, <a href="4-jsn.html#SP33">&#167;33</a>, <a href="4-jsn.html#SP34">&#167;34</a><br/>Web Structure - <a href="8-ws.html#SP7">&#167;7</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">' '</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'\t'</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'\n'</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>

File diff suppressed because it is too large Load diff

View file

@ -204,7 +204,7 @@ deallocate.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">match_results</span><span class="plain-syntax"> </span><span class="function-syntax">Regexp::create_mr</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">Regexp::create_mr</span></span>:<br/><a href="4-pm.html#SP14">&#167;14</a><br/>Command Line Arguments - <a href="3-cla.html#SP11">&#167;11</a>, <a href="3-cla.html#SP12">&#167;12</a><br/>Preprocessor - <a href="4-prp.html#SP3_2">&#167;3.2</a>, <a href="4-prp.html#SP4_1">&#167;4.1</a>, <a href="4-prp.html#SP4_1_3_1_1">&#167;4.1.3.1.1</a>, <a href="4-prp.html#SP11_2">&#167;11.2</a>, <a href="4-prp.html#SP17">&#167;17</a><br/>JSON - <a href="4-jsn.html#SP33">&#167;33</a><br/>Web Structure - <a href="8-ws.html#SP7_3_2">&#167;7.3.2</a>, <a href="8-ws.html#SP7_3_3_2">&#167;7.3.3.2</a>, <a href="8-ws.html#SP7_3_3_2_1">&#167;7.3.3.2.1</a>, <a href="8-ws.html#SP7_2_1">&#167;7.2.1</a>, <a href="8-ws.html#SP7_2_2_1">&#167;7.2.2.1</a>, <a href="8-ws.html#SP7_2_2_3">&#167;7.2.2.3</a><br/>Web Modules - <a href="8-wm.html#SP9">&#167;9</a><br/>Build Files - <a href="8-bf.html#SP3">&#167;3</a><br/>Simple Tangler - <a href="8-st.html#SP7_2_3">&#167;7.2.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">match_results</span><span class="plain-syntax"> </span><span class="function-syntax">Regexp::create_mr</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">Regexp::create_mr</span></span>:<br/><a href="4-pm.html#SP14">&#167;14</a><br/>Command Line Arguments - <a href="3-cla.html#SP11">&#167;11</a>, <a href="3-cla.html#SP12">&#167;12</a><br/>Preprocessor - <a href="4-prp.html#SP3_2">&#167;3.2</a>, <a href="4-prp.html#SP4_1">&#167;4.1</a>, <a href="4-prp.html#SP4_1_3_1_1">&#167;4.1.3.1.1</a>, <a href="4-prp.html#SP11_2">&#167;11.2</a>, <a href="4-prp.html#SP17">&#167;17</a><br/>JSON - <a href="4-jsn.html#SP36">&#167;36</a><br/>Web Structure - <a href="8-ws.html#SP7_3_2">&#167;7.3.2</a>, <a href="8-ws.html#SP7_3_3_2">&#167;7.3.3.2</a>, <a href="8-ws.html#SP7_3_3_2_1">&#167;7.3.3.2.1</a>, <a href="8-ws.html#SP7_2_1">&#167;7.2.1</a>, <a href="8-ws.html#SP7_2_2_1">&#167;7.2.2.1</a>, <a href="8-ws.html#SP7_2_2_3">&#167;7.2.2.3</a><br/>Web Modules - <a href="8-wm.html#SP9">&#167;9</a><br/>Build Files - <a href="8-bf.html#SP3">&#167;3</a><br/>Simple Tangler - <a href="8-st.html#SP7_2_3">&#167;7.2.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">match_results</span><span class="plain-syntax"> </span><span class="identifier-syntax">mr</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="element-syntax">no_matched_texts</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="constant-syntax">MAX_BRACKETED_SUBEXPRESSIONS</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
@ -229,7 +229,7 @@ deallocate.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Regexp::match</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">Regexp::match</span></span>:<br/>Command Line Arguments - <a href="3-cla.html#SP11">&#167;11</a>, <a href="3-cla.html#SP12">&#167;12</a><br/>Preprocessor - <a href="4-prp.html#SP3_2">&#167;3.2</a>, <a href="4-prp.html#SP4_1">&#167;4.1</a>, <a href="4-prp.html#SP4_1_3_1_1">&#167;4.1.3.1.1</a>, <a href="4-prp.html#SP11_2">&#167;11.2</a>, <a href="4-prp.html#SP17">&#167;17</a><br/>JSON - <a href="4-jsn.html#SP33">&#167;33</a><br/>Web Structure - <a href="8-ws.html#SP7_3_2">&#167;7.3.2</a>, <a href="8-ws.html#SP7_3_3_2">&#167;7.3.3.2</a>, <a href="8-ws.html#SP7_3_3_2_1">&#167;7.3.3.2.1</a>, <a href="8-ws.html#SP7_2_1">&#167;7.2.1</a>, <a href="8-ws.html#SP7_2_2_1">&#167;7.2.2.1</a>, <a href="8-ws.html#SP7_2_2_3">&#167;7.2.2.3</a><br/>Web Modules - <a href="8-wm.html#SP9">&#167;9</a><br/>Build Files - <a href="8-bf.html#SP3">&#167;3</a><br/>Simple Tangler - <a href="8-st.html#SP7_2_3">&#167;7.2.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">match_results</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mr</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pattern</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Regexp::match</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">Regexp::match</span></span>:<br/>Command Line Arguments - <a href="3-cla.html#SP11">&#167;11</a>, <a href="3-cla.html#SP12">&#167;12</a><br/>Preprocessor - <a href="4-prp.html#SP3_2">&#167;3.2</a>, <a href="4-prp.html#SP4_1">&#167;4.1</a>, <a href="4-prp.html#SP4_1_3_1_1">&#167;4.1.3.1.1</a>, <a href="4-prp.html#SP11_2">&#167;11.2</a>, <a href="4-prp.html#SP17">&#167;17</a><br/>JSON - <a href="4-jsn.html#SP36">&#167;36</a><br/>Web Structure - <a href="8-ws.html#SP7_3_2">&#167;7.3.2</a>, <a href="8-ws.html#SP7_3_3_2">&#167;7.3.3.2</a>, <a href="8-ws.html#SP7_3_3_2_1">&#167;7.3.3.2.1</a>, <a href="8-ws.html#SP7_2_1">&#167;7.2.1</a>, <a href="8-ws.html#SP7_2_2_1">&#167;7.2.2.1</a>, <a href="8-ws.html#SP7_2_2_3">&#167;7.2.2.3</a><br/>Web Modules - <a href="8-wm.html#SP9">&#167;9</a><br/>Build Files - <a href="8-bf.html#SP3">&#167;3</a><br/>Simple Tangler - <a href="8-st.html#SP7_2_3">&#167;7.2.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">match_results</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mr</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pattern</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">mr</span><span class="plain-syntax">) </span><a href="4-pm.html#SP10" class="function-link"><span class="function-syntax">Regexp::prepare</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">mr</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">rv</span><span class="plain-syntax"> = (</span><a href="4-pm.html#SP11" class="function-link"><span class="function-syntax">Regexp::match_r</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">mr</span><span class="plain-syntax">, </span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="identifier-syntax">pattern</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">) &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">)?</span><span class="identifier-syntax">TRUE:FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">mr</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">rv</span><span class="plain-syntax"> == </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">)) </span><a href="4-pm.html#SP9" class="function-link"><span class="function-syntax">Regexp::dispose_of</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">mr</span><span class="plain-syntax">);</span>

View file

@ -88,7 +88,7 @@ access.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="function-syntax">Str::new</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">Str::new</span></span>:<br/><a href="4-sm.html#SP3">&#167;3</a><br/>Debugging Log - <a href="2-dl.html#SP4_1">&#167;4.1</a><br/>Dictionaries - <a href="2-dct.html#SP7_3_1">&#167;7.3.1</a><br/>Command Line Arguments - <a href="3-cla.html#SP6">&#167;6</a>, <a href="3-cla.html#SP11">&#167;11</a><br/>Directories - <a href="3-drc.html#SP4">&#167;4</a><br/>Preprocessor - <a href="4-prp.html#SP3_2_1">&#167;3.2.1</a>, <a href="4-prp.html#SP4_1_3_1_1">&#167;4.1.3.1.1</a>, <a href="4-prp.html#SP4_1_3_1_3">&#167;4.1.3.1.3</a><br/>JSON - <a href="4-jsn.html#SP26">&#167;26</a>, <a href="4-jsn.html#SP29">&#167;29</a>, <a href="4-jsn.html#SP33">&#167;33</a><br/>HTML - <a href="5-htm.html#SP27_2">&#167;27.2</a><br/>Epub Ebooks - <a href="5-ee.html#SP5">&#167;5</a><br/>Version Numbers - <a href="7-vn.html#SP7">&#167;7</a><br/>Web Structure - <a href="8-ws.html#SP5_2">&#167;5.2</a>, <a href="8-ws.html#SP6_1">&#167;6.1</a>, <a href="8-ws.html#SP7_2_1">&#167;7.2.1</a>, <a href="8-ws.html#SP7_2_2_1">&#167;7.2.2.1</a><br/>Build Files - <a href="8-bf.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="function-syntax">Str::new</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">Str::new</span></span>:<br/><a href="4-sm.html#SP3">&#167;3</a><br/>Debugging Log - <a href="2-dl.html#SP4_1">&#167;4.1</a><br/>Dictionaries - <a href="2-dct.html#SP7_3_1">&#167;7.3.1</a><br/>Command Line Arguments - <a href="3-cla.html#SP6">&#167;6</a>, <a href="3-cla.html#SP11">&#167;11</a><br/>Directories - <a href="3-drc.html#SP4">&#167;4</a><br/>Preprocessor - <a href="4-prp.html#SP3_2_1">&#167;3.2.1</a>, <a href="4-prp.html#SP4_1_3_1_1">&#167;4.1.3.1.1</a>, <a href="4-prp.html#SP4_1_3_1_3">&#167;4.1.3.1.3</a><br/>JSON - <a href="4-jsn.html#SP28">&#167;28</a>, <a href="4-jsn.html#SP32_1">&#167;32.1</a>, <a href="4-jsn.html#SP36">&#167;36</a><br/>HTML - <a href="5-htm.html#SP27_2">&#167;27.2</a><br/>Epub Ebooks - <a href="5-ee.html#SP5">&#167;5</a><br/>Version Numbers - <a href="7-vn.html#SP7">&#167;7</a><br/>Web Structure - <a href="8-ws.html#SP5_2">&#167;5.2</a>, <a href="8-ws.html#SP6_1">&#167;6.1</a>, <a href="8-ws.html#SP7_2_1">&#167;7.2.1</a>, <a href="8-ws.html#SP7_2_2_1">&#167;7.2.2.1</a><br/>Build Files - <a href="8-bf.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="4-sm.html#SP2" class="function-link"><span class="function-syntax">Str::new_with_capacity</span></a><span class="plain-syntax">(32);</span>
<span class="plain-syntax">}</span>
@ -108,7 +108,7 @@ duplicated as <span class="extract"><span class="extract-syntax">NULL</span></sp
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="function-syntax">Str::duplicate</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">Str::duplicate</span></span>:<br/>Dictionaries - <a href="2-dct.html#SP7_3_1">&#167;7.3.1</a><br/>Trees - <a href="2-trs.html#SP7">&#167;7</a>, <a href="2-trs.html#SP9">&#167;9</a><br/>Command Line Arguments - <a href="3-cla.html#SP5_1">&#167;5.1</a><br/>Time - <a href="3-tm.html#SP6">&#167;6</a><br/>Preprocessor - <a href="4-prp.html#SP2">&#167;2</a>, <a href="4-prp.html#SP6">&#167;6</a>, <a href="4-prp.html#SP8">&#167;8</a>, <a href="4-prp.html#SP11_1">&#167;11.1</a>, <a href="4-prp.html#SP11_2">&#167;11.2</a>, <a href="4-prp.html#SP11_2_1">&#167;11.2.1</a>, <a href="4-prp.html#SP12">&#167;12</a>, <a href="4-prp.html#SP13">&#167;13</a><br/>JSON - <a href="4-jsn.html#SP4">&#167;4</a>, <a href="4-jsn.html#SP6">&#167;6</a>, <a href="4-jsn.html#SP8">&#167;8</a>, <a href="4-jsn.html#SP23">&#167;23</a>, <a href="4-jsn.html#SP25">&#167;25</a><br/>Epub Ebooks - <a href="5-ee.html#SP5">&#167;5</a><br/>Version Numbers - <a href="7-vn.html#SP7_1">&#167;7.1</a><br/>Web Structure - <a href="8-ws.html#SP7_2_1">&#167;7.2.1</a>, <a href="8-ws.html#SP7_2_2_1">&#167;7.2.2.1</a>, <a href="8-ws.html#SP7_2_2_3_1">&#167;7.2.2.3.1</a><br/>Bibliographic Data for Webs - <a href="8-bdfw.html#SP7_1">&#167;7.1</a><br/>Web Modules - <a href="8-wm.html#SP2">&#167;2</a><br/>Build Files - <a href="8-bf.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">E</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="function-syntax">Str::duplicate</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">Str::duplicate</span></span>:<br/>Dictionaries - <a href="2-dct.html#SP7_3_1">&#167;7.3.1</a><br/>Trees - <a href="2-trs.html#SP7">&#167;7</a>, <a href="2-trs.html#SP9">&#167;9</a><br/>Command Line Arguments - <a href="3-cla.html#SP5_1">&#167;5.1</a><br/>Time - <a href="3-tm.html#SP6">&#167;6</a><br/>Preprocessor - <a href="4-prp.html#SP2">&#167;2</a>, <a href="4-prp.html#SP6">&#167;6</a>, <a href="4-prp.html#SP8">&#167;8</a>, <a href="4-prp.html#SP11_1">&#167;11.1</a>, <a href="4-prp.html#SP11_2">&#167;11.2</a>, <a href="4-prp.html#SP11_2_1">&#167;11.2.1</a>, <a href="4-prp.html#SP12">&#167;12</a>, <a href="4-prp.html#SP13">&#167;13</a><br/>JSON - <a href="4-jsn.html#SP4">&#167;4</a>, <a href="4-jsn.html#SP6">&#167;6</a>, <a href="4-jsn.html#SP8">&#167;8</a>, <a href="4-jsn.html#SP25">&#167;25</a>, <a href="4-jsn.html#SP27">&#167;27</a><br/>Epub Ebooks - <a href="5-ee.html#SP5">&#167;5</a><br/>Version Numbers - <a href="7-vn.html#SP7_1">&#167;7.1</a><br/>Web Structure - <a href="8-ws.html#SP7_2_1">&#167;7.2.1</a>, <a href="8-ws.html#SP7_2_2_1">&#167;7.2.2.1</a>, <a href="8-ws.html#SP7_2_2_3_1">&#167;7.2.2.3.1</a><br/>Bibliographic Data for Webs - <a href="8-bdfw.html#SP7_1">&#167;7.1</a><br/>Web Modules - <a href="8-wm.html#SP2">&#167;2</a><br/>Build Files - <a href="8-bf.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">E</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">E</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="4-sm.html#SP2" class="function-link"><span class="function-syntax">Str::new</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-str.html#SP26" class="function-link"><span class="function-syntax">Streams::open_to_memory</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">, </span><a href="4-sm.html#SP8" class="function-link"><span class="function-syntax">Str::len</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">)+4)) {</span>
@ -198,7 +198,7 @@ thing plus a little extra, for efficiency's sake.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Str::len</span><button class="popup" onclick="togglePopup('usagePopup9')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup9">Usage of <span class="code-font"><span class="function-syntax">Str::len</span></span>:<br/><a href="4-sm.html#SP3">&#167;3</a>, <a href="4-sm.html#SP7">&#167;7</a>, <a href="4-sm.html#SP10">&#167;10</a>, <a href="4-sm.html#SP11">&#167;11</a>, <a href="4-sm.html#SP12">&#167;12</a>, <a href="4-sm.html#SP13">&#167;13</a>, <a href="4-sm.html#SP14">&#167;14</a>, <a href="4-sm.html#SP15">&#167;15</a>, <a href="4-sm.html#SP17">&#167;17</a>, <a href="4-sm.html#SP19">&#167;19</a>, <a href="4-sm.html#SP20">&#167;20</a>, <a href="4-sm.html#SP21">&#167;21</a>, <a href="4-sm.html#SP22">&#167;22</a>, <a href="4-sm.html#SP24">&#167;24</a>, <a href="4-sm.html#SP25">&#167;25</a>, <a href="4-sm.html#SP26">&#167;26</a><br/>Debugging Log - <a href="2-dl.html#SP9">&#167;9</a><br/>Command Line Arguments - <a href="3-cla.html#SP13">&#167;13</a>, <a href="3-cla.html#SP14">&#167;14</a>, <a href="3-cla.html#SP14_1">&#167;14.1</a><br/>Pathnames - <a href="3-pth.html#SP4">&#167;4</a>, <a href="3-pth.html#SP5">&#167;5</a>, <a href="3-pth.html#SP7">&#167;7</a>, <a href="3-pth.html#SP8">&#167;8</a><br/>Filenames - <a href="3-fln.html#SP2">&#167;2</a>, <a href="3-fln.html#SP3">&#167;3</a>, <a href="3-fln.html#SP5">&#167;5</a>, <a href="3-fln.html#SP8">&#167;8</a>, <a href="3-fln.html#SP9">&#167;9</a><br/>Preprocessor - <a href="4-prp.html#SP3_3">&#167;3.3</a>, <a href="4-prp.html#SP4">&#167;4</a>, <a href="4-prp.html#SP4_1_1">&#167;4.1.1</a><br/>Tries and Avinues - <a href="4-taa.html#SP2_1">&#167;2.1</a><br/>Pattern Matching - <a href="4-pm.html#SP3">&#167;3</a>, <a href="4-pm.html#SP4">&#167;4</a>, <a href="4-pm.html#SP10">&#167;10</a>, <a href="4-pm.html#SP11_3">&#167;11.3</a>, <a href="4-pm.html#SP14">&#167;14</a><br/>JSON - <a href="4-jsn.html#SP10">&#167;10</a>, <a href="4-jsn.html#SP26">&#167;26</a>, <a href="4-jsn.html#SP28">&#167;28</a>, <a href="4-jsn.html#SP33">&#167;33</a><br/>HTML - <a href="5-htm.html#SP8">&#167;8</a>, <a href="5-htm.html#SP17">&#167;17</a><br/>Epub Ebooks - <a href="5-ee.html#SP7_1">&#167;7.1</a>, <a href="5-ee.html#SP7_2_3">&#167;7.2.3</a>, <a href="5-ee.html#SP7_2_4">&#167;7.2.4</a><br/>Version Numbers - <a href="7-vn.html#SP7">&#167;7</a>, <a href="7-vn.html#SP7_1">&#167;7.1</a>, <a href="7-vn.html#SP10">&#167;10</a><br/>Web Structure - <a href="8-ws.html#SP5_4">&#167;5.4</a>, <a href="8-ws.html#SP5_4_1">&#167;5.4.1</a>, <a href="8-ws.html#SP5_4_1_1">&#167;5.4.1.1</a>, <a href="8-ws.html#SP5_4_1_2">&#167;5.4.1.2</a>, <a href="8-ws.html#SP7_3">&#167;7.3</a>, <a href="8-ws.html#SP7_3_3_1">&#167;7.3.3.1</a>, <a href="8-ws.html#SP7_2_2_3_1">&#167;7.2.2.3.1</a>, <a href="8-ws.html#SP7_2_2_4">&#167;7.2.2.4</a><br/>Bibliographic Data for Webs - <a href="8-bdfw.html#SP5">&#167;5</a>, <a href="8-bdfw.html#SP6">&#167;6</a><br/>Build Files - <a href="8-bf.html#SP3">&#167;3</a>, <a href="8-bf.html#SP4">&#167;4</a>, <a href="8-bf.html#SP5">&#167;5</a>, <a href="8-bf.html#SP6">&#167;6</a>, <a href="8-bf.html#SP9">&#167;9</a><br/>Simple Tangler - <a href="8-st.html#SP7">&#167;7</a>, <a href="8-st.html#SP7_1">&#167;7.1</a>, <a href="8-st.html#SP7_2_4">&#167;7.2.4</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Str::len</span><button class="popup" onclick="togglePopup('usagePopup9')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup9">Usage of <span class="code-font"><span class="function-syntax">Str::len</span></span>:<br/><a href="4-sm.html#SP3">&#167;3</a>, <a href="4-sm.html#SP7">&#167;7</a>, <a href="4-sm.html#SP10">&#167;10</a>, <a href="4-sm.html#SP11">&#167;11</a>, <a href="4-sm.html#SP12">&#167;12</a>, <a href="4-sm.html#SP13">&#167;13</a>, <a href="4-sm.html#SP14">&#167;14</a>, <a href="4-sm.html#SP15">&#167;15</a>, <a href="4-sm.html#SP17">&#167;17</a>, <a href="4-sm.html#SP19">&#167;19</a>, <a href="4-sm.html#SP20">&#167;20</a>, <a href="4-sm.html#SP21">&#167;21</a>, <a href="4-sm.html#SP22">&#167;22</a>, <a href="4-sm.html#SP24">&#167;24</a>, <a href="4-sm.html#SP25">&#167;25</a>, <a href="4-sm.html#SP26">&#167;26</a><br/>Debugging Log - <a href="2-dl.html#SP9">&#167;9</a><br/>Command Line Arguments - <a href="3-cla.html#SP13">&#167;13</a>, <a href="3-cla.html#SP14">&#167;14</a>, <a href="3-cla.html#SP14_1">&#167;14.1</a><br/>Pathnames - <a href="3-pth.html#SP4">&#167;4</a>, <a href="3-pth.html#SP5">&#167;5</a>, <a href="3-pth.html#SP7">&#167;7</a>, <a href="3-pth.html#SP8">&#167;8</a><br/>Filenames - <a href="3-fln.html#SP2">&#167;2</a>, <a href="3-fln.html#SP3">&#167;3</a>, <a href="3-fln.html#SP5">&#167;5</a>, <a href="3-fln.html#SP8">&#167;8</a>, <a href="3-fln.html#SP9">&#167;9</a><br/>Preprocessor - <a href="4-prp.html#SP3_3">&#167;3.3</a>, <a href="4-prp.html#SP4">&#167;4</a>, <a href="4-prp.html#SP4_1_1">&#167;4.1.1</a><br/>Tries and Avinues - <a href="4-taa.html#SP2_1">&#167;2.1</a><br/>Pattern Matching - <a href="4-pm.html#SP3">&#167;3</a>, <a href="4-pm.html#SP4">&#167;4</a>, <a href="4-pm.html#SP10">&#167;10</a>, <a href="4-pm.html#SP11_3">&#167;11.3</a>, <a href="4-pm.html#SP14">&#167;14</a><br/>JSON - <a href="4-jsn.html#SP10">&#167;10</a>, <a href="4-jsn.html#SP28">&#167;28</a>, <a href="4-jsn.html#SP31">&#167;31</a>, <a href="4-jsn.html#SP36">&#167;36</a>, <a href="4-jsn.html#SP37">&#167;37</a><br/>HTML - <a href="5-htm.html#SP8">&#167;8</a>, <a href="5-htm.html#SP17">&#167;17</a><br/>Epub Ebooks - <a href="5-ee.html#SP7_1">&#167;7.1</a>, <a href="5-ee.html#SP7_2_3">&#167;7.2.3</a>, <a href="5-ee.html#SP7_2_4">&#167;7.2.4</a><br/>Version Numbers - <a href="7-vn.html#SP7">&#167;7</a>, <a href="7-vn.html#SP7_1">&#167;7.1</a>, <a href="7-vn.html#SP10">&#167;10</a><br/>Web Structure - <a href="8-ws.html#SP5_4">&#167;5.4</a>, <a href="8-ws.html#SP5_4_1">&#167;5.4.1</a>, <a href="8-ws.html#SP5_4_1_1">&#167;5.4.1.1</a>, <a href="8-ws.html#SP5_4_1_2">&#167;5.4.1.2</a>, <a href="8-ws.html#SP7_3">&#167;7.3</a>, <a href="8-ws.html#SP7_3_3_1">&#167;7.3.3.1</a>, <a href="8-ws.html#SP7_2_2_3_1">&#167;7.2.2.3.1</a>, <a href="8-ws.html#SP7_2_2_4">&#167;7.2.2.4</a><br/>Bibliographic Data for Webs - <a href="8-bdfw.html#SP5">&#167;5</a>, <a href="8-bdfw.html#SP6">&#167;6</a><br/>Build Files - <a href="8-bf.html#SP3">&#167;3</a>, <a href="8-bf.html#SP4">&#167;4</a>, <a href="8-bf.html#SP5">&#167;5</a>, <a href="8-bf.html#SP6">&#167;6</a>, <a href="8-bf.html#SP9">&#167;9</a><br/>Simple Tangler - <a href="8-st.html#SP7">&#167;7</a>, <a href="8-st.html#SP7_1">&#167;7.1</a>, <a href="8-st.html#SP7_2_4">&#167;7.2.4</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="2-str.html#SP38" class="function-link"><span class="function-syntax">Streams::get_position</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
@ -282,7 +282,7 @@ at those positions may well not be, of course.)
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="2-str.html#SP40" class="function-link"><span class="function-syntax">Streams::get_char_at_index</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">.</span><span class="element-syntax">S</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">.</span><span class="element-syntax">index</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> </span><span class="function-syntax">Str::get_at</span><button class="popup" onclick="togglePopup('usagePopup16')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup16">Usage of <span class="code-font"><span class="function-syntax">Str::get_at</span></span>:<br/><a href="4-sm.html#SP20">&#167;20</a>, <a href="4-sm.html#SP21">&#167;21</a>, <a href="4-sm.html#SP24">&#167;24</a>, <a href="4-sm.html#SP26">&#167;26</a><br/>Pathnames - <a href="3-pth.html#SP7">&#167;7</a><br/>Filenames - <a href="3-fln.html#SP5">&#167;5</a><br/>Preprocessor - <a href="4-prp.html#SP4">&#167;4</a><br/>Tries and Avinues - <a href="4-taa.html#SP2">&#167;2</a><br/>Pattern Matching - <a href="4-pm.html#SP3">&#167;3</a>, <a href="4-pm.html#SP4">&#167;4</a>, <a href="4-pm.html#SP11">&#167;11</a>, <a href="4-pm.html#SP11_4">&#167;11.4</a>, <a href="4-pm.html#SP11_6">&#167;11.6</a>, <a href="4-pm.html#SP14">&#167;14</a>, <a href="4-pm.html#SP14_1">&#167;14.1</a><br/>JSON - <a href="4-jsn.html#SP10">&#167;10</a>, <a href="4-jsn.html#SP11_1">&#167;11.1</a>, <a href="4-jsn.html#SP12">&#167;12</a>, <a href="4-jsn.html#SP13">&#167;13</a>, <a href="4-jsn.html#SP14">&#167;14</a>, <a href="4-jsn.html#SP15">&#167;15</a>, <a href="4-jsn.html#SP16">&#167;16</a>, <a href="4-jsn.html#SP16_1">&#167;16.1</a>, <a href="4-jsn.html#SP29">&#167;29</a>, <a href="4-jsn.html#SP29_1">&#167;29.1</a>, <a href="4-jsn.html#SP30">&#167;30</a>, <a href="4-jsn.html#SP31">&#167;31</a><br/>Web Structure - <a href="8-ws.html#SP5_4_1_1">&#167;5.4.1.1</a>, <a href="8-ws.html#SP7">&#167;7</a><br/>Build Files - <a href="8-bf.html#SP9">&#167;9</a><br/>Simple Tangler - <a href="8-st.html#SP7_2_1">&#167;7.2.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">index</span><span class="plain-syntax">) {</span>
<span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> </span><span class="function-syntax">Str::get_at</span><button class="popup" onclick="togglePopup('usagePopup16')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup16">Usage of <span class="code-font"><span class="function-syntax">Str::get_at</span></span>:<br/><a href="4-sm.html#SP20">&#167;20</a>, <a href="4-sm.html#SP21">&#167;21</a>, <a href="4-sm.html#SP24">&#167;24</a>, <a href="4-sm.html#SP26">&#167;26</a><br/>Pathnames - <a href="3-pth.html#SP7">&#167;7</a><br/>Filenames - <a href="3-fln.html#SP5">&#167;5</a><br/>Preprocessor - <a href="4-prp.html#SP4">&#167;4</a><br/>Tries and Avinues - <a href="4-taa.html#SP2">&#167;2</a><br/>Pattern Matching - <a href="4-pm.html#SP3">&#167;3</a>, <a href="4-pm.html#SP4">&#167;4</a>, <a href="4-pm.html#SP11">&#167;11</a>, <a href="4-pm.html#SP11_4">&#167;11.4</a>, <a href="4-pm.html#SP11_6">&#167;11.6</a>, <a href="4-pm.html#SP14">&#167;14</a>, <a href="4-pm.html#SP14_1">&#167;14.1</a><br/>JSON - <a href="4-jsn.html#SP10">&#167;10</a>, <a href="4-jsn.html#SP11_1">&#167;11.1</a>, <a href="4-jsn.html#SP12">&#167;12</a>, <a href="4-jsn.html#SP13">&#167;13</a>, <a href="4-jsn.html#SP14">&#167;14</a>, <a href="4-jsn.html#SP15">&#167;15</a>, <a href="4-jsn.html#SP16">&#167;16</a>, <a href="4-jsn.html#SP16_1">&#167;16.1</a>, <a href="4-jsn.html#SP32">&#167;32</a>, <a href="4-jsn.html#SP32_1">&#167;32.1</a>, <a href="4-jsn.html#SP32_2">&#167;32.2</a>, <a href="4-jsn.html#SP33">&#167;33</a>, <a href="4-jsn.html#SP34">&#167;34</a><br/>Web Structure - <a href="8-ws.html#SP5_4_1_1">&#167;5.4.1.1</a>, <a href="8-ws.html#SP7">&#167;7</a><br/>Build Files - <a href="8-bf.html#SP9">&#167;9</a><br/>Simple Tangler - <a href="8-st.html#SP7_2_1">&#167;7.2.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">index</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">S</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">index</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="2-str.html#SP40" class="function-link"><span class="function-syntax">Streams::get_char_at_index</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">, </span><span class="identifier-syntax">index</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
@ -319,7 +319,7 @@ at those positions may well not be, of course.)
<p class="commentary firstcommentary"><a id="SP15" class="paragraph-anchor"></a><b>&#167;15. Truncation. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Str::clear</span><button class="popup" onclick="togglePopup('usagePopup21')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup21">Usage of <span class="code-font"><span class="function-syntax">Str::clear</span></span>:<br/><a href="4-sm.html#SP16">&#167;16</a>, <a href="4-sm.html#SP17">&#167;17</a>, <a href="4-sm.html#SP18">&#167;18</a>, <a href="4-sm.html#SP25">&#167;25</a><br/>Directories - <a href="3-drc.html#SP2">&#167;2</a><br/>Text Files - <a href="4-tf.html#SP6">&#167;6</a><br/>Preprocessor - <a href="4-prp.html#SP4_1_3_1_1">&#167;4.1.3.1.1</a>, <a href="4-prp.html#SP11_2">&#167;11.2</a>, <a href="4-prp.html#SP13">&#167;13</a>, <a href="4-prp.html#SP17">&#167;17</a>, <a href="4-prp.html#SP18_1">&#167;18.1</a><br/>Pattern Matching - <a href="4-pm.html#SP11_6">&#167;11.6</a><br/>JSON - <a href="4-jsn.html#SP33">&#167;33</a><br/>HTML - <a href="5-htm.html#SP27_2">&#167;27.2</a><br/>Version Numbers - <a href="7-vn.html#SP7_1">&#167;7.1</a><br/>Web Structure - <a href="8-ws.html#SP5_4_1">&#167;5.4.1</a>, <a href="8-ws.html#SP5_4_1_2">&#167;5.4.1.2</a>, <a href="8-ws.html#SP7_3_2_1">&#167;7.3.2.1</a>, <a href="8-ws.html#SP7_3_3_2">&#167;7.3.3.2</a>, <a href="8-ws.html#SP7_2_2_1">&#167;7.2.2.1</a>, <a href="8-ws.html#SP7_2_2_4">&#167;7.2.2.4</a><br/>Build Files - <a href="8-bf.html#SP8">&#167;8</a>, <a href="8-bf.html#SP9">&#167;9</a><br/>Simple Tangler - <a href="8-st.html#SP7_2">&#167;7.2</a>, <a href="8-st.html#SP7_2_5_1">&#167;7.2.5.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Str::clear</span><button class="popup" onclick="togglePopup('usagePopup21')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup21">Usage of <span class="code-font"><span class="function-syntax">Str::clear</span></span>:<br/><a href="4-sm.html#SP16">&#167;16</a>, <a href="4-sm.html#SP17">&#167;17</a>, <a href="4-sm.html#SP18">&#167;18</a>, <a href="4-sm.html#SP25">&#167;25</a><br/>Directories - <a href="3-drc.html#SP2">&#167;2</a><br/>Text Files - <a href="4-tf.html#SP6">&#167;6</a><br/>Preprocessor - <a href="4-prp.html#SP4_1_3_1_1">&#167;4.1.3.1.1</a>, <a href="4-prp.html#SP11_2">&#167;11.2</a>, <a href="4-prp.html#SP13">&#167;13</a>, <a href="4-prp.html#SP17">&#167;17</a>, <a href="4-prp.html#SP18_1">&#167;18.1</a><br/>Pattern Matching - <a href="4-pm.html#SP11_6">&#167;11.6</a><br/>JSON - <a href="4-jsn.html#SP37">&#167;37</a><br/>HTML - <a href="5-htm.html#SP27_2">&#167;27.2</a><br/>Version Numbers - <a href="7-vn.html#SP7_1">&#167;7.1</a><br/>Web Structure - <a href="8-ws.html#SP5_4_1">&#167;5.4.1</a>, <a href="8-ws.html#SP5_4_1_2">&#167;5.4.1.2</a>, <a href="8-ws.html#SP7_3_2_1">&#167;7.3.2.1</a>, <a href="8-ws.html#SP7_3_3_2">&#167;7.3.3.2</a>, <a href="8-ws.html#SP7_2_2_1">&#167;7.2.2.1</a>, <a href="8-ws.html#SP7_2_2_4">&#167;7.2.2.4</a><br/>Build Files - <a href="8-bf.html#SP8">&#167;8</a>, <a href="8-bf.html#SP9">&#167;9</a><br/>Simple Tangler - <a href="8-st.html#SP7_2">&#167;7.2</a>, <a href="8-st.html#SP7_2_5_1">&#167;7.2.5.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP15" class="function-link"><span class="function-syntax">Str::truncate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
@ -694,7 +694,7 @@ for the staff of a publishing house.)
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Str::includes_at</span><button class="popup" onclick="togglePopup('usagePopup40')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup40">Usage of <span class="code-font"><span class="function-syntax">Str::includes_at</span></span>:<br/>JSON - <a href="4-jsn.html#SP11">&#167;11</a>, <a href="4-jsn.html#SP29">&#167;29</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">line</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pattern</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Str::includes_at</span><button class="popup" onclick="togglePopup('usagePopup40')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup40">Usage of <span class="code-font"><span class="function-syntax">Str::includes_at</span></span>:<br/>JSON - <a href="4-jsn.html#SP11">&#167;11</a>, <a href="4-jsn.html#SP32_1">&#167;32.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">line</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pattern</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP8" class="function-link"><span class="function-syntax">Str::len</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pattern</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax"> + </span><a href="4-sm.html#SP8" class="function-link"><span class="function-syntax">Str::len</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pattern</span><span class="plain-syntax">) &gt; </span><a href="4-sm.html#SP8" class="function-link"><span class="function-syntax">Str::len</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">line</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>

View file

@ -135,7 +135,7 @@ client.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">TextFiles::read</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">TextFiles::read</span></span>:<br/>Command Line Arguments - <a href="3-cla.html#SP11">&#167;11</a><br/>Preprocessor - <a href="4-prp.html#SP1">&#167;1</a><br/>JSON - <a href="4-jsn.html#SP33">&#167;33</a><br/>HTML - <a href="5-htm.html#SP11">&#167;11</a><br/>Web Structure - <a href="8-ws.html#SP6">&#167;6</a><br/>Build Files - <a href="8-bf.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">escape_oddities</span><span class="plain-syntax">, </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">message</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">serious</span><span class="plain-syntax">,</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">TextFiles::read</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">TextFiles::read</span></span>:<br/>Command Line Arguments - <a href="3-cla.html#SP11">&#167;11</a><br/>Preprocessor - <a href="4-prp.html#SP1">&#167;1</a><br/>JSON - <a href="4-jsn.html#SP36">&#167;36</a><br/>HTML - <a href="5-htm.html#SP11">&#167;11</a><br/>Web Structure - <a href="8-ws.html#SP6">&#167;6</a><br/>Build Files - <a href="8-bf.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">escape_oddities</span><span class="plain-syntax">, </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">message</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">serious</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> (</span><span class="identifier-syntax">iterator</span><span class="plain-syntax">)(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">text_file_position</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *),</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">start_at</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">state</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_file_position</span><span class="plain-syntax"> </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">;</span>

View file

@ -225,7 +225,7 @@
<li>
<p class="sectionentry"><a href="4-jsn.html">
<spon class="sectiontitle">JSON</span></a> -
<span class="sectionpurpose">To read and write JSON data interchange material.</span></p>
<span class="sectionpurpose">To read, validate and write JSON data interchange material.</span></p>
</li>
</ul>
</li>

View file

@ -494,25 +494,25 @@ function togglePopup(material_id) {
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">rname</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="element-syntax">exp</span><span class="plain-syntax">[0];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">rtext</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="element-syntax">exp</span><span class="plain-syntax">[1];</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="constant-syntax">STDOUT</span><span class="plain-syntax">, </span><span class="string-syntax">"JSON requirement &lt;%S&gt; set to:\n%S----\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">rname</span><span class="plain-syntax">, </span><span class="identifier-syntax">rtext</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">JSON_requirement</span><span class="plain-syntax"> *</span><span class="identifier-syntax">req</span><span class="plain-syntax"> = </span><a href="../foundation-module/4-jsn.html#SP33" class="function-link"><span class="function-syntax">JSON::decode_printing_errors</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">rtext</span><span class="plain-syntax">, </span><span class="identifier-syntax">known_JSON_reqs</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">JSON_requirement</span><span class="plain-syntax"> *</span><span class="identifier-syntax">req</span><span class="plain-syntax"> = </span><a href="../foundation-module/4-jsn.html#SP37" class="function-link"><span class="function-syntax">JSON::decode_printing_errors</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">rtext</span><span class="plain-syntax">, </span><span class="identifier-syntax">known_JSON_reqs</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">req</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">dict_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">de</span><span class="plain-syntax"> = </span><a href="../foundation-module/2-dct.html#SP5" class="function-link"><span class="function-syntax">Dictionaries::create</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">known_JSON_reqs</span><span class="plain-syntax">, </span><span class="identifier-syntax">rname</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">de</span><span class="plain-syntax">) </span><span class="identifier-syntax">de</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">value</span><span class="plain-syntax"> = </span><span class="identifier-syntax">req</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="../foundation-module/4-jsn.html#SP32" class="function-link"><span class="function-syntax">JSON::encode_req</span></a><span class="plain-syntax">(</span><span class="constant-syntax">STDOUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">req</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="../foundation-module/4-jsn.html#SP35" class="function-link"><span class="function-syntax">JSON::encode_req</span></a><span class="plain-syntax">(</span><span class="constant-syntax">STDOUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">req</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="../foundation-module/4-pm.html#SP10" class="function-link"><span class="function-syntax">Regexp::match</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr</span><span class="plain-syntax">, </span><span class="identifier-syntax">JSON</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">" *(%c+?) against *(%c+)"</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">rtext</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="element-syntax">exp</span><span class="plain-syntax">[0];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">material</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="element-syntax">exp</span><span class="plain-syntax">[1];</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="constant-syntax">STDOUT</span><span class="plain-syntax">, </span><span class="string-syntax">"JSON verification test on:\n%S-- to match --\n%S\n----\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">material</span><span class="plain-syntax">, </span><span class="identifier-syntax">rtext</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">JSON_requirement</span><span class="plain-syntax"> *</span><span class="identifier-syntax">req</span><span class="plain-syntax"> = </span><a href="../foundation-module/4-jsn.html#SP33" class="function-link"><span class="function-syntax">JSON::decode_printing_errors</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">rtext</span><span class="plain-syntax">, </span><span class="identifier-syntax">known_JSON_reqs</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">JSON_requirement</span><span class="plain-syntax"> *</span><span class="identifier-syntax">req</span><span class="plain-syntax"> = </span><a href="../foundation-module/4-jsn.html#SP37" class="function-link"><span class="function-syntax">JSON::decode_printing_errors</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">rtext</span><span class="plain-syntax">, </span><span class="identifier-syntax">known_JSON_reqs</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">req</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">value</span><span class="plain-syntax"> = </span><a href="../foundation-module/4-jsn.html#SP10" class="function-link"><span class="function-syntax">JSON::decode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">material</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">value</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">value</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">JSON_type</span><span class="plain-syntax"> == </span><span class="constant-syntax">ERROR_JSONTYPE</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="constant-syntax">STDOUT</span><span class="plain-syntax">, </span><span class="string-syntax">"JSON error: %S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">value</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">if_error</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">errs</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEW_LINKED_LIST</span><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">v</span><span class="plain-syntax"> = </span><a href="../foundation-module/4-jsn.html#SP26" class="function-link"><span class="function-syntax">JSON::verify</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">value</span><span class="plain-syntax">, </span><span class="identifier-syntax">req</span><span class="plain-syntax">, </span><span class="identifier-syntax">errs</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">v</span><span class="plain-syntax"> = </span><a href="../foundation-module/4-jsn.html#SP28" class="function-link"><span class="function-syntax">JSON::validate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">value</span><span class="plain-syntax">, </span><span class="identifier-syntax">req</span><span class="plain-syntax">, </span><span class="identifier-syntax">errs</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">v</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="constant-syntax">STDOUT</span><span class="plain-syntax">, </span><span class="string-syntax">"Verifies"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>

Binary file not shown.

View file

@ -27,6 +27,7 @@ here we are.
@e JSON_pair_requirement_CLASS
@e JSON_requirement_CLASS
@e JSON_single_requirement_CLASS
@e JSON_type_CLASS
@e JSON_value_CLASS
@e linked_list_CLASS
@e linked_list_item_CLASS
@ -72,6 +73,7 @@ DECLARE_CLASS(HTML_file_state)
DECLARE_CLASS(JSON_pair_requirement)
DECLARE_CLASS(JSON_requirement)
DECLARE_CLASS(JSON_single_requirement)
DECLARE_CLASS(JSON_type)
DECLARE_CLASS(JSON_value)
DECLARE_CLASS(linked_list)
DECLARE_CLASS(method_set)

View file

@ -1,6 +1,6 @@
[JSON::] JSON.
To read and write JSON data interchange material.
To read, validate and write JSON data interchange material.
@h Introduction.
JSON (Douglas Crockford, c. 2000) stands for "JavaScript Object Notation", but is
@ -581,11 +581,11 @@ void JSON::encode_string(OUTPUT_STREAM, text_stream *T) {
@h Requirements.
Of course, the trouble with JSON is that it's a soup of undifferentiated data.
Just because you're expecting a pair of numbers, there's no reason to suppose
that's what you've been given, even if what you were given has parsed successfully.
that's what you've been given.
The following is an intentionally similar tree structure to //JSON_value//,
but with requirements in place of values throughout, and with each member of
an object marked as optional or mandatory.
A //JSON_requirement// is a sort of JSON schema: a specification for the structure
of a //JSON_value//. At the top level, it's a list of one or more equally
good alternative specifications. Note that the empty list is not allowed.
=
typedef struct JSON_requirement {
@ -607,103 +607,139 @@ JSON_requirement *JSON::add_alternative(JSON_requirement *so_far,
return so_far;
}
@ A "single requirement" is a little more than what a type would be in Javascript,
if Javascript actually had types. It can communicate something like "a number"
or "a list of strings"; but it can also say "the value has to be exactly this".
=
typedef struct JSON_single_requirement {
int JSON_type;
struct JSON_requirement *this_requirement;
struct JSON_value *this_value;
struct JSON_requirement *all_if_list;
struct linked_list *if_list; /* of |JSON_requirement| */
struct dictionary *dictionary_if_object; /* to |JSON_pair_requirement| */
struct linked_list *list_if_object; /* of |text_stream| */
struct text_stream *if_error;
int encoding_number;
struct JSON_type *this_type;
CLASS_DEFINITION
} JSON_single_requirement;
@ Exactly one of |this_requirement|, |this_value| and |this_type| should be
non-|NULL|, so we have one constructor function for each case:
=
JSON_single_requirement *JSON::require_requirement(JSON_requirement *req) {
JSON_single_requirement *sing = CREATE(JSON_single_requirement);
sing->this_requirement = req;
sing->this_value = NULL;
sing->this_type = NULL;
return sing;
}
JSON_single_requirement *JSON::require_value(JSON_value *value) {
JSON_single_requirement *sing = CREATE(JSON_single_requirement);
sing->this_requirement = NULL;
sing->this_value = value;
sing->this_type = NULL;
return sing;
}
JSON_single_requirement *JSON::require_type(int t) {
JSON_single_requirement *sing = CREATE(JSON_single_requirement);
sing->this_requirement = NULL;
sing->this_value = NULL;
sing->this_type = JSON::new_type_requirement(t);
return sing;
}
@ JSON types, in our model, look very like //JSON_value//s.
=
typedef struct JSON_type {
int JSON_type;
struct linked_list *if_list; /* of |JSON_requirement| */
struct JSON_requirement *all_if_list;
struct dictionary *dictionary_if_object; /* to |JSON_pair_requirement| */
struct linked_list *list_if_object; /* of |text_stream| */
struct text_stream *if_error;
CLASS_DEFINITION
} JSON_type;
typedef struct JSON_pair_requirement {
struct JSON_requirement *req;
int optional;
CLASS_DEFINITION
} JSON_pair_requirement;
@ The following constructors are used for everything...
JSON_type *JSON::new_type_requirement(int t) {
JSON_type *type = CREATE(JSON_type);
type->JSON_type = t;
=
JSON_single_requirement *JSON::require(int t) {
JSON_single_requirement *req = CREATE(JSON_single_requirement);
req->JSON_type = t;
req->this_requirement = NULL;
req->this_value = NULL;
req->all_if_list = NULL;
req->if_list = NULL;
if (t == ARRAY_JSONTYPE) req->if_list = NEW_LINKED_LIST(JSON_requirement);
req->dictionary_if_object = NULL;
req->list_if_object = NULL;
if (t == OBJECT_JSONTYPE) {
req->dictionary_if_object = Dictionaries::new(16, FALSE);
req->list_if_object = NEW_LINKED_LIST(text_stream);
if (t == ARRAY_JSONTYPE) {
type->if_list = NEW_LINKED_LIST(JSON_requirement);
type->all_if_list = NULL;
} else {
type->if_list = NULL;
type->all_if_list = NULL;
}
req->if_error = NULL;
req->encoding_number = 0;
return req;
if (t == OBJECT_JSONTYPE) {
type->dictionary_if_object = Dictionaries::new(16, FALSE);
type->list_if_object = NEW_LINKED_LIST(text_stream);
} else {
type->dictionary_if_object = NULL;
type->list_if_object = NULL;
}
type->if_error = NULL;
return type;
}
JSON_single_requirement *JSON::require_known(JSON_requirement *req) {
JSON_single_requirement *sing = JSON::require(-1);
sing->this_requirement = req;
return sing;
}
JSON_single_requirement *JSON::require_value(JSON_value *value) {
JSON_single_requirement *sing = JSON::require(-1);
sing->this_value = value;
return sing;
}
@ ...except for "array of any number of entries each matching this":
@ A convenience for "the value must be an array of any number of entries, each
of which meets the requirement |E_req|":
=
JSON_single_requirement *JSON::require_array_of(JSON_requirement *E_req) {
JSON_single_requirement *req = JSON::require(ARRAY_JSONTYPE);
req->all_if_list = E_req;
JSON_single_requirement *req = JSON::require_type(ARRAY_JSONTYPE);
req->this_type->all_if_list = E_req;
return req;
}
@ If an array wants to be a tuple with a fixed number of entries, each with
its own requirement, then instead call |JSON::require(ARRAY_JSONTYPE)| and
its own requirement, then instead call |JSON::require_type(ARRAY_JSONTYPE)| and
then make a number of calls to the following in sequence:
=
void JSON::require_entry(JSON_single_requirement *req_array, JSON_requirement *req_entry) {
if (req_array == NULL) internal_error("no array");
if (req_array->JSON_type != ARRAY_JSONTYPE) internal_error("not an array requirement");
if (req_entry == NULL) internal_error("no new entry");
ADD_TO_LINKED_LIST(req_entry, JSON_requirement, req_array->if_list);
void JSON::require_entry(JSON_single_requirement *array_sr, JSON_requirement *entry_sr) {
if (array_sr == NULL) internal_error("no array");
if ((array_sr->this_type == NULL) ||
(array_sr->this_type->JSON_type != ARRAY_JSONTYPE)) internal_error("not an array");
if (entry_sr == NULL) internal_error("no new entry");
ADD_TO_LINKED_LIST(entry_sr, JSON_requirement, array_sr->this_type->if_list);
}
@ Similarly, create an object requirement with |JSON::require(OBJECT_JSONTYPE)|
@ Similarly, create an object requirement with |JSON::require_type(OBJECT_JSONTYPE)|
and then either require or allow key-value pairs with:
=
void JSON::require_pair(JSON_single_requirement *req_obj, text_stream *key, JSON_requirement *req) {
JSON::require_pair_inner(req_obj, key, req, FALSE);
void JSON::require_pair(JSON_single_requirement *obj_sr, text_stream *key, JSON_requirement *req) {
JSON::require_pair_inner(obj_sr, key, req, FALSE);
}
void JSON::allow_pair(JSON_single_requirement *req_obj, text_stream *key, JSON_requirement *req) {
JSON::require_pair_inner(req_obj, key, req, TRUE);
void JSON::allow_pair(JSON_single_requirement *obj_sr, text_stream *key, JSON_requirement *req) {
JSON::require_pair_inner(obj_sr, key, req, TRUE);
}
void JSON::require_pair_inner(JSON_single_requirement *req_obj, text_stream *key,
void JSON::require_pair_inner(JSON_single_requirement *obj_sr, text_stream *key,
JSON_requirement *req, int opt) {
if (req_obj == NULL) internal_error("no object");
if (req_obj->JSON_type != OBJECT_JSONTYPE) internal_error("not an object requirement");
if (obj_sr == NULL) internal_error("no object");
if ((obj_sr->this_type == NULL) ||
(obj_sr->this_type->JSON_type != OBJECT_JSONTYPE)) internal_error("not an object");
if (req == NULL) internal_error("no val req");
key = Str::duplicate(key);
ADD_TO_LINKED_LIST(key, text_stream, req_obj->list_if_object);
ADD_TO_LINKED_LIST(key, text_stream, obj_sr->this_type->list_if_object);
JSON_pair_requirement *pr = CREATE(JSON_pair_requirement);
pr->req = req;
pr->optional = opt;
dict_entry *de = Dictionaries::create(req_obj->dictionary_if_object, key);
dict_entry *de = Dictionaries::create(obj_sr->this_type->dictionary_if_object, key);
if (de) de->value = pr;
}
@ -711,24 +747,29 @@ void JSON::require_pair_inner(JSON_single_requirement *req_obj, text_stream *key
is not permitted:
=
JSON_pair_requirement *JSON::look_up_pair(JSON_single_requirement *req_obj, text_stream *key) {
if (req_obj == NULL) internal_error("no object");
if (req_obj->JSON_type != OBJECT_JSONTYPE) internal_error("not an object");
dict_entry *de = Dictionaries::find(req_obj->dictionary_if_object, key);
JSON_pair_requirement *JSON::look_up_pair(JSON_single_requirement *obj_sr, text_stream *key) {
if (obj_sr == NULL) internal_error("no object");
if ((obj_sr->this_type == NULL) ||
(obj_sr->this_type->JSON_type != OBJECT_JSONTYPE)) internal_error("not an object");
dict_entry *de = Dictionaries::find(obj_sr->this_type->dictionary_if_object, key);
if (de == NULL) return NULL;
return de->value;
}
@ This is used when parsing textual requirements, to indicate a syntax error:
@ This is used when parsing textual requirements, to indicate a syntax error;
but it is not valid as a requirement itself.
=
JSON_single_requirement *JSON::error_req(text_stream *msg) {
JSON_single_requirement *req = JSON::require(ERROR_JSONTYPE);
req->if_error = Str::duplicate(msg);
JSON_single_requirement *JSON::error_sr(text_stream *msg) {
JSON_single_requirement *req = JSON::require_type(ERROR_JSONTYPE);
req->this_type->if_error = Str::duplicate(msg);
return req;
}
@ The following returns |TRUE| if the value meets the requirement in full;
@h Validation.
To "validate" a JSON value is to determine that it meets some //JSON_requirement//.
The following returns |TRUE| if the value meets the requirement in full;
if not, |FALSE|, and then if |errs| is not null, a list of error messages is
appended to the linked list |errs|.
@ -737,7 +778,7 @@ problem was: e.g. |"object.coordinates[1]"| is the result of the stack
holding |"object" > ".cooordinates" > "[1]"|.
=
int JSON::verify(JSON_value *val, JSON_requirement *req, linked_list *errs) {
int JSON::validate(JSON_value *val, JSON_requirement *req, linked_list *errs) {
lifo_stack *location = NEW_LIFO_STACK(text_stream);
if ((val) && (val->JSON_type == ARRAY_JSONTYPE)) {
PUSH_TO_LIFO_STACK(I"array", text_stream, location);
@ -745,10 +786,10 @@ int JSON::verify(JSON_value *val, JSON_requirement *req, linked_list *errs) {
if ((val) && (val->JSON_type == OBJECT_JSONTYPE)) {
PUSH_TO_LIFO_STACK(I"object", text_stream, location);
}
return JSON::verify_r(val, req, errs, location);
return JSON::validate_r(val, req, errs, location);
}
void JSON::verify_error(linked_list *errs, text_stream *err, lifo_stack *location) {
void JSON::validation_error(linked_list *errs, text_stream *err, lifo_stack *location) {
if (errs) {
text_stream *msg = Str::new();
int S = LinkedLists::len(location);
@ -765,63 +806,77 @@ void JSON::verify_error(linked_list *errs, text_stream *err, lifo_stack *locatio
}
}
@ So this is the recursive verification function:
@ So this is the recursive verification function. At the top level, it says the
value must match one of the single requirements in the list. (We can stop as
soon as it has met one.) If it meets none of them, we produce error messages
for the reason it fails just the first.
=
int JSON::verify_r(JSON_value *val, JSON_requirement *req, linked_list *errs,
int JSON::validate_r(JSON_value *val, JSON_requirement *req, linked_list *errs,
lifo_stack *location) {
if (val == NULL) internal_error("no value");
if (req == NULL) internal_error("no req");
JSON_single_requirement *sing;
LOOP_OVER_LINKED_LIST(sing, JSON_single_requirement, req->alternatives) {
int rv = JSON::verify_sr(val, sing, NULL, location);
int rv = JSON::validate_single_r(val, sing, NULL, location);
if (rv) return TRUE;
}
LOOP_OVER_LINKED_LIST(sing, JSON_single_requirement, req->alternatives) {
JSON::verify_sr(val, sing, errs, location);
JSON::validate_single_r(val, sing, errs, location);
break;
}
return FALSE;
}
int JSON::verify_sr(JSON_value *val, JSON_single_requirement *req, linked_list *errs,
lifo_stack *location) {
if (req->this_requirement)
return JSON::verify_r(val, req->this_requirement, errs, location);
if (req->this_value) {
@ Bad data always fails, and otherwise we split into the three cases.
=
int JSON::validate_single_r(JSON_value *val, JSON_single_requirement *req,
linked_list *errs, lifo_stack *location) {
if (val->JSON_type == ERROR_JSONTYPE) {
JSON::validation_error(errs,
I"erroneous JSON value from parsing bad text", location);
return FALSE;
}
if (req->this_requirement) @<Validate against this requirement@>;
if (req->this_value) @<Validate against this value@>;
if (req->this_type) @<Validate against this type@>;
internal_error("bad single requirement");
}
@<Validate against this requirement@> =
return JSON::validate_r(val, req->this_requirement, errs, location);
@<Validate against this value@> =
if (JSON::eq(val, req->this_value) == FALSE) {
TEMPORARY_TEXT(msg)
WRITE_TO(msg, "value ");
JSON::encode(msg, val);
WRITE_TO(msg, " not one of those allowed");
JSON::verify_error(errs, msg, location);
JSON::validation_error(errs, msg, location);
DISCARD_TEXT(msg)
return FALSE;
}
return TRUE;
}
if (val->JSON_type == ERROR_JSONTYPE) {
JSON::verify_error(errs, I"erroneous JSON value from parsing bad text", location);
return FALSE;
}
@<Verify that the JSON type is correct@>;
@<Validate against this type@> =
@<Verify that the JSON type constructors match@>;
int outcome = TRUE;
if (val->JSON_type == ARRAY_JSONTYPE)
@<Verify that the array entries meet requirements@>;
if (val->JSON_type == OBJECT_JSONTYPE)
@<Verify that the object members meet requirements@>;
return outcome;
}
@<Verify that the JSON type is correct@> =
if (val->JSON_type != req->JSON_type) {
@<Verify that the JSON type constructors match@> =
if (val->JSON_type != req->this_type->JSON_type) {
if (errs) {
TEMPORARY_TEXT(msg)
WRITE_TO(msg, "expected ");
JSON::write_type(msg, req->JSON_type);
JSON::write_type(msg, req->this_type->JSON_type);
WRITE_TO(msg, " but found ");
JSON::write_type(msg, val->JSON_type);
JSON::verify_error(errs, msg, location);
JSON::validation_error(errs, msg, location);
DISCARD_TEXT(msg)
}
return FALSE;
@ -831,11 +886,11 @@ int JSON::verify_sr(JSON_value *val, JSON_single_requirement *req, linked_list *
int count = 0;
JSON_value *E;
LOOP_OVER_LINKED_LIST(E, JSON_value, val->if_list) {
JSON_requirement *E_req = req->all_if_list;
JSON_requirement *E_req = req->this_type->all_if_list;
if (E_req == NULL) {
JSON_requirement *A_req;
int rcount = 0;
LOOP_OVER_LINKED_LIST(A_req, JSON_requirement, req->if_list)
LOOP_OVER_LINKED_LIST(A_req, JSON_requirement, req->this_type->if_list)
if (rcount++ == count)
E_req = A_req;
}
@ -843,10 +898,10 @@ int JSON::verify_sr(JSON_value *val, JSON_single_requirement *req, linked_list *
WRITE_TO(at, "[%d]", count);
PUSH_TO_LIFO_STACK(at, text_stream, location);
if (E_req == NULL) {
JSON::verify_error(errs, I"unexpected array entry", location);
JSON::validation_error(errs, I"unexpected array entry", location);
outcome = FALSE;
} else {
if (JSON::verify_r(E, E_req, errs, location) == FALSE) outcome = FALSE;
if (JSON::validate_r(E, E_req, errs, location) == FALSE) outcome = FALSE;
}
POP_LIFO_STACK(text_stream, location);
DISCARD_TEXT(at)
@ -855,7 +910,17 @@ int JSON::verify_sr(JSON_value *val, JSON_single_requirement *req, linked_list *
@<Verify that the object members meet requirements@> =
text_stream *key;
LOOP_OVER_LINKED_LIST(key, text_stream, val->list_if_object) {
LOOP_OVER_LINKED_LIST(key, text_stream, val->list_if_object)
@<Verify that the member with this key is allowed and contains the right data@>;
LOOP_OVER_LINKED_LIST(key, text_stream, req->this_type->list_if_object) {
JSON_pair_requirement *pr =
Dictionaries::read_value(req->this_type->dictionary_if_object, key);
if (pr == NULL) internal_error("broken JSON object requirement");
if (pr->optional == FALSE)
@<Verify that the value object does provide this mandatory member@>;
}
@<Verify that the member with this key is allowed and contains the right data@> =
JSON_value *E = Dictionaries::read_value(val->dictionary_if_object, key);
if (E == NULL) internal_error("broken JSON object dictionary");
JSON_pair_requirement *pr = JSON::look_up_pair(req, key);
@ -865,29 +930,24 @@ int JSON::verify_sr(JSON_value *val, JSON_single_requirement *req, linked_list *
if (pr == NULL) {
TEMPORARY_TEXT(msg)
WRITE_TO(msg, "unexpected member '%S'", key);
JSON::verify_error(errs, msg, location);
JSON::validation_error(errs, msg, location);
DISCARD_TEXT(msg)
outcome = FALSE;
} else {
if (JSON::verify_r(E, pr->req, errs, location) == FALSE) outcome = FALSE;
if (JSON::validate_r(E, pr->req, errs, location) == FALSE) outcome = FALSE;
}
POP_LIFO_STACK(text_stream, location);
DISCARD_TEXT(at)
}
LOOP_OVER_LINKED_LIST(key, text_stream, req->list_if_object) {
JSON_pair_requirement *pr = Dictionaries::read_value(req->dictionary_if_object, key);
if (pr == NULL) internal_error("broken JSON object requirement");
if (pr->optional == FALSE) {
@<Verify that the value object does provide this mandatory member@> =
JSON_value *E = JSON::look_up_object(val, key);
if (E == NULL) {
TEMPORARY_TEXT(msg)
WRITE_TO(msg, "member '%S' missing", key);
JSON::verify_error(errs, msg, location);
JSON::validation_error(errs, msg, location);
DISCARD_TEXT(msg)
outcome = FALSE;
}
}
}
@h Decoding JSON requirements.
It's convenient to be able to read and write these requirements to textual
@ -915,9 +975,10 @@ For example:
=
This function is essentially the same as //JSON::decode//, but returning a
requirement rather than a value, and therefore a little simpler. Note that
|known_names| can be |NULL| to have it not recognise any such names; there's
no need to create an empty dictionary in this case.
requirement rather than a value.
Note that |known_names| can be |NULL| to have it not recognise any such names;
there's no need to create an empty dictionary if this feature is unwanted.
=
JSON_requirement *JSON::decode_req(text_stream *T, dictionary *known_names) {
@ -933,7 +994,8 @@ JSON_requirement *JSON::decode_req_range(text_stream *T, int from, int to,
int first_nws = -1, last_nws = -1, first_c = 0, last_c = 0;
@<Find the first and last non-whitespace character in requirement@>;
if (first_c == '(') {
if (last_c != ')') return JSON::single_choice(JSON::error_req(I"mismatched '(' ... ')'"));
if (last_c != ')')
return JSON::single_choice(JSON::error_sr(I"mismatched '(' ... ')'"));
from = first_nws + 1;
to = last_nws;
JSON_requirement *req = NULL;
@ -965,35 +1027,41 @@ JSON_requirement *JSON::decode_req_alternative(JSON_requirement *req, text_strea
return JSON::add_alternative(req, sing);
}
@ Note that the keyword |null| is ambiguous in the grammar for JSON requirements:
does it mean "the value |null|", or does it mean "any value of the type |null|"?
This makes no difference because the type |null| admits only the value |null|, but
for what it's worth, we opt for the value.
=
JSON_single_requirement *JSON::decode_sreq_range(text_stream *T, int from, int to,
dictionary *known_names) {
int first_nws = -1, last_nws = -1, first_c = 0, last_c = 0;
@<Find the first and last non-whitespace character in requirement@>;
if (first_nws < 0) return JSON::error_req(I"whitespace where requirement expected");
if (first_nws < 0) return JSON::error_sr(I"whitespace where requirement expected");
switch (first_c) {
case '[':
if (last_c != ']') return JSON::error_req(I"mismatched '[' ... ']'");
JSON_single_requirement *array = JSON::require(ARRAY_JSONTYPE);
return JSON::decode_req_array(array, T, first_nws+1, last_nws, known_names);
if (last_c != ']') return JSON::error_sr(I"mismatched '[' ... ']'");
JSON_single_requirement *array_sr = JSON::require_type(ARRAY_JSONTYPE);
return JSON::decode_req_array(array_sr, T, first_nws+1, last_nws, known_names);
case '{':
if (last_c != '}') return JSON::error_req(I"mismatched '{' ... '}'");
JSON_single_requirement *obj = JSON::require(OBJECT_JSONTYPE);
return JSON::decode_req_object(obj, T, first_nws+1, last_nws, known_names);
if (last_c != '}') return JSON::error_sr(I"mismatched '{' ... '}'");
JSON_single_requirement *obj_sr = JSON::require_type(OBJECT_JSONTYPE);
return JSON::decode_req_object(obj_sr, T, first_nws+1, last_nws, known_names);
case '<':
if (last_c != '>') return JSON::error_req(I"mismatched '<' ... '>'");
if (last_c != '>') return JSON::error_sr(I"mismatched '<' ... '>'");
JSON_requirement *known = NULL;
TEMPORARY_TEXT(name)
for (int i = first_nws+1; i<last_nws; i++)
PUT_TO(name, Str::get_at(T, i));
if (known_names) {
dict_entry *de = Dictionaries::find(known_names, name);
if (de == NULL) return JSON::error_req(I"unknown '<name>'");
if (de == NULL) return JSON::error_sr(I"unknown '<name>'");
known = de->value;
} else {
return JSON::error_req(I"'<' ... '>' not allowed");
return JSON::error_sr(I"'<' ... '>' not allowed");
}
DISCARD_TEXT(name)
if (known) return JSON::require_known(known);
if (known) return JSON::require_requirement(known);
return NULL;
}
@ -1013,7 +1081,7 @@ JSON_single_requirement *JSON::decode_sreq_range(text_stream *T, int from, int t
if (value->JSON_type == ERROR_JSONTYPE) {
TEMPORARY_TEXT(err)
WRITE_TO(err, "JSON value error: %S", value->if_error);
JSON_single_requirement *sing = JSON::error_req(err);
JSON_single_requirement *sing = JSON::error_sr(err);
DISCARD_TEXT(err)
return sing;
}
@ -1021,21 +1089,19 @@ JSON_single_requirement *JSON::decode_sreq_range(text_stream *T, int from, int t
}
if ((Str::includes_at(T, first_nws, I"number")) && (last_nws - first_nws == 5))
return JSON::require(NUMBER_JSONTYPE);
return JSON::require_type(NUMBER_JSONTYPE);
if ((Str::includes_at(T, first_nws, I"double")) && (last_nws - first_nws == 5))
return JSON::require(DOUBLE_JSONTYPE);
return JSON::require_type(DOUBLE_JSONTYPE);
if ((Str::includes_at(T, first_nws, I"string")) && (last_nws - first_nws == 5))
return JSON::require(STRING_JSONTYPE);
return JSON::require_type(STRING_JSONTYPE);
if ((Str::includes_at(T, first_nws, I"boolean")) && (last_nws - first_nws == 6))
return JSON::require(BOOLEAN_JSONTYPE);
if ((Str::includes_at(T, first_nws, I"null")) && (last_nws - first_nws == 3))
return JSON::require(NULL_JSONTYPE);
return JSON::require_type(BOOLEAN_JSONTYPE);
text_stream *msg = Str::new();
WRITE_TO(msg, "unknown JSON type '");
for (int i=first_nws; i<last_nws; i++) PUT_TO(msg, Str::get_at(T, i));
WRITE_TO(msg, "'");
return JSON::error_req(msg);
return JSON::error_sr(msg);
}
@<Find the first and last non-whitespace character in requirement@> =
@ -1053,13 +1119,13 @@ JSON_single_requirement *JSON::decode_sreq_range(text_stream *T, int from, int t
@ Array requirements:
=
JSON_single_requirement *JSON::decode_req_array(JSON_single_requirement *array, text_stream *T,
int from, int to, dictionary *known_names) {
JSON_single_requirement *JSON::decode_req_array(JSON_single_requirement *array_sr,
text_stream *T, int from, int to, dictionary *known_names) {
int content = FALSE;
for (int i=from; i<to; i++)
if (Characters::is_whitespace(Str::get_at(T, i)) == FALSE)
content = TRUE;
if (content == FALSE) return array;
if (content == FALSE) return array_sr;
while ((to > from) && (Characters::is_whitespace(Str::get_at(T, to-1)))) to--;
if (Str::get_at(T, to-1) == '*') {
to--;
@ -1078,25 +1144,25 @@ JSON_single_requirement *JSON::decode_req_array(JSON_single_requirement *array,
}
}
if (first_comma >= 0) {
array = JSON::decode_req_array_entry(array, T, from, first_comma, known_names);
array_sr = JSON::decode_req_array_entry(array_sr, T, from, first_comma, known_names);
from = first_comma + 1;
goto NextEntry;
}
return JSON::decode_req_array_entry(array, T, from, to, known_names);
return JSON::decode_req_array_entry(array_sr, T, from, to, known_names);
}
JSON_single_requirement *JSON::decode_req_array_entry(JSON_single_requirement *array, text_stream *T,
int from, int to, dictionary *known_names) {
JSON_single_requirement *JSON::decode_req_array_entry(JSON_single_requirement *array_sr,
text_stream *T, int from, int to, dictionary *known_names) {
JSON_requirement *req = JSON::decode_req_range(T, from, to, known_names);
JSON::require_entry(array, req);
return array;
JSON::require_entry(array_sr, req);
return array_sr;
}
@ And similarly for objects.
=
JSON_single_requirement *JSON::decode_req_object(JSON_single_requirement *obj, text_stream *T,
int from, int to, dictionary *known_names) {
JSON_single_requirement *JSON::decode_req_object(JSON_single_requirement *obj,
text_stream *T, int from, int to, dictionary *known_names) {
int content = FALSE;
for (int i=from; i<to; i++)
if (Characters::is_whitespace(Str::get_at(T, i)) == FALSE)
@ -1122,14 +1188,14 @@ JSON_single_requirement *JSON::decode_req_object(JSON_single_requirement *obj, t
return JSON::decode_req_object_entry(obj, T, from, to, known_names);
}
JSON_single_requirement *JSON::decode_req_object_entry(JSON_single_requirement *obj, text_stream *T,
int from, int to, dictionary *known_names) {
JSON_single_requirement *JSON::decode_req_object_entry(JSON_single_requirement *obj,
text_stream *T, int from, int to, dictionary *known_names) {
int optional = FALSE;
while (Characters::is_whitespace(Str::get_at(T, from))) from++;
if (Str::get_at(T, from) == '?') { optional = TRUE; from++; }
while (Characters::is_whitespace(Str::get_at(T, from))) from++;
if (Str::get_at(T, from) != '"')
return JSON::error_req(I"key does not begin with quotation mark");
return JSON::error_sr(I"key does not begin with quotation mark");
from++;
int ended = FALSE;
TEMPORARY_TEXT(key)
@ -1142,12 +1208,12 @@ JSON_single_requirement *JSON::decode_req_object_entry(JSON_single_requirement *
PUT_TO(key, c);
}
}
if (ended == FALSE) return JSON::error_req(I"key does not end with quotation mark");
if (ended == FALSE) return JSON::error_sr(I"key does not end with quotation mark");
while (Characters::is_whitespace(Str::get_at(T, from))) from++;
if ((from >= to) || (Str::get_at(T, from) != ':'))
return JSON::error_req(I"key is not followed by ':'");
return JSON::error_sr(I"key is not followed by ':'");
from++;
if (JSON::look_up_pair(obj, key)) return JSON::error_req(I"duplicate key");
if (JSON::look_up_pair(obj, key)) return JSON::error_sr(I"duplicate key");
JSON_requirement *req = JSON::decode_req_range(T, from, to, known_names);
if (optional) JSON::allow_pair(obj, key, req);
else JSON::require_pair(obj, key, req);
@ -1160,22 +1226,21 @@ This is now simple, with one caveat. It's possible to set up requirement trees
so that they are not well-founded. For example:
= (text as InC)
JSON_single_requirement *set = JSON::require(ARRAY_JSONTYPE);
JSON_single_requirement *set = JSON::require_type(ARRAY_JSONTYPE);
set->all_if_list = JSON::single_choice(set);
=
This is not useless: it matches, say, |[]|, |[ [] ]| and |[ [], [ [] ] ]|
and other constructions giving amusement to set theorists. But it would cause
the following to hang without the check on "encoding numbers", which in effect
detect whether a requirement has already been printed in this round.
the following to hang. Note that requirements read in from files (see below)
are always well-founded, and so do not have this issue.
=
int unique_JSON_encoding = 1;
void JSON::encode_req(OUTPUT_STREAM, JSON_requirement *req) {
JSON::encode_req_r(OUT, req, ++unique_JSON_encoding);
JSON::encode_req_r(OUT, req);
}
void JSON::encode_req_r(OUTPUT_STREAM, JSON_requirement *req, int uniq) {
void JSON::encode_req_r(OUTPUT_STREAM, JSON_requirement *req) {
if (req == NULL) internal_error("no JSON value supplied");
int L = LinkedLists::len(req->alternatives);
if (L > 1) WRITE("( ");
@ -1183,38 +1248,32 @@ void JSON::encode_req_r(OUTPUT_STREAM, JSON_requirement *req, int uniq) {
JSON_single_requirement *sing;
LOOP_OVER_LINKED_LIST(sing, JSON_single_requirement, req->alternatives) {
if (c++ > 0) WRITE(" | ");
JSON::encode_sreq_r(OUT, sing, uniq);
JSON::encode_sreq_r(OUT, sing);
}
if (L > 1) WRITE(" )");
}
void JSON::encode_sreq_r(OUTPUT_STREAM, JSON_single_requirement *req, int uniq) {
if (req->encoding_number == uniq) {
WRITE("<req %d>", req->allocation_id);
} else {
req->encoding_number = uniq;
if (req->this_requirement) {
JSON::encode_req_r(OUT, req->this_requirement, uniq);
return;
}
if (req->this_value) {
JSON::encode(OUT, req->this_value);
return;
}
switch (req->JSON_type) {
void JSON::encode_sreq_r(OUTPUT_STREAM, JSON_single_requirement *sing) {
if (sing->this_requirement) JSON::encode_req_r(OUT, sing->this_requirement);
if (sing->this_value) JSON::encode(OUT, sing->this_value);
if (sing->this_type) JSON::encode_type(OUT, sing->this_type);
}
void JSON::encode_type(OUTPUT_STREAM, JSON_type *type) {
switch (type->JSON_type) {
case ARRAY_JSONTYPE: {
WRITE("[");
if (req->all_if_list) {
if (type->all_if_list) {
WRITE(" ");
JSON::encode_req_r(OUT, req->all_if_list, uniq);
JSON::encode_req_r(OUT, type->all_if_list);
WRITE("* ");
} else {
int count = 0;
JSON_requirement *E_req;
LOOP_OVER_LINKED_LIST(E_req, JSON_requirement, req->if_list) {
LOOP_OVER_LINKED_LIST(E_req, JSON_requirement, type->if_list) {
if (count++ > 0) WRITE(",");
WRITE(" ");
JSON::encode_req_r(OUT, E_req, uniq);
JSON::encode_req_r(OUT, E_req);
}
if (count > 0) WRITE(" ");
}
@ -1225,27 +1284,49 @@ void JSON::encode_sreq_r(OUTPUT_STREAM, JSON_single_requirement *req, int uniq)
WRITE("{\n"); INDENT;
int count = 0;
text_stream *key;
LOOP_OVER_LINKED_LIST(key, text_stream, req->list_if_object) {
LOOP_OVER_LINKED_LIST(key, text_stream, type->list_if_object) {
if (count++ > 0) WRITE(",\n");
JSON_pair_requirement *pr =
Dictionaries::read_value(req->dictionary_if_object, key);
Dictionaries::read_value(type->dictionary_if_object, key);
if (pr == NULL) internal_error("broken JSON req dictionary");
if (pr->optional) WRITE("?");
WRITE("\"");
JSON::encode_string(OUT, key);
WRITE("\": ");
JSON::encode_req_r(OUT, pr->req, uniq);
JSON::encode_req_r(OUT, pr->req);
}
if (count > 0) WRITE("\n");
OUTDENT; WRITE("}");
break;
}
default: JSON::write_type(OUT, req->JSON_type);
}
default: JSON::write_type(OUT, type->JSON_type);
}
}
@h Reading requirements files.
This convenient function reads in a set of requirements from a text file. Each
requirement should begin |<name> ::=|, and then continues until the next such
header, or the end of the file. So for example:
= (text)
! My scheme for JSON files describing geographical locations
<optional-letter> ::= ( "alpha" | "beta" | null )
<position> ::= {
"category": <optional-letter>,
"latitude": double,
"longitude": double,
}
=
is a valid file declaring two requirements. Forward references are not allowed --
e.g., <position> can refer to <optional-letter> but not vice versa -- and
therefore the requirements read in will always be well-founded. Comments are
lines beginning with |!|; other than comments, only white space is permitted
before the first requirement begins.
Note that the function //JSON::read_requirements_file// returns a dictionary
of the requirements it has read, by name (but without their angle-brackets):
here, it would have two keys, |optional-letter| and |position|.
=
typedef struct JSON_rrf_state {
@ -1287,9 +1368,14 @@ void JSON::read_requirements_file_helper(text_stream *text, text_file_position *
}
}
@ This is called when the end of a definition is reached, either because another
is about to start, or because the end of the file has come:
=
void JSON::process_req_defn(JSON_rrf_state *state) {
if (Str::len(state->name) > 0) {
JSON_requirement *req = JSON::decode_printing_errors(state->defn, state->dict, &(state->at));
JSON_requirement *req =
JSON::decode_printing_errors(state->defn, state->dict, &(state->at));
if (req) {
dict_entry *de = Dictionaries::create(state->dict, state->name);
if (de) de->value = req;
@ -1306,9 +1392,9 @@ JSON_requirement *JSON::decode_printing_errors(text_stream *defn, dictionary *di
int errors_found = FALSE;
JSON_single_requirement *sing;
LOOP_OVER_LINKED_LIST(sing, JSON_single_requirement, req->alternatives) {
if (sing->JSON_type == ERROR_JSONTYPE) {
if ((sing->this_type) && (sing->this_type->JSON_type == ERROR_JSONTYPE)) {
TEMPORARY_TEXT(err)
WRITE_TO(err, "JSON requirement error: %S", sing->if_error);
WRITE_TO(err, "JSON requirement error: %S", sing->this_type->if_error);
Errors::in_text_file_S(err, tfp);
errors_found = TRUE;
DISCARD_TEXT(err)

View file

@ -455,7 +455,7 @@ void Unit::test_JSON_helper(text_stream *text, text_file_position *tfp, void *st
WRITE_TO(STDOUT, "JSON error: %S", value->if_error);
else {
linked_list *errs = NEW_LINKED_LIST(text_stream);
int v = JSON::verify(value, req, errs);
int v = JSON::validate(value, req, errs);
if (v) {
WRITE_TO(STDOUT, "Verifies");
} else {