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 12char cvsroot_include_c[] = "$Id: include.c 11080 2009-01-24 13:15:51Z bhy $"; 13 14#include "swig.h" 15 16static List *directories = 0; /* List of include directories */ 17static String *lastpath = 0; /* Last file that was included */ 18static List *pdirectories = 0; /* List of pushed directories */ 19static int dopush = 1; /* Whether to push directories */ 20 21/* This functions determine whether to push/pop dirs in the preprocessor */ 22void Swig_set_push_dir(int push) { 23 dopush = push; 24} 25 26int 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 36List *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 56void 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 76void 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 90String *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 101static 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 145List *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 158static 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 */ 194FILE *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 */ 199FILE *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 211String *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 236static 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 254String *Swig_include(const_String_or_char_ptr name) { 255 return Swig_include_any(name, 0); 256} 257 258String *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 268int 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 290static Hash *named_files = 0; 291 292void 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 304File *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 316char *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 338char *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 * ----------------------------------------------------------------------------- */ 352char *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 * ----------------------------------------------------------------------------- */ 370char *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} 384