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