1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
#include "ragel.h"
#include <inttypes.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
%%{
machine ragel;
write data noerror nofinal;
action red { fputs("\x1b[31m", stderr); }
action reset { fputs("\x1b[0m", stderr); }
action end { fputs("\x1b[0m\n", stderr); }
action mark { fputc('^', stderr); }
action tail { fputc('~', stderr); }
action lead { fputc(' ', stderr); }
word = alnum*;
token = ' ' | punct;
until_err = (any when { fpc != *error })*;
search_err := ((any | token %{ *error = fpc; }) when { fpc != ragel->pe && fpc <= ragel->p })*;
print_err := (until_err %red <: word %reset <: (any - '\n')*) ${ fputc(fc, stderr); } >lead %!end %/end;
print_mark := (until_err ${ fputc(' ', stderr); } %red %mark <: any word $tail) >lead %!end %/end;
}%%
static void
ragel_exec_error(const struct ragel *ragel, const int start_cs, const char **error)
{
(void)ragel_start;
assert(ragel && ragel->cl && error);
int cs = start_cs;
const char *p = ragel->cl, *pe = ragel->pe, *eof = ragel->eof;
assert(p <= pe);
%% write exec;
}
void
ragel_throw_error(struct ragel *ragel, const char *fmt, ...)
{
assert(ragel && fmt);
ragel->error = true;
const char *error = ragel->p;
if (!ragel->input.binary)
ragel_exec_error(ragel, ragel_en_search_err, &error);
const char *name = (ragel->name ? ragel->name : "");
assert(error >= ragel->cl);
uint64_t column = (error - ragel->cl);
fprintf(stderr, "\x1b[37m%s:%" PRIu64 ":%" PRIu64 " \x1b[31merror: \x1b[0m", name, ragel->lineno, column);
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
fputc('\n', stderr);
if (!ragel->input.binary) {
ragel_exec_error(ragel, ragel_en_print_err, &error);
ragel_exec_error(ragel, ragel_en_print_mark, &error);
}
}
void
ragel_set_name(struct ragel *ragel, const char *name)
{
assert(ragel);
ragel->name = name;
}
void
ragel_advance_line(struct ragel *ragel)
{
assert(ragel);
++ragel->lineno;
ragel->cl = ragel->p;
}
void
ragel_feed_input(struct ragel *ragel, const bool eof, const struct ragel_mem *input)
{
assert(ragel);
ragel->input = *input;
ragel->cl = ragel->p = ragel->input.data;
ragel->pe = ragel->input.end;
ragel->eof = (eof ? ragel->pe : NULL);
assert(ragel->p <= ragel->pe);
}
|