diff options
-rw-r--r-- | html/020run.cc.html | 3 | ||||
-rw-r--r-- | html/035lookup.cc.html | 20 | ||||
-rw-r--r-- | html/036refcount.cc.html | 2 | ||||
-rw-r--r-- | html/042name.cc.html | 4 | ||||
-rw-r--r-- | html/050scenario.cc.html | 3 | ||||
-rw-r--r-- | html/053recipe_header.cc.html | 11 | ||||
-rw-r--r-- | html/057immutable.cc.html | 8 | ||||
-rw-r--r-- | html/080display.cc.html | 8 | ||||
-rw-r--r-- | html/091socket.cc.html | 68 | ||||
-rw-r--r-- | html/092socket.mu.html | 38 | ||||
-rw-r--r-- | html/edit/011-errors.mu.html | 6 | ||||
-rw-r--r-- | html/http-client.mu.html | 3 | ||||
-rw-r--r-- | html/http-server.mu.html | 4 |
13 files changed, 108 insertions, 70 deletions
diff --git a/html/020run.cc.html b/html/020run.cc.html index cb39df0e..57ea81ac 100644 --- a/html/020run.cc.html +++ b/html/020run.cc.html @@ -90,12 +90,15 @@ routine* Current_routine = <span class="Constant">NULL</span><span class="Delimi map<string<span class="Delimiter">,</span> <span class="Normal">int</span>> Instructions_running<span class="Delimiter">;</span> map<string<span class="Delimiter">,</span> <span class="Normal">int</span>> Locations_read<span class="Delimiter">;</span> map<string<span class="Delimiter">,</span> <span class="Normal">int</span>> Locations_read_by_instruction<span class="Delimiter">;</span> +<span class="Delimiter">:(before "End Setup")</span> +Current_routine = <span class="Constant">NULL</span><span class="Delimiter">;</span> <span class="Delimiter">:(code)</span> <span class="Normal">void</span> run<span class="Delimiter">(</span><span class="Normal">const</span> recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span> routine rr<span class="Delimiter">(</span>r<span class="Delimiter">);</span> Current_routine = &rr<span class="Delimiter">;</span> run_current_routine<span class="Delimiter">();</span> + Current_routine = <span class="Constant">NULL</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Normal">void</span> run_current_routine<span class="Delimiter">()</span> <span class="Delimiter">{</span> diff --git a/html/035lookup.cc.html b/html/035lookup.cc.html index 277d71ed..07545857 100644 --- a/html/035lookup.cc.html +++ b/html/035lookup.cc.html @@ -104,6 +104,15 @@ canonize<span class="Delimiter">(</span>x<span class="Delimiter">);</span> <span class="traceAbsent">-mem: storing 34 in location 0</span> <span class="traceContains">+error: can't write to location 0 in '1:address:num/lookup <- copy 34'</span> +<span class="Comment">//: attempts to /lookup address 0 always loudly fail</span> +<span class="Delimiter">:(scenario lookup_0_fails)</span> +<span class="Special">% Hide_errors = true;</span> +<span class="muRecipe">def</span> main [ + <span class="Constant">1</span>:address:num<span class="Special"> <- </span>copy <span class="Constant">0</span> + <span class="Constant">2</span>:num<span class="Special"> <- </span>copy <span class="Constant">1</span>:address:num/lookup +] +<span class="traceContains">+error: tried to /lookup 0 in '2:num <- copy 1:address:num/lookup'</span> + <span class="Delimiter">:(code)</span> <span class="Normal">void</span> canonize<span class="Delimiter">(</span>reagent& x<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span> @@ -122,10 +131,10 @@ canonize<span class="Delimiter">(</span>x<span class="Delimiter">);</span> raise << maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> << <span class="Constant">"tried to /lookup 0</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - lookup_memory_core<span class="Delimiter">(</span>x<span class="Delimiter">);</span> + lookup_memory_core<span class="Delimiter">(</span>x<span class="Delimiter">,</span> <span class="Comment">/*</span><span class="Comment">check_for_null</span><span class="Comment">*/</span><span class="Constant">true</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> -<span class="Normal">void</span> lookup_memory_core<span class="Delimiter">(</span>reagent& x<span class="Delimiter">)</span> <span class="Delimiter">{</span> +<span class="Normal">void</span> lookup_memory_core<span class="Delimiter">(</span>reagent& x<span class="Delimiter">,</span> <span class="Normal">bool</span> check_for_null<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>x<span class="Delimiter">.</span>value == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span> trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">"mem"</span><span class="Delimiter">)</span> << <span class="Constant">"location "</span> << x<span class="Delimiter">.</span>value << <span class="Constant">" is "</span> << no_scientific<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> x<span class="Delimiter">.</span>value<span class="Delimiter">))</span> << end<span class="Delimiter">();</span> x<span class="Delimiter">.</span>set_value<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> x<span class="Delimiter">.</span>value<span class="Delimiter">));</span> @@ -134,6 +143,12 @@ canonize<span class="Delimiter">(</span>x<span class="Delimiter">);</span> trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">"mem"</span><span class="Delimiter">)</span> << <span class="Constant">"skipping refcount at "</span> << x<span class="Delimiter">.</span>value << end<span class="Delimiter">();</span> x<span class="Delimiter">.</span>set_value<span class="Delimiter">(</span>x<span class="Delimiter">.</span>value+<span class="Constant">1</span><span class="Delimiter">);</span> <span class="Comment">// skip refcount</span> <span class="Delimiter">}</span> + <span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>check_for_null<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>Current_routine<span class="Delimiter">)</span> + raise << <span class="Constant">"tried to /lookup 0 in '"</span> << to_original_string<span class="Delimiter">(</span>current_instruction<span class="Delimiter">())</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + <span class="Normal">else</span> + raise << <span class="Constant">"tried to /lookup 0</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + <span class="Delimiter">}</span> drop_one_lookup<span class="Delimiter">(</span>x<span class="Delimiter">);</span> <span class="Delimiter">}</span> @@ -147,6 +162,7 @@ canonize<span class="Delimiter">(</span>x<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Normal">void</span> test_lookup_zero_address_does_not_skip_refcount<span class="Delimiter">()</span> <span class="Delimiter">{</span> + Hide_errors = <span class="Constant">true</span><span class="Delimiter">;</span> reagent x<span class="Delimiter">(</span><span class="Constant">"*x:address:num"</span><span class="Delimiter">);</span> x<span class="Delimiter">.</span>set_value<span class="Delimiter">(</span><span class="Constant">34</span><span class="Delimiter">);</span> <span class="Comment">// unsafe</span> put<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> <span class="Constant">34</span><span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span> diff --git a/html/036refcount.cc.html b/html/036refcount.cc.html index 40547a4d..95e1bf03 100644 --- a/html/036refcount.cc.html +++ b/html/036refcount.cc.html @@ -119,7 +119,7 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color <span class="Normal">int</span> payload_size<span class="Delimiter">(</span>reagent<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> x<span class="Delimiter">)</span> <span class="Delimiter">{</span> x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>pair<string<span class="Delimiter">,</span> string_tree*><span class="Delimiter">(</span><span class="Constant">"lookup"</span><span class="Delimiter">,</span> <span class="Constant">NULL</span><span class="Delimiter">));</span> - lookup_memory_core<span class="Delimiter">(</span>x<span class="Delimiter">);</span> + lookup_memory_core<span class="Delimiter">(</span>x<span class="Delimiter">,</span> <span class="Comment">/*</span><span class="Comment">check for nulls</span><span class="Comment">*/</span><span class="Constant">false</span><span class="Delimiter">);</span> <span class="Identifier">return</span> size_of<span class="Delimiter">(</span>x<span class="Delimiter">)</span> + <span class="Comment">/*</span><span class="Comment">refcount</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> diff --git a/html/042name.cc.html b/html/042name.cc.html index 098fee41..d6133a59 100644 --- a/html/042name.cc.html +++ b/html/042name.cc.html @@ -52,7 +52,7 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color <span class="muRecipe">def</span> main [ <span class="Normal">x</span>:num<span class="Special"> <- </span>copy y:num ] -<span class="traceContains">+error: main: use before set: 'y'</span> +<span class="traceContains">+error: main: tried to read ingredient 'y' in 'x:num <- copy y:num' but it hasn't been written to yet</span> <span class="Comment"># todo: detect conditional defines</span> <span class="Delimiter">:(after "Transform.push_back(compute_container_sizes)")</span> @@ -92,7 +92,7 @@ Name = Name_snapshot<span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>is_named_location<span class="Delimiter">(</span>ingredient<span class="Delimiter">))</span> names_used = <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>is_integer<span class="Delimiter">(</span>ingredient<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!already_transformed<span class="Delimiter">(</span>ingredient<span class="Delimiter">,</span> names<span class="Delimiter">))</span> <span class="Delimiter">{</span> - raise << maybe<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">)</span> << <span class="Constant">"use before set: '"</span> << ingredient<span class="Delimiter">.</span>name << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + raise << maybe<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">)</span> << <span class="Constant">"tried to read ingredient '"</span> << ingredient<span class="Delimiter">.</span>name << <span class="Constant">"' in '"</span> << to_original_string<span class="Delimiter">(</span>inst<span class="Delimiter">)</span> << <span class="Constant">"' but it hasn't been written to yet</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Comment">// use-before-set Error</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> diff --git a/html/050scenario.cc.html b/html/050scenario.cc.html index 3ca291e8..d44504a0 100644 --- a/html/050scenario.cc.html +++ b/html/050scenario.cc.html @@ -160,13 +160,14 @@ vector<scenario> Scenarios<span class="Delimiter">;</span> Num_core_mu_scenarios = SIZE<span class="Delimiter">(</span>Scenarios<span class="Delimiter">);</span> <span class="Delimiter">:(before "End Tests")</span> Hide_missing_default_space_errors = <span class="Constant">false</span><span class="Delimiter">;</span> -<span class="Normal">if</span> <span class="Delimiter">(</span>Num_core_mu_scenarios<span class="Delimiter">)</span> <span class="Delimiter">{</span> +<span class="Normal">if</span> <span class="Delimiter">(</span>Num_core_mu_scenarios > <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> time<span class="Delimiter">(</span>&t<span class="Delimiter">);</span> cerr << <span class="Constant">"Mu tests: "</span> << ctime<span class="Delimiter">(</span>&t<span class="Delimiter">);</span> <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < Num_core_mu_scenarios<span class="Delimiter">;</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="CommentedCode">//? cerr << '\n' << i << ": " << Scenarios.at(i).name;</span> run_mu_scenario<span class="Delimiter">(</span>Scenarios<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span> <span class="Normal">if</span> <span class="Delimiter">(</span>Passed<span class="Delimiter">)</span> cerr << <span class="Constant">"."</span><span class="Delimiter">;</span> + <span class="Normal">else</span> ++Num_failures<span class="Delimiter">;</span> <span class="Delimiter">}</span> cerr << <span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> diff --git a/html/053recipe_header.cc.html b/html/053recipe_header.cc.html index 021db5f4..a922f9e2 100644 --- a/html/053recipe_header.cc.html +++ b/html/053recipe_header.cc.html @@ -266,7 +266,7 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span local-scope <span class="Normal">b</span>:num<span class="Special"> <- </span>add a:num<span class="Delimiter">,</span> <span class="Constant">1</span> ] -<span class="traceContains">+error: foo: use before set: 'a'</span> +<span class="traceContains">+error: foo: tried to read ingredient 'a' in 'b:num <- add a:num, 1' but it hasn't been written to yet</span> <span class="traceContains">+error: did you forget 'load-ingredients'?</span> <span class="Delimiter">:(after "use-before-set Error")</span> @@ -286,6 +286,15 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span <span class="Normal">if</span> <span class="Delimiter">(</span>is_present_in_ingredients<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> recipe_name<span class="Delimiter">)),</span> x<span class="Delimiter">.</span>name<span class="Delimiter">))</span> raise << <span class="Constant">" did you forget 'load-ingredients'?</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> +<span class="Delimiter">:(code)</span> +<span class="Normal">bool</span> is_present_in_ingredients<span class="Delimiter">(</span><span class="Normal">const</span> recipe& callee<span class="Delimiter">,</span> <span class="Normal">const</span> string& ingredient_name<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>callee<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>callee<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name == ingredient_name<span class="Delimiter">)</span> + <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> + <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> +<span class="Delimiter">}</span> + <span class="SalientComment">//:: Check all calls against headers.</span> <span class="Delimiter">:(scenario show_clear_error_on_bad_call)</span> diff --git a/html/057immutable.cc.html b/html/057immutable.cc.html index f1fbb793..5f8ad767 100644 --- a/html/057immutable.cc.html +++ b/html/057immutable.cc.html @@ -538,14 +538,6 @@ set<<span class="Normal">int</span>> scan_contained_in_product_indices<spa <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> -<span class="Normal">bool</span> is_present_in_ingredients<span class="Delimiter">(</span><span class="Normal">const</span> recipe& callee<span class="Delimiter">,</span> <span class="Normal">const</span> string& ingredient_name<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>callee<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>callee<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name == ingredient_name<span class="Delimiter">)</span> - <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> - <span class="Delimiter">}</span> - <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> -<span class="Delimiter">}</span> - set<<span class="Normal">int</span>> ingredient_indices<span class="Delimiter">(</span><span class="Normal">const</span> instruction& inst<span class="Delimiter">,</span> <span class="Normal">const</span> set<reagent>& ingredient_names<span class="Delimiter">)</span> <span class="Delimiter">{</span> set<<span class="Normal">int</span>> result<span class="Delimiter">;</span> <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> diff --git a/html/080display.cc.html b/html/080display.cc.html index 56533131..a5f85757 100644 --- a/html/080display.cc.html +++ b/html/080display.cc.html @@ -47,17 +47,17 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color <span class="PreProc">#define CHECK_SCREEN \</span> <span class="PreProc"> </span><span class="Normal">if</span><span class="PreProc"> (!tb_is_active()) </span><span class="Delimiter">{</span><span class="PreProc"> \</span> <span class="PreProc"> </span><span class="Normal">if</span><span class="PreProc"> (Run_tests) \</span> -<span class="PreProc"> raise << maybe(current_recipe_name()) << </span><span class="Constant">"tried to print to real screen before 'open-console'</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="PreProc"> << end()</span><span class="Delimiter">;</span><span class="PreProc"> \</span> -<span class="PreProc"> </span><span class="Normal">else</span><span class="PreProc"> \</span> <span class="PreProc"> raise << maybe(current_recipe_name()) << </span><span class="Constant">"tried to print to real screen in a test!</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="PreProc"> << end()</span><span class="Delimiter">;</span><span class="PreProc"> \</span> +<span class="PreProc"> </span><span class="Normal">else</span><span class="PreProc"> \</span> +<span class="PreProc"> raise << maybe(current_recipe_name()) << </span><span class="Constant">"tried to print to real screen before 'open-console' or after 'close-console'</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="PreProc"> << end()</span><span class="Delimiter">;</span><span class="PreProc"> \</span> <span class="PreProc"> </span><span class="Identifier">break</span><span class="Delimiter">;</span><span class="PreProc"> \</span> <span class="PreProc"> </span><span class="Delimiter">}</span> <span class="PreProc">#define CHECK_CONSOLE \</span> <span class="PreProc"> </span><span class="Normal">if</span><span class="PreProc"> (!tb_is_active()) </span><span class="Delimiter">{</span><span class="PreProc"> \</span> <span class="PreProc"> </span><span class="Normal">if</span><span class="PreProc"> (Run_tests) \</span> -<span class="PreProc"> raise << maybe(current_recipe_name()) << </span><span class="Constant">"tried to read event from real keyboard/mouse before 'open-console'</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="PreProc"> << end()</span><span class="Delimiter">;</span><span class="PreProc"> \</span> -<span class="PreProc"> </span><span class="Normal">else</span><span class="PreProc"> \</span> <span class="PreProc"> raise << maybe(current_recipe_name()) << </span><span class="Constant">"tried to read event from real keyboard/mouse in a test!</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="PreProc"> << end()</span><span class="Delimiter">;</span><span class="PreProc"> \</span> +<span class="PreProc"> </span><span class="Normal">else</span><span class="PreProc"> \</span> +<span class="PreProc"> raise << maybe(current_recipe_name()) << </span><span class="Constant">"tried to read event from real keyboard/mouse before 'open-console' or after 'close-console'</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="PreProc"> << end()</span><span class="Delimiter">;</span><span class="PreProc"> \</span> <span class="PreProc"> </span><span class="Identifier">break</span><span class="Delimiter">;</span><span class="PreProc"> \</span> <span class="PreProc"> </span><span class="Delimiter">}</span> diff --git a/html/091socket.cc.html b/html/091socket.cc.html index e205508f..2c75978a 100644 --- a/html/091socket.cc.html +++ b/html/091socket.cc.html @@ -14,6 +14,7 @@ pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background- body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color: #080808; } * { font-size: 12pt; font-size: 1em; } .Constant { color: #00a0a0; } +.CommentedCode { color: #6c6c6c; } .cSpecial { color: #008000; } .Delimiter { color: #800080; } .Identifier { color: #c0a020; } @@ -155,7 +156,7 @@ socket_t* server_socket<span class="Delimiter">(</span><span class="Normal">int< <span class="Normal">int</span> dummy = <span class="Constant">0</span><span class="Delimiter">;</span> setsockopt<span class="Delimiter">(</span>result<span class="Delimiter">-></span>fd<span class="Delimiter">,</span> SOL_SOCKET<span class="Delimiter">,</span> SO_REUSEADDR<span class="Delimiter">,</span> &dummy<span class="Delimiter">,</span> <span class="Normal">sizeof</span><span class="Delimiter">(</span>dummy<span class="Delimiter">));</span> result<span class="Delimiter">-></span>addr<span class="Delimiter">.</span>sin_family = AF_INET<span class="Delimiter">;</span> - result<span class="Delimiter">-></span>addr<span class="Delimiter">.</span>sin_addr<span class="Delimiter">.</span>s_addr = INADDR_ANY<span class="Delimiter">;</span> + result<span class="Delimiter">-></span>addr<span class="Delimiter">.</span>sin_addr<span class="Delimiter">.</span>s_addr = Current_scenario ? htonl<span class="Delimiter">(</span>INADDR_LOOPBACK<span class="Delimiter">)</span> : INADDR_ANY<span class="Delimiter">;</span> <span class="Comment">// run tests without running afoul of any firewall</span> result<span class="Delimiter">-></span>addr<span class="Delimiter">.</span>sin_port = htons<span class="Delimiter">(</span>port<span class="Delimiter">);</span> <span class="Normal">if</span> <span class="Delimiter">(</span>bind<span class="Delimiter">(</span>result<span class="Delimiter">-></span>fd<span class="Delimiter">,</span> <span class="Normal">reinterpret_cast</span><sockaddr*><span class="Delimiter">(</span>&result<span class="Delimiter">-></span>addr<span class="Delimiter">),</span> <span class="Normal">sizeof</span><span class="Delimiter">(</span>result<span class="Delimiter">-></span>addr<span class="Delimiter">))</span> >= <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> listen<span class="Delimiter">(</span>result<span class="Delimiter">-></span>fd<span class="Delimiter">,</span> <span class="Comment">/*</span><span class="Comment">queue length</span><span class="Comment">*/</span><span class="Constant">5</span><span class="Delimiter">);</span> @@ -223,16 +224,12 @@ _READ_FROM_SOCKET<span class="Delimiter">,</span> put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"$read-from-socket"</span><span class="Delimiter">,</span> _READ_FROM_SOCKET<span class="Delimiter">);</span> <span class="Delimiter">:(before "End Primitive Recipe Checks")</span> <span class="Normal">case</span> _READ_FROM_SOCKET: <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> - raise << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'$read-from-socket' requires exactly two ingredients, but got '"</span> << inst<span class="Delimiter">.</span>original_string << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + raise << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'$read-from-socket' requires exactly one ingredient, but got '"</span> << inst<span class="Delimiter">.</span>original_string << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!is_mu_number<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span> - raise << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"first ingredient of '$read-from-socket' should be a number, but got '"</span> << to_string<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> - <span class="Identifier">break</span><span class="Delimiter">;</span> - <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!is_mu_number<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span> - raise << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"second ingredient of '$read-from-socket' should be a number, but got '"</span> << to_string<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + raise << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"first ingredient of '$read-from-socket' should be a number (socket), but got '"</span> << to_string<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Normal">int</span> nprod = SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">);</span> @@ -240,8 +237,8 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span raise << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'$read-from-socket' requires 1-4 products, but got '"</span> << inst<span class="Delimiter">.</span>original_string << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!is_mu_text<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span> - raise << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"first product of '$read-from-socket' should be a text (address array character), but got '"</span> << to_string<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!is_mu_character<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span> + raise << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"first product of '$read-from-socket' should be a character, but got '"</span> << to_string<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Normal">if</span> <span class="Delimiter">(</span>nprod > <span class="Constant">1</span> && !is_mu_boolean<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span> @@ -269,20 +266,25 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span <span class="Comment">// so use poll() in the beginning to wait for data before calling recv()</span> <span class="Comment">// 3. but poll() will block on EOF, so only use poll() on the very first</span> <span class="Comment">// $read-from-socket on a socket</span> + <span class="Comment">//</span> + <span class="Comment">// Also, there was an unresolved issue where attempts to read() a small</span> + <span class="Comment">// number of bytes (less than 447 on Linux and Mac) would cause browsers to</span> + <span class="Comment">// prematurely close the connection. See commit 3403. That seems to be gone</span> + <span class="Comment">// after moving to recv()+poll(). It was never observed on OpenBSD.</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!socket<span class="Delimiter">-></span>polled<span class="Delimiter">)</span> <span class="Delimiter">{</span> pollfd p<span class="Delimiter">;</span> bzero<span class="Delimiter">(</span>&p<span class="Delimiter">,</span> <span class="Normal">sizeof</span><span class="Delimiter">(</span>p<span class="Delimiter">));</span> p<span class="Delimiter">.</span>fd = socket<span class="Delimiter">-></span>fd<span class="Delimiter">;</span> p<span class="Delimiter">.</span>events = POLLIN | POLLHUP<span class="Delimiter">;</span> - <span class="Normal">int</span> status = poll<span class="Delimiter">(</span>&p<span class="Delimiter">,</span> <span class="Comment">/*</span><span class="Comment">num pollfds</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">,</span> <span class="Comment">/*</span><span class="Comment">timeout</span><span class="Comment">*/</span><span class="Constant">100</span><span class="Comment">/*</span><span class="Comment">ms</span><span class="Comment">*/</span><span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>status == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">int</span> poll_result = poll<span class="Delimiter">(</span>&p<span class="Delimiter">,</span> <span class="Comment">/*</span><span class="Comment">num pollfds</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">,</span> <span class="Comment">/*</span><span class="Comment">timeout</span><span class="Comment">*/</span><span class="Constant">100</span><span class="Comment">/*</span><span class="Comment">ms</span><span class="Comment">*/</span><span class="Delimiter">);</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>poll_result == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">no data</span><span class="Comment">*/</span><span class="Constant">0</span><span class="Delimiter">);</span> products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">found</span><span class="Comment">*/</span><span class="Constant">false</span><span class="Delimiter">);</span> products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">eof</span><span class="Comment">*/</span><span class="Constant">false</span><span class="Delimiter">);</span> products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">3</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">error</span><span class="Comment">*/</span><span class="Constant">0</span><span class="Delimiter">);</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>status < <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>poll_result < <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">int</span> error_code = errno<span class="Delimiter">;</span> raise << maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> << <span class="Constant">"error in $read-from-socket</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">no data</span><span class="Comment">*/</span><span class="Constant">0</span><span class="Delimiter">);</span> @@ -293,15 +295,19 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span <span class="Delimiter">}</span> socket<span class="Delimiter">-></span>polled = <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">int</span> bytes = <span class="Normal">static_cast</span><<span class="Normal">int</span>><span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span> - <span class="Normal">char</span>* contents = <span class="Normal">new</span> <span class="Normal">char</span>[bytes]<span class="Delimiter">;</span> - bzero<span class="Delimiter">(</span>contents<span class="Delimiter">,</span> bytes<span class="Delimiter">);</span> - <span class="Normal">int</span> bytes_read = recv<span class="Delimiter">(</span>socket<span class="Delimiter">-></span>fd<span class="Delimiter">,</span> contents<span class="Delimiter">,</span> bytes-<span class="Comment">/*</span><span class="Comment">terminal null</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">,</span> MSG_DONTWAIT<span class="Delimiter">);</span> - products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>new_mu_text<span class="Delimiter">(</span>contents<span class="Delimiter">));</span> + <span class="Normal">char</span> c = <span class="cSpecial">'\0'</span><span class="Delimiter">;</span> + <span class="Normal">int</span> error_code = <span class="Constant">0</span><span class="Delimiter">;</span> + <span class="Normal">int</span> bytes_read = recv<span class="Delimiter">(</span>socket<span class="Delimiter">-></span>fd<span class="Delimiter">,</span> &c<span class="Delimiter">,</span> <span class="Comment">/*</span><span class="Comment">single byte</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">,</span> MSG_DONTWAIT<span class="Delimiter">);</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>bytes_read < <span class="Constant">0</span><span class="Delimiter">)</span> error_code = errno<span class="Delimiter">;</span> +<span class="CommentedCode">//? if (error_code) {</span> +<span class="CommentedCode">//? ostringstream out;</span> +<span class="CommentedCode">//? out << "error in $read-from-socket " << socket->fd;</span> +<span class="CommentedCode">//? perror(out.str().c_str());</span> +<span class="CommentedCode">//? }</span> + products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>c<span class="Delimiter">);</span> products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">found</span><span class="Comment">*/</span><span class="Constant">true</span><span class="Delimiter">);</span> products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">eof</span><span class="Comment">*/</span>bytes_read <= <span class="Constant">0</span><span class="Delimiter">);</span> - products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">3</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">error</span><span class="Comment">*/</span><span class="Constant">0</span><span class="Delimiter">);</span> - <span class="Normal">delete</span> contents<span class="Delimiter">;</span> + products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">3</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>error_code<span class="Delimiter">);</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -320,17 +326,16 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> <span class="Normal">case</span> _WRITE_TO_SOCKET: <span class="Delimiter">{</span> <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> x = <span class="Normal">static_cast</span><<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span>><span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span> - socket_t* session = <span class="Normal">reinterpret_cast</span><socket_t*><span class="Delimiter">(</span>x<span class="Delimiter">);</span> - <span class="Comment">// write just one character at a time to the session socket</span> + socket_t* socket = <span class="Normal">reinterpret_cast</span><socket_t*><span class="Delimiter">(</span>x<span class="Delimiter">);</span> + <span class="Comment">// write just one character at a time to the socket</span> <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> y = <span class="Normal">static_cast</span><<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span>><span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span> <span class="Normal">char</span> c = <span class="Normal">static_cast</span><<span class="Normal">char</span>><span class="Delimiter">(</span>y<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>write<span class="Delimiter">(</span>session<span class="Delimiter">-></span>fd<span class="Delimiter">,</span> &c<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>write<span class="Delimiter">(</span>socket<span class="Delimiter">-></span>fd<span class="Delimiter">,</span> &c<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> << <span class="Constant">"failed to write to socket</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> exit<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> result = <span class="Normal">reinterpret_cast</span><<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span>><span class="Delimiter">(</span>session<span class="Delimiter">);</span> products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span> - products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>result<span class="Delimiter">);</span> + products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -345,7 +350,15 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!is_mu_number<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span> - raise << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"first ingredient of '$close-socket' should be a character, but got '"</span> << to_string<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + raise << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"first ingredient of '$close-socket' should be a number, but got '"</span> << to_string<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + raise << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'$close-socket' requires exactly one product, but got '"</span> << inst<span class="Delimiter">.</span>original_string << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name != inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name<span class="Delimiter">)</span> <span class="Delimiter">{</span> + raise << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"product of '$close-socket' must be first ingredient '"</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="Constant">"', but got '"</span> << inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Identifier">break</span><span class="Delimiter">;</span> @@ -355,6 +368,9 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> x = <span class="Normal">static_cast</span><<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span>><span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span> socket_t* socket = <span class="Normal">reinterpret_cast</span><socket_t*><span class="Delimiter">(</span>x<span class="Delimiter">);</span> close<span class="Delimiter">(</span>socket<span class="Delimiter">-></span>fd<span class="Delimiter">);</span> + <span class="Normal">delete</span> socket<span class="Delimiter">;</span> + products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span> + products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> <span class="Comment">// make sure we can't reuse the socket</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> diff --git a/html/092socket.mu.html b/html/092socket.mu.html index 78321183..e3c179eb 100644 --- a/html/092socket.mu.html +++ b/html/092socket.mu.html @@ -54,6 +54,7 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color memory-should-contain [ 10:array:character <span class="Special"><-</span> <span class="Constant">[abc]</span> ] + socket <span class="Special"><-</span> $close-socket socket ] <span class="Comment"># helper just for this scenario</span> <span class="muRecipe">def</span> example-handler query:text<span class="muRecipe"> -> </span>response:text [ @@ -85,18 +86,18 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color <span class="muData">type</span> request-handler = (recipe text<span class="muRecipe"> -> </span>text) -<span class="muRecipe">def</span> serve-one-request socket:num, request-handler:request-handler [ +<span class="muRecipe">def</span> serve-one-request socket:num, request-handler:request-handler<span class="muRecipe"> -> </span>socket:num [ <span class="Constant">local-scope</span> <span class="Constant">load-ingredients</span> session:num <span class="Special"><-</span> $accept socket assert session, <span class="Constant">[ </span> <span class="Constant">F - example-server-test: $accept failed]</span> contents:&:source:char, sink:&:sink:char <span class="Special"><-</span> new-channel<span class="Constant"> 30</span> - sink <span class="Special"><-</span> start-running receive-from-socket session, sink + start-running receive-from-socket session, sink query:text <span class="Special"><-</span> drain contents response:text <span class="Special"><-</span> call request-handler, query write-to-socket session, response - $close-socket session + session <span class="Special"><-</span> $close-socket session ] <span class="muRecipe">def</span> start-reading-from-network resources:&:resources, uri:text<span class="muRecipe"> -> </span>contents:&:source:char [ @@ -120,7 +121,7 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color req:text <span class="Special"><-</span> interpolate <span class="Constant">[GET _ HTTP/1.1]</span>, path request-socket socket, req contents:&:source:char, sink:&:sink:char <span class="Special"><-</span> new-channel<span class="Constant"> 10000</span> - start-running receive-from-socket socket, sink + start-running receive-from-client-socket-and-close socket, sink ] <span class="muRecipe">def</span> request-socket socket:num, s:text<span class="muRecipe"> -> </span>socket:num [ @@ -134,33 +135,34 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color $write-to-socket socket, <span class="Constant">10/lf</span> ] -<span class="muRecipe">def</span> receive-from-socket socket:num, sink:&:sink:char<span class="muRecipe"> -> </span>sink:&:sink:char [ +<span class="muRecipe">def</span> receive-from-socket socket:num, sink:&:sink:char<span class="muRecipe"> -> </span>sink:&:sink:char, socket:num [ <span class="Constant">local-scope</span> <span class="Constant">load-ingredients</span> <span class="Delimiter">{</span> <span class="Constant"> +next-attempt</span> - req:text, found?:bool, eof?:bool, error:num <span class="Special"><-</span> $read-from-socket socket, <span class="Constant">4096/bytes</span> + c:char, found?:bool, eof?:bool, error:num <span class="Special"><-</span> $read-from-socket socket + <span class="muControl">break-if</span> eof? <span class="muControl">break-if</span> error <span class="Delimiter">{</span> - <span class="muControl">break-if</span> found? - switch - <span class="muControl">loop</span> <span class="Constant">+next-attempt</span> + <span class="muControl">break-unless</span> found? + sink <span class="Special"><-</span> write sink, c <span class="Delimiter">}</span> - bytes-read:num <span class="Special"><-</span> length *req - i:num <span class="Special"><-</span> copy<span class="Constant"> 0</span> <span class="Delimiter">{</span> - done?:bool <span class="Special"><-</span> greater-or-equal i, bytes-read - <span class="muControl">break-if</span> done? - c:char <span class="Special"><-</span> index *req, i <span class="Comment"># todo: unicode</span> - sink <span class="Special"><-</span> write sink, c - i <span class="Special"><-</span> add i,<span class="Constant"> 1</span> - <span class="muControl">loop</span> + <span class="muControl">break-if</span> found? + switch <span class="Delimiter">}</span> - <span class="muControl">loop-unless</span> eof? + <span class="muControl">loop</span> <span class="Delimiter">}</span> sink <span class="Special"><-</span> close sink ] +<span class="muRecipe">def</span> receive-from-client-socket-and-close socket:num, sink:&:sink:char<span class="muRecipe"> -> </span>sink:&:sink:char, socket:num [ + <span class="Constant">local-scope</span> + <span class="Constant">load-ingredients</span> + sink <span class="Special"><-</span> receive-from-socket socket, sink + socket <span class="Special"><-</span> $close-socket socket +] + <span class="muRecipe">def</span> write-to-socket socket:num, s:text [ <span class="Constant">local-scope</span> <span class="Constant">load-ingredients</span> diff --git a/html/edit/011-errors.mu.html b/html/edit/011-errors.mu.html index 2bdf811a..91e48c57 100644 --- a/html/edit/011-errors.mu.html +++ b/html/edit/011-errors.mu.html @@ -521,7 +521,8 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color <span class="Constant"> . local-scope ╎ .</span> <span class="Constant"> . x:num <- copy y:num ╎ .</span> <span class="Constant"> .] ╎ .</span> - <span class="Constant"> .foo: use before set: 'y' ╎ .</span> + <span class="Constant"> .foo: tried to read ingredient 'y' in 'x:num <- co↩╎ .</span> + <span class="Constant"> .py y:num' but it hasn't been written to yet ╎ .</span> <span class="Constant"> .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎ .</span> <span class="Constant"> . ╎ .</span> ] @@ -539,7 +540,8 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color <span class="Constant"> . local-scope ╎ .</span> <span class="Constant"> . x:num <- copy y:num ╎ .</span> <span class="Constant"> .] ╎ .</span> - <span class="Constant"> .foo: use before set: 'y' ╎ .</span> + <span class="Constant"> .foo: tried to read ingredient 'y' in 'x:num <- co↩╎ .</span> + <span class="Constant"> .py y:num' but it hasn't been written to yet ╎ .</span> <span class="Constant"> .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎ .</span> <span class="Constant"> . ╎ .</span> ] diff --git a/html/http-client.mu.html b/html/http-client.mu.html index 264f56ed..8421fc60 100644 --- a/html/http-client.mu.html +++ b/html/http-client.mu.html @@ -18,7 +18,6 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color .Comment { color: #9090ff; } .Constant { color: #00a0a0; } .Special { color: #c00000; } -.CommentedCode { color: #6c6c6c; } .muRecipe { color: #ff8700; } --> </style> @@ -43,8 +42,6 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color <span class="muControl">break-if</span> done? n <span class="Special"><-</span> add n,<span class="Constant"> 1</span> buf <span class="Special"><-</span> append buf, c -<span class="CommentedCode">#? trunc?:bool <- greater-or-equal n, 10000</span> -<span class="CommentedCode">#? loop-unless trunc?</span> <span class="muControl">loop</span> <span class="Delimiter">}</span> result:text <span class="Special"><-</span> buffer-to-array buf diff --git a/html/http-server.mu.html b/html/http-server.mu.html index 97220e9b..6ed0ffe6 100644 --- a/html/http-server.mu.html +++ b/html/http-server.mu.html @@ -54,8 +54,8 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color <span class="Constant">SUCCESS!</span> <span class="Constant">]</span> $print <span class="Constant">10/newline</span>, <span class="Constant">[Wrote to and closing socket...]</span>, <span class="Constant">10/newline</span> - $close-socket session - $close-socket socket + session <span class="Special"><-</span> $close-socket session + socket <span class="Special"><-</span> $close-socket socket ] </pre> </body> |