-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathconfig_scan.l
110 lines (96 loc) · 3.95 KB
/
config_scan.l
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
/*
* Copyright (C) 2015 Richard Burke
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
%{
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "config_parse_util.h"
#include "config_parse.h"
#include "util.h"
/* Define custom signature for yylex */
#define YY_DECL int yylex(Session *sess, const char *file_path)
/* Define action executed prior to the matched rule's action.
Here it is used to update position data */
#define YY_USER_ACTION cp_update_parser_location(yytext, file_path);
%}
/* Don't define functions which aren't used */
%option noinput
%option nounput
/* Assume there are no more files to scan on
EOF and avoid calling yywrap */
%option noyywrap
%%
#.*$
[[:space:]]+ { if (memchr(yytext, '\n', yyleng) != NULL) {
return TKN_NEW_LINE; } }
(-|\+)?[[:digit:]]+ { yylval.string = strdup(yytext);
return TKN_INTEGER; }
true|false { yylval.string = strdup(yytext);
return TKN_BOOLEAN; }
\"(\\.|[^\\"])*\" { yylval.string = strdup(yytext);
return TKN_STRING; }
\/(\\\/|[^\/])*\/[[:lower:]]* { yylval.string = strdup(yytext);
return TKN_REGEX; }
[[:alpha:]_]+ { yylval.string = strdup(yytext);
return TKN_NAME; }
![^\n]+ { yylval.string = strdup(yytext);
return TKN_SHELL_COMMAND; }
"=" { return TKN_ASSIGN; }
";" { return TKN_SEMI_COLON; }
"{" { return TKN_LEFT_BRACKET; }
"}" { return TKN_RIGHT_BRACKET; }
[^=;{}[:space:][:^print:]]+ { yylval.string = strdup(yytext);
return TKN_UNQUOTED_STRING; }
. { se_add_error(sess,
cp_get_config_error(
ERR_INVALID_CONFIG_CHARACTERS,
&yylloc,
"Invalid character \"%s\"",
yytext)); }
%%
void cp_start_scan_file(List *buffer_stack, FILE *file)
{
/* Add flex buffer to the buffer stack in case we
start processing a new buffer before finishing this
one */
YY_BUFFER_STATE buffer = yy_create_buffer(file, YY_BUF_SIZE);
list_add(buffer_stack, buffer);
yy_switch_to_buffer(buffer);
}
void cp_start_scan_string(List *buffer_stack, const char *str)
{
YY_BUFFER_STATE buffer = yy_scan_string(str);
list_add(buffer_stack, buffer);
}
void cp_finish_scan(List *buffer_stack)
{
size_t stack_size = list_size(buffer_stack);
assert(stack_size > 0);
if (stack_size > 0) {
/* Finished processing the current buffer
so pop if off the stack */
YY_BUFFER_STATE buffer = list_pop(buffer_stack);
yy_delete_buffer(buffer);
if (--stack_size > 0) {
/* Process any unfinished buffers left on the stack
that were switched away from */
buffer = list_get_last(buffer_stack);
yy_switch_to_buffer(buffer);
}
}
}