summaryrefslogtreecommitdiffstats
path: root/tc/emp_ematch.l
blob: 2f4926d43d5b2a9eb55253ac2eb26d2e4c86c1aa (plain)
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/* SPDX-License-Identifier: GPL-2.0 */
%{
 #include "emp_ematch.tab.h"
 #include "m_ematch.h"

 extern int ematch_argc;
 extern char **ematch_argv;

 #define yylval ematch_lval

 #define NEXT_EM_ARG() do { ematch_argc--; ematch_argv++; } while(0);

 #define YY_INPUT(buf, result, max_size)				\
 {									\
 next:									\
 	if (ematch_argc <= 0)						\
		result = YY_NULL;					\
	else if (**ematch_argv == '\0') {				\
		NEXT_EM_ARG();						\
		goto next;						\
	} else {							\
		if (max_size <= strlen(*ematch_argv) + 1) {		\
			fprintf(stderr, "match argument too long.\n");	\
			result = YY_NULL;				\
		} else {						\
			strcpy(buf, *ematch_argv);			\
			result = strlen(*ematch_argv) + 1;		\
			buf[result-1] = ' ';				\
			buf[result] = '\0';				\
			NEXT_EM_ARG();					\
		}							\
	}								\
 }

 static void __attribute__ ((unused)) yyunput (int c,char *buf_ptr  );
 static void __attribute__ ((unused)) yy_push_state (int  new_state );
 static void __attribute__ ((unused)) yy_pop_state  (void);
 static int  __attribute__ ((unused)) yy_top_state (void );

 static char *strbuf;
 static unsigned int strbuf_size;
 static unsigned int strbuf_index;

 static void strbuf_enlarge(void)
 {
 	strbuf_size += 512;
 	strbuf = realloc(strbuf, strbuf_size);
 }

 static void strbuf_append_char(char c)
 {
 	while (strbuf_index >= strbuf_size)
 		strbuf_enlarge();
 	strbuf[strbuf_index++] = c;
 }

 static void strbuf_append_charp(char *s)
 {
 	while (strbuf_index >= strbuf_size)
 		strbuf_enlarge();
 	memcpy(strbuf + strbuf_index, s, strlen(s));
 	strbuf_index += strlen(s);
 }

%}

%x lexstr

%option 8bit stack warn noyywrap prefix="ematch_"
%%
[ \t\r\n]+

\"					{
						if (strbuf == NULL) {
							strbuf_size = 512;
							strbuf = calloc(1, strbuf_size);
							if (strbuf == NULL)
								return ERROR;
						}
						strbuf_index = 0;

						BEGIN(lexstr);
					}

<lexstr>\"					{
						BEGIN(INITIAL);
						yylval.b = bstr_new(strbuf, strbuf_index);
						yylval.b->quoted = 1;
						return ATTRIBUTE;
					}

<lexstr>\\[0-7]{1,3}			{ /* octal escape sequence */
						int res;

						sscanf(yytext + 1, "%o", &res);
						if (res > 0xFF) {
							fprintf(stderr, "error: octal escape sequence" \
							" out of range\n");
							return ERROR;
						}
						strbuf_append_char((unsigned char) res);
					}

<lexstr>\\[0-9]+				{ /* catch wrong octal escape seq. */
						fprintf(stderr, "error: invalid octale escape sequence\n");
						return ERROR;
					}

<lexstr>\\x[0-9a-fA-F]{1,2}		{
						int res;

						sscanf(yytext + 2, "%x", &res);

						if (res > 0xFF) {
							fprintf(stderr, "error: hexadecimal escape " \
							"sequence out of range\n");
							return ERROR;
						}
						strbuf_append_char((unsigned char) res);
					}

<lexstr>\\n				strbuf_append_char('\n');
<lexstr>\\r				strbuf_append_char('\r');
<lexstr>\\t				strbuf_append_char('\t');
<lexstr>\\v				strbuf_append_char('\v');
<lexstr>\\b				strbuf_append_char('\b');
<lexstr>\\f				strbuf_append_char('\f');
<lexstr>\\a				strbuf_append_char('\a');

<lexstr>\\(.|\n)			strbuf_append_char(yytext[1]);
<lexstr>[^\\\n\"]+			strbuf_append_charp(yytext);

[aA][nN][dD]				return AND;
[oO][rR]				return OR;
[nN][oO][tT]				return NOT;
"("					|
")"					{
						return yylval.i = *yytext;
					}
[^" \t\r\n()][^ \t\r\n()]*		{
						yylval.b = bstr_alloc(yytext);
						if (yylval.b == NULL)
							return ERROR;
						return ATTRIBUTE;
					}
%%