1 /* -----------------------------------------------------------------------------
2 * This file is part of SWIG, which is licensed as a whole under version 3
3 * (or any later version) of the GNU General Public License. Some additional
4 * terms also apply to certain portions of SWIG. The full details of the SWIG
5 * license and copyrights can be found in the LICENSE and COPYRIGHT files
6 * included with the SWIG source code as distributed by the SWIG developers
7 * and at http://www.swig.org/legal.html.
8 *
9 * include.c
10 *
11 * The functions in this file are used to manage files in the SWIG library.
12 * General purpose functions for opening, including, and retrieving pathnames
13 * are provided.
14 * ----------------------------------------------------------------------------- */
15
16 #include "swig.h"
17
18 static List *directories = 0; /* List of include directories */
19 static String *lastpath = 0; /* Last file that was included */
20 static List *pdirectories = 0; /* List of pushed directories */
21 static int dopush = 1; /* Whether to push directories */
22 static int file_debug = 0;
23
24 /* This functions determine whether to push/pop dirs in the preprocessor */
Swig_set_push_dir(int push)25 void Swig_set_push_dir(int push) {
26 dopush = push;
27 }
28
Swig_get_push_dir(void)29 int Swig_get_push_dir(void) {
30 return dopush;
31 }
32
33 /* -----------------------------------------------------------------------------
34 * Swig_add_directory()
35 *
36 * Adds a directory to the SWIG search path.
37 * ----------------------------------------------------------------------------- */
38
Swig_add_directory(const_String_or_char_ptr dirname)39 List *Swig_add_directory(const_String_or_char_ptr dirname) {
40 String *adirname;
41 if (!directories)
42 directories = NewList();
43 assert(directories);
44 if (dirname) {
45 adirname = NewString(dirname);
46 Append(directories,adirname);
47 Delete(adirname);
48 }
49 return directories;
50 }
51
52 /* -----------------------------------------------------------------------------
53 * Swig_push_directory()
54 *
55 * Inserts a directory at the front of the SWIG search path. This is used by
56 * the preprocessor to grab files in the same directory as other included files.
57 * ----------------------------------------------------------------------------- */
58
Swig_push_directory(const_String_or_char_ptr dirname)59 void Swig_push_directory(const_String_or_char_ptr dirname) {
60 String *pdirname;
61 if (!Swig_get_push_dir())
62 return;
63 if (!pdirectories)
64 pdirectories = NewList();
65 assert(pdirectories);
66 pdirname = NewString(dirname);
67 assert(pdirname);
68 Insert(pdirectories,0,pdirname);
69 Delete(pdirname);
70 }
71
72 /* -----------------------------------------------------------------------------
73 * Swig_pop_directory()
74 *
75 * Pops a directory off the front of the SWIG search path. This is used by
76 * the preprocessor.
77 * ----------------------------------------------------------------------------- */
78
Swig_pop_directory(void)79 void Swig_pop_directory(void) {
80 if (!Swig_get_push_dir())
81 return;
82 if (!pdirectories)
83 return;
84 Delitem(pdirectories, 0);
85 }
86
87 /* -----------------------------------------------------------------------------
88 * Swig_last_file()
89 *
90 * Returns the full pathname of the last file opened.
91 * ----------------------------------------------------------------------------- */
92
Swig_last_file(void)93 String *Swig_last_file(void) {
94 assert(lastpath);
95 return lastpath;
96 }
97
98 /* -----------------------------------------------------------------------------
99 * Swig_search_path_any()
100 *
101 * Returns a list of the current search paths.
102 * ----------------------------------------------------------------------------- */
103
Swig_search_path_any(int syspath)104 static List *Swig_search_path_any(int syspath) {
105 String *filename;
106 List *slist;
107 int i, ilen;
108
109 slist = NewList();
110 assert(slist);
111 filename = NewStringEmpty();
112 assert(filename);
113 #ifdef MACSWIG
114 Printf(filename, "%s", SWIG_FILE_DELIMITER);
115 #else
116 Printf(filename, ".%s", SWIG_FILE_DELIMITER);
117 #endif
118 Append(slist, filename);
119 Delete(filename);
120
121 /* If there are any pushed directories. Add them first */
122 if (pdirectories) {
123 ilen = Len(pdirectories);
124 for (i = 0; i < ilen; i++) {
125 filename = NewString(Getitem(pdirectories,i));
126 Append(filename,SWIG_FILE_DELIMITER);
127 Append(slist,filename);
128 Delete(filename);
129 }
130 }
131 /* Add system directories next */
132 ilen = Len(directories);
133 for (i = 0; i < ilen; i++) {
134 filename = NewString(Getitem(directories,i));
135 Append(filename,SWIG_FILE_DELIMITER);
136 if (syspath) {
137 /* If doing a system include, put the system directories first */
138 Insert(slist,i,filename);
139 } else {
140 /* Otherwise, just put the system directories after the pushed directories (if any) */
141 Append(slist,filename);
142 }
143 Delete(filename);
144 }
145 return slist;
146 }
147
Swig_search_path()148 List *Swig_search_path() {
149 return Swig_search_path_any(0);
150 }
151
152
153
154 /* -----------------------------------------------------------------------------
155 * Swig_open()
156 *
157 * open a file, optionally looking for it in the include path. Returns an open
158 * FILE * on success.
159 * ----------------------------------------------------------------------------- */
160
Swig_open_file(const_String_or_char_ptr name,int sysfile,int use_include_path)161 static FILE *Swig_open_file(const_String_or_char_ptr name, int sysfile, int use_include_path) {
162 FILE *f;
163 String *filename;
164 List *spath = 0;
165 char *cname;
166 int i, ilen, nbytes;
167 char bom[3];
168
169 if (!directories)
170 directories = NewList();
171 assert(directories);
172
173 cname = Char(name);
174 filename = NewString(cname);
175 assert(filename);
176 if (file_debug) {
177 Printf(stdout, " Open: %s\n", filename);
178 }
179 f = fopen(Char(filename), "r");
180 if (!f && use_include_path) {
181 spath = Swig_search_path_any(sysfile);
182 ilen = Len(spath);
183 for (i = 0; i < ilen; i++) {
184 Clear(filename);
185 Printf(filename, "%s%s", Getitem(spath, i), cname);
186 f = fopen(Char(filename), "r");
187 if (f)
188 break;
189 }
190 Delete(spath);
191 }
192 if (f) {
193 Delete(lastpath);
194 lastpath = filename;
195
196 /* Skip the UTF-8 BOM if it's present */
197 nbytes = (int)fread(bom, 1, 3, f);
198 if (nbytes == 3 && bom[0] == (char)0xEF && bom[1] == (char)0xBB && bom[2] == (char)0xBF) {
199 /* skip */
200 } else {
201 fseek(f, 0, SEEK_SET);
202 }
203 }
204 return f;
205 }
206
207 /* Open a file - searching the include paths to find it */
Swig_include_open(const_String_or_char_ptr name)208 FILE *Swig_include_open(const_String_or_char_ptr name) {
209 return Swig_open_file(name, 0, 1);
210 }
211
212 /* Open a file - does not use include paths to find it */
Swig_open(const_String_or_char_ptr name)213 FILE *Swig_open(const_String_or_char_ptr name) {
214 return Swig_open_file(name, 0, 0);
215 }
216
217
218
219 /* -----------------------------------------------------------------------------
220 * Swig_read_file()
221 *
222 * Reads data from an open FILE * and returns it as a string.
223 * ----------------------------------------------------------------------------- */
224
Swig_read_file(FILE * f)225 String *Swig_read_file(FILE *f) {
226 int len;
227 char buffer[4096];
228 String *str = NewStringEmpty();
229
230 assert(str);
231 while (fgets(buffer, 4095, f)) {
232 Append(str, buffer);
233 }
234 len = Len(str);
235 /* Add a newline if not present on last line -- the preprocessor seems to
236 * rely on \n and not EOF terminating lines */
237 if (len) {
238 char *cstr = Char(str);
239 if (cstr[len - 1] != '\n') {
240 Append(str, "\n");
241 }
242 }
243 return str;
244 }
245
246 /* -----------------------------------------------------------------------------
247 * Swig_include()
248 *
249 * Opens a file and returns it as a string.
250 * ----------------------------------------------------------------------------- */
251
Swig_include_any(const_String_or_char_ptr name,int sysfile)252 static String *Swig_include_any(const_String_or_char_ptr name, int sysfile) {
253 FILE *f;
254 String *str;
255 String *file;
256
257 f = Swig_open_file(name, sysfile, 1);
258 if (!f)
259 return 0;
260 str = Swig_read_file(f);
261 fclose(f);
262 Seek(str, 0, SEEK_SET);
263 file = Copy(Swig_last_file());
264 Setfile(str, file);
265 Delete(file);
266 Setline(str, 1);
267 return str;
268 }
269
Swig_include(const_String_or_char_ptr name)270 String *Swig_include(const_String_or_char_ptr name) {
271 return Swig_include_any(name, 0);
272 }
273
Swig_include_sys(const_String_or_char_ptr name)274 String *Swig_include_sys(const_String_or_char_ptr name) {
275 return Swig_include_any(name, 1);
276 }
277
278 /* -----------------------------------------------------------------------------
279 * Swig_insert_file()
280 *
281 * Copies the contents of a file into another file
282 * ----------------------------------------------------------------------------- */
283
Swig_insert_file(const_String_or_char_ptr filename,File * outfile)284 int Swig_insert_file(const_String_or_char_ptr filename, File *outfile) {
285 char buffer[4096];
286 int nbytes;
287 FILE *f = Swig_include_open(filename);
288
289 if (!f)
290 return -1;
291 while ((nbytes = Read(f, buffer, 4096)) > 0) {
292 Write(outfile, buffer, nbytes);
293 }
294 fclose(f);
295 return 0;
296 }
297
298 /* -----------------------------------------------------------------------------
299 * Swig_register_filebyname()
300 *
301 * Register a "named" file with the core. Named files can become targets
302 * for %insert directives and other SWIG operations. This function takes
303 * the place of the f_header, f_wrapper, f_init, and other global variables
304 * in SWIG1.1
305 * ----------------------------------------------------------------------------- */
306
307 static Hash *named_files = 0;
308
Swig_register_filebyname(const_String_or_char_ptr filename,File * outfile)309 void Swig_register_filebyname(const_String_or_char_ptr filename, File *outfile) {
310 if (!named_files)
311 named_files = NewHash();
312 Setattr(named_files, filename, outfile);
313 }
314
315 /* -----------------------------------------------------------------------------
316 * Swig_filebyname()
317 *
318 * Get a named file
319 * ----------------------------------------------------------------------------- */
320
Swig_filebyname(const_String_or_char_ptr filename)321 File *Swig_filebyname(const_String_or_char_ptr filename) {
322 if (!named_files)
323 return 0;
324 return Getattr(named_files, filename);
325 }
326
327 /* -----------------------------------------------------------------------------
328 * Swig_file_extension()
329 *
330 * Returns the extension of a file
331 * ----------------------------------------------------------------------------- */
332
Swig_file_extension(const_String_or_char_ptr filename)333 String *Swig_file_extension(const_String_or_char_ptr filename) {
334 String *name = Swig_file_filename(filename);
335 const char *c = strrchr(Char(name), '.');
336 String *extension = c ? NewString(c) : NewString("");
337 Delete(name);
338 return extension;
339 }
340
341 /* -----------------------------------------------------------------------------
342 * Swig_file_basename()
343 *
344 * Returns the filename with the extension removed.
345 * ----------------------------------------------------------------------------- */
346
Swig_file_basename(const_String_or_char_ptr filename)347 String *Swig_file_basename(const_String_or_char_ptr filename) {
348 String *extension = Swig_file_extension(filename);
349 String *basename = NewStringWithSize(filename, Len(filename) - Len(extension));
350 Delete(extension);
351 return basename;
352 }
353
354 /* -----------------------------------------------------------------------------
355 * Swig_file_filename()
356 *
357 * Return the file name with any leading path stripped off
358 * ----------------------------------------------------------------------------- */
Swig_file_filename(const_String_or_char_ptr filename)359 String *Swig_file_filename(const_String_or_char_ptr filename) {
360 const char *delim = SWIG_FILE_DELIMITER;
361 const char *c = strrchr(Char(filename), *delim);
362 return c ? NewString(c + 1) : NewString(filename);
363 }
364
365 /* -----------------------------------------------------------------------------
366 * Swig_file_dirname()
367 *
368 * Return the name of the directory associated with a file
369 * ----------------------------------------------------------------------------- */
Swig_file_dirname(const_String_or_char_ptr filename)370 String *Swig_file_dirname(const_String_or_char_ptr filename) {
371 const char *delim = SWIG_FILE_DELIMITER;
372 const char *c = strrchr(Char(filename), *delim);
373 return c ? NewStringWithSize(filename, (int)(c - Char(filename) + 1)) : NewString("");
374 }
375
376 /*
377 * Swig_file_debug()
378 */
Swig_file_debug_set()379 void Swig_file_debug_set() {
380 file_debug = 1;
381 }
382