]> git.saurik.com Git - wxWidgets.git/blob - wxPython/wxSWIG/SWIG/main.cxx
Since I have made several changes to SWIG over the years to accomodate
[wxWidgets.git] / wxPython / wxSWIG / SWIG / main.cxx
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 * $Header$
17 *
18 * main.cxx
19 *
20 * The main program.
21 *
22 ***********************************************************************/
23
24 #define WRAP
25
26 #include "internal.h"
27 #include "ascii.h"
28 #include "latex.h"
29 #include "html.h"
30 #include "nodoc.h"
31 #include <time.h>
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <ctype.h>
35
36 class SwigException {};
37
38 static char *usage = "\
39 \nDocumentation Options\n\
40 -dascii - ASCII documentation.\n\
41 -dhtml - HTML documentation.\n\
42 -dlatex - LaTeX documentation.\n\
43 -dnone - No documentation.\n\n\
44 General Options\n\
45 -c - Produce raw wrapper code (omit support code)\n\
46 -c++ - Enable C++ processing\n\
47 -ci - Check a file into the SWIG library\n\
48 -co - Check a file out of the SWIG library\n\
49 -d docfile - Set name of the documentation file.\n\
50 -Dsymbol - Define a symbol (for conditional compilation)\n\
51 -I<dir> - Look for SWIG files in <dir>\n\
52 -l<ifile> - Include SWIG library file.\n\
53 -make_default - Create default constructors/destructors\n\
54 -nocomment - Ignore all comments (for documentation).\n\
55 -o outfile - Set name of the output file.\n\
56 -objc - Enable Objective C processing\n\
57 -stat - Print statistics\n\
58 -strict n - Set pointer type-checking strictness\n\
59 -swiglib - Report location of SWIG library and exit\n\
60 -t typemap_file - Use a typemap file.\n\
61 -v - Run in verbose mode\n\
62 -version - Print SWIG version number\n\
63 -help - This output.\n\n";
64
65 //-----------------------------------------------------------------
66 // main()
67 //
68 // Main program. Initializes the files and starts the parser.
69 //-----------------------------------------------------------------
70
71 char infilename[256];
72 char filename[256];
73 char fn_header[256];
74 char fn_wrapper[256];
75 char fn_init[256];
76 char output_dir[512];
77
78 #ifdef MACSWIG
79 FILE *swig_log;
80 #endif
81
82 char *SwigLib;
83
84 //char** __argv;
85 //int __argc;
86
87 int SWIG_main(int argc, char *argv[], Language *l, Documentation *d) {
88
89 int i;
90 char *c;
91 extern FILE *LEX_in;
92 extern void add_directory(char *);
93 extern char *get_time();
94 char temp[512];
95 char infile[512];
96
97 char *outfile_name = 0;
98 extern int add_iname(char *);
99 int help = 0;
100 int ignorecomments = 0;
101 int checkout = 0;
102 int checkin = 0;
103 char *typemap_file = 0;
104 char *includefiles[256];
105 int includecount = 0;
106 extern void check_suffix(char *);
107 extern void scanner_file(FILE *);
108
109 #ifdef MACSWIG
110 try {
111 #endif
112
113 f_wrappers = 0;
114 f_init = 0;
115 f_header = 0;
116
117 //__argc = argc;
118 //__argv = argv;
119 lang = l;
120 doc = d;
121 Status = 0;
122 TypeStrict = 2; // Very strict type checking
123 Verbose = 0;
124 char *doc_file = 0;
125
126 DataType::init_typedef(); // Initialize the type handler
127
128 // Set up some default symbols (available in both SWIG interface files
129 // and C files)
130
131 add_symbol("SWIG",0,0); // Define the SWIG symbol
132 #ifdef MACSWIG
133 add_symbol("SWIGMAC",0,0);
134 #endif
135 #ifdef SWIGWIN32
136 add_symbol("SWIGWIN32",0,0);
137 #endif
138
139 strcpy(LibDir, getSwigLib());
140 SwigLib = copy_string(LibDir); // Make a copy of the real library location
141 #ifdef MACSWIG
142 sprintf(temp,"%s:config", LibDir);
143 add_directory(temp);
144 add_directory(":swig_lib:config");
145 add_directory(LibDir);
146 add_directory(":swig_lib");
147 #else
148 sprintf(temp,"%s/config", LibDir);
149 add_directory(temp);
150 add_directory("./swig_lib/config");
151 add_directory(LibDir);
152 add_directory("./swig_lib");
153 sprintf(InitName,"init_wrap");
154 #endif
155
156 sprintf(InitName,"init_wrap");
157
158 // Get options
159 for (i = 1; i < argc; i++) {
160 if (argv[i]) {
161 if (strncmp(argv[i],"-I",2) == 0) {
162 // Add a new directory search path
163 includefiles[includecount++] = copy_string(argv[i]+2);
164 mark_arg(i);
165 } else if (strncmp(argv[i],"-D",2) == 0) {
166 // Create a symbol
167 add_symbol(argv[i]+2, (DataType *) 0, (char *) 0);
168 mark_arg(i);
169 } else if (strcmp(argv[i],"-strict") == 0) {
170 if (argv[i+1]) {
171 TypeStrict = atoi(argv[i+1]);
172 mark_arg(i);
173 mark_arg(i+1);
174 i++;
175 } else {
176 arg_error();
177 }
178 } else if ((strcmp(argv[i],"-verbose") == 0) || (strcmp(argv[i],"-v") == 0)) {
179 Verbose = 1;
180 mark_arg(i);
181 } else if (strcmp(argv[i],"-dascii") == 0) {
182 doc = new ASCII;
183 mark_arg(i);
184 } else if (strcmp(argv[i],"-dnone") == 0) {
185 doc = new NODOC;
186 mark_arg(i);
187 } else if (strcmp(argv[i],"-dhtml") == 0) {
188 doc = new HTML;
189 mark_arg(i);
190 } else if (strcmp(argv[i],"-dlatex") == 0) {
191 doc = new LATEX;
192 mark_arg(i);
193 } else if (strcmp(argv[i],"-nocomment") == 0) {
194 ignorecomments = 1;
195 mark_arg(i);
196 } else if (strcmp(argv[i],"-stat") == 0) {
197 Stats=1;
198 mark_arg(i);
199 } else if (strcmp(argv[i],"-c++") == 0) {
200 CPlusPlus=1;
201 mark_arg(i);
202 } else if (strcmp(argv[i],"-objc") == 0) {
203 ObjC = 1;
204 mark_arg(i);
205 } else if (strcmp(argv[i],"-c") == 0) {
206 NoInclude=1;
207 mark_arg(i);
208 } else if (strcmp(argv[i],"-make_default") == 0) {
209 GenerateDefault = 1;
210 mark_arg(i);
211 } else if (strcmp(argv[i],"-swiglib") == 0) {
212 printf("%s\n", LibDir);
213 SWIG_exit(0);
214 } else if (strcmp(argv[i],"-o") == 0) {
215 mark_arg(i);
216 if (argv[i+1]) {
217 outfile_name = copy_string(argv[i+1]);
218 mark_arg(i+1);
219 i++;
220 } else {
221 arg_error();
222 }
223 } else if (strcmp(argv[i],"-d") == 0) {
224 mark_arg(i);
225 if (argv[i+1]) {
226 doc_file = copy_string(argv[i+1]);
227 mark_arg(i+1);
228 i++;
229 } else {
230 arg_error();
231 }
232 } else if (strcmp(argv[i],"-t") == 0) {
233 mark_arg(i);
234 if (argv[i+1]) {
235 typemap_file = copy_string(argv[i+1]);
236 mark_arg(i+1);
237 i++;
238 } else {
239 arg_error();
240 }
241 } else if (strcmp(argv[i],"-version") == 0) {
242 fprintf(stderr,"\nSWIG Version %d.%d %s\n", SWIG_MAJOR_VERSION,
243 SWIG_MINOR_VERSION, SWIG_SPIN);
244 fprintf(stderr,"Copyright (c) 1995-98\n");
245 fprintf(stderr,"University of Utah and the Regents of the University of California\n");
246 fprintf(stderr,"\nCompiled with %s\n", SWIG_CC);
247 SWIG_exit(0);
248 } else if (strncmp(argv[i],"-l",2) == 0) {
249 // Add a new directory search path
250 library_add(argv[i]+2);
251 mark_arg(i);
252 } else if (strcmp(argv[i],"-co") == 0) {
253 checkout = 1;
254 mark_arg(i);
255 } else if (strcmp(argv[i],"-ci") == 0) {
256 checkin = 1;
257 mark_arg(i);
258 } else if (strcmp(argv[i],"-help") == 0) {
259 fputs(usage,stderr);
260 mark_arg(i);
261 help = 1;
262 }
263 }
264 }
265
266 while (includecount > 0) {
267 add_directory(includefiles[--includecount]);
268 }
269
270 // Create a new documentation handler
271
272 if (doc == 0) doc = new ASCII;
273
274 // Open up a comment handler
275
276 comment_handler = new CommentHandler();
277 comment_handler->parse_args(argc,argv);
278 if (ignorecomments) comment_handler->style("ignore",0);
279
280 // Create a new documentation entry
281
282 doctitle = new DocTitle("",0);
283 doctitle->parse_args(argc,argv);
284 doc_entry = doctitle;
285
286 // Handle documentation module options
287
288 doc->parse_args(argc,argv);
289
290 // Parse language dependent options
291
292 lang->parse_args(argc,argv);
293
294 if (help) SWIG_exit(0); // Exit if we're in help mode
295
296 // Check all of the options to make sure we're cool.
297
298 check_options();
299
300 // If we made it this far, looks good. go for it....
301
302 // Create names of temporary files that are created
303
304 sprintf(infilename,"%s", argv[argc-1]);
305 input_file = new char[strlen(infilename)+1];
306 strcpy(input_file, infilename);
307
308 // If the user has requested to check out a file, handle that
309
310 if (checkout) {
311 int stat;
312 char *outfile = input_file;
313 if (outfile_name)
314 outfile = outfile_name;
315 stat = checkout_file(input_file,outfile);
316 if (!stat) {
317 fprintf(stderr,"%s checked out from the SWIG library\n",input_file);
318 } else {
319 FILE * f = fopen(input_file,"r");
320 if (f) {
321 fprintf(stderr,"Unable to check-out %s. File already exists.\n", input_file);
322 fclose(f);
323 } else {
324 fprintf(stderr,"Unable to check-out %s\n", input_file);
325 }
326 }
327 } else if (checkin) {
328 // Try to check-in a file to the SWIG library
329 int stat;
330 char *outname = input_file;
331 if (outfile_name)
332 outname = outfile_name;
333 stat = checkin_file(SwigLib, LibDir, input_file, outname);
334 if (!stat) {
335 fprintf(stderr,"%s checked-in to %s/%s/%s\n", input_file, SwigLib, LibDir, outname);
336 } else {
337 fprintf(stderr,"Unable to check-in %s to %s/%s\n", input_file, SwigLib, LibDir);
338 }
339 } else {
340 doctitle->file = copy_string(input_file);
341 doctitle->line_number = -1000;
342 doctitle->end_line = -1000;
343
344 // Check the suffix for a .c file. If so, we're going to
345 // declare everything we see as "extern"
346
347 check_suffix(infilename);
348
349 // Strip off suffix
350
351 c = infilename + strlen(infilename);
352 while (c != infilename) {
353 if (*c == '.') {
354 *c = 0;
355 break;
356 } else {
357 c--;
358 }
359 }
360
361 if (!outfile_name) {
362 sprintf(fn_header,"%s_wrap.c",infilename);
363 strcpy(infile,infilename);
364 strcpy(output_dir,"");
365 } else {
366 sprintf(fn_header,"%s",outfile_name);
367 // Try to identify the output directory
368 char *cc = outfile_name;
369 char *lastc = outfile_name;
370 while (*cc) {
371 #ifdef MACSWIG
372 if (*cc == ':') lastc = cc+1;
373 #else
374 if (*cc == '/') lastc = cc+1;
375 #endif
376 cc++;
377 }
378 cc = outfile_name;
379 char *dd = output_dir;
380 while (cc != lastc) {
381 *dd = *cc;
382 dd++;
383 cc++;
384 }
385 *dd = 0;
386 // Patch up the input filename
387 cc = infilename + strlen(infilename);
388 while (cc != infilename) {
389 #ifdef MACSWIG
390 if (*cc == ':') {
391 cc++;
392 break;
393 }
394 #else
395 if (*cc == '/') {
396 cc++;
397 break;
398 }
399 #endif
400 cc--;
401 }
402 strcpy(infile,cc);
403 }
404
405 sprintf(fn_wrapper,"%s%s_wrap.wrap",output_dir,infile);
406 sprintf(fn_init,"%s%s_wrap.init",output_dir,infile);
407
408 sprintf(title,"%s", fn_header);
409
410 // Open up files
411
412 if ((f_input = fopen(input_file,"r")) == 0) {
413 // Okay. File wasn't found right away. Let's see if we can
414 // extract it from the SWIG library instead.
415 if ((checkout_file(input_file,input_file)) == -1) {
416 fprintf(stderr,"Unable to open %s\n", input_file);
417 SWIG_exit(0);
418 } else {
419 // Successfully checked out a file from the library, print a warning and
420 // continue
421 checkout = 1;
422 fprintf(stderr,"%s checked out from the SWIG library.\n",input_file);
423 if ((f_input = fopen(input_file,"r")) == 0) {
424 fprintf(stderr,"Unable to open %s\n", input_file);
425 SWIG_exit(0);
426 }
427 }
428 }
429
430 // Add to the include list
431
432 add_iname(infilename);
433
434 // Initialize the scanner
435
436 LEX_in = f_input;
437 scanner_file(LEX_in);
438
439 // printf("fn_header = %s\n", fn_header);
440 // printf("fn_wrapper = %s\n", fn_wrapper);
441 // printf("fn_init = %s\n", fn_init);
442
443 if((f_header = fopen(fn_header,"w")) == 0) {
444 fprintf(stderr,"Unable to open %s\n", fn_header);
445 exit(0);
446 }
447 if((f_wrappers = fopen(fn_wrapper,"w")) == 0) {
448 fprintf(stderr,"Unable to open %s\n",fn_wrapper);
449 exit(0);
450 }
451 if ((f_init = fopen(fn_init,"w")) == 0) {
452 fprintf(stderr,"Unable to open %s\n",fn_init);
453 exit(0);
454 }
455
456 // Open up documentation
457
458 if (doc_file) {
459 doc->init(doc_file);
460 } else {
461 doc_file = new char[strlen(infile)+strlen(output_dir)+8];
462 sprintf(doc_file,"%s%s_wrap",output_dir,infile);
463 doc->init(doc_file);
464 }
465
466 // Set up the typemap for handling new return strings
467 {
468 DataType *temp_t = new DataType(T_CHAR);
469 temp_t->is_pointer++;
470 if (CPlusPlus)
471 typemap_register("newfree",typemap_lang,temp_t,"","delete [] $source;\n",0);
472 else
473 typemap_register("newfree",typemap_lang,temp_t,"","free($source);\n",0);
474
475 delete temp_t;
476 }
477
478 // Define the __cplusplus symbol
479 if (CPlusPlus)
480 add_symbol("__cplusplus",0,0);
481
482
483 // Load up the typemap file if given
484
485 if (typemap_file) {
486 if (include_file(typemap_file) == -1) {
487 fprintf(stderr,"Unable to locate typemap file %s. Aborting.\n", typemap_file);
488 SWIG_exit(1);
489 }
490 }
491
492 // If in Objective-C mode. Load in a configuration file
493
494 if (ObjC) {
495 // Add the 'id' object type as a void *
496 /* DataType *t = new DataType(T_VOID);
497 t->is_pointer = 1;
498 t->implicit_ptr = 0;
499 t->typedef_add("id");
500 delete t;
501 */
502 }
503
504 // Pass control over to the specific language interpreter
505
506 lang->parse();
507
508 fclose(f_wrappers);
509 fclose(f_init);
510
511 swig_append(fn_wrapper,f_header);
512 swig_append(fn_init,f_header);
513
514 fclose(f_header);
515
516 // Print out documentation. Due to tree-like nature of documentation,
517 // printing out the title prints out everything.
518
519 while(doctitle) {
520 doctitle->output(doc);
521 doctitle = doctitle->next;
522 }
523
524 doc->close();
525
526 // Remove temporary files
527
528 remove(fn_wrapper);
529 remove(fn_init);
530
531 // If only producing documentation, remove the wrapper file as well
532
533 if (DocOnly)
534 remove(fn_header);
535
536 // Check for undefined types that were used.
537
538 if (Verbose)
539 type_undefined_check();
540
541 if (Stats) {
542 fprintf(stderr,"Wrapped %d functions\n", Stat_func);
543 fprintf(stderr,"Wrapped %d variables\n", Stat_var);
544 fprintf(stderr,"Wrapped %d constants\n", Stat_const);
545 type_undefined_check();
546 }
547
548 if (checkout) {
549 // File was checked out from the SWIG library. Remove it now
550 remove(input_file);
551 }
552 }
553 #ifdef MACSWIG
554 fclose(swig_log);
555 } catch (SwigException) {
556 fclose(swig_log);
557 }
558 #else
559 exit(error_count);
560 #endif
561 return(error_count);
562 }
563
564 // --------------------------------------------------------------------------
565 // SWIG_exit()
566 //
567 // Fatal parser error. Exit and cleanup
568 // --------------------------------------------------------------------------
569
570 void SWIG_exit(int) {
571
572 if (f_wrappers) {
573 fclose(f_wrappers);
574 remove(fn_wrapper);
575 }
576 if (f_header) {
577 fclose(f_header);
578 remove(fn_header);
579 }
580 if (f_init) {
581 fclose(f_init);
582 remove(fn_init);
583 }
584 #ifndef MACSWIG
585 exit(1);
586 #else
587 throw SwigException();
588 #endif
589 }
590
591
592 // --------------------------------------------------------------------------
593 // swig_pragma(char *name, char *value)
594 //
595 // Handle pragma directives. Not many supported right now
596 // --------------------------------------------------------------------------
597
598 void swig_pragma(char *name, char *value) {
599
600 if (strcmp(name,"make_default") == 0) {
601 GenerateDefault = 1;
602 }
603 if (strcmp(name,"no_default") == 0) {
604 GenerateDefault = 0;
605 }
606 if (strcmp(name,"objc_new") == 0) {
607 objc_construct = copy_string(value);
608 }
609 if (strcmp(name,"objc_delete") == 0) {
610 objc_destruct = copy_string(value);
611 }
612 }
613
614
615
616 char* getSwigLib() {
617 char* c;
618 char* rv;
619
620 // Check for SWIG_LIB environment variable
621 if ((c = getenv("SWIG_LIB")) != (char *) 0) {
622 rv = c;
623 } else {
624 #ifdef SWIG_LIB
625 rv = SWIG_LIB;
626 #else
627 // use executable location
628 static char path[256];
629 char* last;
630 strcpy(path, __argv[0]);
631 last = strrchr(path, '/');
632 if (! last) last = strrchr(path, '\\');
633 if (last)
634 strcpy(last+1, "swig_lib");
635 else
636 strcpy(path, "swig_lib");
637 rv = path;
638 #endif
639 }
640 printf("Using swig lib at: %s\n", rv);
641 return rv;
642 }
643