From: kramm Date: Mon, 20 Oct 2008 13:58:50 +0000 (+0000) Subject: include file and state stack handling X-Git-Tag: release-0-9-0~872 X-Git-Url: http://git.asbjorn.biz/?p=swftools.git;a=commitdiff_plain;h=1ae58b8b15dee25f1915c344f4fdea9f9c3d41ea include file and state stack handling --- diff --git a/lib/as3/files.c b/lib/as3/files.c new file mode 100644 index 0000000..e30b112 --- /dev/null +++ b/lib/as3/files.c @@ -0,0 +1,189 @@ +/* files.c + + Extension module for the rfxswf library. + Part of the swftools package. + + Copyright (c) 2008 Matthias Kramm + + 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 +#include +#include +#include +#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(r1r2) { + *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 index 0000000..7243718 --- /dev/null +++ b/lib/as3/files.h @@ -0,0 +1,34 @@ +/* files.h + + Extension module for the rfxswf library. + Part of the swftools package. + + Copyright (c) 2008 Matthias Kramm + + 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