tg/generate.c

172 lines
3.2 KiB
C
Raw Normal View History

2014-08-11 14:04:59 -04:00
#include <stdio.h>
#include <signal.h>
#include <execinfo.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>
#include "tl-tl.h"
static char buf[1 << 20];
int buf_size;
int *buf_ptr = (int *)buf;
int *buf_end;
int verbosity;
int get_int (void) {
assert (buf_ptr < buf_end);
return *(buf_ptr ++);
}
long long get_long (void) {
assert (buf_ptr + 1 < buf_end);
long long r = *(long long *)buf_ptr;
buf_ptr += 2;
return r;
}
char *get_string (int *len) {
int l = *(unsigned char *)buf_ptr;
assert (l != 0xff);
char *res;
int tlen = 0;
if (l == 0xfe) {
l = ((unsigned)get_int ()) >> 8;
res = (char *)buf_ptr;
tlen = l;
} else {
res = ((char *)buf_ptr) + 1;
tlen = 1 + l;
}
*len = l;
tlen += ((-tlen) & 3);
assert (!(tlen & 3));
buf_ptr += tlen / 4;
assert (buf_ptr <= buf_end);
return res;
}
int parse_type (void) {
assert (get_int () == TLS_TYPE);
int name = get_int ();
int l;
char *name = get_string (&l);
int flags = get_int ();
int arity = get_int ();
long long params_types = get_long ();
printf ("int fetch_type_%s (struct paramed_type *T) {\n");
printf (" if (arity) { assert (T); }\n");
printf ("\n");
return 0;
}
int parse_tlo_file (void) {
buf_end = buf_ptr + (buf_size / 4);
assert (get_int () == TLS_SCHEMA_V2);
get_int (); // version
get_int (); // date
int i;
int types_num = get_int ();
for (i = 0; i < types_num; i++) {
if (parse_type () < 0) { return -1; }
}
return 0;
}
void usage (void) {
printf ("usage: generate [-v] [-h] <tlo-file>\n"
);
exit (2);
}
void logprintf (const char *format, ...) __attribute__ ((format (printf, 1, 2)));
void logprintf (const char *format __attribute__ ((unused)), ...) {
}
void hexdump (int *in_ptr, int *in_end) {
int *ptr = in_ptr;
while (ptr < in_end) { printf (" %08x", *(ptr ++)); }
printf ("\n");
}
#ifdef HAVE_EXECINFO_H
void print_backtrace (void) {
void *buffer[255];
const int calls = backtrace (buffer, sizeof (buffer) / sizeof (void *));
backtrace_symbols_fd (buffer, calls, 1);
}
#else
void print_backtrace (void) {
if (write (1, "No libexec. Backtrace disabled\n", 32) < 0) {
// Sad thing
}
}
#endif
void sig_segv_handler (int signum __attribute__ ((unused))) {
if (write (1, "SIGSEGV received\n", 18) < 0) {
// Sad thing
}
print_backtrace ();
exit (EXIT_FAILURE);
}
void sig_abrt_handler (int signum __attribute__ ((unused))) {
if (write (1, "SIGABRT received\n", 18) < 0) {
// Sad thing
}
print_backtrace ();
exit (EXIT_FAILURE);
}
int main (int argc, char **argv) {
signal (SIGSEGV, sig_segv_handler);
signal (SIGABRT, sig_abrt_handler);
int i;
while ((i = getopt (argc, argv, "vh")) != -1) {
switch (i) {
case 'h':
usage ();
return 2;
case 'v':
verbosity++;
break;
}
}
if (argc != optind + 1) {
usage ();
}
int fd = open (argv[optind], O_RDONLY);
if (fd < 0) {
fprintf (stderr, "Can not open file '%s'. Error %m\n", argv[optind]);
exit (1);
}
buf_size = read (fd, buf, (1 << 20));
if (fd == (1 << 20)) {
fprintf (stderr, "Too big tlo file\n");
exit (2);
}
return parse_tlo_file ();
}