3 Compiler for parsing Flash2 AVM2 ABC Actionscript
5 Extension module for the rfxswf library.
6 Part of the swftools package.
8 Copyright (c) 2008/2009 Matthias Kramm <kramm@quiss.org>
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
24 #include "tokenizer.h"
27 #include "parser.tab.h"
30 #ifdef HAVE_SYS_STAT_H
37 /* flex/bison definitions */
38 extern int a3_parse();
40 extern int as3_lex_destroy();
42 void as3_setverbosity(int level)
46 void as3_add_include_dir(char*dir)
51 static char registry_initialized = 0;
52 static char parser_initialized = 0;
54 //#define STORE_TOKENS
68 int token = as3_lex();
69 /* FIXME: current_file needs to be stored, too */
70 mem_put(&tokens, &token, sizeof(token));
71 mem_put(&tokens, &a3_lval, sizeof(a3_lval));
72 mem_put(&tokens, ¤t_line, sizeof(current_line));
73 mem_put(&tokens, ¤t_column, sizeof(current_column));
77 mem_get(&tokens, &token, sizeof(token));
78 mem_get(&tokens, &a3_lval, sizeof(a3_lval));
79 mem_get(&tokens, ¤t_line, sizeof(current_line));
80 mem_get(&tokens, ¤t_column, sizeof(current_column));
88 typedef struct _compile_list {
91 struct _compile_list*next;
93 static compile_list_t*compile_list=0;
95 static void as3_parse_file_or_array(int pass, const char*name, const char*filename, const void*mem, int length)
97 if(!registry_initialized) {
98 registry_initialized = 1;
101 if(!parser_initialized) {
102 parser_initialized = 1;
104 #if defined(STORE_TOKENS)
112 if(as3_pass==1 && !mem) {
113 compile_list_t*c = rfx_calloc(sizeof(compile_list_t));
114 c->next = compile_list;
115 c->name = strdup(name);
116 c->filename = strdup(filename);
119 DEBUG printf("[pass %d] parse file %s %s\n", pass, name, filename);
120 fi = enter_file2(name, filename, 0);
123 DEBUG printf("[pass %d] parse bytearray %s (%d bytes)\n", pass, name, length);
124 enter_file(name, name, 0);
125 as3_buffer_input((void*)mem, length);
129 initialize_file(name, filename);
135 typedef struct _scheduled_file {
138 struct _scheduled_file*next;
141 static scheduled_file_t*scheduled=0;
142 dict_t*scheduled_dict=0;
144 void as3_parse_scheduled(int pass)
146 DEBUG printf("[pass %d] parse scheduled\n", pass);
149 scheduled_file_t*s = scheduled;
152 scheduled_file_t*old = s;
153 as3_parse_file_or_array(pass, s->name, s->filename, 0,0);
158 old->filename = old->name = 0;
163 dict_destroy(scheduled_dict);
168 void as3_schedule_file(const char*name, const char*filename)
170 if(!scheduled_dict) {
171 scheduled_dict = dict_new();
174 filename = normalize_path(filename);
176 if(dict_contains(scheduled_dict, filename)) {
177 return; //already processed
179 dict_put(scheduled_dict, filename, 0);
181 DEBUG printf("[pass %d] schedule %s %s\n", as3_pass, name, filename);
183 NEW(scheduled_file_t, f);
184 f->name = strdup(name);
185 f->filename = strdup(filename);
186 f->next = scheduled; // dfs
190 void as3_parse_list()
192 while(compile_list) {
193 as3_parse_file_or_array(2, compile_list->name, compile_list->filename, 0,0);
194 compile_list = compile_list->next;
198 void as3_parse_bytearray(const char*name, const void*mem, int length)
201 as3_parse_file_or_array(1, name, 0, mem, length);
202 as3_parse_scheduled(1);
205 as3_parse_file_or_array(2, name, 0, mem, length);
209 void as3_parse_file(const char*filename)
211 char*fullfilename = find_file(filename, 1);
217 as3_parse_file_or_array(1, filename, fullfilename, 0,0);
218 as3_parse_scheduled(1);
226 void as3_parse_directory(const char*dir)
230 as3_schedule_directory(dir);
232 as3_warning("Directory %s doesn't contain any ActionScript files", dir);
233 as3_parse_scheduled(1);
239 char as3_schedule_directory(const char*dirname)
241 DEBUG printf("[pass %d] schedule directory %s\n", as3_pass, dirname);
244 include_dir_t*i = current_include_dirs;
246 char*fulldirname = concat_paths(i->path, dirname);
247 DEBUG printf("[pass %d] ... %s\n", as3_pass, fulldirname);
248 DIR*dir = opendir(fulldirname);
256 char*name = ent->d_name;
262 if(strncasecmp(&name[l-3], ".as", 3))
264 char*fullfilename = concatPaths(fulldirname, name);
265 as3_schedule_file(name, fullfilename);
276 void as3_schedule_package(const char*package)
278 DEBUG printf("[pass %d] schedule package %s\n", as3_pass, package);
279 char*dirname = strdup(package);
282 if(dirname[s]=='.') dirname[s]='/';
285 if(!as3_schedule_directory(dirname))
286 as3_softwarning("Could not find package %s in file system", package);
289 static void schedule_class(const char*package, const char*cls, char error)
292 DEBUG printf("[pass %d] schedule class %s.%s\n", as3_pass, package, cls);
295 as3_schedule_package(package);
298 int l1 = package?strlen(package):0;
299 int l2 = cls?strlen(cls):0;
300 char*filename = malloc(l1+l2+5);
306 filename[t++] = package[s];
312 strcpy(filename+t, cls);
313 strcpy(filename+t+l2, ".as");
315 if(!(f=find_file(filename, error))) {
317 /* try lower case filename (not packagename!), too */
318 for(i=t;i<t+l2;i++) {
319 if(filename[i]>='A' && filename[i]<='Z')
320 filename[i] += 'a'-'A';
322 if(!(f=find_file(filename, error))) {
324 strcpy(filename+t, cls);
325 strcpy(filename+t+l2, ".as");
326 as3_warning("Could not open file %s", filename);
331 as3_schedule_file(filename, f);
334 void as3_schedule_class(const char*package, const char*cls)
336 schedule_class(package, cls, 1);
339 void as3_schedule_class_noerror(const char*package, const char*cls)
341 schedule_class(package, cls, 0);
345 static void*as3code = 0;
348 if(parser_initialized) {
349 parser_initialized = 0;
350 as3code = finish_parser();
354 char* as3_getglobalclass()
356 return as3_globalclass;
361 if(parser_initialized) {
362 parser_initialized = 0;
363 swf_FreeABC(finish_parser());
368 if(as3_globalclass) {
369 free(as3_globalclass);as3_globalclass=0;