Rebuild library.lo after changing ./configure options
[strongswan.git] / src / starter / parser.l
1 %option noinput
2 %option nounput
3 %{
4 /* FreeS/WAN config file parser (parser.l)
5  * Copyright (C) 2001 Mathieu Lafon - Arkoon Network Security
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the
9  * Free Software Foundation; either version 2 of the License, or (at your
10  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15  * for more details.
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 extern void yyerror(const char *);
27 extern int yylex(void);
28 extern int yylex_destroy(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         yylex_destroy();
73 }
74
75 int _parser_y_include (const char *filename)
76 {
77         glob_t files;
78         int i, ret;
79
80         ret = glob(filename, GLOB_ERR, NULL, &files);
81         if (ret)
82         {
83                 const char *err;
84
85                 switch (ret)
86                 {
87                 case GLOB_NOSPACE:
88                         err = "include files ran out of memory";
89                         break;
90                 case GLOB_ABORTED:
91                         err = "include files aborted due to read error";
92                         break;
93                 case GLOB_NOMATCH:
94                         err = "include files found no matches";
95                         break;
96                 default:
97                         err = "unknown include files error";
98                 }
99                 yyerror(err);
100                 return 1;
101         }
102
103         for (i = 0; i < files.gl_pathc; i++)
104         {
105                 FILE *f;
106                 unsigned int p = __parser_y_private.stack_ptr + 1;
107
108                 if (p >= MAX_INCLUDE_DEPTH)
109                 {
110                         yyerror("max inclusion depth reached");
111                         return 1;
112                 }
113
114                 f = fopen(files.gl_pathv[i], "r");
115                 if (!f)
116                 {
117                         yyerror("can't open include filename");
118                         continue;
119                 }
120
121                 __parser_y_private.stack_ptr++;
122                 __parser_y_private.file[p] = f;
123                 __parser_y_private.stack[p] = YY_CURRENT_BUFFER;
124                 __parser_y_private.line[p] = 1;
125                 __parser_y_private.filename[p] = strdup(files.gl_pathv[i]);
126
127                 yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE));
128         }
129         globfree(&files);
130         return 0;
131 }
132
133 %}
134
135 %%
136
137 <<EOF>> {
138                 if (__parser_y_private.filename[__parser_y_private.stack_ptr]) {
139                                 free(__parser_y_private.filename[__parser_y_private.stack_ptr]);
140                                 __parser_y_private.filename[__parser_y_private.stack_ptr] = NULL;
141                 }
142                 if (__parser_y_private.file[__parser_y_private.stack_ptr]) {
143                                 fclose(__parser_y_private.file[__parser_y_private.stack_ptr]);
144                                 __parser_y_private.file[__parser_y_private.stack_ptr] = NULL;
145                                 yy_delete_buffer (YY_CURRENT_BUFFER);
146                                 yy_switch_to_buffer
147                                                 (__parser_y_private.stack[__parser_y_private.stack_ptr]);
148                 }
149                 if (--__parser_y_private.stack_ptr < 0) {
150                                 yyterminate();
151                 }
152 }
153
154 ^[\t ]+                 return FIRST_SPACES;
155
156 [\t ]+                  /* ignore spaces in line */ ;
157
158 =                               return EQUAL;
159
160 \n|#.*\n                {
161                                                                                 __parser_y_private.line[__parser_y_private.stack_ptr]++;
162                                                                                 return EOL;
163                                                                 }
164
165 config                  return CONFIG;
166 setup                   return SETUP;
167 conn                    return CONN;
168 ca                      return CA;
169 include                 return INCLUDE;
170 version                 return FILE_VERSION;
171
172 [^\"= \t\n]+    {
173                                                                                 yylval.s = strdup(yytext);
174                                                                                 return STRING;
175                                                                 }
176
177 \"[^\"\n]*\"    {
178                                                                                 yylval.s = strdup(yytext+1);
179                                                                                 if (yylval.s) yylval.s[strlen(yylval.s)-1]='\0';
180                                                                                 return STRING;
181                                                                 }
182
183 .                               yyerror(yytext);
184
185 %%
186
187 int yywrap(void)
188 {
189         return 1;
190 }
191