fixed unescape function in swf5compiler
[swftools.git] / lib / action / swf5compiler.flex
blobe100fc276850508b7a35f5d6cd8b193d664ebb15
1 %{
3 #include <math.h>
4 #include <string.h>
6 #include "compile.h"
7 #include "action.h"
8 #include "blocks/error.h"
9 #include "swf5compiler.tab.h" /* defines token types */
11 static int swf5debug;
13 static const char *lexBuffer = NULL;
14 static int lexBufferLen = 0;
16 static int  sLineNumber = 0;
17 static char szLine[1024];
18 static char msgbufs[2][1024] = { {0}, {0} }, *msgline = {0};
19 static int  column = 0;
21 static void comment();
22 static void comment1();
23 static void count();
24 static void countline();
25 static void warning(char *msg);
27 #define YY_INPUT(buf,result,max_size) result=lexBufferInput(buf, max_size)
29 /* thanks to the prolific and brilliant Raff: */
30 static int lexBufferInput(char *buf, int max_size)
32   int l = lexBufferLen > max_size ? max_size : lexBufferLen;
34   if (lexBufferLen <= 0)
35     return YY_NULL;
37   memcpy(buf, lexBuffer, l);
38   lexBuffer += l;
39   lexBufferLen -= l;
40   return l;
43         /* very inefficient method of unescaping strings */
44 static void unescape(char *buf)
46   char *p, *n;
48   n = p = buf;
49   while(*p) {
50     if(*p == '\\') {
51         switch(p[1])
52         {
53         case 'b' : *n++ = '\b'; break;
54         case 'f' : *n++ = '\f'; break;
55         case 'n' : *n++ = '\n'; break;
56         case 'r' : *n++ = '\r'; break;
57         case 't' : *n++ = '\t'; break;
58         case 'x' :
59         case 'u' : warning("unsupported escape sequence");
60         }
61         p+=2;
62     } else {
63         *n++ = *p++;
64     }
65   }
66   *n = 0;
69 void swf5ParseInit(const char *script, int debug)
71   checkByteOrder();
72   yyrestart(NULL);
74   swf5debug = debug;
76   lexBuffer = script;
77   lexBufferLen = strlen(script);
78   sLineNumber = 0;
79   column = 0;
80   msgline = msgbufs[0];
85 %s asm
88  // forward declaration needed by the following function
89 #ifndef YY_PROTO
90 #ifdef YY_USE_PROTOS
91 #define YY_PROTO(proto) proto
92 #else
93 #define YY_PROTO(proto) ()
94 #endif
95 #endif
96  static void yyunput YY_PROTO(( int c, char *buf_ptr ));
98  void do_unput5(const char c) { unput(c); }
101 DIGIT    [0-9]
102 ID       [a-zA-Z_][a-zA-Z0-9_]*
106 0x[0-9a-fA-F]+  { count();      swf5lval.intVal = strtoul(yytext, NULL, 0);
107                                         return INTEGER;         }
108 0[0-7]+                 { count();      swf5lval.intVal = strtoul(yytext, NULL, 0);
109                                         return INTEGER;         }
110 {DIGIT}+                { count();      swf5lval.intVal = atoi(yytext);
111                                         return INTEGER;         }
112 {DIGIT}+"."{DIGIT}*     { count();      swf5lval.doubleVal = atof(yytext);
113                                         return DOUBLE;          }
114 true                    { count();      swf5lval.intVal = 1;
115                                         return BOOLEAN;         }
116 false                   { count();      swf5lval.intVal = 0;
117                                         return BOOLEAN;         }
118 null                    { count();      return NULLVAL;         }
119 break                   { count();      return BREAK;           }
120 continue                { count();      return CONTINUE;        }
121 function                { count();      return FUNCTION;        }
122 else                    { count();      return ELSE;            }
123 switch                  { count();      return SWITCH;          }
124 case                    { count();      return CASE;            }
125 default                 { count();      return DEFAULT;         }
126 for                     { count();      return FOR;             }
127 in                      { count();      return IN;              }
128 if                      { count();      return IF;              }
129 while                   { count();      return WHILE;           }
130 do                      { count();      return DO;              }
131 var                     { count();      return VAR;             }
132 new                     { count();      return NEW;             }
133 delete                  { count();      return DELETE;          }
134 return                  { count();      return RETURN;          }
135 with                    { count();      return WITH;            }
136 asm                     { count();      BEGIN(asm); return ASM;         }
137 eval                    { count();      return EVAL;            }
138 typeof                  { count();      return TYPEOF; }
139 instanceof                      { count();      return INSTANCEOF; }
141   /* legacy functions */
142 random                  { count();      return RANDOM;  }
143 getTimer                { count();      return GETTIMER;        }
144 length                  { count();      return LENGTH;  }
145 concat                  { count();      return CONCAT;  }
146 substr                  { count();      return SUBSTR;  }
147 trace                   { count();      return TRACE;   }
148 int                     { count();      return INT;     }
149 ord                     { count();      return ORD;     }
150 chr                     { count();      return CHR;     }
151 getURL                  { count();      return GETURL;  }
152 getURL1                 { count();      return GETURL1; }
153 nextFrame               { count();      return NEXTFRAME;       }
154 prevFrame               { count();      return PREVFRAME;       }
155 play                    { count();      return PLAY;            }
156 stop                    { count();      return STOP;            }
157 toggleQuality           { count();      return TOGGLEQUALITY;   }
158 stopSounds              { count();      return STOPSOUNDS;      }
159 callFrame               { count();      return CALLFRAME;       }
160 gotoFrame               { count();      return GOTOFRAME;       }
161 setTarget               { count();      return SETTARGET;       }
162 loadVariables           { count();      return LOADVARIABLES;   }
163 loadMovie               { count();      return LOADMOVIE;       }
164 loadVariablesNum        { count();      return LOADVARIABLESNUM;        }
165 loadMovieNum            { count();      return LOADMOVIENUM;    }
166 duplicateMovieClip      { count();      return DUPLICATEMOVIECLIP; }
167 removeMovieClip         { count();      return REMOVEMOVIECLIP; }
169   /* assembler ops */
170 <asm>{
171 dup                     { count();      return DUP; }
172 swap                    { count();      return SWAP; }
173 pop                     { count();      return POP; }
174 push                    { count();      return PUSH; }
175 setregister             { count();      return SETREGISTER; }
176 callfunction            { count();      return CALLFUNCTION; }
177 callmethod              { count();      return CALLMETHOD; }
178 and                     { count();      return AND; }
179 or                      { count();      return OR; }
180 xor                     { count();      return XOR; }
181 modulo                  { count();      return MODULO; }
182 add                     { count();      return ADD; }
183 newadd                  { count();      return ADD; }
184 lessthan                { count();      return LESSTHAN; }
185 newlessthan             { count();      return LESSTHAN; }
186 equals                  { count();      return EQUALS; }
187 newequals               { count();      return EQUALS; }
188 inc                     { count();      return INC; }
189 dec                     { count();      return DEC; }
190 enumerate               { count();      return ENUMERATE; }
191 initobject              { count();      return INITOBJECT; }
192 initarray               { count();      return INITARRAY; }
193 getmember               { count();      return GETMEMBER; }
194 setmember               { count();      return SETMEMBER; }
195 shiftleft               { count();      return SHIFTLEFT; }
196 shiftright              { count();      return SHIFTRIGHT; }
197 shiftright2             { count();      return SHIFTRIGHT2; }
198 varequals               { count();      return VAREQUALS; }
199 oldadd                  { count();      return OLDADD; }
200 subtract                { count();      return SUBTRACT; }
201 multiply                { count();      return MULTIPLY; }
202 divide                  { count();      return DIVIDE; }
203 oldequals               { count();      return OLDEQUALS; }
204 oldlessthan             { count();      return OLDLESSTHAN; }
205 logicaland              { count();      return LOGICALAND; }
206 logicalor               { count();      return LOGICALOR; }
207 not                     { count();      return NOT; }
208 stringeq                { count();      return STRINGEQ; }
209 stringlength            { count();      return STRINGLENGTH; }
210 substring               { count();      return SUBSTRING; }
211 getvariable             { count();      return GETVARIABLE; }
212 setvariable             { count();      return SETVARIABLE; }
213 settargetexpr           { count();      return SETTARGETEXPRESSION; }
214 startdrag               { count();      return STARTDRAG; }
215 stopdrag                { count();      return STOPDRAG; }
216 stringlessthan          { count();      return STRINGLESSTHAN; }
217 mblength                { count();      return MBLENGTH; }
218 mbsubstring             { count();      return MBSUBSTRING; }
219 mbord                   { count();      return MBORD; }
220 mbchr                   { count();      return MBCHR; }
221 branch                  { count();      return BRANCHALWAYS; }
222 branchalways            { count();      return BRANCHALWAYS; }
223 branchiftrue            { count();      return BRANCHIFTRUE; }
224 post                    { count();      return POST; }
225 get                     { count();      return GET; }
226 end                     { count();      return END;             }
229 r\:{DIGIT}+             { count();      swf5lval.str = strdup(yytext+2);
230                                         return REGISTER;        }
233 {ID}                    { count();      swf5lval.str = strdup(yytext);
234                                         return IDENTIFIER;      }
236 \"(\\.|[^\\"])*\"       { count();      swf5lval.str = strdup(yytext+1);
237                                         swf5lval.str[strlen(swf5lval.str)-1]=0;
238                                         unescape(swf5lval.str);
239                                         return STRING;          }
241 \'(\\.|[^\\'])*\'       { count();      swf5lval.str = strdup(yytext+1);
242                                         swf5lval.str[strlen(swf5lval.str)-1]=0;
243                                         unescape(swf5lval.str);
244                                         return STRING;          }
246 \"(\\.|[^\\"])*$        { count();      swf5lval.str = strdup("");
247                                         warning("Unterminated string!");
248                                         return STRING;          }
250 \'(\\.|[^\\'])*$        { count();      swf5lval.str = strdup("");
251                                         warning("Unterminated string!");
252                                         return STRING;          }
254 "/*"                    { count();      comment();              }
255 "//"                    { count();      comment1();             }
256 [ \t\v\f]               { count(); }
258 "++"                    { count();      return INCR; }
259 "--"                    { count();      return DECR; }
260 "<="                    { count();      return LE; }
261 ">="                    { count();      return GE; }
262 "=="                    { count();      return EQ; }
263 "!="                    { count();      return NE; }
264 "&&"                    { count();      return LAN; }
265 "||"                    { count();      return LOR; }
266 "*="                    { count();      return MEQ; }
267 "/="                    { count();      return DEQ; }
268 "+="                    { count();      return IEQ; }
269 "-="                    { count();      return SEQ; }
270 "&="                    { count();      return AEQ; }
271 "|="                    { count();      return OEQ; }
272 "<<"                    { count();      return SHL; }
273 ">>"                    { count();      return SHR; }
274 ">>>"                   { count();      return SHR2; }
275 "<<="                   { count();      return SHLEQ; }
276 ">>="                   { count();      return SHREQ; }
277 ">>>="                  { count();      return SHR2EQ; }
279 "<"                     { count();      return '<'; }
280 ">"                     { count();      return '>'; }
281 ";"                     { count();      return ';'; }
282 "="                     { count();      return '='; }
283 "+"                     { count();      return '+'; }
284 "-"                     { count();      return '-'; }
285 "&"                     { count();      return '&'; }
286 "|"                     { count();      return '|'; }
287 "^"                     { count();      return '^'; }
288 "*"                     { count();      return '*'; }
289 "/"                     { count();      return '/'; }
290 "%"                     { count();      return '%'; }
291 "!"                     { count();      return '!'; }
292 "("                     { count();      return '('; }
293 ")"                     { count();      return ')'; }
294 "["                     { count();      return '['; }
295 "]"                     { count();      return ']'; }
296 "{"                     { count();      return '{'; }
297 "}"                     { count();      BEGIN(0); return '}'; }
298 ","                     { count();      return ','; }
299 "."                     { count();      return '.'; }
300 "?"                     { count();      return '?'; }
301 ":"                     { count();      return ':'; }
302 "~"                     { count();      return '~'; }
304 \r?\n                   { count();      strcpy(szLine, yytext + 1);
305                                         countline();    yyless(1);      }
307 .                       SWF_error("Unrecognized character: %s\n", yytext);
310 static int getinput() {
311 #ifdef __cplusplus
312                                         return yyinput();
313 #else
314                                         return input();
315 #endif
318 int swf5wrap()
320   return 1;
323 static void countline()
325   if(sLineNumber != 0)
326     msgline[column] = 0;
328   ++sLineNumber;
329   column = 0;
330   msgline = msgbufs[sLineNumber & 1];
333 static int LineNumber(void)
335    return (sLineNumber + 1);
338 static int ColumnNumber(void)
340    return column;
343 static char *LineText(void)
345   msgline[column] = 0;
346   return msgline;
349 static void comment()
351    // Handle block comments
353    int c, c1;
355 loop:
356    // We have the start of a comment so look skip everything up to the
357    // end of the comment character
358    while ((c = getinput()) != '*' && c != EOF)
359    {
360       if(column < 1023)
361          msgline[column] = c;
363       ++column;
365       // keep the line number in synch
366       if (c == '\n')
367       {
368          // start the output (matches the algorithim in the lexx above)
369          countline();
370       }
372       if (swf5debug) putchar(c);
373    }
375    // is this the end of comment character
376    if ((c1 = getinput()) != '/' && c != EOF)
377    {
378       // false start as this was no end of comment
379       do_unput5(c1);
380       goto loop;
381    }
383    // write out the start of the end of comment
384    if (c != EOF)
385       if (swf5debug) putchar(c);
387    // write out the end of the end of comment
388    if (c1 != EOF) 
389       if (swf5debug) putchar(c1);
392 static void comment1()
394    // Handle comment of type 1 (ie '//')
396    int c;
398    // this is a line comment
399    while ((c = getinput()) != '\n' && c != EOF)
400    {
401       if (swf5debug) putchar(c);
403       if(column < 1023)
404          msgline[column] = c;
406       ++column;
407    };
409    // keep the line number in synch
410    if (c == '\n')
411    {
412       if (swf5debug) putchar(c);
414       countline();
415    }
418 static void count(void)
420    int n;
422    // Count the characters to maintain the current column position
423    if (yytext[0] == '\n')
424    {
425       if (swf5debug) printf("\n");
426    }
427    else
428    {
429       if (swf5debug) printf("%s", yytext);
431       for(n=0; n<yyleng; ++n, ++column)
432       {
433         if(column < 1023)
434           msgline[column] = yytext[n];
435       }
437       //-- keep writing the stuff to standard output
438       //column += yyleng;
439    }
442 static void printprog()
444   if(sLineNumber)
445     SWF_warn("\n%s", msgbufs[(sLineNumber-1)&1]);
447   if(column < 1023)
448     msgline[column] = 0;
450   SWF_warn("\n%s", msgline);
453 static void warning(char *msg)
455    // print a warning message
456    printprog();
457    SWF_warn("\n%*s", ColumnNumber(), "^");
458    SWF_warn("\nLine %4.4d:  Reason: '%s' \n", LineNumber(), msg);
461 void swf5error(char *msg)
463   // report a error
464   if(strlen(yytext))
465   {
466     SWF_error("\n%s\n%*s\nLine %i:  Reason: '%s'\n",
467               LineText(), ColumnNumber(), "^", LineNumber(), msg);
468   }
469   else
470   {
471     SWF_error("\nLine %d: Reason: 'Unexpected EOF found while looking for input.'\n", LineNumber());
472   }