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
|
#include "ragel.h"
#include <inttypes.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
%%{
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((fpc == *error ? '^' : '~'), stderr); }
action lead { fprintf(stderr, (ragel->input.binary ? "%3s" : "%s"), ""); }
action char { fprintf(stderr, (ragel->input.binary ? "%02X " : "%c"), (uint8_t)fc); }
valid = ^cntrl - space - punct;
mark_token = (space valid | punct) ${ *error = fpc; };
search_err := ((any | mark_token) when { fpc != ragel->pe && fpc <= ragel->p })*;
word = print | valid*;
until_err = (any when { fpc != *error })*;
print_err := (until_err <: (word - '\n') >red %reset <: (print - '\n')*) $char >*lead %!end %/end;
print_mark := (until_err $lead <: (any | word) >red $mark) >*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);
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);
}
|