~sbinet/star-tex-patches

[PATCH star-tex 2/3] internal/ctex: generate input TeX commands from CGo

Details
Message ID
<1SSGQ33hkOY4qeWmGpuSY6sLc4jTp4RmWhT0HfaT3w@cp7-web-039.plabs.ch>
DKIM signature
missing
Download raw message
Patch: +55 -63
Signed-off-by: Sebastien Binet <s@sbinet.org>
---
 internal/ctex/ctex-api.c |  7 +++---
 internal/ctex/ctex-api.h |  5 ++--
 internal/ctex/ctex.c     | 41 ++++++++-----------------------
 internal/ctex/ctex.go    | 52 +++++++++++++++++++++++++++-------------
 internal/ctex/ctex.h     | 13 ++++------
 5 files changed, 55 insertions(+), 63 deletions(-)

diff --git a/internal/ctex/ctex-api.c b/internal/ctex/ctex-api.c
index b45b327..f2ad7de 100644
--- a/internal/ctex/ctex-api.c
+++ b/internal/ctex/ctex-api.c
@@ -11,9 +11,8 @@ void ctex_del_context(ctex_t **ctx) {
  *ctx = NULL;
}

int ctex_context_typeset(ctex_t *ctx, const char *tex_fname,
                         const char *dvi_oname, const char *search_dir,
                         const char *working_dir, const char *err_oname) {
  process(ctx, tex_fname, dvi_oname, search_dir, working_dir, err_oname);
int ctex_context_typeset(ctex_t *ctx, const char *oname, const char *istream,
                         const char *ostream) {
  typeset(ctx, oname, istream, ostream);
  return 0;
}
diff --git a/internal/ctex/ctex-api.h b/internal/ctex/ctex-api.h
index 45a343f..0ec4617 100644
--- a/internal/ctex/ctex-api.h
+++ b/internal/ctex/ctex-api.h
@@ -10,9 +10,8 @@ extern "C" {
ctex_t *ctex_new_context();
void ctex_del_context(ctex_t **ctx);

int ctex_context_typeset(ctex_t *ctx, const char *tex_fname,
                         const char *dvi_oname, const char *search_dir,
                         const char *working_dir, const char *err_oname);
int ctex_context_typeset(ctex_t *ctx, const char *oname, const char *istream,
                         const char *ostream);

#ifdef __cplusplus
} /* extern "C" */
diff --git a/internal/ctex/ctex.c b/internal/ctex/ctex.c
index 07a59d4..8febf17 100644
--- a/internal/ctex/ctex.c
+++ b/internal/ctex/ctex.c
@@ -20,9 +20,8 @@ void ctex_init_ctx(ctex_t *ctx) {
  ctx->term_out = NULL;
  ctx->term_in = NULL;

  ctx->input_stream_buf = NULL;
  ctx->input_stream_len = 0;
  ctx->input_stream = NULL;
  ctx->istream = NULL;
  ctx->ostream = NULL;

  ctex_dvi_init(&ctx->dvi_mgr);
}
@@ -888,7 +887,7 @@ bool_t input_ln(ctex_t *ctx, FILE *f, bool_t bypass_eoln) {

bool_t init_terminal(ctex_t *ctx) {
  bool_t result;
  ctx->term_in = ctx->input_stream;
  ctx->term_in = ctx->istream;
  if (!ctx->term_in)
    io_error(errno, "TTY:");
  while (true) {
@@ -19299,21 +19298,19 @@ void init_prim(ctex_t *ctx) {
  ctx->no_new_control_sequence = true;
}

void getopt(ctex_t *ctx, int argc, const char **args) {
  for (int i = 0; i < argc; i++) {
    // ' ' must come first, the first character is always skipped…
    fprintf(ctx->input_stream, " %s", args[i]);
  }
}
void typeset(ctex_t *ctx, const char *oname, const char *istream,
             const char *ostream) {
  ctx->istream = fopen(istream, "r"); // will be closed as term_in
  ctx->ostream = fopen(ostream, "w"); // will be closed as term_out

  ctx->dvi_mgr.dvi_file = fopen(oname, "w");

void typeset(ctex_t *ctx, int argc, const char **args) {
  getopt(ctx, argc, args);
  if (setjmp(ctx->_JL9998))
    goto _L9998;
  if (setjmp(ctx->_JL9999))
    goto _L9999;
  ctx->history = 3;
  ctx->term_out = ctx->output_stream;
  ctx->term_out = ctx->ostream;
  if (!ctx->term_out)
    io_error(errno, "TTY:");
  if (ctx->ready_already == 314159)
@@ -19420,21 +19417,3 @@ _L9999:
    fclose(ctx->fmt_file);
  return;
}

void process(ctex_t *ctx, const char *filename, const char *result,
             const char *search_dir, const char *working_dir,
             const char *output) {

  ctx->input_stream =
      open_memstream(&ctx->input_stream_buf,
                     &ctx->input_stream_len); // will be closed as term_in
  ctx->output_stream = fopen(output, "w");    // will be closed as term_out

  ctx->dvi_mgr.dvi_file = fopen(result, "w");

  const char *args[5] = {
      // omits all stops (\batchmode also omits terminal output)
      "\\nonstopmode", "\\input plain", "\\input", filename, "\\end",
  };
  typeset(ctx, 5, args);
}
diff --git a/internal/ctex/ctex.go b/internal/ctex/ctex.go
index e9d7cf2..a3c8e4d 100644
--- a/internal/ctex/ctex.go
+++ b/internal/ctex/ctex.go
@@ -65,33 +65,54 @@ func (ctx *Context) Process(dvi io.Writer, f io.Reader) error {
	}
	defer os.RemoveAll(tmp)

	in, err := os.Create(filepath.Join(tmp, "input.tex"))
	tex, err := os.Create(filepath.Join(tmp, "input.tex"))
	if err != nil {
		return fmt.Errorf("could not create input TeX document: %w", err)
	}
	defer in.Close()
	defer tex.Close()

	_, err = io.Copy(in, f)
	_, err = io.Copy(tex, f)
	if err != nil {
		return fmt.Errorf("could not fill input TeX document: %w", err)
	}

	c_name := C.CString(in.Name())
	defer C.free(unsafe.Pointer(c_name))
	err = tex.Sync()
	if err != nil {
		return fmt.Errorf("could not save input TeX document: %w", err)
	}

	cmd, err := os.Create(filepath.Join(tmp, "cmd.tex"))
	if err != nil {
		return fmt.Errorf("could not create input TeX document: %w", err)
	}
	defer cmd.Close()

	for _, arg := range []string{
		`\nonstopmode`,
		`\input plain`,
		`\input`,
		tex.Name(),
		`\end`,
	} {
		// ' ' must come first, the first character is always skipped…
		fmt.Fprintf(cmd, " %s", arg)
	}

	err = cmd.Close()
	if err != nil {
		return fmt.Errorf("could not save input TeX commands: %w", err)
	}

	c_stdin := C.CString(cmd.Name())
	defer C.free(unsafe.Pointer(c_stdin))

	oname := filepath.Join(tmp, "out.dvi")
	c_dvi := C.CString(oname)
	defer C.free(unsafe.Pointer(c_dvi))

	c_search := C.CString(ctx.search)
	defer C.free(unsafe.Pointer(c_search))

	c_work := C.CString(ctx.work)
	defer C.free(unsafe.Pointer(c_work))

	ename := filepath.Join(tmp, "err.log")
	c_cerr := C.CString(ename)
	defer C.free(unsafe.Pointer(c_cerr))
	c_stdout := C.CString(ename)
	defer C.free(unsafe.Pointer(c_stdout))

	defer func() {
		if err == nil {
@@ -119,9 +140,8 @@ func (ctx *Context) Process(dvi io.Writer, f io.Reader) error {

	o := C.ctex_context_typeset(
		ctx.ctx,
		c_name, c_dvi,
		c_search, c_work,
		c_cerr,
		c_dvi,
		c_stdin, c_stdout,
	)

	if o != 0 {
diff --git a/internal/ctex/ctex.h b/internal/ctex/ctex.h
index e44b73a..b62e82e 100644
--- a/internal/ctex/ctex.h
+++ b/internal/ctex/ctex.h
@@ -260,10 +260,8 @@ typedef struct {

  jmp_buf _JL9998;
  jmp_buf _JL9999;
  FILE *output_stream; // displays the logging messages
  char *input_stream_buf;
  size_t input_stream_len;
  FILE *input_stream; // stores the command line args
  FILE *istream; // tex engine stdin
  FILE *ostream; // tex engine stdout
  //
  // inexplicably, p2c forgets these
  int tfm_file_mode;
@@ -610,11 +608,8 @@ bool_t load_fmt_file(ctex_t *ctx);
void close_files_and_terminate(ctex_t *ctx);
void final_cleanup(ctex_t *ctx);
void init_prim(ctex_t *ctx);
void getopt(ctex_t *ctx, int argc, const char **args);
void typeset(ctex_t *ctx, int argc, const char **args);
void process(ctex_t *ctx, const char *tex_fname, const char *dvi_ofname,
             const char *serach_dir, const char *work_dir,
             const char *err_oname);
void typeset(ctex_t *ctx, const char *oname, const char *istream,
             const char *ostream);

#ifdef __cplusplus
} // extern "C"
-- 
2.30.1
Reply to thread Export thread (mbox)