<div dir="ltr">I&#39;m using s7 to convert from Dune (the standard OCaml build tool) to Bazel. Dune files use sexp syntax, so in general this works great; almost all of the conversion logic is written in s7 scheme.<div><br></div><div>But I&#39;ve come across a problem that has me stumped.  The one incompatibility I&#39;ve found in dune syntax is use of a dot &#39;.&#39; to mean &quot;current directory&quot;. For example:</div><div><br></div><div>(run ocaml-protoc %{deps} -binary -pp -ml_out .)<br></div><div><br></div><div>Notice the dot at the end.  The s7 reader throws an error &quot;unexpected close paren: ..&quot;.  So I catch the error, close the input port, use the C api to read the file into a C string (dune files are short), convert &#39;.&#39; to &#39;./&#39;, and then s7 read the string from a string-port, giving a scheme list.  Works great.</div><div><br></div><div>The problem arises when I try to return the result. The routine that reads the dune files is load-dune, written in C (I use the C fts api to crawl the source tree, read the dune files, and construct a scheme object that mirrors the source tree).  So my main routine, in C, loads my convert.scm and then does s7_call (I&#39;ve also tried s7_apply_function, no difference) to run the main routine, which then calls load-dune.  The latter ends by returning the scheme structure that results from crawling the source tree and reading the dune files (using C apis).</div><div><br></div><div>This works great when the dune files can be read by s7 without error. Control resumes in convert.scm, which then runs the remaining conversion code (in scheme).  But when I encounter the bad-dot syntax, I handle the error as described above, but when I &#39;return&#39;, control does not resume in convert.scm.  Instead it resumes in the C code at the s7_call invocation site. So the value I return is returned as the result of s7_call (or s7_apply_function) which means the rest of my conversion code is skipped.</div><div><br></div><div>In other words it seems to skip the scheme call stack.  But I print the call stack (using backtrace and backtrace_symbols), and its the same for both good dune files and bad (corrected) dune files.  I also print a bunch of debug msgs to stdout, and they are the same in both cases. The only difference I can see is the return location.</div><div><br></div><div>I tried using s7_gc_protect functions in various ways to no effect.  I tried disabling GC by s7_gc_on(s7, s7_f(s7)); but that had no effect.  I tried eliminating the code that reads the file into a string by using a string constant, to no effect.</div><div><br></div><div>So I think it must be related to the way I&#39;ve configured error handling. I&#39;ve tried to follow the examples, e.g.</div><div><br></div><div>    old_err_port = s7_set_current_error_port(s7, s7_open_output_string(s7));<br>    if (old_err_port != s7_nil(s7)) {<br>        gc_loc = s7_gc_protect(s7, old_err_port);<br>    }<br></div><div><br></div><div>I also do this:</div><div><br></div><div>s7_pointer _s7_error_handler(s7_scheme *sc, s7_pointer args)<br>{<br>    if (strstr(s7_string(s7_car(args)), &quot;unexpected close paren:&quot;) != NULL) {<br>        if (debug)<br>            printf(RED &quot;Error: BAD DOT&quot; CRESET &quot;\n&quot;);<br>        s7_write(s7, s7_make_string(s7, &quot;BADDOT&quot;),<br>                 s7_current_error_port(s7));<br>        return s7_t(s7);<br>    } else {<br></div><div>      ...</div><div>    }</div><div>   }</div><div><br></div><div>   s7_define_function(s7, &quot;error-handler&quot;,<br>                       _s7_error_handler, 1, 0, false,<br>                       &quot;our error handler&quot;);<br></div><div><br></div><div>    s7_eval_c_string(s7, &quot;(set! (hook-functions *error-hook*) \n\<br>                            (list (lambda (hook) \n\<br>                                    (error-handler \n\<br>                                      (apply format #f (hook &#39;data))) \n\<br>                                    (set! (hook &#39;result) &#39;our-error))))&quot;);<br><br></div><div>and it all seems to work, insofar as the read error is caught, I detect &quot;BADDOT&quot;, and fix the read.  But the return does not work, and I have no idea why.</div><div><br></div><div>Suggestions?</div><div><br></div><div>Thanks,</div><div><br></div><div>Gregg</div></div>