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