#include "parser.h"
#include "parser.tab.h"
#include "compiler.h"
+#include "../os.h"
+#ifdef HAVE_DIRENT_H
+#include <dirent.h>
+#endif
/* flex/bison definitions */
-extern void as3_set_in (FILE * in_str );
extern int a3_parse();
extern int as3_lex();
extern int as3_lex_destroy();
#endif
}
-void as3_parse_file(char*filename)
+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;
mem_init(&tokens);
#endif
}
+ as3_pass=pass;
-#ifdef STORE_TOKENS
- tokens.pos = 0;
- tokens.read_pos = 0;
-#endif
-
- FILE*fi = enter_file2(filename, 0);
+ FILE*fi = 0;
+ if(filename) {
+ //printf("[pass %d] parse file %s %s\n", pass, name, filename);
+ fi = enter_file2(name, filename, 0);
+ as3_file_input(fi);
+ } else {
+ //printf("[pass %d] parse bytearray %s (%d bytes)\n", pass, name, length);
+ enter_file(name, name, 0);
+ as3_buffer_input(mem, length);
+ }
- /* pass 1 */
- as3_pass = 1;
as3_tokencount=0;
- as3_set_in(fi);
- initialize_file(filename);
+ 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)
+{
+ 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();
-#ifdef STORE_TOKENS
- tokens.read_pos = 0;
+ //printf("schedule %s %s\n", name, filename);
+
+ if(dict_contains(scheduled_dict, filename)) {
+ return; //already processed
+ } else {
+ dict_put(scheduled_dict, filename, 0);
+ }
+
+ 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_schedule_directory(dir);
+ as3_parse_scheduled(1);
+ as3_schedule_directory(dir);
+ as3_parse_scheduled(2);
+}
+
+char as3_schedule_directory(const char*dirname)
+{
+ char ok=0;
+#ifdef HAVE_DIRENT_H
+ include_dir_t*i = current_include_dirs;
+ while(i) {
+ char*fulldirname = concatPaths(i->path, dirname);
+ DIR*dir = opendir(dirname);
+ 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(dirname, name);
+ as3_schedule_file(name, fullfilename);
+ free(fullfilename);
+ }
+ }
+ free(fulldirname);
+ i = i->next;
+ }
#endif
+ return ok;
+}
- /* pass 2 */
- as3_pass = 2;
- as3_tokencount=0;
- enter_file(filename, 0);
- fseek(fi, 0, SEEK_SET);
- as3_set_in(fi);
- initialize_file(filename);
- a3_parse();
- as3_lex_destroy();
- finish_file();
+void as3_schedule_package(const char*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);
+}
- fclose(fi);
+void as3_schedule_class(const char*package, const char*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<t+l2;i++) {
+ if(filename[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;