3 Extension module for the rfxswf library.
4 Part of the swftools package.
6 Copyright (c) 2008 Matthias Kramm <kramm@quiss.org>
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
29 #include "tokenizer.h"
32 static int verbose = 0;
33 static void dbg(const char*format, ...)
40 va_start(arglist, format);
41 vsnprintf(buf, sizeof(buf)-1, format, arglist);
44 while(l && buf[l-1]=='\n') {
48 printf("(includefilehandler) ");
56 char* current_filename=0;
57 char* current_filename_short=0;
58 char* current_filename_long=0;
59 include_dir_t* current_include_dirs=0;
61 #define MAX_INCLUDE_DEPTH 16
63 void*include_stack[MAX_INCLUDE_DEPTH];
64 int line_stack[MAX_INCLUDE_DEPTH];
65 int column_stack[MAX_INCLUDE_DEPTH];
66 char* filename_stack[MAX_INCLUDE_DEPTH];
67 char* shortfilename_stack[MAX_INCLUDE_DEPTH];
68 char* longfilename_stack[MAX_INCLUDE_DEPTH];
69 include_dir_t* includedir_stack[MAX_INCLUDE_DEPTH];
70 int include_stack_ptr = 0;
72 void add_include_dir(char*dir)
74 include_dir_t*d = malloc(sizeof(include_dir_t));
75 memset(d , 0, sizeof(include_dir_t));
76 d->path = strdup(dir);
77 d->next = current_include_dirs;
78 current_include_dirs = d;
81 void del_include_dirs(include_dir_t*d, include_dir_t*d2)
84 include_dir_t*next = d->next;
85 free(d->path);d->path=0;
92 char*get_path(const char*file)
94 char*path = strdup(file);
95 char*r1 = strrchr(path, '/');
96 char*r2 = strrchr(path, '\\');
108 char is_absolute(const char*filename)
110 if(!filename || !filename[0])
112 if(filename[0]=='/' || filename[0]=='\\')
114 if(filename[1]==':' && filename[2]=='/')
116 if(filename[1]==':' && filename[2]=='\\')
121 char* filename_to_lowercase(const char*name)
123 char*n = strdup(name);
124 //char*x1 = strrchr(name, '/');
125 //char*x2 = strrchr(name, '\\');
130 /* FIXME: what we probably should do here is use libc's tolower().
131 I don't really know yet, though, how Windows (or MacOS X) handles
132 lowercasing of Unicode filenames */
133 if(*s>='A' && *s<='Z')
140 char* normalize_path(const char*path)
143 if(!is_absolute(path)) {
145 char*c = getcwd(buf,512);
147 d = n = malloc(l+strlen(path)+10);
148 strcpy(n, buf);d += l;
149 if(!l || n[l-1]!=path_seperator) {
150 *d=path_seperator;d++;
153 d = n = strdup(path);
159 if(init && s[0] == '.' && (s[1]==path_seperator || s[1]=='\0')) {
165 if(init && s[0] == '.' && s[1] == '.' && (s[2] == path_seperator || s[2]=='\0')) {
171 if(!(last=strrchr(n, path_seperator))) {
182 if(*s==path_seperator) init=1;
186 if(d!=n && d[-1]==path_seperator)
190 #ifdef LOWERCASE_UPPERCASE
191 n = filename_to_lowercase(n);
196 static void testnormalize()
198 #define TEST(x) {printf("%s -> %s\n", (x), normalize_path(x));}
202 TEST("../as3/parser.y");
203 TEST("../as3/ok/../ok/scope.as");
205 TEST("ok/./scope.as");
206 TEST("./ok/scope.as");
213 TEST("/tmp/../usr/");
216 char* concat_paths(const char*base, const char*add)
218 int l1 = strlen(base);
219 int l2 = strlen(add);
222 while(l1 && base[l1-1] == path_seperator)
224 while(pos < l2 && add[pos] == path_seperator)
226 n = (char*)malloc(l1 + (l2-pos) + 2);
228 n[l1]=path_seperator;
229 memcpy(&n[l1+1],&add[pos],l2-pos+1);
233 char*find_file(const char*filename, char error)
235 include_dir_t*i = current_include_dirs;
237 if(is_absolute(filename)) {
238 FILE*fi = fopen(filename, "rb");
241 return strdup(filename);
245 as3_warning("Include directory stack is empty, while looking for file %s", filename);
248 char*p = concat_paths(i->path, filename);
263 as3_error("Couldn't find file %s", filename);
264 i = current_include_dirs;
266 fprintf(stderr, "include dir: %s\n", i->path);
272 void enter_file(const char*name, const char*filename, void*state)
274 if(include_stack_ptr >= MAX_INCLUDE_DEPTH) {
275 as3_error("Includes nested too deeply");
278 include_stack[include_stack_ptr] = state;
279 line_stack[include_stack_ptr] = current_line;
280 column_stack[include_stack_ptr] = current_column;
281 shortfilename_stack[include_stack_ptr] = current_filename_short;
282 longfilename_stack[include_stack_ptr] = current_filename_long;
283 filename_stack[include_stack_ptr] = current_filename;
284 includedir_stack[include_stack_ptr] = current_include_dirs;
286 /*char*dir = get_path(filename);
287 add_include_dir(dir);
292 dbg("entering file %s", filename);
296 current_filename = strdup(name);
297 current_filename_short = strdup(name);
298 current_filename_long = strdup(filename);
301 FILE*enter_file2(const char*name, const char*filename, void*state)
303 enter_file(name, filename, state);
304 FILE*fi = fopen(filename, "rb");
306 as3_error("Couldn't find file %s: %s", filename, strerror(errno));
313 dbg("leaving file %s", current_filename);
314 if(--include_stack_ptr<=0) {
317 free(current_filename);current_filename = filename_stack[include_stack_ptr];
318 free(current_filename_short);current_filename_short = shortfilename_stack[include_stack_ptr];
319 free(current_filename_long);current_filename_long = longfilename_stack[include_stack_ptr];
320 current_column = column_stack[include_stack_ptr];
321 current_line = line_stack[include_stack_ptr];
322 del_include_dirs(includedir_stack[include_stack_ptr], current_include_dirs);
323 current_include_dirs = includedir_stack[include_stack_ptr];
324 return include_stack[include_stack_ptr];