Annotation of embedaddon/strongswan/src/starter/parser/parser.y, 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: #define _GNU_SOURCE /* for asprintf() */
18: #include <stdio.h>
19:
20: #include <utils/parser_helper.h>
21: #include <settings/settings_types.h>
22: #include <parser/conf_parser.h>
23:
24: #include "parser.h"
25:
26: #define YYDEBUG 1
27:
28: /**
29: * Defined by the lexer
30: */
31: int conf_parser_lex(YYSTYPE *lvalp, void *scanner);
32: int conf_parser_lex_init_extra(parser_helper_t *extra, void *scanner);
33: int conf_parser_lex_destroy(void *scanner);
34: int conf_parser_set_in(FILE *in, void *scanner);
35: void conf_parser_set_debug(int debug, void *scanner);
36: char *conf_parser_get_text(void *scanner);
37: int conf_parser_get_leng(void *scanner);
38: int conf_parser_get_lineno(void *scanner);
39: /* Custom functions in lexer */
40: bool conf_parser_open_next_file(parser_helper_t *ctx);
41:
42: /**
43: * Forward declaration
44: */
45: static void conf_parser_error(parser_helper_t *ctx, const char *s);
46:
47: /**
48: * Make sure to call lexer with the proper context
49: */
50: #undef yylex
51: static int yylex(YYSTYPE *lvalp, parser_helper_t *ctx)
52: {
53: return conf_parser_lex(lvalp, ctx->scanner);
54: }
55:
56: %}
57: %debug
58:
59: /* generate verbose error messages */
60: %error-verbose
61: /* generate a reentrant parser */
62: %define api.pure
63: /* prefix function/variable declarations */
64: %name-prefix "conf_parser_"
65:
66: /* interact properly with the reentrant lexer */
67: %lex-param {parser_helper_t *ctx}
68: %parse-param {parser_helper_t *ctx}
69:
70: /* types for terminal symbols... */
71: %union {
72: char *s;
73: conf_parser_section_t t;
74: }
75: %token <s> STRING
76: %token EQ SPACES NEWLINE CONFIG_SETUP CONN CA STRING_ERROR
77:
78: /* ...and other symbols */
79: %type <t> section_type
80: %type <s> section_name value
81:
82: /* make the equal sign left associative */
83: %left EQ
84:
85: /* properly destroy STRING tokens, which are strdup()ed, on errors */
86: %destructor { free($$); } STRING section_name value
87:
88: /* there are two shift/reduce conflicts because we allow empty lines (and lines
89: * with spaces) within settings and anywhere else (i.e. in the beginning) */
90: //%expect 2
91:
92: %%
93:
94: /**
95: * ipsec.conf grammar rules
96: */
97: statements:
98: /* empty */
99: | statements NEWLINE
100: | statements statement
101: ;
102:
103: statement:
104: section
105: | SPACES setting
106: ;
107:
108: section:
109: section_type section_name
110: {
111: if ($1 != CONF_PARSER_CONFIG_SETUP && (!$2 || !strlen($2)))
112: {
113: PARSER_DBG1(ctx, "section name missing");
114: free($2);
115: YYERROR;
116: }
117: conf_parser_t *parser = (conf_parser_t*)ctx->context;
118: parser->add_section(parser, $1, $2);
119: }
120: ;
121:
122: section_type:
123: CONFIG_SETUP
124: {
125: $$ = CONF_PARSER_CONFIG_SETUP;
126: }
127: |
128: CONN
129: {
130: $$ = CONF_PARSER_CONN;
131: }
132: |
133: CA
134: {
135: $$ = CONF_PARSER_CA;
136: }
137: ;
138:
139: section_name:
140: /* empty */
141: {
142: $$ = NULL;
143: }
144: | STRING
145: {
146: $$ = $1;
147: }
148: ;
149:
150: setting:
151: /* empty */
152: |
153: STRING EQ value
154: {
155: if (!strlen($1))
156: {
157: PARSER_DBG1(ctx, "setting name can't be empty");
158: free($1);
159: free($3);
160: YYERROR;
161: }
162: conf_parser_t *parser = (conf_parser_t*)ctx->context;
163: parser->add_setting(parser, $1, $value);
164: }
165: |
166: STRING EQ
167: {
168: if (!strlen($1))
169: {
170: PARSER_DBG1(ctx, "setting name can't be empty");
171: free($1);
172: YYERROR;
173: }
174: conf_parser_t *parser = (conf_parser_t*)ctx->context;
175: parser->add_setting(parser, $1, NULL);
176: }
177: |
178: STRING
179: {
180: PARSER_DBG1(ctx, "missing value for setting '%s'", $1);
181: free($1);
182: YYERROR;
183: }
184: ;
185:
186: value:
187: STRING
188: | value STRING
189: { /* just put a single space between them, use strings for more */
190: if (asprintf(&$$, "%s %s", $1, $2) < 0)
191: {
192: free($1);
193: free($2);
194: YYERROR;
195: }
196: free($1);
197: free($2);
198: }
199: ;
200:
201: %%
202:
203: /**
204: * Referenced by the generated parser
205: */
206: static void conf_parser_error(parser_helper_t *ctx, const char *s)
207: {
208: char *text = conf_parser_get_text(ctx->scanner);
209: int len = conf_parser_get_leng(ctx->scanner);
210:
211: if (len && text[len-1] == '\n')
212: { /* cut off newline at the end to avoid muti-line log messages */
213: len--;
214: }
215: PARSER_DBG1(ctx, "%s [%.*s]", s, (int)len, text);
216: }
217:
218: /**
219: * Parse the given file
220: */
221: bool conf_parser_parse_file(conf_parser_t *this, char *name)
222: {
223: parser_helper_t *helper;
224: bool success = FALSE;
225:
226: helper = parser_helper_create(this);
227: helper->get_lineno = conf_parser_get_lineno;
228: if (conf_parser_lex_init_extra(helper, &helper->scanner) != 0)
229: {
230: helper->destroy(helper);
231: return FALSE;
232: }
233: helper->file_include(helper, name);
234: if (!conf_parser_open_next_file(helper))
235: {
236: DBG1(DBG_CFG, "failed to open config file '%s'", name);
237: }
238: else
239: {
240: if (getenv("DEBUG_CONF_PARSER"))
241: {
242: yydebug = 1;
243: conf_parser_set_debug(1, helper->scanner);
244: }
245: success = yyparse(helper) == 0;
246: if (!success)
247: {
248: DBG1(DBG_CFG, "invalid config file '%s'", name);
249: }
250: }
251: conf_parser_lex_destroy(helper->scanner);
252: helper->destroy(helper);
253: return success;
254: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>