Annotation of embedaddon/strongswan/src/starter/parser/lexer.l, revision 1.1.1.1
1.1 misho 1: %{
2: /*
3: * Copyright (C) 2013-2014 Tobias Brunner
4: * HSR Hochschule fuer Technik Rapperswil
5: *
6: * This program is free software; you can redistribute it and/or modify it
7: * under the terms of the GNU General Public License as published by the
8: * Free Software Foundation; either version 2 of the License, or (at your
9: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10: *
11: * This program is distributed in the hope that it will be useful, but
12: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14: * for more details.
15: */
16:
17: #include <utils/parser_helper.h>
18: #include <parser/conf_parser.h>
19:
20: #include "parser.h"
21:
22: bool conf_parser_open_next_file(parser_helper_t *ctx);
23:
24: static void include_files(parser_helper_t *ctx);
25:
26: %}
27: %option debug
28: %option warn
29:
30: /* use start conditions stack */
31: %option stack
32:
33: /* do not declare unneeded functions */
34: %option noinput noyywrap
35:
36: /* do not include unistd.h as it might conflict with our scanner states */
37: %option nounistd
38: /* due to that disable interactive mode, which requires isatty() */
39: %option never-interactive
40:
41: /* don't use global variables, and interact properly with bison */
42: %option reentrant bison-bridge
43:
44: /* maintain the line number */
45: %option yylineno
46:
47: /* don't generate a default rule */
48: %option nodefault
49:
50: /* prefix function/variable declarations */
51: %option prefix="conf_parser_"
52: /* don't change the name of the output file otherwise autotools has issues */
53: %option outfile="lex.yy.c"
54:
55: /* type of our extra data */
56: %option extra-type="parser_helper_t*"
57:
58: /* state used to scan include file patterns */
59: %x inc
60: /* state used to scan quoted strings */
61: %x str
62:
63: %%
64:
65: ^[\t ]*"version"[^\n]*$ /* eat legacy version declaration */
66: ^[\t ]+ return SPACES;
67: [\t ]+ /* eat other whitespace */
68: [\t ]*#[^\n]* /* eat comments */
69:
70: \n return NEWLINE;
71:
72: "=" return EQ;
73: ^"config setup" return CONFIG_SETUP;
74: ^"conn" return CONN;
75: ^"ca" return CA;
76:
77: "include"[\t ]+/[^=] {
78: yyextra->string_init(yyextra);
79: yy_push_state(inc, yyscanner);
80: }
81:
82: "\"" {
83: yyextra->string_init(yyextra);
84: yy_push_state(str, yyscanner);
85: }
86:
87: (@#)?[^\"#= \t\n]+ {
88: yylval->s = strdup(yytext);
89: return STRING;
90: }
91:
92: <inc>{
93: /* we allow all characters except # and spaces, they can be escaped */
94: <<EOF>> |
95: [#\n\t ] {
96: if (*yytext)
97: {
98: switch (yytext[0])
99: {
100: case '\n':
101: /* put the newline back to fix the line numbers */
102: unput('\n');
103: yy_set_bol(0);
104: break;
105: case '#':
106: /* comments are parsed outside of this start condition */
107: unput(yytext[0]);
108: break;
109: }
110: }
111: include_files(yyextra);
112: yy_pop_state(yyscanner);
113: }
114: "\"" { /* string include */
115: yy_push_state(str, yyscanner);
116: }
117: \\ {
118: yyextra->string_add(yyextra, yytext);
119: }
120: \\["#} ] {
121: yyextra->string_add(yyextra, yytext+1);
122: }
123: [^"\\#\n\t ]+ {
124: yyextra->string_add(yyextra, yytext);
125: }
126: }
127:
128: <str>{
129: "\"" |
130: <<EOF>> |
131: \\ {
132: if (!streq(yytext, "\""))
133: {
134: PARSER_DBG1(yyextra, "unterminated string detected");
135: return STRING_ERROR;
136: }
137: if (yy_top_state(yyscanner) == inc)
138: { /* string include */
139: include_files(yyextra);
140: yy_pop_state(yyscanner);
141: yy_pop_state(yyscanner);
142: }
143: else
144: {
145: yy_pop_state(yyscanner);
146: yylval->s = yyextra->string_get(yyextra);
147: return STRING;
148: }
149: }
150: \\n yyextra->string_add(yyextra, "\n");
151: \\r yyextra->string_add(yyextra, "\r");
152: \\t yyextra->string_add(yyextra, "\t");
153: \\\r?\n /* merge lines that end with EOL characters */
154: \\. yyextra->string_add(yyextra, yytext+1);
155: [^\\"]+ {
156: yyextra->string_add(yyextra, yytext);
157: }
158: }
159:
160: <<EOF>> {
161: conf_parser_pop_buffer_state(yyscanner);
162: if (!conf_parser_open_next_file(yyextra) && !YY_CURRENT_BUFFER)
163: {
164: yyterminate();
165: }
166: }
167:
168: %%
169:
170: /**
171: * Open the next file, if any is queued and readable, otherwise returns FALSE.
172: */
173: bool conf_parser_open_next_file(parser_helper_t *ctx)
174: {
175: FILE *file;
176:
177: file = ctx->file_next(ctx);
178: if (!file)
179: {
180: return FALSE;
181: }
182:
183: conf_parser_set_in(file, ctx->scanner);
184: conf_parser_push_buffer_state(
185: conf_parser__create_buffer(file, YY_BUF_SIZE,
186: ctx->scanner), ctx->scanner);
187: return TRUE;
188: }
189:
190: /**
191: * Assumes that the file pattern to include is currently stored as string on
192: * the helper object.
193: */
194: static void include_files(parser_helper_t *ctx)
195: {
196: char *pattern = ctx->string_get(ctx);
197:
198: ctx->file_include(ctx, pattern);
199: free(pattern);
200:
201: conf_parser_open_next_file(ctx);
202: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>