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>