along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+#include "common.h"
#include "tokenizer.h"
#include "files.h"
#include "parser.h"
#include "parser.tab.h"
#include "compiler.h"
-#include <errno.h>
+#include "../os.h"
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_DIRENT_H
+#include <dirent.h>
+#endif
/* flex/bison definitions */
-extern void avm2_set_in (FILE * in_str );
-extern int avm2_parse();
-extern int avm2_lex_destroy();
+extern int a3_parse();
+extern int as3_lex();
+extern int as3_lex_destroy();
+
+static char config_recurse = 0;
void as3_setverbosity(int level)
{
{
add_include_dir(dir);
}
+void as3_set_option(const char*key, const char*value)
+{
+ if(!strcmp(key, "recurse")) {
+ config_recurse=atoi(value);
+ }
+}
static char registry_initialized = 0;
static char parser_initialized = 0;
-void as3_parse_file(char*filename)
+//#define STORE_TOKENS
+
+//#define DEBUG
+#define DEBUG if(0)
+
+int a3_lex()
+{
+ as3_tokencount++;
+ return as3_lex();
+}
+
+typedef struct _compile_list {
+ const char*name;
+ const char*filename;
+ struct _compile_list*next;
+} compile_list_t;
+static compile_list_t*compile_list=0;
+
+static void as3_parse_file_or_array(const char*name, const char*filename, const void*mem, int length)
{
if(!registry_initialized) {
registry_initialized = 1;
initialize_parser();
}
- char*fullfilename = enter_file(filename, 0);
- FILE*fi = fopen(fullfilename, "rb");
- if(!fi) {
- syntaxerror("Couldn't find file %s: %s", fullfilename, strerror(errno));
+ FILE*fi = 0;
+ if(filename) {
+ if(as3_pass==1 && !mem) {
+ // record the fact that we compiled this file
+ compile_list_t*c = rfx_calloc(sizeof(compile_list_t));
+ c->next = compile_list;
+ c->name = strdup(name);
+ c->filename = strdup(filename);
+ compile_list = c;
+ }
+ DEBUG printf("[pass %d] parse file %s %s\n", as3_pass, name, filename);
+ fi = enter_file2(name, filename, 0);
+ as3_file_input(fi);
+ } else {
+ DEBUG printf("[pass %d] parse bytearray %s (%d bytes)\n", as3_pass, name, length);
+ enter_file(name, name, 0);
+ as3_buffer_input((void*)mem, length);
}
- avm2_set_in(fi);
- initialize_file(filename);
- avm2_parse();
- avm2_lex_destroy();
- fclose(fi);
+
+ as3_tokencount=0;
+ initialize_file(name, filename);
+ a3_parse();
+ as3_lex_destroy();
finish_file();
+ if(fi) fclose(fi);
+}
+
+typedef struct _scheduled_file {
+ char*name;
+ char*filename;
+ struct _scheduled_file*next;
+} scheduled_file_t;
+
+static scheduled_file_t*scheduled=0;
+dict_t*scheduled_dict=0;
+
+void as3_parse_scheduled()
+{
+ DEBUG printf("[pass %d] parse scheduled\n", as3_pass);
+
+ while(scheduled) {
+ scheduled_file_t*s = scheduled;
+ scheduled = 0;
+ while(s) {
+ scheduled_file_t*old = s;
+ as3_parse_file_or_array(s->name, s->filename, 0,0);
+ s = s->next;
+
+ free(old->filename);
+ free(old->name);
+ old->filename = old->name = 0;
+ free(old);
+ }
+ }
+ if(scheduled_dict) {
+ dict_destroy(scheduled_dict);
+ scheduled_dict=0;
+ }
+}
+
+void as3_schedule_file(const char*name, const char*filename)
+{
+ if(!scheduled_dict) {
+ scheduled_dict = dict_new();
+ }
+
+ filename = normalize_path(filename);
+
+ if(dict_contains(scheduled_dict, filename)) {
+ return; //already processed
+ } else {
+ dict_put(scheduled_dict, filename, 0);
+ }
+ DEBUG printf("[pass %d] schedule %s %s\n", as3_pass, name, filename);
+
+ NEW(scheduled_file_t, f);
+ f->name = strdup(name);
+ f->filename = strdup(filename);
+ f->next = scheduled; // dfs
+ scheduled = f;
+}
+
+void as3_parse_list()
+{
+ while(compile_list) {
+ as3_parse_file_or_array(compile_list->name, compile_list->filename, 0,0);
+ compile_list = compile_list->next;
+ }
}
+void as3_parse_bytearray(const char*name, const void*mem, int length)
+{
+ as3_pass = 1;
+ as3_parse_file_or_array(name, 0, mem, length);
+ as3_parse_scheduled();
+
+ registry_resolve_all();
+
+ as3_pass = 2;
+ as3_parse_file_or_array(name, 0, mem, length);
+ as3_parse_list();
+}
+
+void as3_parse_file(const char*filename)
+{
+ char*fullfilename = find_file(filename, 1);
+ if(!fullfilename)
+ return; // not found
+
+ compile_list = 0;
+ as3_pass = 1;
+ as3_schedule_file(filename, fullfilename);
+ as3_parse_scheduled();
+
+ registry_resolve_all();
+
+ as3_pass = 2;
+ as3_parse_list();
+
+ free(fullfilename);
+}
+
+void as3_parse_directory(const char*dir)
+{
+ compile_list = 0;
+
+ as3_pass = 1;
+ as3_schedule_directory(dir);
+ if(!scheduled)
+ as3_warning("Directory %s doesn't contain any ActionScript files", dir);
+ as3_parse_scheduled();
+
+ registry_resolve_all();
+
+ as3_pass = 2;
+ as3_parse_list();
+}
+
+char as3_schedule_directory(const char*dirname)
+{
+ DEBUG printf("[pass %d] schedule directory %s\n", as3_pass, dirname);
+ char ok=0;
+#ifdef HAVE_DIRENT_H
+ include_dir_t*i = current_include_dirs;
+ while(i) {
+ char*fulldirname = concat_paths(i->path, dirname);
+ DEBUG printf("[pass %d] ... %s\n", as3_pass, fulldirname);
+ DIR*dir = opendir(fulldirname);
+ if(dir) {
+ ok = 1;
+ struct dirent*ent;
+ while(1) {
+ ent = readdir(dir);
+ if (!ent)
+ break;
+ char*name = ent->d_name;
+ char type = 0;
+ if(!name) continue;
+ int l=strlen(name);
+ if(l<4)
+ continue;
+ if(strncasecmp(&name[l-3], ".as", 3))
+ continue;
+ char*fullfilename = concatPaths(fulldirname, name);
+ as3_schedule_file(name, fullfilename);
+ free(fullfilename);
+ }
+ }
+ free(fulldirname);
+ i = i->next;
+ }
+#endif
+ return ok;
+}
+
+void as3_schedule_package(const char*package)
+{
+ DEBUG printf("[pass %d] schedule package %s\n", as3_pass, package);
+ char*dirname = strdup(package);
+ int s=0;
+ while(dirname[s]) {
+ if(dirname[s]=='.')
+ dirname[s] = path_seperator;
+ s++;
+ };
+ if(!as3_schedule_directory(dirname))
+ as3_softwarning("Could not find package %s in file system", package);
+}
+
+static void schedule_class(const char*package, const char*cls, char error)
+{
+ if(error) {
+ DEBUG printf("[pass %d] schedule class %s.%s\n", as3_pass, package, cls);
+ }
+ if(!cls) {
+ as3_schedule_package(package);
+ return;
+ }
+ int l1 = package?strlen(package):0;
+ int l2 = cls?strlen(cls):0;
+ char*filename = malloc(l1+l2+5);
+ int s=0,t=0;
+ while(package[s]) {
+ if(package[s]=='.')
+ filename[t++]='/';
+ else
+ filename[t++] = package[s];
+ s++;
+ }
+ if(t)
+ filename[t++] = '/';
+
+ strcpy(filename+t, cls);
+ strcpy(filename+t+l2, ".as");
+ char*f=find_file(filename, error);
+ if(!f) {
+ int i;
+ filename = filename_to_lowercase(filename);
+ f=find_file(filename, error);
+ }
+ if(!f) {
+ if(error) {
+ strcpy(filename+t, cls);
+ strcpy(filename+t+l2, ".as");
+ as3_warning("Could not open file %s", filename);
+ }
+ return;
+ }
+ as3_schedule_file(filename, f);
+}
+
+void as3_schedule_class(const char*package, const char*cls)
+{
+ schedule_class(package, cls, 1);
+}
+
+void as3_schedule_class_noerror(const char*package, const char*cls)
+{
+ if(config_recurse) {
+ schedule_class(package, cls, 0);
+ }
+}
+
+
static void*as3code = 0;
void* as3_getcode()
{
if(parser_initialized) {
parser_initialized = 0;
swf_FreeABC(finish_parser());
+#ifdef STORE_TOKENS
+ mem_clear(&tokens);
+#endif
}
if(as3_globalclass) {
free(as3_globalclass);as3_globalclass=0;