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 */
25 #include "tokenizer.h"
28 #include "parser.tab.h"
31 #ifdef HAVE_SYS_STAT_H
38 /* flex/bison definitions */
39 extern int a3_parse();
41 extern int as3_lex_destroy();
43 static char config_recurse = 0;
45 void as3_setverbosity(int level)
49 void as3_add_include_dir(char*dir)
53 void as3_set_option(const char*key, const char*value)
55 if(!strcmp(key, "recurse")) {
56 config_recurse=atoi(value);
60 static char registry_initialized = 0;
61 static char parser_initialized = 0;
63 //#define STORE_TOKENS
74 typedef struct _compile_list {
77 struct _compile_list*next;
79 static compile_list_t*compile_list=0;
81 static void as3_parse_file_or_array(const char*name, const char*filename, const void*mem, int length)
83 if(!registry_initialized) {
84 registry_initialized = 1;
87 if(!parser_initialized) {
88 parser_initialized = 1;
94 if(as3_pass==1 && !mem) {
95 // record the fact that we compiled this file
96 compile_list_t*c = rfx_calloc(sizeof(compile_list_t));
97 c->next = compile_list;
98 c->name = strdup(name);
99 c->filename = strdup(filename);
102 DEBUG printf("[pass %d] parse file %s %s\n", as3_pass, name, filename);
103 fi = enter_file2(name, filename, 0);
106 DEBUG printf("[pass %d] parse bytearray %s (%d bytes)\n", as3_pass, name, length);
107 enter_file(name, name, 0);
108 as3_buffer_input((void*)mem, length);
112 initialize_file(name, filename);
119 typedef struct _scheduled_file {
122 struct _scheduled_file*next;
125 static scheduled_file_t*scheduled=0;
126 dict_t*scheduled_dict=0;
128 void as3_parse_scheduled()
130 DEBUG printf("[pass %d] parse scheduled\n", as3_pass);
133 scheduled_file_t*s = scheduled;
136 scheduled_file_t*old = s;
137 as3_parse_file_or_array(s->name, s->filename, 0,0);
142 old->filename = old->name = 0;
147 dict_destroy(scheduled_dict);
152 void as3_schedule_file(const char*name, const char*filename)
154 if(!scheduled_dict) {
155 scheduled_dict = dict_new();
158 filename = normalize_path(filename);
160 if(dict_contains(scheduled_dict, filename)) {
161 return; //already processed
163 dict_put(scheduled_dict, filename, 0);
165 DEBUG printf("[pass %d] schedule %s %s\n", as3_pass, name, filename);
167 NEW(scheduled_file_t, f);
168 f->name = strdup(name);
169 f->filename = strdup(filename);
170 f->next = scheduled; // dfs
174 void as3_parse_list()
176 while(compile_list) {
177 as3_parse_file_or_array(compile_list->name, compile_list->filename, 0,0);
178 compile_list = compile_list->next;
182 void as3_parse_bytearray(const char*name, const void*mem, int length)
185 as3_parse_file_or_array(name, 0, mem, length);
186 as3_parse_scheduled();
188 registry_resolve_all();
191 as3_parse_file_or_array(name, 0, mem, length);
195 void as3_parse_file(const char*filename)
197 char*fullfilename = find_file(filename, 1);
203 as3_schedule_file(filename, fullfilename);
204 as3_parse_scheduled();
206 registry_resolve_all();
214 void as3_parse_directory(const char*dir)
219 as3_schedule_directory(dir);
221 as3_warning("Directory %s doesn't contain any ActionScript files", dir);
222 as3_parse_scheduled();
224 registry_resolve_all();
230 char as3_schedule_directory(const char*dirname)
232 DEBUG printf("[pass %d] schedule directory %s\n", as3_pass, dirname);
235 include_dir_t*i = current_include_dirs;
237 char*fulldirname = concat_paths(i->path, dirname);
238 DEBUG printf("[pass %d] ... %s\n", as3_pass, fulldirname);
239 DIR*dir = opendir(fulldirname);
247 char*name = ent->d_name;
253 if(strncasecmp(&name[l-3], ".as", 3))
255 char*fullfilename = concatPaths(fulldirname, name);
256 as3_schedule_file(name, fullfilename);
267 void as3_schedule_package(const char*package)
269 DEBUG printf("[pass %d] schedule package %s\n", as3_pass, package);
270 char*dirname = strdup(package);
274 dirname[s] = path_seperator;
277 if(!as3_schedule_directory(dirname))
278 as3_softwarning("Could not find package %s in file system", package);
281 static void schedule_class(const char*package, const char*cls, char error)
284 DEBUG printf("[pass %d] schedule class %s.%s\n", as3_pass, package, cls);
287 as3_schedule_package(package);
290 int l1 = package?strlen(package):0;
291 int l2 = cls?strlen(cls):0;
292 char*filename = malloc(l1+l2+5);
298 filename[t++] = package[s];
304 strcpy(filename+t, cls);
305 strcpy(filename+t+l2, ".as");
306 char*f=find_file(filename, error);
309 filename = filename_to_lowercase(filename);
310 f=find_file(filename, error);
314 strcpy(filename+t, cls);
315 strcpy(filename+t+l2, ".as");
316 as3_warning("Could not open file %s", filename);
320 as3_schedule_file(filename, f);
323 void as3_schedule_class(const char*package, const char*cls)
325 schedule_class(package, cls, 1);
328 void as3_schedule_class_noerror(const char*package, const char*cls)
331 schedule_class(package, cls, 0);
336 static void*as3code = 0;
339 if(parser_initialized) {
340 parser_initialized = 0;
341 as3code = finish_parser();
345 char* as3_getglobalclass()
347 return as3_globalclass;
352 if(parser_initialized) {
353 parser_initialized = 0;
354 swf_FreeABC(finish_parser());
359 if(as3_globalclass) {
360 free(as3_globalclass);as3_globalclass=0;