moved extern declaration up to prevent compile-time errors.
[swftools.git] / src / parser.lex
index 57c7056..d5d81d6 100644 (file)
@@ -1,7 +1,9 @@
 %{
 
 #include <string.h>
-#include "q.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include "../lib/q.h"
 #include "parser.h"
 
 //RVALUE        {NUMBER}|{PERCENT}|{NAME}|\"{STRING}\"|{DIM}
@@ -116,6 +118,43 @@ static void store(enum type_t type, int line, int column, char*text, int length)
     prefix = 0;
 }
 
+#define MAX_INCLUDE_DEPTH 16
+YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
+int line_stack[MAX_INCLUDE_DEPTH];
+int column_stack[MAX_INCLUDE_DEPTH];
+int include_stack_ptr = 0;
+
+void handleInclude(char*text, int len)
+{
+    text+=9;len-=9;
+    while(len >=1 && (text[0] == ' ' || text[0] == '\t')) {
+       text++;len--;
+    }
+    while(len >= 1 && (text[len-1] == ' ' || text[len-1] == '\n')) {
+       len--;
+    }
+    if(len >= 2 && text[0] == '"' && text[len-1] == '"') {
+       text++; len-=2;
+    }
+    text[len] = 0;
+    if(include_stack_ptr >= MAX_INCLUDE_DEPTH) {
+       fprintf( stderr, "Includes nested too deeply" );
+       exit( 1 );
+    }
+    include_stack[include_stack_ptr] = YY_CURRENT_BUFFER;
+    line_stack[include_stack_ptr] = line;
+    column_stack[include_stack_ptr] = column;
+    include_stack_ptr++;
+    yyin = fopen(text, "rb");
+    if (!yyin) {
+       fprintf(stderr, "Couldn't open %s\n", text);
+       exit(1);
+    }
+    yy_switch_to_buffer(
+       yy_create_buffer( yyin, YY_BUF_SIZE ) );
+    BEGIN(INITIAL);
+}
+
 #define c() {count(yytext, yyleng, YY_START);}
 #define s(type) {store(type, line, column, yytext, yyleng);}
 %}
@@ -124,8 +163,8 @@ static void store(enum type_t type, int line, int column, char*text, int length)
 %x BINARY
 
 NAME    [a-zA-Z_./](-*[a-zA-Z0-9_./])*
-TWIP    ([0-9]+(\.([0-9]([05])?)?)?)
-NUMBER  [0-9]+(\.[0-9]*)?
+TWIP    (-?[0-9]+(\.([0-9]([05])?)?)?)
+NUMBER  -?[0-9]+(\.[0-9]*)?
 PERCENT         {NUMBER}%
 STRING   (\\.|[^\\"\n])*
 S       [ \n\r\t]
@@ -148,6 +187,7 @@ RVALUE       \"{STRING}\"|([^ \n\r\t]+)
 <R>{ /* values which appear only on the right-hand side of assignments, like: x=50% */
     [^ \n\t\r]*                    {s(IDENTIFIER);c();BEGIN(0);}
 }
+\.include{S}.*\n                   {handleInclude(yytext, yyleng);}
 \.{NAME}                   {s(COMMAND);c();}
 {NAME}{S}*:                 {s(LABEL);c();}
 {NAME}                      {s(IDENTIFIER);c();}
@@ -167,7 +207,19 @@ RVALUE      \"{STRING}\"|([^ \n\r\t]+)
                             exit(1);
                             yyterminate();
                            }
-<<EOF>>                            {c();s(END);yyterminate();}
+<<EOF>>                            {c();
+                            if ( --include_stack_ptr < 0 ) {
+                               s(END);
+                               yyterminate();
+                            } else {
+                                yy_delete_buffer( YY_CURRENT_BUFFER );
+                                yy_switch_to_buffer(
+                                     include_stack[include_stack_ptr] );
+                                column = column_stack[include_stack_ptr];
+                                line = line_stack[include_stack_ptr];
+                            }
+                           }
+
 %%
 
 int yywrap()