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"
33 #ifdef HAVE_SYS_STAT_H
40 /* flex/bison definitions */
41 extern int a3_parse();
43 extern int as3_lex_destroy();
45 static char config_recurse
= 0;
47 void as3_setverbosity(int level
)
51 void as3_add_include_dir(char*dir
)
55 void as3_set_option(const char*key
, const char*value
)
57 if(!strcmp(key
, "recurse")) {
58 config_recurse
=atoi(value
);
62 static char registry_initialized
= 0;
63 static char parser_initialized
= 0;
65 //#define STORE_TOKENS
76 typedef struct _compile_list
{
79 struct _compile_list
*next
;
81 static compile_list_t
*compile_list
=0;
83 static void as3_parse_file_or_array(const char*name
, const char*filename
, const void*mem
, int length
)
85 if(!registry_initialized
) {
86 registry_initialized
= 1;
89 if(!parser_initialized
) {
90 parser_initialized
= 1;
96 if(as3_pass
==1 && !mem
) {
97 // record the fact that we compiled this file
98 compile_list_t
*c
= rfx_calloc(sizeof(compile_list_t
));
99 c
->next
= compile_list
;
100 c
->name
= strdup(name
);
101 c
->filename
= strdup(filename
);
104 DEBUG
printf("[pass %d] parse file %s %s\n", as3_pass
, name
, filename
);
105 fi
= enter_file2(name
, filename
, 0);
108 DEBUG
printf("[pass %d] parse bytearray %s (%d bytes)\n", as3_pass
, name
, length
);
109 enter_file(name
, name
, 0);
110 as3_buffer_input((void*)mem
, length
);
114 initialize_file(name
, filename
);
121 typedef struct _scheduled_file
{
124 struct _scheduled_file
*next
;
127 static scheduled_file_t
*scheduled
=0;
128 dict_t
*scheduled_dict
=0;
130 void as3_parse_scheduled()
132 DEBUG
printf("[pass %d] parse scheduled\n", as3_pass
);
135 scheduled_file_t
*s
= scheduled
;
138 scheduled_file_t
*old
= s
;
139 as3_parse_file_or_array(s
->name
, s
->filename
, 0,0);
144 old
->filename
= old
->name
= 0;
149 dict_destroy(scheduled_dict
);
154 void as3_schedule_file(const char*name
, const char*filename
)
156 if(!scheduled_dict
) {
157 scheduled_dict
= dict_new();
160 filename
= normalize_path(filename
);
162 if(dict_contains(scheduled_dict
, filename
)) {
163 return; //already processed
165 dict_put(scheduled_dict
, filename
, 0);
167 DEBUG
printf("[pass %d] schedule %s %s\n", as3_pass
, name
, filename
);
169 NEW(scheduled_file_t
, f
);
170 f
->name
= strdup(name
);
171 f
->filename
= strdup(filename
);
172 f
->next
= scheduled
; // dfs
176 void as3_parse_list()
178 while(compile_list
) {
179 as3_parse_file_or_array(compile_list
->name
, compile_list
->filename
, 0,0);
180 compile_list
= compile_list
->next
;
184 void as3_parse_bytearray(const char*name
, const void*mem
, int length
)
187 as3_parse_file_or_array(name
, 0, mem
, length
);
188 as3_parse_scheduled();
190 registry_resolve_all();
193 as3_parse_file_or_array(name
, 0, mem
, length
);
197 void as3_parse_file(const char*filename
)
199 char*fullfilename
= find_file(filename
, 1);
205 as3_schedule_file(filename
, fullfilename
);
206 as3_parse_scheduled();
208 registry_resolve_all();
216 void as3_parse_directory(const char*dir
)
221 as3_schedule_directory(dir
);
223 as3_warning("Directory %s doesn't contain any ActionScript files", dir
);
224 as3_parse_scheduled();
226 registry_resolve_all();
232 char as3_schedule_directory(const char*dirname
)
234 DEBUG
printf("[pass %d] schedule directory %s\n", as3_pass
, dirname
);
237 include_dir_t
*i
= current_include_dirs
;
239 char*fulldirname
= concat_paths(i
->path
, dirname
);
240 DEBUG
printf("[pass %d] ... %s\n", as3_pass
, fulldirname
);
241 DIR*dir
= opendir(fulldirname
);
249 char*name
= ent
->d_name
;
255 if(strncasecmp(&name
[l
-3], ".as", 3))
257 char*fullfilename
= concatPaths(fulldirname
, name
);
258 as3_schedule_file(name
, fullfilename
);
269 void as3_schedule_package(const char*package
)
271 DEBUG
printf("[pass %d] schedule package %s\n", as3_pass
, package
);
272 char*dirname
= strdup(package
);
276 dirname
[s
] = path_seperator
;
279 if(!as3_schedule_directory(dirname
))
280 as3_softwarning("Could not find package %s in file system", package
);
283 static void schedule_class(const char*package
, const char*cls
, char error
)
286 DEBUG
printf("[pass %d] schedule class %s.%s\n", as3_pass
, package
, cls
);
289 as3_schedule_package(package
);
292 int l1
= package
?strlen(package
):0;
293 int l2
= cls
?strlen(cls
):0;
294 char*filename
= malloc(l1
+l2
+5);
300 filename
[t
++] = package
[s
];
306 strcpy(filename
+t
, cls
);
307 strcpy(filename
+t
+l2
, ".as");
308 char*f
=find_file(filename
, error
);
311 filename
= filename_to_lowercase(filename
);
312 f
=find_file(filename
, error
);
316 strcpy(filename
+t
, cls
);
317 strcpy(filename
+t
+l2
, ".as");
318 as3_warning("Could not open file %s", filename
);
322 as3_schedule_file(filename
, f
);
325 void as3_schedule_class(const char*package
, const char*cls
)
327 schedule_class(package
, cls
, 1);
330 void as3_schedule_class_noerror(const char*package
, const char*cls
)
333 schedule_class(package
, cls
, 0);
338 static void*as3code
= 0;
341 if(parser_initialized
) {
342 parser_initialized
= 0;
343 as3code
= finish_parser();
347 void* as3_getassets(void*t
)
349 return swf_AssetsToTags((TAG
*)t
, registry_getassets());
351 char* as3_getglobalclass()
353 return as3_globalclass
;
358 if(parser_initialized
) {
359 parser_initialized
= 0;
360 swf_FreeABC(finish_parser());
365 if(as3_globalclass
) {
366 free(as3_globalclass
);as3_globalclass
=0;