[CM] fn defined in C returns to wrong place
Gregg Reynolds
dev at mobileink.com
Fri Aug 26 06:04:57 PDT 2022
I'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.
But I've come across a problem that has me stumped. The one
incompatibility I've found in dune syntax is use of a dot '.' to mean
"current directory". For example:
(run ocaml-protoc %{deps} -binary -pp -ml_out .)
Notice the dot at the end. The s7 reader throws an error "unexpected close
paren: ..". 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 '.' to './',
and then s7 read the string from a string-port, giving a scheme list.
Works great.
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'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).
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 'return', 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.
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.
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.
So I think it must be related to the way I've configured error handling.
I've tried to follow the examples, e.g.
old_err_port = s7_set_current_error_port(s7, s7_open_output_string(s7));
if (old_err_port != s7_nil(s7)) {
gc_loc = s7_gc_protect(s7, old_err_port);
}
I also do this:
s7_pointer _s7_error_handler(s7_scheme *sc, s7_pointer args)
{
if (strstr(s7_string(s7_car(args)), "unexpected close paren:") != NULL)
{
if (debug)
printf(RED "Error: BAD DOT" CRESET "\n");
s7_write(s7, s7_make_string(s7, "BADDOT"),
s7_current_error_port(s7));
return s7_t(s7);
} else {
...
}
}
s7_define_function(s7, "error-handler",
_s7_error_handler, 1, 0, false,
"our error handler");
s7_eval_c_string(s7, "(set! (hook-functions *error-hook*) \n\
(list (lambda (hook) \n\
(error-handler \n\
(apply format #f (hook 'data))) \n\
(set! (hook 'result) 'our-error))))");
and it all seems to work, insofar as the read error is caught, I detect
"BADDOT", and fix the read. But the return does not work, and I have no
idea why.
Suggestions?
Thanks,
Gregg
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://cm-mail.stanford.edu/pipermail/cmdist/attachments/20220826/e1f3eec9/attachment.html>
More information about the Cmdist
mailing list