git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@967 626c5289-ae23-0410-ae9c-e8d60b6d4f22
909 lines
22 KiB
C++
909 lines
22 KiB
C++
/* -----------------------------------------------------------------------------
|
|
* generate.cxx
|
|
*
|
|
* This file manages the code generation process and serves as a bridge between
|
|
* the new SWIG parser and the old set of C++-based language modules.
|
|
*
|
|
* Author(s) : David Beazley (beazley@cs.uchicago.edu)
|
|
*
|
|
* Copyright (C) 1999-2000. The University of Chicago
|
|
* See the file LICENSE for information on usage and redistribution.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
#include "swig11.h"
|
|
|
|
static char cvstag[] = "$Header$";
|
|
|
|
int ReadOnly = 0;
|
|
int WrapExtern = 0;
|
|
|
|
/* Access permissions: public, private, protected */
|
|
enum { PUBLIC, PRIVATE, PROTECTED };
|
|
int Access = PUBLIC;
|
|
|
|
/* Miscellaneous modes */
|
|
int Native = 0;
|
|
|
|
/* This function tries to locate the module name within the parse tree */
|
|
static String *find_module(DOH *node) {
|
|
DOH *n;
|
|
|
|
if (!node) return 0;
|
|
n = node;
|
|
while (n) {
|
|
if (Swig_tag_check(n,"module")) {
|
|
return Getname(n);
|
|
}
|
|
if (Swig_tag_check(n,"file")) {
|
|
String *ty;
|
|
ty = Getattr(n,"type");
|
|
if (Cmp(ty,"include") == 0) {
|
|
DOH *m;
|
|
/* Might be in an include file */
|
|
m = find_module(Getchild(n));
|
|
if (m) return m;
|
|
}
|
|
}
|
|
n = Getnext(n);
|
|
}
|
|
return find_module(Getchild(node));
|
|
}
|
|
|
|
/* This helper function emits external function declarations */
|
|
static
|
|
void emit_extern_func(DOH *node, File *f) {
|
|
Parm *p;
|
|
SwigType *tc;
|
|
char *c;
|
|
String *storage;
|
|
storage = Getattr(node,"storage");
|
|
if (!storage) return;
|
|
c = Char(storage);
|
|
if (strncmp(c,"extern",6) == 0) {
|
|
List *tl = NewList();
|
|
p = Getparms(node);
|
|
while (p) {
|
|
Append(tl,Gettype(p));
|
|
p = Getnext(p);
|
|
}
|
|
tc = Copy(Gettype(node));
|
|
SwigType_add_function(tc,tl);
|
|
Printf(f,"%s %s;\n", storage, SwigType_str(tc,Getname(node)));
|
|
Delete(tc);
|
|
Delete(tl);
|
|
}
|
|
}
|
|
|
|
/* Test if static */
|
|
static int
|
|
check_static(DOH *node) {
|
|
String *storage = Getattr(node,"storage");
|
|
if (!storage) return 0;
|
|
if (Cmp(storage,"static") == 0) return 1;
|
|
return 0;
|
|
}
|
|
|
|
/* Test if extern */
|
|
static int
|
|
check_extern(DOH *node) {
|
|
String *storage = Getattr(node,"storage");
|
|
if (!storage) return 0;
|
|
if (strncmp(Char(storage),"extern",6) == 0) return 1;
|
|
return 0;
|
|
}
|
|
|
|
static String *new_name = 0;
|
|
|
|
/* Handle renaming */
|
|
static
|
|
void set_scriptname(DOH *node) {
|
|
if (new_name) {
|
|
Setattr(node,"scriptname",new_name);
|
|
} else {
|
|
String *aname = Getattr(node,"altname");
|
|
if (aname) {
|
|
Setattr(node,"scriptname",aname);
|
|
} else {
|
|
Setattr(node,"scriptname", Getname(node));
|
|
}
|
|
}
|
|
new_name = 0;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* C++ Support
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
static DOH *class_hash = 0; /* Hash table of classes that have been seen so far */
|
|
static DOH *current_class = 0; /* Set when wrapping a class */
|
|
static DOH *class_name = 0; /* Real name of current class */
|
|
static DOH *class_types = 0; /* Types defined within this class */
|
|
static String *construct_name = 0; /* Expected name of a constructor */
|
|
int AddMethods = 0; /* Set when in addmethods mode */
|
|
int Abstract = 0; /* Set when the class is determined to be abstract */
|
|
static int have_destructor = 0;
|
|
static int have_constructor = 0;
|
|
|
|
/* Check for abstract classes */
|
|
|
|
int cplus_check_abstract(DOH *node) {
|
|
while (node) {
|
|
if (Getattr(node,"abstract")) return 1;
|
|
node = Getnext(node);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* Given a class object, this function builds an internal symbol table */
|
|
void cplus_build_symbols(DOH *node) {
|
|
Hash *sym;
|
|
DOH *c;
|
|
sym = Getattr(node,"symbols");
|
|
if (!sym) {
|
|
sym = NewHash();
|
|
Setattr(node,"symbols",sym);
|
|
}
|
|
c = Getchild(node);
|
|
while (c) {
|
|
String *name = Getname(c);
|
|
String *tag = Gettag(c);
|
|
if (Cmp(tag,"c:destructor") == 0) {
|
|
name = NewStringf("~%s",name);
|
|
}
|
|
if (name) {
|
|
DOH *pnode = Getattr(sym,name);
|
|
if (pnode) {
|
|
Printf(stderr,"%s:%d. '%s' redefined. Previous definition at %s:%d.\n",
|
|
Getfile(c),Getline(c), name, Getfile(pnode), Getline(pnode));
|
|
} else {
|
|
Setattr(sym,name,c);
|
|
}
|
|
}
|
|
c = Getnext(c);
|
|
}
|
|
return;
|
|
}
|
|
|
|
/* Inherit certain types of declarations from another class */
|
|
|
|
|
|
|
|
/* Add a class type */
|
|
static void
|
|
class_addtype(String *name, String *cname) {
|
|
String *s;
|
|
if (!cname)
|
|
s = NewStringf("%s::%s", class_name, name);
|
|
else
|
|
s = NewStringf("%s::%s", cname, name);
|
|
|
|
if (!class_types) class_types = NewHash();
|
|
Setattr(class_types,name,s);
|
|
}
|
|
|
|
/* Updates a type with a fully qualified version */
|
|
static void
|
|
class_update_type(String *type) {
|
|
String *base, *rep;
|
|
if (!type) return;
|
|
base = SwigType_base(type);
|
|
if (!class_types) return;
|
|
rep = Getattr(class_types,base);
|
|
if (rep) {
|
|
SwigType_setbase(type,rep);
|
|
/* Printf(stdout,"updated type = '%s'\n", type); */
|
|
}
|
|
}
|
|
|
|
/* Updates a list of parms with fully qualified names */
|
|
static void
|
|
class_update_parms(ParmList *p) {
|
|
while (p) {
|
|
class_update_type(Gettype(p));
|
|
p = Getnext(p);
|
|
}
|
|
}
|
|
|
|
/* Traverse the inheritance hierarchy of a class */
|
|
void
|
|
cplus_walk_inherit(DOH *cls, void (*action)(DOH *base, void *clientdata), void *clientdata) {
|
|
DOH *base;
|
|
List *bases;
|
|
int i, nbase;
|
|
|
|
bases = Getattr(cls,"bases");
|
|
if (bases) {
|
|
nbase = Len(bases);
|
|
for (i = 0; i < nbase; i++) {
|
|
base = Getattr(class_hash, Getitem(bases,i));
|
|
if (base) {
|
|
(*action)(base,clientdata);
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Action for inheriting type definitions */
|
|
static void inherit_types(DOH *cls, void *clientdata) {
|
|
DOH *ty;
|
|
ty = Getattr(cls,"types");
|
|
if (ty) {
|
|
String *key;
|
|
SwigType_merge_scope(ty,0);
|
|
for (key = Firstkey(ty); key; key = Nextkey(ty)) {
|
|
class_addtype(key, Getname(cls));
|
|
}
|
|
}
|
|
cplus_walk_inherit(cls,inherit_types,clientdata);
|
|
}
|
|
|
|
/* Action for inheriting typemaps */
|
|
static void inherit_typemaps(DOH *cls, void *clientdata) {
|
|
DOH *ty;
|
|
|
|
cplus_walk_inherit(cls,inherit_typemaps,clientdata);
|
|
ty = Getattr(cls,"typemaps");
|
|
if (ty) {
|
|
if (!clientdata)
|
|
Swig_typemap_new_scope(ty);
|
|
else
|
|
Swig_typemap_pop_scope();
|
|
}
|
|
}
|
|
|
|
extern "C" {
|
|
int swig11_unknown(DOH *node, void *clientdata) {
|
|
Printf(stdout,"::: Unknown tag - '%s'\n", Getattr(node,"tag"));
|
|
return 0;
|
|
}
|
|
|
|
int swig11_nil(DOH *node, void *clientdata) {
|
|
return 0;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* swig11_file()
|
|
*
|
|
* File inclusion directives. %include, %extern, and %import.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int swig11_file(DOH *node, void *clientdata) {
|
|
DOH *c;
|
|
String *type;
|
|
int old_we = WrapExtern;
|
|
|
|
type = Getattr(node,"type");
|
|
if ((Cmp(type, "extern") == 0) || (Cmp(type,"import") == 0)) {
|
|
WrapExtern = 1;
|
|
}
|
|
c = Getchild(node);
|
|
if (Cmp(type,"import") == 0) {
|
|
/* If importing a module, we try to find the module name and pass it to
|
|
the language modules */
|
|
String *modname;
|
|
modname = find_module(c);
|
|
if (modname) {
|
|
lang->import(modname);
|
|
}
|
|
}
|
|
Swig_emit_all(c,clientdata);
|
|
WrapExtern = old_we;
|
|
return 0;
|
|
}
|
|
/* -----------------------------------------------------------------------------
|
|
* swig11_scope()
|
|
*
|
|
* Handle the %scope directive. This is a new feature not present in SWIG1.1.
|
|
* Creates a new typemap scope and has other side effects.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int swig11_scope(DOH *node, void *clientdata) {
|
|
DOH *c;
|
|
String *name;
|
|
|
|
c = Getchild(node);
|
|
name = Getname(node);
|
|
|
|
Swig_typemap_new_scope(0);
|
|
if (name) {
|
|
if (Cmp(name,"native") == 0) {
|
|
int oldnative = Native;
|
|
Native = 1;
|
|
Swig_emit_all(c,clientdata);
|
|
Native = oldnative;
|
|
} else if (Cmp(name,"readonly") == 0) {
|
|
int oldro = ReadOnly;
|
|
ReadOnly = 1;
|
|
Swig_emit_all(c,clientdata);
|
|
ReadOnly = oldro;
|
|
} else {
|
|
Swig_emit_all(c,clientdata);
|
|
}
|
|
}
|
|
Hash *scp = Swig_typemap_pop_scope();
|
|
Setattr(node,"typemaps", scp);
|
|
return 0;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* swig11_insert()
|
|
*
|
|
* Code insertion with various %{ %} directives.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int swig11_insert(DOH *node, void *clientdata) {
|
|
String *section;
|
|
String *filename;
|
|
String *code;
|
|
File *out;
|
|
|
|
if (WrapExtern) return 0;
|
|
|
|
section = Getattr(node,"section");
|
|
if (!section) {
|
|
section = (void *) "header";
|
|
}
|
|
out = Swig_filebyname(section);
|
|
if (!out) {
|
|
Printf(stderr,"%s:%d. Can't insert code into unknown section '%s'\n", Getfile(node), Getline(node), section);
|
|
return 0;
|
|
}
|
|
filename = Getattr(node,"filename");
|
|
if (filename) {
|
|
/* The user is inserting the contents of a file */
|
|
if (Swig_insert_file(filename,out) < 0) {
|
|
Printf(stderr,"%s:%d. File '%s' not found.\n", Getfile(node), Getline(node), filename);
|
|
}
|
|
return 0;
|
|
}
|
|
code = Getattr(node,"code");
|
|
if (code) {
|
|
Printf(out,"%s",code);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* swig11_pragma()
|
|
*
|
|
* %pragma directive.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int swig11_pragma(DOH *node, void *clientdata) {
|
|
String *name;
|
|
String *value;
|
|
|
|
if (WrapExtern) return 0;
|
|
|
|
name = Getname(node);
|
|
value = Getvalue(node);
|
|
|
|
if (Cmp(name,"readonly") == 0) {
|
|
ReadOnly = 1;
|
|
} else if (Cmp(name,"readwrite") == 0) {
|
|
ReadOnly = 0;
|
|
} else if (Cmp(name,"name") == 0) {
|
|
new_name = value;
|
|
}
|
|
lang->pragma(node);
|
|
return 0;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* swig11_typemap()
|
|
*
|
|
* Handle the %typemap directive.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int swig11_typemap(DOH *node, void *clientdata) {
|
|
String *name;
|
|
SwigType *type;
|
|
String *code;
|
|
DOH *parms;
|
|
String *method;
|
|
|
|
if (WrapExtern) return 0;
|
|
method = Getattr(node,"method");
|
|
name = Getname(node);
|
|
type = Gettype(node);
|
|
code = Getattr(node,"code");
|
|
parms = Getparms(node);
|
|
|
|
if (current_class) {
|
|
class_update_type(type);
|
|
class_update_type(parms);
|
|
}
|
|
|
|
if (code) {
|
|
Swig_typemap_register(method,type,name,code,parms);
|
|
} else {
|
|
String *srcname;
|
|
String *srctype;
|
|
srcname = Getattr(node,"srcname");
|
|
srctype = Getattr(node,"srctype");
|
|
if (srcname && srctype) {
|
|
Swig_typemap_copy(method,srctype,srcname,type,name);
|
|
} else {
|
|
Swig_typemap_clear(method,type,name);
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* swig11_apply()
|
|
*
|
|
* The %apply directive.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int swig11_apply(DOH *node, void *clientdata) {
|
|
DOH *parms;
|
|
String *name;
|
|
SwigType *type;
|
|
|
|
if (WrapExtern) return 0;
|
|
|
|
name = Getname(node);
|
|
type = Gettype(node);
|
|
parms = Getparms(node);
|
|
|
|
while (parms) {
|
|
Swig_typemap_apply(type,name,Gettype(parms),Getname(parms));
|
|
parms = Getnext(parms);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* swig11_exception()
|
|
*
|
|
* The %except directive.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int swig11_exception(DOH *node, void *clientdata) {
|
|
String *code = Getattr(node,"code");
|
|
if (WrapExtern) return 0;
|
|
if (code) {
|
|
Swig_except_register(code);
|
|
} else {
|
|
Swig_except_clear();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* swig11_clear()
|
|
*
|
|
* The %clear directive.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int swig11_clear(DOH *node, void *clientdata) {
|
|
DOH *parms = Getattr(node,"parms");
|
|
if (WrapExtern) return 0;
|
|
while (parms) {
|
|
Swig_typemap_clear_apply(Gettype(parms),Getname(parms));
|
|
parms = Getnext(parms);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* swig11_constant
|
|
*
|
|
* The %constant directive
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int swig11_constant(DOH *node, void *clientdata) {
|
|
if (WrapExtern) return 0;
|
|
if (Access != PUBLIC) return 0;
|
|
|
|
set_scriptname(node);
|
|
lang->constant(node);
|
|
return 0;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* swig11_function()
|
|
*
|
|
* Emit a wrapper function.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int swig11_function(DOH *node, void *clientdata) {
|
|
int is_static;
|
|
if (WrapExtern) return 0;
|
|
if (Access != PUBLIC) return 0;
|
|
|
|
is_static = check_static(node);
|
|
set_scriptname(node);
|
|
|
|
/* Will need some kind of class check in here */
|
|
|
|
if (current_class) {
|
|
/* Function has been declared inside a class definition. */
|
|
class_update_parms(Getparms(node));
|
|
class_update_type(Gettype(node));
|
|
String *name = Getname(node);
|
|
if (Cmp(name,construct_name) == 0) {
|
|
have_constructor =1;
|
|
if (!Abstract) {
|
|
lang->cpp_constructor(node);
|
|
}
|
|
} else {
|
|
if (is_static) lang->cpp_staticfunction(node);
|
|
else lang->cpp_memberfunction(node);
|
|
}
|
|
} else {
|
|
|
|
/* Can't wrap a static function. Oh well. */
|
|
if (is_static) return 0;
|
|
emit_extern_func(node,f_header);
|
|
|
|
if (Native) {
|
|
lang->nativefunction(node);
|
|
} else {
|
|
lang->function(node);
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* swig11_variable()
|
|
*
|
|
* Wrap a variable.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int swig11_variable(DOH *node, void *clientdata) {
|
|
int is_static;
|
|
SwigType *type;
|
|
|
|
if (WrapExtern) return 0;
|
|
if (Access != PUBLIC) return 0;
|
|
|
|
if (Native) {
|
|
Printf(stderr,"%s:%d. Can't wrap variables in %%native mode (ignored).\n", Getfile(node),Getline(node));
|
|
return 0;
|
|
}
|
|
|
|
type = Gettype(node);
|
|
|
|
is_static = check_static(node);
|
|
set_scriptname(node);
|
|
|
|
if (current_class) {
|
|
/* Inside a class definition */
|
|
if (is_static) {
|
|
lang->cpp_staticvariable(node);
|
|
} else {
|
|
lang->cpp_variable(node);
|
|
}
|
|
} else {
|
|
if (check_extern(node)) {
|
|
Printf(f_header,"extern %s;\n", SwigType_str(type, Getname(node)));
|
|
}
|
|
if (is_static) return 0;
|
|
|
|
if (SwigType_isconst(type)) {
|
|
swig11_constant(node,clientdata);
|
|
} else {
|
|
lang->variable(node);
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* swig11_typedef()
|
|
*
|
|
* Handle a typedef declaration.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int swig11_typedef(DOH *node, void *clientdata) {
|
|
String *name;
|
|
SwigType *type;
|
|
|
|
type = Gettype(node);
|
|
name = Getname(node);
|
|
SwigType_typedef(type,name);
|
|
|
|
if (current_class) {
|
|
class_addtype(name,0);
|
|
}
|
|
lang->add_typedef(type, Char(name));
|
|
return 0;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* swig11_enum()
|
|
*
|
|
* Support for enumerations.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int swig11_enum(DOH *node, void *clientdata) {
|
|
DOH *c;
|
|
String *name;
|
|
if (WrapExtern) return 0;
|
|
if (Access != PUBLIC) return 0;
|
|
|
|
name = Getname(node);
|
|
if (name && CPlusPlus) {
|
|
/* Add a typedef */
|
|
String *t = NewStringf("enum %s", name);
|
|
SwigType_typedef(t,name);
|
|
class_addtype(name,0);
|
|
Delete(t);
|
|
}
|
|
c = Getchild(node);
|
|
Swig_emit_all(c,clientdata);
|
|
return 0;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* swig11_enumvalue()
|
|
*
|
|
* Create a constant corresponding to an enum value.
|
|
* ----------------------------------------------------------------------------- */
|
|
int swig11_enumvalue(DOH *node, void *clientdata) {
|
|
set_scriptname(node);
|
|
Setattr(node,"type","int"); /* Enums wrapped as ints */
|
|
if (!Getvalue(node)) { /* If no value, use the name itself */
|
|
if (class_name) {
|
|
Setvalue(node,NewStringf("%s::%s",class_name, Getname(node)));
|
|
} else {
|
|
Setvalue(node,Getname(node));
|
|
}
|
|
}
|
|
if (current_class) {
|
|
lang->cpp_constant(node);
|
|
} else {
|
|
swig11_constant(node,clientdata);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* swig11_class()
|
|
*
|
|
* Wrapping of C++ classes
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int swig11_class(DOH *node, void *clientdata) {
|
|
DOH *c;
|
|
List *bases;
|
|
|
|
/* Save the class */
|
|
String *name = Getname(node);
|
|
Setattr(class_hash,name,node);
|
|
if (WrapExtern) return 0;
|
|
|
|
if (Native) {
|
|
Printf(stderr,"%s:%d. Can't wrap structures or classes in %%native mode (ignored).\n", Getfile(node),Getline(node));
|
|
return 0;
|
|
}
|
|
|
|
set_scriptname(node);
|
|
class_name = name;
|
|
class_types = 0;
|
|
|
|
have_destructor = 0;
|
|
have_constructor = 0;
|
|
|
|
/* Need to merge in data from other scopes. For typemaps, can include scopes
|
|
for each base class one after the other. For types, need to merge type information */
|
|
|
|
SwigType_new_scope();
|
|
if (name) {
|
|
SwigType_set_scope_name(name);
|
|
}
|
|
|
|
cplus_walk_inherit(node, inherit_types, 0);
|
|
|
|
/* Merge in typemaps */
|
|
cplus_walk_inherit(node, inherit_typemaps, 0);
|
|
|
|
/* Create a typemap scope for this class */
|
|
Swig_typemap_new_scope(0);
|
|
|
|
cplus_build_symbols(node);
|
|
lang->cpp_open_class(node);
|
|
current_class = node;
|
|
|
|
construct_name = Getname(node);
|
|
if (!CPlusPlus) {
|
|
String *altname = Getattr(node,"altname");
|
|
if (altname) construct_name = altname;
|
|
}
|
|
|
|
c = Getchild(node);
|
|
Abstract = cplus_check_abstract(c);
|
|
|
|
Swig_emit_all(c,clientdata);
|
|
|
|
bases = Getattr(node,"bases");
|
|
if (bases) {
|
|
String *b;
|
|
lang->cpp_inherit(bases);
|
|
b = Firstitem(bases);
|
|
while (b) {
|
|
SwigType_inherit(Getname(current_class),b);
|
|
b = Nextitem(bases);
|
|
}
|
|
}
|
|
|
|
/* Check for constructors and destructors */
|
|
|
|
if (CPlusPlus) {
|
|
if (!have_constructor && !Abstract) {
|
|
DOH *cn = NewHash();
|
|
Setname(cn, Getname(current_class));
|
|
Setattr(cn,"scriptname", Getname(current_class));
|
|
lang->cpp_constructor(cn);
|
|
}
|
|
if (!have_destructor) {
|
|
DOH *dn = NewHash();
|
|
Setname(dn, Getname(current_class));
|
|
Setattr(dn,"scriptname", Getname(current_class));
|
|
lang->cpp_destructor(dn);
|
|
}
|
|
}
|
|
|
|
lang->cpp_close_class();
|
|
|
|
/* Pop the type scope and save with the class */
|
|
|
|
Hash *scp = SwigType_pop_scope();
|
|
Setattr(node,"types",scp);
|
|
|
|
scp = Swig_typemap_pop_scope();
|
|
Setattr(node,"typemaps",scp);
|
|
Setattr(node,"classtypes",class_types);
|
|
|
|
/* Pop off all of the typemap scopes we added */
|
|
cplus_walk_inherit(node,inherit_typemaps, (void *) 1);
|
|
|
|
current_class = 0;
|
|
construct_name = 0;
|
|
class_name = 0;
|
|
return 0;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* swig11_classdecl()
|
|
*
|
|
* Empty class declaration. Used to register classes with language modules.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int swig11_classdecl(DOH *node, void *clientdata) {
|
|
if (WrapExtern) return 0;
|
|
set_scriptname(node);
|
|
|
|
lang->cpp_class_decl(node);
|
|
return 0;
|
|
}
|
|
|
|
int swig11_addmethods(DOH *node, void *clientdata) {
|
|
DOH *c;
|
|
int oldaddmethods = AddMethods;
|
|
if (WrapExtern) return 0;
|
|
if (!current_class) {
|
|
Printf(stderr,"%s:%d. %%addmethods ignored (does not appear inside a class).\n", Getfile(node),Getline(node));
|
|
return 0;
|
|
}
|
|
AddMethods = 1;
|
|
c = Getchild(node);
|
|
Swig_emit_all(c,clientdata);
|
|
AddMethods = oldaddmethods;;
|
|
return 0;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* swig11_destructor()
|
|
*
|
|
* C++ Destructor
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int swig11_destructor(DOH *node, void *clientdata) {
|
|
if (WrapExtern) return 0;
|
|
if (Access != PUBLIC) return 0;
|
|
if (!current_class) return 0;
|
|
|
|
set_scriptname(node);
|
|
lang->cpp_destructor(node);
|
|
have_destructor = 1;
|
|
return 0;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* swig11_access()
|
|
*
|
|
* Handle an access specifier (public, private, protected)
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int swig11_access(DOH *node, void *clientdata) {
|
|
String *name = Getname(node);
|
|
if (Cmp(name,"public") == 0) Access = PUBLIC;
|
|
else if (Cmp(name,"private") == 0) Access = PRIVATE;
|
|
else if (Cmp(name,"protected") == 0) Access = PROTECTED;
|
|
return 0;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* swig11_types()
|
|
*
|
|
* Handle the types directive.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int swig11_types(DOH *node, void *clientdata) {
|
|
Parm *p;
|
|
p = Getparms(node);
|
|
while (p) {
|
|
SwigType *t = Gettype(p);
|
|
SwigType_remember(t);
|
|
p = Getnext(p);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static SwigRule rules[] = {
|
|
{ "file", swig11_file},
|
|
{ "scope", swig11_scope},
|
|
{ "insert", swig11_insert},
|
|
{ "pragma", swig11_pragma},
|
|
{ "typemap", swig11_typemap},
|
|
{ "apply", swig11_apply},
|
|
{ "exception", swig11_exception},
|
|
{ "clear", swig11_clear},
|
|
{ "addmethods", swig11_addmethods},
|
|
{ "constant", swig11_constant},
|
|
{ "function", swig11_function},
|
|
{ "variable", swig11_variable},
|
|
{ "typedef", swig11_typedef},
|
|
{ "enum", swig11_enum},
|
|
{ "enumvalue", swig11_enumvalue},
|
|
{ "class", swig11_class},
|
|
{ "classdecl", swig11_classdecl},
|
|
{ "destructor", swig11_destructor},
|
|
{ "access", swig11_access},
|
|
{ "types", swig11_types},
|
|
{ "module", swig11_nil},
|
|
{ "*", swig11_unknown},
|
|
{ 0 }
|
|
};
|
|
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* generate()
|
|
*
|
|
* Called by the SWIG1.1 system to emit code
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
void generate(DOH *node) {
|
|
DOH *c;
|
|
extern String *swig_module;
|
|
|
|
/* Initialize globals */
|
|
class_hash = NewHash();
|
|
|
|
Swig_add_rules(rules);
|
|
c = Getattr(node,"child");
|
|
|
|
/* Find the module name */
|
|
if (!swig_module) {
|
|
swig_module = find_module(c);
|
|
}
|
|
if (!swig_module) {
|
|
Printf(stderr,"SWIG: No module name specified! Please use %%module or -module.\n");
|
|
Swig_exit(EXIT_FAILURE);
|
|
}
|
|
|
|
lang->initialize(swig_module);
|
|
Swig_emit_all(c,0);
|
|
lang->close();
|
|
|
|
/* Swig_dump_tags(node,0); */
|
|
|
|
}
|
|
|
|
|