X-Git-Url: http://git.asbjorn.biz/?p=swftools.git;a=blobdiff_plain;f=src%2Fparser.lex;h=a4338e8f56b72974e4a4c31e267d0750aff8e951;hp=e03175a1f9703931cade508c8025a0c5ccf1d900;hb=c63b2bf21dc1df9a736f0b4c08f6cba828cdab92;hpb=b52d3471652c8872497ff81ff46de4fda543298c diff --git a/src/parser.lex b/src/parser.lex index e03175a..a4338e8 100644 --- a/src/parser.lex +++ b/src/parser.lex @@ -5,6 +5,7 @@ #include #include "../lib/q.h" #include "parser.h" +#include "../lib/utf8.h" //RVALUE {NUMBER}|{PERCENT}|{NAME}|\"{STRING}\"|{DIM} //. {printf("%s\n", yytext);} @@ -37,21 +38,58 @@ static void unescapeString(string_t * tmp) /* fixme - this routine expects the string to be null-terminated */ - for (p1=tmp->str; (p=strchr(p1, '\\')); p1 = p+1) + for (p1=(char*)tmp->str; (p=strchr(p1, '\\')); p1 = p+1) { + int nr=2; + int new=1; switch(p[1]) { - 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; + case '\\': p[0] = '\\'; break; + case '"': p[0] = '"'; break; + case 'b': p[0] = '\b'; break; + case 'f': p[0] = '\f'; break; + case 'n': p[0] = '\n'; break; + case 'r': p[0] = '\r'; break; + case 't': p[0] = '\t'; break; + case 'x': case 'u': { + int max=4; + int num=0; + char*utf8; + char bracket = 0; + if(p[1] == 'u') + max = 6; + if(p[2] == '{') { + bracket = 1;nr++;max++; + } + while(strchr("0123456789abcdefABCDEF", p[nr]) && (bracket || nr < max)) { + num <<= 4; + if(p[nr]>='0' && p[nr]<='9') num |= p[nr] - '0'; + if(p[nr]>='a' && p[nr]<='f') num |= p[nr] - 'a' + 10; + if(p[nr]>='A' && p[nr]<='F') num |= p[nr] - 'A' + 10; + nr++; + } + if(bracket && p[nr]=='}') { + bracket = 0; + nr++; + } + utf8 = getUTF8(num); + new = strlen(utf8); + memcpy(p, utf8, new); // do not copy the terminating zero + break; + } default: continue; } - strcpy(p, p+1); + tmp->len -= (nr-new); + { + int t; + char*to=p+new,*from=p+nr; + while(*from) { + *to = *from; + to++; + from++; + } + } } } @@ -119,18 +157,21 @@ static void store(enum type_t type, int line, int column, char*text, int length) } #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; +static YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH]; +static int line_stack[MAX_INCLUDE_DEPTH]; +static int column_stack[MAX_INCLUDE_DEPTH]; +static int include_stack_ptr = 0; -void handleInclude(char*text, int len) +static 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')) { + while(len >= 1 && + (text[len-1] == ' ' || + text[len-1] == '\r' || + text[len-1] == '\n')) { len--; } if(len >= 2 && text[0] == '"' && text[len-1] == '"') { @@ -150,9 +191,14 @@ void handleInclude(char*text, int len) fprintf(stderr, "Couldn't open %s\n", text); exit(1); } - yy_switch_to_buffer( - yy_create_buffer( yyin, YY_BUF_SIZE ) ); + yy_switch_to_buffer(yy_create_buffer( yyin, YY_BUF_SIZE ) ); + +#ifdef INITIAL BEGIN(INITIAL); +#else + // best guess + BEGIN(0); +#endif } #define c() {count(yytext, yyleng, YY_START);} @@ -185,11 +231,11 @@ RVALUE \"{STRING}\"|([^ \n\r\t]+) {NAME}{S}*-= {s(ASSIGNMENT);prefix="";c();BEGIN(R);} {NAME}{S}*= {s(ASSIGNMENT);c();BEGIN(R);} { /* values which appear only on the right-hand side of assignments, like: x=50% */ - [^ \n\t\r]* {s(IDENTIFIER);c();BEGIN(0);} + [^ :\n\t\r]* {s(IDENTIFIER);c();BEGIN(0);} } \.include{S}.*\n {handleInclude(yytext, yyleng);} \.{NAME} {s(COMMAND);c();} -:([^.]|\.[^e]|\.e[^n]|\.en[^d]|[ \n\r\t])*\.end {s(RAWDATA);c();} +:([^.]|\.[^e]|\.e[^n]|\.en[^d]|\.end[^ \n\r\t]|[ \n\r\t])*\.end {s(RAWDATA);c();} {NAME} {s(IDENTIFIER);c();} "[" {c();BEGIN(BINARY);} {S} {c();} @@ -235,10 +281,19 @@ void freeTokens(struct token_t*file) struct token_t* generateTokens(char*filename) { - FILE*fi = fopen(filename, "rb"); + FILE*fi; int t; struct token_t*result; int num; + + if(!filename) + return 0; + + if(!strcmp(filename,"-")) + fi = stdin; + else + fi = fopen(filename, "rb"); + if(!fi) { printf("Couldn't find file %s\n", filename); return 0; @@ -253,7 +308,12 @@ struct token_t* generateTokens(char*filename) column=1; yylex(); +#ifdef YY_CURRENT_BUFFER + // some newer flex versions require it like this: + yy_delete_buffer(YY_CURRENT_BUFFER); +#else yy_delete_buffer(yy_current_buffer); +#endif result = (struct token_t*)tokens.buffer; num = tokens.pos/sizeof(struct token_t); @@ -263,7 +323,8 @@ struct token_t* generateTokens(char*filename) result[t].text += (int)strings.buffer; } - fclose(fi); + if(fi!=stdin) + fclose(fi); return result; }