- introduced autotools
[strongswan.git] / src / starter / parser.l
1 %{
2 /* FreeS/WAN config file parser (parser.l)
3  * Copyright (C) 2001 Mathieu Lafon - Arkoon Network Security
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License as published by the
7  * Free Software Foundation; either version 2 of the License, or (at your
8  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13  * for more details.
14  *
15  * RCSID $Id: parser.l,v 1.5 2006/03/28 22:32:33 as Exp $
16  */
17
18 #include <string.h>
19 #include <stdlib.h>
20 #include <glob.h>
21
22 #include "y.tab.h"
23
24 #define MAX_INCLUDE_DEPTH  20
25
26 #define YY_NO_UNPUT
27 extern void yyerror(const char *);
28 extern int yylex (void);
29
30 static struct {
31         int stack_ptr;
32         YY_BUFFER_STATE stack[MAX_INCLUDE_DEPTH];
33         FILE *file[MAX_INCLUDE_DEPTH];
34         unsigned int line[MAX_INCLUDE_DEPTH];
35         char *filename[MAX_INCLUDE_DEPTH];
36 } __parser_y_private;
37
38 void _parser_y_error(char *b, int size, const char *s);
39 void _parser_y_init (const char *f);
40 void _parser_y_fini (void);
41 int _parser_y_include (const char *filename);
42
43 void _parser_y_error(char *b, int size, const char *s)
44 {
45     extern char *yytext; // was: char yytext[];
46
47     snprintf(b, size, "%s:%d: %s [%s]",
48             __parser_y_private.filename[__parser_y_private.stack_ptr],
49             __parser_y_private.line[__parser_y_private.stack_ptr],
50             s, yytext);
51 }
52
53 void _parser_y_init (const char *f)
54 {
55     memset(&__parser_y_private, 0, sizeof(__parser_y_private));
56     __parser_y_private.line[0] = 1;
57     __parser_y_private.filename[0] = strdup(f);
58 }
59
60 void _parser_y_fini (void)
61 {
62     unsigned int i;
63
64     for (i = 0; i < MAX_INCLUDE_DEPTH; i++)
65     {
66         if (__parser_y_private.filename[i])
67             free(__parser_y_private.filename[i]);
68         if (__parser_y_private.file[i])
69             fclose(__parser_y_private.file[i]);
70     }
71     memset(&__parser_y_private, 0, sizeof(__parser_y_private));
72 }
73
74 int _parser_y_include (const char *filename)
75 {
76     glob_t files;
77     int i, ret;
78
79     ret = glob(filename, GLOB_ERR, NULL, &files);
80     if (ret)
81     {
82         const char *err;
83
84         switch (ret)
85         {
86         case GLOB_NOSPACE:
87             err = "include files ran out of memory";
88             break;
89         case GLOB_ABORTED:
90             err = "include files aborted due to read error";
91             break;
92         case GLOB_NOMATCH:
93             err = "include files found no matches";
94             break;
95         default:
96             err = "unknown include files error";
97         }
98         yyerror(err);
99         return 1;
100     }
101
102     for (i = 0; i < files.gl_pathc; i++)
103     {
104         FILE *f;
105         unsigned int p = __parser_y_private.stack_ptr + 1;
106
107         if (p >= MAX_INCLUDE_DEPTH)
108         {
109             yyerror("max inclusion depth reached");
110             return 1;
111         }
112
113         f = fopen(files.gl_pathv[i], "r");
114         if (!f)
115         {
116             yyerror("can't open include filename");
117             continue;
118         }
119
120         __parser_y_private.stack_ptr++;
121         __parser_y_private.file[p] = f;
122         __parser_y_private.stack[p] = YY_CURRENT_BUFFER;
123         __parser_y_private.line[p] = 1;
124         __parser_y_private.filename[p] = strdup(files.gl_pathv[i]);
125
126         yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE));
127     }
128     globfree(&files);
129     return 0;
130 }
131
132 %}
133
134 %%
135
136 <<EOF>> {
137         if (__parser_y_private.filename[__parser_y_private.stack_ptr]) {
138                 free(__parser_y_private.filename[__parser_y_private.stack_ptr]);
139                 __parser_y_private.filename[__parser_y_private.stack_ptr] = NULL;
140         }
141         if (__parser_y_private.file[__parser_y_private.stack_ptr]) {
142                 fclose(__parser_y_private.file[__parser_y_private.stack_ptr]);
143                 __parser_y_private.file[__parser_y_private.stack_ptr] = NULL;
144                 yy_delete_buffer (YY_CURRENT_BUFFER);
145                 yy_switch_to_buffer
146                         (__parser_y_private.stack[__parser_y_private.stack_ptr]);
147         }
148         if (--__parser_y_private.stack_ptr < 0) {
149                 yyterminate();
150         }
151 }
152
153 ^[\t ]+                 return FIRST_SPACES;
154
155 [\t ]+                  /* ignore spaces in line */ ;
156
157 =                               return EQUAL;
158
159 \n|#.*\n                {
160                                         __parser_y_private.line[__parser_y_private.stack_ptr]++;
161                                         return EOL;
162                                 }
163
164 config                  return CONFIG;
165 setup                   return SETUP;
166 conn                    return CONN;
167 ca                      return CA;
168 include                 return INCLUDE;
169 version                 return FILE_VERSION;
170
171 [^\"= \t\n]+    {
172                                         yylval.s = strdup(yytext);
173                                         return STRING;
174                                 }
175
176 \"[^\"\n]*\"    {
177                                         yylval.s = strdup(yytext+1);
178                                         if (yylval.s) yylval.s[strlen(yylval.s)-1]='\0';
179                                         return STRING;
180                                 }
181
182 .                               yyerror(yytext);
183
184 %%
185
186 int yywrap(void)
187 {
188     return 1;
189 }
190