wxWidgets/wxPython/wxSWIG/SWIG/lang.cxx
Robin Dunn c90f71dd8c 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
2002-04-29 19:56:57 +00:00

622 lines
17 KiB
C++

/*******************************************************************************
* Simplified Wrapper and Interface Generator (SWIG)
*
* Author : David Beazley
*
* Department of Computer Science
* University of Chicago
* 1100 E 58th Street
* Chicago, IL 60637
* beazley@cs.uchicago.edu
*
* Please read the file LICENSE for the copyright and terms by which SWIG
* can be used and distributed.
*******************************************************************************/
#include "internal.h"
#include <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
}