#include "tectonic_bridge_core.h"
#include <setjmp.h>
#include <stdio.h>
#define BUF_SIZE 1024
static char format_buf[BUF_SIZE] = "";
void *
xcalloc(size_t nelem, size_t elsize)
{
void *new_mem = calloc(nelem ? nelem : 1, elsize ? elsize : 1);
if (new_mem == NULL)
_tt_abort("xcalloc request for %lu elements of size %lu failed",
(unsigned long) nelem, (unsigned long) elsize);
return new_mem;
}
void *
xmalloc(size_t size)
{
void *new_mem = malloc(size ? size : 1);
if (new_mem == NULL)
_tt_abort("xmalloc request for %lu bytes failed", (unsigned long) size);
return new_mem;
}
void *
xrealloc(void *old_ptr, size_t size)
{
void *new_mem;
if (old_ptr == NULL) {
new_mem = xmalloc(size);
} else {
new_mem = realloc(old_ptr, size ? size : 1);
if (new_mem == NULL)
_tt_abort("xrealloc() to %lu bytes failed", (unsigned long) size);
}
return new_mem;
}
char *
xstrdup(const char *s)
{
char *new_string = xmalloc(strlen (s) + 1);
return strcpy(new_string, s);
}
PRINTF_FUNC(2,0) void
ttstub_diag_vprintf(ttbc_diagnostic_t *diag, const char *format, va_list ap)
{
vsnprintf(format_buf, BUF_SIZE, format, ap);
ttbc_diag_append(diag, format_buf);
}
PRINTF_FUNC(2,3) void
ttstub_diag_printf(ttbc_diagnostic_t *diag, const char *format, ...)
{
va_list ap;
va_start(ap, format);
ttstub_diag_vprintf(diag, format, ap);
va_end(ap);
}
static ttbc_state_t *tectonic_global_bridge_core = NULL;
static jmp_buf jump_buffer;
NORETURN PRINTF_FUNC(1,2) int
_tt_abort(const char *format, ...)
{
va_list ap;
va_start(ap, format);
vsnprintf(format_buf, BUF_SIZE, format, ap);
va_end(ap);
longjmp(jump_buffer, 1);
}
const char *
_ttbc_get_error_message(void)
{
return format_buf;
}
jmp_buf *
ttbc_global_engine_enter(ttbc_state_t *api)
{
tectonic_global_bridge_core = api;
return &jump_buffer;
}
void
ttbc_global_engine_exit(void)
{
tectonic_global_bridge_core = NULL;
}
PRINTF_FUNC(1,2) void
ttstub_issue_warning(const char *format, ...)
{
va_list ap;
va_start(ap, format);
vsnprintf(format_buf, BUF_SIZE, format, ap);
va_end(ap);
ttbc_issue_warning(tectonic_global_bridge_core, format_buf);
}
PRINTF_FUNC(1,2) void
ttstub_issue_error(const char *format, ...)
{
va_list ap;
va_start(ap, format);
vsnprintf(format_buf, BUF_SIZE, format, ap);
va_end(ap);
ttbc_issue_error(tectonic_global_bridge_core, format_buf);
}
void
ttstub_diag_finish(ttbc_diagnostic_t *diag)
{
ttbc_diag_finish(tectonic_global_bridge_core, diag);
}
rust_output_handle_t
ttstub_output_open(char const *path, int is_gz)
{
return ttbc_output_open(tectonic_global_bridge_core, path, is_gz);
}
rust_output_handle_t
ttstub_output_open_stdout(void)
{
return ttbc_output_open_stdout(tectonic_global_bridge_core);
}
int
ttstub_output_putc(rust_output_handle_t handle, int c)
{
return ttbc_output_putc(tectonic_global_bridge_core, handle, c);
}
size_t
ttstub_output_write(rust_output_handle_t handle, const char *data, size_t len)
{
return ttbc_output_write(tectonic_global_bridge_core, handle, (const uint8_t*) data, len);
}
PRINTF_FUNC(2,3) int
ttstub_fprintf(rust_output_handle_t handle, const char *format, ...)
{
static char fprintf_buf[BUF_SIZE] = "";
va_list ap;
va_start(ap, format);
int len = vsnprintf(fprintf_buf, BUF_SIZE, format, ap);
va_end(ap);
if (len >= BUF_SIZE) {
len = BUF_SIZE - 1;
fprintf_buf[len] = '\0';
}
if (len >= 0) {
ttstub_output_write(handle, fprintf_buf, len);
}
return len;
}
int
ttstub_output_flush(rust_output_handle_t handle)
{
return ttbc_output_flush(tectonic_global_bridge_core, handle);
}
int
ttstub_output_close(rust_output_handle_t handle)
{
return ttbc_output_close(tectonic_global_bridge_core, handle);
}
rust_input_handle_t
ttstub_input_open(char const *path, ttbc_file_format format, int is_gz)
{
return ttbc_input_open(tectonic_global_bridge_core, path, format, is_gz);
}
rust_input_handle_t
ttstub_input_open_primary(void)
{
return ttbc_input_open_primary(tectonic_global_bridge_core);
}
ssize_t
ttstub_get_last_input_abspath(char *buffer, size_t len)
{
return ttbc_get_last_input_abspath(tectonic_global_bridge_core, (uint8_t *) buffer, len);
}
size_t
ttstub_input_get_size(rust_input_handle_t handle)
{
return ttbc_input_get_size(tectonic_global_bridge_core, handle);
}
time_t
ttstub_input_get_mtime(rust_input_handle_t handle)
{
int64_t ti = ttbc_input_get_mtime(tectonic_global_bridge_core, handle);
return (time_t) ti;
}
size_t
ttstub_input_seek(rust_input_handle_t handle, ssize_t offset, int whence)
{
int internal_error = 0;
size_t rv = ttbc_input_seek(tectonic_global_bridge_core, handle, offset, whence, &internal_error);
if (internal_error) {
longjmp(jump_buffer, 1);
}
return rv;
}
ssize_t
ttstub_input_read(rust_input_handle_t handle, char *data, size_t len)
{
return ttbc_input_read(tectonic_global_bridge_core, handle, (uint8_t *) data, len);
}
int
ttstub_input_getc(rust_input_handle_t handle)
{
return ttbc_input_getc(tectonic_global_bridge_core, handle);
}
int
ttstub_input_ungetc(rust_input_handle_t handle, int ch)
{
return ttbc_input_ungetc(tectonic_global_bridge_core, handle, ch);
}
int
ttstub_input_close(rust_input_handle_t handle)
{
if (ttbc_input_close(tectonic_global_bridge_core, handle)) {
longjmp(jump_buffer, 1);
}
return 0;
}
int
ttstub_get_file_md5(char const *path, char *digest)
{
return ttbc_get_file_md5(tectonic_global_bridge_core, path, (uint8_t *) digest);
}
int
ttstub_shell_escape(const unsigned short *cmd, size_t len)
{
return ttbc_shell_escape(tectonic_global_bridge_core, cmd, len);
}