whitespace-only change:
[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];
33 static int pbcpos = 0;
34
35 static int parencount = 0;
36 static int commaout = 0;
37 int my_lineno = 1;
38 int my_col = 0;
39 char *my_file = 0;
40 char *prev_word;
41 #define MAX_INCLUDE_DEPTH 50
42
43 void reset_parencount(yyscan_t yyscanner );
44 void reset_semicount(yyscan_t yyscanner );
45 void reset_argcount(yyscan_t yyscanner );
46 struct pval *ael2_parse(char *filename, int *errors);
47 int ael_yyget_column  (yyscan_t yyscanner);
48 void ael_yyset_column (int  column_no , yyscan_t yyscanner);
49 int ael_yyparse (struct parse_io *);
50 static void pbcpush(char x);
51 static int pbcpop(char x);
52 static void pbcwhere(char *text, int *line, int *col );
53 static int c_prevword(void);
54
55 struct stackelement {
56         char *fname;
57         int lineno;
58         int colno;
59         YY_BUFFER_STATE bufstate;
60 };
61 struct stackelement  include_stack[MAX_INCLUDE_DEPTH];
62 int include_stack_index = 0;
63
64 %}
65
66 %x paren semic argg
67 %option prefix="ael_yy"
68 %option batch
69 %option outfile="ael_lex.c"
70 %option reentrant
71 %option bison-bridge
72 %option bison-locations
73 /* %option yylineno I've tried hard, but haven't been able to use this */
74 %option noyywrap
75
76 %%
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 LC;}
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 RC;}
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 LP;}
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 RP;}
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 SEMI;}
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 EQ;}
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 COMMA;}
84 \:      {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;}
85 \&      {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;}
86 \|      {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;}
87 \=\>    {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;}
88 \@      {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;}
89 \/\/[^\n]*  {/*comment*/}
90 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;}
91 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;}
92 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;};
93 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;}
94 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;}
95 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;}
96 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;}
97 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;}
98 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;}
99 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;}
100 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;}
101 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;}
102 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;}
103 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;}
104 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;}
105 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;}
106 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;}
107 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;}
108 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;}
109 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;}
110 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;}
111 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;}
112 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;}
113 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;}
114 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;}
115 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;}
116
117 \n              {my_lineno++;my_col=0;}
118 [ ]+    {/* nothing */ my_col+=yyleng;}
119 [       ]+      {/* nothing */ int wid = 8-(my_col%8); my_col+=wid;}
120
121 [-a-zA-Z0-9'"_/.\<\>\*\+!$#\[\]][-a-zA-Z0-9'"_/.!\*\+\<\>\{\}$#\[\]]*   {
122                 yylloc->first_line = yylloc->last_line = my_lineno;
123                 yylloc->last_column=my_col+yyleng-1;
124                 yylloc->first_column=my_col; /* set up the ptr */
125                 my_col+=yyleng;
126                 yylval->str = strdup(yytext);
127                 /* printf("\nGot WORD %s[%d][%d:%d]\n", yylval->str, my_lineno ,yylloc->first_column,yylloc->last_column );  */
128                 prev_word = yylval->str;
129                 return word;
130         }
131
132 <paren>[^()\[\]\{\}]*\) {
133                 yylloc->first_line = my_lineno;
134                 yylloc->first_column=my_col;
135                 if ( pbcpop(')') ) {
136                         /* error */
137                         int l4,c4;
138                         pbcwhere(yytext, &l4, &c4);
139                         ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched ')' in expression: %s !\n", my_file, my_lineno+l4, c4, yytext);
140                         BEGIN(0);
141                         yylloc->last_line = my_lineno+l4;
142                         yylloc->last_column=c4;
143                         my_col=c4;
144                         my_lineno += l4;
145                         yylval->str = strdup(yytext);
146                         prev_word = 0;
147                         return word;
148                 }
149                 parencount--;
150                 if ( parencount >= 0) {
151                         yymore();
152                 } else {
153                         int l4,c4;
154                         pbcwhere(yytext, &l4, &c4);
155                         yylloc->last_line = my_lineno+l4;
156                         yylloc->last_column=c4;
157                         yylval->str = strdup(yytext);
158                         *(yylval->str+strlen(yylval->str)-1)=0;
159                         /* printf("Got paren word %s\n", yylval->str); */
160                         unput(')');
161                         my_col=c4;
162                         my_lineno += l4;
163                         BEGIN(0);
164                         return word;
165                 }
166         }
167
168 <paren>[^()\[\]\{\}]*\( {
169                 yylloc->first_line = my_lineno; yylloc->first_column=my_col;
170                 parencount++;
171                 pbcpush('(');
172                 yymore();
173         }
174
175 <paren>[^()\[\]\{\}]*\[ {yylloc->first_line = my_lineno;yylloc->first_column=my_col; yymore(); pbcpush('['); }
176
177 <paren>[^()\[\]\{\}]*\] {
178                 yylloc->first_line = my_lineno;yylloc->first_column=my_col;
179                 if ( pbcpop(']') ) {
180                         /* error */
181                         int l4,c4;
182                         pbcwhere(yytext, &l4, &c4);
183                         ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched ']' in expression!\n", my_file, my_lineno+l4, c4);
184                         BEGIN(0);
185                         yylloc->last_line = my_lineno+l4;
186                         yylloc->last_column=c4;
187                         my_col=c4;
188                         my_lineno += l4;
189                         yylval->str = strdup(yytext);
190                         return word;
191                 }
192                 yymore();
193         }
194
195 <paren>[^()\[\]\{\}]*\{ {yylloc->first_line = my_lineno;yylloc->first_column=my_col;  yymore(); pbcpush('{'); }
196
197 <paren>[^()\[\]\{\}]*\} {
198                 yylloc->first_line = my_lineno;
199                 yylloc->first_column=my_col;
200                 if ( pbcpop('}') ) {
201                         /* error */
202                         int l4,c4;
203                         pbcwhere(yytext, &l4, &c4);
204                         ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched '}' in expression!\n", my_file, my_lineno+l4, c4);
205                         BEGIN(0);
206                         yylloc->last_line = my_lineno+l4;
207                         yylloc->last_column=c4;
208                         my_col=c4;
209                         my_lineno += l4;
210                         yylval->str = strdup(yytext);
211                         return word;
212                 }
213                 yymore();
214         }
215
216 <argg>[^(),\{\}\[\]]*\) {
217                 /* printf("ARGG:%s\n",yytext); */
218                 int linecount = 0;
219                 int colcount = my_col;
220                 char *pt = yytext;
221
222                 yylloc->first_line = my_lineno;
223                 yylloc->first_column=my_col;
224                 if ( pbcpop(')') ) {
225                         /* error */
226                         int l4,c4;
227                         pbcwhere(yytext, &l4, &c4);
228                         ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched ')' in expression!\n", my_file, my_lineno+l4, c4);
229                         BEGIN(0);
230                         yylloc->last_line = my_lineno+l4;
231                         yylloc->last_column=c4;
232                         my_col=c4;
233                         my_lineno += l4;
234                         yylval->str = strdup(yytext);
235                         return word;
236                 }
237
238
239                 while (*pt) {
240                         if (*pt == '\n') {
241                                 linecount++;
242                                 colcount=0;
243                         }
244                         pt++;
245                         colcount++;
246                 }
247                 yylloc->last_line = my_lineno+linecount;
248                 yylloc->last_column=colcount;
249                 parencount--;
250                 if( parencount >= 0){
251                         yymore();
252                 } else {
253                         yylval->str = strdup(yytext);
254                         if(yyleng > 1 )
255                                 *(yylval->str+yyleng-1)=0;
256                         /* printf("Got argg word '%s'\n", yylval->str);  */
257                         BEGIN(0);
258                         if ( !strcmp(yylval->str,")") ) {
259                                 free(yylval->str);
260                                 yylval->str = 0;
261                                 my_col+=1;
262                                 return RP;
263                         } else {
264                                 unput(')');
265                                 my_col=colcount;
266                                 my_lineno+=linecount;
267                                 return word;
268                         }
269                 }
270         }
271
272 <argg>[^(),\{\}\[\]]*\(   {
273                 /* printf("ARGG:%s\n",yytext); */
274                 /* printf("GOT AN LP!!!\n"); */
275                 yylloc->first_line = my_lineno;
276                 yylloc->first_column=my_col;
277                 parencount++;
278                 pbcpush('(');
279                 yymore();
280         }
281
282 <argg>[^(),\{\}\[\]]*\, {
283                 /* printf("ARGG:%s\n",yytext); */
284                 if( parencount != 0) {
285                         /* printf("Folding in a comma!\n"); */
286                         yymore();
287                 } else  {
288                         /* printf("got a comma!\n\n");  */
289                         int linecount = 0;
290                         int colcount = my_col;
291                         char *pt;
292
293                         pt = yytext;
294                         while (*pt) {
295                                 if ( *pt == '\n' ) {
296                                         linecount++;
297                                         colcount=0;
298                                 }
299                                 pt++;
300                                 colcount++;
301                         }
302                         yylloc->first_line = my_lineno;
303                         yylloc->last_line = my_lineno+linecount;
304                         yylloc->last_column=colcount;
305                         yylloc->first_column=my_col;
306                         if( !commaout ) {
307                                 if( !strcmp(yytext,"," ) ) {
308                                         commaout = 0;
309                                         my_col+=1;
310                                         return COMMA;
311                                 }
312                                 yylval->str = strdup(yytext); /* printf("Got argg2 word %s\n", yylval->str); */
313                                 unput(',');
314                                 commaout = 1;
315                                 if(yyleng > 1 )
316                                 *(yylval->str+yyleng-1)=0;
317                                 my_lineno+=linecount;
318                                 my_col=colcount;
319                                 return word;
320                         } else {
321                                 commaout = 0;
322                                 my_col+=1;
323                                 return COMMA;
324                         }
325                 }
326         }
327
328 <argg>[^(),\{\}\[\]]*\{ {
329                 /*printf("ARGG:%s\n",yytext);*/
330                 yylloc->first_line = my_lineno;
331                 yylloc->first_column=my_col;
332                 pbcpush('{'); yymore();
333         }
334
335 <argg>[^(),\{\}\[\]]*\} {
336                 /*printf("ARGG:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col;
337                 if ( pbcpop('}') ) {
338                         /* error */
339                         int l4,c4;
340                         pbcwhere(yytext, &l4, &c4);
341                         ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched '}' in expression!\n", my_file, my_lineno+l4, my_col+c4);
342                         BEGIN(0);
343                         yylloc->last_line = my_lineno+l4;
344                         yylloc->last_column=my_col+c4;
345                         my_col=c4;
346                         my_lineno += l4;
347                         yylval->str = strdup(yytext);
348                         return word;
349                 }
350                 yymore();
351         }
352
353 <argg>[^(),\{\}\[\]]*\[ {/*printf("ARGG:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col; yymore(); pbcpush('['); }
354
355 <argg>[^(),\{\}\[\]]*\] {/*printf("ARGG:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col;
356                 if ( pbcpop(']') ) {
357                         /* error */
358                         int l4,c4;
359                         pbcwhere(yytext, &l4, &c4);
360                         ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched ']' in expression!\n", my_file, my_lineno+l4, c4);
361                         BEGIN(0);
362                         yylloc->last_line = my_lineno+l4;
363                         yylloc->last_column=c4;
364                         my_col=c4;
365                         my_lineno += l4;
366                         yylval->str = strdup(yytext);
367                         return word;
368                 }
369                 yymore();
370         }
371
372 <semic>[^;()\{\}\[\]]*\[        {/*printf("SEMIC:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col; yymore(); pbcpush('['); }
373
374 <semic>[^;()\{\}\[\]]*\]        {/*printf("SEMIC:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col;
375                 if ( pbcpop(']') ) {
376                         /* error */
377                         int l4,c4;
378                         pbcwhere(yytext, &l4, &c4);
379                         ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched ']' in expression!\n", my_file, my_lineno+l4, c4);
380                         BEGIN(0);
381                         yylloc->last_line = my_lineno+l4;
382                         yylloc->last_column=c4;
383                         my_col=c4;
384                         my_lineno += l4;
385                         yylval->str = strdup(yytext);
386                         return word;
387                 }
388                 yymore();
389         }
390
391 <semic>[^;()\{\}\[\]]*\{        {/*printf("SEMIC:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col; yymore(); pbcpush('{');}
392
393 <semic>[^;()\{\}\[\]]*\}        {/*printf("SEMIC:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col;
394                 if ( pbcpop('}') ) {
395                         /* error */
396                         int l4,c4;
397                         pbcwhere(yytext, &l4, &c4);
398                         ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched '}' in expression!\n", my_file, my_lineno+l4, my_col+c4);
399                         BEGIN(0);
400                         yylloc->last_line = my_lineno+l4;
401                         yylloc->last_column=my_col+c4;
402                         my_col=c4;
403                         my_lineno += l4;
404                         yylval->str = strdup(yytext);
405                         return word;
406                 }
407                 yymore();
408         }
409
410 <semic>[^;()\{\}\[\]]*\(        {/*printf("SEMIC:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col; yymore(); pbcpush('(');}
411
412 <semic>[^;()\{\}\[\]]*\)        {/*printf("SEMIC:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col;
413                 if ( pbcpop(')') ) {
414                         /* error */
415                         int l4,c4;
416                         pbcwhere(yytext, &l4, &c4);
417                         ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched ')' in expression!\n", my_file, my_lineno+l4, my_col+c4);
418                         BEGIN(0);
419                         yylloc->last_line = my_lineno+l4;
420                         yylloc->last_column=my_col+c4;
421                         my_col=c4;
422                         my_lineno += l4;
423                         yylval->str = strdup(yytext);
424                         return word;
425                 }
426                 yymore();
427         }
428
429 <semic>[^;()\{\}\[\]]*; {
430                 int linecount = 0;
431                 int colcount = my_col;
432                 char *pt = yytext;
433                 while (*pt) {
434                         if ( *pt == '\n' ) {
435                                 linecount++;
436                                 colcount=0;
437                         }
438                         pt++;
439                         colcount++;
440                 }
441                 yylloc->first_line = my_lineno;
442                 yylloc->last_line = my_lineno+linecount;
443                 yylloc->last_column=colcount;
444                 yylloc->first_column=my_col;
445                 yylval->str = strdup(yytext);
446                 if(yyleng > 1)
447                         *(yylval->str+yyleng-1)=0;
448                 /* printf("Got semic word %s\n", yylval->str); */
449                 unput(';');
450                 BEGIN(0);
451                 my_col=colcount;
452                 my_lineno += linecount;
453                 return word;
454         }
455
456 \#include[ \t]+\"[^\"]+\" {
457                 FILE *in1;
458                 char fnamebuf[1024],*p1,*p2;
459                 if ( include_stack_index >= MAX_INCLUDE_DEPTH ) {
460                         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);
461                 } else {
462                         p1 = strchr(yytext,'"');
463                         p2 = strrchr(yytext,'"');
464                         if ( (int)(p2-p1) > 1023 ) {
465                                 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);
466                         } else {
467                                 int i;
468                                 int found = 0;
469                                 strncpy(fnamebuf,p1,p2-p1);
470                                 fnamebuf[p2-p1] = 0;
471                                 for (i=0; i<include_stack_index; i++) {
472                                         if ( !strcmp(fnamebuf,include_stack[i].fname )) {
473                                                 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",
474                                                         my_file, my_lineno, my_col, fnamebuf);
475                                                 found=1;
476                                                 break;
477                                         }
478                                 }
479                                 if ( !found ) {
480                                         *p2 = 0;
481                                         /* relative vs. absolute */
482                                         if ( *(p1+1) != '/' ) {
483                                                 strcpy(fnamebuf,ast_config_AST_CONFIG_DIR);
484                                                 strcat(fnamebuf,"/");
485                                                 strcat(fnamebuf,p1+1);
486                                         } else
487                                                 strcpy(fnamebuf,p1+1);
488                                         in1 = fopen( fnamebuf, "r" );
489                                         if ( ! in1 ) {
490                                                 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);
491                                         } else {
492                                                 char *buffer;
493                                                 struct stat stats;
494                                                 stat(fnamebuf, &stats);
495                                                 buffer = (char*)malloc(stats.st_size+1);
496                                                 fread(buffer, 1, stats.st_size, in1);
497                                                 buffer[stats.st_size] = 0;
498                                                 ast_log(LOG_NOTICE,"  --Read in included file %s, %d chars\n",fnamebuf, (int)stats.st_size);
499                                                 fclose(in1);
500
501                                                 include_stack[include_stack_index].fname = my_file;
502                                                 my_file = strdup(fnamebuf);
503                                                 include_stack[include_stack_index].lineno = my_lineno;
504                                                 include_stack[include_stack_index].colno = my_col+yyleng;
505                                                 include_stack[include_stack_index++].bufstate = YY_CURRENT_BUFFER;
506
507                                                 yy_switch_to_buffer(ael_yy_scan_string (buffer ,yyscanner),yyscanner);
508                                                 free(buffer);
509                                                 my_lineno = 1;
510                                                 my_col = 1;
511                                                 BEGIN(INITIAL);
512                                         }
513                                 }
514                         }
515                 }
516         }
517
518 <<EOF>>         {
519                 if ( --include_stack_index < 0 ) {
520                         yyterminate();
521                 } else {
522                         free(my_file);
523                         yy_delete_buffer( YY_CURRENT_BUFFER, yyscanner );
524                         yy_switch_to_buffer(include_stack[include_stack_index].bufstate, yyscanner );
525                         my_lineno = include_stack[include_stack_index].lineno;
526                         my_col    = include_stack[include_stack_index].colno;
527                         my_file   = include_stack[include_stack_index].fname;
528                 }
529         }
530
531 %%
532
533 static void pbcpush(char x)
534 {
535         pbcstack[pbcpos++] = x;
536 }
537
538 static int pbcpop(char x)
539 {
540         if (   ( x == ')' && pbcstack[pbcpos-1] == '(' )
541                 || ( x == ']' && pbcstack[pbcpos-1] == '[' )
542                 || ( x == '}' && pbcstack[pbcpos-1] == '{' )) {
543                 pbcpos--;
544                 return 0;
545         }
546         return 1; /* error */
547 }
548
549 static int c_prevword(void)
550 {
551         char *c = prev_word;
552         int ret = 0;
553         while ( c && *c ) {
554                 switch (*c) {
555                 case '{': pbcpush('{');break;
556                 case '}': ret = pbcpop('}');break;
557                 case '[':pbcpush('[');break;
558                 case ']':ret = pbcpop(']');break;
559                 case '(':pbcpush('(');break;
560                 case ')':ret = pbcpop(')'); break;
561                 }
562                 if( ret )
563                         return 1;
564                 c++;
565         }
566         return 0;
567 }
568
569 static void pbcwhere(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 void reset_parencount(yyscan_t yyscanner )
587 {
588         struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
589         parencount = 0;
590         pbcpos = 0;
591         pbcpush('(');
592         c_prevword();
593         BEGIN(paren);
594 }
595
596 void reset_semicount(yyscan_t yyscanner )
597 {
598         struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
599         pbcpos = 0;
600         BEGIN(semic);
601 }
602
603 void reset_argcount(yyscan_t yyscanner )
604 {
605         struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
606         parencount = 0;
607         pbcpos = 0;
608         commaout = 0;
609         pbcpush('(');
610         c_prevword();
611         BEGIN(argg);
612 }
613
614
615 struct pval *ael2_parse(char *filename, int *errors)
616 {
617         struct pval *pval;
618         struct parse_io *io;
619         char *buffer;
620         struct stat stats;
621         FILE *fin;
622
623         /* extern int ael_yydebug; */
624
625         io = calloc(sizeof(struct parse_io),1);
626         /* reset the global counters */
627         prev_word = 0;
628         my_lineno = 1;
629         include_stack_index=0;
630         my_col = 0;
631         /* ael_yydebug = 1; */
632         ael_yylex_init(&io->scanner);
633         fin = fopen(filename,"r");
634         if ( !fin ) {
635                 ast_log(LOG_ERROR,"File %s could not be opened\n", filename);
636                 *errors = 1;
637                 return 0;
638         }
639         my_file = strdup(filename);
640         stat(filename, &stats);
641         buffer = (char*)malloc(stats.st_size+2);
642         fread(buffer, 1, stats.st_size, fin);
643         buffer[stats.st_size]=0;
644         fclose(fin);
645
646         ael_yy_scan_string (buffer ,io->scanner);
647         ael_yyset_lineno(1 , io->scanner);
648
649         /* ael_yyset_in (fin , io->scanner);    OLD WAY */
650
651         ael_yyparse(io);
652
653
654         pval = io->pval;
655         *errors = io->syntax_error_count;
656
657         ael_yylex_destroy(io->scanner);
658         free(buffer);
659         free(io);
660
661         return pval;
662 }