include file and state stack handling
authorkramm <kramm>
Mon, 20 Oct 2008 13:58:50 +0000 (13:58 +0000)
committerkramm <kramm>
Mon, 20 Oct 2008 13:58:50 +0000 (13:58 +0000)
lib/as3/files.c [new file with mode: 0644]
lib/as3/files.h [new file with mode: 0644]

diff --git a/lib/as3/files.c b/lib/as3/files.c
new file mode 100644 (file)
index 0000000..e30b112
--- /dev/null
@@ -0,0 +1,189 @@
+/* files.c
+
+   Extension module for the rfxswf library.
+   Part of the swftools package.
+
+   Copyright (c) 2008 Matthias Kramm <kramm@quiss.org>
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <memory.h>
+#include "files.h"
+
+static int verbose = 0;
+static void dbg(const char*format, ...)
+{
+    char buf[1024];
+    int l;
+    va_list arglist;
+    if(!verbose)
+       return;
+    va_start(arglist, format);
+    vsprintf(buf, format, arglist);
+    va_end(arglist);
+    l = strlen(buf);
+    while(l && buf[l-1]=='\n') {
+       buf[l-1] = 0;
+       l--;
+    }
+    printf("(includefilehandler) ");
+    printf("%s\n", buf);
+    fflush(stdout);
+}
+
+
+typedef struct _include_dir {
+    char*path;
+    struct _include_dir*next;
+} include_dir_t;
+
+int current_line=1;
+int current_column=0;
+char* current_filename=0;
+include_dir_t* current_include_dirs=0;
+
+#define MAX_INCLUDE_DEPTH 16
+
+void*include_stack[MAX_INCLUDE_DEPTH];
+int line_stack[MAX_INCLUDE_DEPTH];
+int column_stack[MAX_INCLUDE_DEPTH];
+char* filename_stack[MAX_INCLUDE_DEPTH];
+include_dir_t* includedir_stack[MAX_INCLUDE_DEPTH];
+int include_stack_ptr = 0;
+
+void add_include_dir(char*dir)
+{
+    include_dir_t*d = malloc(sizeof(include_dir_t));
+    memset(d , 0, sizeof(include_dir_t));
+    d->path = dir;
+    d->next = current_include_dirs;
+    current_include_dirs = d;
+}
+char*get_path(char*file)
+{
+    char*path = strdup(file);
+    char*r1 = strrchr(path, '/');
+    char*r2 = strrchr(path, '\\');
+    if(r1<r2) {
+        *r2=0;
+        return path;
+    } else if(r1>r2) {
+        *r1=0;
+        return path;
+    } else {
+        return strdup(".");
+    }
+}
+char* concat_paths(const char*base, const char*add)
+{
+    int l1 = strlen(base);
+    int l2 = strlen(add);
+    int pos = 0;
+    char*n = 0;
+    while(l1 && base[l1-1] == '/')
+       l1--;
+    while(pos < l2 && add[pos] == '/')
+       pos++;
+    n = (char*)malloc(l1 + (l2-pos) + 2);
+    memcpy(n,base,l1);
+    n[l1]='/';
+    memcpy(&n[l1+1],&add[pos],l2-pos+1);
+    return n;
+}
+char is_absolute(char*filename) 
+{
+    if(!filename || !filename[0])
+        return 0;
+    if(filename[0]=='/' || filename[0]=='\\')
+        return 1;
+    if(filename[1]==':' && filename[1]=='/')
+        return 1;
+    if(filename[1]==':' && filename[1]=='\\')
+        return 1;
+    return 0;
+}
+char*find_file(char*filename)
+{
+    include_dir_t*i = current_include_dirs;
+    FILE*fi = 0;
+    if(is_absolute(filename)) {
+        FILE*fi = fopen(filename, "rb");
+        if(fi) {
+            fclose(fi);
+            return strdup(filename);
+        }
+        return 0;
+    }
+    while(i) {
+        char*p = concat_paths(i->path, filename);
+        fi = fopen(p, "rb");
+        if(fi) {
+            fclose(fi);
+            return p;
+        }
+        i = i->next;
+    }
+    return 0;
+}
+
+char*enter_file(char*filename, void*state)
+{
+    if(include_stack_ptr >= MAX_INCLUDE_DEPTH) {
+       syntaxerror("Includes nested too deeply");
+       exit(1);
+    }
+    char*fullfilename = find_file(filename);
+    if(!fullfilename) {
+       syntaxerror("Couldn't find file %s", filename);
+        include_dir_t*i = current_include_dirs;
+        while(i) {
+            fprintf(stderr, "include dir: %s\n", i->path);
+            i = i->next;
+        }
+       exit(1);
+    }
+    include_stack[include_stack_ptr] = state;
+    line_stack[include_stack_ptr] = current_line;
+    column_stack[include_stack_ptr] = current_column;
+    filename_stack[include_stack_ptr] = current_filename;
+    includedir_stack[include_stack_ptr] = current_include_dirs;
+    add_include_dir(get_path(fullfilename));
+    include_stack_ptr++;
+    
+    dbg("entering file %s", fullfilename);
+
+    current_line=1;
+    current_column=0;
+    current_filename=fullfilename;
+    return fullfilename;
+}
+
+void* leave_file()
+{
+    dbg("leaving file %s", current_filename);
+    if(--include_stack_ptr<0) {
+        return 0;
+    } else {
+        current_column = column_stack[include_stack_ptr];
+        current_line = line_stack[include_stack_ptr];
+        free(current_filename);
+        current_filename = filename_stack[include_stack_ptr];
+        current_include_dirs = includedir_stack[include_stack_ptr];
+        return include_stack[include_stack_ptr];
+    }
+}
diff --git a/lib/as3/files.h b/lib/as3/files.h
new file mode 100644 (file)
index 0000000..7243718
--- /dev/null
@@ -0,0 +1,34 @@
+/* files.h
+
+   Extension module for the rfxswf library.
+   Part of the swftools package.
+
+   Copyright (c) 2008 Matthias Kramm <kramm@quiss.org>
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+#ifndef __avm2_files_h__
+#define __avm2_files_h__
+
+extern int current_line;
+extern int current_column;
+extern char* current_filename;
+
+void add_include_dir(char*dir);
+
+char* enter_file(char*filename, void*state);
+void* leave_file();
+
+#endif