]>
Commit | Line | Data |
---|---|---|
c90f71dd RD |
1 | /******************************************************************************* |
2 | * Simplified Wrapper and Interface Generator (SWIG) | |
3 | * | |
4 | * Author : David Beazley | |
5 | * | |
6 | * Department of Computer Science | |
7 | * University of Chicago | |
8 | * 1100 E 58th Street | |
9 | * Chicago, IL 60637 | |
10 | * beazley@cs.uchicago.edu | |
11 | * | |
12 | * Please read the file LICENSE for the copyright and terms by which SWIG | |
13 | * can be used and distributed. | |
14 | *******************************************************************************/ | |
15 | ||
16 | #include "internal.h" | |
17 | #include <stdlib.h> | |
18 | #include <stdio.h> | |
19 | #include <ctype.h> | |
20 | ||
21 | /******************************************************************************* | |
22 | * $Header$ | |
23 | * | |
24 | * File : include.cxx | |
25 | * | |
26 | * Code for including files into a wrapper file. | |
27 | * | |
28 | *******************************************************************************/ | |
29 | ||
30 | /* Delimeter used in accessing files and directories */ | |
31 | ||
32 | #ifdef MACSWIG | |
33 | #define DELIMETER ':' | |
34 | #else | |
35 | #define DELIMETER '/' | |
36 | #endif | |
37 | ||
38 | /* Linked list containing search directories */ | |
39 | ||
40 | struct Dnode { | |
41 | char *dirname; | |
42 | Dnode *next; | |
43 | }; | |
44 | ||
45 | Dnode ihead, iz; | |
46 | int include_init = 0; | |
47 | ||
48 | /* Linked list containing included files */ | |
49 | ||
50 | struct Inode { | |
51 | char *name; | |
52 | Inode *next; | |
53 | }; | |
54 | ||
55 | Inode *include_list = 0; | |
56 | ||
57 | // ----------------------------------------------------------------------------- | |
58 | // void add_directory(char *dirname) | |
59 | // | |
60 | // Adds a directory to the SWIG search path. | |
61 | // | |
62 | // Inputs : dirname = Pathname | |
63 | // | |
64 | // Output : None | |
65 | // | |
66 | // Side Effects : Adds dirname to linked list of pathnames. | |
67 | // ----------------------------------------------------------------------------- | |
68 | ||
69 | void add_directory(char *dirname) { | |
70 | Dnode *d; | |
71 | ||
72 | if (!include_init) { | |
73 | ihead.next = &iz; | |
74 | iz.next = &iz; | |
75 | iz.dirname = new char[2]; | |
76 | iz.dirname[0] = 0; | |
77 | include_init = 1; | |
78 | } | |
79 | ||
80 | d = new Dnode; | |
81 | d->dirname = new char[strlen(dirname)+1]; | |
82 | strcpy(d->dirname,dirname); | |
83 | d->next = ihead.next; | |
84 | ihead.next = d; | |
85 | ||
86 | } | |
87 | ||
88 | // ----------------------------------------------------------------------------- | |
89 | // int add_iname(char *name) | |
90 | // | |
91 | // Adds an include file to the list of processed files. If already present, | |
92 | // returns 1. | |
93 | // | |
94 | // Inputs : name = filename | |
95 | // | |
96 | // Output : 0 on success, 1 on failure. | |
97 | // | |
98 | // Side Effects : Adds name to linked list. | |
99 | // ----------------------------------------------------------------------------- | |
100 | ||
101 | int add_iname(char *name) { | |
102 | ||
103 | Inode *newi, *i; | |
104 | ||
105 | // if (WrapExtern) return 0; // Still thinking about this patch. | |
106 | if (include_list) { | |
107 | /* Search list */ | |
108 | i = include_list; | |
109 | while (i) { | |
110 | if (strcmp(i->name, name) == 0) return 1; | |
111 | i = i->next; | |
112 | } | |
113 | } | |
114 | ||
115 | newi = new Inode; | |
116 | newi->name = new char[strlen(name)+1]; | |
117 | strcpy(newi->name, name); | |
118 | newi->next = include_list; | |
119 | include_list = newi; | |
120 | return 0; | |
121 | } | |
122 | ||
123 | // ----------------------------------------------------------------------------- | |
124 | // void check_suffix(char *name) | |
125 | // | |
126 | // Checks the suffix of an include file to see if we need to handle it | |
127 | // differently. C and C++ source files need a little extra help. | |
128 | // | |
129 | // Inputs : name = include file name. | |
130 | // | |
131 | // Output : None | |
132 | // | |
133 | // Side Effects : | |
134 | // Sets ForceExtern status variable if a C/C++ source file | |
135 | // is detected. | |
136 | // | |
137 | // ----------------------------------------------------------------------------- | |
138 | ||
139 | void check_suffix(char *name) { | |
140 | char *c; | |
141 | ||
142 | if (!name) return; | |
143 | if (strlen(name) == 0) return; | |
144 | c = name+strlen(name)-1; | |
145 | while (c != name) { | |
146 | if (*c == '.') break; | |
147 | c--; | |
148 | } | |
149 | if (c == name) return; | |
150 | ||
151 | /* Check suffixes */ | |
152 | ||
153 | if (strcmp(c,".c") == 0) { | |
154 | ForceExtern = 1; | |
155 | } else if (strcmp(c,".C") == 0) { | |
156 | ForceExtern = 1; | |
157 | } else if (strcmp(c,".cc") == 0) { | |
158 | ForceExtern = 1; | |
159 | } else if (strcmp(c,".cxx") == 0) { | |
160 | ForceExtern = 1; | |
161 | } else if (strcmp(c,".c++") == 0) { | |
162 | ForceExtern = 1; | |
163 | } else if (strcmp(c,".cpp") == 0) { | |
164 | ForceExtern = 1; | |
165 | } else { | |
166 | ForceExtern = 0; | |
167 | } | |
168 | } | |
169 | // ----------------------------------------------------------------------------- | |
170 | // int include_file(char *name) | |
171 | // | |
172 | // Includes a new SWIG wrapper file. Returns -1 if file not found. | |
173 | // | |
174 | // Inputs : name = filename | |
175 | // | |
176 | // Output : 0 on success. -1 on failure. | |
177 | // | |
178 | // Side Effects : sets scanner to read from new file. | |
179 | // ----------------------------------------------------------------------------- | |
180 | ||
181 | int include_file(char *name) { | |
182 | ||
183 | FILE *f; | |
184 | char filename[256]; | |
185 | int found = 0; | |
186 | Dnode *d; | |
187 | extern void scanner_file(FILE *); | |
188 | ||
189 | if (!include_init) return -1; // Not initialized yet | |
190 | if (add_iname(name)) { | |
191 | if (Verbose) fprintf(stderr,"file %s already included.\n", name); | |
192 | return -1; // Already included this file | |
193 | } | |
194 | ||
195 | if (Verbose) { | |
196 | fprintf(stderr,"Wrapping %s...\n", name); | |
197 | fprintf(stderr,"Looking for ./%s\n", name); | |
198 | } | |
199 | ||
200 | if ((f = fopen(name,"r")) != NULL) { | |
201 | input_file = new char[strlen(name)+1]; | |
202 | strcpy(input_file,name); | |
203 | scanner_file(f); | |
204 | check_suffix(name); | |
205 | return 0; | |
206 | } | |
207 | ||
208 | // Now start searching libraries | |
209 | ||
210 | d = ihead.next; // Start of search list | |
211 | while (d != &iz) { | |
212 | // Look for the wrap file in language directory | |
213 | sprintf(filename,"%s%c%s%c%s", d->dirname,DELIMETER,LibDir,DELIMETER,name); | |
214 | if (Verbose) fprintf(stderr,"Looking for %s\n", filename); | |
215 | if((f = fopen(filename,"r")) != NULL) { | |
216 | found = 1; | |
217 | } else { | |
218 | sprintf(filename,"%s%c%s", d->dirname, DELIMETER,name); | |
219 | if (Verbose) fprintf(stderr,"Looking for %s\n", filename); | |
220 | if ((f = fopen(filename,"r")) != NULL) { | |
221 | found = 1; | |
222 | } | |
223 | } | |
224 | if (found) { | |
225 | // Found it, open it up for input | |
226 | input_file = new char[strlen(filename)+1]; | |
227 | strcpy(input_file,filename); | |
228 | scanner_file(f); | |
229 | check_suffix(name); | |
230 | return 0; | |
231 | } | |
232 | d = d->next; | |
233 | } | |
234 | ||
235 | if (!found) fprintf(stderr,"%s : Line %d. Unable to find include file %s (ignored).\n",input_file, line_number, name); | |
236 | ||
237 | return -1; | |
238 | } | |
239 | ||
240 | ||
241 | static char buffer[1024]; | |
242 | ||
243 | // ----------------------------------------------------------------------------- | |
244 | // void copy_data(FILE *f1, FILE *f2) | |
245 | // | |
246 | // Copies data from file f1 to file f2. | |
247 | // | |
248 | // Inputs : f1 = FILE 1 | |
249 | // f2 = FILE 2 | |
250 | // | |
251 | // Output : None | |
252 | // | |
253 | // Side Effects : Closes file f1 upon exit. | |
254 | // ----------------------------------------------------------------------------- | |
255 | ||
256 | void copy_data(FILE *f1, FILE *f2) { | |
257 | ||
258 | while (fgets(buffer,1023,f1)) { | |
259 | fputs(buffer, f2); | |
260 | } | |
261 | fclose(f1); | |
262 | } | |
263 | ||
264 | // ----------------------------------------------------------------------------- | |
265 | // void copy_data(FILE *f1, String *s2) | |
266 | // | |
267 | // Copies data from file f1 to String s2. | |
268 | // | |
269 | // Inputs : f1 = FILE 1 | |
270 | // s2 = String | |
271 | // | |
272 | // Output : None | |
273 | // | |
274 | // Side Effects : Closes file f1 upon exit. | |
275 | // ----------------------------------------------------------------------------- | |
276 | ||
277 | void copy_data(FILE *f1, String &s2) { | |
278 | ||
279 | while (fgets(buffer,1023,f1)) { | |
280 | s2 << buffer; | |
281 | } | |
282 | fclose(f1); | |
283 | } | |
284 | ||
285 | // ----------------------------------------------------------------------------- | |
286 | // int insert_file(char *name, FILE *f) | |
287 | // | |
288 | // Looks for a file and inserts into file f. | |
289 | // | |
290 | // Inputs : name = filename | |
291 | // f = FILE | |
292 | // | |
293 | // Output : 0 on success, -1 on failure. | |
294 | // | |
295 | // Side Effects : None | |
296 | // ----------------------------------------------------------------------------- | |
297 | ||
298 | int insert_file(char *name, FILE *f_out) { | |
299 | ||
300 | FILE *f; | |
301 | char filename[256]; | |
302 | int found = 0; | |
303 | Dnode *d; | |
304 | ||
305 | if (!include_init) return -1; // Not initialized yet | |
306 | if (add_iname(name)) { | |
307 | if (Verbose) fprintf(stderr,"file %s already included.\n", name); | |
308 | return -1; // Already included this file | |
309 | } | |
310 | ||
311 | if (Verbose) fprintf(stderr,"Looking for ./%s\n", name); | |
312 | if ((f = fopen(name,"r")) != NULL) { | |
313 | copy_data(f,f_out); | |
314 | return 0; | |
315 | } | |
316 | ||
317 | // Now start searching libraries | |
318 | ||
319 | d = ihead.next; // Start of search list | |
320 | while (d != &iz) { | |
321 | // Look for the wrap file in language directory | |
322 | sprintf(filename,"%s%c%s%c%s", d->dirname,DELIMETER,LibDir,DELIMETER,name); | |
323 | if (Verbose) fprintf(stderr,"Looking for %s\n", filename); | |
324 | if((f = fopen(filename,"r")) != NULL) { | |
325 | found = 1; | |
326 | } else { | |
327 | sprintf(filename,"%s%c%s", d->dirname, DELIMETER, name); | |
328 | if (Verbose) fprintf(stderr,"Looking for %s\n", filename); | |
329 | if ((f = fopen(filename,"r")) != NULL) { | |
330 | found = 1; | |
331 | } | |
332 | } | |
333 | if (found) { | |
334 | copy_data(f,f_out); | |
335 | return 0; | |
336 | } | |
337 | d = d->next; | |
338 | } | |
339 | ||
340 | if ((!found) && (Verbose)) fprintf(stderr,"unable to find %s. (Ignored)\n",name); | |
341 | return -1; | |
342 | } | |
343 | ||
344 | // ----------------------------------------------------------------------------- | |
345 | // void swig_append(char *filename, FILE *f) | |
346 | // | |
347 | // Appends the contents of filename to stream f. | |
348 | // | |
349 | // Inputs : | |
350 | // filename = File to append | |
351 | // f = FILE handle | |
352 | // | |
353 | // Output : None | |
354 | // | |
355 | // Side Effects : None | |
356 | // ----------------------------------------------------------------------------- | |
357 | ||
358 | void swig_append(char *filename, FILE *f) { | |
359 | ||
360 | FILE *in_file; | |
361 | ||
362 | if ((in_file = fopen(filename,"r")) == NULL) { | |
363 | fprintf(stderr,"** SWIG ERROR ** file %s not found.\n",filename); | |
364 | FatalError(); | |
365 | return; | |
366 | } | |
367 | while (fgets(buffer,1023,in_file)) { | |
368 | fputs(buffer, f); | |
369 | } | |
370 | fclose(in_file); | |
371 | } | |
372 | ||
373 | ||
374 | // ----------------------------------------------------------------------------- | |
375 | // int get_file(char *name, String &str) | |
376 | // | |
377 | // Looks for a file and converts it into a String. | |
378 | // | |
379 | // Inputs : name = filename | |
380 | // str = String | |
381 | // | |
382 | // Output : 0 on success, -1 on failure. | |
383 | // | |
384 | // Side Effects : None | |
385 | // ----------------------------------------------------------------------------- | |
386 | ||
387 | int get_file(char *name, String &str) { | |
388 | ||
389 | FILE *f; | |
390 | char filename[256]; | |
391 | int found = 0; | |
392 | Dnode *d; | |
393 | ||
394 | if (!include_init) return -1; // Not initialized yet | |
395 | ||
396 | if (Verbose) fprintf(stderr,"Looking for %s\n", name); | |
397 | if ((f = fopen(name,"r")) != NULL) { | |
398 | copy_data(f,str); | |
399 | return 0; | |
400 | } | |
401 | ||
402 | // Now start searching libraries | |
403 | ||
404 | d = ihead.next; // Start of search list | |
405 | while (d != &iz) { | |
406 | // Look for the wrap file in language directory | |
407 | sprintf(filename,"%s%c%s%c%s", d->dirname,DELIMETER,LibDir,DELIMETER,name); | |
408 | if (Verbose) fprintf(stderr,"Looking for %s\n", filename); | |
409 | if((f = fopen(filename,"r")) != NULL) { | |
410 | found = 1; | |
411 | } else { | |
412 | sprintf(filename,"%s%c%s", d->dirname, DELIMETER, name); | |
413 | if (Verbose) fprintf(stderr,"Looking for %s\n", filename); | |
414 | if ((f = fopen(filename,"r")) != NULL) { | |
415 | found = 1; | |
416 | } | |
417 | } | |
418 | if (found) { | |
419 | copy_data(f,str); | |
420 | return 0; | |
421 | } | |
422 | d = d->next; | |
423 | } | |
424 | ||
425 | if ((!found)) fprintf(stderr,"SWIG Error. Unable to find %s. Possible installation problem.\n",name); | |
426 | FatalError(); | |
427 | return -1; | |
428 | } | |
429 | ||
430 | static char *libs[1000]; | |
431 | static int nlibs = 0; | |
432 | ||
433 | // ----------------------------------------------------------------------------- | |
434 | // void library_add(char *name) | |
435 | // | |
436 | // Adds a filename to the list of libraries. This is usually only called by | |
437 | // the SWIG main program. | |
438 | // | |
439 | // Inputs : name = library name | |
440 | // | |
441 | // Outputs: None | |
442 | // | |
443 | // Side Effects : Adds the library name to the libs array above | |
444 | // ----------------------------------------------------------------------------- | |
445 | ||
446 | void library_add(char *name) { | |
447 | int i; | |
448 | ||
449 | // Check to make sure it's not already added | |
450 | ||
451 | if (!(*name)) return; | |
452 | ||
453 | for (i = 0; i < nlibs; i++) { | |
454 | if (strcmp(libs[i],name) == 0) return; | |
455 | } | |
456 | ||
457 | libs[nlibs] = copy_string(name); | |
458 | nlibs++; | |
459 | } | |
460 | ||
461 | // ----------------------------------------------------------------------------- | |
462 | // void library_insert() | |
463 | // | |
464 | // Starts parsing all of the SWIG library files. | |
465 | // | |
466 | // Inputs : None | |
467 | // | |
468 | // Output : None | |
469 | // | |
470 | // Side Effects : Opens and attaches all of the specified library files to | |
471 | // the scanner. | |
472 | // | |
473 | // Bugs : Opens all of the files. Will fail if there are too many open files. | |
474 | // | |
475 | // ----------------------------------------------------------------------------- | |
476 | ||
477 | void library_insert() { | |
478 | int i; | |
479 | ||
480 | i = nlibs-1; | |
481 | while (i >= 0) { | |
482 | include_file(libs[i]); | |
483 | i--; | |
484 | } | |
485 | } | |
486 | ||
487 | // ----------------------------------------------------------------------------- | |
488 | // int checkout(char *filename,char *dest) | |
489 | // | |
490 | // Tries to check a file out of the SWIG library. If found, it will save it in | |
491 | // the current directory. This is a useful mechanism for using SWIG as a code | |
492 | // manager and for extracting library files. | |
493 | // | |
494 | // Inputs : filename = Library file | |
495 | // dest = Destination file | |
496 | // | |
497 | // Output : 0 on success | |
498 | // -1 on failure. | |
499 | // | |
500 | // Side Effects : None | |
501 | // ----------------------------------------------------------------------------- | |
502 | ||
503 | int checkout_file(char *filename,char *dest) { | |
504 | ||
505 | FILE *f1; | |
506 | char tempn[256]; | |
507 | ||
508 | // First check to see if the file already exists in current directory | |
509 | f1 = fopen(dest,"r"); | |
510 | if (f1) { | |
511 | if (Verbose) | |
512 | fprintf(stderr,"Warning. Unable to check-out %s. File already exists.\n", filename); | |
513 | fclose(f1); | |
514 | return -1; | |
515 | } | |
516 | ||
517 | while (!f1) { | |
518 | sprintf(tempn,"%s%d",dest,rand()); | |
519 | f1 = fopen(tempn,"r"); | |
520 | if (f1) { | |
521 | fclose(f1); | |
522 | f1 = 0; | |
523 | } else { | |
524 | f1 = fopen(tempn,"w"); | |
525 | if (!f1) { | |
526 | fprintf(stderr,"Unable to open %s for writing\n", tempn); | |
527 | return -1; | |
528 | } | |
529 | } | |
530 | } | |
531 | ||
532 | // Now try to insert the library file into the destination file | |
533 | if ((insert_file(filename,f1)) == -1) { | |
534 | fprintf(stderr,"Unable to check-out '%s'. File does not exist in SWIG library.\n",filename); | |
535 | fclose(f1); | |
536 | remove(tempn); // Unsuccessful, remove file we created | |
537 | return -1; | |
538 | } | |
539 | fclose(f1); | |
540 | // Now move the file | |
541 | rename(tempn,dest); | |
542 | return 0; | |
543 | } | |
544 | ||
545 | ||
546 | // ----------------------------------------------------------------------------- | |
547 | // int checkin_file(char *dir, char *lang, char *source,char *dest) | |
548 | // | |
549 | // Attempts to check a file into the SWIG library. | |
550 | // | |
551 | // Inputs : dir = Location of the SWIG library. | |
552 | // lang = Language specific subdirectory. | |
553 | // source = Source file. | |
554 | // dest = Destination file. | |
555 | // | |
556 | // Output : 0 on success | |
557 | // -1 on failure. | |
558 | // | |
559 | // Side Effects : None | |
560 | // ----------------------------------------------------------------------------- | |
561 | ||
562 | int checkin_file(char *dir, char *lang, char *source, char *dest) { | |
563 | ||
564 | FILE *f1; | |
565 | char tempn[256]; | |
566 | String s; | |
567 | ||
568 | // First check to see if the file exists | |
569 | ||
570 | f1 = fopen(source,"r"); | |
571 | if (!f1) return -1; | |
572 | ||
573 | copy_data(f1,s); | |
574 | ||
575 | // Now try to open the destination file | |
576 | sprintf(tempn,"%s/%s/%s", dir,lang,dest); | |
577 | f1 = fopen(tempn,"w"); | |
578 | if (!f1) return -1; | |
579 | fprintf(f1,"%s",s.get()); | |
580 | fclose(f1); | |
581 | return 0; | |
582 | } | |
583 | ||
584 | ||
585 | ||
586 |