X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fas3%2Fcompiler.c;h=89b746e6e8fe560a80362030f09b4eebbd5eab67;hb=f3f1d7146a8a177af328c1d20f62fa3a44076606;hp=be9cdab683d9d4d0c137fa609861a827704745b6;hpb=18e1026132d3f1ee795ef2679cc15bd7c2e27200;p=swftools.git diff --git a/lib/as3/compiler.c b/lib/as3/compiler.c index be9cdab..89b746e 100644 --- a/lib/as3/compiler.c +++ b/lib/as3/compiler.c @@ -26,11 +26,18 @@ #include "parser.h" #include "parser.tab.h" #include "compiler.h" -#include +#include "../os.h" +#ifdef HAVE_SYS_STAT_H +#include +#endif +#ifdef HAVE_DIRENT_H +#include +#endif /* flex/bison definitions */ -extern void avm2_set_in (FILE * in_str ); -extern int avm2_parse(); +extern int a3_parse(); +extern int as3_lex(); +extern int as3_lex_destroy(); void as3_setverbosity(int level) { @@ -44,7 +51,41 @@ void as3_add_include_dir(char*dir) 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) + +#ifdef STORE_TOKENS +static mem_t tokens; +#endif + +int a3_lex() +{ + as3_tokencount++; +#ifdef STORE_TOKENS + if(as3_pass==1) { + int token = as3_lex(); + /* FIXME: current_file needs to be stored, too */ + mem_put(&tokens, &token, sizeof(token)); + mem_put(&tokens, &a3_lval, sizeof(a3_lval)); + mem_put(&tokens, ¤t_line, sizeof(current_line)); + mem_put(&tokens, ¤t_column, sizeof(current_column)); + return token; + } else { + int token; + mem_get(&tokens, &token, sizeof(token)); + mem_get(&tokens, &a3_lval, sizeof(a3_lval)); + mem_get(&tokens, ¤t_line, sizeof(current_line)); + mem_get(&tokens, ¤t_column, sizeof(current_column)); + return token; + } +#else + return as3_lex(); +#endif +} + +static void as3_parse_file_or_array(int pass, const char*name, const char*filename, void*mem, int length) { if(!registry_initialized) { registry_initialized = 1; @@ -53,21 +94,212 @@ void as3_parse_file(char*filename) if(!parser_initialized) { parser_initialized = 1; initialize_parser(); +#if defined(STORE_TOKENS) + mem_init(&tokens); +#endif } + as3_pass=pass; - 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) { + DEBUG printf("[pass %d] parse file %s %s\n", pass, name, filename); + fi = enter_file2(name, filename, 0); + as3_file_input(fi); + } else { + DEBUG printf("[pass %d] parse bytearray %s (%d bytes)\n", pass, name, length); + enter_file(name, name, 0); + as3_buffer_input(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(); } +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(int pass) +{ + DEBUG printf("[pass %d] parse scheduled\n", pass); + + while(scheduled) { + scheduled_file_t*s = scheduled; + scheduled = 0; + while(s) { + scheduled_file_t*old = s; + as3_parse_file_or_array(pass, 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_bytearray(const char*name, void*mem, int length) +{ + as3_parse_file_or_array(1, name, 0, mem, length); + as3_parse_scheduled(1); + + as3_parse_file_or_array(2, name, 0, mem, length); + as3_parse_scheduled(2); +} + +void as3_parse_file(const char*filename) +{ + char*fullfilename = find_file(filename); + if(!fullfilename) + return; // not found + + as3_parse_file_or_array(1, filename, fullfilename, 0,0); + as3_parse_scheduled(1); + + as3_parse_file_or_array(2, filename, fullfilename, 0,0); + as3_parse_scheduled(2); + + free(fullfilename); +} + +void as3_parse_directory(const char*dir) +{ + as3_pass=1; + as3_schedule_directory(dir); + if(!scheduled) + as3_warning("Directory %s doesn't contain any ActionScript files", dir); + as3_parse_scheduled(1); + as3_pass=2; + as3_schedule_directory(dir); + as3_parse_scheduled(2); +} + +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]='/'; + s++; + }; + if(!as3_schedule_directory(package)) + as3_softwarning("Could not find package %s in file system", package); +} + +void as3_schedule_class(const char*package, const char*cls) +{ + 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=0; + if(!(f=find_file(filename))) { + int i; + /* try lower case filename (not packagename!), too */ + for(i=t;i='A' && filename[i]<='Z') + filename[i] += 'a'-'A'; + } + if(!(f=find_file(filename))) { + strcpy(filename+t, cls); + strcpy(filename+t+l2, ".as"); + as3_warning("Could not open file %s", filename); + return; + } + } + as3_schedule_file(filename, f); +} + static void*as3code = 0; void* as3_getcode() { @@ -87,6 +319,9 @@ void as3_destroy() 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;