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