X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=src%2Fparser.lex;h=beca943b1f55c757ec37462a52029c0fedf9aa4c;hb=77374b6b5505022a057dbab119854c6b4ad48916;hp=c0513d141ce09100ff0fec450bb6df8b52738319;hpb=b415635e319943b44a72f4afa8265b5babed47b2;p=swftools.git diff --git a/src/parser.lex b/src/parser.lex index c0513d1..beca943 100644 --- a/src/parser.lex +++ b/src/parser.lex @@ -1,6 +1,8 @@ %{ #include +#include +#include #include "q.h" #include "parser.h" @@ -32,17 +34,20 @@ static char*prefix = 0; static void unescapeString(string_t * tmp) { char *p, *p1; + /* fixme - this routine expects the string to be + null-terminated */ - for (p1=tmp->str; (p=strchr(p1, '\\')) != 0; p1 = p+1) + for (p1=tmp->str; (p=strchr(p1, '\\')); p1 = p+1) { switch(p[1]) { - case '\\': p[1] = '\\'; break; - case 'b': p[1] = '\b'; break; - case 'f': p[1] = '\f'; break; - case 'n': p[1] = '\n'; break; - case 'r': p[1] = '\r'; break; - case 't': p[1] = '\t'; break; + case '\\': p[1] = '\\'; tmp->len--; break; + case '"': p[1] = '"'; tmp->len--; break; + case 'b': p[1] = '\b'; tmp->len--; break; + case 'f': p[1] = '\f'; tmp->len--; break; + case 'n': p[1] = '\n'; tmp->len--; break; + case 'r': p[1] = '\r'; tmp->len--; break; + case 't': p[1] = '\t'; tmp->len--; break; default: continue; } @@ -113,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);} %} @@ -145,16 +187,16 @@ RVALUE \"{STRING}\"|([^ \n\r\t]+) { /* 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();} "[" {c();BEGIN(BINARY);} {S} {c();} -. {char c,c1=0; +. {char c,c1=yytext[0]; printf("Syntax error in line %d, %d: %s", line, column, yytext); while(1) { c=input(); - if(!c1) c1=c; if(c=='\n' || c==EOF) break; printf("%c", c); @@ -165,7 +207,19 @@ RVALUE \"{STRING}\"|([^ \n\r\t]+) exit(1); yyterminate(); } -<> {c();s(END);yyterminate();} +<> {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()