c90f71dd8c
special cases and other things in wxPython, and since I plan on making several more, I've decided to put the SWIG sources in wxPython's CVS instead of relying on maintaining patches. This effectivly becomes a fork of an obsolete version of SWIG, :-( but since SWIG 1.3 still doesn't have some things I rely on in 1.1, not to mention that my custom patches would all have to be redone, I felt that this is the easier road to take. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@15307 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
587 lines
14 KiB
C++
587 lines
14 KiB
C++
/*******************************************************************************
|
|
* Simplified Wrapper and Interface Generator (SWIG)
|
|
*
|
|
* Author : David Beazley
|
|
*
|
|
* Department of Computer Science
|
|
* University of Chicago
|
|
* 1100 E 58th Street
|
|
* Chicago, IL 60637
|
|
* beazley@cs.uchicago.edu
|
|
*
|
|
* Please read the file LICENSE for the copyright and terms by which SWIG
|
|
* can be used and distributed.
|
|
*******************************************************************************/
|
|
|
|
#include "internal.h"
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <ctype.h>
|
|
|
|
/*******************************************************************************
|
|
* $Header$
|
|
*
|
|
* File : include.cxx
|
|
*
|
|
* Code for including files into a wrapper file.
|
|
*
|
|
*******************************************************************************/
|
|
|
|
/* Delimeter used in accessing files and directories */
|
|
|
|
#ifdef MACSWIG
|
|
#define DELIMETER ':'
|
|
#else
|
|
#define DELIMETER '/'
|
|
#endif
|
|
|
|
/* Linked list containing search directories */
|
|
|
|
struct Dnode {
|
|
char *dirname;
|
|
Dnode *next;
|
|
};
|
|
|
|
Dnode ihead, iz;
|
|
int include_init = 0;
|
|
|
|
/* Linked list containing included files */
|
|
|
|
struct Inode {
|
|
char *name;
|
|
Inode *next;
|
|
};
|
|
|
|
Inode *include_list = 0;
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// void add_directory(char *dirname)
|
|
//
|
|
// Adds a directory to the SWIG search path.
|
|
//
|
|
// Inputs : dirname = Pathname
|
|
//
|
|
// Output : None
|
|
//
|
|
// Side Effects : Adds dirname to linked list of pathnames.
|
|
// -----------------------------------------------------------------------------
|
|
|
|
void add_directory(char *dirname) {
|
|
Dnode *d;
|
|
|
|
if (!include_init) {
|
|
ihead.next = &iz;
|
|
iz.next = &iz;
|
|
iz.dirname = new char[2];
|
|
iz.dirname[0] = 0;
|
|
include_init = 1;
|
|
}
|
|
|
|
d = new Dnode;
|
|
d->dirname = new char[strlen(dirname)+1];
|
|
strcpy(d->dirname,dirname);
|
|
d->next = ihead.next;
|
|
ihead.next = d;
|
|
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// int add_iname(char *name)
|
|
//
|
|
// Adds an include file to the list of processed files. If already present,
|
|
// returns 1.
|
|
//
|
|
// Inputs : name = filename
|
|
//
|
|
// Output : 0 on success, 1 on failure.
|
|
//
|
|
// Side Effects : Adds name to linked list.
|
|
// -----------------------------------------------------------------------------
|
|
|
|
int add_iname(char *name) {
|
|
|
|
Inode *newi, *i;
|
|
|
|
// if (WrapExtern) return 0; // Still thinking about this patch.
|
|
if (include_list) {
|
|
/* Search list */
|
|
i = include_list;
|
|
while (i) {
|
|
if (strcmp(i->name, name) == 0) return 1;
|
|
i = i->next;
|
|
}
|
|
}
|
|
|
|
newi = new Inode;
|
|
newi->name = new char[strlen(name)+1];
|
|
strcpy(newi->name, name);
|
|
newi->next = include_list;
|
|
include_list = newi;
|
|
return 0;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// void check_suffix(char *name)
|
|
//
|
|
// Checks the suffix of an include file to see if we need to handle it
|
|
// differently. C and C++ source files need a little extra help.
|
|
//
|
|
// Inputs : name = include file name.
|
|
//
|
|
// Output : None
|
|
//
|
|
// Side Effects :
|
|
// Sets ForceExtern status variable if a C/C++ source file
|
|
// is detected.
|
|
//
|
|
// -----------------------------------------------------------------------------
|
|
|
|
void check_suffix(char *name) {
|
|
char *c;
|
|
|
|
if (!name) return;
|
|
if (strlen(name) == 0) return;
|
|
c = name+strlen(name)-1;
|
|
while (c != name) {
|
|
if (*c == '.') break;
|
|
c--;
|
|
}
|
|
if (c == name) return;
|
|
|
|
/* Check suffixes */
|
|
|
|
if (strcmp(c,".c") == 0) {
|
|
ForceExtern = 1;
|
|
} else if (strcmp(c,".C") == 0) {
|
|
ForceExtern = 1;
|
|
} else if (strcmp(c,".cc") == 0) {
|
|
ForceExtern = 1;
|
|
} else if (strcmp(c,".cxx") == 0) {
|
|
ForceExtern = 1;
|
|
} else if (strcmp(c,".c++") == 0) {
|
|
ForceExtern = 1;
|
|
} else if (strcmp(c,".cpp") == 0) {
|
|
ForceExtern = 1;
|
|
} else {
|
|
ForceExtern = 0;
|
|
}
|
|
}
|
|
// -----------------------------------------------------------------------------
|
|
// int include_file(char *name)
|
|
//
|
|
// Includes a new SWIG wrapper file. Returns -1 if file not found.
|
|
//
|
|
// Inputs : name = filename
|
|
//
|
|
// Output : 0 on success. -1 on failure.
|
|
//
|
|
// Side Effects : sets scanner to read from new file.
|
|
// -----------------------------------------------------------------------------
|
|
|
|
int include_file(char *name) {
|
|
|
|
FILE *f;
|
|
char filename[256];
|
|
int found = 0;
|
|
Dnode *d;
|
|
extern void scanner_file(FILE *);
|
|
|
|
if (!include_init) return -1; // Not initialized yet
|
|
if (add_iname(name)) {
|
|
if (Verbose) fprintf(stderr,"file %s already included.\n", name);
|
|
return -1; // Already included this file
|
|
}
|
|
|
|
if (Verbose) {
|
|
fprintf(stderr,"Wrapping %s...\n", name);
|
|
fprintf(stderr,"Looking for ./%s\n", name);
|
|
}
|
|
|
|
if ((f = fopen(name,"r")) != NULL) {
|
|
input_file = new char[strlen(name)+1];
|
|
strcpy(input_file,name);
|
|
scanner_file(f);
|
|
check_suffix(name);
|
|
return 0;
|
|
}
|
|
|
|
// Now start searching libraries
|
|
|
|
d = ihead.next; // Start of search list
|
|
while (d != &iz) {
|
|
// Look for the wrap file in language directory
|
|
sprintf(filename,"%s%c%s%c%s", d->dirname,DELIMETER,LibDir,DELIMETER,name);
|
|
if (Verbose) fprintf(stderr,"Looking for %s\n", filename);
|
|
if((f = fopen(filename,"r")) != NULL) {
|
|
found = 1;
|
|
} else {
|
|
sprintf(filename,"%s%c%s", d->dirname, DELIMETER,name);
|
|
if (Verbose) fprintf(stderr,"Looking for %s\n", filename);
|
|
if ((f = fopen(filename,"r")) != NULL) {
|
|
found = 1;
|
|
}
|
|
}
|
|
if (found) {
|
|
// Found it, open it up for input
|
|
input_file = new char[strlen(filename)+1];
|
|
strcpy(input_file,filename);
|
|
scanner_file(f);
|
|
check_suffix(name);
|
|
return 0;
|
|
}
|
|
d = d->next;
|
|
}
|
|
|
|
if (!found) fprintf(stderr,"%s : Line %d. Unable to find include file %s (ignored).\n",input_file, line_number, name);
|
|
|
|
return -1;
|
|
}
|
|
|
|
|
|
static char buffer[1024];
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// void copy_data(FILE *f1, FILE *f2)
|
|
//
|
|
// Copies data from file f1 to file f2.
|
|
//
|
|
// Inputs : f1 = FILE 1
|
|
// f2 = FILE 2
|
|
//
|
|
// Output : None
|
|
//
|
|
// Side Effects : Closes file f1 upon exit.
|
|
// -----------------------------------------------------------------------------
|
|
|
|
void copy_data(FILE *f1, FILE *f2) {
|
|
|
|
while (fgets(buffer,1023,f1)) {
|
|
fputs(buffer, f2);
|
|
}
|
|
fclose(f1);
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// void copy_data(FILE *f1, String *s2)
|
|
//
|
|
// Copies data from file f1 to String s2.
|
|
//
|
|
// Inputs : f1 = FILE 1
|
|
// s2 = String
|
|
//
|
|
// Output : None
|
|
//
|
|
// Side Effects : Closes file f1 upon exit.
|
|
// -----------------------------------------------------------------------------
|
|
|
|
void copy_data(FILE *f1, String &s2) {
|
|
|
|
while (fgets(buffer,1023,f1)) {
|
|
s2 << buffer;
|
|
}
|
|
fclose(f1);
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// int insert_file(char *name, FILE *f)
|
|
//
|
|
// Looks for a file and inserts into file f.
|
|
//
|
|
// Inputs : name = filename
|
|
// f = FILE
|
|
//
|
|
// Output : 0 on success, -1 on failure.
|
|
//
|
|
// Side Effects : None
|
|
// -----------------------------------------------------------------------------
|
|
|
|
int insert_file(char *name, FILE *f_out) {
|
|
|
|
FILE *f;
|
|
char filename[256];
|
|
int found = 0;
|
|
Dnode *d;
|
|
|
|
if (!include_init) return -1; // Not initialized yet
|
|
if (add_iname(name)) {
|
|
if (Verbose) fprintf(stderr,"file %s already included.\n", name);
|
|
return -1; // Already included this file
|
|
}
|
|
|
|
if (Verbose) fprintf(stderr,"Looking for ./%s\n", name);
|
|
if ((f = fopen(name,"r")) != NULL) {
|
|
copy_data(f,f_out);
|
|
return 0;
|
|
}
|
|
|
|
// Now start searching libraries
|
|
|
|
d = ihead.next; // Start of search list
|
|
while (d != &iz) {
|
|
// Look for the wrap file in language directory
|
|
sprintf(filename,"%s%c%s%c%s", d->dirname,DELIMETER,LibDir,DELIMETER,name);
|
|
if (Verbose) fprintf(stderr,"Looking for %s\n", filename);
|
|
if((f = fopen(filename,"r")) != NULL) {
|
|
found = 1;
|
|
} else {
|
|
sprintf(filename,"%s%c%s", d->dirname, DELIMETER, name);
|
|
if (Verbose) fprintf(stderr,"Looking for %s\n", filename);
|
|
if ((f = fopen(filename,"r")) != NULL) {
|
|
found = 1;
|
|
}
|
|
}
|
|
if (found) {
|
|
copy_data(f,f_out);
|
|
return 0;
|
|
}
|
|
d = d->next;
|
|
}
|
|
|
|
if ((!found) && (Verbose)) fprintf(stderr,"unable to find %s. (Ignored)\n",name);
|
|
return -1;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// void swig_append(char *filename, FILE *f)
|
|
//
|
|
// Appends the contents of filename to stream f.
|
|
//
|
|
// Inputs :
|
|
// filename = File to append
|
|
// f = FILE handle
|
|
//
|
|
// Output : None
|
|
//
|
|
// Side Effects : None
|
|
// -----------------------------------------------------------------------------
|
|
|
|
void swig_append(char *filename, FILE *f) {
|
|
|
|
FILE *in_file;
|
|
|
|
if ((in_file = fopen(filename,"r")) == NULL) {
|
|
fprintf(stderr,"** SWIG ERROR ** file %s not found.\n",filename);
|
|
FatalError();
|
|
return;
|
|
}
|
|
while (fgets(buffer,1023,in_file)) {
|
|
fputs(buffer, f);
|
|
}
|
|
fclose(in_file);
|
|
}
|
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// int get_file(char *name, String &str)
|
|
//
|
|
// Looks for a file and converts it into a String.
|
|
//
|
|
// Inputs : name = filename
|
|
// str = String
|
|
//
|
|
// Output : 0 on success, -1 on failure.
|
|
//
|
|
// Side Effects : None
|
|
// -----------------------------------------------------------------------------
|
|
|
|
int get_file(char *name, String &str) {
|
|
|
|
FILE *f;
|
|
char filename[256];
|
|
int found = 0;
|
|
Dnode *d;
|
|
|
|
if (!include_init) return -1; // Not initialized yet
|
|
|
|
if (Verbose) fprintf(stderr,"Looking for %s\n", name);
|
|
if ((f = fopen(name,"r")) != NULL) {
|
|
copy_data(f,str);
|
|
return 0;
|
|
}
|
|
|
|
// Now start searching libraries
|
|
|
|
d = ihead.next; // Start of search list
|
|
while (d != &iz) {
|
|
// Look for the wrap file in language directory
|
|
sprintf(filename,"%s%c%s%c%s", d->dirname,DELIMETER,LibDir,DELIMETER,name);
|
|
if (Verbose) fprintf(stderr,"Looking for %s\n", filename);
|
|
if((f = fopen(filename,"r")) != NULL) {
|
|
found = 1;
|
|
} else {
|
|
sprintf(filename,"%s%c%s", d->dirname, DELIMETER, name);
|
|
if (Verbose) fprintf(stderr,"Looking for %s\n", filename);
|
|
if ((f = fopen(filename,"r")) != NULL) {
|
|
found = 1;
|
|
}
|
|
}
|
|
if (found) {
|
|
copy_data(f,str);
|
|
return 0;
|
|
}
|
|
d = d->next;
|
|
}
|
|
|
|
if ((!found)) fprintf(stderr,"SWIG Error. Unable to find %s. Possible installation problem.\n",name);
|
|
FatalError();
|
|
return -1;
|
|
}
|
|
|
|
static char *libs[1000];
|
|
static int nlibs = 0;
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// void library_add(char *name)
|
|
//
|
|
// Adds a filename to the list of libraries. This is usually only called by
|
|
// the SWIG main program.
|
|
//
|
|
// Inputs : name = library name
|
|
//
|
|
// Outputs: None
|
|
//
|
|
// Side Effects : Adds the library name to the libs array above
|
|
// -----------------------------------------------------------------------------
|
|
|
|
void library_add(char *name) {
|
|
int i;
|
|
|
|
// Check to make sure it's not already added
|
|
|
|
if (!(*name)) return;
|
|
|
|
for (i = 0; i < nlibs; i++) {
|
|
if (strcmp(libs[i],name) == 0) return;
|
|
}
|
|
|
|
libs[nlibs] = copy_string(name);
|
|
nlibs++;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// void library_insert()
|
|
//
|
|
// Starts parsing all of the SWIG library files.
|
|
//
|
|
// Inputs : None
|
|
//
|
|
// Output : None
|
|
//
|
|
// Side Effects : Opens and attaches all of the specified library files to
|
|
// the scanner.
|
|
//
|
|
// Bugs : Opens all of the files. Will fail if there are too many open files.
|
|
//
|
|
// -----------------------------------------------------------------------------
|
|
|
|
void library_insert() {
|
|
int i;
|
|
|
|
i = nlibs-1;
|
|
while (i >= 0) {
|
|
include_file(libs[i]);
|
|
i--;
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// int checkout(char *filename,char *dest)
|
|
//
|
|
// Tries to check a file out of the SWIG library. If found, it will save it in
|
|
// the current directory. This is a useful mechanism for using SWIG as a code
|
|
// manager and for extracting library files.
|
|
//
|
|
// Inputs : filename = Library file
|
|
// dest = Destination file
|
|
//
|
|
// Output : 0 on success
|
|
// -1 on failure.
|
|
//
|
|
// Side Effects : None
|
|
// -----------------------------------------------------------------------------
|
|
|
|
int checkout_file(char *filename,char *dest) {
|
|
|
|
FILE *f1;
|
|
char tempn[256];
|
|
|
|
// First check to see if the file already exists in current directory
|
|
f1 = fopen(dest,"r");
|
|
if (f1) {
|
|
if (Verbose)
|
|
fprintf(stderr,"Warning. Unable to check-out %s. File already exists.\n", filename);
|
|
fclose(f1);
|
|
return -1;
|
|
}
|
|
|
|
while (!f1) {
|
|
sprintf(tempn,"%s%d",dest,rand());
|
|
f1 = fopen(tempn,"r");
|
|
if (f1) {
|
|
fclose(f1);
|
|
f1 = 0;
|
|
} else {
|
|
f1 = fopen(tempn,"w");
|
|
if (!f1) {
|
|
fprintf(stderr,"Unable to open %s for writing\n", tempn);
|
|
return -1;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Now try to insert the library file into the destination file
|
|
if ((insert_file(filename,f1)) == -1) {
|
|
fprintf(stderr,"Unable to check-out '%s'. File does not exist in SWIG library.\n",filename);
|
|
fclose(f1);
|
|
remove(tempn); // Unsuccessful, remove file we created
|
|
return -1;
|
|
}
|
|
fclose(f1);
|
|
// Now move the file
|
|
rename(tempn,dest);
|
|
return 0;
|
|
}
|
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// int checkin_file(char *dir, char *lang, char *source,char *dest)
|
|
//
|
|
// Attempts to check a file into the SWIG library.
|
|
//
|
|
// Inputs : dir = Location of the SWIG library.
|
|
// lang = Language specific subdirectory.
|
|
// source = Source file.
|
|
// dest = Destination file.
|
|
//
|
|
// Output : 0 on success
|
|
// -1 on failure.
|
|
//
|
|
// Side Effects : None
|
|
// -----------------------------------------------------------------------------
|
|
|
|
int checkin_file(char *dir, char *lang, char *source, char *dest) {
|
|
|
|
FILE *f1;
|
|
char tempn[256];
|
|
String s;
|
|
|
|
// First check to see if the file exists
|
|
|
|
f1 = fopen(source,"r");
|
|
if (!f1) return -1;
|
|
|
|
copy_data(f1,s);
|
|
|
|
// Now try to open the destination file
|
|
sprintf(tempn,"%s/%s/%s", dir,lang,dest);
|
|
f1 = fopen(tempn,"w");
|
|
if (!f1) return -1;
|
|
fprintf(f1,"%s",s.get());
|
|
fclose(f1);
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
|