Lindenii Project Forge
Warning: Due to various recent migrations, viewing non-HEAD refs may be broken.
/src/util.c (raw)
#include <stdarg.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include "unicode.h"
#include "util.h"
void parser_fatal(struct parser *parser, const char *err) {
fprintf(stderr, "Error at %d:%d: %s\n",
parser->line, parser->col, err);
fclose(parser->input);
fclose(parser->output);
exit(1);
}
uint32_t parser_getch(struct parser *parser) {
if (parser->qhead) {
return parser->queue[--parser->qhead];
}
if (parser->str) {
uint32_t ch = utf8_decode(&parser->str);
if (!ch || ch == UTF8_INVALID) {
parser->str = NULL;
return UTF8_INVALID;
}
return ch;
}
uint32_t ch = utf8_fgetch(parser->input);
if (ch == '\n') {
parser->col = 0;
++parser->line;
} else {
++parser->col;
}
return ch;
}
void parser_pushch(struct parser *parser, uint32_t ch) {
if (ch != UTF8_INVALID) {
parser->queue[parser->qhead++] = ch;
}
}
void parser_pushstr(struct parser *parser, const char *str) {
parser->str = str;
}
int roff_macro(struct parser *p, char *cmd, ...) {
FILE *f = p->output;
int l = fprintf(f, ".%s", cmd);
va_list ap;
va_start(ap, cmd);
const char *arg;
while ((arg = va_arg(ap, const char *))) {
fputc(' ', f);
fputc('"', f);
while (*arg) {
uint32_t ch = utf8_decode(&arg);
if (ch == '"') {
fputc('\\', f);
++l;
}
l += utf8_fputch(f, ch);
}
fputc('"', f);
l += 3;
}
va_end(ap);
fputc('\n', f);
return l + 1;
}
void *xcalloc(size_t n, size_t s) {
void *p = calloc(n, s);
if (!p) {
fputs("Out of memory\n", stderr);
abort();
}
return p;
}
void *xrealloc(void *p, size_t s) {
void *ret = realloc(p, s);
if (!ret) {
fputs("Out of memory\n", stderr);
abort();
}
return ret;
}