Since I have made several changes to SWIG over the years to accomodate

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
This commit is contained in:
Robin Dunn
2002-04-29 19:56:57 +00:00
parent 3bd1e03385
commit c90f71dd8c
135 changed files with 51307 additions and 1 deletions

View File

@@ -0,0 +1,126 @@
#######################################################################
# $Header$
# Simplified Wrapper and Interface Generator (SWIG)
#
# Makefile for version 1.0 Final
# Dave Beazley
# August 1, 1996
#
# This makefile is now mostly constructed by ./configure.
#
# $Log$
# Revision 1.1 2002/04/29 19:56:48 RD
# Since I have made several changes to SWIG over the years to accomodate
# 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.
#
# Revision 1.1.1.1 1999/02/28 02:00:51 beazley
# Swig1.1
#
# Revision 1.1 1996/08/12 01:55:02 dmb
# Initial revision
#
#######################################################################
#.KEEP_STATE:
srcdir = @srcdir@
VPATH = @srcdir@
# Set your C++ compiler here. g++ works on most machines,
# but you might have to change it depending on your installation.
#
CC = @CXX@
#
# Set the prefix below to indicate where you want SWIG to install its
# files. Normally this is /usr/local
#
prefix = @prefix@
# Location of the SWIG library. Is normally put in /usr/local/lib/swig_lib
# The SWIG library contains configuration files and library modules
# so you should install it someplace where it can be easily accessed.
SWIG_LIB = $(prefix)/lib/swig_lib
# YACC parser. Use bison by default. if this doesn't work, switch
# it over to yacc. If that still doesn't work, let me know...
YACC = @YACC@
# Comment out the following line if you're on an SGI or don't have ranlib!
RANLIB = @RANLIB@
AR = @AR@
########################################################################
# Normally, you shouldn't have to change anything below this point #
########################################################################
LIBOBJS = main.o scanner.o symbol.o include.o types.o parms.o emit.o newdoc.o ascii.o \
html.o latex.o cplus.o lang.o hash.o sstring.o wrapfunc.o getopt.o comment.o \
typemap.o naming.o
LIBSRCS = main.cxx scanner.cxx symbol.cxx include.cxx types.cxx parms.cxx emit.cxx \
newdoc.cxx ascii.cxx html.cxx latex.cxx cplus.cxx lang.cxx hash.cxx \
sstring.cxx wrapfunc.cxx getopt.cxx comment.cxx typemap.cxx naming.cxx
LIBHEADERS = internal.h ../Include/swig.h latex.h ascii.h html.h nodoc.h
LIB = ../libswig.a
PARSER = parser.y
INCLUDE = -I../Include
##-DSWIG_LIB='"$(SWIG_LIB)"'
CFLAGS = @CFLAGS@ -DSWIG_CC='"$(CC)"' @DEFS@
SHELL = /bin/sh
#
#
#
# Rules for creation of a .o file from .cxx
.SUFFIXES: .cxx
.cxx.o:
$(CC) $(INCLUDE) $(CFLAGS) -c -o $*.o $<
all: $(LIB)
$(LIB): parser.o $(LIBOBJS)
@echo "Building library"
$(AR) cr $(LIB) $(LIBOBJS) parser.o
$(RANLIB) $(LIB)
parser.o: parser.cxx $(LIBHEADERS)
$(CC) $(INCLUDE) $(CFLAGS) parser.cxx -c -o parser.o
parser.cxx: $(PARSER)
$(YACC) @YACCFLAGS@
@cp y.tab.h parser.h
@cp y.tab.c parser.cxx
parser::
@cp y.tab.c.bison parser.cxx
@cp y.tab.h.bison parser.h
@cp y.tab.h.bison y.tab.h
$(CC) $(CFLAGS) parser.cxx -c -o parser.o
Makefile: $(srcdir)/Makefile.in ../config.status
(cd ..; CONFIG_FILES=SWIG/Makefile $(SHELL) config.status)
.PRECIOUS: Makefile
clean::
rm -f *.o libswig.a y.tab.c y.tab.h
nuke::
rm -f Makefile *~ #* core a.out
wc::
wc $(LIBSRCS) *.h parser.y

View File

@@ -0,0 +1,464 @@
/*******************************************************************************
* 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 "swig.h"
#include "ascii.h"
#include <ctype.h>
/*******************************************************************************
* $Header$
*
* File : ascii.cxx
*
* Module for producing ASCII documentation.
*
*******************************************************************************/
// -----------------------------------------------------------------------------
// ASCII::ASCII()
//
// Constructor. Initializes the ASCII module.
//
// Inputs : None
//
// Output : Documentation module object
//
// Side Effects :
// Sets page-width and indentation.
// -----------------------------------------------------------------------------
ASCII::ASCII() {
sect_count = 0;
indent = 8;
columns = 70;
}
// -----------------------------------------------------------------------------
// void ASCII::print_string(char *s, int margin, int mode)
//
// Prints a string to the documentation file. Performs line wrapping and
// other formatting.
//
// Inputs :
// s = NULL terminate ASCII string
// margin = Number of characters to be inserted on left side
// mode = If set, text will be reformatted. Otherwise, it's
// printed verbatim (with indentation).
//
// Output : None
//
// Side Effects : None
// -----------------------------------------------------------------------------
void ASCII::print_string(char *s, int margin, int mode) {
char *c;
int i;
int lbreak = 0;
int col;
c = s;
if (!s) return;
// Apply indentation
for (i = 0; i < margin; i++)
fputc(' ',f_doc);
col = margin;
if (mode) {
// Dump out text in formatted mode
// Strip leading white-space
while ((*c) && (isspace(*c))) {
c++;
}
while (*c) {
switch(*c) {
case '\n':
case '\\':
if (lbreak) {
col = margin;
fputc('\n',f_doc);
for (i = 0; i < margin; i++)
fputc(' ',f_doc);
lbreak = 0;
} else {
if ((*c) == '\n') {
col++;
}
lbreak++;
}
break;
case ' ':
case '\t':
case '\r':
case '\f':
if (col > columns) {
fputc('\n',f_doc);
for (i = 0; i < margin; i++)
fputc(' ',f_doc);
col = margin;
} else {
fputc(' ',f_doc);
col++;
}
// Skip over rest of white space found
while ((*c) && isspace(*c)) c++;
c--;
lbreak = 0;
break;
default :
if (lbreak) fputc(' ',f_doc);
lbreak = 0;
fputc(*c,f_doc);
col++;
break;
}
c++;
}
} else {
// Dump out text in pre-formatted mode
while (*c) {
switch(*c) {
case '\n':
fputc('\n',f_doc);
for (i = 0; i < margin; i++)
fputc(' ',f_doc);
break;
default :
fputc(*c,f_doc);
col++;
break;
}
c++;
}
}
}
// -----------------------------------------------------------------------------
// void ASCII::print_decl(DocEntry *de)
//
// Prints the documentation entry corresponding to a declaration
//
// Inputs :
// de = Documentation entry (which should be for a declaration)
//
// Output : None
//
// Side Effects : None
// -----------------------------------------------------------------------------
void ASCII::print_decl(DocEntry *de) {
int i;
char *c;
c = de->usage.get();
fprintf(f_doc,"%s\n",c);
// If there is any C annotation, print that
if (de->print_info) {
c = de->cinfo.get();
if (strlen(c) > 0) {
for (i = 0; i < indent; i++)
fputc(' ',f_doc);
fprintf(f_doc,"[ ");
print_string(c,0,1);
fprintf(f_doc," ]\n");
}
}
c = de->text.get();
if (strlen(c) > 0) {
print_string(c,indent,de->format);
fprintf(f_doc,"\n");
if (de->format) fputc('\n',f_doc);
} else {
fprintf(f_doc,"\n");
}
}
// -----------------------------------------------------------------------------
// void ASCII::print_text(DocEntry *de)
//
// Prints the documentation for a block of text. Will strip any leading white
// space from the text block.
//
// Inputs :
// de = Documentation entry of text
//
// Output : None
//
// Side Effects : None
// -----------------------------------------------------------------------------
void ASCII::print_text(DocEntry *de) {
char *c;
c = de->text.get();
if (strlen(c) > 0) {
while ((*c == '\n')) c++;
print_string(c,0,de->format);
fprintf(f_doc,"\n\n");
}
}
// -----------------------------------------------------------------------------
// void ASCII::title(DocEntry *de)
//
// Sets the title of the documentation file.
//
// Inputs :
// de = Documentation entry of the title.
//
// Output : None
//
// Side Effects : None
// -----------------------------------------------------------------------------
void ASCII::title(DocEntry *de) {
char *c;
c = de->usage.get();
if (strlen(c) > 0) {
fprintf(f_doc,"%s\n\n",c);
}
// If there is any C annotation, print that
if (de->print_info) {
c = de->cinfo.get();
if (strlen(c) > 0) {
fprintf(f_doc,"[ ");
print_string(c,0,1);
fprintf(f_doc," ]\n");
}
}
c = de->text.get();
if (strlen(c)) {
print_string(c,0,de->format);
}
fprintf(f_doc,"\n\n");
}
// -----------------------------------------------------------------------------
// void ASCII::newsection(DocEntry *de, int sectnum)
//
// Starts a new section. Will underline major sections and subsections, but
// not minor subsections.
//
// Inputs :
// de = Documentation entry of the section
// sectnum = Section number.
//
// Output : None
//
// Side Effects :
// Forces a new subsection to be created within the ASCII module.
// -----------------------------------------------------------------------------
void ASCII::newsection(DocEntry *de,int sectnum) {
int i,len = 0;
char temp[256];
char *c;
sect_num[sect_count] = sectnum;
sect_count++;
for (i = 0; i < sect_count; i++) {
sprintf(temp,"%d.",sect_num[i]);
fprintf(f_doc,"%s",temp);
len += strlen(temp);
}
c = de->usage.get();
fprintf(f_doc," %s\n", c);
len += strlen(c) + 2;
// Print an underline if this is a major category
if (sect_count <= 1) {
for (i = 0; i < len; i++)
fputc('=',f_doc);
fputc('\n',f_doc);
} else if (sect_count == 2) {
for (i = 0; i < len; i++)
fputc('-',f_doc);
fputc('\n',f_doc);
} else {
fputc('\n',f_doc);
}
// If there is any C annotation, print that
if (de->print_info) {
c = de->cinfo.get();
if (strlen(c) > 0) {
fprintf(f_doc,"[ ");
print_string(c,0,1);
fprintf(f_doc," ]\n\n");
}
}
// If there is a description text. Print it
c = de->text.get();
if (strlen(c) > 0) {
print_string(c,0,de->format);
fprintf(f_doc,"\n");
}
fprintf(f_doc,"\n");
}
// -----------------------------------------------------------------------------
// void ASCII::endsection()
//
// Ends the current section. It is an error to call this without having first
// called newsection().
//
// Inputs : None
//
// Output : None
//
// Side Effects :
// Pops out of the current section, moving back into the parent section
// -----------------------------------------------------------------------------
void ASCII::endsection() {
if (sect_count > 0) sect_count--;
}
// -----------------------------------------------------------------------------
// void ASCII::separator()
//
// Prints a small dashed line that is used to designate the end of C++ class
// subsections.
//
// Inputs : None
//
// Output : None
//
// Side Effects : None
// -----------------------------------------------------------------------------
void ASCII::separator() {
int i;
for (i = 0; i < 10; i++)
fputc('-',f_doc);
fprintf(f_doc,"\n\n");
}
// -----------------------------------------------------------------------------
// void ASCII::init(char *filename)
//
// Initializes the documentation module and opens up the documentation file.
//
// Inputs : filename = name of documentation file (without suffix)
//
// Output : None
//
// Side Effects : Opens the documentation file.
// -----------------------------------------------------------------------------
void ASCII::init(char *filename) {
char f[256];
sprintf(f,"%s.doc",filename);
sprintf(fn,"%s",filename);
f_doc = fopen(f,"w");
if (f_doc == NULL) {
fprintf(stderr, "Unable to open %s\n", fn);
SWIG_exit(1);
}
}
// -----------------------------------------------------------------------------
// void ASCII::close()
//
// Closes the documentation module. This function should only be called once
//
// Inputs : None
//
// Output : None
//
// Side Effects : Closes the documentation file.
// -----------------------------------------------------------------------------
void ASCII::close(void) {
fclose(f_doc);
if (Verbose)
fprintf(stderr,"Documentation written to %s.doc\n", fn);
}
// -----------------------------------------------------------------------------
// void ASCII::style(char *name, char *value)
//
// Looks for style parameters that the user might have supplied using the
// %style directive. Unrecognized options are simply ignored.
//
// Inputs :
// name = name of the style parameter
// value = value of the style parameter (optional)
//
// Output : None
//
// Side Effects : Can change internal settings of 'indent' and 'columns' members.
// -----------------------------------------------------------------------------
void ASCII::style(char *name, char *value) {
if (strcmp(name,"ascii_indent") == 0) {
if (value) {
indent = atoi(value);
}
} else if (strcmp(name,"ascii_columns") == 0) {
if (value) {
columns = atoi(value);
}
}
}
// -----------------------------------------------------------------------------
// void ASCII::parse_args(int argc, char **argv)
//
// Function for processing options supplied on the SWIG command line.
//
// Inputs :
// argc = Number of arguments
// argv = Argument strings
//
// Output : None
//
// Side Effects : May set various internal parameters.
// -----------------------------------------------------------------------------
static char *ascii_usage = "\
ASCII Documentation Options (available with -dascii)\n\
None available.\n\n";
void ASCII::parse_args(int argc, char **argv) {
int i;
for (i = 0; i < argc; i++) {
if (argv[i]) {
if (strcmp(argv[i],"-help") == 0) {
fputs(ascii_usage,stderr);
}
}
}
}

View File

@@ -0,0 +1,64 @@
/*******************************************************************************
* 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.
*******************************************************************************/
/***********************************************************************
* $Header$
*
* ascii.h
*
* ASCII specific functions for producing documentation. Basically
* prints things out as 80 column ASCII.
***********************************************************************/
class ASCII : public Documentation {
private:
FILE *f_doc;
char fn[256];
void print_string(char *s,int indent,int mode);
int indent; // Indentation (for formatting)
int columns; // Number of columns (for formatting)
int sect_count; // Section counter
int sect_num[20]; // Section numbers
// Style parameters
public:
ASCII();
void parse_args(int argc, char **argv);
void title(DocEntry *de);
void newsection(DocEntry *de, int sectnum);
void endsection();
void print_decl(DocEntry *de);
void print_text(DocEntry *de);
void separator();
void init(char *filename);
void close(void);
void style(char *name, char *value);
};

View File

@@ -0,0 +1,697 @@
/*******************************************************************************
* 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"
/*******************************************************************************
* $Header$
*
* File : comment.cxx
*
* This is a semi-magical module for associating C/C++ comments with
* documentation entries. While this sounds like it might be easy,
* there are a number of subtle problems getting things to associate
* correctly.
*
* Here's the general idea :
*
* 1. The parser and scanner feed both C comments and documentation
* entries to this class. These may show up in really bizarre
* orders (not necessarily the order seen in an interface file).
*
* 2. We maintain separate lists of comments and documentation
* entries.
*
* 3. Periodically, we go through the list of documentation entries
* and see if we can associate any comments.
*
* 4. Upon completion of parsing, it's critical that we cleanup
* the lists using the cleanup() method.
*
*******************************************************************************/
// -----------------------------------------------------------------------------
// struct Comment
//
// Structure used to maintain a linked list of comments for later use.
// -----------------------------------------------------------------------------
class Comment {
public:
String *text; // Text of the comment
int first_line; // First line of the comment
int last_line; // Last line of the comment
int column; // First column of comment
char *file; // Name of the file that it was in
Comment *next; // Next comment (when in a linked list)
Comment *prev; // Previous comment
static Comment *comment_list; // List of all comments
Comment(char *t, int line, int col, char *f);
~Comment();
static Comment *find(DocEntry *de, CommentHandler *ch);
void attach(DocEntry *de, CommentHandler *ch);
};
// -----------------------------------------------------------------------
// Create a new comment. Automatically puts it on the linked list
// -----------------------------------------------------------------------
Comment::Comment(char *t, int line, int col, char *f) {
int nlines = 0;
char *c;
text = new String(t);
c = t;
while (*c) {
if (*c == '\n') nlines++;
c++;
}
first_line = line;
column = col;
last_line = line + nlines - 1;
file = copy_string(f);
if (comment_list) {
comment_list->prev = this;
}
next = comment_list;
comment_list = this;
prev = 0;
}
// -----------------------------------------------------------------------
// Destroy a comment
// -----------------------------------------------------------------------
Comment::~Comment() {
delete text;
delete file;
// Remove from linked list (if applicable)
if (prev) {
prev->next = next;
}
if (next) {
next->prev = prev;
}
if (this == comment_list) comment_list = next;
}
// -----------------------------------------------------------------------
// find(DocEntry *de, CommentHandler *ch)
//
// This function tries to a find a comment matching the search criteria
// of a given comment handler and documentation entry.
// -----------------------------------------------------------------------
Comment *Comment::find(DocEntry *de, CommentHandler *ch) {
Comment *c;
c = comment_list;
// Start walking down our list of stored comments
while (c) {
// printf("Searching %x : %s\n", c, c->text->get());
if (strcmp(de->file,c->file) == 0) {
// At least comment is in the right file. Now check line numbers
if (ch->location == BEFORE) {
// Check to see if the last line of the comment is close
// enough to our declaration.
if ((c->last_line <= de->line_number) &&
((de->line_number - c->last_line) <= ch->skip_lines)) {
return c;
}
} else { // AFTER mode
// Check to see if the first line of the comment is close
// enough to our declaration.
if ((c->first_line >= de->end_line) &&
((c->first_line - de->end_line) <= ch->skip_lines)) {
return c;
}
}
// Check to see if the line numbers are too small. Comments
// are processed in order so there's no sense in checking
// all entries.
if (c->last_line < de->line_number)
return 0;
}
c = c->next;
}
return 0;
}
// -----------------------------------------------------------------------
// void attach(DocEntry *de, CommentHandler *ch)
//
// This function attachs a comment to a documentation entry and applies
// all of the style information in the comment handler.
// -----------------------------------------------------------------------
void Comment::attach(DocEntry *de, CommentHandler *ch) {
int nlines = 0;
char **split = 0;
char *c;
int i,lnum,el;
if (!de) return;
// If we're ignoring comments, forget it
if (ch->ignore) {
return;
}
// If the comment is formatted, no style processing is applied
if (de->format) {
de->text << *text;
return;
}
// Untabify the comment
if (ch->untabify) text->untabify();
// Count how many lines we have
c = text->get();
while (*c) {
if (*c == '\n') nlines++;
c++;
}
if (nlines == 0) return;
// Tokenize the documentation string into lines
split = new char*[nlines+1];
c = text->get();
i = 0;
split[i] = c;
while (*c) {
if (*c == '\n') {
*(c++) = 0;
split[++i] = c;
} else c++;
}
lnum = 0;
// Now process the chop_top and chop_bottom values
// if nlines < (chop_top + chop_bottom), then we do nothing
if (nlines > (ch->chop_top + ch->chop_bottom)) {
lnum += ch->chop_top;
el = nlines-ch->chop_bottom;
} else {
el = nlines;
}
// Now process in-between lines
while (lnum < el) {
/* Chop line */
if (split[lnum]) {
if (strlen(split[lnum]) > (unsigned) (ch->chop_left+ch->chop_right)) {
if (ch->chop_right > 0)
split[lnum][strlen(split[lnum]) - ch->chop_right] = 0;
de->text << &split[lnum][ch->chop_left];
}
}
lnum++;
de->text << "\n";
}
// printf("*** ATTACHING %s : %s\n", de->usage.get(), de->text.get());
delete split;
}
CommentHandler *comment_handler = 0;
Comment *Comment::comment_list = 0;
// ------------------------------------------------------------------------
// struct DocEntryList
//
// This structure manages a linked list of documentation entries that
// haven't had comments attached to them yet.
//
// As a general rule, this list tends to remain rather short.
// ------------------------------------------------------------------------
struct DocEntryList {
DocEntry *de;
CommentHandler *ch;
DocEntryList *next;
DocEntryList *prev;
static DocEntryList *doc_list;
// -----------------------------------------------------------------------
// Create a new list entry
// -----------------------------------------------------------------------
DocEntryList(DocEntry *d, CommentHandler *c) {
de = d;
ch = c;
next = doc_list;
prev = 0;
if (doc_list)
doc_list->prev = this;
doc_list = this;
// Only allow a few doc entries to survive
if (this->next) {
if (this->next->next) {
delete this->next->next;
}
}
}
// -----------------------------------------------------------------------
// Destroy a list entry
// -----------------------------------------------------------------------
~DocEntryList() {
if (prev) {
prev->next = next;
}
if (next) {
next->prev = prev;
}
if (this == doc_list) doc_list = next;
};
// -----------------------------------------------------------------------
// static check()
//
// Checks the list of documentation entries to see if any can be associated.
// -----------------------------------------------------------------------
static void check() {
DocEntryList *dl, *dl_temp;
Comment *cmt;
// printf ("Checking\n");
dl = doc_list;
while (dl) {
cmt = Comment::find(dl->de,dl->ch);
if (cmt) {
// Okay, we found a matching comment. Attach it to this
// documentation entry.
cmt->attach(dl->de,dl->ch);
// Destroy the comment and doc list entry
delete cmt;
// Declarations are always coming in order so we're going
// to blow away all of them past this point
dl_temp = dl->next;
delete dl;
dl = dl_temp;
} else {
dl = dl->next;
}
}
}
};
DocEntryList *DocEntryList::doc_list = 0;
// -----------------------------------------------------------------------------
// CommentHandler::CommentHandler()
//
// Constructor. Creates a new comment handler. Sets up some default values
// for comment handling.
//
// Inputs : None
//
// Output : New CommentHandler object.
//
// Side Effects : Sets default comment handling parameters.
// -----------------------------------------------------------------------------
CommentHandler::CommentHandler() {
skip_lines = 1;
location = AFTER;
chop_top = 0;
chop_bottom = 0;
chop_left = 3;
chop_right = 0;
untabify = 1;
ignore = 0;
}
// -----------------------------------------------------------------------------
// CommentHandler::CommentHandler(CommentHandler *c)
//
// Constructor. Creates a new comment handler, but copies attributes from
// another handler.
//
// Inputs :
// c = A different comment handler.
//
// Output : A new CommentHandler object.
//
// Side Effects : None
// -----------------------------------------------------------------------------
CommentHandler::CommentHandler(CommentHandler *c) {
skip_lines = c->skip_lines;
location = c->location;
chop_top = c->chop_top;
chop_bottom = c->chop_bottom;
chop_left = c->chop_left;
chop_right = c->chop_right;
untabify = c->untabify;
ignore = c->ignore;
}
// -----------------------------------------------------------------------------
// CommentHandler::~CommentHandler()
//
// Destructor. Destroys a comment handler. Does nothing interesting at the
// moment.
//
// Inputs : None
//
// Output : None
//
// Side Effects : None
// -----------------------------------------------------------------------------
CommentHandler::~CommentHandler() {
}
// -----------------------------------------------------------------------------
// void CommentHandler::add_comment(char *text, int line_num, int col, char *file)
//
// This function takes a character string as comment text and appends
// it to the current comment string (which is held in Comment::comment_list)
//
// 1. If two comments appear in successive lines, they are
// concatenated. This is to handle C++ style comments like the
// one surrounding this text.
//
// 2. If a new comment appears, we simply create a new one
//
// Inputs :
// text = Text of the comment
// line_num = Starting line number of the comment
// col = Starting column of the comment
// file = File in which the comment was located.
//
// Output : None
//
// Side Effects :
// Saves the comment in an internal linked list.
// If multiple comments appear in succession, some may end up
// in our comment list permanently (ie. never attached to any
// particular declaration).
// -----------------------------------------------------------------------------
void CommentHandler::add_comment(char *text, int line_num, int col, char *file) {
char *c;
int nlines = 0;
Comment *cmt;
// printf("line_num = %d, %s\n", line_num,text);
// Count up how many lines are in this comment
c = text;
while (*c) {
if (*c == '\n') nlines++;
c++;
}
// Check to see if this comment is in a successive line to the last one
cmt = Comment::comment_list;
if (cmt) {
// Check for column alignment
if ((cmt->column == col) && (line_num == (cmt->last_line + 1)) &&
(nlines <= 1)) {
*(cmt->text) << text;
cmt->last_line = line_num + nlines - 1;
} else {
// This is a new comment, add it to our list
cmt = new Comment(text,line_num,col,file);
}
} else {
cmt = new Comment(text,line_num,col,file);
}
}
// -----------------------------------------------------------------------------
// void CommentHanlder::set_entry(DocEntry *d)
//
// This grabs a DocEntry and hangs onto it.
//
// We will place the doc entry into our documentation list and then
// check it to see if any comments are sitting around.
//
// Inputs : d = Documentation Entry
//
// Output : None
//
// Side Effects :
// May attach comments to the documentation entry. In this case,
// comments and DocEntries may be removed from internal lists.
// -----------------------------------------------------------------------------
void CommentHandler::set_entry(DocEntry *d) {
// printf("Set entry : file: %s, line %d, %s\n", d->file, d->line_number, d->usage.get());
// Create a new list entry and save it
new DocEntryList(d,this);
// Check all of the documentation entries to see if they can be placed
DocEntryList::check();
}
// -----------------------------------------------------------------------------
// static void CommentHandler::cleanup()
//
// Checks all documentation entries and sees if there are any comments available.
// If so, they are attached. This function is usually only called upon completion
// of parsing.
//
// Inputs : None
//
// Output : None
//
// Side Effects :
// Removes documentation entries and comments from internal lists.
//
// -----------------------------------------------------------------------------
void CommentHandler::cleanup() {
int nc, nd;
Comment *c;
DocEntryList *d;
DocEntryList::check();
// Figure out how bad we're doing on memory
nc = 0;
nd = 0;
c = Comment::comment_list;
while (c) {
nc++;
c = c->next;
}
d = DocEntryList::doc_list;
while(d) {
nd++;
d = d->next;
}
if (Verbose) {
printf("%d unprocessed comments, %d unprocessed doc entries.\n",nc,nd);
}
}
// -----------------------------------------------------------------------------
// void CommentHandler::style(char *name, char *value)
//
// Processes comment handling style parameters. The following parameters
// are available :
//
// after - Comments appear after a declaration
// before - Comments appear before a declaration
// skip - Number of blank lines between comment and decl.
// chop_top - Number of lines to chop from top of a comment
// chop_bottom - Number of lines to chop from bottom of a comment
// chop_left - Number of characters to chop from left
// chop_right - Number of characters to chop from right
// tabify - Leave tabs in comment text
// untabify - Strip tabs and convert them into spaces.
// ignore - Ignore comments
// enable - Enable comments
//
// Inputs :
// name - Name of style parameter
// value - Optional parameter value
//
// Output : None
//
// Side Effects : Changes style of comment handler object.
//
// -----------------------------------------------------------------------------
void CommentHandler::style(char *name, char *value) {
if (strcmp(name,"before") == 0) {
location = BEFORE;
} else if (strcmp(name,"after") == 0) {
location = AFTER;
} else if (strcmp(name,"skip") == 0) {
if (value)
skip_lines = atoi(value);
} else if (strcmp(name,"chop_top") == 0) {
if (value)
chop_top = atoi(value);
} else if (strcmp(name,"chop_bottom") == 0) {
if (value)
chop_bottom = atoi(value);
} else if (strcmp(name,"chop_left") == 0) {
if (value)
chop_left = atoi(value);
} else if (strcmp(name,"chop_right") == 0) {
if (value)
chop_right = atoi(value);
} else if (strcmp(name,"tabify") == 0) {
untabify = 0;
} else if (strcmp(name,"untabify") == 0) {
untabify = 1;
} else if (strcmp(name,"ignore") == 0) {
ignore = 1;
} else if (strcmp(name,"enable") == 0) {
ignore = 0;
}
}
// -----------------------------------------------------------------------------
// void CommentHandler::parse_args(int argc, char **argv)
//
// Function for processing command line options given on the SWIG command line.
// See the help string below for available options.
//
// Inputs :
// argc = Argument count
// argv = Argument strings
//
// Output : None
//
// Side Effects :
// Changes various style parameters for the top-level CommentHandler.
// -----------------------------------------------------------------------------
static char *comment_usage = "\
Comment Style Options : \n\
-Safter - Use comments after a declaration.\n\
-Sbefore - Use comments before a declaration.\n\
-Schop_bottom n - Chop n lines from bottom of comments.\n\
-Schop_left n - Chop n characters from left of a comment.\n\
-Schop_right n - Chop n characters from right of a comment.\n\
-Schop_top n - Chop n lines from top of comments.\n\
-Signore - Ignore comments.\n\
-Sskip n - Max lines between comment and declaration.\n\
-Stabify - Do not convert tabs.\n\
-Suntabify - Convert tabs into spaces (the default).\n\n";
void CommentHandler::parse_args(int argc, char **argv) {
int i;
for (i = 1; i < argc; i++) {
if (argv[i]) {
if (strcmp(argv[i],"-Sbefore") == 0) {
this->style("before",0);
mark_arg(i);
} else if (strcmp(argv[i],"-Safter") == 0) {
this->style("after",0);
mark_arg(i);
} else if (strcmp(argv[i],"-Schop_top") == 0) {
if (argv[i+1]) {
this->style("chop_top",argv[i+1]);
mark_arg(i);
mark_arg(i+1);
i++;
} else {
arg_error();
}
} else if (strcmp(argv[i],"-Schop_bottom") == 0) {
if (argv[i+1]) {
this->style("chop_bottom",argv[i+1]);
mark_arg(i);
mark_arg(i+1);
i++;
} else {
arg_error();
}
} else if (strcmp(argv[i],"-Schop_left") == 0) {
if (argv[i+1]) {
this->style("chop_left",argv[i+1]);
mark_arg(i);
mark_arg(i+1);
i++;
} else {
arg_error();
}
} else if (strcmp(argv[i],"-Schop_right") == 0) {
if (argv[i+1]) {
this->style("chop_right",argv[i+1]);
mark_arg(i);
mark_arg(i+1);
i++;
} else {
arg_error();
}
} else if (strcmp(argv[i],"-Sskip") == 0) {
if (argv[i+1]) {
this->style("skip",argv[i+1]);
mark_arg(i);
mark_arg(i+1);
i++;
} else {
arg_error();
}
} else if (strcmp(argv[i],"-Suntabify") == 0) {
this->style("untabify",0);
mark_arg(i);
} else if (strcmp(argv[i],"-Stabify") == 0) {
this->style("tabify",0);
mark_arg(i);
} else if (strcmp(argv[i],"-Signore") == 0) {
this->style("ignore",0);
} else if (strcmp(argv[i],"-help") == 0) {
fputs(comment_usage,stderr);
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,829 @@
/*******************************************************************************
* 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"
/*******************************************************************************
* $Header$
*
* File : emit.cxx
*
* This file contains some useful functions for emitting code that would be
* common to all of the interface languages. Mainly this function deals with
* declaring functions external, creating lists of arguments, and making
* function calls.
*******************************************************************************/
// -----------------------------------------------------------------------------
// void emit_banner(FILE *f)
//
// Emits the SWIG identifying banner in the wrapper file
//
// Inputs : f = FILE handle
//
// Output : None
//
// Side Effects : None
// -----------------------------------------------------------------------------
void emit_banner(FILE *f) {
extern char *get_time();
extern char fn_header[];
fprintf(f,
"/*\n\
* FILE : %s\n\
* \n\
* This file was automatically generated by :\n\
* Simplified Wrapper and Interface Generator (SWIG)\n\
* Version %d.%d %s\n\
* \n\
* Portions Copyright (c) 1995-1998\n\
* The University of Utah and The Regents of the University of California.\n\
* Permission is granted to distribute this file in any manner provided\n\
* this notice remains intact.\n\
* \n\
* Do not make changes to this file--changes will be lost!\n\
*\n\
*/\n\n", fn_header, SWIG_MAJOR_VERSION, SWIG_MINOR_VERSION, SWIG_SPIN);
fprintf(f,"\n#define SWIGCODE\n");
}
// -----------------------------------------------------------------------------
// emit_extern_var(char *decl, DataType *t, int extern_type, FILE *f)
//
// Emits an external variables declaration. Extern_type defines the
// type of external declaration. Currently, only C/C++ declarations
// are allowed, but this might be extended to allow Fortran linkage
// someday
//
// Inputs :
// decl = Name of the declaration
// t = Datatype
// extern_type = Numeric code indicating type of extern
// 0 - No "extern"
// 1,2 - Normal extern (C/C++)
// f = FILE handle
//
// Output : None
//
// Side Effects : None
// -----------------------------------------------------------------------------
void emit_extern_var(char *decl, DataType *t, int extern_type, FILE *f) {
char *arr = 0;
if (t->arraystr) arr = t->arraystr;
else arr = "";
switch(extern_type) {
case 0:
// No extern. Just a forward reference
if (t->arraystr)
t->is_pointer--;
if (t->is_reference) {
t->is_pointer--;
fprintf(f,"%s& %s%s; \n", t->print_full(), decl, arr);
t->is_pointer++;
} else {
fprintf(f,"%s %s%s; \n", t->print_full(), decl,arr);
}
if (t->arraystr)
t->is_pointer++;
break;
case 1: case 2:
if (t->arraystr)
t->is_pointer--;
// Normal C/C++ extern
// fprintf(f,"#line %d \"%s\"\n", line_number, input_file);
if (t->is_reference) {
t->is_pointer--;
fprintf(f,"extern %s& %s%s; \n", t->print_full(), decl,arr);
t->is_pointer++;
} else {
fprintf(f,"extern %s %s%s; \n", t->print_full(), decl,arr);
}
if (t->arraystr)
t->is_pointer++;
default:
break;
}
}
// -----------------------------------------------------------------------------
// emit_extern_func(char *decl, DataType *t, ParmList *L, int extern_type,
// FILE *f)
//
// Emits an external function declaration (similiar to emit_extern_var).
//
// Inputs :
// decl = Name of declaration
// t = Return datatype
// L = parameter list
// extern_type = Type of extern
// 0 - No "extern"
// 1 - extern
// 2 - extern "C"
// 3 - Function declaration (with arg names)
// f = FILE Handle
//
// Output : None
//
// Side Effects : None
//
// -----------------------------------------------------------------------------
void emit_extern_func(char *decl, DataType *t, ParmList *L, int extern_type, FILE *f) {
switch(extern_type) {
case 0:
if (t->is_reference) {
t->is_pointer--;
fprintf(f,"%s&", t->print_full());
t->is_pointer++;
} else {
fprintf(f,"%s", t->print_full());
}
fprintf(f,"%s(", decl);
L->print_types(f);
fprintf(f,");\n");
break;
case 1:
// Normal C/C++ extern
// fprintf(f,"#line %d \"%s\"\n", line_number, input_file);
if (t->is_reference) {
t->is_pointer--;
fprintf(f,"extern %s&", t->print_full());
t->is_pointer++;
} else {
fprintf(f,"extern %s", t->print_full());
}
fprintf(f,"%s(", decl);
L->print_types(f);
fprintf(f,");\n");
break;
case 2:
// A C++ --- > C Extern
// fprintf(f,"#line %d \"%s\"\n", line_number, input_file);
if (t->is_reference) {
t->is_pointer--;
fprintf(f,"extern \"C\" %s&", t->print_full());
t->is_pointer++;
} else {
fprintf(f,"extern \"C\" %s", t->print_full());
}
fprintf(f,"%s(", decl);
L->print_types(f);
fprintf(f,");\n");
break;
case 3:
// A function declaration (for inlining )
if (t->is_reference) {
t->is_pointer--;
fprintf(f,"%s&", t->print_full());
t->is_pointer++;
} else {
fprintf(f,"%s", t->print_full());
}
fprintf(f,"%s(", decl);
L->print_args(f);
fprintf(f,")\n");
break;
default:
break;
}
}
// -----------------------------------------------------------------------------
// char *emit_local(int i)
//
// Returns the name of local variable for parameter i
//
// Inputs : i = Parameter number
//
// Output : NULL terminated ASCII string
//
// Side Effects : Result is left in a static local variable.
// -----------------------------------------------------------------------------
char *emit_local(int i) {
static char arg[64];
sprintf(arg,"_arg%d", i);
return arg;
}
// -----------------------------------------------------------------------------
// int emit_args(char *d, DataType *rt, ParmList *l, FILE *f)
//
// Creates a list of variable declarations for both the return value
// and function parameters.
//
// The return value is always called _result and arguments label as
// _arg0, _arg1, _arg2, etc...
//
// Returns the number of parameters associated with a function.
//
// Inputs :
// d = Name of function
// rt = Return type
// l = Parameter list
// f = FILE Handle
//
// Output : Number of function arguments
//
// Side Effects : None
//
// Note : This function is obsolete. Use emit_args below...
// -----------------------------------------------------------------------------
int emit_args(DataType *rt, ParmList *l, FILE *f) {
Parm *p;
int i;
char temp[64];
String def;
char *tm;
// Declare the return variable
if ((rt->type != T_VOID) || (rt->is_pointer)) {
if ((rt->type == T_USER) && (!rt->is_pointer)) {
// Special case for return by "value"
rt->is_pointer++;
fprintf(f,"\t %s _result;\n", rt->print_type());
rt->is_pointer--;
} else {
// Normal return value
fprintf(f,"\t %s _result;\n", rt->print_type());
}
}
// Emit function arguments
i = 0;
p = l->get_first();
while (p != 0) {
if ((p->t->type != T_VOID) || (p->t->is_pointer)) {
sprintf(temp,"_arg%d", i);
if (p->defvalue) {
if ((p->t->is_reference) || ((p->t->type == T_USER) && (p->call_type == CALL_REFERENCE)))
fprintf(f,"\t %s _arg%d = &%s;\n", p->t->print_type(),i, p->defvalue);
else
fprintf(f,"\t %s _arg%d = %s;\n", p->t->print_type(),i, p->defvalue);
} else {
fprintf(f,"\t %s _arg%d;\n", p->t->print_type(),i);
tm = typemap_lookup("arginit", typemap_lang, p->t, p->name,"",temp);
if (tm) {
def << tm;
}
}
// Check for ignore or default typemaps
tm = typemap_lookup("default",typemap_lang,p->t,p->name,"",temp);
if (tm)
def << tm;
tm = typemap_lookup("ignore",typemap_lang,p->t,p->name,"",temp);
if (tm) {
def << tm;
p->ignore = 1;
}
tm = typemap_check("build",typemap_lang,p->t,p->name);
if (tm) {
p->ignore = 1;
}
i++;
}
p = l->get_next();
}
fprintf(f,"%s",def.get());
// i now contains number of parameters
return(i);
}
// -----------------------------------------------------------------------------
// int emit_args(char *d, DataType *rt, ParmList *l, WrapperFunction &f)
//
// Creates a list of variable declarations for both the return value
// and function parameters.
//
// The return value is always called _result and arguments label as
// _arg0, _arg1, _arg2, etc...
//
// Returns the number of parameters associated with a function.
//
// Inputs :
// d = Name of function
// rt = Return type
// l = Parameter list
// f = Wrapper function object
//
// Output : Number of function arguments
//
// Side Effects : None
//
// -----------------------------------------------------------------------------
int emit_args(DataType *rt, ParmList *l, WrapperFunction &f) {
Parm *p;
int i;
char *tm;
// Declare the return variable
if ((rt->type != T_VOID) || (rt->is_pointer)) {
if ((rt->type == T_USER) && (!rt->is_pointer)) {
// Special case for return by "value"
rt->is_pointer++;
f.add_local(rt->print_type(), "_result");
rt->is_pointer--;
} else {
// Normal return value
f.add_local(rt->print_type(), "_result");
}
}
// Emit function arguments
i = 0;
p = l->get_first();
while (p != 0) {
if ((p->t->type != T_VOID) || (p->t->is_pointer)) {
char *temp = emit_local(i);
// Figure out default values
if (((p->t->is_reference) && (p->defvalue)) ||
((p->t->type == T_USER) && (p->call_type == CALL_REFERENCE) && (p->defvalue))) {
String deftmp;
deftmp << "(" << p->t->print_type() << ") &" << p->defvalue;
f.add_local(p->t->print_type(),temp,deftmp.get());
} else {
String deftmp;
char *dv = 0;
if (p->defvalue) {
deftmp << "(" << p->t->print_type() << ") " << p->defvalue;
dv = deftmp.get();
}
f.add_local(p->t->print_type(), temp, dv);
tm = typemap_lookup("arginit", typemap_lang, p->t,p->name,"",temp,&f);
if (tm) {
f.code << tm << "\n";
}
}
// Check for ignore or default typemaps
tm = typemap_lookup("default",typemap_lang,p->t,p->name,"",temp,&f);
if (tm)
f.code << tm << "\n";
tm = typemap_lookup("ignore",typemap_lang,p->t,p->name,"",temp,&f);
if (tm) {
f.code << tm << "\n";
p->ignore = 1;
}
tm = typemap_check("build",typemap_lang,p->t,p->name);
if (tm) {
p->ignore = 1;
}
i++;
}
p = l->get_next();
}
// i now contains number of parameters
return(i);
}
// -----------------------------------------------------------------------------
// int emit_func_call(char *decl, DataType *t, ParmList *l, FILE *f)
//
// Emits code for a function call.
//
// Inputs :
// decl = name of function
// t = Return datatype
// l = Parameter list
// f = FILE Handle
//
// Output : None
//
// Side Effects : None
//
// Note : This function is obsolete
// -----------------------------------------------------------------------------
void emit_func_call(char *decl, DataType *t, ParmList *l, FILE *f) {
int i;
Parm *p;
// fprintf(f,"#line %d \"%s\"\n", line_number, input_file);
fprintf(f,"\t ");
// First check if there is a return value
if ((t->type != T_VOID) || (t->is_pointer)) {
if ((t->type == T_USER) && (!t->is_pointer)) {
// Special case for return by "value"
// Caution : This *will* cause a memory leak if not
// used properly.
if (CPlusPlus) {
fprintf(f,"_result = new %s(", t->print_type());
} else {
t->is_pointer++;
fprintf(f,"_result = %s malloc(sizeof(", t->print_cast());
t->is_pointer--;
fprintf(f,"%s));\n", t->print_type());
fprintf(f,"\t*(_result) = ");
}
} else {
// Check if this is a C++ reference
if (t->is_reference) {
t->is_pointer--;
fprintf(f,"%s& _result_ref = ", t->print_full());
t->is_pointer++;
} else {
// Normal return values
fprintf(f,"_result = %s", t->print_cast());
}
}
}
// Now print out function call
fprintf(f,"%s(",decl);
i = 0;
p = l->get_first();
while(p != 0) {
if ((p->t->type != T_VOID) || (p->t->is_pointer)){
fprintf(f,"%s",p->t->print_arraycast());
if ((!p->t->is_reference) && (p->call_type & CALL_VALUE)) fprintf(f,"&");
if ((!(p->call_type & CALL_VALUE)) &&
((p->t->is_reference) || (p->call_type & CALL_REFERENCE)))
fprintf(f,"*");
fprintf(f,"_arg%d",i);
i++;
}
p = l->get_next();
if (p != 0)
fprintf(f,",");
}
fprintf(f,")");
if ((t->type == T_USER) && (!t->is_pointer)) {
if (CPlusPlus) {
fprintf(f,")");
}
}
fprintf(f,";\n");
if (t->is_reference) {
fprintf(f,"\t _result = %s &_result_ref;\n", t->print_cast());
}
}
// -----------------------------------------------------------------------------
// int emit_func_call(char *decl, DataType *t, ParmList *l, WrapperFunction &f)
//
// Emits code for a function call (new version).
//
// Exception handling support :
//
// - This function checks to see if any sort of exception mechanism
// has been defined. If so, we emit the function call in an exception
// handling block.
//
// Inputs :
// decl = name of function
// t = Return datatype
// l = Parameter list
// f = WrapperFunction object
//
// Output : None
//
// Side Effects : None
//
// -----------------------------------------------------------------------------
void emit_func_call(char *decl, DataType *t, ParmList *l, WrapperFunction &f) {
int i;
Parm *p;
String fcall;
String exc;
char *tm;
// f.code << "#line " << line_number << " \"" << input_file << "\"\n";
fcall << tab4;
// First check if there is a return value
if ((t->type != T_VOID) || (t->is_pointer)) {
if ((t->type == T_USER) && (!t->is_pointer)) {
// Special case for return by "value"
// Caution : This *will* cause a memory leak if not
// used properly.
if (CPlusPlus) {
fcall << "_result = new " << t->print_type() << "(";
} else {
t->is_pointer++;
fcall << "_result = " << t->print_cast() << " malloc(sizeof(";
t->is_pointer--;
fcall << t->print_type() << "));\n";
fcall << tab4 << "*(_result) = ";
}
} else {
// Check if this is a C++ reference
if (t->is_reference) {
t->is_pointer--;
fcall << t->print_full() << "& _result_ref = ";
t->is_pointer++;
} else {
// Normal return value
fcall << "_result = " << t->print_cast();
}
}
}
// Now print out function call
fcall << decl << "(";
i = 0;
p = l->get_first();
while(p != 0) {
if ((p->t->type != T_VOID) || (p->t->is_pointer)){
fcall << p->t->print_arraycast();
if ((!p->t->is_reference) && (p->call_type & CALL_VALUE))
fcall << "&";
if ((!(p->call_type & CALL_VALUE)) &&
((p->t->is_reference) || (p->call_type & CALL_REFERENCE)))
fcall << "*";
fcall << emit_local(i);
i++;
}
p = l->get_next();
if (p != 0)
fcall << ",";
}
fcall << ")";
if ((t->type == T_USER) && (!t->is_pointer)) {
if (CPlusPlus) {
fcall << ")";
}
}
fcall << ";\n";
if (t->is_reference) {
fcall << tab4 << "_result = "<< t->print_cast() << " &_result_ref;\n";
}
// Check for exception handling
if ((tm = typemap_lookup("except",typemap_lang,t,decl,"_result",""))) {
// Found a type-specific mapping
exc << tm;
exc.replace("$function",fcall);
exc.replace("$name",decl);
f.code << exc;
} else if ((tm = fragment_lookup("except",typemap_lang, t->id))) {
exc << tm;
exc.replace("$function",fcall);
exc.replace("$name",decl);
f.code << exc;
} else {
f.code << fcall;
}
}
// -----------------------------------------------------------------------------
// void emit_hex(FILE *f)
//
// Emits the default C-code to handle pointers. This is normally contained
// in the SWIG library file 'swigptr.swg'
//
// Inputs : f = FILE handle
//
// Output : None
//
// Side Effects : None
// -----------------------------------------------------------------------------
void emit_hex(FILE *f) {
int stat;
// Look for a pointer configuration file
stat = insert_file("swigptr.swg", f);
if (stat == -1) {
fprintf(stderr,"** Fatal error. Unable to locate 'swigptr.swg'\n");
SWIG_exit(1);
}
}
// -----------------------------------------------------------------------------
// void emit_set_get(char *name, char *iname, DataType *type)
//
// Emits a pair of functions to set/get the value of a variable.
// This should be used as backup in case the target language can't
// provide variable linking.
//
// double foo;
//
// Gets translated into the following :
//
// double foo_set(double x) {
// return foo = x;
// }
//
// double foo_get() {
// return foo;
// }
//
// Need to handle special cases for char * and for user
// defined types.
//
// 1. char *
//
// Will free previous contents (if any) and allocate
// new storage. Could be risky, but it's a reasonably
// natural thing to do.
//
// 2. User_Defined
// Will assign value from a pointer.
// Will return a pointer to current value.
//
//
// Inputs :
// name = Name of variable
// iname = Renamed version of variable
// type = Datatype of the variable
//
// Output : None
//
// Side Effects : None
// -----------------------------------------------------------------------------
void emit_set_get(char *name, char *iname, DataType *t) {
Parm *p;
ParmList *l;
String new_name;
String new_iname;
String wname;
// First write a function to set the variable of the variable
if (!(Status & STAT_READONLY)) {
if ((t->type == T_USER) && (!t->is_pointer)) {
t->is_pointer++;
fprintf(f_header,"static %s %s(%s val) {\n",
t->print_type(), name_set(name), t->print_type());
t->is_pointer--;
} else {
fprintf(f_header,"static %s %s(%s val) {\n",
t->print_type(), name_set(name), t->print_type());
}
if ((t->type != T_VOID) || (t->is_pointer)) {
if (!t->is_pointer) {
// Have a real value here
// If it's a user defined type, we'll do something special.
// Otherwise, just assign it.
if (t->type != T_USER) {
fprintf(f_header,"\t return (%s) (%s = val);\n", t->print_type(), name);
} else {
fprintf(f_header,"\t %s = *(val);\n", name);
t->is_pointer++;
fprintf(f_header,"\t return (%s) &%s;\n", t->print_type(),name);
t->is_pointer--;
}
} else {
// Is a pointer type here. If string, we do something
// special. Otherwise. No problem.
if ((t->type == T_CHAR) && (t->is_pointer == 1)) {
if (CPlusPlus) {
fprintf(f_header,"\t if (%s) delete %s;\n", name,name);
fprintf(f_header,"\t %s = new char[strlen(val)+1];\n",name);
fprintf(f_header,"\t strcpy(%s,val);\n", name);
fprintf(f_header,"\t return %s;\n", name);
} else {
fprintf(f_header,"\t if (%s) free(%s);\n", name,name);
fprintf(f_header,"\t %s = (char *) malloc(strlen(val)+1);\n",name);
fprintf(f_header,"\t strcpy(%s,val);\n", name);
fprintf(f_header,"\t return %s;\n", name);
}
} else {
fprintf(f_header,"\t return (%s) (%s = val);\n", t->print_type(), name);
}
}
}
fprintf(f_header,"}\n");
// Now wrap it.
l = new ParmList;
p = new Parm(t,0);
if ((t->type == T_USER) && (!t->is_pointer)) p->t->is_pointer++;
p->name = new char[1];
p->name[0] = 0;
l->append(p);
new_name = name_set(name);
new_iname = name_set(iname);
if ((t->type == T_USER) && (!t->is_pointer)) {
t->is_pointer++;
lang->create_function(new_name, new_iname, t, l);
t->is_pointer--;
} else {
lang->create_function(new_name, new_iname, t, l);
}
delete l;
delete p;
if (doc_entry) doc_entry->usage << "\n";
}
// Now write a function to get the value of the variable
if ((t->type == T_USER) && (!t->is_pointer)) {
t->is_pointer++;
fprintf(f_header,"static %s %s() { \n",
t->print_type(), name_get(name));
fprintf(f_header,"\t return (%s) &%s;\n", t->print_type(), name);
t->is_pointer--;
} else {
fprintf(f_header,"static %s %s() { \n",
t->print_type(), name_get(name));
fprintf(f_header,"\t return (%s) %s;\n", t->print_type(), name);
}
fprintf(f_header,"}\n");
// Wrap this function
l = new ParmList;
new_name = name_get(name);
new_iname = name_get(iname);
if ((t->type == T_USER) && (!t->is_pointer)) {
t->is_pointer++;
lang->create_function(new_name, new_iname, t, l);
t->is_pointer--;
} else {
lang->create_function(new_name, new_iname, t, l);
}
delete l;
}

View File

@@ -0,0 +1,141 @@
/*******************************************************************************
* 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"
/*******************************************************************************
* $Header$
*
* File : getopt.cxx
*
* This file defines a few functions for handling command line arguments.
* C++ makes this really funky---especially since each language module
* may want to extract it's own command line arguments.
*
* My own special version of getopt. This is a bit weird, because we
* don't know what the options are in advance (they could be determined
* by a language module).
*******************************************************************************/
static char **args;
static int numargs;
static int *marked;
// -----------------------------------------------------------------------------
// void init_args(int argc, char **argv)
//
// Initializes the argument list.
//
// Inputs :
// argc = Argument count
// argv = Argument array
//
// Output : None
//
// Side Effects : Saves local copy of argc and argv
// -----------------------------------------------------------------------------
void
init_args(int argc, char **argv)
{
int i;
numargs = argc;
args = argv;
marked = new int[numargs];
for (i = 0; i < argc; i++) {
marked[i] = 0;
}
marked[0] = 1;
}
// -----------------------------------------------------------------------------
// void mark_arg(int n)
//
// Marks an argument as being parsed. All modules should do this whenever they
// parse a command line option.
//
// Inputs : n = Argument number
//
// Output : None
//
// Side Effects : Sets a status bit internally
// -----------------------------------------------------------------------------
void
mark_arg(int n) {
if (marked)
marked[n] = 1;
}
// -----------------------------------------------------------------------------
// void check_options()
//
// Checks for unparsed command line options. If so, issues an error and exits.
//
// Inputs : None
//
// Output : None
//
// Side Effects : exits if there are unparsed options
// -----------------------------------------------------------------------------
void check_options() {
int error = 0;
int i;
if (!marked) {
fprintf(stderr,"Must specify an input file. Use -help for available options.\n");
SWIG_exit(1);
}
for (i = 1; i < numargs-1; i++) {
if (!marked[i]) {
fprintf(stderr,"swig error : Unrecognized option %s\n", args[i]);
error=1;
}
}
if (error) {
fprintf(stderr,"Use 'swig -help' for available options.\n");
SWIG_exit(1);
}
if (marked[numargs-1]) {
fprintf(stderr,"Must specify an input file. Use -help for available options.\n");
SWIG_exit(1);
}
}
// -----------------------------------------------------------------------------
// void arg_error()
//
// Generates a generic error message and exits.
//
// Inputs : None
//
// Output : None
//
// Side Effects : Exits
// -----------------------------------------------------------------------------
void arg_error() {
fprintf(stderr,"SWIG : Unable to parse command line options.\n");
fprintf(stderr,"Use 'swig -help' for available options.\n");
SWIG_exit(1);
}

View File

@@ -0,0 +1,359 @@
/*******************************************************************************
* 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"
/*******************************************************************************
* $Header$
*
* File : hash.cxx
*
* A very simple Hash table class. Could probably make it more elegant with
* templates, but templates are pure evil...
*******************************************************************************/
#define INIT_SIZE 119
// -----------------------------------------------------------------------------
// Hash::Hash()
//
// Constructor. Creates a new hash table.
//
// Inputs : None
//
// Output : New Hash object.
//
// Side Effects : None
// -----------------------------------------------------------------------------
Hash::Hash() {
int i;
hashsize = INIT_SIZE;
hashtable = new Node *[hashsize];
for (i = 0; i < hashsize; i++) {
hashtable[i] = 0;
}
index = -1;
current = 0;
}
// -----------------------------------------------------------------------------
// Hash::~Hash()
//
// Destructor.
//
// Inputs : None
//
// Output : None
//
// Side Effects : Total destruction.
// -----------------------------------------------------------------------------
Hash::~Hash() {
int i;
Node *n,*next;
for (i = 0; i < hashsize; i++) {
if (hashtable[i]) {
n = hashtable[i];
while (n) {
next = n->next;
delete n;
n = next;
}
}
}
delete [] hashtable;
}
// -----------------------------------------------------------------------------
// int Hash::h1(const char *key)
//
// Hashing function.
//
// Inputs : ASCII character string.
//
// Output : Hash table index.
//
// Side Effects : None
// -----------------------------------------------------------------------------
int Hash::h1(const char *key) {
int h = 0;
const char *c;
c = key;
while (*c) {
h = (128*h + *c) % hashsize;
c++;
}
return h;
}
// -----------------------------------------------------------------------------
// int Hash::add(const char *k, void *obj)
//
// Adds a new object to the hash table.
//
// Inputs :
// k = Hash key
// obj = Pointer to an object
//
// Output : 0 on success, -1 if item is already in hash table.
//
// Side Effects :
// Makes a new hash table entry.
// -----------------------------------------------------------------------------
int Hash::add(const char *k, void *obj) {
int hv;
Node *n,*prev;
hv = h1(k); // Get hash value
n = hashtable[hv];
prev = n;
while (n) {
if (strcmp(n->key,k) == 0) return -1; // Already in hash table
prev = n;
n = n->next;
}
// Safe to add this to the table
n = new Node(k,obj,0);
if (prev) prev->next = n;
else hashtable[hv] = n;
return 0;
}
// -----------------------------------------------------------------------------
// int Hash::add(const char *k, void *obj, void (*d)(void *))
//
// Adds a new object to the hash table. Allows additional specification of
// a callback function for object deletion.
//
// Inputs :
// k = Hash key
// obj = Object pointer
// d = Deletion function
//
// Output : 0 on success, -1 if item is already in hash table.
//
// Side Effects :
// Adds an entry to the hash table
// -----------------------------------------------------------------------------
int Hash::add(const char *k, void *obj, void (*d)(void *)) {
int hv;
Node *n,*prev;
hv = h1(k); // Get hash value
n = hashtable[hv];
prev = n;
while (n) {
if (strcmp(n->key,k) == 0) return -1; // Already in hash table
prev = n;
n = n->next;
}
// Safe to add this to the table
n = new Node(k,obj,d);
if (prev) prev->next = n;
else hashtable[hv] = n;
return 0;
}
// -----------------------------------------------------------------------------
// void *Hash::lookup(const char *k)
//
// Looks up a value in the hash table. Returns a pointer to the object if found.
//
// Inputs : k = key value
//
// Output : Pointer to object or NULL if not found.
//
// Side Effects : None
// -----------------------------------------------------------------------------
void *Hash::lookup(const char *k) {
int hv;
Node *n;
hv = h1(k); // Get hash value
n = hashtable[hv];
while (n) {
if (strcmp(n->key,k) == 0) return n->object;
n = n->next;
}
return 0;
}
// -----------------------------------------------------------------------------
// void Hash::remove(const char *k)
//
// Removes an item from the hash table. Does nothing if item isn't in the
// hash table to begin with.
//
// Inputs : k = Key value
//
// Output : None
//
// Side Effects : Deletes item from hash table.
// -----------------------------------------------------------------------------
void Hash::remove(const char *k) {
int hv;
Node *n,*prev;
hv = h1(k); // Get hash value
n = hashtable[hv];
prev = 0;
while (n) {
if (strcmp(n->key,k) == 0) {
// Found it, kill the thing
if (prev) {
prev->next = n->next;
} else {
hashtable[hv] = n->next;
}
delete n;
return;
}
prev = n;
n = n->next;
}
}
// -----------------------------------------------------------------------------
// void *Hash::first()
//
// Gets the first item from the hash table or NULL if empty.
//
// Inputs : None
//
// Output : First object in hash table or NULL if hash table is empty.
//
// Side Effects : Resets an internal iterator variable on the hash table.
// -----------------------------------------------------------------------------
void *Hash::first() {
index = 0;
current = 0;
while (!hashtable[index] && (index < hashsize))
index++;
if (index >= hashsize) return 0;
current = hashtable[index];
return current->object;
}
// -----------------------------------------------------------------------------
// char *Hash::firstkey()
//
// Gets the first key from the hash table or NULL if empty.
//
// Inputs : None
//
// Output : First key in hash table or NULL if hash table is empty.
//
// Side Effects : Resets an internal iterator variable on the hash table.
// -----------------------------------------------------------------------------
char *Hash::firstkey() {
index = 0;
current = 0;
while ((index < hashsize) && (!hashtable[index]))
index++;
if (index >= hashsize) return 0;
current = hashtable[index];
return current->key;
}
// -----------------------------------------------------------------------------
// void *Hash::next()
//
// Returns the next item in the hash table or NULL if there are no more entries.
// A call to first() should generally be made before using this function.
//
// Inputs : None
//
// Output : Pointer to next object or NULL if there are no more objects.
//
// Side Effects : Updates an iterator variable private to the hash table.
// -----------------------------------------------------------------------------
void *Hash::next() {
if (index < 0) return first();
// Try to move to the next entry
current = current->next;
if (current) {
return current->object;
} else {
index++;
while ((index < hashsize) && (!hashtable[index]))
index++;
if (index >= hashsize) return 0;
current = hashtable[index];
return current->object;
}
}
// -----------------------------------------------------------------------------
// char *Hash::nextkey()
//
// Returns the next key in the hash table or NULL if there are no more entries.
// A call to firstkey() should generally be made before using this function.
//
// Inputs : None
//
// Output : Pointer to next key or NULL if there are no more objects.
//
// Side Effects : Updates an iterator variable private to the hash table.
// -----------------------------------------------------------------------------
char *Hash::nextkey() {
if (index < 0) return firstkey();
// Try to move to the next entry
current = current->next;
if (current) {
return current->key;
} else {
index++;
while (!hashtable[index] && (index < hashsize))
index++;
if (index >= hashsize) return 0;
current = hashtable[index];
return current->key;
}
}

View File

@@ -0,0 +1,598 @@
/*******************************************************************************
* 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 "swig.h"
#include "html.h"
/*******************************************************************************
* $Header$
*
* File : html.cxx
*
* HTML specific functions for producing documentation.
*******************************************************************************/
#define PRE 0
#define FORMAT 1
// -----------------------------------------------------------------------------
// HTML::HTML()
//
// Constructor. Creates a new HTML documentation module object.
//
// Inputs : None
//
// Output : HTML Object
//
// Side Effects : None
// -----------------------------------------------------------------------------
HTML::HTML() {
sect_count = 0;
last_section = 0;
// Initialize default tags for various parts of the documentation
tag_body = "<BODY BGCOLOR=\"#ffffff\">:</BODY>";
tag_title = "<H1>:</H1>";
tag_contents = "<HR><H1>:</H1>";
tag_section = "<HR><H2>:</H2>";
tag_subsection = "<H3>:</H3>";
tag_subsubsection = "<H4>:</H4>";
tag_usage = "<P><TT><B>:</B></TT>";
tag_descrip = "<BLOCKQUOTE>:</BLOCKQUOTE>";
tag_text = "<P>";
tag_cinfo = "";
tag_preformat = "<PRE>:</PRE>";
}
// -----------------------------------------------------------------------------
// char *HTML::start_tag(char *tag)
//
// Utility function for returning the first part of an HTML tag variable.
// A tag must look like this :
//
// "<b>:</b>"
//
// The start tag for this would be "<b>"
//
// Inputs : tag = HTML tag string
//
// Output : Staring portion of the tag variable.
//
// Side Effects : None.
// -----------------------------------------------------------------------------
char *HTML::start_tag(char *tag) {
static String stag;
char *c;
stag = "";
c = tag;
while ((*c) && (*c != ':')) {
stag << *c;
c++;
}
return stag.get();
}
// -----------------------------------------------------------------------------
// char *HTML::end_tag(char *tag)
//
// Utility for returning an end-tag. The counterpart to start_tag().
//
// Inputs : tag = HTML tag string
//
// Output : Ending portion of tag variable.
//
// Side Effects : None
// -----------------------------------------------------------------------------
char *HTML::end_tag(char *tag) {
static String etag;
char *c;
etag = "";
c = tag;
while ((*c) && (*c != ':')) {
c++;
}
if (*c) {
c++;
while (*c) {
etag << *c;
c++;
}
}
return etag.get();
}
// -----------------------------------------------------------------------------
// void HTML::print_string(char *s, String &str, int mode)
//
// Outputs the contents of string s into String str. If mode is 1, we
// will reformat the text and apply a few common HTML character
// substitutions.
//
// Inputs : s = Documentation text string
// mode = Formatting mode (0 = preformat, 1 = formatted)
//
// Output : str = Output is append to str.
//
// Side Effects : None
// -----------------------------------------------------------------------------
void HTML::print_string(char *s, String &str,int mode) {
char *c;
c = s;
while (*c) {
switch(*c) {
case '\"':
str << "&quot;";
break;
case '&':
str << "&amp;";
break;
case '<':
if (mode == PRE)
str << "&lt;";
else
str << (char) *c;
break;
case '>':
if (mode == PRE)
str << "&gt;";
else
str << (char) *c;
break;
default :
str << (char ) *c;
break;
}
c++;
}
}
// -----------------------------------------------------------------------------
// void HTML::print_decl(DocEntry *de)
//
// Generates documentation for a declaration.
//
// Inputs : de = Documentation entry
//
// Output : None
//
// Side Effects : None
// -----------------------------------------------------------------------------
void HTML::print_decl(DocEntry *de) {
char *c;
c = de->usage.get();
while ((*c) && ((*c == ' ') || (*c == '\t') || (*c == '\n'))) c++;
if (c) {
s_doc << start_tag(tag_usage);
print_string(c,s_doc,PRE);
s_doc << end_tag(tag_usage) << "\n";
} else return;
// Only print this if there is information
if ((strlen(de->cinfo.get()) && de->print_info) || strlen(de->text.get())) {
s_doc << start_tag(tag_descrip);
if (!de->format)
s_doc << start_tag(tag_preformat);
}
// If there is any C annotation, print that
if (de->print_info) {
c = de->cinfo.get();
if (strlen(c) > 0) {
s_doc << start_tag(tag_cinfo);
s_doc << "[ ";
print_string(c,s_doc,PRE);
s_doc << " ]" << end_tag(tag_cinfo) << "\n";
if (de->format) s_doc << "<BR>";
}
}
c = de->text.get();
if (strlen(c) > 0) {
print_string(c,s_doc,de->format);
}
if ((strlen(de->cinfo.get()) && de->print_info) || strlen(de->text.get())) {
if (!de->format) s_doc << end_tag(tag_preformat);
s_doc << end_tag(tag_descrip) << "\n";
}
s_doc << "\n";
}
// -----------------------------------------------------------------------------
// void HTML::print_text(DocEntry *de)
//
// Generates documentation for a text-block. Strips any leading whitespace.
//
// Inputs : de = Documentation entry
//
// Output : None
//
// Side Effects : None
// -----------------------------------------------------------------------------
void HTML::print_text(DocEntry *de) {
char *c;
c = de->text.get();
if (strlen(c) > 0) {
s_doc << start_tag(tag_text);
if (!de->format)
s_doc << start_tag(tag_preformat);
print_string(c,s_doc,de->format);
if (!de->format)
s_doc << end_tag(tag_preformat) << "\n";
s_doc << end_tag(tag_text) << "\n";
}
}
// -----------------------------------------------------------------------------
// void HTML::title(DocEntry *de)
//
// Generates the title for an HTML document.
//
// Inputs : de = Title documentation entry
//
// Output : None
//
// Side Effects : None
// -----------------------------------------------------------------------------
void HTML::title(DocEntry *de) {
char *c;
c = de->usage.get();
if (strlen(c) > 0) {
s_title << "<HEAD>\n"
<< "<TITLE>\n";
print_string(c,s_title,PRE);
s_title << "</TITLE>\n"
<< start_tag(tag_body) << "\n";
s_title << start_tag(tag_title);
print_string(c,s_title,PRE);
s_title << end_tag(tag_title) << "\n";
}
if (!de->format)
s_title << start_tag(tag_preformat);
// If there is any C annotation, print that
if (de->print_info) {
c = de->cinfo.get();
if (strlen(c) > 0) {
s_title << start_tag(tag_cinfo) << "[ ";
print_string(c,s_title,de->format);
s_title << " ]" << end_tag(tag_cinfo);
if (de->format)
s_title << "<BR>\n";
else
s_title << "\n";
}
}
c = de->text.get();
if (strlen(c)) {
print_string(c,s_title,de->format);
}
if (!de->format)
s_title << end_tag(tag_preformat) << "\n";
}
// -----------------------------------------------------------------------------
// void HTML::newsection(DocEntry *de, int sectnum)
//
// Creates a new section. sect_count is used to determine the formatting of
// the header. Also fills in a table of contents
//
// Inputs :
// de = Documentation Entry
// sectnum = Section number
//
// Output : None
//
// Side Effects :
// Creates a new subsection. Updates HTML table of contents.
// -----------------------------------------------------------------------------
void HTML::newsection(DocEntry *de,int sectnum) {
int i,f;
char *c;
char *tag;
sect_num[sect_count] = sectnum;
sect_count++;
f = sect_count + 1;
if (f > 5) f = 5;
// Form table of contents
// if sect_count > last_section. We need to indent
// if sect_count < last_section. We need to pop out
if (sect_count > last_section) {
for (i = 0; i < sect_count - last_section; i++)
contents << "<UL>";
} else if (sect_count < last_section) {
for (i = 0; i < last_section - sect_count; i++)
contents << "</UL>";
}
last_section = sect_count;
contents << "<LI> <A HREF=\"#s";
s_doc << "<A name=\"s";
for (i = 0; i < sect_count; i++) {
s_doc << sect_num[i] << "_";
contents << sect_num[i] << "_";
}
contents << "\">";
// Figure out the tag fields
switch(f) {
case 1:
tag = tag_title;
break;
case 2:
tag = tag_section;
break;
case 3:
tag = tag_subsection;
break;
case 4:
tag = tag_subsubsection;
break;
default:
tag = tag_subsubsection;
}
s_doc << "\">\n"
<< start_tag(tag);
for (i = 0; i < sect_count; i++) {
s_doc << sect_num[i] << ".";
contents << sect_num[i] << ".";
}
c = de->usage.get();
s_doc << " ";
contents << " ";
print_string(c,s_doc,PRE);
print_string(c,contents,PRE);
s_doc << end_tag(tag) << "</A>\n";
contents << "</A>\n";
if (!de->format)
s_doc << start_tag(tag_preformat);
// If there is any C annotation, print that
if (de->print_info) {
c = de->cinfo.get();
if (strlen(c) > 0) {
s_doc << start_tag(tag_cinfo) << "[ ";
print_string(c,s_doc,de->format);
s_doc << " ]" << end_tag(tag_cinfo);
if (de->format)
s_doc << "<BR>\n";
else
s_doc << "\n";
}
}
// If there is a description text. Print it
c = de->text.get();
if (strlen(c) > 0) {
print_string(c,s_doc,de->format);
s_doc << "\n";
}
if (!de->format)
s_doc << end_tag(tag_preformat) << "\n";
}
// -----------------------------------------------------------------------------
// void HTML::endsection()
//
// Ends a subsection. It is an error to call this without first calling
// newsection previously.
//
// Inputs : None
//
// Output : None
//
// Side Effects : Closes current section and goes back to parent.
//
// -----------------------------------------------------------------------------
void HTML::endsection() {
if (sect_count > 0) sect_count--;
}
// -----------------------------------------------------------------------------
// void HTML::separator()
//
// Prints a separator after the declaration of a C++ class. Currently
// does nothing in HTML mode.
//
// Inputs : None
//
// Output : None
//
// Side Effects : None
// -----------------------------------------------------------------------------
void HTML::separator() {
}
// -----------------------------------------------------------------------------
// void HTML::init(char *filename)
//
// Initializes the HTML module and opens up the documentation file.
//
// Inputs : filename = Name of documentation file (without a suffix)
//
// Output : None
//
// Side Effects : Opens documentation file.
// -----------------------------------------------------------------------------
void HTML::init(char *filename) {
char f[256];
sprintf(f,"%s.html",filename);
f_doc = fopen(f,"w");
if (f_doc == NULL) {
fprintf(stderr,"Unable to open %s\n",f);
SWIG_exit(1);
}
/* Print a HTML banner */
fprintf(f_doc,"<HTML>\n");
}
// -----------------------------------------------------------------------------
// void HTML::close(void)
//
// Dumps the table of contents and forms the final documentation file. Closes
// the documentation file upon completion.
//
// Inputs : None
//
// Output : None
//
// Side Effects : Closes documentation file.
// -----------------------------------------------------------------------------
void HTML::close(void) {
int i;
for (i = 0; i < last_section; i++)
contents << "</UL>\n";
fprintf(f_doc,"%s\n",s_title.get());
if (last_section) {
fprintf(f_doc,"%s Contents %s\n",start_tag(tag_contents),end_tag(tag_contents));
fprintf(f_doc,"%s\n",contents.get());
}
fprintf(f_doc,"%s\n",s_doc.get());
fprintf(f_doc,"%s\n", end_tag(tag_body));
fprintf(f_doc,"</HTML>\n");
fclose(f_doc);
}
// -----------------------------------------------------------------------------
// void HTML::style(char *name, char *value)
//
// Process parameters given with the %style directive. Does nothing if an
// unrecognized parameter is given.
//
// Inputs :
// name = name of style parameter
// value = ASCII string with value of parameter.
//
// Output : None
//
// Side Effects : Updates internal style parameters.
// -----------------------------------------------------------------------------
void HTML::style(char *name, char *value) {
if (strcmp(name,"html_title") == 0) {
if (value)
tag_title = copy_string(value);
} else if (strcmp(name,"html_contents") == 0) {
if (value)
tag_contents = copy_string(value);
} else if (strcmp(name,"html_section") == 0) {
if (value)
tag_section = copy_string(value);
} else if (strcmp(name,"html_subsection") == 0) {
if (value)
tag_subsection = copy_string(value);
} else if (strcmp(name,"html_subsubsection") == 0) {
if (value)
tag_subsubsection = copy_string(value);
} else if (strcmp(name,"html_usage") == 0) {
if (value)
tag_usage = copy_string(value);
} else if (strcmp(name,"html_descrip") == 0) {
if (value)
tag_descrip = copy_string(value);
} else if (strcmp(name,"html_text") == 0) {
if (value)
tag_text = copy_string(value);
} else if (strcmp(name,"html_cinfo") == 0) {
if (value)
tag_cinfo = copy_string(value);
} else if (strcmp(name,"html_preformat") == 0) {
if (value)
tag_preformat = copy_string(value);
} else if (strcmp(name,"html_body") == 0) {
if (value)
tag_body = copy_string(value);
}
}
// -----------------------------------------------------------------------------
// void HTML::parse_args(int argc, char **argv)
//
// Parse command line options given on the SWIG command line.
//
// Inputs :
// argc = argument count
// argv = argument array
//
// Output : None
//
// Side Effects : Marks arguments as being parsed.
// -----------------------------------------------------------------------------
static char *html_usage = "\
HTML Documentation Options (available with -dhtml)\n\
None available.\n\n";
void HTML::parse_args(int argc, char **argv) {
int i;
for (i = 0; i < argc; i++) {
if (argv[i]) {
if (strcmp(argv[i],"-help") == 0) {
fputs(html_usage,stderr);
}
}
}
}

View File

@@ -0,0 +1,76 @@
/*******************************************************************************
* 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.
*******************************************************************************/
/***********************************************************************
* $Header$
*
* html.h
*
* HTML specific functions for producing documentation.
***********************************************************************/
class HTML : public Documentation {
private:
FILE *f_doc;
void print_string(char *s, String &str, int mode);
char *start_tag(char *);
char *end_tag(char *);
int sect_count;
int sect_num[20];
int last_section;
String s_doc;
String s_title;
String contents;
char *tag_body;
char *tag_title;
char *tag_contents;
char *tag_section;
char *tag_subsection;
char *tag_subsubsection;
char *tag_usage;
char *tag_descrip;
char *tag_text;
char *tag_cinfo;
char *tag_preformat;
public:
HTML();
void parse_args(int argc, char **argv);
void title(DocEntry *de);
void newsection(DocEntry *de, int sectnum);
void endsection();
void print_decl(DocEntry *de);
void print_text(DocEntry *de);
void separator();
void init(char *filename);
void close(void);
void style(char *name, char *value);
};

View File

@@ -0,0 +1,586 @@
/*******************************************************************************
* 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;
}

View File

@@ -0,0 +1,215 @@
/*******************************************************************************
* 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.
*******************************************************************************/
/***********************************************************************
* $Header$
*
* internals.h
*
* Contains global variables used in libswig, but which are otherwise
* inaccessible to the user.
*
***********************************************************************/
#include "swig.h"
// -------------------------------------------------------------------
// class DocTitle : public DocEntry
//
// Top level class for managing documentation. Prints out a title,
// date, etc...
// -------------------------------------------------------------------
class DocTitle : public DocEntry {
public:
DocTitle(char *title, DocEntry *_parent); // Create a new title
void output(Documentation *d); // Output documentation
};
// --------------------------------------------------------------------
// class DocSection : public DocEntry
//
// Documentation entry for a section
// --------------------------------------------------------------------
class DocSection : public DocEntry {
public:
DocSection(char *section, DocEntry *_parent);
void output(Documentation *d);
};
// --------------------------------------------------------------------
// class DocFunction : public DocEntry
//
// Documentation entry for generic sorts of declarations
// --------------------------------------------------------------------
class DocDecl : public DocEntry {
public:
DocDecl(char *fname, DocEntry *_parent);
DocDecl(DocEntry *de, DocEntry *_parent);
void output(Documentation *d);
};
// --------------------------------------------------------------------
// class DocClass : public DocEntry
//
// Documentation entry for a C++ class or C struct
// --------------------------------------------------------------------
class DocClass : public DocEntry {
public:
DocClass(char *classname, DocEntry *_parent);
void output(Documentation *d);
};
// --------------------------------------------------------------------
// class DocText : public DocEntry
//
// Documentation entry for some plain ole text. Declared using
// the %text %{,%} directive.
// --------------------------------------------------------------------
class DocText : public DocEntry {
public:
DocText(char *_text, DocEntry *_parent);
void output(Documentation *d);
};
// --------------------------------------------------------------------
// class CommentHandler
//
// Class for managing comment processing.
// --------------------------------------------------------------------
class CommentHandler {
public:
CommentHandler();
CommentHandler(CommentHandler *c);
~CommentHandler();
void add_comment(char *text, int line_num, int col, char *file); // Add a comment
void set_entry(DocEntry *d); // Set documentation entry
static void cleanup(); // Clean-up everything before quitting
void style(char *name, char *value);
void parse_args(int argc, char **argv); // Parse command line options
// Comment handling style parameters
int skip_lines; // # blank lines before comment is throw away
int location; // Comment location (BEFORE or AFTER)
int chop_top; // Lines to chop from the top of a comment
int chop_bottom; // Lines to chop from the bottom
int chop_left; // Characters to chop from left
int chop_right; // Characters to chop from right
int untabify; // Expand tabs
int ignore; // Ignore comments
};
#define BEFORE 0
#define AFTER 1
extern int include_file(char *); // Insert library file
extern char category[256];
extern char title[256];
extern DocEntry *doc_entry;
extern DocEntry *doctitle; // The very first docentry
extern DocEntry *doc_stack[256]; // Stack of documentation entries
extern CommentHandler *handler_stack[256]; // Stack of comment handlers
extern int doc_stack_top; // Top of stack
extern Language *lang;
extern Documentation *doc;
extern CommentHandler *comment_handler; // Comment handling system
extern void swig_append(char *, FILE *);
extern int Stat_func, Stat_var, Stat_const;
extern int IgnoreDoc;
extern int ForceExtern;
extern int WrapExtern;
extern String CCode;
extern int GenerateDefault;
extern int type_id;
extern char *ConfigFile;
extern char *objc_construct;
extern char *objc_destruct;
extern int DocOnly;
// Structure for holding typemap parameters
// A typemap parameter consists of a single parameter (type + name)
// and an optional list of arguments corresponding to local variables.
// Has an optional link for building linked lists of parameter lists
struct TMParm {
Parm *p;
ParmList *args;
TMParm *next;
TMParm() {
next = 0;
}
};
/* Global variables. Needs to be cleaned up */
#ifdef WRAP
FILE *f_header; // Some commonly used
FILE *f_wrappers; // FILE pointers
FILE *f_init;
FILE *f_input;
char InitName[256];
char LibDir[512]; // Library directory
char **InitNames = 0;
int Status;
int TypeStrict; // Type checking strictness
int Verbose;
char category[256]; // Variables for documentation
char title[256];
DocEntry *doc_entry = 0; // Current documentation entry
DocEntry *doctitle = 0; // First doc entry
DocEntry *doc_stack[256]; // Stack of documentation entries
CommentHandler *handler_stack[256]; // Stack of comment handlers
int doc_stack_top = 0; // Top of stack
Language *lang; // Language method
Documentation *doc; // Documentation method
int Stat_func = 0;
int Stat_var = 0;
int Stat_const = 0;
int CPlusPlus = 0;
int ObjC = 0;
int ObjCClass = 0;
int AddMethods = 0; // AddMethods flag
int NewObject = 0; // NewObject flag
int Inline = 0; // Inline mode
int Stats = 0;
int IgnoreDoc = 0; // Ignore documentation mode
int ForceExtern = 0; // Force extern mode
int WrapExtern = 0;
int GenerateDefault = 0; // Generate default constructors
char *Config = 0;
int NoInclude = 0;
char *typemap_lang = 0; // Typemap name
int type_id = 0; // Type identifier
int error_count = 0; // Error count
char *ConfigFile = 0;
int DocOnly = 0; // Only produce documentation
#endif
/* Number of initialization names that can be used */
#define NI_NAMES 512
extern void type_undefined_check(void);

View File

@@ -0,0 +1,621 @@
/*******************************************************************************
* 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 <ctype.h>
// -----------------------------------------------------------------------
// $Header$
//
// lang.cxx
//
// This file contains some default methods for the SWIG language class.
// Default C++ handling is implemented here as well as a few utility functions.
//
// -----------------------------------------------------------------------
// -----------------------------------------------------------------
// void Language::set_init(char *iname)
//
// Called to make an initialization function by %init (obsolete)
// -----------------------------------------------------------------
void Language::set_init(char *iname) {
set_module(iname,0);
}
// -----------------------------------------------------------------
// void Language::create_command(char *cname, char *iname
//
// Method for adding a previous wrapped C function.
// -----------------------------------------------------------------
void Language::create_command(char *, char *) {
fprintf(stderr,"SWIG Warning. No command creation procedure defined.\n");
fprintf(stderr,"C++ inheritance may not work correctly.\n");
}
// -----------------------------------------------------------------
// void Language::add_native(char *targetlang, char *funcname)
//
// Method for adding a native function
// -----------------------------------------------------------------
void
Language::add_native(char *, char *funcname) {
fprintf(stderr,"%s : Line %d. Adding native function %s not supported (ignored).\n", input_file, line_number, funcname);
}
static char *ClassName = 0; // This is the real name of the current class
static char *ClassRename = 0; // This is non-NULL if the class has been renamed
static char *ClassType = 0; // Type of class (ie. union, struct, class)
// ---------------------------------------------------------------------------------
// void Language::cpp_open_class(char *classname, char *classrename, char *ctype, int strip)
//
// Open a new C++ class.
//
// INPUTS:
// classname = Real name of the C++ class
// classrename = New name of the class (if %name was used)
// ctype = Class type (struct, class, union, etc...)
// strip = Flag indicating whether we should strip the class type off
//
// This function is in charge of creating a new class. The SWIG parser has
// already processed the entire class definition prior to calling this
// function (which should simplify things considerably).
//
// ---------------------------------------------------------------------------------
void Language::cpp_open_class(char *classname, char *classrename, char *ctype, int strip) {
// Copy the class name
if (ClassName) delete ClassName;
ClassName = copy_string(classname);
// Copy the class renaming
if (ClassRename) delete ClassRename;
if (classrename) {
ClassRename = copy_string(classrename);
} else {
ClassRename = 0; // No renaming
}
// Make the class type
if (ClassType) delete ClassType;
ClassType = new char[strlen(ctype)+2];
if (strip) ClassType[0] = 0;
else sprintf(ClassType,"%s ",ctype);
if (doc_entry) {
doc_entry->usage = "";
doc_entry->name = copy_string(classname);
doc_entry->usage << "class ";
if (ClassRename) doc_entry->usage << ClassRename;
else doc_entry->usage << ClassName;
doc_entry->cinfo << "created from " << ctype
<< " " << classname;
}
}
// ---------------------------------------------------------------------------------
// void Language::cpp_close_class()
//
// Close the current class
// ---------------------------------------------------------------------------------
void Language::cpp_close_class() {
// Doesn't really do anything
}
// ---------------------------------------------------------------------------------
// void Language::cpp_member_func(char *name, char *iname, DataType *t, ParmList *l)
//
// Method for adding C++ member function
//
// INPUTS:
// name - name of the member function
// iname - renaming (if given)
// t - Return datatype
// l - Parameter list
//
// By default, we're going to create a function of the form :
//
// Foo_bar(this,args)
//
// Where Foo is the classname, bar is the member name and the this pointer is
// explicitly attached to the beginning.
//
// The renaming only applies to the member function part, not the full classname.
//
// ---------------------------------------------------------------------------------
void Language::cpp_member_func(char *name, char *iname, DataType *t, ParmList *l) {
char cname[256]; // Name of the C function
char new_name[256];
char *prefix;
// Generate the C wrapper function name and interpreter name of this function
// Set the classname prefix
if (ClassRename) {
prefix = ClassRename;
} else {
prefix = ClassName;
}
// Generate the C wrapper name for this method
if (AddMethods) {
char *bc = cplus_base_class(name); // Get base class name of this method
if (bc)
strcpy(cname, name_member(name,bc));
else
strcpy(cname, name_member(name,ClassName));
} else {
strcpy(cname, name_member(name,ClassName));
}
// Create the actual function name
if (iname) {
strcpy(new_name, name_member(iname, prefix));
} else {
strcpy(new_name, name_member(name,prefix));
}
// Now do a symbol table lookup on it :
if (add_symbol(new_name, 0,0)) {
fprintf(stderr,"%s : Line %d. Function %s (member %s) multiply defined (2nd definition ignored).\n",
input_file, line_number, cname, name);
return;
}
// Now produce the resulting wrapper function
if (doc_entry) {
doc_entry->cinfo << "Member : ";
}
cplus_emit_member_func(ClassName, ClassType, ClassRename, name, iname, t, l, AddMethods);
}
// ---------------------------------------------------------------------------------
// void Language::cpp_constructor(char *name, char *iname, ParmList *l)
//
// Method for adding C++ member constructor
//
// INPUTS:
// name - Name of the constructor (usually same as classname)
// iname - Renamed version
// l - parameters
// ---------------------------------------------------------------------------------
void Language::cpp_constructor(char *name, char *iname, ParmList *l) {
char *prefix, *cname;
if ((strcmp(name,ClassName)) && (!ObjCClass)) {
fprintf(stderr,"%s : Line %d. Function %s must have a return type.\n",
input_file, line_number, name);
return;
}
// Set the prefix
if (ClassRename)
prefix = ClassRename;
else
prefix = ClassName;
if (iname)
cname = name_construct(iname);
else
cname = name_construct(prefix);
// Add this function to the SWIG symbol table
if (add_symbol(cname, 0,0)) {
fprintf(stderr,"%s : Line %d. Constructor %s multiply defined (2nd definition ignored).\n",
input_file, line_number, cname);
return;
}
// Attach a note to the cinfo field.
if (doc_entry)
doc_entry->cinfo << "Constructor: ";
// Call our default method
cplus_emit_constructor(ClassName, ClassType, ClassRename, name, iname, l, AddMethods);
}
// ---------------------------------------------------------------------------------
// void Language::cpp_destructor(char *name, char *iname)
//
// Method for adding C++ member destructor
//
// INPUT:
// name - Name of the destructor (classname)
// iname - Renamed destructor
//
// ---------------------------------------------------------------------------------
void Language::cpp_destructor(char *name, char *iname) {
char *cname;
if (ClassRename)
cname = name_destroy(ClassRename);
else
cname = name_destroy(ClassName);
// Add this function to the SWIG symbol table
if (add_symbol(cname, 0,0)) {
fprintf(stderr,"%s : Line %d. Destructor %s multiply defined (2nd definition ignored).\n",
input_file, line_number, cname);
return;
}
// Attach a note to the description
if (doc_entry)
doc_entry->cinfo << "Destructor: ";
// Call our default method
cplus_emit_destructor(ClassName, ClassType, ClassRename, name, iname, AddMethods);
}
// ---------------------------------------------------------------------------------
// void Language::cleanup()
//
// Perform any necessary cleanup after reaching end of interface file
// ---------------------------------------------------------------------------------
void Language::cpp_cleanup() {
// This doesn't do anything (well, not be default)
}
// ---------------------------------------------------------------------------------
// void Language::cpp_inherit(char **baseclass, int mode)
//
// Inherit attributes from given baseclass.
//
// INPUT:
// baseclass = NULL terminate list of baseclasses
//
// ---------------------------------------------------------------------------------
void Language::cpp_inherit(char **baseclass, int mode) {
extern void cplus_inherit_members(char *, int);
int i = 0;
if (!baseclass) return;
while (baseclass[i]) {
cplus_inherit_members(baseclass[i],mode);
i++;
}
}
// ---------------------------------------------------------------------------------
// void Language::cpp_variable(char *name, char *iname, DataType *t)
//
// Wrap a C++ data member
//
// INPUTS :
// name = Name of the C++ member
// iname = Name as used in the interpreter
// t = Datatype
//
// This creates a pair of functions to set/get the variable of a member.
// ---------------------------------------------------------------------------------
void Language::cpp_variable(char *name, char *iname, DataType *t) {
char *prefix, *cname;
// Set the class prefix
if (ClassRename) {
prefix = ClassRename;
} else {
prefix = ClassName;
}
if (iname)
cname = name_get(name_member(iname,prefix));
else
cname = name_get(name_member(name,prefix));
// Check the symbol table
if (add_symbol(cname,(DataType *) 0,(char *) 0)) {
fprintf(stderr,"%s : Line %d. Variable %s multiply defined (2nd definition ignored).\n", input_file, line_number, cname);
return;
}
// Attach a c descriptor
if (doc_entry)
doc_entry->cinfo << "Member data: ";
// Create a function to set the value of the variable
if (!(Status & STAT_READONLY)) {
cplus_emit_variable_set(ClassName, ClassType, ClassRename, name, iname, t, AddMethods);
// Add a new line to the documentation entry
if (doc_entry) doc_entry->usage << "\n";
}
// Create a function to get the value of a variable
cplus_emit_variable_get(ClassName,ClassType, ClassRename, name, iname, t, AddMethods);
}
// ---------------------------------------------------------------------------------
// void Language::cpp_static_func(char *name, char *iname, DataType *t, ParmList *l)
//
// Wrap a static C++ function
//
// INPUTS:
// name = Real name of the function
// iname = New name in interpreter
// t = Return datatype
// l = Parameters
// ---------------------------------------------------------------------------------
void Language::cpp_static_func(char *name, char *iname, DataType *t, ParmList *l) {
char *prefix;
char *mname;
char *cname;
// Set the classname prefix
if (ClassRename)
prefix = ClassRename;
else
prefix = ClassName;
// Set the member function name
if (iname)
mname = iname;
else
mname = name;
cname = name_member(mname,prefix);
// Now do a symbol table lookup on it :
if (add_symbol(cname, 0,0)) {
if (ObjCClass)
fprintf(stderr,"%s : Line %d. class function %s multiply defined (2nd definition ignored).\n",
input_file, line_number, cname);
else
fprintf(stderr,"%s : Line %d. static function %s multiply defined (2nd definition ignored).\n",
input_file, line_number, cname);
return;
}
if (doc_entry) {
if (ObjCClass)
doc_entry->cinfo << "Class method : ";
else
doc_entry->cinfo << "Static member : ";
}
cplus_emit_static_func(ClassName,ClassType, ClassRename, name, iname, t, l, AddMethods);
}
// ---------------------------------------------------------------------------------
// void Language::cpp_declare_const(char *name, char *iname, DataType *t, char *value)
//
// Create a C++ constant
//
// INPUTS :
// name = Real name of the constant
// iname = new name
// t = Datatype
// value = value as a string
//
// ---------------------------------------------------------------------------------
void Language::cpp_declare_const(char *name, char *iname, DataType *type, char *value)
{
char *cname;
char mname[256];
char *new_value;
char *prefix;
// Set the classname prefix
if (ClassRename) {
prefix = ClassRename;
} else {
prefix = ClassName;
}
// Set the constant name
if (iname)
cname = name_member(iname,prefix);
else
cname = name_member(name,prefix);
// Now do a symbol table lookup on it :
if (add_symbol(cname, 0,0)) {
fprintf(stderr,"%s : Line %d. Constant %s (member %s) multiply defined (2nd definition ignored).\n",
input_file, line_number, cname, name);
return;
}
// Form correct C++ name
sprintf(mname,"%s::%s",ClassName,name);
// Declare a constant
if (!value) {
new_value = new char[strlen(ClassName)+strlen(name)+3];
sprintf(new_value,"%s::%s",ClassName,name);
} else {
new_value = value;
}
lang->declare_const(cname,cname,type, new_value);
if (!value) {
delete new_value;
}
}
// ---------------------------------------------------------------------------------
// void Language::cpp_static_var(char *name, char *iname, DataType *t)
//
// Wrap a static C++ variable
//
// INPUT :
// name = name of the variable
// iname = interpreter name
// t = Datatype
//
// ---------------------------------------------------------------------------------
void Language::cpp_static_var(char *name, char *iname, DataType *t) {
char *cname;
char mname[256];
char *prefix;
// Set the classname prefix
if (ClassRename) {
prefix = ClassRename;
} else {
prefix = ClassName;
}
// Create the variable name
if (iname)
cname = name_member(iname,prefix);
else
cname = name_member(name,prefix);
// Now do a symbol table lookup on it :
if (add_symbol(cname, 0,0)) {
fprintf(stderr,"%s : Line %d. Variable %s (member %s) multiply defined (2nd definition ignored).\n",
input_file, line_number, cname, name);
return;
}
// Form correct C++ name
sprintf(mname,"%s::%s",ClassName,name);
if (doc_entry)
doc_entry->cinfo << "Static member : ";
// Link with this variable
lang->link_variable(mname,cname,t);
}
// ---------------------------------------------------------------------------------
// void Language::cpp_class_decl(char *classtype, char *classrename, char *classname)
//
// A forward class declaration
// ---------------------------------------------------------------------------------
void Language::cpp_class_decl(char *, char *, char *) {
// Does nothing by default
}
// -----------------------------------------------------------------------------
// void Language::cpp_pragma(Pragma *plist)
//
// Handler C++ pragmas
// -----------------------------------------------------------------------------
void Language::cpp_pragma(Pragma *) {
// Does nothing by default
}
// ---------------------------------------------------------------------------------
// void Language::add_typedef(DataType *t, char *name)
//
// Process a typedef declaration.
// ---------------------------------------------------------------------------------
void Language::add_typedef(DataType *, char *) {
}
// ---------------------------------------------------------------------------------
// void Language::pragma(char *target, char *var, char *value)
//
// A pragma declaration
// ---------------------------------------------------------------------------------
void Language::pragma(char *, char *, char *) {
// Does nothing by default
}
// ---------------------------------------------------------------------------------
// void Language::import(char *filename)
//
// An import directive
// ---------------------------------------------------------------------------------
void Language::import(char *) {
// Does nothing by default
}

View File

@@ -0,0 +1,490 @@
/*******************************************************************************
* 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.
*******************************************************************************/
/***********************************************************************
* $Header$
*
* latex.c
*
* Latex specific functions for producing documentation.
*
***********************************************************************/
#include "swig.h"
#include "latex.h"
// -------------------------------------------------------------------
// LATEX::LATEX()
//
// Create new LaTeX handler
// -------------------------------------------------------------------
LATEX::LATEX() {
sect_count = 0;
tag_pagestyle = "\\pagestyle{headings}";
tag_parindent = "0.0in";
tag_textwidth = "6.5in";
tag_documentstyle = "[11pt]{article}";
tag_oddsidemargin = "0.0in";
tag_title = "{\\Large \\bf : }";
tag_preformat = "{\\small \\begin{verbatim}:\\end{verbatim}}";
tag_usage = "{\\tt \\bf : }";
tag_descrip = "\\\\\n\\makebox[0.5in]{}\\begin{minipage}[t]{6in}:\n\\end{minipage}\\\\\n";
tag_text = ":\\\\";
tag_cinfo = "{\\tt : }\\\\";
tag_section = "\\section{:}";
tag_subsection="\\subsection{:}";
tag_subsubsection="\\subsubsection{:}";
}
// -------------------------------------------------------------------
// char *start_tag(char *tag) {
//
// Returns the start of a tag
// -------------------------------------------------------------------
char *LATEX::start_tag(char *tag) {
static String stag;
char *c;
stag = "";
c = tag;
while ((*c) && (*c != ':')) {
stag << *c;
c++;
}
return stag.get();
}
// -------------------------------------------------------------------
// char *end_tag(char *tag) {
//
// Returns the end of a tag
// -------------------------------------------------------------------
char *LATEX::end_tag(char *tag) {
static String etag;
char *c;
etag = "";
c = tag;
while ((*c) && (*c != ':')) {
c++;
}
if (*c) {
c++;
while (*c) {
etag << *c;
c++;
}
}
return etag.get();
}
// -------------------------------------------------------------------
// LATEX::print_string(char *s, String &str)
//
// Dumps string s to str, but performs some LaTeX character replacements
// -------------------------------------------------------------------
void LATEX::print_string(char *s, String &str) {
char *c;
c = s;
while (*c) {
switch(*c) {
case '*':
case '<':
case '>':
case '+':
case '=':
case '|':
str << "$" << *c << "$";
break;
case '\\':
str << "\\\\";
break;
case '_':
str << "\\_";
break;
case '%':
str << "\\%";
break;
case '$':
str << "\\$";
break;
case '&':
str << "\\&";
break;
case '#':
str << "\\#";
break;
case '\n':
str << "\\\\\n";
break;
default :
str << *c;
break;
}
c++;
}
}
// --------------------------------------------------------------
// LATEX::print_decl(DocEntry *)
//
// Print a documentation entry
// --------------------------------------------------------------
void LATEX::print_decl(DocEntry *de) {
char *c;
c = de->usage.get();
if (c) {
s_doc << start_tag(tag_usage);
print_string(c,s_doc);
s_doc << end_tag(tag_usage) << "\n";
}
// Check to see if there any information available
if ((strlen(de->cinfo.get()) && de->print_info) || strlen(de->text.get())) {
// There is additional information now. If we're in preformatting mode,
// we need to handle things differently
s_doc << start_tag(tag_descrip) << "\n";
if (!de->format) {
// Verbatim mode
s_doc << start_tag(tag_preformat) << "\n";
// If there is any C annotation, print that
if (de->print_info) {
c = de->cinfo.get();
if (strlen(c) > 0) {
s_doc << "[ " << c << " ]\n";
}
}
c = de->text.get();
if (strlen(c) > 0) {
s_doc << c;
}
s_doc << end_tag(tag_preformat) << "\n";
} else {
// We are in format mode now
// We need to emit some stubs for the description format
// If there is any C annotation, print that
if (de->print_info) {
c = de->cinfo.get();
if (strlen(c) > 0) {
s_doc << start_tag(tag_cinfo) << "[ ";
print_string(c,s_doc);
s_doc << " ] " << end_tag(tag_cinfo) << "\n";
}
}
// Print out descriptive text (if any).
c = de->text.get();
if (strlen(c) > 0) {
s_doc << c << "\\\\\n";
}
}
s_doc << end_tag(tag_descrip) << "\n";
} else {
s_doc << "\\\\\n"; // No description available, move to next line
}
}
// --------------------------------------------------------------
// LATEX::print_text(DocEntry *de)
//
// Print out some text. We use verbatim mode because of formatting
// problems.
// --------------------------------------------------------------
void LATEX::print_text(DocEntry *de) {
char *c;
c = de->text.get();
if (strlen(c) > 0) {
if (de->format) {
s_doc << start_tag(tag_text) << "\n";
s_doc << c;
s_doc << end_tag(tag_text) << "\n\n";
} else {
s_doc << start_tag(tag_preformat) << "\n";
s_doc << c;
s_doc << end_tag(tag_preformat) << "\n\n";
}
}
}
void LATEX::title(DocEntry *de) {
char *c;
c = de->usage.get();
if (strlen(c) > 0) {
s_doc << start_tag(tag_title) << " ";
print_string(c,s_doc);
s_doc << end_tag(tag_title) << "\\\\\n";
}
// Print out any C annotation and descriptive text
// Check to see if there any information available
if ((strlen(de->cinfo.get()) && de->print_info) || strlen(de->text.get())) {
// There is additional information now. If we're in preformatting mode,
// we need to handle things differently
if (!de->format) {
// Verbatim mode
s_doc << start_tag(tag_preformat) << "\n";
// If there is any C annotation, print that
if (de->print_info) {
c = de->cinfo.get();
if (strlen(c) > 0) {
s_doc << "[ " << c << " ]\n";
}
}
c = de->text.get();
if (strlen(c) > 0) {
s_doc << c;
}
s_doc << end_tag(tag_preformat) << "\n\n";
} else {
// We are in format mode now
// We need to emit some stubs for the description format
s_doc << start_tag(tag_text);
// If there is any C annotation, print that
if (de->print_info) {
c = de->cinfo.get();
if (strlen(c) > 0) {
s_doc << start_tag(tag_cinfo) << "[ ";
print_string(c,s_doc);
s_doc << " ] " << end_tag(tag_cinfo) << "\n";
}
}
// Print out descriptive text (if any).
c = de->text.get();
if (strlen(c) > 0) {
s_doc << c;
}
s_doc << end_tag(tag_text);
}
}
}
void LATEX::newsection(DocEntry *de,int sectnum) {
char *c;
char *tag;
sect_num[sect_count] = sectnum;
sect_count++;
switch (sect_count) {
case 1: /* Section */
tag = tag_section;
break;
case 2: /* Subsection */
tag = tag_subsection;
break;
default: /* subsubsection */
tag = tag_subsubsection;
break;
}
s_doc << start_tag(tag);
c = de->usage.get();
print_string(c,s_doc);
s_doc << end_tag(tag);
// Print out any C annotation and descriptive text
// Check to see if there any information available
if ((strlen(de->cinfo.get()) && de->print_info) || strlen(de->text.get())) {
// There is additional information now. If we're in preformatting mode,
// we need to handle things differently
if (!de->format) {
// Verbatim mode
s_doc << start_tag(tag_preformat) << "\n";
// If there is any C annotation, print that
if (de->print_info) {
c = de->cinfo.get();
if (strlen(c) > 0) {
s_doc << "[ " << c << " ]\n";
}
}
c = de->text.get();
if (strlen(c) > 0) {
s_doc << c;
}
s_doc << end_tag(tag_preformat) << "\n\n";
} else {
// We are in format mode now
// We need to emit some stubs for the description format
s_doc << start_tag(tag_text);
// If there is any C annotation, print that
if (de->print_info) {
c = de->cinfo.get();
if (strlen(c) > 0) {
s_doc << start_tag(tag_cinfo) << "[ ";
print_string(c,s_doc);
s_doc << " ] " << end_tag(tag_cinfo) << "\n";
}
}
// Print out descriptive text (if any).
c = de->text.get();
if (strlen(c) > 0) {
s_doc << c;
}
s_doc << end_tag(tag_text);
}
}
}
void LATEX::endsection() {
if (sect_count > 0) sect_count--;
}
void LATEX::separator() {
}
void LATEX::init(char *filename) {
char f[256];
sprintf(f,"%s.tex",filename);
sprintf(fn,"%s",filename);
f_doc = fopen(f,"w");
if (f_doc == NULL) {
fprintf(stderr, "Unable to open %s\n", fn);
SWIG_exit(1);
}
}
void LATEX::close(void) {
fprintf(f_doc,"\\documentstyle%s\n",tag_documentstyle);
fprintf(f_doc,"\\setlength{\\parindent}{%s}\n",tag_parindent);
fprintf(f_doc,"\\setlength{\\textwidth}{%s}\n",tag_textwidth);
fprintf(f_doc,"\\setlength{\\oddsidemargin}{%s}\n",tag_oddsidemargin);
fprintf(f_doc,"%s\n",tag_pagestyle);
fprintf(f_doc,"\\begin{document}\n");
fprintf(f_doc,"%s\n",s_doc.get());
fprintf(f_doc,"\\end{document}\n");
fclose(f_doc);
if (Verbose)
fprintf(stderr,"Documentation written to %s.tex\n", fn);
}
// -------------------------------------------------------------------
// LATEX::style(char *name, char *value)
//
// Process style parameters
// -------------------------------------------------------------------
void LATEX::style(char *name, char *value) {
if (strcmp(name,"latex_title") == 0) {
if (value)
tag_title = copy_string(value);
} else if (strcmp(name,"latex_pagestyle") == 0) {
if (value)
tag_pagestyle = copy_string(value);
} else if (strcmp(name,"latex_section") == 0) {
if (value)
tag_section = copy_string(value);
} else if (strcmp(name,"latex_subsection") == 0) {
if (value)
tag_subsection = copy_string(value);
} else if (strcmp(name,"latex_subsubsection") == 0) {
if (value)
tag_subsubsection = copy_string(value);
} else if (strcmp(name,"latex_usage") == 0) {
if (value)
tag_usage = copy_string(value);
} else if (strcmp(name,"latex_descrip") == 0) {
if (value)
tag_descrip = copy_string(value);
} else if (strcmp(name,"latex_text") == 0) {
if (value)
tag_text = copy_string(value);
} else if (strcmp(name,"latex_cinfo") == 0) {
if (value)
tag_cinfo = copy_string(value);
} else if (strcmp(name,"latex_preformat") == 0) {
if (value)
tag_preformat = copy_string(value);
} else if (strcmp(name,"latex_parindent") == 0) {
if (value)
tag_parindent = copy_string(value);
} else if (strcmp(name,"latex_textwidth") == 0) {
if (value)
tag_textwidth = copy_string(value);
} else if (strcmp(name,"latex_documentstyle") == 0) {
if (value)
tag_documentstyle = copy_string(value);
} else if (strcmp(name,"latex_oddsidemargin") == 0) {
if (value)
tag_oddsidemargin = copy_string(value);
}
}
// -------------------------------------------------------------------
// LATEX::parse_args(int argc, char **argv)
//
// Parse command line options
// -------------------------------------------------------------------
static char *latex_usage = "\
LATEX Documentation Options (available with -dlatex)\n\
None available.\n\n";
void LATEX::parse_args(int argc, char **argv) {
int i;
for (i = 0; i < argc; i++) {
if (argv[i]) {
if (strcmp(argv[i],"-help") == 0) {
fputs(latex_usage,stderr);
}
}
}
}

View File

@@ -0,0 +1,79 @@
/*******************************************************************************
* 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.
*******************************************************************************/
/***********************************************************************
* $Header$
*
* latex.h
*
* Latex specific functions for producing documentation.
***********************************************************************/
class LATEX : public Documentation {
private:
FILE *f_doc;
String s_doc;
char fn[256];
char *start_tag(char *);
char *end_tag(char *);
void print_string(char *s, String &str);
int sect_count; // Section counter
int sect_num[20]; // Section numbers
// Style parameters
char *tag_parindent;
char *tag_textwidth;
char *tag_documentstyle;
char *tag_oddsidemargin;
char *tag_title;
char *tag_preformat;
char *tag_usage;
char *tag_descrip;
char *tag_text;
char *tag_cinfo;
char *tag_pagestyle;
char *tag_section;
char *tag_subsection;
char *tag_subsubsection;
public:
LATEX();
void parse_args(int argc, char **argv);
void title(DocEntry *de);
void newsection(DocEntry *de, int sectnum);
void endsection();
void print_decl(DocEntry *de);
void print_text(DocEntry *de);
void separator();
void init(char *filename);
void close(void);
void style(char *name, char *value);
};

View File

@@ -0,0 +1,643 @@
/*******************************************************************************
* 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.
*******************************************************************************/
/***********************************************************************
* $Header$
*
* main.cxx
*
* The main program.
*
***********************************************************************/
#define WRAP
#include "internal.h"
#include "ascii.h"
#include "latex.h"
#include "html.h"
#include "nodoc.h"
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
class SwigException {};
static char *usage = "\
\nDocumentation Options\n\
-dascii - ASCII documentation.\n\
-dhtml - HTML documentation.\n\
-dlatex - LaTeX documentation.\n\
-dnone - No documentation.\n\n\
General Options\n\
-c - Produce raw wrapper code (omit support code)\n\
-c++ - Enable C++ processing\n\
-ci - Check a file into the SWIG library\n\
-co - Check a file out of the SWIG library\n\
-d docfile - Set name of the documentation file.\n\
-Dsymbol - Define a symbol (for conditional compilation)\n\
-I<dir> - Look for SWIG files in <dir>\n\
-l<ifile> - Include SWIG library file.\n\
-make_default - Create default constructors/destructors\n\
-nocomment - Ignore all comments (for documentation).\n\
-o outfile - Set name of the output file.\n\
-objc - Enable Objective C processing\n\
-stat - Print statistics\n\
-strict n - Set pointer type-checking strictness\n\
-swiglib - Report location of SWIG library and exit\n\
-t typemap_file - Use a typemap file.\n\
-v - Run in verbose mode\n\
-version - Print SWIG version number\n\
-help - This output.\n\n";
//-----------------------------------------------------------------
// main()
//
// Main program. Initializes the files and starts the parser.
//-----------------------------------------------------------------
char infilename[256];
char filename[256];
char fn_header[256];
char fn_wrapper[256];
char fn_init[256];
char output_dir[512];
#ifdef MACSWIG
FILE *swig_log;
#endif
char *SwigLib;
//char** __argv;
//int __argc;
int SWIG_main(int argc, char *argv[], Language *l, Documentation *d) {
int i;
char *c;
extern FILE *LEX_in;
extern void add_directory(char *);
extern char *get_time();
char temp[512];
char infile[512];
char *outfile_name = 0;
extern int add_iname(char *);
int help = 0;
int ignorecomments = 0;
int checkout = 0;
int checkin = 0;
char *typemap_file = 0;
char *includefiles[256];
int includecount = 0;
extern void check_suffix(char *);
extern void scanner_file(FILE *);
#ifdef MACSWIG
try {
#endif
f_wrappers = 0;
f_init = 0;
f_header = 0;
//__argc = argc;
//__argv = argv;
lang = l;
doc = d;
Status = 0;
TypeStrict = 2; // Very strict type checking
Verbose = 0;
char *doc_file = 0;
DataType::init_typedef(); // Initialize the type handler
// Set up some default symbols (available in both SWIG interface files
// and C files)
add_symbol("SWIG",0,0); // Define the SWIG symbol
#ifdef MACSWIG
add_symbol("SWIGMAC",0,0);
#endif
#ifdef SWIGWIN32
add_symbol("SWIGWIN32",0,0);
#endif
strcpy(LibDir, getSwigLib());
SwigLib = copy_string(LibDir); // Make a copy of the real library location
#ifdef MACSWIG
sprintf(temp,"%s:config", LibDir);
add_directory(temp);
add_directory(":swig_lib:config");
add_directory(LibDir);
add_directory(":swig_lib");
#else
sprintf(temp,"%s/config", LibDir);
add_directory(temp);
add_directory("./swig_lib/config");
add_directory(LibDir);
add_directory("./swig_lib");
sprintf(InitName,"init_wrap");
#endif
sprintf(InitName,"init_wrap");
// Get options
for (i = 1; i < argc; i++) {
if (argv[i]) {
if (strncmp(argv[i],"-I",2) == 0) {
// Add a new directory search path
includefiles[includecount++] = copy_string(argv[i]+2);
mark_arg(i);
} else if (strncmp(argv[i],"-D",2) == 0) {
// Create a symbol
add_symbol(argv[i]+2, (DataType *) 0, (char *) 0);
mark_arg(i);
} else if (strcmp(argv[i],"-strict") == 0) {
if (argv[i+1]) {
TypeStrict = atoi(argv[i+1]);
mark_arg(i);
mark_arg(i+1);
i++;
} else {
arg_error();
}
} else if ((strcmp(argv[i],"-verbose") == 0) || (strcmp(argv[i],"-v") == 0)) {
Verbose = 1;
mark_arg(i);
} else if (strcmp(argv[i],"-dascii") == 0) {
doc = new ASCII;
mark_arg(i);
} else if (strcmp(argv[i],"-dnone") == 0) {
doc = new NODOC;
mark_arg(i);
} else if (strcmp(argv[i],"-dhtml") == 0) {
doc = new HTML;
mark_arg(i);
} else if (strcmp(argv[i],"-dlatex") == 0) {
doc = new LATEX;
mark_arg(i);
} else if (strcmp(argv[i],"-nocomment") == 0) {
ignorecomments = 1;
mark_arg(i);
} else if (strcmp(argv[i],"-stat") == 0) {
Stats=1;
mark_arg(i);
} else if (strcmp(argv[i],"-c++") == 0) {
CPlusPlus=1;
mark_arg(i);
} else if (strcmp(argv[i],"-objc") == 0) {
ObjC = 1;
mark_arg(i);
} else if (strcmp(argv[i],"-c") == 0) {
NoInclude=1;
mark_arg(i);
} else if (strcmp(argv[i],"-make_default") == 0) {
GenerateDefault = 1;
mark_arg(i);
} else if (strcmp(argv[i],"-swiglib") == 0) {
printf("%s\n", LibDir);
SWIG_exit(0);
} else if (strcmp(argv[i],"-o") == 0) {
mark_arg(i);
if (argv[i+1]) {
outfile_name = copy_string(argv[i+1]);
mark_arg(i+1);
i++;
} else {
arg_error();
}
} else if (strcmp(argv[i],"-d") == 0) {
mark_arg(i);
if (argv[i+1]) {
doc_file = copy_string(argv[i+1]);
mark_arg(i+1);
i++;
} else {
arg_error();
}
} else if (strcmp(argv[i],"-t") == 0) {
mark_arg(i);
if (argv[i+1]) {
typemap_file = copy_string(argv[i+1]);
mark_arg(i+1);
i++;
} else {
arg_error();
}
} else if (strcmp(argv[i],"-version") == 0) {
fprintf(stderr,"\nSWIG Version %d.%d %s\n", SWIG_MAJOR_VERSION,
SWIG_MINOR_VERSION, SWIG_SPIN);
fprintf(stderr,"Copyright (c) 1995-98\n");
fprintf(stderr,"University of Utah and the Regents of the University of California\n");
fprintf(stderr,"\nCompiled with %s\n", SWIG_CC);
SWIG_exit(0);
} else if (strncmp(argv[i],"-l",2) == 0) {
// Add a new directory search path
library_add(argv[i]+2);
mark_arg(i);
} else if (strcmp(argv[i],"-co") == 0) {
checkout = 1;
mark_arg(i);
} else if (strcmp(argv[i],"-ci") == 0) {
checkin = 1;
mark_arg(i);
} else if (strcmp(argv[i],"-help") == 0) {
fputs(usage,stderr);
mark_arg(i);
help = 1;
}
}
}
while (includecount > 0) {
add_directory(includefiles[--includecount]);
}
// Create a new documentation handler
if (doc == 0) doc = new ASCII;
// Open up a comment handler
comment_handler = new CommentHandler();
comment_handler->parse_args(argc,argv);
if (ignorecomments) comment_handler->style("ignore",0);
// Create a new documentation entry
doctitle = new DocTitle("",0);
doctitle->parse_args(argc,argv);
doc_entry = doctitle;
// Handle documentation module options
doc->parse_args(argc,argv);
// Parse language dependent options
lang->parse_args(argc,argv);
if (help) SWIG_exit(0); // Exit if we're in help mode
// Check all of the options to make sure we're cool.
check_options();
// If we made it this far, looks good. go for it....
// Create names of temporary files that are created
sprintf(infilename,"%s", argv[argc-1]);
input_file = new char[strlen(infilename)+1];
strcpy(input_file, infilename);
// If the user has requested to check out a file, handle that
if (checkout) {
int stat;
char *outfile = input_file;
if (outfile_name)
outfile = outfile_name;
stat = checkout_file(input_file,outfile);
if (!stat) {
fprintf(stderr,"%s checked out from the SWIG library\n",input_file);
} else {
FILE * f = fopen(input_file,"r");
if (f) {
fprintf(stderr,"Unable to check-out %s. File already exists.\n", input_file);
fclose(f);
} else {
fprintf(stderr,"Unable to check-out %s\n", input_file);
}
}
} else if (checkin) {
// Try to check-in a file to the SWIG library
int stat;
char *outname = input_file;
if (outfile_name)
outname = outfile_name;
stat = checkin_file(SwigLib, LibDir, input_file, outname);
if (!stat) {
fprintf(stderr,"%s checked-in to %s/%s/%s\n", input_file, SwigLib, LibDir, outname);
} else {
fprintf(stderr,"Unable to check-in %s to %s/%s\n", input_file, SwigLib, LibDir);
}
} else {
doctitle->file = copy_string(input_file);
doctitle->line_number = -1000;
doctitle->end_line = -1000;
// Check the suffix for a .c file. If so, we're going to
// declare everything we see as "extern"
check_suffix(infilename);
// Strip off suffix
c = infilename + strlen(infilename);
while (c != infilename) {
if (*c == '.') {
*c = 0;
break;
} else {
c--;
}
}
if (!outfile_name) {
sprintf(fn_header,"%s_wrap.c",infilename);
strcpy(infile,infilename);
strcpy(output_dir,"");
} else {
sprintf(fn_header,"%s",outfile_name);
// Try to identify the output directory
char *cc = outfile_name;
char *lastc = outfile_name;
while (*cc) {
#ifdef MACSWIG
if (*cc == ':') lastc = cc+1;
#else
if (*cc == '/') lastc = cc+1;
#endif
cc++;
}
cc = outfile_name;
char *dd = output_dir;
while (cc != lastc) {
*dd = *cc;
dd++;
cc++;
}
*dd = 0;
// Patch up the input filename
cc = infilename + strlen(infilename);
while (cc != infilename) {
#ifdef MACSWIG
if (*cc == ':') {
cc++;
break;
}
#else
if (*cc == '/') {
cc++;
break;
}
#endif
cc--;
}
strcpy(infile,cc);
}
sprintf(fn_wrapper,"%s%s_wrap.wrap",output_dir,infile);
sprintf(fn_init,"%s%s_wrap.init",output_dir,infile);
sprintf(title,"%s", fn_header);
// Open up files
if ((f_input = fopen(input_file,"r")) == 0) {
// Okay. File wasn't found right away. Let's see if we can
// extract it from the SWIG library instead.
if ((checkout_file(input_file,input_file)) == -1) {
fprintf(stderr,"Unable to open %s\n", input_file);
SWIG_exit(0);
} else {
// Successfully checked out a file from the library, print a warning and
// continue
checkout = 1;
fprintf(stderr,"%s checked out from the SWIG library.\n",input_file);
if ((f_input = fopen(input_file,"r")) == 0) {
fprintf(stderr,"Unable to open %s\n", input_file);
SWIG_exit(0);
}
}
}
// Add to the include list
add_iname(infilename);
// Initialize the scanner
LEX_in = f_input;
scanner_file(LEX_in);
// printf("fn_header = %s\n", fn_header);
// printf("fn_wrapper = %s\n", fn_wrapper);
// printf("fn_init = %s\n", fn_init);
if((f_header = fopen(fn_header,"w")) == 0) {
fprintf(stderr,"Unable to open %s\n", fn_header);
exit(0);
}
if((f_wrappers = fopen(fn_wrapper,"w")) == 0) {
fprintf(stderr,"Unable to open %s\n",fn_wrapper);
exit(0);
}
if ((f_init = fopen(fn_init,"w")) == 0) {
fprintf(stderr,"Unable to open %s\n",fn_init);
exit(0);
}
// Open up documentation
if (doc_file) {
doc->init(doc_file);
} else {
doc_file = new char[strlen(infile)+strlen(output_dir)+8];
sprintf(doc_file,"%s%s_wrap",output_dir,infile);
doc->init(doc_file);
}
// Set up the typemap for handling new return strings
{
DataType *temp_t = new DataType(T_CHAR);
temp_t->is_pointer++;
if (CPlusPlus)
typemap_register("newfree",typemap_lang,temp_t,"","delete [] $source;\n",0);
else
typemap_register("newfree",typemap_lang,temp_t,"","free($source);\n",0);
delete temp_t;
}
// Define the __cplusplus symbol
if (CPlusPlus)
add_symbol("__cplusplus",0,0);
// Load up the typemap file if given
if (typemap_file) {
if (include_file(typemap_file) == -1) {
fprintf(stderr,"Unable to locate typemap file %s. Aborting.\n", typemap_file);
SWIG_exit(1);
}
}
// If in Objective-C mode. Load in a configuration file
if (ObjC) {
// Add the 'id' object type as a void *
/* DataType *t = new DataType(T_VOID);
t->is_pointer = 1;
t->implicit_ptr = 0;
t->typedef_add("id");
delete t;
*/
}
// Pass control over to the specific language interpreter
lang->parse();
fclose(f_wrappers);
fclose(f_init);
swig_append(fn_wrapper,f_header);
swig_append(fn_init,f_header);
fclose(f_header);
// Print out documentation. Due to tree-like nature of documentation,
// printing out the title prints out everything.
while(doctitle) {
doctitle->output(doc);
doctitle = doctitle->next;
}
doc->close();
// Remove temporary files
remove(fn_wrapper);
remove(fn_init);
// If only producing documentation, remove the wrapper file as well
if (DocOnly)
remove(fn_header);
// Check for undefined types that were used.
if (Verbose)
type_undefined_check();
if (Stats) {
fprintf(stderr,"Wrapped %d functions\n", Stat_func);
fprintf(stderr,"Wrapped %d variables\n", Stat_var);
fprintf(stderr,"Wrapped %d constants\n", Stat_const);
type_undefined_check();
}
if (checkout) {
// File was checked out from the SWIG library. Remove it now
remove(input_file);
}
}
#ifdef MACSWIG
fclose(swig_log);
} catch (SwigException) {
fclose(swig_log);
}
#else
exit(error_count);
#endif
return(error_count);
}
// --------------------------------------------------------------------------
// SWIG_exit()
//
// Fatal parser error. Exit and cleanup
// --------------------------------------------------------------------------
void SWIG_exit(int) {
if (f_wrappers) {
fclose(f_wrappers);
remove(fn_wrapper);
}
if (f_header) {
fclose(f_header);
remove(fn_header);
}
if (f_init) {
fclose(f_init);
remove(fn_init);
}
#ifndef MACSWIG
exit(1);
#else
throw SwigException();
#endif
}
// --------------------------------------------------------------------------
// swig_pragma(char *name, char *value)
//
// Handle pragma directives. Not many supported right now
// --------------------------------------------------------------------------
void swig_pragma(char *name, char *value) {
if (strcmp(name,"make_default") == 0) {
GenerateDefault = 1;
}
if (strcmp(name,"no_default") == 0) {
GenerateDefault = 0;
}
if (strcmp(name,"objc_new") == 0) {
objc_construct = copy_string(value);
}
if (strcmp(name,"objc_delete") == 0) {
objc_destruct = copy_string(value);
}
}
char* getSwigLib() {
char* c;
char* rv;
// Check for SWIG_LIB environment variable
if ((c = getenv("SWIG_LIB")) != (char *) 0) {
rv = c;
} else {
#ifdef SWIG_LIB
rv = SWIG_LIB;
#else
// use executable location
static char path[256];
char* last;
strcpy(path, __argv[0]);
last = strrchr(path, '/');
if (! last) last = strrchr(path, '\\');
if (last)
strcpy(last+1, "swig_lib");
else
strcpy(path, "swig_lib");
rv = path;
#endif
}
printf("Using swig lib at: %s\n", rv);
return rv;
}

View File

@@ -0,0 +1,107 @@
# Modified from automatic creation by Kevin Butler (butler@byu.edu)
# for Microsoft Visual C++ (11/22/96)
#
#######################################################################
# $Header$
# Simplified Wrapper and Interface Generator (SWIG)
#
# Makefile for version 1.1
# Dave Beazley
# March 12, 1997
#
# This makefile is now mostly constructed by ./configure.
#
# $Log$
# Revision 1.1 2002/04/29 19:56:48 RD
# Since I have made several changes to SWIG over the years to accomodate
# 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.
#
# Revision 1.1.1.1 1999/02/28 02:00:52 beazley
# Swig1.1
#
# Revision 1.1 1996/08/12 01:55:02 dmb
# Initial revision
#
#######################################################################
#.KEEP_STATE:
rootdir = ..
!include <..\make_win.in>
########################################################################
# Normally, you shouldn't have to change anything below this point #
########################################################################
LIBOBJS = main.obj scanner.obj symbol.obj include.obj types.obj parms.obj emit.obj newdoc.obj ascii.obj \
html.obj latex.obj cplus.obj lang.obj hash.obj sstring.obj wrapfunc.obj getopt.obj comment.obj typemap.obj naming.obj
LIBSRCS = main.cxx scanner.cxx symbol.cxx include.cxx types.cxx parms.cxx emit.cxx \
newdoc.cxx ascii.cxx html.cxx latex.cxx cplus.cxx lang.cxx hash.cxx \
sstring.cxx wrapfunc.cxx getopt.cxx comment.cxx typemap.cxx naming.cxx
LIBHEADERS = internal.h $(rootdir)/Include/swig.h latex.h ascii.h html.h nodoc.h
LIBNAME = $(rootdir)\libswig.lib
#
# Rules for creation of a .obj file from .cxx
.SUFFIXES: .cxx
.cxx.obj:
$(CC) $(INCFLAGS) $(CFLAGS) -c -o $*.obj $<
all: $(LIBNAME)
$(LIBNAME): parser.obj $(LIBOBJS)
@echo "Building library"
@$(LD) $(LD_FLAGS) -out:$(LIBNAME) $(LIBOBJS) parser.obj
parser.obj: parser.cxx $(LIBHEADERS)
$(CC) $(INCFLAGS) $(CFLAGS) parser.cxx -c -o parser.obj
parser.cxx: $(PARSER)
@echo "Must rebuild the parser with yacc"
parser::
@cp y.tab.c.bison parser.cxx
@cp y.tab.h.bison parser.h
@cp y.tab.h.bison y.tab.h
$(CC) $(CFLAGS) parser.cxx -c -o parser.obj
main.obj: main.cxx
scanner.obj: scanner.cxx
wrapper.obj: wrapper.cxx
include.obj: include.cxx
types.obj: types.cxx
emit.obj: emit.cxx
cplus.obj: cplus.cxx
misc.obj: misc.cxx
hash.obj: hash.cxx
sstring.obj: sstring.cxx
getopt.obj: getopt.cxx
wrapfunc.obj: wrapfunc.cxx
swigmain.obj: swigmain.cxx
symbol.obj: symbol.cxx
parms.obj: parms.cxx
newdoc.obj: newdoc.cxx
lang.obj: lang.cxx
comment.obj: comment.cxx
latex.obj: latex.cxx
ascii.obj: ascii.cxx
html.obj: html.cxx
typemap.obj: typemap.cxx
naming.obj: naming.cxx
clean::
@del *.obj
@del $(LIBNAME)

View File

@@ -0,0 +1,299 @@
/*******************************************************************************
* 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 <limits.h>
#include <ctype.h>
// --------------------------------------------------------------------------------
// $Header$
//
// naming.cxx
//
// SWIG naming service.
//
// This module provides universal naming services for manufacturing function names.
// All language modules use this so it provides a convenient centralized
// mechanism for producing names.
// --------------------------------------------------------------------------------
// Structure for holding names
struct NamingScheme {
char *format;
int first; // Scoping information
int last; // Scoping information
NamingScheme *next;
NamingScheme(char *n) {
format = copy_string(n);
first = type_id;
last = INT_MAX;
next = 0;
};
};
// Hash table containing naming data
static Hash naming_hash;
// Variable indicating naming scope
static int naming_scope = -1;
//-----------------------------------------------------------------
// make_wrap_name(char *s)
//
// Takes the name at src, and converts it into a syntactically
// valid identifier name. This is a hack to get the wrapper
// generator to support class member functions and other things.
//
// ie. We can define a function name as obj->foo(),
// but we'll need to call the wrapper function something like
// _wrap_obj__foo()
//-----------------------------------------------------------------
void make_wrap_name(char *s) {
char *c1 = s;
int i;
for (i = 0; i < (int) strlen(s); i++, c1++) {
if(!isalnum(*c1)) *c1 = '_';
}
}
// --------------------------------------------------------------------------------
// int name_scope(int scope)
//
// Set the scope variable. This is used to determine what naming scheme to
// use. Returns the current value of the scope.
// --------------------------------------------------------------------------------
int name_scope(int scope) {
int s = naming_scope;
naming_scope = scope;
return s;
}
// --------------------------------------------------------------------------------
// void name_register(char *method, char *format)
//
// Registers a new naming scheme.
// --------------------------------------------------------------------------------
void name_register(char *method, char *format) {
NamingScheme *ns, *nns;
ns = (NamingScheme *) naming_hash.lookup(method);
if (ns) {
naming_hash.remove(method);
}
nns = new NamingScheme(format); // Create a new naming scheme
if (ns) ns->last = type_id;
nns->next = ns;
naming_hash.add(method,nns);
};
// --------------------------------------------------------------------------------
// char *name_getformat(char *method)
//
// Looks up a naming scheme in the hash table. The scope of the name should have
// been set prior to calling this. If not set, we just use the last name entered.
// Returns the format string or NULL if no name has been set.
// --------------------------------------------------------------------------------
static char *name_getformat(char *method) {
NamingScheme *ns;
int scope;
if (naming_scope == -1) scope = type_id;
else scope = naming_scope;
ns = (NamingScheme *) naming_hash.lookup(method);
while (ns) {
if ((ns->first <= scope) && (scope < ns->last))
return ns->format;
ns = ns->next;
}
return 0;
}
// --------------------------------------------------------------------------------
// char *name_wrapper(char *fname, char *prefix, int suppress)
//
// Returns the name of a wrapper function. The following variables are
// available :
//
// %f -> fname
// %p -> prefix
// %l -> language
//
// By default a wrapper function gets the name _wrap_prefixfname.
//
// --------------------------------------------------------------------------------
char *name_wrapper(char *fname, char *prefix, int suppress) {
static String fmt;
char *f;
f = name_getformat("wrapper");
if (!f) {
f = "_wrap_%p%f"; // Default wrapper name
}
fmt = f;
fmt.replace("%f",fname);
fmt.replace("%l",typemap_lang);
fmt.replace("%p",prefix);
if (!suppress)
make_wrap_name(fmt);
return fmt;
}
// --------------------------------------------------------------------------------
// char *name_member(char *fname, char *classname, int suppress)
//
// Returns the name of a method function. The following variables are
// available :
//
// %f -> fname
// %c -> classname
// %l -> language
//
// By default, the name of a method is given as Classname_method.
// --------------------------------------------------------------------------------
char *name_member(char *fname, char *classname, int suppress) {
static String fmt;
char *f;
f = name_getformat("member");
if (!f) {
f = "%c_%f";
}
fmt = f;
fmt.replace("%f",fname);
fmt.replace("%l",typemap_lang);
fmt.replace("%c",classname);
if (!suppress)
make_wrap_name(fmt);
return fmt;
}
// --------------------------------------------------------------------------------
// char *name_get(char *vname, int suppress)
//
// Returns the name of the accessor function used to get a variable.
//
// %v -> variable name
//
// --------------------------------------------------------------------------------
char *name_get(char *vname, int suppress) {
static String fmt;
char *f;
f = name_getformat("get");
if (!f) {
f = "%v_get";
}
fmt = f;
fmt.replace("%v",vname);
if (!suppress)
make_wrap_name(fmt);
return fmt;
}
// --------------------------------------------------------------------------------
// char *name_set(char *vname, int suppress)
//
// Returns the name of the accessor function used to set a variable.
//
// %v -> variable name
// --------------------------------------------------------------------------------
char *name_set(char *vname, int suppress) {
static String fmt;
char *f;
f = name_getformat("set");
if (!f) {
f = "%v_set";
}
fmt = f;
fmt.replace("%v",vname);
if (!suppress)
make_wrap_name(fmt);
return fmt;
}
// --------------------------------------------------------------------------------
// char *name_construct(char *classname, int suppress)
//
// Returns the name of the accessor function used to create an object.
// By default this is "new_classname"
//
// %c -> classname
// %l -> language
//
// --------------------------------------------------------------------------------
char *name_construct(char *classname, int suppress) {
static String fmt;
char *f;
f = name_getformat("construct");
if (!f) {
f = "new_%c";
}
fmt = f;
fmt.replace("%l",typemap_lang);
fmt.replace("%c",classname);
if (!suppress)
make_wrap_name(fmt);
return fmt;
}
// --------------------------------------------------------------------------------
// char *name_destroy(char *classname, int suppress)
//
// Returns the name of the accessor function used to destroy an object.
// By default this is "delete_classname"
//
// %c -> classname
// %l -> language
//
// --------------------------------------------------------------------------------
char *name_destroy(char *classname, int suppress) {
static String fmt;
char *f;
f = name_getformat("destroy");
if (!f) {
f = "delete_%c";
}
fmt = f;
fmt.replace("%l",typemap_lang);
fmt.replace("%c",classname);
if (!suppress)
make_wrap_name(fmt);
return fmt;
}

View File

@@ -0,0 +1,607 @@
/*******************************************************************************
* 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.
*******************************************************************************/
/***********************************************************************
* $Header$
*
* newdoc.cxx
*
* SWIG Documentation system. (2nd attempt)
*
* SWIG organizes documentation as a tree structure where each node is a
* documentation entry (DocEntry) of some kind. To generate documentation,
* we simply traverse the tree and call output methods.
*
* A sample documentation tree looks something like the following :
*
* TITLE ----> SECTION 1 ----> func1
* ----> func2
* ----> func3
* ----> class ---> func1
* ---> func2
* ---> var1
* ----> func4
*
* ----> SECTION 2 ----> func1
* ----> var1
*
* and so on.
*
* This structure makes it possible to organize C++ classes and more
* complicated structures. Hopefully this will provide enough structure
* for later versions of SWIG.
*
*************************************************************************/
#include "internal.h"
#include <ctype.h>
extern char *get_time();
static char *last_name = 0;
DocEntry *DocEntry::dead_entries = 0;
// Utility function for converting a string to upper case
static void str_toupper(char *str) {
char *c;
c = str;
while (*c) {
*c = toupper(*c);
c++;
}
}
// --------------------------------------------------------------------
// DocEntry::~DocEntry
//
// Destroy a documentation entry. Destroys this entry and all of
// its children.
// --------------------------------------------------------------------
DocEntry::~DocEntry() {
DocEntry *de, *de1;
if (name) delete name;
// Now kill all of the children (well, figuratively speaking)
de = child;
while (de) {
de1 = de->next;
delete de;
de = de1;
}
}
// --------------------------------------------------------------------
// void DocEntry::sort_children()
//
// Sort children by name (not height). This function gathers all
// of the children up into an array of pointers. Then we do an
// insertion sort on it and place the children back in order.
// --------------------------------------------------------------------
void DocEntry::sort_children() {
int count = 0;
int i,j;
DocEntry *d;
DocEntry **list;
DocEntry *v;
if (!child) return; // Nothing to sort
d = child;
while (d) {
count++;
d = d->next;
}
// allocate a temporary array for sorting everything
list = new DocEntry *[count+2];
// Now put pointers into list
d = child;
i = 0;
while (d) {
list[i] = d;
d = d->next;
i++;
}
// Do an insertion sort by name
for (i = 1; i < count; i++) {
v = list[i];
j = i;
while((j > 0) && (strcmp(list[j-1]->name,v->name) > 0)) {
list[j] = list[j-1];
j--;
}
list[j] = v;
}
// Now, we're going to reorganize the children in order
list[count] = 0;
child = list[0]; // Our child is the first one in the list
d = child;
for (i = 0; i < count; i++) {
d->next = list[i+1];
d = d->next;
}
delete list;
}
// --------------------------------------------------------------------
// void DocEntry::output()
//
// Output this entry
// --------------------------------------------------------------------
void DocEntry::output(Documentation *) {
fprintf(stderr,"SWIG (internal) : No output method defined for DocEntry.\n");
}
// --------------------------------------------------------------------
// DocEntry::add(DocEntry *de)
//
// Adds a new DocEntry as a sibling. Basically we just walk down the
// linked list and append ourselves to the end. The documentation
// Entry we're adding may, in fact, have siblings too, but this function
// Should still work.
// --------------------------------------------------------------------
void DocEntry::add(DocEntry *de) {
DocEntry *d,*d1;
d = next;
d1 = this;
while (d) {
d1 = d;
d = d->next;
}
d1->next = de;
de->previous = d1; // Set up the previous list member
}
// --------------------------------------------------------------------
// DocEntry::addchild(DocEntry *de)
//
// Adds a new DocEntry as a child. If we're in Ignore mode, the
// documentation entry is still created, but we simply abandon it.
// --------------------------------------------------------------------
void DocEntry::addchild(DocEntry *de) {
if (!IgnoreDoc) {
if (child) child->add(de);
else child = de;
} else {
if (dead_entries) dead_entries->add(de);
else dead_entries = de;
}
}
// -------------------------------------------------------------------
// DocEntry::remove()
//
// Removes a documentation entry from the tree and places it on
// the dead_entries list
// -------------------------------------------------------------------
void DocEntry::remove() {
if (previous) {
if (next)
previous->next = next; // Take out of the linked list
else
previous->next = 0;
} else { // Make sure our parent isn't pointing to us
if (parent)
parent->child = next;
}
previous = 0;
next = 0;
if (!dead_entries) dead_entries = this;
else dead_entries->add(this);
}
// -------------------------------------------------------------------
// void DocEntry::style(char *name, char *value)
//
// Set style parameters of a documentation entry
// -------------------------------------------------------------------
void DocEntry::style(char *pname, char *) {
if (strcmp(pname,"sort") == 0) {
sorted = 1;
} else if (strcmp(pname,"nosort") == 0) {
sorted = 0;
} else if (strcmp(pname,"info") == 0) {
print_info = 1;
} else if (strcmp(pname,"noinfo") == 0) {
print_info = 0;
} else if (strcmp(pname,"pre") == 0) {
format = 0;
} else if (strcmp(pname,"format") == 0) {
format = 1;
}
}
// -------------------------------------------------------------------
// void DocEntry::parse_args(int argc, char **argv)
//
// Take command line options and process them. This really only
// applies to the top-level documentation entry.
// -------------------------------------------------------------------
static char *doc_usage = "\
Documentation Processing : \n\
-Sformat - Reformat comment text\n\
-Sinfo - Print C formatting information (the default)\n\
-Snoinfo - Omit C formatting information.\n\
-Snosort - Print everything in order (the default)\n\
-Spre - Assume comments are pre-formatted (the default)\n\
-Ssort - Sort documentation alphabetically\n\n";
void DocEntry::parse_args(int argc, char **argv) {
int i;
for (i = 1; i < argc; i++) {
if (argv[i]) {
if (strcmp(argv[i],"-Ssort") == 0) {
this->style("sort",0);
mark_arg(i);
} else if (strcmp(argv[i],"-Snosort") == 0) {
this->style("nosort",0);
mark_arg(i);
} else if (strcmp(argv[i],"-Sinfo") == 0) {
this->style("info",0);
mark_arg(i);
} else if (strcmp(argv[i],"-Snoinfo") == 0) {
this->style("noinfo",0);
mark_arg(i);
} else if (strcmp(argv[i],"-Spre") == 0) {
this->style("pre",0);
mark_arg(i);
} else if (strcmp(argv[i],"-Sformat") == 0) {
this->style("format",0);
mark_arg(i);
} else if (strcmp(argv[i],"-help") == 0) {
fputs(doc_usage,stderr);
}
}
}
}
// -------------------------------------------------------------------
// DocTitle::DocTitle(char *title, DocEntry *_parent);
//
// Create a new title documentation entry. The name of the entry
// is the title.
//
// The body text is optional, but may be filled in with a description
// as well.
// -------------------------------------------------------------------
DocTitle::DocTitle(char *title, DocEntry *_parent) {
name = copy_string(title);
str_toupper(name);
parent = _parent;
child = 0;
next = 0;
previous = 0;
usage << title << "\n";
counter = 1;
is_separator = 1;
line_number = ::start_line;
end_line = ::line_number;
file = copy_string(input_file);
if (_parent) {
sorted = _parent->sorted;
format = _parent->format;
print_info = _parent->print_info;
} else {
sorted = SWIGDEFAULT_SORT;
format = SWIGDEFAULT_FORMAT;
print_info = SWIGDEFAULT_INFO;
}
comment_handler->set_entry(this);
if (last_name) delete last_name;
last_name = 0;
}
// --------------------------------------------------------------------
// DocTitle::output(Documentation *d)
//
// Output a title to the Documentation module
// --------------------------------------------------------------------
void DocTitle::output(Documentation *d) {
DocEntry *de;
d->title(this);
if (sorted) {
sort_children();
}
// Now output my children
de = child;
while (de) {
de->output(d);
de = de->next;
}
}
// -------------------------------------------------------------------
// DocSection::DocSection(char *section, DocEntry *_parent);
//
// Create a new documentation section. The name and description is
// set to the name of the section. The text field is optional
// but could contain a more complete description.
//
// The sorted field indicates whether members of this section are
// sorted or not.
// -------------------------------------------------------------------
DocSection::DocSection(char *section, DocEntry *_parent) {
name = copy_string(section);
str_toupper(name);
parent = _parent;
child = 0;
next = 0;
previous = 0;
usage << section;
counter = 1;
is_separator = 1;
if (_parent) _parent->addchild(this);
line_number = ::start_line;
end_line = ::line_number;
file = copy_string(input_file);
if (_parent) {
sorted = _parent->sorted;
format = _parent->format;
print_info = _parent->print_info;
} else {
sorted = SWIGDEFAULT_SORT;
format = SWIGDEFAULT_FORMAT;
print_info = SWIGDEFAULT_INFO;
}
comment_handler->set_entry(this);
if (last_name) delete last_name;
last_name = 0;
}
// --------------------------------------------------------------------
// DocSection::output(Documentation *d)
//
// Output a section to the documentation module
// --------------------------------------------------------------------
void DocSection::output(Documentation *d) {
DocEntry *de;
// Make a new section
d->newsection(this,this->parent->counter++); // Make a new section
// Sort the children if necessary
if (sorted) {
sort_children();
}
// Now output my children
de = child;
while (de) {
de->output(d);
de = de->next;
}
// End this section
d->endsection();
}
// -------------------------------------------------------------------
// DocDecl::DocDecl(char *fname, DocEntry *_parent);
//
// Create documentation for a function declaration.
// -------------------------------------------------------------------
DocDecl::DocDecl(char *fname, DocEntry *_parent) {
name = copy_string(fname);
str_toupper(name);
parent = _parent;
child = 0;
next = 0;
previous = 0;
is_separator = 0;
if (_parent) _parent->addchild(this);
line_number = ::start_line;
end_line = ::line_number;
file = copy_string(input_file);
if (_parent) {
sorted = _parent->sorted;
format = _parent->format;
print_info = _parent->print_info;
} else {
sorted = SWIGDEFAULT_SORT;
format = SWIGDEFAULT_FORMAT;
print_info = SWIGDEFAULT_INFO;
}
comment_handler->set_entry(this);
if (last_name) delete last_name;
last_name = copy_string(name);
}
// --------------------------------------------------------------------
// DocDecl::DocDecl(DocEntry *de, DocEntry *_parent)
//
// Make a new declaration entry, but copy attributes from someone else
// --------------------------------------------------------------------
DocDecl::DocDecl(DocEntry *de, DocEntry *_parent) {
name = copy_string(de->name);
usage = de->usage.get();
cinfo = de->cinfo.get();
text = de->text.get();
line_number = de->line_number;
end_line = de->end_line;
file = copy_string(de->file);
print_info = de->print_info;
format = de->format;
if (_parent) {
_parent->addchild(this);
}
}
// --------------------------------------------------------------------
// DocDecl::output(Documentation *d)
//
// Output a function to the documentation module
// --------------------------------------------------------------------
void DocDecl::output(Documentation *d) {
d->print_decl(this);
}
// -------------------------------------------------------------------
// DocClass::DocClass(char *classname, DocEntry *_parent);
//
// Create a new class section. Classes are created as funny sorts of
// sections.
//
// The sorted field indicates whether members of this section are
// sorted or not.
// -------------------------------------------------------------------
DocClass::DocClass(char *classname, DocEntry *_parent) {
name = copy_string(classname);
str_toupper(name);
parent = _parent;
child = 0;
next = 0;
previous = 0;
usage << classname<< "\n";
counter = 1;
is_separator = 1;
if (_parent) _parent->addchild(this);
line_number = ::start_line;
end_line = ::line_number;
file = copy_string(input_file);
if (_parent) {
sorted = _parent->sorted;
format = _parent->format;
print_info = _parent->print_info;
} else {
sorted = SWIGDEFAULT_SORT;
format = SWIGDEFAULT_FORMAT;
print_info = SWIGDEFAULT_INFO;
}
comment_handler->set_entry(this);
if (last_name) delete last_name;
last_name = copy_string(name);
}
// --------------------------------------------------------------------
// DocClass::output(Documentation *d)
//
// Output a section to the documentation module
// --------------------------------------------------------------------
void DocClass::output(Documentation *d) {
DocEntry *de;
// Make a new section
d->newsection(this,this->parent->counter++); // Make a subsection for this
// Sort the children if necessary
if (sorted) {
sort_children();
}
// Now output my children
de = child;
while (de) {
de->output(d);
de = de->next;
}
// End this section
d->endsection();
// We now check to see if the next thing is a separator. If not, we'll
// emit a separator
if (next) {
if (!next->is_separator)
d->separator();
}
}
// -------------------------------------------------------------------
// DocText::DocText(char *_text, DocEntry *_parent);
//
// Create documentation for a function declaration.
// -------------------------------------------------------------------
DocText::DocText(char *_text, DocEntry *_parent) {
if (!last_name)
name = copy_string(""); // There is no name for text
else
name = copy_string(last_name);
parent = _parent;
child = 0;
next = 0;
previous = 0;
text << _text;
is_separator = 0;
if (_parent) _parent->addchild(this);
if (_parent) {
sorted = _parent->sorted;
format = _parent->format;
print_info = _parent->print_info;
} else {
sorted = SWIGDEFAULT_SORT;
format = SWIGDEFAULT_FORMAT;
print_info = SWIGDEFAULT_INFO;
}
}
// --------------------------------------------------------------------
// DocText::output(Documentation *d)
//
// Output a function to the documentation module
// --------------------------------------------------------------------
void DocText::output(Documentation *d) {
d->print_text(this);
}

View File

@@ -0,0 +1,54 @@
/*******************************************************************************
* 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.
*******************************************************************************/
/***********************************************************************
* $Header$
*
* nodoc.h
*
* A null documentation header. Does nothing.
***********************************************************************/
class NODOC : public Documentation {
private:
public:
NODOC() { };
void parse_args(int, char **) { };
void title(DocEntry *) { };
void newsection(DocEntry *, int) { };
void endsection() { };
void print_decl(DocEntry *) { };
void print_text(DocEntry *) { };
void separator() { };
void init(char *) { };
void close(void) { };
void style(char *, char *) { };
};

View File

@@ -0,0 +1,478 @@
/*******************************************************************************
* 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.
*******************************************************************************/
/* ------------------------------------------------------------------------
$Header$
parms.cxx
This file is used to manage function parameters and parameter lists.
Rewritten (10/27) to solve a bunch of problems with memory management
and proper cleanup of things.
------------------------------------------------------------------------ */
#include "swig.h"
// ------------------------------------------------------------------------
// Parm::Parm(DataType *type, char *n)
//
// Create a new parameter from datatype 'type' and name 'n'.
// Copies will be made of type and n, unless they aren't specified.
// ------------------------------------------------------------------------
Parm::Parm(DataType *type, char *n) {
if (type) {
t = new DataType(type);
} else {
t = 0;
}
name = copy_string(n);
call_type = 0;
defvalue = 0;
ignore = 0;
objc_separator = 0;
}
// ------------------------------------------------------------------------
// Parm::Parm(Parm *p)
//
// Make a copy of a parameter
// ------------------------------------------------------------------------
Parm::Parm(Parm *p) {
if (p->t) t = new DataType(p->t);
name = copy_string(p->name);
call_type = p->call_type;
defvalue = copy_string(p->defvalue);
ignore = p->ignore;
objc_separator = copy_string(p->objc_separator);
}
// ------------------------------------------------------------------------
// Parm::~Parm()
//
// Destroy a parameter
// ------------------------------------------------------------------------
Parm::~Parm() {
if (t) delete t;
if (name) delete name;
if (defvalue) delete defvalue;
if (objc_separator) delete objc_separator;
}
/********************************************************************
class ParmList
These functions are used to manipulate lists of parameters
********************************************************************/
// ------------------------------------------------------------------
// ParmList::ParmList()
//
// Create a new (empty) parameter list
// ------------------------------------------------------------------
ParmList::ParmList() {
nparms = 0;
maxparms = MAXPARMS;
parms = new Parm *[maxparms]; // Create an array of parms
for (int i = 0; i < MAXPARMS; i++)
parms[i] = (Parm *) 0;
}
// ------------------------------------------------------------------
// ParmList::ParmList(ParmList *l)
//
// Make a copy of parameter list
// ------------------------------------------------------------------
ParmList::ParmList(ParmList *l) {
int i;
if (l) {
nparms = l->nparms;
maxparms = l->maxparms;
parms = new Parm *[maxparms];
for (i = 0; i < maxparms; i++) {
if (l->parms[i])
parms[i] = new Parm(l->parms[i]);
else
parms[i] = 0;
}
} else {
nparms = 0;
maxparms = MAXPARMS;
parms = new Parm *[maxparms]; // Create an array of parms
for (i = 0; i < MAXPARMS; i++)
parms[i] = (Parm *) 0;
}
}
// ------------------------------------------------------------------
// ParmList::~ParmList()
//
// Delete a parameter list
// ------------------------------------------------------------------
ParmList::~ParmList() {
for (int i = 0; i < maxparms; i++) {
if (parms[i]) delete parms[i];
}
}
// ------------------------------------------------------------------
// void ParmList::moreparms() (PRIVATE)
//
// Doubles the amount of parameter memory available.
// ------------------------------------------------------------------
void ParmList::moreparms() {
Parm **newparms;
int i;
newparms = new Parm *[maxparms*2];
for (i = 0; i < 2*maxparms; i++)
newparms[i] = (Parm *) 0;
for (i = 0; i < maxparms; i++) {
newparms[i] = parms[i];
}
maxparms = 2*maxparms;
delete parms;
parms = newparms;
}
// ------------------------------------------------------------------
// void ParmList::append(Parm *p)
//
// Add a new parameter to the end of a parameter list
// ------------------------------------------------------------------
void ParmList::append(Parm *p) {
if (nparms == maxparms) moreparms();
// Add parm onto the end
parms[nparms] = new Parm(p);
nparms++;
}
// ------------------------------------------------------------------
// void ParmList::insert(Parm *p, int pos)
//
// Inserts a parameter at position pos. Parameters are inserted
// *before* any existing parameter at position pos.
// ------------------------------------------------------------------
void ParmList::insert(Parm *p, int pos) {
// If pos is out of range, we'd better fix it
if (pos < 0) pos = 0;
if (pos > nparms) pos = nparms;
// If insertion is going to need more memory, take care of that now
if (nparms >= maxparms) moreparms();
// Now shift all of the existing parms to the right
for (int i = nparms; i > pos; i--) {
parms[i] = parms[i-1];
}
// Set new parameter
parms[pos] = new Parm(p);
nparms++;
}
// ------------------------------------------------------------------
// void ParmList::del(int pos)
//
// Deletes the parameter at position pos.
// ------------------------------------------------------------------
void ParmList::del(int pos) {
if (nparms <= 0) return;
if (pos < 0) pos = 0;
if (pos >= nparms) pos = nparms-1;
// Delete the parameter (if it exists)
if (parms[pos]) delete parms[pos];
// Now slide all of the parameters to the left
for (int i = pos; i < nparms-1; i++) {
parms[i] = parms[i+1];
}
nparms--;
}
// ------------------------------------------------------------------
// Parm *ParmList::get(int pos)
//
// Gets the parameter at location pos. Returns 0 if invalid
// position.
// ------------------------------------------------------------------
Parm *ParmList::get(int pos) {
if ((pos < 0) || (pos >= nparms)) return 0;
return parms[pos];
}
// ------------------------------------------------------------------
// int ParmList::numopt()
//
// Gets the number of optional arguments.
// ------------------------------------------------------------------
int ParmList::numopt() {
int n = 0;
int state = 0;
for (int i = 0; i < nparms; i++) {
if (parms[i]->defvalue) {
n++;
state = 1;
} else if (typemap_check("default",typemap_lang,parms[i]->t,parms[i]->name)) {
n++;
state = 1;
} else if (typemap_check("ignore",typemap_lang,parms[i]->t,parms[i]->name)) {
n++;
} else if (typemap_check("build",typemap_lang,parms[i]->t,parms[i]->name)) {
n++;
} else {
if (state) {
fprintf(stderr,"%s : Line %d. Argument %d must have a default value!\n", input_file,line_number,i+1);
}
}
}
return n;
}
// ------------------------------------------------------------------
// int ParmList::numarg()
//
// Gets the number of arguments
// ------------------------------------------------------------------
int ParmList::numarg() {
int n = 0;
for (int i = 0; i < nparms; i++) {
if (!parms[i]->ignore)
n++;
}
return n;
}
// ------------------------------------------------------------------
// Parm &ParmList::operator[](int n)
//
// Returns parameter n in the parameter list. May generate
// an error if that parameter is out of range.
// ------------------------------------------------------------------
Parm &ParmList::operator[](int n) {
if ((n < 0) || (n >= nparms)) {
fprintf(stderr,"ParmList : Fatal error. subscript out of range in ParmList.operator[]\n");
SWIG_exit(1);
}
return *parms[n];
}
// ---------------------------------------------------------------------
// Parm * ParmList::get_first()
//
// Returns the first item on a parameter list.
// ---------------------------------------------------------------------
Parm *ParmList::get_first() {
current_parm = 0;
if (nparms > 0) return parms[current_parm++];
else return (Parm *) 0;
}
// ----------------------------------------------------------------------
// Parm *ParmList::get_next()
//
// Returns the next item on the parameter list.
// ----------------------------------------------------------------------
Parm * ParmList::get_next() {
if (current_parm >= nparms) return 0;
else return parms[current_parm++];
}
// ---------------------------------------------------------------------
// void ParmList::print_types(FILE *f)
//
// Prints a comma separated list of all of the parameter types.
// This is for generating valid C prototypes. Has to do some
// manipulation of pointer types depending on how the call_type
// variable has been set.
// ----------------------------------------------------------------------
void ParmList::print_types(FILE *f) {
int is_pointer;
int pn;
pn = 0;
while(pn < nparms) {
is_pointer = parms[pn]->t->is_pointer;
if (parms[pn]->t->is_reference) {
if (parms[pn]->t->is_pointer) {
parms[pn]->t->is_pointer--;
fprintf(f,"%s&", parms[pn]->t->print_real());
parms[pn]->t->is_pointer++;
} else {
fprintf(f,"%s&", parms[pn]->t->print_real());
}
} else {
if (parms[pn]->call_type & CALL_VALUE) parms[pn]->t->is_pointer++;
if (parms[pn]->call_type & CALL_REFERENCE) parms[pn]->t->is_pointer--;
fprintf(f,"%s", parms[pn]->t->print_real());
parms[pn]->t->is_pointer = is_pointer;
}
pn++;
if (pn < nparms)
fprintf(f,",");
}
}
// ---------------------------------------------------------------------
// void ParmList::print_types(String &f)
//
// Generates a comma separated list of function types. Is used in
// C++ code generation when generating hash keys and for function overloading.
// ----------------------------------------------------------------------
void ParmList::print_types(String &f) {
int is_pointer;
int pn;
pn = 0;
while(pn < nparms) {
is_pointer = parms[pn]->t->is_pointer;
if (parms[pn]->t->is_reference) {
if (parms[pn]->t->is_pointer) {
parms[pn]->t->is_pointer--;
f << parms[pn]->t->print_real() << "&";
parms[pn]->t->is_pointer++;
} else {
f << parms[pn]->t->print_real() << "&";
}
} else {
if (parms[pn]->call_type & CALL_VALUE) parms[pn]->t->is_pointer++;
if (parms[pn]->call_type & CALL_REFERENCE) parms[pn]->t->is_pointer--;
f << parms[pn]->t->print_real();
parms[pn]->t->is_pointer = is_pointer;
}
pn++;
if (pn < nparms)
f << ",";
}
}
// ---------------------------------------------------------------------
// void ParmList::print_args(FILE *f)
//
// Prints a comma separated list of all of the parameter arguments.
// ----------------------------------------------------------------------
void ParmList::print_args(FILE *f) {
int is_pointer;
int pn;
pn = 0;
while(pn < nparms) {
is_pointer = parms[pn]->t->is_pointer;
if (parms[pn]->t->is_reference) {
if (parms[pn]->t->is_pointer) {
parms[pn]->t->is_pointer--;
fprintf(f,"%s&", parms[pn]->t->print_full());
parms[pn]->t->is_pointer++;
} else {
fprintf(f,"%s&", parms[pn]->t->print_full());
}
} else {
if (parms[pn]->call_type & CALL_VALUE) parms[pn]->t->is_pointer++;
if (parms[pn]->call_type & CALL_REFERENCE) parms[pn]->t->is_pointer--;
fprintf(f,"%s", parms[pn]->t->print_full());
parms[pn]->t->is_pointer = is_pointer;
}
fprintf(f,"%s",parms[pn]->name);
pn++;
if (pn < nparms)
fprintf(f,",");
}
}
// -------------------------------------------------------------------
// int check_defined()
//
// Checks to see if all of the datatypes are defined.
// -------------------------------------------------------------------
int ParmList::check_defined() {
int a = 0;
int i;
for (i = 0; i < nparms; i++) {
if (parms[i]) {
a+=parms[i]->t->check_defined();
}
}
if (a) return 1;
else return 0;
}
// -------------------------------------------------------------------
// void ParmList::sub_parmnames(String &s)
//
// Given a string, this function substitutes all of the parameter
// names with their internal representation. Used in very special
// kinds of typemaps.
// -------------------------------------------------------------------
void ParmList::sub_parmnames(String &s) {
Parm *p;
extern char *emit_local(int i);
for (int i = 0; i < nparms; i++) {
p = get(i);
if (strlen(p->name) > 0) {
s.replaceid(p->name, emit_local(i));
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,149 @@
typedef union {
char *id;
struct Declaration {
char *id;
int is_pointer;
int is_reference;
} decl;
struct InitList {
char **names;
int count;
} ilist;
struct DocList {
char **names;
char **values;
int count;
} dlist;
struct Define {
char *id;
int type;
} dtype;
DataType *type;
Parm *p;
TMParm *tmparm;
ParmList *pl;
int ivalue;
} YYSTYPE;
#define ID 258
#define HBLOCK 259
#define WRAPPER 260
#define POUND 261
#define STRING 262
#define NUM_INT 263
#define NUM_FLOAT 264
#define CHARCONST 265
#define NUM_UNSIGNED 266
#define NUM_LONG 267
#define NUM_ULONG 268
#define TYPEDEF 269
#define TYPE_INT 270
#define TYPE_UNSIGNED 271
#define TYPE_SHORT 272
#define TYPE_LONG 273
#define TYPE_FLOAT 274
#define TYPE_DOUBLE 275
#define TYPE_CHAR 276
#define TYPE_VOID 277
#define TYPE_SIGNED 278
#define TYPE_BOOL 279
#define TYPE_TYPEDEF 280
#define LPAREN 281
#define RPAREN 282
#define COMMA 283
#define SEMI 284
#define EXTERN 285
#define INIT 286
#define LBRACE 287
#define RBRACE 288
#define DEFINE 289
#define PERIOD 290
#define CONST 291
#define STRUCT 292
#define UNION 293
#define EQUAL 294
#define SIZEOF 295
#define MODULE 296
#define LBRACKET 297
#define RBRACKET 298
#define WEXTERN 299
#define ILLEGAL 300
#define READONLY 301
#define READWRITE 302
#define NAME 303
#define RENAME 304
#define INCLUDE 305
#define CHECKOUT 306
#define ADDMETHODS 307
#define PRAGMA 308
#define CVALUE 309
#define COUT 310
#define ENUM 311
#define ENDDEF 312
#define MACRO 313
#define CLASS 314
#define PRIVATE 315
#define PUBLIC 316
#define PROTECTED 317
#define COLON 318
#define STATIC 319
#define VIRTUAL 320
#define FRIEND 321
#define OPERATOR 322
#define THROW 323
#define TEMPLATE 324
#define NATIVE 325
#define INLINE 326
#define IFDEF 327
#define IFNDEF 328
#define ENDIF 329
#define ELSE 330
#define UNDEF 331
#define IF 332
#define DEFINED 333
#define ELIF 334
#define RAW_MODE 335
#define ALPHA_MODE 336
#define TEXT 337
#define DOC_DISABLE 338
#define DOC_ENABLE 339
#define STYLE 340
#define LOCALSTYLE 341
#define TYPEMAP 342
#define EXCEPT 343
#define IMPORT 344
#define ECHO 345
#define NEW 346
#define APPLY 347
#define CLEAR 348
#define DOCONLY 349
#define TITLE 350
#define SECTION 351
#define SUBSECTION 352
#define SUBSUBSECTION 353
#define LESSTHAN 354
#define GREATERTHAN 355
#define USERDIRECTIVE 356
#define OC_INTERFACE 357
#define OC_END 358
#define OC_PUBLIC 359
#define OC_PRIVATE 360
#define OC_PROTECTED 361
#define OC_CLASS 362
#define OC_IMPLEMENT 363
#define OC_PROTOCOL 364
#define OR 365
#define XOR 366
#define AND 367
#define LSHIFT 368
#define RSHIFT 369
#define PLUS 370
#define MINUS 371
#define STAR 372
#define SLASH 373
#define UMINUS 374
#define NOT 375
#define LNOT 376
#define DCOLON 377
extern YYSTYPE yylval;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,587 @@
/*******************************************************************************
* 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 <ctype.h>
//-----------------------------------------------------------------------
// char *copy_string(char *str)
//
// Makes a copy of string str. Returns a pointer to it.
//-----------------------------------------------------------------------
char *copy_string(char *str) {
char *res = 0;
if (str) {
res = new char[strlen(str)+1];
strcpy(res,str);
}
return res;
}
//-----------------------------------------------------------------------
// void format_string(char *str)
//
// Replace all of the escape sequences in the string str. It is
// assumed that the new string is smaller than the original!
//-----------------------------------------------------------------------
void format_string(char *str) {
char *newstr, *c,*c1;
int state;
if (!str) return;
newstr = copy_string(str);
c = newstr;
c1 = str;
state = 0;
while (*c) {
switch(state) {
case 0:
if (*c == '\\')
state = 1;
else {
*(c1++) = *c;
state = 0;
}
break;
case 1:
// We're in a simple escape sequence figure out what to do
switch(*c) {
case 'n':
*(c1++) = '\n';
break;
case 'f':
*(c1++) = '\f';
break;
case 'r':
*(c1++) = '\r';
break;
case 't':
*(c1++) = '\t';
break;
case '\\':
*(c1++) = '\\';
break;
case '\"':
*(c1++) = '\"';
break;
case '\'':
*(c1++) = '\'';
break;
default:
*(c1++) = '\\';
*(c1++) = *c;
}
state = 0;
break;
default:
*(c1++) = *c;
state = 0;
}
c++;
}
*c1 = 0;
delete newstr;
}
// ---------------------------------------------------------------------------
// $Header$
// sstring.cxx
//
// SWIG String class.
// This class is used to construct long strings when writing
// wrapper functions. It also "mimicks" the C++ streams I/O
// library for creating strings. For example :
//
// str << "hi there" << 3 << "\n";
//
// Will append the given strings to str.
//
// The idea here is to provide a mechanism for writing wrapper
// functions as strings before writing them out to a file.
//
// ---------------------------------------------------------------------------
#define INIT_MAXSIZE 64
// ---------------------------------------------------------------
// Pools. This is a list of available strings for memory allocation
// and deletion.
// ---------------------------------------------------------------
struct StrMem {
char *str;
int len;
};
#define POOLSIZE 100
static StrMem pool[POOLSIZE];
static int pool_index = 0;
// Returns an item from the pool that can accomodate len
static char *get_pool(int len, int &newlen) {
int i,j;
char *nc;
if (pool_index < 1) {
newlen = len;
return new char[len];
}
i = pool_index-1;
j = 0;
while(i >= 0) {
if ((pool[i].len >= len) && (pool[i].len <= 4*len)) {
nc = pool[i].str;
newlen = pool[i].len;
pool[i].str = pool[pool_index-1].str;
pool[i].len = pool[pool_index-1].len;
pool_index--;
return nc;
}
j++;
i--;
}
newlen = len;
return new char[len];
}
// Puts an item onto the pool
static void put_pool(char *str, int len) {
if (len < INIT_MAXSIZE) {
delete [] str;
return;
}
if (pool_index == POOLSIZE) {
delete [] pool[pool_index-1].str;
pool_index--;
}
pool[pool_index].str = str;
pool[pool_index].len = len;
if (pool_index != POOLSIZE)
pool_index++;
}
// ---------------------------------------------------------------
// String::String()
//
// Create a new string with nothing in it
// ---------------------------------------------------------------
String::String() {
maxsize = INIT_MAXSIZE;
str = get_pool(maxsize,maxsize); // May return a pool that is larger
str[0] = 0;
len = 0;
}
// ---------------------------------------------------------------
// String::String(const char *s)
//
// Create a new string copied from a normal C-style string
// ---------------------------------------------------------------
String::String(const char *s) {
int max = INIT_MAXSIZE;
int l = 0;
if (s) {
l = (int) strlen(s);
if ((l+1) > max) max = l+1;
}
str = get_pool(max,maxsize);
if (s) {
strcpy(str,s);
len = l;
} else {
str[0] = 0;
len = 0;
}
}
// ---------------------------------------------------------------
// String::~String(const char *s)
//
// Destroy a string
// ---------------------------------------------------------------
String::~String() {
put_pool(str,maxsize);
}
// ---------------------------------------------------------------
// String::add(const char *newstr)
//
// Concatenate newstr onto the current string
// ---------------------------------------------------------------
void String::add(const char *newstr) {
int newlen;
char *nstr = 0;
int newmaxsize;
int l;
l = (int) strlen(newstr);
newlen = len+l + 1;
if (newlen >= maxsize-1) {
newmaxsize = 2*maxsize;
if (newlen >= newmaxsize -1) newmaxsize = newlen + 1;
nstr = get_pool(newmaxsize,newmaxsize);
strcpy(nstr,str);
put_pool(str,maxsize);
maxsize = newmaxsize;
str = nstr;
}
strcpy(str+len,newstr);
len += l;
}
// ---------------------------------------------------------------
// String::add(char)
//
// Adds a single character to the current string
// ---------------------------------------------------------------
void String::add(char nc) {
int newlen;
char *nstr = 0;
int newmaxsize;
newlen = len+ 1;
if (newlen >= maxsize-1) {
newmaxsize = 2*maxsize;
if (newlen >= newmaxsize -1) newmaxsize = newlen + 1;
nstr = get_pool(newmaxsize,newmaxsize);
strcpy(nstr,str);
put_pool(str,maxsize);
maxsize = newmaxsize;
str = nstr;
}
str[len++] = nc;
str[len] = 0;
}
// -----------------------------------------------------------------
// String::insert(const char *newstr)
//
// Inserts a string into the front of a string. (Primarily used
// for documentation generation)
// -----------------------------------------------------------------
void String::insert(const char *newstr) {
int newlen;
char *nstr = 0;
int newmaxsize;
int i,l;
l = strlen(newstr);
newlen = len + l + 1;
if (newlen >= maxsize-1) {
newmaxsize = 2*maxsize;
if (newlen >= newmaxsize -1) newmaxsize = newlen + 1;
nstr = get_pool(newmaxsize,newmaxsize);
strcpy(nstr,str);
put_pool(str,maxsize);
maxsize = newmaxsize;
str = nstr;
}
/* Shift all of the characters over */
for (i = len -1; i >= 0; i--) {
str[i+l] = str[i];
}
/* Now insert the new string */
strncpy(str,newstr,l);
len += l;
str[len] = 0;
}
// -----------------------------------------------------------------
// char *String::get()
//
// Get the current value of the string
// -----------------------------------------------------------------
char *String::get() const {
return str;
}
// -----------------------------------------------------------------
// String &operator<<(...)
//
// Shorthand for appending to the end of a string
// -----------------------------------------------------------------
String &operator<<(String &t,const char *s) {
t.add(s);
return t;
}
String &operator<<(String &t,const char s) {
t.add(s);
return t;
}
String &operator<<(String &t,const int a) {
char temp[64];
sprintf(temp,"%d",a);
t.add(temp);
return t;
}
String &operator<<(String &t, String &s) {
t.add(s.get());
return t;
}
String &String::operator=(const char *s) {
int newlen;
if (s) {
newlen = strlen(s);
if ((newlen >= maxsize) && (str)) {
put_pool(str,maxsize);
str = get_pool(newlen+1,maxsize);
maxsize = newlen+1;
}
strcpy(str,s);
len = newlen;
} else {
str[0] = 0;
len = 0;
}
return *this;
}
// -----------------------------------------------------------------
// String &operator>>(...)
//
// Shorthand for inserting into the beginning of a string
// -----------------------------------------------------------------
String &operator>>(const char *s, String &t) {
t.insert(s);
return t;
}
String &operator>>(String &s, String &t) {
t.insert(s.get());
return t;
}
// -----------------------------------------------------------------
// void String::untabify()
//
// Expand all tabs into spaces. This is useful for producing
// documentation and other things.
// -----------------------------------------------------------------
void String::untabify() {
char *s;
char *c;
int pos;
int i;
int oldmaxsize;
// Copy the current string representation
s = str;
oldmaxsize = maxsize;
// Reset the internal state of this string
len = 0;
str = get_pool(maxsize,maxsize);
str[0]= 0;
// Now walk down the old string and expand tabs. Tabs are usually place
// every 8 characters.
pos = 0;
c = s;
while (*c) {
if (*c == '\n') {
pos = -1;
}
if (*c == '\t') {
// Expand the character
for (i = 0; i < (8 - (pos % 8)); i++) {
this->add(' ');
}
pos+=(8-(pos % 8));
} else {
this->add(*c);
pos++;
}
c++;
}
// Blow away the old string
put_pool(s,oldmaxsize);
}
// -----------------------------------------------------------------
// void String::replace(const char *token, const char *rep)
//
// Search for tokens in a string and replace them with rep.
// This probably isn't the fastest implementation, but fortunately
// SWIG rarely calls this function.
// -----------------------------------------------------------------
void String::replace(const char *token, const char *rep) {
char *s, *c, *t;
int oldmaxsize = maxsize;
// Copy the current string representation
s = str;
// Now walk down the old string and search for tokens
c = s;
t = strstr(c,token);
if (t) {
len = 0;
str = get_pool(maxsize,maxsize);
while (t) {
// Found a token in string s
// Dump characters into our string
char temp;
temp = *t;
*t = 0;
this->add(c);
c = t;
*t = temp;
// Now dump the replacement string into place
this->add(rep);
// Jump over the token
c+=strlen(token);
t = strstr(c,token);
}
// Attach rest of the string
if (*c)
this->add(c);
put_pool(s,oldmaxsize);
}
}
// -----------------------------------------------------------------
// void String::replaceid(char *token, char *rep)
//
// Searches for valid identifiers matching token and replaces
// them with rep. Unlike replace() tokens must be a valid C
// identifier (surrounded by whitespace).
// -----------------------------------------------------------------
void String::replaceid(const char *token, const char *rep) {
char *s, *c, *t;
int whitespace, tokenlen;
int oldmaxsize = maxsize;
// Copy the current string representation
s = str;
// Reset the internal state of this string
tokenlen = strlen(token);
// Now walk down the old string and search for tokens
c = s;
t = strstr(c,token);
if (t) {
len = 0;
str = get_pool(maxsize,maxsize);
while (t) {
// Found a token in string s
// Dump characters into our string
whitespace = 1;
while (c != t) {
this->add(*c);
if (!(isalpha(*c) || (*c == '_') || (*c == '$'))) whitespace = 1;
else whitespace = 0;
c++;
}
if (whitespace) {
// Check to see if there is whitespace afterwards
if ((!c[tokenlen]) || (!(isalnum(c[tokenlen]) || (c[tokenlen] == '_') || (c[tokenlen] == '$')))) {
this->add(rep);
} else {
this->add(token);
}
c+=tokenlen;
} else {
this->add(*c);
c++;
}
t = strstr(c,token);
}
// Attach rest of the string
if (*c)
this->add(c);
// Delete the old string
put_pool(s,oldmaxsize);
}
}
// -----------------------------------------------------------------
// void String::strip()
//
// Intelligently strips whitespace from a string. Will not strip
// whitespace if it is between two characters that are part of a
// legal C identifier. For example 'unsigned int'.
// -----------------------------------------------------------------
void String::strip() {
char *s = str; // Old pointer value
char *c, lastchar = 0;
int whitespace = 0;
int oldmaxsize = maxsize;
str = get_pool(maxsize,maxsize); // Get a new string.
len = 0;
c = s;
while(*c) {
if (!isspace(*c)) {
// See if this character doesn't violate our whitespace rules
if (whitespace) {
if (isalnum(lastchar) || (lastchar == '_') || (lastchar == '$')) {
if (isalnum(*c) || (*c == '_') || (*c == '$'))
this->add(' ');
}
}
this->add(*c);
lastchar = *c;
whitespace = 0;
} else {
whitespace = 1;
}
c++;
}
put_pool(s,oldmaxsize);
}

View File

@@ -0,0 +1,196 @@
/*******************************************************************************
* 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"
/*******************************************************************************
* $Header$
*
* File : symbol.cxx
*
* Symbol table management.
*
*******************************************************************************/
// -----------------------------------------------------------------------------
// Symbol object
// -----------------------------------------------------------------------------
struct Symbol {
~Symbol() {
if (name) delete name;
if (type) delete type;
if (value) delete value;
}
char *name;
DataType *type; // Optional datatype
char *value; // Optional value (for constant expressions)
};
static Hash SymHash; // SWIG Symbol table
// -----------------------------------------------------------------------------
// int add_symbol(char *name, DataType *type, char *value)
//
// Adds a symbol to the symbol table. Returns -1 if symbol is already in the
// table.
//
// Inputs :
// name = Symbol name
// type = Datatype (for constants). Optional.
// value = Value string. Optional.
//
// Output : 0 on success, -1 if symbol already exists.
//
// Side Effects : None
// -----------------------------------------------------------------------------
int add_symbol(char *name, DataType *type, char *value) {
Symbol *s;
int ret;
s = new Symbol;
s->name = copy_string(name);
if (type)
s->type = new DataType(type);
else s->type = (DataType *) 0;
if (value)
s->value = copy_string(value);
else s->value = (char *) 0;
// Add this to the symbol table
ret = SymHash.add(s->name, s);
if (ret == -1) {
delete s;
}
return ret;
}
// -----------------------------------------------------------------------------
// int lookup_symbol(char *name)
//
// Checks to see if a symbol is in the symbol table.
//
// Inputs : name = Symbol name
//
// Output : 0 if not found, 1 if found.
//
// Side Effects : None
// -----------------------------------------------------------------------------
int lookup_symbol(char *name) {
Symbol *s;
s = (Symbol *) SymHash.lookup(name);
if (s) return 1;
else return 0;
}
// -----------------------------------------------------------------------------
// DataType *lookup_symtype(char *name)
//
// Returns the datatype of a symbol or NULL if not found.
//
// Inputs : name = Symbol name
//
// Output : Datatype of symbol, NULL if not found.
//
// Side Effects : None
// -----------------------------------------------------------------------------
DataType *lookup_symtype(char *name) {
Symbol *s;
s = (Symbol *) SymHash.lookup(name);
if (s) return s->type;
else return (DataType *) 0;
}
// -----------------------------------------------------------------------------
// char *lookup_symvalue(char *name)
//
// Returns the value associate with a symbol.
//
// Inputs : name = Symbol name
//
// Output : Symbol value (or NULL if not present).
//
// Side Effects : None
// -----------------------------------------------------------------------------
char *lookup_symvalue(char *name) {
Symbol *s;
s = (Symbol *) SymHash.lookup(name);
if (s) return s->value;
else return (char *) 0;
}
// -----------------------------------------------------------------------------
// int update_symbol(char *name, DataType *type, char *value)
//
// Updates a symbol (or create it) in the hash table.
//
// Inputs :
// name = Name of symbol
// type = Datatype of symbol (optional)
// value = Symbol value (optional)
//
// Output : 0
//
// Side Effects : None
// -----------------------------------------------------------------------------
int update_symbol(char *name, DataType *type, char *value) {
Symbol *s;
s = (Symbol *) SymHash.lookup(name);
if (s) {
if (s->type) delete s->type;
if (s->value) delete s->value;
if (type)
s->type = new DataType(type);
else
s->type = (DataType *) 0;
if (value)
s->value = copy_string(value);
else
s->value = (char *) 0;
return 0;
} else {
return add_symbol(name, type, value);
}
}
// -----------------------------------------------------------------------------
// void remove_symbol(char *name)
//
// Removes a symbol from the symbol table.
//
// Inputs : name = Symbol name.
//
// Output : None
//
// Side Effects : None
// -----------------------------------------------------------------------------
void remove_symbol(char *name) {
SymHash.remove(name);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,164 @@
/*******************************************************************************
* 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.
*******************************************************************************/
// ------------------------------------------------------------------
// wrapfunc.cxx
//
// Created : June 22, 1996
// Dave Beazley
//
// This file defines a class for writing wrappers. Instead of worrying
// about I/O problems, this wrapper class can be used to write functions
// out of order.
//
// Defines 3 string objects.
// def - Wrapper function definition (function name and arguments)
// locals - Local variable definitions
// code - The actual wrapper function code
//
//-------------------------------------------------------------------
#include "internal.h"
#include <ctype.h>
// -------------------------------------------------------------------
// Print out a wrapper function.
//
// -------------------------------------------------------------------
void WrapperFunction::print(FILE *f) {
fprintf(f,"%s\n",def.get());
fprintf(f,"%s\n",locals.get());
fprintf(f,"%s\n",code.get());
}
// -------------------------------------------------------------------
// Print out a wrapper function.
//
// -------------------------------------------------------------------
void WrapperFunction::print(String &f) {
f << def << "\n"
<< locals << "\n"
<< code << "\n";
}
// -------------------------------------------------------------------
// Safely add a local variable.
//
// Maintains a hash table to prevent double adding.
// -------------------------------------------------------------------
void WrapperFunction::add_local(char *type, char *name, char *defarg) {
char *stored_type;
char *new_type;
char temp[256],*c,*t;
new_type = new char[strlen(type)+1];
strcpy(new_type,type);
// Figure out what the name of this variable is
c = name;
t = temp;
while ((isalnum(*c) || (*c == '_') || (*c == '$')) && (*c)) {
*(t++) = *c;
c++;
}
*t = 0;
if (h.add(temp,new_type,WrapperFunction::del_type) == -1) {
// Check to see if a type mismatch has occurred
stored_type = (char *) h.lookup(temp);
if (strcmp(type,stored_type) != 0)
fprintf(stderr,"Error. Type %s conflicts with previously declared type of %s\n",
type, stored_type);
return;
}
// Successful, write some wrapper code
if (!defarg)
locals << tab4 << type << " " << name << ";\n";
else
locals << tab4 << type << " " << name << " = " << defarg << ";\n";
}
// -------------------------------------------------------------------
// char *WrapperFunction::new_local(char *type, char *name, char *defarg) {
//
// A safe way to add a new local variable. type and name are used as
// a starting point, but a new local variable will be created if these
// are already in use.
// -------------------------------------------------------------------
char *WrapperFunction::new_local(char *type, char *name, char *defarg) {
char *new_type;
static String new_name;
char *c;
new_type = new char[strlen(type)+1];
strcpy(new_type,type);
new_name = "";
c = name;
for (c = name; ((isalnum(*c) || (*c == '_') || (*c == '$')) && (*c)); c++)
new_name << *c;
// Try to add a new local variable
if (h.add(new_name,new_type,WrapperFunction::del_type) == -1) {
// Local variable already exists, try to generate a new name
int i = 0;
new_name = "";
// This is a little funky. We copy characters until we reach a nonvalid
// identifier symbol, add a number, then append the rest. This is
// needed to properly handle arrays.
c = name;
for (c = name; ((isalnum(*c) || (*c == '_') || (*c == '$')) && (*c)); c++)
new_name << *c;
new_name << i;
while (h.add(new_name,new_type,WrapperFunction::del_type) == -1) {
i++;
c = name;
new_name = "";
for (c = name; ((isalnum(*c) || (*c == '_') || (*c == '$')) && (*c)); c++)
new_name << *c;
new_name << i;
}
}
new_name << c;
// Successful, write some wrapper code
if (!defarg)
locals << tab4 << type << " " << new_name << ";\n";
else
locals << tab4 << type << " " << new_name << " = " << defarg << ";\n";
// Need to strip off the array symbols now
c = new_name.get();
while ((isalnum(*c) || (*c == '_') || (*c == '$')) && (*c))
c++;
*c = 0;
return new_name;
}
// ------------------------------------------------------------------
// static WrapperFunction::del_type(void *obj)
//
// Callback function used when cleaning up the hash table.
// ------------------------------------------------------------------
void WrapperFunction::del_type(void *obj) {
delete (char *) obj;
}