9466c6c45a5306c93e3c3ce54a47673dffef9cf7
[asterisk/asterisk.git] / pbx / ael / ael.flex
1 %{
2 /*
3  * Asterisk -- An open source telephony toolkit.
4  *
5  * Copyright (C) 2006, Digium, Inc.
6  *
7  * Steve Murphy <murf@parsetree.com>
8  *
9  * See http://www.asterisk.org for more information about
10  * the Asterisk project. Please do not directly contact
11  * any of the maintainers of this project for assistance;
12  * the project provides a web site, mailing lists and IRC
13  * channels for your use.
14  *
15  * This program is free software, distributed under the terms of
16  * the GNU General Public License Version 2. See the LICENSE file
17  * at the top of the source tree.
18  */
19 /*! \file
20  *
21  * \brief Flex scanner description of tokens used in AEL2 .
22  *
23  */#include <sys/types.h>
24 #include <sys/stat.h>
25 #include <unistd.h>
26
27 #include "asterisk.h"
28 #include "asterisk/logger.h"
29 #include "ael/ael.tab.h"
30 #include "asterisk/ael_structs.h"
31
32 static char pbcstack[400];      /* XXX missing size checks */
33 static int pbcpos = 0;
34
35 static int parencount = 0;
36 static int commaout = 0;
37 static int my_lineno = 1;
38 static int my_col = 0;
39 static char *my_file = 0;
40 char *prev_word;
41 #define MAX_INCLUDE_DEPTH 50
42
43 int ael_yyget_column  (yyscan_t yyscanner);
44 void ael_yyset_column (int  column_no , yyscan_t yyscanner);
45 int ael_yyparse (struct parse_io *);
46 static void pbcpush(char x);
47 static int pbcpop(char x);
48 static void pbcwhere(const char *text, int *line, int *col );
49
50 struct stackelement {
51         char *fname;
52         int lineno;
53         int colno;
54         YY_BUFFER_STATE bufstate;
55 };
56 static struct stackelement  include_stack[MAX_INCLUDE_DEPTH];
57 static int include_stack_index = 0;
58
59 %}
60
61 %x paren semic argg
62 %option prefix="ael_yy"
63 %option batch
64 %option outfile="ael_lex.c"
65 %option reentrant
66 %option bison-bridge
67 %option bison-locations
68 /* %option yylineno I've tried hard, but haven't been able to use this */
69 %option noyywrap
70
71 %%
72 \{      {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return LC;}
73 \}      {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return RC;}
74 \(      {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return LP;}
75 \)      {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return RP;}
76 \;      {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return SEMI;}
77 \=      {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return EQ;}
78 \,      {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return COMMA;}
79 \:      {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return COLON;}
80 \&      {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return AMPER;}
81 \|      {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return BAR;}
82 \=\>    {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return EXTENMARK;}
83 \@      {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return AT;}
84 \/\/[^\n]*  {/*comment*/}
85 context {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_CONTEXT;}
86 abstract        {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_ABSTRACT;}
87 macro   {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_MACRO;};
88 globals {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_GLOBALS;}
89 ignorepat       {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_IGNOREPAT;}
90 switch  {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_SWITCH;}
91 if      {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_IF;}
92 ifTime  {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_IFTIME;}
93 random  {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_RANDOM;}
94 regexten        {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_REGEXTEN;}
95 hint    {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_HINT;}
96 else    {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_ELSE;}
97 goto    {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_GOTO;}
98 jump    {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_JUMP;}
99 return  {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_RETURN;}
100 break   {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_BREAK;}
101 continue        {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_CONTINUE;}
102 for     {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_FOR;}
103 while   {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_WHILE;}
104 case    {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_CASE;}
105 default {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_DEFAULT;}
106 pattern {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_PATTERN;}
107 catch   {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_CATCH;}
108 switches        {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_SWITCHES;}
109 eswitches       {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_ESWITCHES;}
110 includes        {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_INCLUDES;}
111
112 \n              {my_lineno++;my_col=0;}
113 [ ]+    {/* nothing */ my_col+=yyleng;}
114 [       ]+      {/* nothing */ int wid = 8-(my_col%8); my_col+=wid;}
115
116 [-a-zA-Z0-9'"_/.\<\>\*\+!$#\[\]][-a-zA-Z0-9'"_/.!\*\+\<\>\{\}$#\[\]]*   {
117                 yylloc->first_line = yylloc->last_line = my_lineno;
118                 yylloc->last_column=my_col+yyleng-1;
119                 yylloc->first_column=my_col; /* set up the ptr */
120                 my_col+=yyleng;
121                 yylval->str = strdup(yytext);
122                 /* printf("\nGot WORD %s[%d][%d:%d]\n", yylval->str, my_lineno ,yylloc->first_column,yylloc->last_column );  */
123                 prev_word = yylval->str;
124                 return word;
125         }
126
127 <paren>[^()\[\]\{\}]*\) {
128                 yylloc->first_line = my_lineno;
129                 yylloc->first_column=my_col;
130                 if ( pbcpop(')') ) {
131                         /* error */
132                         int l4,c4;
133                         pbcwhere(yytext, &l4, &c4);
134                         ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched ')' in expression: %s !\n", my_file, my_lineno+l4, c4, yytext);
135                         BEGIN(0);
136                         yylloc->last_line = my_lineno+l4;
137                         yylloc->last_column=c4;
138                         my_col=c4;
139                         my_lineno += l4;
140                         yylval->str = strdup(yytext);
141                         prev_word = 0;
142                         return word;
143                 }
144                 parencount--;
145                 if ( parencount >= 0) {
146                         yymore();
147                 } else {
148                         int l4,c4;
149                         pbcwhere(yytext, &l4, &c4);
150                         yylloc->last_line = my_lineno+l4;
151                         yylloc->last_column=c4;
152                         yylval->str = strdup(yytext);
153                         *(yylval->str+strlen(yylval->str)-1)=0;
154                         /* printf("Got paren word %s\n", yylval->str); */
155                         unput(')');
156                         my_col=c4;
157                         my_lineno += l4;
158                         BEGIN(0);
159                         return word;
160                 }
161         }
162
163 <paren>[^()\[\]\{\}]*\( {
164                 yylloc->first_line = my_lineno; yylloc->first_column=my_col;
165                 parencount++;
166                 pbcpush('(');
167                 yymore();
168         }
169
170 <paren>[^()\[\]\{\}]*\[ {yylloc->first_line = my_lineno;yylloc->first_column=my_col; yymore(); pbcpush('['); }
171
172 <paren>[^()\[\]\{\}]*\] {
173                 yylloc->first_line = my_lineno;yylloc->first_column=my_col;
174                 if ( pbcpop(']') ) {
175                         /* error */
176                         int l4,c4;
177                         pbcwhere(yytext, &l4, &c4);
178                         ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched ']' in expression!\n", my_file, my_lineno+l4, c4);
179                         BEGIN(0);
180                         yylloc->last_line = my_lineno+l4;
181                         yylloc->last_column=c4;
182                         my_col=c4;
183                         my_lineno += l4;
184                         yylval->str = strdup(yytext);
185                         return word;
186                 }
187                 yymore();
188         }
189
190 <paren>[^()\[\]\{\}]*\{ {yylloc->first_line = my_lineno;yylloc->first_column=my_col;  yymore(); pbcpush('{'); }
191
192 <paren>[^()\[\]\{\}]*\} {
193                 yylloc->first_line = my_lineno;
194                 yylloc->first_column=my_col;
195                 if ( pbcpop('}') ) {
196                         /* error */
197                         int l4,c4;
198                         pbcwhere(yytext, &l4, &c4);
199                         ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched '}' in expression!\n", my_file, my_lineno+l4, c4);
200                         BEGIN(0);
201                         yylloc->last_line = my_lineno+l4;
202                         yylloc->last_column=c4;
203                         my_col=c4;
204                         my_lineno += l4;
205                         yylval->str = strdup(yytext);
206                         return word;
207                 }
208                 yymore();
209         }
210
211 <argg>[^(),\{\}\[\]]*\) {
212                 /* printf("ARGG:%s\n",yytext); */
213                 int linecount = 0;
214                 int colcount = my_col;
215                 char *pt = yytext;
216
217                 yylloc->first_line = my_lineno;
218                 yylloc->first_column=my_col;
219                 if ( pbcpop(')') ) {
220                         /* error */
221                         int l4,c4;
222                         pbcwhere(yytext, &l4, &c4);
223                         ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched ')' in expression!\n", my_file, my_lineno+l4, c4);
224                         BEGIN(0);
225                         yylloc->last_line = my_lineno+l4;
226                         yylloc->last_column=c4;
227                         my_col=c4;
228                         my_lineno += l4;
229                         yylval->str = strdup(yytext);
230                         return word;
231                 }
232
233
234                 while (*pt) {
235                         if (*pt == '\n') {
236                                 linecount++;
237                                 colcount=0;
238                         }
239                         pt++;
240                         colcount++;
241                 }
242                 yylloc->last_line = my_lineno+linecount;
243                 yylloc->last_column=colcount;
244                 parencount--;
245                 if( parencount >= 0){
246                         yymore();
247                 } else {
248                         yylval->str = strdup(yytext);
249                         if(yyleng > 1 )
250                                 *(yylval->str+yyleng-1)=0;
251                         /* printf("Got argg word '%s'\n", yylval->str);  */
252                         BEGIN(0);
253                         if ( !strcmp(yylval->str,")") ) {
254                                 free(yylval->str);
255                                 yylval->str = 0;
256                                 my_col+=1;
257                                 return RP;
258                         } else {
259                                 unput(')');
260                                 my_col=colcount;
261                                 my_lineno+=linecount;
262                                 return word;
263                         }
264                 }
265         }
266
267 <argg>[^(),\{\}\[\]]*\(   {
268                 /* printf("ARGG:%s\n",yytext); */
269                 /* printf("GOT AN LP!!!\n"); */
270                 yylloc->first_line = my_lineno;
271                 yylloc->first_column=my_col;
272                 parencount++;
273                 pbcpush('(');
274                 yymore();
275         }
276
277 <argg>[^(),\{\}\[\]]*\, {
278                 /* printf("ARGG:%s\n",yytext); */
279                 if( parencount != 0) {
280                         /* printf("Folding in a comma!\n"); */
281                         yymore();
282                 } else  {
283                         /* printf("got a comma!\n\n");  */
284                         int linecount = 0;
285                         int colcount = my_col;
286                         char *pt;
287
288                         pt = yytext;
289                         while (*pt) {
290                                 if ( *pt == '\n' ) {
291                                         linecount++;
292                                         colcount=0;
293                                 }
294                                 pt++;
295                                 colcount++;
296                         }
297                         yylloc->first_line = my_lineno;
298                         yylloc->last_line = my_lineno+linecount;
299                         yylloc->last_column=colcount;
300                         yylloc->first_column=my_col;
301                         if( !commaout ) {
302                                 if( !strcmp(yytext,"," ) ) {
303                                         commaout = 0;
304                                         my_col+=1;
305                                         return COMMA;
306                                 }
307                                 yylval->str = strdup(yytext); /* printf("Got argg2 word %s\n", yylval->str); */
308                                 unput(',');
309                                 commaout = 1;
310                                 if(yyleng > 1 )
311                                 *(yylval->str+yyleng-1)=0;
312                                 my_lineno+=linecount;
313                                 my_col=colcount;
314                                 return word;
315                         } else {
316                                 commaout = 0;
317                                 my_col+=1;
318                                 return COMMA;
319                         }
320                 }
321         }
322
323 <argg>[^(),\{\}\[\]]*\{ {
324                 /*printf("ARGG:%s\n",yytext);*/
325                 yylloc->first_line = my_lineno;
326                 yylloc->first_column=my_col;
327                 pbcpush('{'); yymore();
328         }
329
330 <argg>[^(),\{\}\[\]]*\} {
331                 /*printf("ARGG:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col;
332                 if ( pbcpop('}') ) {
333                         /* error */
334                         int l4,c4;
335                         pbcwhere(yytext, &l4, &c4);
336                         ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched '}' in expression!\n", my_file, my_lineno+l4, my_col+c4);
337                         BEGIN(0);
338                         yylloc->last_line = my_lineno+l4;
339                         yylloc->last_column=my_col+c4;
340                         my_col=c4;
341                         my_lineno += l4;
342                         yylval->str = strdup(yytext);
343                         return word;
344                 }
345                 yymore();
346         }
347
348 <argg>[^(),\{\}\[\]]*\[ {/*printf("ARGG:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col; yymore(); pbcpush('['); }
349
350 <argg>[^(),\{\}\[\]]*\] {/*printf("ARGG:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col;
351                 if ( pbcpop(']') ) {
352                         /* error */
353                         int l4,c4;
354                         pbcwhere(yytext, &l4, &c4);
355                         ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched ']' in expression!\n", my_file, my_lineno+l4, c4);
356                         BEGIN(0);
357                         yylloc->last_line = my_lineno+l4;
358                         yylloc->last_column=c4;
359                         my_col=c4;
360                         my_lineno += l4;
361                         yylval->str = strdup(yytext);
362                         return word;
363                 }
364                 yymore();
365         }
366
367 <semic>[^;()\{\}\[\]]*\[        {/*printf("SEMIC:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col; yymore(); pbcpush('['); }
368
369 <semic>[^;()\{\}\[\]]*\]        {/*printf("SEMIC:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col;
370                 if ( pbcpop(']') ) {
371                         /* error */
372                         int l4,c4;
373                         pbcwhere(yytext, &l4, &c4);
374                         ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched ']' in expression!\n", my_file, my_lineno+l4, c4);
375                         BEGIN(0);
376                         yylloc->last_line = my_lineno+l4;
377                         yylloc->last_column=c4;
378                         my_col=c4;
379                         my_lineno += l4;
380                         yylval->str = strdup(yytext);
381                         return word;
382                 }
383                 yymore();
384         }
385
386 <semic>[^;()\{\}\[\]]*\{        {/*printf("SEMIC:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col; yymore(); pbcpush('{');}
387
388 <semic>[^;()\{\}\[\]]*\}        {/*printf("SEMIC:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col;
389                 if ( pbcpop('}') ) {
390                         /* error */
391                         int l4,c4;
392                         pbcwhere(yytext, &l4, &c4);
393                         ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched '}' in expression!\n", my_file, my_lineno+l4, my_col+c4);
394                         BEGIN(0);
395                         yylloc->last_line = my_lineno+l4;
396                         yylloc->last_column=my_col+c4;
397                         my_col=c4;
398                         my_lineno += l4;
399                         yylval->str = strdup(yytext);
400                         return word;
401                 }
402                 yymore();
403         }
404
405 <semic>[^;()\{\}\[\]]*\(        {/*printf("SEMIC:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col; yymore(); pbcpush('(');}
406
407 <semic>[^;()\{\}\[\]]*\)        {/*printf("SEMIC:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col;
408                 if ( pbcpop(')') ) {
409                         /* error */
410                         int l4,c4;
411                         pbcwhere(yytext, &l4, &c4);
412                         ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched ')' in expression!\n", my_file, my_lineno+l4, my_col+c4);
413                         BEGIN(0);
414                         yylloc->last_line = my_lineno+l4;
415                         yylloc->last_column=my_col+c4;
416                         my_col=c4;
417                         my_lineno += l4;
418                         yylval->str = strdup(yytext);
419                         return word;
420                 }
421                 yymore();
422         }
423
424 <semic>[^;()\{\}\[\]]*; {
425                 int linecount = 0;
426                 int colcount = my_col;
427                 char *pt = yytext;
428                 while (*pt) {
429                         if ( *pt == '\n' ) {
430                                 linecount++;
431                                 colcount=0;
432                         }
433                         pt++;
434                         colcount++;
435                 }
436                 yylloc->first_line = my_lineno;
437                 yylloc->last_line = my_lineno+linecount;
438                 yylloc->last_column=colcount;
439                 yylloc->first_column=my_col;
440                 yylval->str = strdup(yytext);
441                 if(yyleng > 1)
442                         *(yylval->str+yyleng-1)=0;
443                 /* printf("Got semic word %s\n", yylval->str); */
444                 unput(';');
445                 BEGIN(0);
446                 my_col=colcount;
447                 my_lineno += linecount;
448                 return word;
449         }
450
451 \#include[ \t]+\"[^\"]+\" {
452                 FILE *in1;
453                 char fnamebuf[1024],*p1,*p2;
454                 if ( include_stack_index >= MAX_INCLUDE_DEPTH ) {
455                         ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Includes nested too deeply! Wow!!! How did you do that?\n", my_file, my_lineno, my_col);
456                 } else {
457                         p1 = strchr(yytext,'"');
458                         p2 = strrchr(yytext,'"');
459                         if ( (int)(p2-p1) > 1023 ) {
460                                 ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Filename is incredibly way too long (%d chars!). Inclusion ignored!\n", my_file, my_lineno, my_col, yyleng - 10);
461                         } else {
462                                 int i;
463                                 int found = 0;
464                                 strncpy(fnamebuf,p1,p2-p1);
465                                 fnamebuf[p2-p1] = 0;
466                                 for (i=0; i<include_stack_index; i++) {
467                                         if ( !strcmp(fnamebuf,include_stack[i].fname )) {
468                                                 ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Nice Try!!! But %s has already been included (perhaps by another file), and would cause an infinite loop of file inclusions!!! Include directive ignored\n",
469                                                         my_file, my_lineno, my_col, fnamebuf);
470                                                 found=1;
471                                                 break;
472                                         }
473                                 }
474                                 if ( !found ) {
475                                         *p2 = 0;
476                                         /* relative vs. absolute */
477                                         if ( *(p1+1) != '/' ) {
478                                                 strcpy(fnamebuf,ast_config_AST_CONFIG_DIR);
479                                                 strcat(fnamebuf,"/");
480                                                 strcat(fnamebuf,p1+1);
481                                         } else
482                                                 strcpy(fnamebuf,p1+1);
483                                         in1 = fopen( fnamebuf, "r" );
484                                         if ( ! in1 ) {
485                                                 ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Couldn't find the include file: %s; ignoring the Include directive!\n", my_file, my_lineno, my_col, fnamebuf);
486                                         } else {
487                                                 char *buffer;
488                                                 struct stat stats;
489                                                 stat(fnamebuf, &stats);
490                                                 buffer = (char*)malloc(stats.st_size+1);
491                                                 fread(buffer, 1, stats.st_size, in1);
492                                                 buffer[stats.st_size] = 0;
493                                                 ast_log(LOG_NOTICE,"  --Read in included file %s, %d chars\n",fnamebuf, (int)stats.st_size);
494                                                 fclose(in1);
495
496                                                 include_stack[include_stack_index].fname = my_file;
497                                                 my_file = strdup(fnamebuf);
498                                                 include_stack[include_stack_index].lineno = my_lineno;
499                                                 include_stack[include_stack_index].colno = my_col+yyleng;
500                                                 include_stack[include_stack_index++].bufstate = YY_CURRENT_BUFFER;
501
502                                                 yy_switch_to_buffer(ael_yy_scan_string (buffer ,yyscanner),yyscanner);
503                                                 free(buffer);
504                                                 my_lineno = 1;
505                                                 my_col = 1;
506                                                 BEGIN(INITIAL);
507                                         }
508                                 }
509                         }
510                 }
511         }
512
513 <<EOF>>         {
514                 if ( --include_stack_index < 0 ) {
515                         yyterminate();
516                 } else {
517                         free(my_file);
518                         yy_delete_buffer( YY_CURRENT_BUFFER, yyscanner );
519                         yy_switch_to_buffer(include_stack[include_stack_index].bufstate, yyscanner );
520                         my_lineno = include_stack[include_stack_index].lineno;
521                         my_col    = include_stack[include_stack_index].colno;
522                         my_file   = include_stack[include_stack_index].fname;
523                 }
524         }
525
526 %%
527
528 static void pbcpush(char x)
529 {
530         pbcstack[pbcpos++] = x;
531 }
532
533 static int pbcpop(char x)
534 {
535         if (   ( x == ')' && pbcstack[pbcpos-1] == '(' )
536                 || ( x == ']' && pbcstack[pbcpos-1] == '[' )
537                 || ( x == '}' && pbcstack[pbcpos-1] == '{' )) {
538                 pbcpos--;
539                 return 0;
540         }
541         return 1; /* error */
542 }
543
544 #if 0
545 static int c_prevword(void)
546 {
547         char *c = prev_word;
548         int ret = 0;
549         while ( c && *c ) {
550                 switch (*c) {
551                 case '{': pbcpush('{');break;
552                 case '}': ret = pbcpop('}');break;
553                 case '[':pbcpush('[');break;
554                 case ']':ret = pbcpop(']');break;
555                 case '(':pbcpush('(');break;
556                 case ')':ret = pbcpop(')'); break;
557                 }
558                 if( ret )
559                         return 1;
560                 c++;
561         }
562         return 0;
563 }
564 #endif
565
566 /* compute the total number of lines and columns in the text
567  * passed as argument.
568  */
569 static void pbcwhere(const char *text, int *line, int *col )
570 {
571         int loc_line = 0;
572         int loc_col = 0;
573         while ( *text ) {
574                 if ( *text == '\n' ) {
575                         loc_line++;
576                         loc_col = 1;
577                 } else {
578                         loc_col++;
579                 }
580                 text++;
581         }
582         *line = loc_line;
583         *col = loc_col;
584 }
585
586 #if 0
587 static void reset_parencount(yyscan_t yyscanner )
588 {
589         struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
590         parencount = 0;
591         pbcpos = 0;
592         pbcpush('(');
593         c_prevword();
594         BEGIN(paren);
595 }
596
597 static void reset_semicount(yyscan_t yyscanner )
598 {
599         struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
600         pbcpos = 0;
601         BEGIN(semic);
602 }
603
604 static void reset_argcount(yyscan_t yyscanner )
605 {
606         struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
607         parencount = 0;
608         pbcpos = 0;
609         commaout = 0;
610         pbcpush('(');
611         c_prevword();
612         BEGIN(argg);
613 }
614
615 #endif
616
617 /* used elsewhere, but some local vars */
618 struct pval *ael2_parse(char *filename, int *errors)
619 {
620         struct pval *pval;
621         struct parse_io *io;
622         char *buffer;
623         struct stat stats;
624         FILE *fin;
625
626         /* extern int ael_yydebug; */
627
628         io = calloc(sizeof(struct parse_io),1);
629         /* reset the global counters */
630         prev_word = 0;
631         my_lineno = 1;
632         include_stack_index=0;
633         my_col = 0;
634         /* ael_yydebug = 1; */
635         ael_yylex_init(&io->scanner);
636         fin = fopen(filename,"r");
637         if ( !fin ) {
638                 ast_log(LOG_ERROR,"File %s could not be opened\n", filename);
639                 *errors = 1;
640                 return 0;
641         }
642         my_file = strdup(filename);
643         stat(filename, &stats);
644         buffer = (char*)malloc(stats.st_size+2);
645         fread(buffer, 1, stats.st_size, fin);
646         buffer[stats.st_size]=0;
647         fclose(fin);
648
649         ael_yy_scan_string (buffer ,io->scanner);
650         ael_yyset_lineno(1 , io->scanner);
651
652         /* ael_yyset_in (fin , io->scanner);    OLD WAY */
653
654         ael_yyparse(io);
655
656
657         pval = io->pval;
658         *errors = io->syntax_error_count;
659
660         ael_yylex_destroy(io->scanner);
661         free(buffer);
662         free(io);
663
664         return pval;
665 }