[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Request to abstract write operations to stdout and stderr in jitter
From: |
Mohammad-Reza Nabipoor |
Subject: |
Request to abstract write operations to stdout and stderr in jitter |
Date: |
Sun, 8 Nov 2020 21:03:38 +0330 |
Hi, Luca.
As you know, poke provides a `libpoke` library that can be used in other
programs (like GUI, or head-less daemons).
But there's huge problem for those programs:
Jitter writes stuff directly to the `stdout` and `stderr`.
So the user of `libpoke` doesn't access to all data (those generated by jitter).
Consider the following C program (`pk-dis.c`); it has a `BUF` struct to
capture the disassembly of `plus1` function. But it only contains the
operands of the instructions, not the full disassembly.
Please look at the line that contains the word `bufstrcmp` below.
I've installed the `poke` using `make install DESTDIR=/tmp`. And I'm using the
`libpoke.a` static library.
I think you should change the `RTPATH` macro at line 3.
```
// gcc -o pk-dis pk-dis.c -I/tmp/usr/include /tmp/usr/lib/libpoke.a -lgc
#define RTPATH "/tmp/usr/share/poke"
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <err.h>
#include <libpoke.h>
struct buf
{
char *begin;
char *end;
char *cur; // cursor
};
static void bufinit (struct buf *b, char *mem, size_t msz);
static int bufempty (struct buf *b);
static void bufappendv (struct buf *b, const char *fmt, va_list ap);
static void bufappend (struct buf *b, const char *fmt, ...);
static int bufstrcmp (struct buf *b, const char *str);
static struct buf BUF;
static void
tif_flush (void)
{
}
static void
tif_puts (const char *s)
{
bufappend (&BUF, "%s", s);
}
static void
tif_printf (const char *fmt, ...)
{
va_list ap;
va_start (ap, fmt);
bufappendv (&BUF, fmt, ap);
va_end (ap);
}
static void
tif_indent (unsigned int lvl, unsigned int chr)
{
char *L;
L = alloca (lvl + 1);
memset (L, chr, lvl);
L[lvl] = '\0';
bufappend (&BUF, "%s", L);
}
static void
tif_class (const char *cls)
{
}
static void
tif_class_end (const char *cls)
{
}
static void
tif_hlink (const char *url, const char *id)
{
bufappend (&BUF, "%s", url);
}
static void
tif_hlink_end (void)
{
}
int
main ()
{
struct pk_term_if term = {
.flush_fn = tif_flush,
.puts_fn = tif_puts,
.printf_fn = tif_printf,
.indent_fn = tif_indent,
.class_fn = tif_class,
.end_class_fn = tif_class_end,
.hyperlink_fn = tif_hlink,
.end_hyperlink_fn = tif_hlink_end,
};
pk_compiler pkc;
int ok;
// init buffer
{
enum
{
BSZ = 1024, // 1 KiB
};
char *mem;
if ((mem = malloc (BSZ)) == NULL)
err (1, "malloc() failed");
bufinit (&BUF, mem, BSZ);
}
if ((pkc = pk_compiler_new (RTPATH, &term)) == NULL)
errx (1, "pk_compiler_new() failed");
{
const char *prg = "fun plus1 = (int x) int: {return x + 1;}";
ok = pk_compile_buffer (pkc, prg, NULL);
assert (ok != 0);
}
assert (bufempty (&BUF));
pk_disassemble_function (pkc, "plus1", 0);
assert (!bufempty (&BUF));
assert (bufstrcmp (&BUF, "\"plus1\"100x1111Exception {code=0x3,msg=\"no "
"return\",exit_status=0x1}1")
== 0);
pk_compiler_free (pkc);
free (BUF.begin);
return 0;
}
static void
bufinit (struct buf *b, char *mem, size_t msz)
{
assert (b != NULL);
assert (mem != NULL);
b->begin = mem;
b->end = b->begin + msz;
b->cur = b->begin;
}
static int
bufempty (struct buf *b)
{
assert (b != NULL);
return b->cur == b->begin;
}
static void
bufappendv (struct buf *b, const char *fmt, va_list ap)
{
assert (b != NULL);
int n;
if (!(b->cur < b->end))
errx (1, "memory full");
n = vsnprintf (b->cur, b->end - b->cur, fmt, ap);
if (n < 0)
errx (1, "vsnprintf() failed");
b->cur += n;
}
static void
bufappend (struct buf *b, const char *fmt, ...)
{
assert (b != NULL);
assert (fmt != NULL);
va_list ap;
va_start (ap, fmt);
bufappendv (b, fmt, ap);
va_end (ap);
}
static int
bufstrcmp (struct buf *b, const char *str)
{
assert (b != NULL);
return strncmp (b->begin, str, b->cur - b->begin);
}
```
The output of `./pk-dis` is:
```
note
$L1:
prolog
pushf
regvar
pushf
pushvar 0x1, 0x0
push
addi
nip2
popf
popf
return
popf
push
raise
popf
return
exitvm
```
So, do you have any solution for this?
It'd be nice if you abstract these operations using macros or functions.
Thanks,
Mohammad-Reza
- Request to abstract write operations to stdout and stderr in jitter,
Mohammad-Reza Nabipoor <=