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>