Annotation of embedaddon/strongswan/src/libstrongswan/settings/settings_lexer.l, revision 1.1.1.2

1.1       misho       1: %{
                      2: /*
                      3:  * Copyright (C) 2014-2018 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: 
                     19: #include "settings_parser.h"
                     20: 
                     21: bool settings_parser_open_next_file(parser_helper_t *ctx);
                     22: 
                     23: static void include_files(parser_helper_t *ctx);
                     24: 
                     25: %}
                     26: %option debug
                     27: %option warn
                     28: 
                     29: /* use start conditions stack */
                     30: %option stack
                     31: 
                     32: /* do not declare unneeded functions */
                     33: %option noinput noyywrap
                     34: 
                     35: /* do not include unistd.h as it might conflict with our scanner states */
                     36: %option nounistd
                     37: /* due to that disable interactive mode, which requires isatty() */
                     38: %option never-interactive
                     39: 
1.1.1.2 ! misho      40: /* don't use global variables */
        !            41: %option reentrant
1.1       misho      42: 
                     43: /* maintain the line number */
                     44: %option yylineno
                     45: 
                     46: /* don't generate a default rule */
                     47: %option nodefault
                     48: 
                     49: /* prefix function/variable declarations */
                     50: %option prefix="settings_parser_"
                     51: /* don't change the name of the output file otherwise autotools has issues */
                     52: %option outfile="lex.yy.c"
                     53: 
                     54: /* type of our extra data */
                     55: %option extra-type="parser_helper_t*"
                     56: 
                     57: /* state used to scan references */
                     58: %x ref
                     59: /* state used to scan values */
                     60: %x val
                     61: /* state used to scan include file patterns */
                     62: %x inc
                     63: /* state used to scan quoted strings */
                     64: %x str
                     65: 
                     66: /* pattern for section/key names */
                     67: NAME [^#{}:.,="\r\n\t ]
                     68: 
                     69: %%
                     70: 
                     71: [\t ]*#[^\r\n]*                        /* eat comments */
                     72: [\t\r ]+                               /* eat whitespace */
                     73: \n|#.*\n                               /* eat newlines and comments at the end of a line */
                     74: 
                     75: "{"                                            |
                     76: "}"                                            return yytext[0];
                     77: 
                     78: "."                                            return DOT;
                     79: ","                                            return COMMA;
                     80: 
                     81: ":"                                            {
                     82:        yy_push_state(ref, yyscanner);
                     83:        return COLON;
                     84: }
                     85: 
                     86: "="                                            {
                     87:        yy_push_state(val, yyscanner);
                     88:        return yytext[0];
                     89: }
                     90: 
                     91: "include"[\t ]+/[^=]   {
                     92:        yyextra->string_init(yyextra);
                     93:        yy_push_state(inc, yyscanner);
                     94: }
                     95: 
                     96: "\""                                   {
                     97:        PARSER_DBG1(yyextra, "unexpected string detected");
                     98:        return STRING_ERROR;
                     99: }
                    100: 
                    101: {NAME}+                                {
                    102:        yylval->s = strdup(yytext);
                    103:        return NAME;
                    104: }
                    105: 
                    106: <ref>{
                    107:        [\t ]*#[^\r\n]*                 /* eat comments */
                    108:        [\t\r ]+                                /* eat whitespace */
                    109:        \n|#.*\n                                /* eat newlines and comments at the end of a line */
                    110: 
                    111:        ","                                             return COMMA;
                    112: 
                    113:        {NAME}+(\.{NAME}+)* {
                    114:                yylval->s = strdup(yytext);
                    115:                return NAME;
                    116:        }
                    117: 
                    118:        .                                       {
                    119:                unput(yytext[0]);
                    120:                yy_pop_state(yyscanner);
                    121:        }
                    122: }
                    123: 
                    124: <val>{
                    125:        \r                                      /* just ignore these */
                    126:        [\t ]+
                    127:        <<EOF>>                         |
                    128:        [#}\n]                          {
                    129:                if (*yytext)
                    130:                {
                    131:                        switch (yytext[0])
                    132:                        {
                    133:                                case '\n':
                    134:                                        /* put the newline back to fix the line numbers */
                    135:                                        unput('\n');
                    136:                                        yy_set_bol(0);
                    137:                                        break;
                    138:                                case '#':
                    139:                                case '}':
                    140:                                        /* these are parsed outside of this start condition */
                    141:                                        unput(yytext[0]);
                    142:                                        break;
                    143:                        }
                    144:                }
                    145:                yy_pop_state(yyscanner);
                    146:                return NEWLINE;
                    147:        }
                    148: 
                    149:        "\""                            {
                    150:                yyextra->string_init(yyextra);
                    151:                yy_push_state(str, yyscanner);
                    152:        }
                    153: 
                    154:        /* same as above, but allow more characters */
                    155:        [^#}"\r\n\t ]+          {
                    156:                yylval->s = strdup(yytext);
                    157:                return NAME;
                    158:        }
                    159: }
                    160: 
                    161: <inc>{
                    162:        \r                                      /* just ignore these */
                    163:        /* we allow all characters except #, } and spaces, they can be escaped */
                    164:        <<EOF>>                         |
                    165:        [#}\n\t ]                       {
                    166:                if (*yytext)
                    167:                {
                    168:                        switch (yytext[0])
                    169:                        {
                    170:                                case '\n':
                    171:                                        /* put the newline back to fix the line numbers */
                    172:                                        unput('\n');
                    173:                                        yy_set_bol(0);
                    174:                                        break;
                    175:                                case '#':
                    176:                                case '}':
                    177:                                        /* these are parsed outside of this start condition */
                    178:                                        unput(yytext[0]);
                    179:                                        break;
                    180:                        }
                    181:                }
                    182:                include_files(yyextra);
                    183:                yy_pop_state(yyscanner);
                    184:        }
                    185:        "\""                            {       /* string include */
                    186:                yy_push_state(str, yyscanner);
                    187:        }
                    188:        \\                                      {
                    189:                yyextra->string_add(yyextra, yytext);
                    190:        }
                    191:        \\["#} ]                        {
                    192:                yyextra->string_add(yyextra, yytext+1);
                    193:        }
                    194:        [^"\\#}\r\n\t ]+ {
                    195:                yyextra->string_add(yyextra, yytext);
                    196:        }
                    197: }
                    198: 
                    199: <str>{
                    200:        \r                                      /* just ignore these */
                    201:        "\""                            |
                    202:        <<EOF>>                         |
                    203:        \\                                      {
                    204:                if (!streq(yytext, "\""))
                    205:                {
                    206:                        PARSER_DBG1(yyextra, "unterminated string detected");
                    207:                        return STRING_ERROR;
                    208:                }
                    209:                if (yy_top_state(yyscanner) == inc)
                    210:                {       /* string include */
                    211:                        include_files(yyextra);
                    212:                        yy_pop_state(yyscanner);
                    213:                        yy_pop_state(yyscanner);
                    214:                }
                    215:                else
                    216:                {
                    217:                        yy_pop_state(yyscanner);
                    218:                        yylval->s = yyextra->string_get(yyextra);
                    219:                        return STRING;
                    220:                }
                    221:        }
                    222: 
                    223:        \\n     yyextra->string_add(yyextra, "\n");
                    224:        \\r     yyextra->string_add(yyextra, "\r");
                    225:        \\t     yyextra->string_add(yyextra, "\t");
                    226:        \\\r?\n /* merge lines that end with escaped EOL characters */
                    227:        \\.     yyextra->string_add(yyextra, yytext+1);
                    228:        [^\\\r"]+                       {
                    229:                yyextra->string_add(yyextra, yytext);
                    230:        }
                    231: }
                    232: 
                    233: <<EOF>>                                        {
                    234:        settings_parser_pop_buffer_state(yyscanner);
                    235:        if (!settings_parser_open_next_file(yyextra) && !YY_CURRENT_BUFFER)
                    236:        {
                    237:                yyterminate();
                    238:        }
                    239: }
                    240: 
                    241: %%
                    242: 
                    243: /**
                    244:  * Open the next file, if any is queued and readable, otherwise returns FALSE.
                    245:  */
                    246: bool settings_parser_open_next_file(parser_helper_t *ctx)
                    247: {
                    248:        FILE *file;
                    249: 
                    250:        file = ctx->file_next(ctx);
                    251:        if (!file)
                    252:        {
                    253:                return FALSE;
                    254:        }
                    255: 
                    256:        settings_parser_set_in(file, ctx->scanner);
                    257:        settings_parser_push_buffer_state(
                    258:                        settings_parser__create_buffer(file, YY_BUF_SIZE,
                    259:                                                                                   ctx->scanner), ctx->scanner);
                    260:        return TRUE;
                    261: }
                    262: 
                    263: /**
                    264:  * Assumes that the file pattern to include is currently stored as string on
                    265:  * the helper object.
                    266:  */
                    267: static void include_files(parser_helper_t *ctx)
                    268: {
                    269:        char *pattern = ctx->string_get(ctx);
                    270: 
                    271:        ctx->file_include(ctx, pattern);
                    272:        free(pattern);
                    273: 
                    274:        settings_parser_open_next_file(ctx);
                    275: }
                    276: 
                    277: /**
                    278:  * Load the given string to be parsed next
                    279:  */
                    280: void settings_parser_load_string(parser_helper_t *ctx, const char *content)
                    281: {
                    282:        settings_parser__scan_string(content, ctx->scanner);
                    283: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>