[metapost] MPlib: detect bye/end

luigi scarso luigi.scarso at gmail.com
Thu Dec 15 12:48:18 CET 2016


On Fri, Dec 9, 2016 at 11:50 AM, Nicola <nvitacolonna at gmail.com> wrote:
> Hello,
> when running a non-interactive MP instance, how can I detect that the last
> executed command was `bye`, `end` or something that causes MetaPost to quit?
>
> For instance, after
>
>     char *line = "bye."
>     int history = mp_execute(mp, line, strlen(line));
>
> mp_rundata(mp) returns non-zero size data (it returns zero-size data if I
> execute another command).
>
> Nicola
>
> --
> http://tug.org/metapost/

The effect of  scanning an "end" are the following calls:

mp_final_cleanup (mp);


                                          │
mp_close_files_and_terminate (mp);

The last one ends with
 mp->finished = true;

As first step mp_execute resets the streams, and if  mp->finished =
true  then returns


@ @c
int mp_execute (MP mp, char *s, size_t l) {
  mp_reset_stream (&(mp->run_data.term_out));
  mp_reset_stream (&(mp->run_data.log_out));
  mp_reset_stream (&(mp->run_data.error_out));
  mp_reset_stream (&(mp->run_data.ship_out));
  if (mp->finished) {
    return mp->history;

>From now whatever string  is put into execute,  the streams data are
NULL and nothing is executed.
We can execute a test string like "tracingall;tracingnone;": before
and "end" this should put something into one stream,
and if all the streams data are still NULL then we have already
executed an "end" .
Of course to execute a string we need a valid mp state .

static char *tracingall =
"tracingonline:=1; showstopping:=1;"
"tracingcommands:=3; tracingtitles:=1; tracingequations:=1;"
"tracingcapsules:=1; tracingspecs:=2; tracingchoices:=1; tracinglostchars:=1;"
"tracingstats:=1; tracingoutput:=1; tracingmacros:=1; tracingrestores:=1;";
static int strlen_tracingall=240;

static char *tracingnone =
"tracingcommands:=0; tracingtitles:=0; tracingequations:=0;"
"tracingcapsules:=0; tracingspecs:=0; tracingchoices:=0; tracinglostchars:=0;"
"tracingstats:=0; tracingoutput:=0; tracingmacros:=0; tracingrestores:=0;";
static int strlen_tracingnone=206;

int check_after_end_mp(MP mp)
{
 mp_run_data *cmd_result ;
 int ret;
 ret = -1 ;
 if (mp==NULL)
  return ret;
 ret = 0;
 mp_execute(mp, tracingall, strlen_tracingall);
 cmd_result = mp_rundata(mp);
 if ( cmd_result->term_out.data  == NULL &&
      cmd_result->error_out.data == NULL &&
      cmd_result->log_out.data   == NULL &&
      cmd_result->ship_out.data  == NULL )
  ret = 1;
 mp_execute(mp, tracingnone, strlen_tracingnone);
 return ret ;
}

MetaPost rev. 2107 has a new function mp_finished that returns
mp->finished as boolean,
so one can avoid the two calls of mp_execute

int check_after_end_mp(MP mp)
{
 mp_run_data *cmd_result ;
 int ret;
 ret = -1 ;
 if (mp==NULL)
  return ret;
 ret = 0;
 cmd_result = mp_rundata(mp);
 if ( mp_finished(mp)                    &&
      cmd_result->term_out.data  == NULL &&
      cmd_result->error_out.data == NULL &&
      cmd_result->log_out.data   == NULL &&
      cmd_result->ship_out.data  == NULL )
  ret = 1;
 return ret ;
}




-- 
luigi



More information about the metapost mailing list