Merge branch 'master' into gsoc2012-scilab

Conflicts:
	.gitignore
	.travis.yml
	COPYRIGHT
	Examples/Makefile.in
	Examples/test-suite/constructor_copy.i
	Makefile.in
	configure.ac
This commit is contained in:
Simon Marchetto 2014-06-06 16:33:16 +02:00
commit 07b06a4089
1502 changed files with 46955 additions and 11374 deletions

View file

@ -25,12 +25,15 @@ extern "C" {
extern String *cparse_file;
extern int cparse_line;
extern int cparse_cplusplus;
extern int cparse_cplusplusout;
extern int cparse_start_line;
extern void Swig_cparse_cplusplus(int);
extern void Swig_cparse_cplusplusout(int);
extern void scanner_file(File *);
extern void scanner_next_token(int);
extern void skip_balanced(int startchar, int endchar);
extern String *get_raw_text_balanced(int startchar, int endchar);
extern void skip_decl(void);
extern void scanner_check_typedef(void);
extern void scanner_ignore_typedef(void);
@ -56,7 +59,7 @@ extern "C" {
extern void cparse_normalize_void(Node *);
extern Parm *Swig_cparse_parm(String *s);
extern ParmList *Swig_cparse_parms(String *s, Node *file_line_node);
extern Node *new_node(const_String_or_char_ptr tag);
/* templ.c */
extern int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab *tscope);

View file

@ -37,6 +37,9 @@ int cparse_start_line = 0;
/* C++ mode */
int cparse_cplusplus = 0;
/* Generate C++ compatible code when wrapping C code */
int cparse_cplusplusout = 0;
/* Private vars */
static int scan_init = 0;
static int num_brace = 0;
@ -52,6 +55,14 @@ void Swig_cparse_cplusplus(int v) {
cparse_cplusplus = v;
}
/* -----------------------------------------------------------------------------
* Swig_cparse_cplusplusout()
* ----------------------------------------------------------------------------- */
void Swig_cparse_cplusplusout(int v) {
cparse_cplusplusout = v;
}
/* ----------------------------------------------------------------------------
* scanner_init()
*
@ -118,6 +129,16 @@ void skip_balanced(int startchar, int endchar) {
return;
}
/* -----------------------------------------------------------------------------
* get_raw_text_balanced()
*
* Returns raw text between 2 braces
* ----------------------------------------------------------------------------- */
String *get_raw_text_balanced(int startchar, int endchar) {
return Scanner_get_raw_text_balanced(scan, startchar, endchar);
}
/* ----------------------------------------------------------------------------
* void skip_decl(void)
*
@ -246,6 +267,8 @@ static int yylook(void) {
return GREATERTHANOREQUALTO;
case SWIG_TOKEN_RSHIFT:
return RSHIFT;
case SWIG_TOKEN_ARROW:
return ARROW;
case SWIG_TOKEN_PERIOD:
return PERIOD;
case SWIG_TOKEN_MODULO:
@ -283,15 +306,25 @@ static int yylook(void) {
case SWIG_TOKEN_STRING:
yylval.id = Swig_copy_string(Char(Scanner_text(scan)));
return STRING;
case SWIG_TOKEN_WSTRING:
yylval.id = Swig_copy_string(Char(Scanner_text(scan)));
return WSTRING;
case SWIG_TOKEN_CHAR:
yylval.str = NewString(Scanner_text(scan));
if (Len(yylval.str) == 0) {
Swig_error(cparse_file, cparse_line, "Empty character constant\n");
Printf(stdout,"%d\n", Len(Scanner_text(scan)));
}
return CHARCONST;
case SWIG_TOKEN_WCHAR:
yylval.str = NewString(Scanner_text(scan));
if (Len(yylval.str) == 0) {
Swig_error(cparse_file, cparse_line, "Empty character constant\n");
}
return WCHARCONST;
/* Numbers */
case SWIG_TOKEN_INT:
@ -542,8 +575,16 @@ int yylex(void) {
return (PROTECTED);
if (strcmp(yytext, "friend") == 0)
return (FRIEND);
if (strcmp(yytext, "constexpr") == 0)
return (CONSTEXPR);
if (strcmp(yytext, "thread_local") == 0)
return (THREAD_LOCAL);
if (strcmp(yytext, "decltype") == 0)
return (DECLTYPE);
if (strcmp(yytext, "virtual") == 0)
return (VIRTUAL);
if (strcmp(yytext, "static_assert") == 0)
return (STATIC_ASSERT);
if (strcmp(yytext, "operator") == 0) {
int nexttok;
String *s = NewString("operator ");
@ -592,6 +633,11 @@ int yylex(void) {
yylval.str = s;
return OPERATOR;
}
} else if (nexttok == SWIG_TOKEN_STRING) {
/* Operator "" or user-defined string literal ""_suffix */
Append(s,"\"\"");
yylval.str = s;
return OPERATOR;
} else if (nexttok == SWIG_TOKEN_ID) {
/* We have an identifier. This could be any number of things. It could be a named version of
an operator (e.g., 'and_eq') or it could be a conversion operator. To deal with this, we're
@ -678,6 +724,8 @@ int yylex(void) {
}
if (strcmp(yytext, "throw") == 0)
return (THROW);
if (strcmp(yytext, "noexcept") == 0)
return (NOEXCEPT);
if (strcmp(yytext, "try") == 0)
return (yylex());
if (strcmp(yytext, "catch") == 0)
@ -688,6 +736,8 @@ int yylex(void) {
return (yylex());
if (strcmp(yytext, "explicit") == 0)
return (EXPLICIT);
if (strcmp(yytext, "auto") == 0)
return (AUTO);
if (strcmp(yytext, "export") == 0)
return (yylex());
if (strcmp(yytext, "typename") == 0)
@ -696,15 +746,18 @@ int yylex(void) {
yylval.intvalue = cparse_line;
return (TEMPLATE);
}
if (strcmp(yytext, "delete") == 0) {
if (strcmp(yytext, "delete") == 0)
return (DELETE_KW);
}
if (strcmp(yytext, "using") == 0) {
if (strcmp(yytext, "default") == 0)
return (DEFAULT);
if (strcmp(yytext, "using") == 0)
return (USING);
}
if (strcmp(yytext, "namespace") == 0) {
if (strcmp(yytext, "namespace") == 0)
return (NAMESPACE);
}
if (strcmp(yytext, "override") == 0)
return (OVERRIDE);
if (strcmp(yytext, "final") == 0)
return (FINAL);
} else {
if (strcmp(yytext, "class") == 0) {
Swig_warning(WARN_PARSE_CLASS_KEYWORD, cparse_file, cparse_line, "class keyword used, but not in C++ mode.\n");

File diff suppressed because it is too large Load diff

View file

@ -825,7 +825,7 @@ Node *Swig_cparse_template_locate(String *name, Parm *tparms, Symtab *tscope) {
/* If not a templated class we must have a templated function.
The template found is not necessarily the one we want when dealing with templated
functions. We don't want any specialized templated functions as they won't have
the default parameters. Lets look for the unspecialized template. Also make sure
the default parameters. Let's look for the unspecialized template. Also make sure
the number of template parameters is correct as it is possible to overload a
templated function with different numbers of template parameters. */

View file

@ -88,3 +88,17 @@ void cparse_normalize_void(Node *n) {
}
}
}
/* -----------------------------------------------------------------------------
* new_node()
*
* Create an empty parse node, setting file and line number information
* ----------------------------------------------------------------------------- */
Node *new_node(const_String_or_char_ptr tag) {
Node *n = NewHash();
set_nodeType(n,tag);
Setfile(n,cparse_file);
Setline(n,cparse_line);
return n;
}

View file

@ -51,7 +51,7 @@ Sequence Operations
-------------------
Getitem(list,index) Get an item
Setitem(list,index,val) Set an item
Delitem(list,index,val) Delete an item
Delitem(list,index) Delete an item
Insert(list,index,val) Insert an item
Append(list,val) Append to end
Push(list,val) Insert at beginning
@ -65,7 +65,7 @@ Putc(ch,obj) Put a character
Ungetc(ch,obj) Put character back on input stream
Seek(obj,offset,whence) Seek
Tell(obj) Return file pointer
Close(obj) Close
Delete(obj) Decrease the reference count, close file if zero
String Operations
-----------------

View file

@ -947,11 +947,12 @@ int DohGetmark(DOH *ho) {
DOH *DohCall(DOH *func, DOH *args) {
DOH *result;
DOH *(*builtin) (DOH *);
DohFuncPtr_t builtin;
builtin = (DOH *(*)(DOH *)) GetVoid(func, "builtin");
if (!builtin)
builtin.p = GetVoid(func, "builtin");
if (!builtin.p)
return 0;
result = (*builtin) (args);
result = (*builtin.func) (args);
return result;
}

View file

@ -336,6 +336,12 @@ extern DOHList *DohSplit(DOHFile * input, char ch, int nsplits);
extern DOHList *DohSplitLines(DOHFile * input);
extern DOH *DohNone;
/* Helper union for converting between function and object pointers. */
typedef union DohFuncPtr {
void* p;
DOH *(*func)(DOH *);
} DohFuncPtr_t;
extern void DohMemoryDebug(void);
#ifndef DOH_LONG_NAMES

View file

@ -46,15 +46,19 @@ static int Writen(DOH *out, void *buffer, int len) {
* ----------------------------------------------------------------------------- */
void DohEncoding(const char *name, DOH *(*fn) (DOH *s)) {
DohFuncPtr_t fp;
if (!encodings)
encodings = NewHash();
Setattr(encodings, (void *) name, NewVoid((void *) fn, 0));
fp.func = fn;
Setattr(encodings, (void *) name, NewVoid(fp.p, 0));
}
/* internal function for processing an encoding */
static DOH *encode(char *name, DOH *s) {
DOH *handle, *ns;
DOH *(*fn) (DOH *);
DohFuncPtr_t fp;
long pos;
char *cfmt = strchr(name, ':');
DOH *tmp = 0;
@ -72,8 +76,9 @@ static DOH *encode(char *name, DOH *s) {
s = tmp;
pos = Tell(s);
Seek(s, 0, SEEK_SET);
fn = (DOH *(*)(DOH *)) Data(handle);
ns = (*fn) (s);
fp.p = Data(handle);
ns = (*fp.func) (s);
assert(pos != -1);
(void)Seek(s, pos, SEEK_SET);
if (tmp)

View file

@ -1114,6 +1114,7 @@ DOHString *DohNewStringWithSize(const DOHString_or_char *so, int len) {
str->maxsize = max;
if (s) {
strncpy(str->str, s, len);
str->str[l] = 0;
str->len = l;
str->sp = l;
} else {

View file

@ -52,6 +52,7 @@
#define WARN_DEPRECATED_NODEFAULT 123
#define WARN_DEPRECATED_TYPEMAP_LANG 124
#define WARN_DEPRECATED_INPUT_FILE 125
#define WARN_DEPRECATED_NESTED_WORKAROUND 126
/* -- Preprocessor -- */
@ -91,6 +92,11 @@
#define WARN_PARSE_NAMED_NESTED_CLASS 325
#define WARN_PARSE_EXTEND_NAME 326
#define WARN_CPP11_LAMBDA 340
#define WARN_CPP11_ALIAS_DECLARATION 341
#define WARN_CPP11_ALIAS_TEMPLATE 342
#define WARN_CPP11_VARIADIC_TEMPLATE 343
#define WARN_IGNORE_OPERATOR_NEW 350 /* new */
#define WARN_IGNORE_OPERATOR_DELETE 351 /* delete */
#define WARN_IGNORE_OPERATOR_PLUS 352 /* + */
@ -170,6 +176,8 @@
#define WARN_TYPEMAP_DIRECTOROUT_PTR 473
#define WARN_TYPEMAP_OUT_OPTIMAL_IGNORED 474
#define WARN_TYPEMAP_OUT_OPTIMAL_MULTIPLE 475
#define WARN_TYPEMAP_INITIALIZER_LIST 476
#define WARN_TYPEMAP_DIRECTORTHROWS_UNDEF 477
/* -- Fragments -- */
#define WARN_FRAGMENT_NOT_FOUND 490

View file

@ -48,12 +48,14 @@ eswig_SOURCES = CParse/cscanner.c \
Modules/go.cxx \
Modules/guile.cxx \
Modules/java.cxx \
Modules/javascript.cxx \
Modules/lang.cxx \
Modules/lua.cxx \
Modules/main.cxx \
Modules/modula3.cxx \
Modules/module.cxx \
Modules/mzscheme.cxx \
Modules/nested.cxx \
Modules/ocaml.cxx \
Modules/octave.cxx \
Modules/overload.cxx \
@ -76,6 +78,7 @@ eswig_SOURCES = CParse/cscanner.c \
Swig/cwrap.c \
Swig/deprecate.c \
Swig/error.c \
Swig/extend.c \
Swig/fragment.c \
Swig/getopt.c \
Swig/include.c \
@ -89,7 +92,7 @@ eswig_SOURCES = CParse/cscanner.c \
Swig/typeobj.c \
Swig/typemap.c \
Swig/typesys.c \
Swig/wrapfunc.c
Swig/wrapfunc.c
bin_PROGRAMS = eswig
eswig_LDADD = @SWIGLIBS@
@ -98,7 +101,7 @@ eswig_LDADD = @SWIGLIBS@
CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
# The executable is copied to the root directory for installation and running the test-suite.
# This occurs on each invocation of make and is a step towards providing support for multiple
# This occurs on each invocation of make and is a step towards providing support for multiple
# build directories.
all-local: eswig@EXEEXT@
cp -f $(top_builddir)/Source/eswig@EXEEXT@ $(top_builddir)/swig@EXEEXT@
@ -117,7 +120,7 @@ distclean-local:
# swig executable as a way of checking before and after the 'beautifying'.
# Single files can be beautified with the beautify-file target, eg: 'make beautify-file INDENTFILE=chosenfile.c'
SWIGTYPEDEFS=-T bool -T File -T DohObjInfo -T Parm -T Language -T List -T Typetab -T ModuleFactory -T ErrorMessageFormat -T Symtab -T Hash -T String -T DohBase -T Node -T String_or_char -T SwigType -T Dispatcher -T Wrapper -T DohStringMethods -T DohFileMethods -T DohListMethods -T DohHashMethods -T DOH -T DohIterator -T ParmList -T FILE -T HashNode -T DOHString_or_char
SWIGTYPEDEFS=-T bool -T File -T DohObjInfo -T Parm -T Language -T List -T Typetab -T ModuleFactory -T ErrorMessageFormat -T Symtab -T Hash -T Scanner -T String -T DohBase -T Node -T String_or_char -T SwigType -T Dispatcher -T Wrapper -T DohStringMethods -T DohFileMethods -T DohListMethods -T DohHashMethods -T DOH -T DohIterator -T ParmList -T FILE -T HashNode -T DOHObj_or_char -T DOHFile -T DOHString -T DOHString_or_char -T UpcallData
INDENTBAKSDIR=../IndentBaks
beautify:
@ -144,4 +147,3 @@ beautify-file:
indent -kr --honour-newlines --line-length160 --indent-level2 --braces-on-func-def-line --leave-optional-blank-lines $(SWIGTYPEDEFS) $(INDENTFILE) -o $(INDENTFILE).tmp;
cat $(INDENTFILE).tmp | sed -e 's/const const /const /' > $(INDENTFILE);
rm $(INDENTFILE).tmp;

View file

@ -20,7 +20,7 @@
// #define ALLEGROCL_TYPE_DEBUG
// #define ALLEGROCL_CLASS_DEBUG
static const char *usage = (char *) "\
static const char *usage = "\
Allegro CL Options (available with -allegrocl)\n\
-identifier-converter <type or funcname> - \n\
Specifies the type of conversion to do on C identifiers to convert\n\

View file

@ -421,7 +421,7 @@ class Allocate:public Dispatcher {
while (cc) {
Node *cp = cc;
if (classname) {
Setattr(cp, "classname", classname);
Setattr(cp, "extendsmartclassname", classname);
}
Setattr(cp, "allocate:smartpointeraccess", "1");
/* If constant, we have to be careful */
@ -559,7 +559,11 @@ Allocate():
virtual int classDeclaration(Node *n) {
Symtab *symtab = Swig_symbol_current();
Swig_symbol_setscope(Getattr(n, "symtab"));
save_value<Node*> oldInclass(inclass);
save_value<AccessMode> oldAcessMode(cplus_mode);
save_value<int> oldExtendMode(extendmode);
if (Getattr(n, "template"))
extendmode = 0;
if (!CPlusPlus) {
/* Always have default constructors/destructors in C */
Setattr(n, "allocate:default_constructor", "1");
@ -580,7 +584,6 @@ Allocate():
}
}
}
inclass = n;
String *kind = Getattr(n, "kind");
if (Strcmp(kind, "class") == 0) {
@ -659,7 +662,7 @@ Allocate():
}
if (!Getattr(n, "allocate:has_destructor")) {
/* No destructor was defined. We need to check a few things here too */
/* No destructor was defined */
List *bases = Getattr(n, "allbases");
int allows_destruct = 1;
@ -676,13 +679,13 @@ Allocate():
}
if (!Getattr(n, "allocate:has_assign")) {
/* No destructor was defined. We need to check a few things here too */
/* No assignment operator was defined */
List *bases = Getattr(n, "allbases");
int allows_assign = 1;
for (int i = 0; i < Len(bases); i++) {
Node *n = Getitem(bases, i);
/* If base class does not allow default destructor, we don't allow it either */
/* If base class does not allow assignment, we don't allow it either */
if (Getattr(n, "allocate:has_assign")) {
allows_assign = !Getattr(n, "allocate:noassign");
}
@ -693,13 +696,13 @@ Allocate():
}
if (!Getattr(n, "allocate:has_new")) {
/* No destructor was defined. We need to check a few things here too */
/* No new operator was defined */
List *bases = Getattr(n, "allbases");
int allows_new = 1;
for (int i = 0; i < Len(bases); i++) {
Node *n = Getitem(bases, i);
/* If base class does not allow default destructor, we don't allow it either */
/* If base class does not allow new operator, we don't allow it either */
if (Getattr(n, "allocate:has_new")) {
allows_new = !Getattr(n, "allocate:nonew");
}
@ -711,7 +714,7 @@ Allocate():
/* Check if base classes allow smart pointers, but might be hidden */
if (!Getattr(n, "allocate:smartpointer")) {
Node *sp = Swig_symbol_clookup((char *) "operator ->", 0);
Node *sp = Swig_symbol_clookup("operator ->", 0);
if (sp) {
/* Look for parent */
Node *p = parentNode(sp);
@ -728,7 +731,6 @@ Allocate():
/* Only care about default behavior. Remove temporary values */
Setattr(n, "allocate:visit", "1");
inclass = 0;
Swig_symbol_setscope(symtab);
return SWIG_OK;
}
@ -771,7 +773,7 @@ Allocate():
/* Check to see if this is a static member or not. If so, we add an attribute
cplus:staticbase that saves the current class */
if (checkAttribute(n, "storage", "static")) {
if (Swig_storage_isstatic(n)) {
Setattr(n, "cplus:staticbase", inclass);
}
@ -779,18 +781,26 @@ Allocate():
if (cplus_mode != PUBLIC) {
if (Strcmp(name, "operator =") == 0) {
/* Look for a private assignment operator */
Setattr(inclass, "allocate:has_assign", "1");
if (!GetFlag(n, "deleted"))
Setattr(inclass, "allocate:has_assign", "1");
Setattr(inclass, "allocate:noassign", "1");
} else if (Strcmp(name, "operator new") == 0) {
/* Look for a private new operator */
Setattr(inclass, "allocate:has_new", "1");
if (!GetFlag(n, "deleted"))
Setattr(inclass, "allocate:has_new", "1");
Setattr(inclass, "allocate:nonew", "1");
}
} else {
if (Strcmp(name, "operator =") == 0) {
Setattr(inclass, "allocate:has_assign", "1");
if (!GetFlag(n, "deleted"))
Setattr(inclass, "allocate:has_assign", "1");
else
Setattr(inclass, "allocate:noassign", "1");
} else if (Strcmp(name, "operator new") == 0) {
Setattr(inclass, "allocate:has_new", "1");
if (!GetFlag(n, "deleted"))
Setattr(inclass, "allocate:has_new", "1");
else
Setattr(inclass, "allocate:nonew", "1");
}
/* Look for smart pointer operator */
if ((Strcmp(name, "operator ->") == 0) && (!GetFlag(n, "feature:ignore"))) {
@ -817,13 +827,13 @@ Allocate():
}
List *methods = smart_pointer_methods(sc, 0, isconst);
Setattr(inclass, "allocate:smartpointer", methods);
Setattr(inclass, "allocate:smartpointerbase", base);
Setattr(inclass, "allocate:smartpointerpointeeclassname", Getattr(sc, "name"));
} else {
/* Hmmm. The return value is not a pointer. If the type is a value
or reference. We're going to chase it to see if another operator->()
can be found */
if ((SwigType_check_decl(type, "")) || (SwigType_check_decl(type, "r."))) {
Node *nn = Swig_symbol_clookup((char *) "operator ->", Getattr(sc, "symtab"));
Node *nn = Swig_symbol_clookup("operator ->", Getattr(sc, "symtab"));
if (nn) {
Delete(base);
Delete(type);

View file

@ -136,6 +136,12 @@ public:
return SWIG_OK;
}
virtual int lambdaDeclaration(Node *n) {
show_attributes(n);
emit_children(n);
return SWIG_OK;
}
virtual int enumDeclaration(Node *n) {
show_attributes(n);
emit_children(n);

View file

@ -18,7 +18,7 @@
//#define CFFI_DEBUG
//#define CFFI_WRAP_DEBUG
static const char *usage = (char *) "\
static const char *usage = "\
CFFI Options (available with -cffi)\n\
-generate-typedef - Use defctype to generate shortcuts according to the\n\
typedefs in the input.\n\
@ -506,11 +506,6 @@ int CFFI::functionWrapper(Node *n) {
void CFFI::emit_defun(Node *n, String *name) {
// String *storage=Getattr(n,"storage");
// if(!storage || (Strcmp(storage,"extern") && Strcmp(storage,"externc")))
// return SWIG_OK;
String *func_name = Getattr(n, "sym:name");
ParmList *pl = Getattr(n, "parms");
@ -583,12 +578,6 @@ int CFFI::constantWrapper(Node *n) {
}
int CFFI::variableWrapper(Node *n) {
// String *storage=Getattr(n,"storage");
// Printf(stdout,"\"%s\" %s)\n",storage,Getattr(n, "sym:name"));
// if(!storage || (Strcmp(storage,"extern") && Strcmp(storage,"externc")))
// return SWIG_OK;
String *var_name = Getattr(n, "sym:name");
String *lisp_type = Swig_typemap_lookup("cin", n, "", 0);
String *lisp_name = lispify_name(n, var_name, "'variable");
@ -687,7 +676,7 @@ void CFFI::emit_class(Node *n) {
if (!first)
Printf(supers, " ");
String *s = Getattr(i.item, "name");
Printf(supers, "%s", lispify_name(i.item, s, "'classname"));
Printf(supers, "%s", lispify_name(i.item, lispy_name(Char(s)), "'classname"));
}
} else {
// Printf(supers,"ff:foreign-pointer");

View file

@ -15,7 +15,7 @@
#include <ctype.h>
static const char *usage = (char *) "\
static const char *usage = "\
\
CHICKEN Options (available with -chicken)\n\
-closprefix <prefix> - Prepend <prefix> to all clos identifiers\n\
@ -29,7 +29,7 @@ CHICKEN Options (available with -chicken)\n\
\n";
static char *module = 0;
static char *chicken_path = (char *) "chicken";
static const char *chicken_path = "chicken";
static int num_methods = 0;
static File *f_begin = 0;
@ -620,7 +620,7 @@ int CHICKEN::functionWrapper(Node *n) {
if (in_class)
clos_name = NewString(member_name);
else
clos_name = chickenNameMapping(scmname, (char *) "");
clos_name = chickenNameMapping(scmname, "");
if (!any_specialized_arg) {
method_def = NewString("");
@ -775,7 +775,7 @@ int CHICKEN::variableWrapper(Node *n) {
if (in_class)
clos_name = NewString(member_name);
else
clos_name = chickenNameMapping(scmname, (char *) "");
clos_name = chickenNameMapping(scmname, "");
Node *class_node = classLookup(t);
String *clos_code = Getattr(n, "tmap:varin:closcode");
@ -942,7 +942,7 @@ int CHICKEN::constantWrapper(Node *n) {
if (in_class)
clos_name = NewString(member_name);
else
clos_name = chickenNameMapping(scmname, (char *) "");
clos_name = chickenNameMapping(scmname, "");
if (GetFlag(n, "feature:constasvar")) {
Printv(clos_methods, "(define ", clos_name, " (", chickenPrimitiveName(scmname), "))\n", NIL);
Printv(scm_const_defs, "(set! ", scmname, " (", scmname, "))\n", NIL);
@ -1372,7 +1372,7 @@ void CHICKEN::dispatchFunction(Node *n) {
} else if (in_class)
clos_name = NewString(member_name);
else
clos_name = chickenNameMapping(scmname, (char *) "");
clos_name = chickenNameMapping(scmname, "");
Iterator f;
List *prev = 0;

View file

@ -13,7 +13,7 @@
#include "swigmod.h"
static const char *usage = (char *) "\
static const char *usage = "\
CLISP Options (available with -clisp)\n\
-extern-all - Create clisp definitions for all the functions and\n\
global variables otherwise only definitions for\n\
@ -148,7 +148,7 @@ int CLISP::top(Node *n) {
int CLISP::functionWrapper(Node *n) {
is_function = 1;
String *storage = Getattr(n, "storage");
if (!extern_all_flag && (!storage || (Strcmp(storage, "extern") && Strcmp(storage, "externc"))))
if (!extern_all_flag && (!storage || (!Swig_storage_isextern(n) && !Swig_storage_isexternc(n))))
return SWIG_OK;
String *func_name = Getattr(n, "sym:name");
@ -217,10 +217,9 @@ int CLISP::constantWrapper(Node *n) {
int CLISP::variableWrapper(Node *n) {
is_function = 0;
// SwigType *type=;
String *storage = Getattr(n, "storage");
if (!extern_all_flag && (!storage || (Strcmp(storage, "extern") && Strcmp(storage, "externc"))))
if (!extern_all_flag && (!storage || (!Swig_storage_isextern(n) && !Swig_storage_isexternc(n))))
return SWIG_OK;
String *var_name = Getattr(n, "sym:name");

View file

@ -307,7 +307,7 @@ int Contracts::cDeclaration(Node *n) {
return SWIG_OK;
if (Getattr(n, "feature:contract"))
ret = emit_contract(n, (InClass && !checkAttribute(n, "storage", "static")));
ret = emit_contract(n, InClass && !Swig_storage_isstatic(n));
return ret;
}
@ -342,11 +342,13 @@ int Contracts::namespaceDeclaration(Node *n) {
int Contracts::classDeclaration(Node *n) {
int ret = SWIG_OK;
int oldInClass = InClass;
Node *oldClass = CurrentClass;
InClass = 1;
CurrentClass = n;
emit_children(n);
InClass = 0;
CurrentClass = 0;
InClass = oldInClass;
CurrentClass = oldClass;
return ret;
}

View file

@ -53,7 +53,6 @@ class CSHARP:public Language {
String *proxy_class_code;
String *module_class_code;
String *proxy_class_name; // proxy class name
String *full_proxy_class_name;// fully qualified proxy class name when using nspace feature, otherwise same as proxy_class_name
String *full_imclass_name; // fully qualified intermediary class name when using nspace feature, otherwise same as imclass_name
String *variable_name; //Name of a variable being wrapped
String *proxy_class_constants_code;
@ -87,6 +86,7 @@ class CSHARP:public Language {
int n_directors;
int first_class_dmethod;
int curr_class_dmethod;
int nesting_depth;
enum EnumFeature { SimpleEnum, TypeunsafeEnum, TypesafeEnum, ProperEnum };
@ -125,7 +125,6 @@ public:
proxy_class_code(NULL),
module_class_code(NULL),
proxy_class_name(NULL),
full_proxy_class_name(NULL),
full_imclass_name(NULL),
variable_name(NULL),
proxy_class_constants_code(NULL),
@ -156,7 +155,8 @@ public:
n_dmethods(0),
n_directors(0),
first_class_dmethod(0),
curr_class_dmethod(0) {
curr_class_dmethod(0),
nesting_depth(0){
/* for now, multiple inheritance in directors is disabled, this
should be easy to implement though */
director_multiple_inheritance = 0;
@ -179,7 +179,13 @@ public:
proxyname = Getattr(n, "proxyname");
if (!proxyname) {
String *nspace = Getattr(n, "sym:nspace");
String *symname = Getattr(n, "sym:name");
String *symname = Copy(Getattr(n, "sym:name"));
if (symname && !GetFlag(n, "feature:flatnested")) {
for (Node *outer_class = Getattr(n, "nested:outer"); outer_class; outer_class = Getattr(outer_class, "nested:outer")) {
Push(symname, ".");
Push(symname, Getattr(outer_class, "sym:name"));
}
}
if (nspace) {
if (namespce)
proxyname = NewStringf("%s.%s.%s", namespce, nspace, symname);
@ -190,6 +196,7 @@ public:
}
Setattr(n, "proxyname", proxyname);
Delete(proxyname);
Delete(symname);
}
}
}
@ -776,7 +783,7 @@ public:
}
}
Printv(imclass_class_code, "\n [DllImport(\"", dllimport, "\", EntryPoint=\"", wname, "\")]\n", NIL);
Printv(imclass_class_code, "\n [global::System.Runtime.InteropServices.DllImport(\"", dllimport, "\", EntryPoint=\"", wname, "\")]\n", NIL);
if (im_outattributes)
Printf(imclass_class_code, " %s\n", im_outattributes);
@ -1025,7 +1032,7 @@ public:
*/
if (proxy_flag && wrapping_member_flag && !enum_constant_flag) {
// Capitalize the first letter in the variable in the getter/setter function name
bool getter_flag = Cmp(symname, Swig_name_set(getNSpace(), Swig_name_member(0, proxy_class_name, variable_name))) != 0;
bool getter_flag = Cmp(symname, Swig_name_set(getNSpace(), Swig_name_member(0, getClassPrefix(), variable_name))) != 0;
String *getter_setter_name = NewString("");
if (!getter_flag)
@ -1080,6 +1087,30 @@ public:
return ret;
}
String *getCurrentScopeName(String *nspace)
{
String *scope = 0;
if (nspace || getCurrentClass()) {
scope = NewString("");
if (nspace)
Printf(scope, "%s", nspace);
if (Node* cls = getCurrentClass())
{
if (Node *outer = Getattr(cls, "nested:outer")) {
String *outerClassesPrefix = Copy(Getattr(outer, "sym:name"));
for (outer = Getattr(outer, "nested:outer"); outer != 0; outer = Getattr(outer, "nested:outer")) {
Push(outerClassesPrefix, ".");
Push(outerClassesPrefix, Getattr(outer, "sym:name"));
}
Printv(scope, nspace ? "." : "", outerClassesPrefix, ".", proxy_class_name, NIL);
Delete(outerClassesPrefix);
} else
Printv(scope, nspace ? "." : "", proxy_class_name, NIL);
}
}
return scope;
}
/* ----------------------------------------------------------------------
* enumDeclaration()
@ -1123,14 +1154,7 @@ public:
if ((enum_feature != SimpleEnum) && symname && typemap_lookup_type) {
// Wrap (non-anonymous) C/C++ enum within a typesafe, typeunsafe or proper C# enum
String *scope = 0;
if (nspace || proxy_class_name) {
scope = NewString("");
if (nspace)
Printf(scope, "%s", nspace);
if (proxy_class_name)
Printv(scope, nspace ? "." : "", proxy_class_name, NIL);
}
String *scope = getCurrentScopeName(nspace);
if (!addSymbol(symname, n, scope))
return SWIG_ERROR;
@ -1278,12 +1302,11 @@ public:
scope = Copy(module_class_name);
}
} else {
scope = NewString("");
if (nspace)
Printf(scope, "%s.", nspace);
if (proxy_class_name)
Printf(scope, "%s.", proxy_class_name);
Printf(scope, "%s",Getattr(parent, "sym:name"));
scope = getCurrentScopeName(nspace);
if (!scope)
scope = Copy(Getattr(parent, "sym:name"));
else
Printf(scope, ".%s", Getattr(parent, "sym:name"));
}
if (!addSymbol(name, n, scope))
return SWIG_ERROR;
@ -1589,6 +1612,7 @@ public:
String *c_baseclassname = NULL;
SwigType *typemap_lookup_type = Getattr(n, "classtypeobj");
bool feature_director = Swig_directorclass(n) ? true : false;
bool has_outerclass = Getattr(n, "nested:outer") != 0 && !GetFlag(n, "feature:flatnested");
// Inheritance from pure C# classes
Node *attributes = NewHash();
@ -1648,7 +1672,8 @@ public:
// Pure C# interfaces
const String *pure_interfaces = typemapLookup(n, derived ? "csinterfaces_derived" : "csinterfaces", typemap_lookup_type, WARN_NONE);
// Start writing the proxy class
Printv(proxy_class_def, typemapLookup(n, "csimports", typemap_lookup_type, WARN_NONE), // Import statements
if (!has_outerclass)
Printv(proxy_class_def, typemapLookup(n, "csimports", typemap_lookup_type, WARN_NONE), // Import statements
"\n", NIL);
// Class attributes
@ -1699,7 +1724,7 @@ public:
if (*Char(destructor_call))
Replaceall(destruct, "$imcall", destructor_call);
else
Replaceall(destruct, "$imcall", "throw new MethodAccessException(\"C++ destructor does not have public access\")");
Replaceall(destruct, "$imcall", "throw new global::System.MethodAccessException(\"C++ destructor does not have public access\")");
if (*Char(destruct))
Printv(proxy_class_def, "\n ", destruct_methodmodifiers, " ", derived ? "override" : "virtual", " void ", destruct_methodname, "() ", destruct, "\n",
NIL);
@ -1719,7 +1744,7 @@ public:
Printf(proxy_class_code, " if (SwigDerivedClassHasMethod(\"%s\", swigMethodTypes%s))\n", method, methid);
Printf(proxy_class_code, " swigDelegate%s = new SwigDelegate%s_%s(SwigDirector%s);\n", methid, proxy_class_name, methid, overname);
}
String *director_connect_method_name = Swig_name_member(getNSpace(), proxy_class_name, "director_connect");
String *director_connect_method_name = Swig_name_member(getNSpace(), getClassPrefix(), "director_connect");
Printf(proxy_class_code, " %s.%s(swigCPtr", imclass_name, director_connect_method_name);
for (i = first_class_dmethod; i < curr_class_dmethod; ++i) {
UpcallData *udata = Getitem(dmethods_seq, i);
@ -1732,9 +1757,9 @@ public:
if (first_class_dmethod < curr_class_dmethod) {
// Only emit if there is at least one director method
Printf(proxy_class_code, "\n");
Printf(proxy_class_code, " private bool SwigDerivedClassHasMethod(string methodName, Type[] methodTypes) {\n");
Printf(proxy_class_code, " private bool SwigDerivedClassHasMethod(string methodName, global::System.Type[] methodTypes) {\n");
Printf(proxy_class_code,
" System.Reflection.MethodInfo methodInfo = this.GetType().GetMethod(methodName, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance, null, methodTypes, null);\n");
" global::System.Reflection.MethodInfo methodInfo = this.GetType().GetMethod(methodName, global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Instance, null, methodTypes, null);\n");
Printf(proxy_class_code, " bool hasDerivedMethod = methodInfo.DeclaringType.IsSubclassOf(typeof(%s));\n", proxy_class_name);
/* Could add this code to cover corner case where the GetMethod() returns a method which allows type
* promotion, eg it will return foo(double), if looking for foo(int).
@ -1795,11 +1820,11 @@ public:
// Add code to do C++ casting to base class (only for classes in an inheritance hierarchy)
if (derived) {
String *smartptr = Getattr(n, "feature:smartptr");
String *upcast_method = Swig_name_member(getNSpace(), proxy_class_name, smartptr != 0 ? "SWIGSmartPtrUpcast" : "SWIGUpcast");
String *upcast_method = Swig_name_member(getNSpace(), getClassPrefix(), smartptr != 0 ? "SWIGSmartPtrUpcast" : "SWIGUpcast");
String *wname = Swig_name_wrapper(upcast_method);
Printv(imclass_cppcasts_code, "\n [DllImport(\"", dllimport, "\", EntryPoint=\"", wname, "\")]\n", NIL);
Printf(imclass_cppcasts_code, " public static extern IntPtr %s(IntPtr jarg1);\n", upcast_method);
Printv(imclass_cppcasts_code, "\n [global::System.Runtime.InteropServices.DllImport(\"", dllimport, "\", EntryPoint=\"", wname, "\")]\n", NIL);
Printf(imclass_cppcasts_code, " public static extern global::System.IntPtr %s(global::System.IntPtr jarg1);\n", upcast_method);
Replaceall(imclass_cppcasts_code, "$csclassname", proxy_class_name);
@ -1846,11 +1871,36 @@ public:
String *nspace = getNSpace();
File *f_proxy = NULL;
// save class local variables
String *old_proxy_class_name = proxy_class_name;
String *old_full_imclass_name = full_imclass_name;
String *old_destructor_call = destructor_call;
String *old_proxy_class_constants_code = proxy_class_constants_code;
String *old_proxy_class_def = proxy_class_def;
String *old_proxy_class_code = proxy_class_code;
bool has_outerclass = Getattr(n, "nested:outer") && !GetFlag(n, "feature:flatnested");
if (proxy_flag) {
proxy_class_name = NewString(Getattr(n, "sym:name"));
if (Node *outer = Getattr(n, "nested:outer")) {
String *outerClassesPrefix = Copy(Getattr(outer, "sym:name"));
for (outer = Getattr(outer, "nested:outer"); outer != 0; outer = Getattr(outer, "nested:outer")) {
Push(outerClassesPrefix, ".");
Push(outerClassesPrefix, Getattr(outer, "sym:name"));
}
String *fnspace = nspace ? NewStringf("%s.%s", nspace, outerClassesPrefix) : outerClassesPrefix;
if (!addSymbol(proxy_class_name, n, fnspace))
return SWIG_ERROR;
if (nspace)
Delete(fnspace);
Delete(outerClassesPrefix);
}
else {
if (!addSymbol(proxy_class_name, n, nspace))
return SWIG_ERROR;
}
if (!nspace) {
full_proxy_class_name = NewStringf("%s", proxy_class_name);
full_imclass_name = NewStringf("%s", imclass_name);
if (Cmp(proxy_class_name, imclass_name) == 0) {
Printf(stderr, "Class name cannot be equal to intermediary class name: %s\n", proxy_class_name);
@ -1863,36 +1913,34 @@ public:
}
} else {
if (namespce) {
full_proxy_class_name = NewStringf("%s.%s.%s", namespce, nspace, proxy_class_name);
full_imclass_name = NewStringf("%s.%s", namespce, imclass_name);
} else {
full_proxy_class_name = NewStringf("%s.%s", nspace, proxy_class_name);
full_imclass_name = NewStringf("%s", imclass_name);
}
}
if (!addSymbol(proxy_class_name, n, nspace))
return SWIG_ERROR;
// Each outer proxy class goes into a separate file
if (!has_outerclass) {
String *output_directory = outputDirectory(nspace);
String *filen = NewStringf("%s%s.cs", output_directory, proxy_class_name);
f_proxy = NewFile(filen, "w", SWIG_output_files());
if (!f_proxy) {
FileErrorDisplay(filen);
SWIG_exit(EXIT_FAILURE);
}
Append(filenames_list, Copy(filen));
Delete(filen);
filen = NULL;
String *output_directory = outputDirectory(nspace);
String *filen = NewStringf("%s%s.cs", output_directory, proxy_class_name);
f_proxy = NewFile(filen, "w", SWIG_output_files());
if (!f_proxy) {
FileErrorDisplay(filen);
SWIG_exit(EXIT_FAILURE);
// Start writing out the proxy class file
emitBanner(f_proxy);
addOpenNamespace(nspace, f_proxy);
}
Append(filenames_list, Copy(filen));
Delete(filen);
filen = NULL;
// Start writing out the proxy class file
emitBanner(f_proxy);
addOpenNamespace(nspace, f_proxy);
Clear(proxy_class_def);
Clear(proxy_class_code);
else
++nesting_depth;
proxy_class_def = NewString("");
proxy_class_code = NewString("");
destructor_call = NewString("");
proxy_class_constants_code = NewString("");
}
@ -1903,7 +1951,7 @@ public:
emitProxyClassDefAndCPPCasts(n);
String *csclazzname = Swig_name_member(getNSpace(), proxy_class_name, ""); // mangled full proxy class name
String *csclazzname = Swig_name_member(getNSpace(), getClassPrefix(), ""); // mangled full proxy class name
Replaceall(proxy_class_def, "$csclassname", proxy_class_name);
Replaceall(proxy_class_code, "$csclassname", proxy_class_name);
@ -1924,17 +1972,35 @@ public:
Replaceall(proxy_class_def, "$dllimport", dllimport);
Replaceall(proxy_class_code, "$dllimport", dllimport);
Replaceall(proxy_class_constants_code, "$dllimport", dllimport);
Printv(f_proxy, proxy_class_def, proxy_class_code, NIL);
if (!has_outerclass)
Printv(f_proxy, proxy_class_def, proxy_class_code, NIL);
else {
Swig_offset_string(proxy_class_def, nesting_depth);
Append(old_proxy_class_code, proxy_class_def);
Swig_offset_string(proxy_class_code, nesting_depth);
Append(old_proxy_class_code, proxy_class_code);
}
// Write out all the constants
if (Len(proxy_class_constants_code) != 0)
Printv(f_proxy, proxy_class_constants_code, NIL);
Printf(f_proxy, "}\n");
addCloseNamespace(nspace, f_proxy);
Delete(f_proxy);
f_proxy = NULL;
if (Len(proxy_class_constants_code) != 0) {
if (!has_outerclass)
Printv(f_proxy, proxy_class_constants_code, NIL);
else {
Swig_offset_string(proxy_class_constants_code, nesting_depth);
Append(old_proxy_class_code, proxy_class_constants_code);
}
}
if (!has_outerclass) {
Printf(f_proxy, "}\n");
addCloseNamespace(nspace, f_proxy);
Delete(f_proxy);
f_proxy = NULL;
} else {
for (int i = 0; i < nesting_depth; ++i)
Append(old_proxy_class_code, " ");
Append(old_proxy_class_code, "}\n\n");
--nesting_depth;
}
/* Output the downcast method, if necessary. Note: There's no other really
good place to put this code, since Abstract Base Classes (ABCs) can and should have
@ -1971,17 +2037,18 @@ public:
Delete(csclazzname);
Delete(proxy_class_name);
proxy_class_name = NULL;
Delete(full_proxy_class_name);
full_proxy_class_name = NULL;
proxy_class_name = old_proxy_class_name;
Delete(full_imclass_name);
full_imclass_name = NULL;
full_imclass_name = old_full_imclass_name;
Delete(destructor_call);
destructor_call = NULL;
destructor_call = old_destructor_call;
Delete(proxy_class_constants_code);
proxy_class_constants_code = NULL;
proxy_class_constants_code = old_proxy_class_constants_code;
Delete(proxy_class_def);
proxy_class_def = old_proxy_class_def;
Delete(proxy_class_code);
proxy_class_code = old_proxy_class_code;
}
return SWIG_OK;
}
@ -1994,7 +2061,7 @@ public:
if (proxy_flag) {
String *overloaded_name = getOverloadedName(n);
String *intermediary_function_name = Swig_name_member(getNSpace(), proxy_class_name, overloaded_name);
String *intermediary_function_name = Swig_name_member(getNSpace(), getClassPrefix(), overloaded_name);
Setattr(n, "proxyfuncname", Getattr(n, "sym:name"));
Setattr(n, "imfuncname", intermediary_function_name);
proxyClassFunctionHandler(n);
@ -2014,7 +2081,7 @@ public:
if (proxy_flag) {
String *overloaded_name = getOverloadedName(n);
String *intermediary_function_name = Swig_name_member(getNSpace(), proxy_class_name, overloaded_name);
String *intermediary_function_name = Swig_name_member(getNSpace(), getClassPrefix(), overloaded_name);
Setattr(n, "proxyfuncname", Getattr(n, "sym:name"));
Setattr(n, "imfuncname", intermediary_function_name);
proxyClassFunctionHandler(n);
@ -2094,7 +2161,7 @@ public:
if (wrapping_member_flag && !enum_constant_flag) {
// Properties
setter_flag = (Cmp(Getattr(n, "sym:name"), Swig_name_set(getNSpace(), Swig_name_member(0, proxy_class_name, variable_name))) == 0);
setter_flag = (Cmp(Getattr(n, "sym:name"), Swig_name_set(getNSpace(), Swig_name_member(0, getClassPrefix(), variable_name))) == 0);
if (setter_flag)
Swig_typemap_attach_parms("csvarin", l, NULL);
}
@ -2264,7 +2331,7 @@ public:
Node *explicit_n = Getattr(n, "explicitcallnode");
if (explicit_n) {
String *ex_overloaded_name = getOverloadedName(explicit_n);
String *ex_intermediary_function_name = Swig_name_member(getNSpace(), proxy_class_name, ex_overloaded_name);
String *ex_intermediary_function_name = Swig_name_member(getNSpace(), getClassPrefix(), ex_overloaded_name);
String *ex_imcall = Copy(imcall);
Replaceall(ex_imcall, "$imfuncname", ex_intermediary_function_name);
@ -3098,25 +3165,37 @@ public:
* ----------------------------------------------------------------------------- */
void substituteClassnameSpecialVariable(SwigType *classnametype, String *tm, const char *classnamespecialvariable) {
String *replacementname;
if (SwigType_isenum(classnametype)) {
String *enumname = getEnumName(classnametype);
if (enumname)
Replaceall(tm, classnamespecialvariable, enumname);
else
Replaceall(tm, classnamespecialvariable, NewStringf("int"));
if (enumname) {
replacementname = Copy(enumname);
} else {
bool anonymous_enum = (Cmp(classnametype, "enum ") == 0);
if (anonymous_enum) {
replacementname = NewString("int");
} else {
// An unknown enum - one that has not been parsed (neither a C enum forward reference nor a definition) or an ignored enum
replacementname = NewStringf("SWIGTYPE%s", SwigType_manglestr(classnametype));
Replace(replacementname, "enum ", "", DOH_REPLACE_ANY);
Setattr(swig_types_hash, replacementname, classnametype);
}
}
} else {
String *classname = getProxyName(classnametype);
String *classname = getProxyName(classnametype); // getProxyName() works for pointers to classes too
if (classname) {
Replaceall(tm, classnamespecialvariable, classname); // getProxyName() works for pointers to classes too
} else { // use $descriptor if SWIG does not know anything about this type. Note that any typedefs are resolved.
String *descriptor = NewStringf("SWIGTYPE%s", SwigType_manglestr(classnametype));
Replaceall(tm, classnamespecialvariable, descriptor);
replacementname = Copy(classname);
} else {
// use $descriptor if SWIG does not know anything about this type. Note that any typedefs are resolved.
replacementname = NewStringf("SWIGTYPE%s", SwigType_manglestr(classnametype));
// Add to hash table so that the type wrapper classes can be created later
Setattr(swig_types_hash, descriptor, classnametype);
Delete(descriptor);
Setattr(swig_types_hash, replacementname, classnametype);
}
}
Replaceall(tm, classnamespecialvariable, replacementname);
Delete(replacementname);
}
/* -----------------------------------------------------------------------------
@ -3206,6 +3285,9 @@ public:
Replaceall(swigtype, "$imclassname", imclass_name);
Replaceall(swigtype, "$dllimport", dllimport);
// For unknown enums
Replaceall(swigtype, "$enumvalues", "");
Printv(f_swigtype, swigtype, NIL);
addCloseNamespace(0, f_swigtype);
@ -3376,19 +3458,26 @@ public:
// Output the director connect method:
String *norm_name = SwigType_namestr(Getattr(n, "name"));
String *swig_director_connect = Swig_name_member(getNSpace(), proxy_class_name, "director_connect");
String *dirclassname = directorClassName(n);
String *swig_director_connect = Swig_name_member(getNSpace(), getClassPrefix(), "director_connect");
String *wname = Swig_name_wrapper(swig_director_connect);
String *sym_name = Getattr(n, "sym:name");
String *qualified_classname = Copy(sym_name);
String *nspace = getNSpace();
String *dirClassName = directorClassName(n);
String *smartptr = Getattr(n, "feature:smartptr");
if (!GetFlag(n, "feature:flatnested")) {
for (Node *outer_class = Getattr(n, "nested:outer"); outer_class; outer_class = Getattr(outer_class, "nested:outer")) {
Push(qualified_classname, ".");
Push(qualified_classname, Getattr(outer_class, "sym:name"));
}
}
if (nspace)
Insert(qualified_classname, 0, NewStringf("%s.", nspace));
Printv(imclass_class_code, "\n [DllImport(\"", dllimport, "\", EntryPoint=\"", wname, "\")]\n", NIL);
Printf(imclass_class_code, " public static extern void %s(HandleRef jarg1", swig_director_connect);
Printv(imclass_class_code, "\n [global::System.Runtime.InteropServices.DllImport(\"", dllimport, "\", EntryPoint=\"", wname, "\")]\n", NIL);
Printf(imclass_class_code, " public static extern void %s(global::System.Runtime.InteropServices.HandleRef jarg1", swig_director_connect);
Wrapper *code_wrap = NewWrapper();
Printf(code_wrap->def, "SWIGEXPORT void SWIGSTDCALL %s(void *objarg", wname);
@ -3415,7 +3504,7 @@ public:
Printf(code_wrap->def, ", ");
if (i != first_class_dmethod)
Printf(code_wrap->code, ", ");
Printf(code_wrap->def, "%s::SWIG_Callback%s_t callback%s", dirClassName, methid, methid);
Printf(code_wrap->def, "%s::SWIG_Callback%s_t callback%s", dirclassname, methid, methid);
Printf(code_wrap->code, "callback%s", methid);
Printf(imclass_class_code, ", %s.SwigDelegate%s_%s delegate%s", qualified_classname, sym_name, methid, methid);
}
@ -3432,7 +3521,7 @@ public:
Delete(wname);
Delete(swig_director_connect);
Delete(qualified_classname);
Delete(dirClassName);
Delete(dirclassname);
}
/* ---------------------------------------------------------------
@ -3485,7 +3574,7 @@ public:
// we're consistent with the sym:overload name in functionWrapper. (?? when
// does the overloaded method name get set?)
imclass_dmethod = NewStringf("SwigDirector_%s", Swig_name_member(getNSpace(), classname, overloaded_name));
imclass_dmethod = NewStringf("SwigDirector_%s", Swig_name_member(getNSpace(), getClassPrefix(), overloaded_name));
qualified_return = SwigType_rcaststr(returntype, "c_result");
@ -3917,7 +4006,7 @@ public:
Printf(director_delegate_definitions, " SwigDelegate%s_%s(%s);\n", classname, methid, delegate_parms);
Printf(director_delegate_instances, " private SwigDelegate%s_%s swigDelegate%s;\n", classname, methid, methid);
Printf(director_method_types, " private static Type[] swigMethodTypes%s = new Type[] { %s };\n", methid, proxy_method_types);
Printf(director_method_types, " private static global::System.Type[] swigMethodTypes%s = new global::System.Type[] { %s };\n", methid, proxy_method_types);
Printf(director_connect_parms, "SwigDirector%s%s delegate%s", classname, methid, methid);
}
@ -3931,6 +4020,7 @@ public:
Delete(proxy_method_types);
Delete(callback_def);
Delete(callback_code);
Delete(dirclassname);
DelWrapper(w);
return status;
@ -3970,13 +4060,11 @@ public:
String *basetype = Getattr(parent, "classtype");
String *target = Swig_method_decl(0, decl, dirclassname, parms, 0, 0);
String *call = Swig_csuperclass_call(0, basetype, superparms);
String *classtype = SwigType_namestr(Getattr(n, "name"));
Printf(f_directors, "%s::%s : %s, %s {\n", dirclassname, target, call, Getattr(parent, "director:ctor"));
Printf(f_directors, " swig_init_callbacks();\n");
Printf(f_directors, "}\n\n");
Delete(classtype);
Delete(target);
Delete(call);
}
@ -4047,6 +4135,29 @@ public:
return Language::classDirectorInit(n);
}
int classDeclaration(Node *n) {
String *old_director_callback_typedefs = director_callback_typedefs;
String *old_director_callbacks = director_callbacks;
String *old_director_delegate_callback = director_delegate_callback;
String *old_director_delegate_definitions = director_delegate_definitions;
String *old_director_delegate_instances = director_delegate_instances;
String *old_director_method_types = director_method_types;
String *old_director_connect_parms = director_connect_parms;
int ret = Language::classDeclaration(n);
// these variables are deleted in emitProxyClassDefAndCPPCasts, hence no Delete here
director_callback_typedefs = old_director_callback_typedefs;
director_callbacks = old_director_callbacks;
director_delegate_callback = old_director_delegate_callback;
director_delegate_definitions = old_director_delegate_definitions;
director_delegate_instances = old_director_delegate_instances;
director_method_types = old_director_method_types;
director_connect_parms = old_director_connect_parms;
return ret;
}
/* ----------------------------------------------------------------------
* classDirectorDestructor()
* ---------------------------------------------------------------------- */
@ -4079,7 +4190,7 @@ public:
int classDirectorEnd(Node *n) {
int i;
String *director_classname = directorClassName(n);
String *dirclassname = directorClassName(n);
Wrapper *w = NewWrapper();
@ -4089,7 +4200,7 @@ public:
Printf(f_directors_h, " void swig_connect_director(");
Printf(w->def, "void %s::swig_connect_director(", director_classname);
Printf(w->def, "void %s::swig_connect_director(", dirclassname);
for (i = first_class_dmethod; i < curr_class_dmethod; ++i) {
UpcallData *udata = Getitem(dmethods_seq, i);
@ -4116,7 +4227,7 @@ public:
Printf(f_directors_h, "};\n\n");
Printf(w->code, "}\n\n");
Printf(w->code, "void %s::swig_init_callbacks() {\n", director_classname);
Printf(w->code, "void %s::swig_init_callbacks() {\n", dirclassname);
for (i = first_class_dmethod; i < curr_class_dmethod; ++i) {
UpcallData *udata = Getitem(dmethods_seq, i);
String *overname = Getattr(udata, "overname");
@ -4127,6 +4238,7 @@ public:
Wrapper_print(w, f_directors);
DelWrapper(w);
Delete(dirclassname);
return Language::classDirectorEnd(n);
}
@ -4159,8 +4271,8 @@ public:
String *base = Getattr(n, "classtype");
String *class_ctor = NewString("Swig::Director()");
String *directorname = directorClassName(n);
String *declaration = Swig_class_declaration(n, directorname);
String *dirclassname = directorClassName(n);
String *declaration = Swig_class_declaration(n, dirclassname);
Printf(declaration, " : public %s, public Swig::Director", base);
@ -4168,9 +4280,12 @@ public:
Setattr(n, "director:decl", declaration);
Setattr(n, "director:ctor", class_ctor);
Delete(directorname);
Delete(dirclassname);
}
NestedClassSupport nestedClassesSupport() const {
return NCS_Full;
}
}; /* class CSHARP */
/* -----------------------------------------------------------------------------
@ -4188,7 +4303,7 @@ extern "C" Language *swig_csharp(void) {
* Static member variables
* ----------------------------------------------------------------------------- */
const char *CSHARP::usage = (char *) "\
const char *CSHARP::usage = "\
C# Options (available with -csharp)\n\
-dllimport <dl> - Override DllImport attribute name to <dl>\n\
-namespace <nm> - Generate wrappers into C# namespace <nm>\n\

View file

@ -568,8 +568,7 @@ public:
writeTypeWrapperClass(swig_type.key, swig_type.item);
}
// Add the proxy functions (and classes, if they are not written to a
// seperate file).
// Add the proxy functions (and classes, if they are not written to a separate file).
replaceModuleVariables(proxy_dmodule_code);
Printv(proxy_d_file, proxy_dmodule_code, NIL);
@ -1399,7 +1398,7 @@ public:
// generates a getter function (which is the same as a read only property
// in D) which retrieves the value via by calling the C wrapper.
// Note that this is only called for global constants, static member
// constants are already handeled in staticmemberfunctionHandler().
// constants are already handled in staticmemberfunctionHandler().
Swig_save("constantWrapper", n, "value", NIL);
Swig_save("constantWrapper", n, "tmap:ctype:out", "tmap:imtype:out", "tmap:dtype:out", "tmap:out:null", "tmap:imtype:outattributes", "tmap:dtype:outattributes", NIL);
@ -3602,7 +3601,7 @@ private:
* package if one is set.
*
* This is only used for dependencies created in generated code, user-
* (i.e. typemap-) specified import statements are handeled seperately.
* (i.e. typemap-) specified import statements are handled separately.
* --------------------------------------------------------------------------- */
void requireDType(const String *nspace, const String *symname) {
String *dmodule = createModuleName(nspace, symname);
@ -4054,10 +4053,10 @@ private:
// TODO: Fix const-correctness of methods called in here and make type const.
// We make use of the fact that this function is called at least once for
// every type encountered which is written to a seperate file, which allows
// every type encountered which is written to a separate file, which allows
// us to handle imports here.
// When working in split proxy module mode, each generated proxy class/enum
// is written to a seperate module. This requires us to add a corresponding
// is written to a separate module. This requires us to add a corresponding
// import when a type is used in another generated module. If we are not
// working in split proxy module mode, this is not relevant and the
// generated module name is discarded.
@ -4066,35 +4065,39 @@ private:
if (SwigType_isenum(type)) {
// RESEARCH: Make sure that we really cannot get here for anonymous enums.
Node *n = enumLookup(type);
String *enum_name = Getattr(n, "sym:name");
if (n) {
String *enum_name = Getattr(n, "sym:name");
Node *p = parentNode(n);
if (p && !Strcmp(nodeType(p), "class")) {
// This is a nested enum.
String *parent_name = Getattr(p, "sym:name");
String *nspace = Getattr(p, "sym:nspace");
Node *p = parentNode(n);
if (p && !Strcmp(nodeType(p), "class")) {
// This is a nested enum.
String *parent_name = Getattr(p, "sym:name");
String *nspace = Getattr(p, "sym:nspace");
// An enum nested in a class is not written to a seperate module (this
// would not even be possible in D), so just import the parent.
requireDType(nspace, parent_name);
// An enum nested in a class is not written to a separate module (this
// would not even be possible in D), so just import the parent.
requireDType(nspace, parent_name);
String *module = createModuleName(nspace, parent_name);
if (inProxyModule(module)) {
type_name = NewStringf("%s.%s", parent_name, enum_name);
String *module = createModuleName(nspace, parent_name);
if (inProxyModule(module)) {
type_name = NewStringf("%s.%s", parent_name, enum_name);
} else {
type_name = NewStringf("%s%s.%s.%s", package, module, parent_name, enum_name);
}
} else {
type_name = NewStringf("%s%s.%s.%s", package, module, parent_name, enum_name);
// A non-nested enum is written to a separate module, import it.
String *nspace = Getattr(n, "sym:nspace");
requireDType(nspace, enum_name);
String *module = createModuleName(nspace, enum_name);
if (inProxyModule(module)) {
type_name = Copy(enum_name);
} else {
type_name = NewStringf("%s%s.%s", package, module, enum_name);
}
}
} else {
// A non-nested enum is written to a seperate module, import it.
String *nspace = Getattr(n, "sym:nspace");
requireDType(nspace, enum_name);
String *module = createModuleName(nspace, enum_name);
if (inProxyModule(module)) {
type_name = Copy(enum_name);
} else {
type_name = NewStringf("%s%s.%s", package, module, enum_name);
}
type_name = NewStringf("int");
}
} else {
Node *n = classLookup(type);
@ -4646,7 +4649,7 @@ extern "C" Language *swig_d(void) {
/* -----------------------------------------------------------------------------
* Usage information displayed at the command line.
* ----------------------------------------------------------------------------- */
const char *D::usage = (char *) "\
const char *D::usage = "\
D Options (available with -d)\n\
-d2 - Generate code for D2/Phobos (default: D1/Tango)\n\
-package <pkg> - Write generated D modules into package <pkg>\n\

View file

@ -275,8 +275,8 @@ String *Swig_method_decl(SwigType *rettype, SwigType *decl, const_String_or_char
void Swig_director_emit_dynamic_cast(Node *n, Wrapper *f) {
// TODO: why is the storage element removed in staticmemberfunctionHandler ??
if ((!is_public(n) && (is_member_director(n) || GetFlag(n, "explicitcall"))) ||
(is_non_virtual_protected_access(n) && !(checkAttribute(n, "staticmemberfunctionHandler:storage", "static") ||
checkAttribute(n, "storage", "static"))
(is_non_virtual_protected_access(n) && !(Swig_storage_isstatic_custom(n, "staticmemberfunctionHandler:storage") ||
Swig_storage_isstatic(n))
&& !Equal(nodeType(n), "constructor"))) {
Node *parent = Getattr(n, "parentNode");
String *dirname;

View file

@ -22,10 +22,14 @@ class GO:public Language {
bool gccgo_flag;
// Prefix to use with gccgo.
String *go_prefix;
// -fgo-prefix option.
String *prefix_option;
// -fgo-pkgpath option.
String *pkgpath_option;
// Whether to use a shared library.
bool use_shlib;
// Name of shared library to import.
String *soname;
// Size in bits of the C type "long".
int long_type_size;
// Size in bits of the Go type "int". 0 if not specified.
int intgo_type_size;
@ -41,6 +45,7 @@ class GO:public Language {
File *f_c_init;
File *f_c_directors;
File *f_c_directors_h;
File *f_go_imports;
File *f_go_runtime;
File *f_go_header;
File *f_go_wrappers;
@ -74,20 +79,28 @@ class GO:public Language {
bool making_variable_wrappers;
// True when working with a static member function.
bool is_static_member_function;
// A hash table of enum types that we have seen but which may not have
// been defined. The index is a SwigType.
Hash *undefined_enum_types;
// A hash table of types that we have seen but which may not have
// been defined. The index is a SwigType.
Hash *undefined_types;
// A hash table of classes which were defined. The index is a Go
// type name.
Hash *defined_types;
// A hash table of all the go_imports already imported. The index is a full
// import name e.g. '"runtime"' or '_ "runtime/cgo"' or 'sc "syscall"'.
Hash *go_imports;
public:
GO():package(NULL),
module(NULL),
gccgo_flag(false),
go_prefix(NULL),
prefix_option(NULL),
pkgpath_option(NULL),
use_shlib(false),
soname(NULL),
long_type_size(32),
intgo_type_size(0),
f_c_begin(NULL),
f_go_begin(NULL),
@ -98,6 +111,7 @@ public:
f_c_init(NULL),
f_c_directors(NULL),
f_c_directors_h(NULL),
f_go_imports(NULL),
f_go_runtime(NULL),
f_go_header(NULL),
f_go_wrappers(NULL),
@ -113,8 +127,10 @@ public:
class_methods(NULL),
making_variable_wrappers(false),
is_static_member_function(false),
undefined_enum_types(NULL),
undefined_types(NULL),
defined_types(NULL) {
defined_types(NULL),
go_imports(NULL) {
director_multiple_inheritance = 1;
director_language = 1;
director_prot_ctor_code = NewString("_swig_gopanic(\"accessing abstract class or protected constructor\");");
@ -146,13 +162,25 @@ private:
gccgo_flag = true;
} else if (strcmp(argv[i], "-go-prefix") == 0) {
if (argv[i + 1]) {
go_prefix = NewString(argv[i + 1]);
prefix_option = NewString(argv[i + 1]);
Swig_mark_arg(i);
Swig_mark_arg(i + 1);
i++;
} else {
Swig_arg_error();
}
} else if (strcmp(argv[i], "-go-pkgpath") == 0) {
if (argv[i + 1]) {
pkgpath_option = NewString(argv[i + 1]);
Swig_mark_arg(i);
Swig_mark_arg(i + 1);
i++;
} else {
Swig_arg_error();
}
} else if (strcmp(argv[i], "-use-shlib") == 0) {
Swig_mark_arg(i);
use_shlib = true;
} else if (strcmp(argv[i], "-soname") == 0) {
if (argv[i + 1]) {
soname = NewString(argv[i + 1]);
@ -163,12 +191,8 @@ private:
Swig_arg_error();
}
} else if (strcmp(argv[i], "-longsize") == 0) {
// Ignore for backward compatibility.
if (argv[i + 1]) {
long_type_size = atoi(argv[i + 1]);
if (long_type_size != 32 && long_type_size != 64) {
Printf(stderr, "-longsize not 32 or 64\n");
Swig_arg_error();
}
Swig_mark_arg(i);
Swig_mark_arg(i + 1);
++i;
@ -195,8 +219,8 @@ private:
}
}
if (gccgo_flag && !go_prefix) {
go_prefix = NewString("go");
if (gccgo_flag && !pkgpath_option && !prefix_option) {
prefix_option = NewString("go");
}
// Add preprocessor symbol to parser.
@ -206,12 +230,6 @@ private:
Preprocessor_define("SWIGGO_GCCGO 1", 0);
}
if (long_type_size == 32) {
Preprocessor_define("SWIGGO_LONG_TYPE_SIZE 32", 0);
} else {
Preprocessor_define("SWIGGO_LONG_TYPE_SIZE 64", 0);
}
// This test may be removed in the future, when we can assume that
// everybody has upgraded to Go 1.1. The code below is prepared
// for this test to simply be taken out.
@ -274,13 +292,35 @@ private:
if (!package) {
package = Copy(module);
}
if (!soname) {
if (!soname && use_shlib) {
soname = Copy(package);
Append(soname, ".so");
}
if (gccgo_flag) {
String *pref;
if (pkgpath_option) {
pref = pkgpath_option;
} else {
pref = prefix_option;
}
go_prefix = NewString("");
for (char *p = Char(pref); *p != '\0'; p++) {
if ((*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z') || (*p >= '0' && *p <= '9') || *p == '.' || *p == '$') {
Putc(*p, go_prefix);
} else {
Putc('_', go_prefix);
}
}
if (!pkgpath_option) {
Append(go_prefix, ".");
Append(go_prefix, package);
}
}
// Get filenames.
String *swig_filename = Getattr(n, "infile");
String *c_filename = Getattr(n, "outfile");
String *c_filename_h = Getattr(n, "outfile_h");
@ -332,6 +372,7 @@ private:
f_c_wrappers = NewString("");
f_c_init = NewString("");
f_c_directors = NewString("");
f_go_imports = NewString("");
f_go_runtime = NewString("");
f_go_header = NewString("");
f_go_wrappers = NewString("");
@ -349,6 +390,7 @@ private:
Swig_register_filebyname("director", f_c_directors);
Swig_register_filebyname("director_h", f_c_directors_h);
Swig_register_filebyname("go_begin", f_go_begin);
Swig_register_filebyname("go_imports", f_go_imports);
Swig_register_filebyname("go_runtime", f_go_runtime);
Swig_register_filebyname("go_header", f_go_header);
Swig_register_filebyname("go_wrapper", f_go_wrappers);
@ -360,13 +402,23 @@ private:
}
Swig_banner(f_c_begin);
if (CPlusPlus) {
Printf(f_c_begin, "\n// source: %s\n\n", swig_filename);
} else {
Printf(f_c_begin, "\n/* source: %s */\n\n", swig_filename);
}
Printf(f_c_runtime, "#define SWIGMODULE %s\n", module);
if (gccgo_flag) {
Printf(f_c_runtime, "#define SWIGGO_PREFIX %s\n", go_prefix);
}
if (directorsEnabled()) {
Printf(f_c_runtime, "#define SWIG_DIRECTORS\n");
Swig_banner(f_c_directors_h);
Printf(f_c_directors_h, "\n// source: %s\n\n", swig_filename);
Printf(f_c_directors_h, "#ifndef SWIG_%s_WRAP_H_\n", module);
Printf(f_c_directors_h, "#define SWIG_%s_WRAP_H_\n\n", module);
@ -377,9 +429,11 @@ private:
}
Swig_banner(f_go_begin);
Printf(f_go_begin, "\n// source: %s\n", swig_filename);
if (!gccgo_flag) {
if (!gccgo_flag && soname) {
Swig_banner(f_gc_begin);
Printf(f_gc_begin, "\n/* source: %s */\n\n", swig_filename);
Printf(f_gc_begin, "\n/* This file should be compiled with 6c/8c. */\n");
Printf(f_gc_begin, "#pragma dynimport _ _ \"%s\"\n", soname);
}
@ -388,14 +442,12 @@ private:
Printf(f_go_begin, "\npackage %s\n\n", package);
Printf(f_go_runtime, "//extern %sSwigCgocall\n", module);
Printf(f_go_runtime, "func SwigCgocall()\n");
Printf(f_go_runtime, "//extern %sSwigCgocallDone\n", module);
Printf(f_go_runtime, "func SwigCgocallDone()\n");
Printf(f_go_runtime, "//extern %sSwigCgocallBack\n", module);
Printf(f_go_runtime, "func SwigCgocallBack()\n");
Printf(f_go_runtime, "//extern %sSwigCgocallBackDone\n", module);
Printf(f_go_runtime, "func SwigCgocallBackDone()\n\n");
if (gccgo_flag) {
Printf(f_go_runtime, "func SwigCgocall()\n");
Printf(f_go_runtime, "func SwigCgocallDone()\n");
Printf(f_go_runtime, "func SwigCgocallBack()\n");
Printf(f_go_runtime, "func SwigCgocallBackDone()\n\n");
}
// All the C++ wrappers should be extern "C".
@ -403,15 +455,26 @@ private:
// Set up the hash table for types not defined by SWIG.
undefined_enum_types = NewHash();
undefined_types = NewHash();
defined_types = NewHash();
go_imports = NewHash();
// Emit code.
Language::top(n);
Delete(go_imports);
// Write out definitions for the types not defined by SWIG.
if (Len(undefined_enum_types) > 0)
Printv(f_go_wrappers, "\n", NULL);
for (Iterator p = First(undefined_enum_types); p.key; p = Next(p)) {
String *name = p.item;
Printv(f_go_wrappers, "type ", name, " int\n", NULL);
}
Printv(f_go_wrappers, "\n", NULL);
for (Iterator p = First(undefined_types); p.key; p = Next(p)) {
String *ty = goType(NULL, p.key);
@ -430,6 +493,7 @@ private:
}
Delete(ty);
}
Delete(undefined_enum_types);
Delete(undefined_types);
Delete(defined_types);
@ -453,6 +517,7 @@ private:
Dump(f_c_runtime, f_c_begin);
Dump(f_c_wrappers, f_c_begin);
Dump(f_c_init, f_c_begin);
Dump(f_go_imports, f_go_begin);
Dump(f_go_header, f_go_begin);
Dump(f_go_runtime, f_go_begin);
Dump(f_go_wrappers, f_go_begin);
@ -466,6 +531,7 @@ private:
Delete(f_c_header);
Delete(f_c_wrappers);
Delete(f_c_init);
Delete(f_go_imports);
Delete(f_go_runtime);
Delete(f_go_header);
Delete(f_go_wrappers);
@ -495,7 +561,10 @@ private:
String *hold_import = imported_package;
String *modname = Getattr(n, "module");
if (modname) {
Printv(f_go_begin, "import \"", modname, "\"\n", NULL);
if (!Getattr(go_imports, modname)) {
Setattr(go_imports, modname, modname);
Printv(f_go_imports, "import \"", modname, "\"\n", NULL);
}
imported_package = modname;
saw_import = true;
}
@ -504,6 +573,31 @@ private:
return r;
}
/* ----------------------------------------------------------------------
* Language::insertDirective()
*
* If the section is go_imports, store them for later.
* ---------------------------------------------------------------------- */
virtual int insertDirective(Node *n) {
char *section = Char(Getattr(n, "section"));
if ((ImportMode && !Getattr(n, "generated")) ||
!section || (strcmp(section, "go_imports") != 0)) {
return Language::insertDirective(n);
}
char *code = Char(Getattr(n, "code"));
char *pch = strtok(code, ",");
while (pch != NULL) {
// Do not import same thing more than once.
if (!Getattr(go_imports, pch)) {
Setattr(go_imports, pch, pch);
Printv(f_go_imports, "import ", pch, "\n", NULL);
}
pch = strtok(NULL, ",");
}
return SWIG_OK;
}
/* ----------------------------------------------------------------------
* functionWrapper()
*
@ -1074,6 +1168,7 @@ private:
Wrapper *f = NewWrapper();
Printv(f->def, "#pragma dynimport ", wname, " ", wname, " \"\"\n", NULL);
Printv(f->def, "#pragma cgo_import_static ", wname, "\n", NULL);
Printv(f->def, "extern void (*", wname, ")(void*);\n", NULL);
Printv(f->def, "static void (*x", wname, ")(void*) = ", wname, ";\n", NULL);
Printv(f->def, "\n", NULL);
@ -1323,7 +1418,7 @@ private:
// Start the function definition.
String *fnname = NewString("");
Printv(fnname, go_prefix, "_", wname, "(", NULL);
Printv(fnname, "go_", wname, "(", NULL);
if (parm_count > required_count) {
Printv(fnname, "intgo _swig_optargc", NULL);
@ -1352,17 +1447,21 @@ private:
Printv(fnname, ")", NULL);
String *fndef = NewString("");
if (SwigType_type(result) == T_VOID) {
Printv(f->def, "void ", fnname, NULL);
Printv(fndef, "void ", fnname, NULL);
} else {
String *ct = gccgoCTypeForGoValue(n, result, fnname);
Printv(f->def, ct, NULL);
Printv(fndef, ct, NULL);
Delete(ct);
}
Printv(f->def, " {\n", NULL);
Printv(f->def, fndef, " __asm__(\"", go_prefix, "_", wname, "\");\n", NULL);
Printv(f->def, fndef, " {\n", NULL);
Delete(fnname);
Delete(fndef);
if (SwigType_type(result) != T_VOID) {
String *ln = NewString("go_result");
@ -1611,7 +1710,7 @@ private:
return goComplexConstant(n, type);
}
if (Getattr(n, "storage") && Strcmp(Getattr(n, "storage"), "static") == 0) {
if (Swig_storage_isstatic(n)) {
return goComplexConstant(n, type);
}
@ -2794,7 +2893,7 @@ private:
if (!gccgo_flag) {
Printv(f_c_directors, "extern \"C\" void ", wname, "(void*, int);\n", NULL);
} else {
Printv(f_c_directors, "extern \"C\" void ", wname, "(void*) __asm__(\"", go_prefix, ".", package, ".", go_name, "\");\n", NULL);
Printv(f_c_directors, "extern \"C\" void ", wname, "(void*) __asm__(\"", go_prefix, ".", go_name, "\");\n", NULL);
}
}
@ -2815,6 +2914,8 @@ private:
Printv(f_c_directors, " crosscall2(", wname, ", &a, (int) sizeof a);\n", NULL);
Printv(f_gc_wrappers, "#pragma dynexport ", wname, " ", wname, "\n", NULL);
Printv(f_gc_wrappers, "#pragma cgo_export_static ", wname, " ", wname, "\n", NULL);
Printv(f_gc_wrappers, "#pragma textflag 7\n", NULL);
Printv(f_gc_wrappers, "extern void \xc2\xb7", go_name, "();\n", NULL);
Printv(f_gc_wrappers, "void\n", NULL);
Printv(f_gc_wrappers, wname, "(void *a, int32 n)\n", NULL);
@ -2908,17 +3009,20 @@ private:
return r;
}
String *go_upcall = NewString("Director");
Append(go_upcall, cn);
Append(go_upcall, go_name);
r = makeDispatchFunction(on, go_upcall, director_struct_name, is_static, director_struct_name, true);
if (r != SWIG_OK) {
return r;
if (!GetFlag(n, "abstract")) {
String *go_upcall = NewString("Director");
Append(go_upcall, cn);
Append(go_upcall, go_name);
r = makeDispatchFunction(on, go_upcall, director_struct_name, is_static, director_struct_name, true);
if (r != SWIG_OK) {
return r;
}
Delete(go_upcall);
}
Delete(cn);
Delete(go_name);
Delete(director_struct_name);
Delete(go_upcall);
Delete(go_name);
Delete(cn);
}
}
Setattr(class_methods, name, NewString(""));
@ -3000,6 +3104,11 @@ private:
Append(upcall_name, go_name);
String *upcall_wname = Swig_name_wrapper(upcall_name);
if (overname) {
Append(upcall_wname, overname);
}
String *upcall_gc_name = buildGoWrapperName(upcall_name, overname);
String *go_with_over_name = Copy(go_name);
if (overname) {
@ -3042,40 +3151,36 @@ private:
Printv(f_go_wrappers, "\n", NULL);
Printv(f_go_wrappers, "}\n\n", NULL);
// Declare the upcall function, which calls the method on the
// parent class.
if (!GetFlag(n, "abstract")) {
// Declare the upcall function, which calls the method on the
// parent class.
if (overname) {
Append(upcall_wname, overname);
if (gccgo_flag) {
Printv(f_go_wrappers, "//extern ", go_prefix, "_", upcall_wname, "\n", NULL);
}
Printv(f_go_wrappers, "func ", upcall_gc_name, "(", go_type_name, NULL);
p = parms;
for (int i = 0; i < parm_count; ++i) {
p = getParm(p);
String *tm = goWrapperType(p, Getattr(p, "type"), false);
Printv(f_go_wrappers, ", ", tm, NULL);
Delete(tm);
p = nextParm(p);
}
Printv(f_go_wrappers, ")", NULL);
if (SwigType_type(result) != T_VOID) {
String *tm = goWrapperType(n, result, true);
Printv(f_go_wrappers, " ", tm, NULL);
Delete(tm);
}
Printv(f_go_wrappers, "\n", NULL);
}
String *upcall_gc_name = buildGoWrapperName(upcall_name, overname);
if (gccgo_flag) {
Printv(f_go_wrappers, "//extern ", go_prefix, "_", upcall_wname, "\n", NULL);
}
Printv(f_go_wrappers, "func ", upcall_gc_name, "(", go_type_name, NULL);
p = parms;
for (int i = 0; i < parm_count; ++i) {
p = getParm(p);
String *tm = goWrapperType(p, Getattr(p, "type"), false);
Printv(f_go_wrappers, ", ", tm, NULL);
Delete(tm);
p = nextParm(p);
}
Printv(f_go_wrappers, ")", NULL);
if (SwigType_type(result) != T_VOID) {
String *tm = goWrapperType(n, result, true);
Printv(f_go_wrappers, " ", tm, NULL);
Delete(tm);
}
Printv(f_go_wrappers, "\n", NULL);
// Define the method on the director class in Go.
Printv(f_go_wrappers, "func (swig_p *", director_struct_name, ") ", go_with_over_name, "(", NULL);
@ -3126,181 +3231,189 @@ private:
}
Printv(f_go_wrappers, "\t}\n", NULL);
if (gccgo_flag) {
Printv(f_go_wrappers, "\tdefer SwigCgocallDone()\n", NULL);
Printv(f_go_wrappers, "\tSwigCgocall()\n", NULL);
}
Printv(f_go_wrappers, "\t", NULL);
if (SwigType_type(result) != T_VOID) {
Printv(f_go_wrappers, "return ", NULL);
}
Printv(f_go_wrappers, upcall_gc_name, "(swig_p.", go_type_name, NULL);
p = parms;
for (int i = 0; i < parm_count; ++i) {
p = getParm(p);
SwigType *pt = Getattr(p, "type");
Printv(f_go_wrappers, ", ", Getattr(p, "lname"), NULL);
if (goTypeIsInterface(p, pt)) {
Printv(f_go_wrappers, ".Swigcptr()", NULL);
if (GetFlag(n, "abstract")) {
Printv(f_go_wrappers, "\tpanic(\"call to pure virtual method\")\n", NULL);
} else {
if (gccgo_flag) {
Printv(f_go_wrappers, "\tdefer SwigCgocallDone()\n", NULL);
Printv(f_go_wrappers, "\tSwigCgocall()\n", NULL);
}
p = nextParm(p);
Printv(f_go_wrappers, "\t", NULL);
if (SwigType_type(result) != T_VOID) {
Printv(f_go_wrappers, "return ", NULL);
}
Printv(f_go_wrappers, upcall_gc_name, "(swig_p.", go_type_name, NULL);
p = parms;
for (int i = 0; i < parm_count; ++i) {
p = getParm(p);
SwigType *pt = Getattr(p, "type");
Printv(f_go_wrappers, ", ", Getattr(p, "lname"), NULL);
if (goTypeIsInterface(p, pt)) {
Printv(f_go_wrappers, ".Swigcptr()", NULL);
}
p = nextParm(p);
}
Printv(f_go_wrappers, ")\n", NULL);
}
Printv(f_go_wrappers, ")\n", NULL);
Printv(f_go_wrappers, "}\n\n", NULL);
// Define a method in the C++ director class that the C++ upcall
// function can call. This permits an upcall to a protected
// method.
String *upcall_method_name = NewString("_swig_upcall_");
Append(upcall_method_name, name);
if (overname) {
Append(upcall_method_name, overname);
}
SwigType *rtype = Getattr(n, "classDirectorMethods:type");
String *upcall_decl = Swig_method_decl(rtype, Getattr(n, "decl"), upcall_method_name, parms, 0, 0);
Printv(f_c_directors_h, " ", upcall_decl, " {\n", NULL);
Delete(upcall_decl);
Printv(f_c_directors_h, " ", NULL);
if (SwigType_type(result) != T_VOID) {
Printv(f_c_directors_h, "return ", NULL);
}
String *super_call = Swig_method_call(super, parms);
Printv(f_c_directors_h, super_call, ";\n", NULL);
Delete(super_call);
Printv(f_c_directors_h, " }\n", NULL);
// Define the C++ function that the Go function calls.
SwigType *first_type = NULL;
Parm *first_parm = parms;
if (!is_static) {
first_type = NewString("SwigDirector_");
Append(first_type, class_name);
SwigType_add_pointer(first_type);
first_parm = NewParm(first_type, "p", n);
set_nextSibling(first_parm, parms);
}
Swig_save("classDirectorMethod", n, "wrap:name", "wrap:action", NULL);
Setattr(n, "wrap:name", upcall_wname);
String *action = NewString("");
if (SwigType_type(result) != T_VOID) {
Printv(action, Swig_cresult_name(), " = (", SwigType_lstr(result, 0), ")", NULL);
if (SwigType_isreference(result)) {
Printv(action, "&", NULL);
if (!GetFlag(n, "abstract")) {
String *upcall_method_name = NewString("_swig_upcall_");
Append(upcall_method_name, name);
if (overname) {
Append(upcall_method_name, overname);
}
}
Printv(action, Swig_cparm_name(NULL, 0), "->", upcall_method_name, "(", NULL);
SwigType *rtype = Getattr(n, "classDirectorMethods:type");
String *upcall_decl = Swig_method_decl(rtype, Getattr(n, "decl"), upcall_method_name, parms, 0, 0);
Printv(f_c_directors_h, " ", upcall_decl, " {\n", NULL);
Delete(upcall_decl);
p = parms;
int i = 0;
while (p != NULL) {
if (SwigType_type(Getattr(p, "type")) != T_VOID) {
String *pname = Swig_cparm_name(NULL, i + 1);
if (i > 0) {
Printv(action, ", ", NULL);
Printv(f_c_directors_h, " ", NULL);
if (SwigType_type(result) != T_VOID) {
Printv(f_c_directors_h, "return ", NULL);
}
String *super_call = Swig_method_call(super, parms);
Printv(f_c_directors_h, super_call, ";\n", NULL);
Delete(super_call);
Printv(f_c_directors_h, " }\n", NULL);
// Define the C++ function that the Go function calls.
SwigType *first_type = NULL;
Parm *first_parm = parms;
if (!is_static) {
first_type = NewString("SwigDirector_");
Append(first_type, class_name);
SwigType_add_pointer(first_type);
first_parm = NewParm(first_type, "p", n);
set_nextSibling(first_parm, parms);
}
Swig_save("classDirectorMethod", n, "wrap:name", "wrap:action", NULL);
Setattr(n, "wrap:name", upcall_wname);
String *action = NewString("");
if (SwigType_type(result) != T_VOID) {
Printv(action, Swig_cresult_name(), " = (", SwigType_lstr(result, 0), ")", NULL);
if (SwigType_isreference(result)) {
Printv(action, "&", NULL);
}
}
Printv(action, Swig_cparm_name(NULL, 0), "->", upcall_method_name, "(", NULL);
// A parameter whose type is a reference is converted into a
// pointer type by gcCTypeForGoValue. We are calling a
// function which expects a reference so we need to convert
// back.
if (SwigType_isreference(Getattr(p, "type"))) {
Printv(action, "*", NULL);
p = parms;
int i = 0;
while (p != NULL) {
if (SwigType_type(Getattr(p, "type")) != T_VOID) {
String *pname = Swig_cparm_name(NULL, i + 1);
if (i > 0) {
Printv(action, ", ", NULL);
}
// A parameter whose type is a reference is converted into a
// pointer type by gcCTypeForGoValue. We are calling a
// function which expects a reference so we need to convert
// back.
if (SwigType_isreference(Getattr(p, "type"))) {
Printv(action, "*", NULL);
}
Printv(action, pname, NULL);
Delete(pname);
i++;
}
Printv(action, pname, NULL);
Delete(pname);
i++;
p = nextSibling(p);
}
p = nextSibling(p);
}
Printv(action, ");", NULL);
Setattr(n, "wrap:action", action);
Printv(action, ");", NULL);
Setattr(n, "wrap:action", action);
if (!gccgo_flag) {
// Write the upcall wrapper function. This is compiled by gc
// and calls the C++ function.
int r = gcFunctionWrapper(n, upcall_name, upcall_name, overname, upcall_wname, first_parm, result, is_static, true);
if (r != SWIG_OK) {
return r;
if (!gccgo_flag) {
// Write the upcall wrapper function. This is compiled by gc
// and calls the C++ function.
int r = gcFunctionWrapper(n, upcall_name, upcall_name, overname, upcall_wname, first_parm, result, is_static, true);
if (r != SWIG_OK) {
return r;
}
r = gccFunctionWrapper(n, NULL, upcall_wname, first_parm, result);
if (r != SWIG_OK) {
return r;
}
} else {
int r = gccgoFunctionWrapper(n, NULL, upcall_wname, first_parm, result);
if (r != SWIG_OK) {
return r;
}
}
r = gccFunctionWrapper(n, NULL, upcall_wname, first_parm, result);
if (r != SWIG_OK) {
return r;
Delete(first_type);
if (first_parm != parms) {
Delete(first_parm);
}
} else {
int r = gccgoFunctionWrapper(n, NULL, upcall_wname, first_parm, result);
if (r != SWIG_OK) {
return r;
Swig_restore(n);
Delete(upcall_method_name);
// Define a function that uses the Go director type that other
// methods in the Go type can call to get parent methods.
Printv(f_go_wrappers, "func Director", cn, go_with_over_name, "(p ", cn, NULL);
p = parms;
for (int i = 0; i < parm_count; ++i) {
p = getParm(p);
Printv(f_go_wrappers, ", ", Getattr(p, "lname"), " ", NULL);
String *tm = goType(p, Getattr(p, "type"));
Printv(f_go_wrappers, tm, NULL);
Delete(tm);
p = nextParm(p);
}
}
Delete(first_type);
if (first_parm != parms) {
Delete(first_parm);
}
Printv(f_go_wrappers, ")", NULL);
Swig_restore(n);
// Define a function which uses the Go director type that other
// methods in the Go type can call to get parent methods.
Printv(f_go_wrappers, "func Director", cn, go_with_over_name, "(p ", cn, NULL);
p = parms;
for (int i = 0; i < parm_count; ++i) {
p = getParm(p);
Printv(f_go_wrappers, ", ", Getattr(p, "lname"), " ", NULL);
String *tm = goType(p, Getattr(p, "type"));
Printv(f_go_wrappers, tm, NULL);
Delete(tm);
p = nextParm(p);
}
Printv(f_go_wrappers, ")", NULL);
if (SwigType_type(result) != T_VOID) {
String *tm = goType(n, result);
Printv(f_go_wrappers, " ", tm, NULL);
Delete(tm);
}
Printv(f_go_wrappers, " {\n", NULL);
if (gccgo_flag) {
Printv(f_go_wrappers, "\tdefer SwigCgocallDone()\n", NULL);
Printv(f_go_wrappers, "\tSwigCgocall()\n", NULL);
}
Printv(f_go_wrappers, "\t", NULL);
if (SwigType_type(result) != T_VOID) {
Printv(f_go_wrappers, "return ", NULL);
}
Printv(f_go_wrappers, upcall_gc_name, "(p.(*", director_struct_name, ").", go_type_name, NULL);
p = parms;
for (int i = 0; i < parm_count; ++i) {
p = getParm(p);
SwigType *pt = Getattr(p, "type");
Printv(f_go_wrappers, ", ", Getattr(p, "lname"), NULL);
if (goTypeIsInterface(p, pt)) {
Printv(f_go_wrappers, ".Swigcptr()", NULL);
if (SwigType_type(result) != T_VOID) {
String *tm = goType(n, result);
Printv(f_go_wrappers, " ", tm, NULL);
Delete(tm);
}
p = nextParm(p);
}
Printv(f_go_wrappers, ")\n", NULL);
Printv(f_go_wrappers, "}\n\n", NULL);
Printv(f_go_wrappers, " {\n", NULL);
if (gccgo_flag) {
Printv(f_go_wrappers, "\tdefer SwigCgocallDone()\n", NULL);
Printv(f_go_wrappers, "\tSwigCgocall()\n", NULL);
}
Printv(f_go_wrappers, "\t", NULL);
if (SwigType_type(result) != T_VOID) {
Printv(f_go_wrappers, "return ", NULL);
}
Printv(f_go_wrappers, upcall_gc_name, "(p.(*", director_struct_name, ").", go_type_name, NULL);
p = parms;
for (int i = 0; i < parm_count; ++i) {
p = getParm(p);
SwigType *pt = Getattr(p, "type");
Printv(f_go_wrappers, ", ", Getattr(p, "lname"), NULL);
if (goTypeIsInterface(p, pt)) {
Printv(f_go_wrappers, ".Swigcptr()", NULL);
}
p = nextParm(p);
}
Printv(f_go_wrappers, ")\n", NULL);
Printv(f_go_wrappers, "}\n\n", NULL);
}
// The Go function which invokes the method. This is called
// from by the C++ method on the director class.
@ -3380,17 +3493,16 @@ private:
}
Printv(f_go_wrappers, "\n", NULL);
Delete(upcall_gc_name);
}
Printv(f_go_wrappers, "}\n\n", NULL);
Delete(result_wrapper);
// Build the C++ functions.
Delete(upcall_wname);
Delete(upcall_gc_name);
// Build the C++ functions.
if (!gccgo_flag) {
Printv(f_c_directors, "extern \"C\" void ", callback_wname, "(void*, int);\n", NULL);
@ -3424,10 +3536,9 @@ private:
Delete(fnname);
Printv(f_c_directors, " __asm__(\"", go_prefix, ".", package, ".", callback_name, "\");\n", NULL);
Printv(f_c_directors, " __asm__(\"", go_prefix, ".", callback_name, "\");\n", NULL);
}
Delete(upcall_method_name);
Delete(go_with_over_name);
}
@ -3534,6 +3645,8 @@ private:
// The C wrapper code which calls the Go function.
Printv(f_gc_wrappers, "#pragma dynexport ", callback_wname, " ", callback_wname, "\n", NULL);
Printv(f_gc_wrappers, "#pragma cgo_export_static ", callback_wname, " ", callback_wname, "\n", NULL);
Printv(f_gc_wrappers, "#pragma textflag 7\n", NULL);
Printv(f_gc_wrappers, "extern void \xc2\xb7", callback_name, "();\n", NULL);
Printv(f_gc_wrappers, "void\n", NULL);
Printv(f_gc_wrappers, callback_wname, "(void *a, int32 n)\n", NULL);
@ -4394,11 +4507,20 @@ private:
SwigType *t = SwigType_typedef_resolve_all(type);
Node *e = Language::enumLookup(t);
if (e) {
ret = goEnumName(e);
} else if (Strcmp(t, "enum ") == 0) {
ret = NewString("int");
if (SwigType_isenum(t)) {
Node *e = Language::enumLookup(t);
if (e) {
ret = goEnumName(e);
} else if (Strcmp(t, "enum ") == 0) {
ret = NewString("int");
} else {
// An unknown enum - one that has not been parsed (neither a C enum forward reference nor a definition) or an ignored enum
String *tt = Copy(t);
Replace(tt, "enum ", "", DOH_REPLACE_ANY);
ret = exportedName(tt);
Setattr(undefined_enum_types, t, ret);
Delete(tt);
}
} else if (SwigType_isfunctionpointer(type) || SwigType_isfunction(type)) {
ret = NewString("_swig_fnptr");
} else if (SwigType_ismemberpointer(type)) {
@ -4667,14 +4789,11 @@ private:
ret = NewString("_Complex double ");
} else if (is_interface) {
SwigType *t = SwigType_typedef_resolve_all(type);
SwigType_strip_qualifiers(t);
if (SwigType_ispointer(t)) {
SwigType_del_pointer(t);
SwigType_strip_qualifiers(t);
}
if (SwigType_isreference(t)) {
SwigType_del_reference(t);
SwigType_strip_qualifiers(t);
}
SwigType_add_pointer(t);
ret = SwigType_lstr(t, name);
@ -4694,6 +4813,9 @@ private:
if (is_int) {
ret = NewString("intgo ");
Append(ret, name);
} else if (is_int64) {
ret = NewString("long long ");
Append(ret, name);
} else {
ret = SwigType_lstr(t, name);
}
@ -4706,8 +4828,13 @@ private:
}
}
if (Language::enumLookup(t) != NULL || Strcmp(t, "enum ") == 0) {
if (Language::enumLookup(t) != NULL) {
is_int = true;
} else {
SwigType *tstripped = SwigType_strip_qualifiers(t);
if (SwigType_isenum(tstripped))
is_int = true;
Delete(tstripped);
}
Delete(t);
@ -4860,7 +4987,7 @@ private:
bool isStatic(Node *n) {
String *storage = Getattr(n, "storage");
return (storage && (Strcmp(storage, "static") == 0 || Strcmp(storage, "friend") == 0) && (!SmartPointer || !Getattr(n, "allocate:smartpointeraccess")));
return (storage && (Swig_storage_isstatic(n) || Strcmp(storage, "friend") == 0) && (!SmartPointer || !Getattr(n, "allocate:smartpointeraccess")));
}
/* ----------------------------------------------------------------------
@ -4892,12 +5019,13 @@ extern "C" Language *swig_go(void) {
* ----------------------------------------------------------------------------- */
// Usage message.
const char * const GO::usage = (char *) "\
const char * const GO::usage = "\
Go Options (available with -go)\n\
-gccgo - Generate code for gccgo rather than 6g/8g\n\
-go-pkgpath <p> - Like gccgo -fgo-pkgpath option\n\
-go-prefix <p> - Like gccgo -fgo-prefix option\n\
-longsize <s> - Set size of C/C++ long type--32 or 64 bits\n\
-intgosize <s> - Set size of Go int type--32 or 64 bits\n\
-package <name> - Set name of the Go package to <name>\n\
-use-shlib - Force use of a shared library\n\
-soname <name> - Set shared library holding C/C++ code to <name>\n\
\n";

View file

@ -16,7 +16,7 @@
#include <ctype.h>
// Note string broken in half for compilers that can't handle long strings
static const char *usage = (char *) "\
static const char *usage = "\
Guile Options (available with -guile)\n\
-emitsetters - Emit procedures-with-setters for variables\n\
and structure slots.\n\
@ -24,7 +24,7 @@ Guile Options (available with -guile)\n\
-exportprimitive - Add the (export ...) code from scmstub into the\n\
GOOPS file.\n\
-goopsprefix <prefix> - Prepend <prefix> to all goops identifiers\n\
-linkage <lstyle> - Use linkage protocol <lstyle> (default `simple')\n\
-Linkage <lstyle> - Use linkage protocol <lstyle> (default `simple')\n\
Use `module' for native Guile module linking\n\
(requires Guile >= 1.5.0). Use `passive' for\n\
passive linking (no C-level module-handling code),\n\
@ -1018,7 +1018,7 @@ public:
if (in_class)
goops_name = NewString(memberfunction_name);
else
goops_name = goopsNameMapping(proc_name, (char *) "");
goops_name = goopsNameMapping(proc_name, "");
String *primitive_name = NewString("");
if (primRenamer)
Printv(primitive_name, "primitive:", proc_name, NIL);
@ -1204,7 +1204,7 @@ public:
// export wrapper into goops file
if (!in_class) { // only if the variable is not part of a class
String *class_name = SwigType_typedef_resolve_all(SwigType_base(t));
String *goops_name = goopsNameMapping(proc_name, (char *) "");
String *goops_name = goopsNameMapping(proc_name, "");
String *primitive_name = NewString("");
if (primRenamer)
Printv(primitive_name, "primitive:", NIL);
@ -1350,7 +1350,7 @@ public:
Printv(f_header, tm, "\n", NIL);
} else {
// Create variable and assign it a value
Printf(f_header, "static %s = %s;\n", SwigType_lstr(nctype, var_name), rvalue);
Printf(f_header, "static %s = %s;\n", SwigType_str(type, var_name), rvalue);
}
{
/* Hack alert: will cleanup later -- Dave */

View file

@ -86,6 +86,7 @@ class JAVA:public Language {
int n_directors;
int first_class_dmethod;
int curr_class_dmethod;
int nesting_depth;
enum EnumFeature { SimpleEnum, TypeunsafeEnum, TypesafeEnum, ProperEnum };
@ -154,7 +155,8 @@ public:
n_dmethods(0),
n_directors(0),
first_class_dmethod(0),
curr_class_dmethod(0) {
curr_class_dmethod(0),
nesting_depth(0){
/* for now, multiple inheritance in directors is disabled, this
should be easy to implement though */
director_multiple_inheritance = 0;
@ -192,28 +194,38 @@ public:
*
* Test to see if a type corresponds to something wrapped with a proxy class.
* Return NULL if not otherwise the proxy class name, fully qualified with
* package name if the nspace feature is used.
* package name if the nspace feature is used, unless jnidescriptor is true as
* the package name is handled differently (unfortunately for legacy reasons).
* ----------------------------------------------------------------------------- */
String *getProxyName(SwigType *t) {
String *getProxyName(SwigType *t, bool jnidescriptor = false) {
String *proxyname = NULL;
if (proxy_flag) {
Node *n = classLookup(t);
if (n) {
proxyname = Getattr(n, "proxyname");
if (!proxyname) {
if (!proxyname || jnidescriptor) {
String *nspace = Getattr(n, "sym:nspace");
String *symname = Getattr(n, "sym:name");
String *symname = Copy(Getattr(n, "sym:name"));
if (symname && !GetFlag(n, "feature:flatnested")) {
for (Node *outer_class = Getattr(n, "nested:outer"); outer_class; outer_class = Getattr(outer_class, "nested:outer")) {
Push(symname, ".");
Push(symname, Getattr(outer_class, "sym:name"));
}
}
if (nspace) {
if (package)
if (package && !jnidescriptor)
proxyname = NewStringf("%s.%s.%s", package, nspace, symname);
else
proxyname = NewStringf("%s.%s", nspace, symname);
} else {
proxyname = Copy(symname);
}
Setattr(n, "proxyname", proxyname);
Delete(proxyname);
if (!jnidescriptor) {
Setattr(n, "proxyname", proxyname); // Cache it
Delete(proxyname);
}
Delete(symname);
}
}
}
@ -1131,7 +1143,7 @@ public:
*/
if (proxy_flag && wrapping_member_flag && !enum_constant_flag) {
// Capitalize the first letter in the variable to create a JavaBean type getter/setter function name
bool getter_flag = Cmp(symname, Swig_name_set(getNSpace(), Swig_name_member(0, proxy_class_name, variable_name))) != 0;
bool getter_flag = Cmp(symname, Swig_name_set(getNSpace(), Swig_name_member(0, getClassPrefix(), variable_name))) != 0;
String *getter_setter_name = NewString("");
if (!getter_flag)
@ -1182,6 +1194,30 @@ public:
return ret;
}
String *getCurrentScopeName(String *nspace)
{
String *scope = 0;
if (nspace || getCurrentClass()) {
scope = NewString("");
if (nspace)
Printf(scope, "%s", nspace);
if (Node* cls = getCurrentClass())
{
if (Node *outer = Getattr(cls, "nested:outer")) {
String *outerClassesPrefix = Copy(Getattr(outer, "sym:name"));
for (outer = Getattr(outer, "nested:outer"); outer != 0; outer = Getattr(outer, "nested:outer")) {
Push(outerClassesPrefix, ".");
Push(outerClassesPrefix, Getattr(outer, "sym:name"));
}
Printv(scope, nspace ? "." : "", outerClassesPrefix, ".", proxy_class_name, NIL);
Delete(outerClassesPrefix);
} else
Printv(scope, nspace ? "." : "", proxy_class_name, NIL);
}
}
return scope;
}
/* ----------------------------------------------------------------------
* enumDeclaration()
*
@ -1215,14 +1251,7 @@ public:
if ((enum_feature != SimpleEnum) && symname && typemap_lookup_type) {
// Wrap (non-anonymous) C/C++ enum within a typesafe, typeunsafe or proper Java enum
String *scope = 0;
if (nspace || proxy_class_name) {
scope = NewString("");
if (nspace)
Printf(scope, "%s", nspace);
if (proxy_class_name)
Printv(scope, nspace ? "." : "", proxy_class_name, NIL);
}
String *scope = getCurrentScopeName(nspace);
if (!addSymbol(symname, n, scope))
return SWIG_ERROR;
@ -1377,12 +1406,11 @@ public:
scope = Copy(constants_interface_name);
}
} else {
scope = NewString("");
if (nspace)
Printf(scope, "%s.", nspace);
if (proxy_class_name)
Printf(scope, "%s.", proxy_class_name);
Printf(scope, "%s",Getattr(parent, "sym:name"));
scope = getCurrentScopeName(nspace);
if (!scope)
scope = Copy(Getattr(parent, "sym:name"));
else
Printf(scope, ".%s", Getattr(parent, "sym:name"));
}
if (!addSymbol(name, n, scope))
return SWIG_ERROR;
@ -1710,6 +1738,7 @@ public:
String *c_baseclassname = NULL;
SwigType *typemap_lookup_type = Getattr(n, "classtypeobj");
bool feature_director = Swig_directorclass(n) ? true : false;
bool has_outerclass = Getattr(n, "nested:outer") != 0 && !GetFlag(n, "feature:flatnested");
// Inheritance from pure Java classes
Node *attributes = NewHash();
@ -1770,8 +1799,11 @@ public:
const String *pure_interfaces = typemapLookup(n, "javainterfaces", typemap_lookup_type, WARN_NONE);
// Start writing the proxy class
Printv(proxy_class_def, typemapLookup(n, "javaimports", typemap_lookup_type, WARN_NONE), // Import statements
"\n", typemapLookup(n, "javaclassmodifiers", typemap_lookup_type, WARN_JAVA_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers
if (!has_outerclass) // Import statements
Printv(proxy_class_def, typemapLookup(n, "javaimports", typemap_lookup_type, WARN_NONE),"\n", NIL);
else
Printv(proxy_class_def, "static ", NIL); // C++ nested classes correspond to static java classes
Printv(proxy_class_def, typemapLookup(n, "javaclassmodifiers", typemap_lookup_type, WARN_JAVA_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers
" $javaclassname", // Class name and bases
(*Char(wanted_base)) ? " extends " : "", wanted_base, *Char(pure_interfaces) ? // Pure Java interfaces
" implements " : "", pure_interfaces, " {", derived ? typemapLookup(n, "javabody_derived", typemap_lookup_type, WARN_JAVA_TYPEMAP_JAVABODY_UNDEF) : // main body of class
@ -1822,7 +1854,7 @@ public:
/* Also insert the swigTakeOwnership and swigReleaseOwnership methods */
if (feature_director) {
String *destruct_jnicall, *release_jnicall, *take_jnicall;
String *changeown_method_name = Swig_name_member(getNSpace(), proxy_class_name, "change_ownership");
String *changeown_method_name = Swig_name_member(getNSpace(), getClassPrefix(), "change_ownership");
destruct_jnicall = NewStringf("%s()", destruct_methodname);
release_jnicall = NewStringf("%s.%s(this, swigCPtr, false)", full_imclass_name, changeown_method_name);
@ -1848,7 +1880,7 @@ public:
// Add code to do C++ casting to base class (only for classes in an inheritance hierarchy)
if (derived) {
String *smartptr = Getattr(n, "feature:smartptr");
String *upcast_method = Swig_name_member(getNSpace(), proxy_class_name, smartptr != 0 ? "SWIGSmartPtrUpcast" : "SWIGUpcast");
String *upcast_method = Swig_name_member(getNSpace(), getClassPrefix(), smartptr != 0 ? "SWIGSmartPtrUpcast" : "SWIGUpcast");
String *jniname = makeValidJniName(upcast_method);
String *wname = Swig_name_wrapper(jniname);
Printf(imclass_cppcasts_code, " public final static native long %s(long jarg1);\n", upcast_method);
@ -1905,13 +1937,31 @@ public:
virtual int classHandler(Node *n) {
File *f_proxy = NULL;
String *old_proxy_class_name = proxy_class_name;
String *old_full_proxy_class_name = full_proxy_class_name;
String *old_full_imclass_name = full_imclass_name;
String *old_destructor_call = destructor_call;
String *old_destructor_throws_clause = destructor_throws_clause;
String *old_proxy_class_constants_code = proxy_class_constants_code;
String *old_proxy_class_def = proxy_class_def;
String *old_proxy_class_code = proxy_class_code;
bool has_outerclass = Getattr(n, "nested:outer") && !GetFlag(n, "feature:flatnested");
if (proxy_flag) {
proxy_class_name = NewString(Getattr(n, "sym:name"));
String *nspace = getNSpace();
constructIntermediateClassName(n);
String *outerClassesPrefix = 0;
if (Node *outer = Getattr(n, "nested:outer")) {
outerClassesPrefix = Copy(Getattr(outer, "sym:name"));
for (outer = Getattr(outer, "nested:outer"); outer != 0; outer = Getattr(outer, "nested:outer")) {
Push(outerClassesPrefix, ".");
Push(outerClassesPrefix, Getattr(outer, "sym:name"));
}
}
if (!nspace) {
full_proxy_class_name = NewStringf("%s", proxy_class_name);
full_proxy_class_name = outerClassesPrefix ? NewStringf("%s.%s", outerClassesPrefix, proxy_class_name) : NewStringf("%s", proxy_class_name);
if (Cmp(proxy_class_name, imclass_name) == 0) {
Printf(stderr, "Class name cannot be equal to intermediary class name: %s\n", proxy_class_name);
@ -1923,54 +1973,73 @@ public:
SWIG_exit(EXIT_FAILURE);
}
} else {
if (package)
full_proxy_class_name = NewStringf("%s.%s.%s", package, nspace, proxy_class_name);
else
full_proxy_class_name = NewStringf("%s.%s", nspace, proxy_class_name);
if (outerClassesPrefix) {
if (package)
full_proxy_class_name = NewStringf("%s.%s.%s.%s", package, nspace, outerClassesPrefix, proxy_class_name);
else
full_proxy_class_name = NewStringf("%s.%s.%s", nspace, outerClassesPrefix, proxy_class_name);
} else {
if (package)
full_proxy_class_name = NewStringf("%s.%s.%s", package, nspace, proxy_class_name);
else
full_proxy_class_name = NewStringf("%s.%s", nspace, proxy_class_name);
}
}
if (!addSymbol(proxy_class_name, n, nspace))
return SWIG_ERROR;
String *output_directory = outputDirectory(nspace);
String *filen = NewStringf("%s%s.java", output_directory, proxy_class_name);
f_proxy = NewFile(filen, "w", SWIG_output_files());
if (!f_proxy) {
FileErrorDisplay(filen);
SWIG_exit(EXIT_FAILURE);
}
Append(filenames_list, Copy(filen));
Delete(filen);
filen = NULL;
// Start writing out the proxy class file
emitBanner(f_proxy);
if (package || nspace) {
Printf(f_proxy, "package ");
if (package)
Printv(f_proxy, package, nspace ? "." : "", NIL);
if (outerClassesPrefix) {
String *fnspace = nspace ? NewStringf("%s.%s", nspace, outerClassesPrefix) : outerClassesPrefix;
if (!addSymbol(proxy_class_name, n, fnspace))
return SWIG_ERROR;
if (nspace)
Printv(f_proxy, nspace, NIL);
Printf(f_proxy, ";\n");
Delete(fnspace);
Delete(outerClassesPrefix);
}
else {
if (!addSymbol(proxy_class_name, n, nspace))
return SWIG_ERROR;
}
Clear(proxy_class_def);
Clear(proxy_class_code);
// Each outer proxy class goes into a separate file
if (!has_outerclass) {
String *output_directory = outputDirectory(nspace);
String *filen = NewStringf("%s%s.java", output_directory, proxy_class_name);
f_proxy = NewFile(filen, "w", SWIG_output_files());
if (!f_proxy) {
FileErrorDisplay(filen);
SWIG_exit(EXIT_FAILURE);
}
Append(filenames_list, Copy(filen));
Delete(filen);
Delete(output_directory);
// Start writing out the proxy class file
emitBanner(f_proxy);
if (package || nspace) {
Printf(f_proxy, "package ");
if (package)
Printv(f_proxy, package, nspace ? "." : "", NIL);
if (nspace)
Printv(f_proxy, nspace, NIL);
Printf(f_proxy, ";\n");
}
}
else
++nesting_depth;
proxy_class_def = NewString("");
proxy_class_code = NewString("");
destructor_call = NewString("");
destructor_throws_clause = NewString("");
proxy_class_constants_code = NewString("");
Delete(output_directory);
}
Language::classHandler(n);
if (proxy_flag) {
emitProxyClassDefAndCPPCasts(n);
String *javaclazzname = Swig_name_member(getNSpace(), proxy_class_name, ""); // mangled full proxy class name
String *javaclazzname = Swig_name_member(getNSpace(), getClassPrefix(), ""); // mangled full proxy class name
Replaceall(proxy_class_def, "$javaclassname", proxy_class_name);
Replaceall(proxy_class_code, "$javaclassname", proxy_class_name);
@ -1988,22 +2057,42 @@ public:
Replaceall(proxy_class_code, "$imclassname", full_imclass_name);
Replaceall(proxy_class_constants_code, "$imclassname", full_imclass_name);
Printv(f_proxy, proxy_class_def, proxy_class_code, NIL);
if (!has_outerclass)
Printv(f_proxy, proxy_class_def, proxy_class_code, NIL);
else {
Swig_offset_string(proxy_class_def, nesting_depth);
Append(old_proxy_class_code, proxy_class_def);
Swig_offset_string(proxy_class_code, nesting_depth);
Append(old_proxy_class_code, proxy_class_code);
}
// Write out all the constants
if (Len(proxy_class_constants_code) != 0)
Printv(f_proxy, proxy_class_constants_code, NIL);
if (Len(proxy_class_constants_code) != 0) {
if (!has_outerclass)
Printv(f_proxy, proxy_class_constants_code, NIL);
else {
Swig_offset_string(proxy_class_constants_code, nesting_depth);
Append(old_proxy_class_code, proxy_class_constants_code);
}
}
Printf(f_proxy, "}\n");
Delete(f_proxy);
f_proxy = NULL;
if (!has_outerclass) {
Printf(f_proxy, "}\n");
Delete(f_proxy);
f_proxy = NULL;
} else {
for (int i = 0; i < nesting_depth; ++i)
Append(old_proxy_class_code, " ");
Append(old_proxy_class_code, "}\n\n");
--nesting_depth;
}
/* Output the downcast method, if necessary. Note: There's no other really
good place to put this code, since Abstract Base Classes (ABCs) can and should have
downcasts, making the constructorHandler() a bad place (because ABCs don't get to
have constructors emitted.) */
if (GetFlag(n, "feature:javadowncast")) {
String *downcast_method = Swig_name_member(getNSpace(), proxy_class_name, "SWIGDowncast");
String *downcast_method = Swig_name_member(getNSpace(), getClassPrefix(), "SWIGDowncast");
String *jniname = makeValidJniName(downcast_method);
String *wname = Swig_name_wrapper(jniname);
@ -2035,17 +2124,21 @@ public:
Delete(javaclazzname);
Delete(proxy_class_name);
proxy_class_name = NULL;
proxy_class_name = old_proxy_class_name;
Delete(full_proxy_class_name);
full_proxy_class_name = NULL;
full_proxy_class_name = old_full_proxy_class_name;
Delete(full_imclass_name);
full_imclass_name = NULL;
full_imclass_name = old_full_imclass_name;
Delete(destructor_call);
destructor_call = NULL;
destructor_call = old_destructor_call;
Delete(destructor_throws_clause);
destructor_throws_clause = NULL;
destructor_throws_clause = old_destructor_throws_clause;
Delete(proxy_class_constants_code);
proxy_class_constants_code = NULL;
proxy_class_constants_code = old_proxy_class_constants_code;
Delete(proxy_class_def);
proxy_class_def = old_proxy_class_def;
Delete(proxy_class_code);
proxy_class_code = old_proxy_class_code;
}
return SWIG_OK;
@ -2061,7 +2154,7 @@ public:
if (proxy_flag) {
String *overloaded_name = getOverloadedName(n);
String *intermediary_function_name = Swig_name_member(getNSpace(), proxy_class_name, overloaded_name);
String *intermediary_function_name = Swig_name_member(getNSpace(), getClassPrefix(), overloaded_name);
Setattr(n, "proxyfuncname", Getattr(n, "sym:name"));
Setattr(n, "imfuncname", intermediary_function_name);
proxyClassFunctionHandler(n);
@ -2083,7 +2176,7 @@ public:
if (proxy_flag) {
String *overloaded_name = getOverloadedName(n);
String *intermediary_function_name = Swig_name_member(getNSpace(), proxy_class_name, overloaded_name);
String *intermediary_function_name = Swig_name_member(getNSpace(), getClassPrefix(), overloaded_name);
Setattr(n, "proxyfuncname", Getattr(n, "sym:name"));
Setattr(n, "imfuncname", intermediary_function_name);
proxyClassFunctionHandler(n);
@ -2159,7 +2252,7 @@ public:
if (wrapping_member_flag && !enum_constant_flag) {
// For wrapping member variables (Javabean setter)
setter_flag = (Cmp(Getattr(n, "sym:name"), Swig_name_set(getNSpace(), Swig_name_member(0, proxy_class_name, variable_name))) == 0);
setter_flag = (Cmp(Getattr(n, "sym:name"), Swig_name_set(getNSpace(), Swig_name_member(0, getClassPrefix(), variable_name))) == 0);
}
/* Start generating the proxy function */
@ -2313,7 +2406,7 @@ public:
Node *explicit_n = Getattr(n, "explicitcallnode");
if (explicit_n) {
String *ex_overloaded_name = getOverloadedName(explicit_n);
String *ex_intermediary_function_name = Swig_name_member(getNSpace(), proxy_class_name, ex_overloaded_name);
String *ex_intermediary_function_name = Swig_name_member(getNSpace(), getClassPrefix(), ex_overloaded_name);
String *ex_imcall = Copy(imcall);
Replaceall(ex_imcall, "$imfuncname", ex_intermediary_function_name);
@ -2885,6 +2978,7 @@ public:
* getEnumName()
*
* If jnidescriptor is set, inner class names are separated with '$' otherwise a '.'
* and the package is also not added to the name.
* ----------------------------------------------------------------------------- */
String *getEnumName(SwigType *t, bool jnidescriptor) {
@ -2899,7 +2993,7 @@ public:
String *scopename_prefix = Swig_scopename_prefix(Getattr(n, "name"));
String *proxyname = 0;
if (scopename_prefix) {
proxyname = getProxyName(scopename_prefix);
proxyname = getProxyName(scopename_prefix, jnidescriptor);
}
if (proxyname) {
const char *class_separator = jnidescriptor ? "$" : ".";
@ -2908,7 +3002,7 @@ public:
// global enum or enum in a namespace
String *nspace = Getattr(n, "sym:nspace");
if (nspace) {
if (package)
if (package && !jnidescriptor)
enumname = NewStringf("%s.%s.%s", package, nspace, symname);
else
enumname = NewStringf("%s.%s", nspace, symname);
@ -2916,8 +3010,8 @@ public:
enumname = Copy(symname);
}
}
if (!jnidescriptor) { // not cached
Setattr(n, "enumname", enumname);
if (!jnidescriptor) {
Setattr(n, "enumname", enumname); // Cache it
Delete(enumname);
}
Delete(scopename_prefix);
@ -2935,10 +3029,11 @@ public:
* that SWIG knows about. Also substitutes enums with enum name.
* Otherwise use the $descriptor name for the Java class name. Note that the $&javaclassname substitution
* is the same as a $&descriptor substitution, ie one pointer added to descriptor name.
* Note that the path separator is a '.' unless jnidescriptor is set.
* Inputs:
* pt - parameter type
* tm - typemap contents that might contain the special variable to be replaced
* jnidescriptor - if set, inner class names are separated with '$' otherwise a '.'
* jnidescriptor - if set, inner class names are separated with '$' otherwise a '/' is used for the path separator
* Outputs:
* tm - typemap contents complete with the special variable substitution
* Return:
@ -2984,25 +3079,40 @@ public:
* ----------------------------------------------------------------------------- */
void substituteClassnameSpecialVariable(SwigType *classnametype, String *tm, const char *classnamespecialvariable, bool jnidescriptor) {
String *replacementname;
if (SwigType_isenum(classnametype)) {
String *enumname = getEnumName(classnametype, jnidescriptor);
if (enumname)
Replaceall(tm, classnamespecialvariable, enumname);
else
Replaceall(tm, classnamespecialvariable, NewStringf("int"));
if (enumname) {
replacementname = Copy(enumname);
} else {
bool anonymous_enum = (Cmp(classnametype, "enum ") == 0);
if (anonymous_enum) {
replacementname = NewString("int");
} else {
// An unknown enum - one that has not been parsed (neither a C enum forward reference nor a definition) or an ignored enum
replacementname = NewStringf("SWIGTYPE%s", SwigType_manglestr(classnametype));
Replace(replacementname, "enum ", "", DOH_REPLACE_ANY);
Setattr(swig_types_hash, replacementname, classnametype);
}
}
} else {
String *classname = getProxyName(classnametype);
String *classname = getProxyName(classnametype, jnidescriptor); // getProxyName() works for pointers to classes too
if (classname) {
Replaceall(tm, classnamespecialvariable, classname); // getProxyName() works for pointers to classes too
} else { // use $descriptor if SWIG does not know anything about this type. Note that any typedefs are resolved.
String *descriptor = NewStringf("SWIGTYPE%s", SwigType_manglestr(classnametype));
Replaceall(tm, classnamespecialvariable, descriptor);
replacementname = Copy(classname);
} else {
// use $descriptor if SWIG does not know anything about this type. Note that any typedefs are resolved.
replacementname = NewStringf("SWIGTYPE%s", SwigType_manglestr(classnametype));
// Add to hash table so that the type wrapper classes can be created later
Setattr(swig_types_hash, descriptor, classnametype);
Delete(descriptor);
Setattr(swig_types_hash, replacementname, classnametype);
}
}
if (jnidescriptor)
Replaceall(replacementname,".","/");
Replaceall(tm, classnamespecialvariable, replacementname);
Delete(replacementname);
}
/* -----------------------------------------------------------------------------
@ -3085,6 +3195,11 @@ public:
Replaceall(swigtype, "$javaclassname", classname);
Replaceall(swigtype, "$module", module_class_name);
Replaceall(swigtype, "$imclassname", imclass_name);
// For unknown enums
Replaceall(swigtype, "$static ", "");
Replaceall(swigtype, "$enumvalues", "");
Printv(f_swigtype, swigtype, NIL);
Delete(f_swigtype);
@ -3388,7 +3503,7 @@ public:
// Output the director connect method:
String *jni_imclass_name = makeValidJniName(imclass_name);
String *norm_name = SwigType_namestr(Getattr(n, "name"));
String *swig_director_connect = Swig_name_member(getNSpace(), proxy_class_name, "director_connect");
String *swig_director_connect = Swig_name_member(getNSpace(), getClassPrefix(), "director_connect");
String *swig_director_connect_jni = makeValidJniName(swig_director_connect);
String *smartptr = Getattr(n, "feature:smartptr");
String *dirClassName = directorClassName(n);
@ -3428,7 +3543,7 @@ public:
Delete(swig_director_connect);
// Output the swigReleaseOwnership, swigTakeOwnership methods:
String *changeown_method_name = Swig_name_member(getNSpace(), proxy_class_name, "change_ownership");
String *changeown_method_name = Swig_name_member(getNSpace(), getClassPrefix(), "change_ownership");
String *changeown_jnimethod_name = makeValidJniName(changeown_method_name);
Printf(imclass_class_code, " public final static native void %s(%s obj, long cptr, boolean take_or_release);\n", changeown_method_name, full_proxy_class_name);
@ -3497,10 +3612,36 @@ public:
// Delete(method_attr);
}
/* -----------------------------------------------------------------------------
* substitutePackagePath()
*
* Replace $packagepath using the javapackage typemap associated with passed
* parm or global package if p is 0. "$packagepath/" is replaced with "" if
* no package is set. Note that the path separator is a '/'.
* ----------------------------------------------------------------------------- */
void substitutePackagePath(String *text, Parm *p) {
String *pkg_path= 0;
if (p)
pkg_path = Swig_typemap_lookup("javapackage", p, "", 0);
if (!pkg_path || Len(pkg_path) == 0)
pkg_path = Copy(package_path);
if (Len(pkg_path) > 0) {
Replaceall(pkg_path, ".", "/");
Replaceall(text, "$packagepath", pkg_path);
} else {
Replaceall(text, "$packagepath/", empty_string);
Replaceall(text, "$packagepath", empty_string);
}
Delete(pkg_path);
}
/* ---------------------------------------------------------------
* Canonicalize the JNI field descriptor
*
* Replace the $javapackage and $javaclassname family of special
* Replace the $packagepath and $javaclassname family of special
* variables with the desired package and Java proxy name as
* required in the JNI field descriptors.
*
@ -3511,27 +3652,11 @@ public:
* --------------------------------------------------------------- */
String *canonicalizeJNIDescriptor(String *descriptor_in, Parm *p) {
String *pkg_path = Swig_typemap_lookup("javapackage", p, "", 0);
SwigType *type = Getattr(p, "type");
if (!pkg_path || Len(pkg_path) == 0)
pkg_path = package_path;
String *descriptor_out = Copy(descriptor_in);
substituteClassname(type, descriptor_out, true);
if (Len(pkg_path) > 0 && Strchr(descriptor_out, '.') == NULL) {
Replaceall(descriptor_out, "$packagepath", pkg_path);
} else {
Replaceall(descriptor_out, "$packagepath/", empty_string);
Replaceall(descriptor_out, "$packagepath", empty_string);
}
Replaceall(descriptor_out, ".", "/");
if (pkg_path != package_path)
Delete(pkg_path);
substitutePackagePath(descriptor_out, p);
return descriptor_out;
}
@ -3928,17 +4053,33 @@ public:
// Get any Java exception classes in the throws typemap
ParmList *throw_parm_list = NULL;
// May need to add Java throws clause to director methods if %catches defined
// Get any Java exception classes in the throws typemap
ParmList *catches_list = Getattr(n, "catchlist");
if (catches_list) {
Swig_typemap_attach_parms("throws", catches_list, 0);
Swig_typemap_attach_parms("directorthrows", catches_list, 0);
for (p = catches_list; p; p = nextSibling(p)) {
addThrows(n, "tmap:throws", p);
}
}
if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) {
int gencomma = 0;
Append(w->def, " throw(");
Append(declaration, " throw(");
if (throw_parm_list)
if (throw_parm_list) {
Swig_typemap_attach_parms("throws", throw_parm_list, 0);
Swig_typemap_attach_parms("directorthrows", throw_parm_list, 0);
}
for (p = throw_parm_list; p; p = nextSibling(p)) {
if (Getattr(p, "tmap:throws")) {
addThrows(n, "tmap:throws", p);
// %catches replaces the specified exception specification
if (!catches_list) {
addThrows(n, "tmap:throws", p);
}
if (gencomma++) {
Append(w->def, ", ");
@ -4001,7 +4142,8 @@ public:
Printf(w->code, "jenv->%s(Swig::jclass_%s, Swig::director_methids[%s], %s);\n", methop, imclass_name, methid, jupcall_args);
Printf(w->code, "if (jenv->ExceptionCheck() == JNI_TRUE) return $null;\n");
// Generate code to handle any Java exception thrown by director delegation
directorExceptHandler(n, catches_list ? catches_list : throw_parm_list, w);
if (!is_void) {
String *jresult_str = NewString("jresult");
@ -4042,7 +4184,8 @@ public:
/* Terminate wrapper code */
Printf(w->code, "} else {\n");
Printf(w->code, "SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, \"null upcall object\");\n");
Printf(w->code, "SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, \"null upcall object in %s::%s \");\n",
SwigType_namestr(c_classname), SwigType_namestr(name));
Printf(w->code, "}\n");
Printf(w->code, "if (swigjobj) jenv->DeleteLocalRef(swigjobj);\n");
@ -4098,6 +4241,61 @@ public:
return status;
}
/* ------------------------------------------------------------
* directorExceptHandler()
*
* Emit code to map Java exceptions back to C++ exceptions when
* feature("director:except") is applied to a method node.
* This is generated after the Java method upcall.
* ------------------------------------------------------------ */
void directorExceptHandler(Node *n, ParmList *throw_parm_list, Wrapper *w) {
String *directorexcept = Getattr(n, "feature:director:except");
if (!directorexcept) {
directorexcept = NewString("");
Printf(directorexcept, "jthrowable $error = jenv->ExceptionOccurred();\n");
Printf(directorexcept, "if ($error) {\n");
Printf(directorexcept, " jenv->ExceptionClear();$directorthrowshandlers\n");
Printf(directorexcept, " throw Swig::DirectorException(jenv, $error);\n");
Printf(directorexcept, "}\n");
} else {
directorexcept = Copy(directorexcept);
}
// Can explicitly disable director:except by setting to "" or "0"
if (Len(directorexcept) > 0 && Cmp(directorexcept, "0") != 0) {
// Replace $packagepath
substitutePackagePath(directorexcept, 0);
// Replace $directorthrowshandlers with any defined typemap handlers (or nothing)
if (Strstr(directorexcept, "$directorthrowshandlers")) {
String *directorthrowshandlers_code = NewString("");
for (Parm *p = throw_parm_list; p; p = nextSibling(p)) {
String *tm = Getattr(p, "tmap:directorthrows");
if (tm) {
// replace $packagepath/$javaclassname
String *directorthrows = canonicalizeJNIDescriptor(tm, p);
Printv(directorthrowshandlers_code, directorthrows, NIL);
Delete(directorthrows);
} else {
String *t = Getattr(p,"type");
Swig_warning(WARN_TYPEMAP_DIRECTORTHROWS_UNDEF, Getfile(n), Getline(n), "No directorthrows typemap defined for %s\n", SwigType_str(t, 0));
}
}
Replaceall(directorexcept, "$directorthrowshandlers", directorthrowshandlers_code);
Delete(directorthrowshandlers_code);
}
Replaceall(directorexcept, "$error", "swigerror");
Printf(w->code, " %s\n", directorexcept);
}
Delete(directorexcept);
}
/* ------------------------------------------------------------
* directorPrefixArgs()
* ------------------------------------------------------------ */
@ -4425,6 +4623,9 @@ public:
Setattr(n, "director:ctor", class_ctor);
}
NestedClassSupport nestedClassesSupport() const {
return NCS_Full;
}
}; /* class JAVA */
/* -----------------------------------------------------------------------------
@ -4442,7 +4643,7 @@ extern "C" Language *swig_java(void) {
* Static member variables
* ----------------------------------------------------------------------------- */
const char *JAVA::usage = (char *) "\
const char *JAVA::usage = "\
Java Options (available with -java)\n\
-nopgcpp - Suppress premature garbage collection prevention parameter\n\
-noproxy - Generate the low-level functional interface instead\n\

File diff suppressed because it is too large Load diff

View file

@ -20,7 +20,7 @@ static int director_mode = 0;
static int director_protected_mode = 1;
static int all_protected_mode = 0;
static int naturalvar_mode = 0;
Language* Language::this_ = 0;
Language *Language::this_ = 0;
/* Set director_protected_mode */
void Wrapper_director_mode_set(int flag) {
@ -137,6 +137,8 @@ int Dispatcher::emit_one(Node *n) {
ret = namespaceDeclaration(n);
} else if (strcmp(tag, "template") == 0) {
ret = templateDeclaration(n);
} else if (strcmp(tag, "lambda") == 0) {
ret = lambdaDeclaration(n);
}
/* ===============================================================
@ -282,6 +284,9 @@ int Dispatcher::classDeclaration(Node *n) {
int Dispatcher::templateDeclaration(Node *n) {
return defaultHandler(n);
}
int Dispatcher::lambdaDeclaration(Node *n) {
return defaultHandler(n);
}
int Dispatcher::classforwardDeclaration(Node *n) {
return defaultHandler(n);
}
@ -314,8 +319,7 @@ overloading(0),
multiinput(0),
cplus_runtime(0),
directors(0) {
Hash *symbols = NewHash();
Setattr(symtabs, "", symbols); // create top level/global symbol table scope
symbolAddScope(""); // create top level/global symbol table scope
argc_template_string = NewString("argc");
argv_template_string = NewString("argv[%d]");
@ -350,7 +354,7 @@ Language::~Language() {
String *dirclassname;
String *nspace = NewString(Getattr(n, "sym:nspace"));
const char *attrib = "director:classname";
String *classname = Getattr(n, "sym:name");
String *classname = getClassPrefix();
Replace(nspace, NSPACE_SEPARATOR, "_", DOH_REPLACE_ANY);
if (Len(nspace) > 0)
@ -468,12 +472,21 @@ void swig_pragma(char *lang, char *name, char *value) {
/* --------------------------------------------------------------------------
* Language::use_naturalvar_mode()
*
* Determine whether to use const ref typemaps instead of pointer typemaps
* for variable access.
* -------------------------------------------------------------------------- */
int Language::use_naturalvar_mode(Node *n) const {
if (Getattr(n, "unnamed"))
return 0;
int nvar = naturalvar_mode || GetFlag(n, "feature:naturalvar");
if (!nvar) {
// The naturalvar feature can be attached to either the variable name or the variable's type
// naturalvar on the variable name is more specific and overrides naturalvar on the variable's type
String *naturalvar = Getattr(n, "feature:naturalvar");
bool explicitly_off = naturalvar && Strcmp(naturalvar, "0") == 0;
int nvar = GetFlag(n, "feature:naturalvar");
if (!explicitly_off && !nvar) {
/* look for feature in the class */
SwigType *ty = Getattr(n, "type");
SwigType *fullty = SwigType_typedef_resolve_all(ty);
@ -485,13 +498,17 @@ int Language::use_naturalvar_mode(Node *n) const {
Replaceall(tys, "class ", "");
}
Node *typenode = Swig_symbol_clookup(tys, 0);
if (typenode)
nvar = GetFlag(typenode, "feature:naturalvar");
if (typenode) {
naturalvar = Getattr(typenode, "feature:naturalvar");
explicitly_off = naturalvar && Strcmp(naturalvar, "0") == 0;
nvar = nvar || GetFlag(typenode, "feature:naturalvar");
}
Delete(tys);
}
Delete(fullty);
}
return nvar ? CWRAP_NATURAL_VAR : 0;
nvar = nvar || naturalvar_mode;
return explicitly_off ? 0 : nvar ? CWRAP_NATURAL_VAR : 0;
}
/* ----------------------------------------------------------------------
@ -506,9 +523,6 @@ int Language::top(Node *n) {
if (Getattr(options, "naturalvar")) {
naturalvar_mode = 1;
}
if (Getattr(options, "nonaturalvar")) {
naturalvar_mode = 0;
}
}
}
classhash = Getattr(n, "classes");
@ -520,15 +534,9 @@ int Language::top(Node *n) {
* ---------------------------------------------------------------------- */
int Language::extendDirective(Node *n) {
int oldam = Extend;
AccessMode oldmode = cplus_mode;
Extend = CWRAP_EXTEND;
cplus_mode = PUBLIC;
save_value<int> oldam(Extend, CWRAP_EXTEND);
save_value<AccessMode> oldmode(cplus_mode, PUBLIC);
emit_children(n);
Extend = oldam;
cplus_mode = oldmode;
return SWIG_OK;
}
@ -951,7 +959,7 @@ int Language::cDeclaration(Node *n) {
if (AddExtern) {
if (f_header) {
if ((Cmp(storage, "extern") == 0) || (ForceExtern && !storage)) {
if (Swig_storage_isextern(n) || (ForceExtern && !storage)) {
/* we don't need the 'extern' part in the C/C++ declaration,
and it produces some problems when namespace and SUN
Studio is used.
@ -981,7 +989,7 @@ int Language::cDeclaration(Node *n) {
}
}
Printf(f_header, ";\n");
} else if (Cmp(storage, "externc") == 0) {
} else if (Swig_storage_isexternc(n)) {
/* here 'extern "C"' is needed */
String *str = SwigType_str(ty, name);
Printf(f_header, "extern \"C\" %s;\n", str);
@ -1010,15 +1018,13 @@ int Language::cDeclaration(Node *n) {
/* Some kind of variable declaration */
String *declaration = Copy(decl);
Delattr(n, "decl");
if (Getattr(n, "nested"))
SetFlag(n, "feature:immutable");
if (!CurrentClass) {
if ((Cmp(storage, "extern") == 0) || ForceExtern) {
f_header = Swig_filebyname("header");
if (Swig_storage_isextern(n) || ForceExtern) {
if (AddExtern) {
f_header = Swig_filebyname("header");
if (f_header) {
String *str = SwigType_str(ty, name);
Printf(f_header, "extern %s;\n", str);
Printf(f_header, "%s %s;\n", Getattr(n, "storage"), str);
Delete(str);
}
}
@ -1054,7 +1060,7 @@ int Language::cDeclaration(Node *n) {
int Language::functionHandler(Node *n) {
String *storage = Getattr(n, "storage");
int isfriend = CurrentClass && Cmp(storage, "friend") == 0;
int isstatic = CurrentClass && Cmp(storage, "static") == 0 && !(SmartPointer && Getattr(n, "allocate:smartpointeraccess"));
int isstatic = CurrentClass && Swig_storage_isstatic(n) && !(SmartPointer && Getattr(n, "allocate:smartpointeraccess"));
Parm *p = Getattr(n, "parms");
if (GetFlag(n, "feature:del")) {
/* the method acts like a delete operator, ie, we need to disown the parameter */
@ -1236,8 +1242,8 @@ int Language::memberfunctionHandler(Node *n) {
String *fname = Swig_name_member(NSpace, ClassPrefix, symname);
if (Extend && SmartPointer) {
if (!Getattr(n, "classname")) {
Setattr(n, "classname", Getattr(CurrentClass, "allocate:smartpointerbase"));
if (!Getattr(n, "extendsmartclassname")) {
Setattr(n, "extendsmartclassname", Getattr(CurrentClass, "allocate:smartpointerpointeeclassname"));
}
}
// Set up the type for the cast to this class for use when wrapping const director (virtual) methods.
@ -1362,7 +1368,6 @@ int Language::variableHandler(Node *n) {
if (!CurrentClass) {
globalvariableHandler(n);
} else {
String *storage = Getattr(n, "storage");
Swig_save("variableHandler", n, "feature:immutable", NIL);
if (SmartPointer) {
/* If a smart-pointer and it's a constant access, we have to set immutable */
@ -1370,7 +1375,7 @@ int Language::variableHandler(Node *n) {
SetFlag(n, "feature:immutable");
}
}
if ((Cmp(storage, "static") == 0) && !(SmartPointer && Getattr(n, "allocate:smartpointeraccess"))) {
if (Swig_storage_isstatic(n) && !(SmartPointer && Getattr(n, "allocate:smartpointeraccess"))) {
staticmembervariableHandler(n);
} else {
membervariableHandler(n);
@ -1424,7 +1429,7 @@ int Language::membervariableHandler(Node *n) {
String *target = 0;
if (!Extend) {
if (SmartPointer) {
if (checkAttribute(n, "storage", "static")) {
if (Swig_storage_isstatic(n)) {
Node *sn = Getattr(n, "cplus:staticbase");
String *base = Getattr(sn, "name");
target = NewStringf("%s::%s", base, name);
@ -1484,6 +1489,7 @@ int Language::membervariableHandler(Node *n) {
Setattr(n, "type", type);
Setattr(n, "name", name);
Setattr(n, "sym:name", symname);
Delattr(n, "memberset");
/* Delete all attached typemaps and typemap attributes */
Iterator ki;
@ -1501,6 +1507,7 @@ int Language::membervariableHandler(Node *n) {
Setattr(n, "sym:name", mrename_get);
Setattr(n, "memberget", "1");
functionWrapper(n);
Delattr(n, "memberget");
}
Delete(mrename_get);
Delete(mrename_set);
@ -1555,7 +1562,7 @@ int Language::membervariableHandler(Node *n) {
int Language::staticmembervariableHandler(Node *n) {
Swig_require("staticmembervariableHandler", n, "*name", "*sym:name", "*type", "?value", NIL);
String *value = Getattr(n, "value");
String *classname = !SmartPointer ? (isNonVirtualProtectedAccess(n) ? DirectorClassName : ClassName) : Getattr(CurrentClass, "allocate:smartpointerbase");
String *classname = !SmartPointer ? (isNonVirtualProtectedAccess(n) ? DirectorClassName : ClassName) : Getattr(CurrentClass, "allocate:smartpointerpointeeclassname");
if (!value || !Getattr(n, "hasconsttype")) {
String *name = Getattr(n, "name");
@ -2358,6 +2365,16 @@ int Language::classDeclaration(Node *n) {
return SWIG_NOWRAP;
}
// save class local variables for nested classes support
int oldInClass = InClass;
String *oldClassType = ClassType;
String *oldClassPrefix = ClassPrefix;
String *oldClassName = ClassName;
String *oldDirectorClassName = DirectorClassName;
String *oldNSpace = NSpace;
Node *oldCurrentClass = CurrentClass;
int dir = 0;
String *kind = Getattr(n, "kind");
String *name = Getattr(n, "name");
String *tdname = Getattr(n, "tdname");
@ -2366,6 +2383,8 @@ int Language::classDeclaration(Node *n) {
int strip = CPlusPlus ? 1 : unnamed && tdname;
if (cplus_mode != PUBLIC)
return SWIG_NOWRAP;
if (!name) {
Swig_warning(WARN_LANG_CLASS_UNNAMED, input_file, line_number, "Can't generate wrappers for unnamed struct/class.\n");
return SWIG_NOWRAP;
@ -2376,15 +2395,21 @@ int Language::classDeclaration(Node *n) {
Swig_warning(WARN_LANG_IDENTIFIER, input_file, line_number, "Can't wrap class %s unless renamed to a valid identifier.\n", SwigType_namestr(symname));
return SWIG_NOWRAP;
}
AccessMode oldAccessMode = cplus_mode;
Node *outerClass = Getattr(n, "nested:outer");
if (outerClass && oldAccessMode != PUBLIC)
return SWIG_NOWRAP;
ClassName = Copy(name);
ClassPrefix = Copy(symname);
if (Cmp(kind, "class") == 0) {
cplus_mode = PRIVATE;
} else {
cplus_mode = PUBLIC;
}
ClassName = Copy(name);
ClassPrefix = Copy(symname);
for (; outerClass; outerClass = Getattr(outerClass, "nested:outer")) {
Push(ClassPrefix, "_");
Push(ClassPrefix, Getattr(outerClass, "sym:name"));
}
if (strip) {
ClassType = Copy(name);
} else {
@ -2395,13 +2420,11 @@ int Language::classDeclaration(Node *n) {
InClass = 1;
CurrentClass = n;
String *oldNSpace = NSpace;
NSpace = Getattr(n, "sym:nspace");
int oldAbstract = Abstract;
/* Call classHandler() here */
if (!ImportMode) {
int dir = 0;
if (directorsEnabled()) {
int ndir = GetFlag(n, "feature:director");
int nndir = GetFlag(n, "feature:nodirector");
@ -2439,25 +2462,29 @@ int Language::classDeclaration(Node *n) {
classDirector(n);
}
/* check for abstract after resolving directors */
Abstract = abstractClassTest(n);
Abstract = abstractClassTest(n);
classHandler(n);
} else {
Abstract = abstractClassTest(n);
Language::classHandler(n);
}
Abstract = oldAbstract;
cplus_mode = oldAccessMode;
NSpace = oldNSpace;
InClass = 0;
CurrentClass = 0;
InClass = oldInClass;
CurrentClass = oldCurrentClass;
Delete(ClassType);
ClassType = 0;
ClassType = oldClassType;
Delete(ClassPrefix);
ClassPrefix = 0;
ClassPrefix = oldClassPrefix;
Delete(ClassName);
ClassName = 0;
Delete(DirectorClassName);
DirectorClassName = 0;
ClassName = oldClassName;
if (dir) {
Delete(DirectorClassName);
}
DirectorClassName = oldDirectorClassName;
return SWIG_OK;
}
@ -2466,7 +2493,9 @@ int Language::classDeclaration(Node *n) {
* ---------------------------------------------------------------------- */
int Language::classHandler(Node *n) {
save_value<int> oldExtend(Extend);
if (Getattr(n, "template"))
Extend = 0;
bool hasDirector = Swig_directorclass(n) ? true : false;
/* Emit all of the class members */
@ -2499,7 +2528,7 @@ int Language::classHandler(Node *n) {
if (dirprot_mode() && extraDirectorProtectedCPPMethodsRequired()) {
Node *vtable = Getattr(n, "vtable");
String *symname = Getattr(n, "sym:name");
AccessMode old_mode = cplus_mode;
save_value<AccessMode> old_mode(cplus_mode);
cplus_mode = PROTECTED;
int len = Len(vtable);
for (int i = 0; i < len; i++) {
@ -2528,7 +2557,6 @@ int Language::classHandler(Node *n) {
}
Delete(wrapname);
}
cplus_mode = old_mode;
}
}
@ -2636,7 +2664,7 @@ int Language::constructorDeclaration(Node *n) {
String *scope = Swig_scopename_check(ClassName) ? Swig_scopename_prefix(ClassName) : 0;
String *actual_name = scope ? NewStringf("%s::%s", scope, name) : NewString(name);
Delete(scope);
if (!Equal(actual_name, expected_name) && !(Getattr(n, "template"))) {
if (!Equal(actual_name, expected_name) && !SwigType_istemplate(expected_name)) {
bool illegal_name = true;
if (Extend) {
// Check for typedef names used as a constructor name in %extend. This is deprecated except for anonymous
@ -2723,7 +2751,7 @@ int Language::constructorHandler(Node *n) {
Setattr(n, "handled_as_constructor", "1");
}
Swig_ConstructorToFunction(n, NSpace, ClassType, none_comparison, director_ctor, CPlusPlus, Getattr(n, "template") ? 0 : Extend);
Swig_ConstructorToFunction(n, NSpace, ClassType, none_comparison, director_ctor, CPlusPlus, Getattr(n, "template") ? 0 : Extend, DirectorClassName);
Setattr(n, "sym:name", mrename);
functionWrapper(n);
Delete(mrename);
@ -2745,7 +2773,7 @@ int Language::copyconstructorHandler(Node *n) {
String *director_ctor = get_director_ctor_code(n, director_ctor_code,
director_prot_ctor_code,
abstracts);
Swig_ConstructorToFunction(n, NSpace, ClassType, none_comparison, director_ctor, CPlusPlus, Getattr(n, "template") ? 0 : Extend);
Swig_ConstructorToFunction(n, NSpace, ClassType, none_comparison, director_ctor, CPlusPlus, Getattr(n, "template") ? 0 : Extend, DirectorClassName);
Setattr(n, "sym:name", mrename);
functionWrapper(n);
Delete(mrename);
@ -2926,11 +2954,14 @@ int Language::constantWrapper(Node *n) {
* ---------------------------------------------------------------------- */
int Language::variableWrapper(Node *n) {
Swig_require("variableWrapper", n, "*name", "*sym:name", "*type", "?parms", NIL);
Swig_require("variableWrapper", n, "*name", "*sym:name", "*type", "?parms", "?varset", "?varget", NIL);
String *symname = Getattr(n, "sym:name");
SwigType *type = Getattr(n, "type");
String *name = Getattr(n, "name");
Delattr(n,"varset");
Delattr(n,"varget");
/* If no way to set variables. We simply create functions */
int assignable = is_assignable(n);
int flags = use_naturalvar_mode(n);
@ -2961,12 +2992,16 @@ int Language::variableWrapper(Node *n) {
Delete(pname0);
}
if (make_set_wrapper) {
Setattr(n, "varset", "1");
functionWrapper(n);
} else {
SetFlag(n, "feature:immutable");
}
/* Restore parameters */
Setattr(n, "sym:name", symname);
Setattr(n, "type", type);
Setattr(n, "name", name);
Delattr(n, "varset");
/* Delete all attached typemaps and typemap attributes */
Iterator ki;
@ -2980,7 +3015,9 @@ int Language::variableWrapper(Node *n) {
String *gname = Swig_name_get(NSpace, symname);
Setattr(n, "sym:name", gname);
Delete(gname);
Setattr(n, "varget", "1");
functionWrapper(n);
Delattr(n, "varget");
Swig_restore(n);
return SWIG_OK;
}
@ -3024,17 +3061,10 @@ void Language::main(int argc, char *argv[]) {
* ----------------------------------------------------------------------------- */
int Language::addSymbol(const String *s, const Node *n, const_String_or_char_ptr scope) {
//Printf( stdout, "addSymbol: %s %s\n", s, scope );
Hash *symbols = Getattr(symtabs, scope ? scope : "");
if (!symbols) {
// New scope which has not been added by the target language - lazily created.
symbols = NewHash();
Setattr(symtabs, scope, symbols);
// Add the new scope as a symbol in the top level scope.
// Alternatively the target language must add it in before attempting to add symbols into the scope.
const_String_or_char_ptr top_scope = "";
Hash *topscope_symbols = Getattr(symtabs, top_scope);
Setattr(topscope_symbols, scope, NewHash());
symbols = symbolAddScope(scope);
} else {
Node *c = Getattr(symbols, s);
if (c && (c != n)) {
@ -3050,6 +3080,70 @@ int Language::addSymbol(const String *s, const Node *n, const_String_or_char_ptr
return 1;
}
/* -----------------------------------------------------------------------------
* Language::symbolAddScope()
*
* Creates a scope (symbols Hash) for given name. This method is auxiliary,
* you don't have to call it - addSymbols will lazily create scopes automatically.
* If scope with given name already exists, then do nothing.
* Returns newly created (or already existing) scope.
* ----------------------------------------------------------------------------- */
Hash* Language::symbolAddScope(const_String_or_char_ptr scope) {
Hash *symbols = symbolScopeLookup(scope);
if(!symbols) {
// The order in which the following code is executed is important. In the Language
// constructor addScope("") is called to create a top level scope.
// Thus we must first add a symbols hash to symtab and only then add pseudo
// symbols to the top-level scope.
// New scope which has not been added by the target language - lazily created.
symbols = NewHash();
Setattr(symtabs, scope, symbols);
// Add the new scope as a symbol in the top level scope.
// Alternatively the target language must add it in before attempting to add symbols into the scope.
const_String_or_char_ptr top_scope = "";
Hash *topscope_symbols = Getattr(symtabs, top_scope);
Hash *pseudo_symbol = NewHash();
Setattr(pseudo_symbol, "sym:scope", "1");
Setattr(topscope_symbols, scope, pseudo_symbol);
}
return symbols;
}
/* -----------------------------------------------------------------------------
* Language::symbolScopeLookup()
*
* Lookup and returns a symtable (hash) representing given scope. Hash contains
* all symbols in this scope.
* ----------------------------------------------------------------------------- */
Hash* Language::symbolScopeLookup( const_String_or_char_ptr scope ) {
Hash *symbols = Getattr(symtabs, scope ? scope : "");
return symbols;
}
/* -----------------------------------------------------------------------------
* Language::symbolScopePseudoSymbolLookup()
*
* For every scope there is a special pseudo-symbol in the top scope (""). It
* exists solely to detect name clashes. This pseudo symbol may contain a few properties,
* but more could be added. This is also true for the top level scope ("").
* It contains a pseudo symbol with name "" (empty). Pseudo symbol contains the
* following properties:
* sym:scope = "1" - a flag that this is a scope pseudo symbol
*
* Pseudo symbols are a Hash*, not a Node*.
* There is no difference from symbolLookup() method except for signature
* and return type.
* ----------------------------------------------------------------------------- */
Hash* Language::symbolScopePseudoSymbolLookup( const_String_or_char_ptr scope )
{
/* Getting top scope */
const_String_or_char_ptr top_scope = "";
Hash *symbols = Getattr(symtabs, top_scope);
return Getattr(symbols, scope);
}
/* -----------------------------------------------------------------------------
* Language::dumpSymbols()
* ----------------------------------------------------------------------------- */
@ -3145,6 +3239,7 @@ Node *Language::classLookup(const SwigType *s) const {
(Len(prefix) == 0) || // simple type (pass by value)
(Strcmp(prefix, "p.") == 0) || // pointer
(Strcmp(prefix, "r.") == 0) || // reference
(Strcmp(prefix, "z.") == 0) || // rvalue reference
SwigType_prefix_is_simple_1D_array(prefix); // Simple 1D array (not arrays of pointers/references)
// Also accept pointer by const reference, not non-const pointer reference
if (!acceptable_prefix && (Strcmp(prefix, "r.p.") == 0)) {
@ -3422,6 +3517,9 @@ bool Language::extraDirectorProtectedCPPMethodsRequired() const {
return true;
}
Language::NestedClassSupport Language::nestedClassesSupport() const {
return NCS_Unknown;
}
/* -----------------------------------------------------------------------------
* Language::is_wrapping_class()
* ----------------------------------------------------------------------------- */

File diff suppressed because it is too large Load diff

View file

@ -49,6 +49,7 @@ int SwigRuntime = 0; // 0 = no option, 1 = -runtime, 2 = -noruntime
extern "C" {
extern String *ModuleName;
extern int ignore_nested_classes;
}
/* usage string split into multiple parts otherwise string is too big for some compilers */
@ -159,9 +160,9 @@ static String *SwigLib = 0; // Library directory
static String *SwigLibWinUnix = 0; // Extra library directory on Windows
static int freeze = 0;
static String *lang_config = 0;
static char *hpp_extension = (char *) "h";
static char *cpp_extension = (char *) "cxx";
static char *depends_extension = (char *) "d";
static const char *hpp_extension = "h";
static const char *cpp_extension = "cxx";
static const char *depends_extension = "d";
static String *outdir = 0;
static String *xmlout = 0;
static int outcurrentdir = 0;
@ -323,7 +324,7 @@ const String *SWIG_output_directory() {
}
void SWIG_config_cppext(const char *ext) {
cpp_extension = (char *) ext;
cpp_extension = ext;
}
List *SWIG_output_files() {
@ -464,7 +465,7 @@ void SWIG_getoptions(int argc, char *argv[]) {
Swig_mark_arg(i);
} else if (strncmp(argv[i], "-D", 2) == 0) {
String *d = NewString(argv[i] + 2);
Replace(d, (char *) "=", (char *) " ", DOH_REPLACE_ANY | DOH_REPLACE_FIRST);
Replace(d, "=", " ", DOH_REPLACE_ANY | DOH_REPLACE_FIRST);
Preprocessor_define((DOH *) d, 0);
Delete(d);
// Create a symbol
@ -483,6 +484,10 @@ void SWIG_getoptions(int argc, char *argv[]) {
Preprocessor_define((DOH *) "__cplusplus __cplusplus", 0);
Swig_cparse_cplusplus(1);
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-c++out") == 0) {
// Undocumented
Swig_cparse_cplusplusout(1);
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-fcompact") == 0) {
Wrapper_compact_print_mode_set(1);
Swig_mark_arg(i);
@ -498,9 +503,6 @@ void SWIG_getoptions(int argc, char *argv[]) {
} else if (strcmp(argv[i], "-naturalvar") == 0) {
Wrapper_naturalvar_mode_set(1);
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-nonaturalvar") == 0) {
Wrapper_naturalvar_mode_set(0);
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-directors") == 0) {
SWIG_setfeature("feature:director", "1");
Wrapper_director_mode_set(1);
@ -855,10 +857,6 @@ void SWIG_getoptions(int argc, char *argv[]) {
}
}
int SWIG_main(int argc, char *argv[], Language *l) {
char *c;
@ -903,6 +901,9 @@ int SWIG_main(int argc, char *argv[], Language *l) {
Wrapper_director_mode_set(0);
Wrapper_director_protected_mode_set(1);
// Inform the parser if the nested classes should be ignored unless explicitly told otherwise via feature:flatnested
ignore_nested_classes = l->nestedClassesSupport() == Language::NCS_Unknown ? 1 : 0;
// Create Library search directories
// Check for SWIG_LIB environment variable
@ -947,6 +948,11 @@ int SWIG_main(int argc, char *argv[], Language *l) {
// Don't check for an input file if -external-runtime is passed
Swig_check_options(external_runtime ? 0 : 1);
if (CPlusPlus && cparse_cplusplusout) {
Printf(stderr, "The -c++out option is for C input but C++ input has been requested via -c++\n");
SWIG_exit(EXIT_FAILURE);
}
install_opts(argc, argv);
// Add language dependent directory to the search path
@ -1161,6 +1167,12 @@ int SWIG_main(int argc, char *argv[], Language *l) {
Printf(stdout, "debug-module stage 1\n");
Swig_print_tree(Getattr(top, "module"));
}
if (!CPlusPlus) {
if (Verbose)
Printf(stdout, "Processing unnamed structs...\n");
Swig_nested_name_unnamed_c_structs(top);
}
Swig_extend_unused_check();
if (Verbose) {
Printf(stdout, "Processing types...\n");
@ -1181,6 +1193,12 @@ int SWIG_main(int argc, char *argv[], Language *l) {
}
Swig_default_allocators(top);
if (CPlusPlus) {
if (Verbose)
Printf(stdout, "Processing nested classes...\n");
Swig_nested_process_classes(top);
}
if (dump_top & STAGE3) {
Printf(stdout, "debug-top stage 3\n");
Swig_print_tree(top);

View file

@ -3956,7 +3956,7 @@ extern "C" Language *swig_modula3(void) {
* Static member variables
* ----------------------------------------------------------------------------- */
const char *MODULA3::usage = (char *) "\
const char *MODULA3::usage = "\
Modula 3 Options (available with -modula3)\n\
-generateconst <file> - Generate code for computing numeric values of constants\n\
-generaterename <file> - Generate suggestions for %rename\n\

View file

@ -15,7 +15,7 @@
#include <ctype.h>
static const char *usage = (char *) "\
static const char *usage = "\
Mzscheme Options (available with -mzscheme)\n\
-declaremodule - Create extension that declares a module\n\
-dynamic-load <library>,[library,...] - Do not link with these libraries, dynamic load\n\
@ -36,7 +36,7 @@ static bool declaremodule = false;
static bool noinit = false;
static String *load_libraries = NULL;
static String *module = 0;
static char *mzscheme_path = (char *) "mzscheme";
static const char *mzscheme_path = "mzscheme";
static String *init_func_def = 0;
static File *f_begin = 0;

449
Source/Modules/nested.cxx Normal file
View file

@ -0,0 +1,449 @@
/* -----------------------------------------------------------------------------
* This file is part of SWIG, which is licensed as a whole under version 3
* (or any later version) of the GNU General Public License. Some additional
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
* and at http://www.swig.org/legal.html.
*
* nested.cxx
*
* Nested structs support
* ----------------------------------------------------------------------------- */
#include "swigmod.h"
#include "cparse.h"
// Nested classes processing section
static Hash *classhash = 0;
static String *make_name(Node *n, String *name, SwigType *decl) {
int destructor = name && (*(Char(name)) == '~');
if (String *yyrename = Getattr(n, "class_rename")) {
String *s = NewString(yyrename);
Delattr(n, "class_rename");
if (destructor && (*(Char(s)) != '~')) {
Insert(s, 0, "~");
}
return s;
}
if (!name)
return 0;
return Swig_name_make(n, 0, name, decl, 0);
}
// C version of add_symbols()
static void add_symbols_c(Node *n) {
String *decl;
String *wrn = 0;
String *symname = 0;
int iscdecl = Cmp(nodeType(n), "cdecl") == 0;
Setattr(n, "ismember", "1");
Setattr(n, "access", "public");
if (Getattr(n, "sym:name"))
return;
decl = Getattr(n, "decl");
if (!SwigType_isfunction(decl)) {
String *name = Getattr(n, "name");
String *makename = Getattr(n, "parser:makename");
if (iscdecl) {
String *storage = Getattr(n, "storage");
if (Cmp(storage, "typedef") == 0) {
Setattr(n, "kind", "typedef");
} else {
SwigType *type = Getattr(n, "type");
String *value = Getattr(n, "value");
Setattr(n, "kind", "variable");
if (value && Len(value)) {
Setattr(n, "hasvalue", "1");
}
if (type) {
SwigType *ty;
SwigType *tmp = 0;
if (decl) {
ty = tmp = Copy(type);
SwigType_push(ty, decl);
} else {
ty = type;
}
if (!SwigType_ismutable(ty)) {
SetFlag(n, "hasconsttype");
SetFlag(n, "feature:immutable");
}
if (tmp)
Delete(tmp);
}
if (!type) {
Printf(stderr, "notype name %s\n", name);
}
}
}
Swig_features_get(Swig_cparse_features(), 0, name, 0, n);
if (makename) {
symname = make_name(n, makename, 0);
Delattr(n, "parser:makename"); /* temporary information, don't leave it hanging around */
} else {
makename = name;
symname = make_name(n, makename, 0);
}
if (!symname) {
symname = Copy(Getattr(n, "unnamed"));
}
if (symname) {
wrn = Swig_name_warning(n, 0, symname, 0);
}
} else {
String *name = Getattr(n, "name");
SwigType *fdecl = Copy(decl);
SwigType *fun = SwigType_pop_function(fdecl);
if (iscdecl) {
Setattr(n, "kind", "function");
}
Swig_features_get(Swig_cparse_features(), 0, name, fun, n);
symname = make_name(n, name, fun);
wrn = Swig_name_warning(n, 0, symname, fun);
Delete(fdecl);
Delete(fun);
}
if (!symname)
return;
if (GetFlag(n, "feature:ignore")) {
/* Only add to C symbol table and continue */
Swig_symbol_add(0, n);
} else if (strncmp(Char(symname), "$ignore", 7) == 0) {
char *c = Char(symname) + 7;
SetFlag(n, "feature:ignore");
if (strlen(c)) {
SWIG_WARN_NODE_BEGIN(n);
Swig_warning(0, Getfile(n), Getline(n), "%s\n", c + 1);
SWIG_WARN_NODE_END(n);
}
Swig_symbol_add(0, n);
} else {
Node *c;
if ((wrn) && (Len(wrn))) {
String *metaname = symname;
if (!Getmeta(metaname, "already_warned")) {
SWIG_WARN_NODE_BEGIN(n);
Swig_warning(0, Getfile(n), Getline(n), "%s\n", wrn);
SWIG_WARN_NODE_END(n);
Setmeta(metaname, "already_warned", "1");
}
}
c = Swig_symbol_add(symname, n);
if (c != n) {
/* symbol conflict attempting to add in the new symbol */
if (Getattr(n, "sym:weak")) {
Setattr(n, "sym:name", symname);
} else {
String *e = NewStringEmpty();
String *en = NewStringEmpty();
String *ec = NewStringEmpty();
int redefined = Swig_need_redefined_warn(n, c, true);
if (redefined) {
Printf(en, "Identifier '%s' redefined (ignored)", symname);
Printf(ec, "previous definition of '%s'", symname);
} else {
Printf(en, "Redundant redeclaration of '%s'", symname);
Printf(ec, "previous declaration of '%s'", symname);
}
if (Cmp(symname, Getattr(n, "name"))) {
Printf(en, " (Renamed from '%s')", SwigType_namestr(Getattr(n, "name")));
}
Printf(en, ",");
if (Cmp(symname, Getattr(c, "name"))) {
Printf(ec, " (Renamed from '%s')", SwigType_namestr(Getattr(c, "name")));
}
Printf(ec, ".");
SWIG_WARN_NODE_BEGIN(n);
if (redefined) {
Swig_warning(WARN_PARSE_REDEFINED, Getfile(n), Getline(n), "%s\n", en);
Swig_warning(WARN_PARSE_REDEFINED, Getfile(c), Getline(c), "%s\n", ec);
} else {
Swig_warning(WARN_PARSE_REDUNDANT, Getfile(n), Getline(n), "%s\n", en);
Swig_warning(WARN_PARSE_REDUNDANT, Getfile(c), Getline(c), "%s\n", ec);
}
SWIG_WARN_NODE_END(n);
Printf(e, "%s:%d:%s\n%s:%d:%s\n", Getfile(n), Getline(n), en, Getfile(c), Getline(c), ec);
Setattr(n, "error", e);
Delete(e);
Delete(en);
Delete(ec);
}
}
}
Delete(symname);
}
/* Strips C-style and C++-style comments from string in-place. */
static void strip_comments(char *string) {
int state = 0;
/*
* 0 - not in comment
* 1 - in c-style comment
* 2 - in c++-style comment
* 3 - in string
* 4 - after reading / not in comments
* 5 - after reading * in c-style comments
* 6 - after reading \ in strings
*/
char *c = string;
while (*c) {
switch (state) {
case 0:
if (*c == '\"')
state = 3;
else if (*c == '/')
state = 4;
break;
case 1:
if (*c == '*')
state = 5;
*c = ' ';
break;
case 2:
if (*c == '\n')
state = 0;
else
*c = ' ';
break;
case 3:
if (*c == '\"')
state = 0;
else if (*c == '\\')
state = 6;
break;
case 4:
if (*c == '/') {
*(c - 1) = ' ';
*c = ' ';
state = 2;
} else if (*c == '*') {
*(c - 1) = ' ';
*c = ' ';
state = 1;
} else
state = 0;
break;
case 5:
if (*c == '/')
state = 0;
else
state = 1;
*c = ' ';
break;
case 6:
state = 3;
break;
}
++c;
}
}
// Create a %insert with a typedef to make a new name visible to C
static Node *create_insert(Node *n, bool noTypedef = false) {
// format a typedef
String *ccode = Getattr(n, "code");
Push(ccode, " ");
if (noTypedef) {
Push(ccode, Getattr(n, "name"));
Push(ccode, " ");
Push(ccode, Getattr(n, "kind"));
} else {
Push(ccode, Getattr(n, "kind"));
Push(ccode, "typedef ");
Append(ccode, " ");
Append(ccode, Getattr(n, "tdname"));
}
Append(ccode, ";");
/* Strip comments - further code may break in presence of comments. */
strip_comments(Char(ccode));
/* Make all SWIG created typedef structs/unions/classes unnamed else
redefinition errors occur - nasty hack alert. */
if (!noTypedef) {
const char *types_array[3] = { "struct", "union", "class" };
for (int i = 0; i < 3; i++) {
char *code_ptr = Char(ccode);
while (code_ptr) {
/* Replace struct name (as in 'struct name {...}' ) with whitespace
name will be between struct and opening brace */
code_ptr = strstr(code_ptr, types_array[i]);
if (code_ptr) {
char *open_bracket_pos;
code_ptr += strlen(types_array[i]);
open_bracket_pos = strchr(code_ptr, '{');
if (open_bracket_pos) {
/* Make sure we don't have something like struct A a; */
char *semi_colon_pos = strchr(code_ptr, ';');
if (!(semi_colon_pos && (semi_colon_pos < open_bracket_pos)))
while (code_ptr < open_bracket_pos)
*code_ptr++ = ' ';
}
}
}
}
}
{
/* Remove SWIG directive %constant which may be left in the SWIG created typedefs */
char *code_ptr = Char(ccode);
while (code_ptr) {
code_ptr = strstr(code_ptr, "%constant");
if (code_ptr) {
char *directive_end_pos = strchr(code_ptr, ';');
if (directive_end_pos) {
while (code_ptr <= directive_end_pos)
*code_ptr++ = ' ';
}
}
}
}
Node *newnode = NewHash();
set_nodeType(newnode, "insert");
Setfile(newnode, Getfile(n));
Setline(newnode, Getline(n));
String *code = NewStringEmpty();
Wrapper_pretty_print(ccode, code);
Setattr(newnode, "code", code);
Delete(code);
Delattr(n, "code");
return newnode;
}
static void insertNodeAfter(Node *n, Node *c) {
Node *g = parentNode(n);
set_parentNode(c, g);
Node *ns = nextSibling(n);
if (Node *outer = Getattr(c, "nested:outer")) {
while (ns && outer == Getattr(ns, "nested:outer")) {
n = ns;
ns = nextSibling(n);
}
}
if (!ns) {
set_lastChild(g, c);
} else {
set_nextSibling(c, ns);
set_previousSibling(ns, c);
}
set_nextSibling(n, c);
set_previousSibling(c, n);
}
void Swig_nested_name_unnamed_c_structs(Node *n) {
if (!classhash)
classhash = Getattr(n, "classes");
Node *c = firstChild(n);
while (c) {
Node *next = nextSibling(c);
if (String *declName = Getattr(c, "nested:unnamed")) {
if (Node *outer = Getattr(c, "nested:outer")) {
// generate a name
String *name = NewStringf("%s_%s", Getattr(outer, "name"), declName);
Delattr(c, "nested:unnamed");
// set the name to the class and symbol table
Setattr(c, "tdname", name);
Setattr(c, "name", name);
Swig_symbol_setscope(Getattr(c, "symtab"));
Swig_symbol_setscopename(name);
// now that we have a name - gather base symbols
if (List *publicBases = Getattr(c, "baselist")) {
List *bases = Swig_make_inherit_list(name, publicBases, 0);
Swig_inherit_base_symbols(bases);
Delete(bases);
}
Setattr(classhash, name, c);
// Merge the extension into the symbol table
if (Node *am = Getattr(Swig_extend_hash(), name)) {
Swig_extend_merge(c, am);
Swig_extend_append_previous(c, am);
Delattr(Swig_extend_hash(), name);
}
Swig_symbol_popscope();
// process declarations following this type (assign correct new type)
SwigType *ty = Copy(name);
Node *decl = nextSibling(c);
List *declList = NewList();
while (decl && Getattr(decl, "nested:unnamedtype") == c) {
Setattr(decl, "type", ty);
Append(declList, decl);
Delattr(decl, "nested:unnamedtype");
SetFlag(decl, "feature:immutable");
add_symbols_c(decl);
decl = nextSibling(decl);
}
Delete(ty);
Swig_symbol_setscope(Swig_symbol_global_scope());
add_symbols_c(c);
Node *ins = create_insert(c);
insertNodeAfter(c, ins);
removeNode(c);
insertNodeAfter(n, c);
Delete(ins);
Delattr(c, "nested:outer");
} else {
// global unnamed struct - ignore it and it's instances
SetFlag(c, "feature:ignore");
while (next && Getattr(next, "nested:unnamedtype") == c) {
SetFlag(next, "feature:ignore");
next = nextSibling(next);
}
c = next;
continue;
}
} else if (cparse_cplusplusout) {
if (Getattr(c, "nested:outer")) {
Node *ins = create_insert(c, true);
insertNodeAfter(c, ins);
Delete(ins);
Delattr(c, "nested:outer");
}
}
// process children
Swig_nested_name_unnamed_c_structs(c);
c = next;
}
}
static void remove_outer_class_reference(Node *n) {
for (Node *c = firstChild(n); c; c = nextSibling(c)) {
if (GetFlag(c, "feature:flatnested") || Language::instance()->nestedClassesSupport() == Language::NCS_None) {
Delattr(c, "nested:outer");
remove_outer_class_reference(c);
}
}
}
void Swig_nested_process_classes(Node *n) {
Node *c = firstChild(n);
while (c) {
Node *next = nextSibling(c);
if (!Getattr(c, "templatetype")) {
if (GetFlag(c, "nested") && (GetFlag(c, "feature:flatnested") || Language::instance()->nestedClassesSupport() == Language::NCS_None)) {
removeNode(c);
if (!checkAttribute(c, "access", "public"))
SetFlag(c, "feature:ignore");
else if (Strcmp(nodeType(n),"extend") == 0 && Strcmp(nodeType(parentNode(n)),"class") == 0)
insertNodeAfter(parentNode(n), c);
else
insertNodeAfter(n, c);
}
Swig_nested_process_classes(c);
}
c = next;
}
remove_outer_class_reference(n);
}

View file

@ -15,7 +15,7 @@
#include <ctype.h>
static const char *usage = (char *) "\
static const char *usage = "\
Ocaml Options (available with -ocaml)\n\
-oldvarnames - Old intermediary method names for variable wrappers\n\
-prefix <name> - Set a prefix <name> to be prepended to all names\n\
@ -29,7 +29,7 @@ static int const_enum = 0;
static int static_member_function = 0;
static int generate_sizeof = 0;
static String *prefix = 0;
static char *ocaml_path = (char *) "ocaml";
static const char *ocaml_path = "ocaml";
static bool old_variable_names = false;
static String *classname = 0;
static String *module = 0;

View file

@ -1,5 +1,5 @@
/* -----------------------------------------------------------------------------
* This file is part of SWIG, which is licensed as a whole under version 3
* This file is part of SWIG, which is licensed as a whole under version 3
* (or any later version) of the GNU General Public License. Some additional
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
@ -12,11 +12,12 @@
* ----------------------------------------------------------------------------- */
#include "swigmod.h"
#include "cparse.h"
static String *global_name = 0;
static String *op_prefix = 0;
static const char *usage = (char *) "\
static const char *usage = "\
Octave Options (available with -octave)\n\
-globals <name> - Set <name> used to access C global variables [default: 'cvar']\n\
Use '.' to load C global variables into module namespace\n\
@ -74,51 +75,44 @@ public:
constructor_name(0),
docs(0)
{
/* Add code to manage protected constructors and directors */
director_prot_ctor_code = NewString("");
Printv(director_prot_ctor_code,
"if ( $comparison ) { /* subclassed */\n",
" $director_new \n",
"} else {\n", " error(\"accessing abstract class or protected constructor\"); \n", " SWIG_fail;\n", "}\n", NIL);
/* Add code to manage protected constructors and directors */
director_prot_ctor_code = NewString("");
Printv(director_prot_ctor_code,
"if ( $comparison ) { /* subclassed */\n",
" $director_new \n",
"} else {\n", " error(\"accessing abstract class or protected constructor\"); \n", " SWIG_fail;\n", "}\n", NIL);
enable_cplus_runtime_mode();
allow_overloading();
director_multiple_inheritance = 1;
director_language = 1;
docs = NewHash();
}
enable_cplus_runtime_mode();
allow_overloading();
director_multiple_inheritance = 1;
director_language = 1;
docs = NewHash();
}
virtual void main(int argc, char *argv[]) {
for (int i = 1; i < argc; i++) {
if (argv[i]) {
if (strcmp(argv[i], "-help") == 0) {
fputs(usage, stdout);
} else if (strcmp(argv[i], "-global") == 0 ||
strcmp(argv[i], "-noglobal") == 0) {
Printv(stderr,
"*** -global/-noglobal are no longer supported\n"
"*** global load behaviour is now determined at module load\n"
"*** see the Perl section in the manual for details.\n", NIL);
SWIG_exit(EXIT_FAILURE);
} else if (strcmp(argv[i], "-globals") == 0) {
if (argv[i + 1]) {
global_name = NewString(argv[i + 1]);
Swig_mark_arg(i);
Swig_mark_arg(i + 1);
i++;
} else {
Swig_arg_error();
}
} else if (strcmp(argv[i], "-opprefix") == 0) {
if (argv[i + 1]) {
op_prefix = NewString(argv[i + 1]);
Swig_mark_arg(i);
Swig_mark_arg(i + 1);
i++;
} else {
Swig_arg_error();
}
}
if (strcmp(argv[i], "-help") == 0) {
fputs(usage, stdout);
} else if (strcmp(argv[i], "-globals") == 0) {
if (argv[i + 1]) {
global_name = NewString(argv[i + 1]);
Swig_mark_arg(i);
Swig_mark_arg(i + 1);
i++;
} else {
Swig_arg_error();
}
} else if (strcmp(argv[i], "-opprefix") == 0) {
if (argv[i + 1]) {
op_prefix = NewString(argv[i + 1]);
Swig_mark_arg(i);
Swig_mark_arg(i + 1);
i++;
} else {
Swig_arg_error();
}
}
}
}
@ -132,27 +126,31 @@ public:
SWIG_config_file("octave.swg");
SWIG_typemap_lang("octave");
allow_overloading();
// Octave API is C++, so output must be C++ compatibile even when wrapping C code
if (!cparse_cplusplus)
Swig_cparse_cplusplusout(1);
}
virtual int top(Node *n) {
{
Node *mod = Getattr(n, "module");
if (mod) {
Node *options = Getattr(mod, "options");
if (options) {
int dirprot = 0;
if (Getattr(options, "dirprot")) {
dirprot = 1;
}
if (Getattr(options, "nodirprot")) {
dirprot = 0;
}
if (Getattr(options, "directors")) {
allow_directors();
if (dirprot)
allow_dirprot();
}
}
Node *options = Getattr(mod, "options");
if (options) {
int dirprot = 0;
if (Getattr(options, "dirprot")) {
dirprot = 1;
}
if (Getattr(options, "nodirprot")) {
dirprot = 0;
}
if (Getattr(options, "directors")) {
allow_directors();
if (dirprot)
allow_dirprot();
}
}
}
}
@ -197,8 +195,8 @@ public:
Printf(f_runtime, "#define SWIG_DIRECTORS\n");
Swig_banner(f_directors_h);
if (dirprot_mode()) {
// Printf(f_directors_h, "#include <map>\n");
// Printf(f_directors_h, "#include <string>\n\n");
// Printf(f_directors_h, "#include <map>\n");
// Printf(f_directors_h, "#include <string>\n\n");
}
}
@ -258,19 +256,19 @@ public:
String *r = NewString("");
for (int j=0;s[j];++j) {
if (s[j] == '\n') {
Append(r, "\\n\\\n");
Append(r, "\\n\\\n");
} else if (s[j] == '\r') {
Append(r, "\\r");
Append(r, "\\r");
} else if (s[j] == '\t') {
Append(r, "\\t");
Append(r, "\\t");
} else if (s[j] == '\\') {
Append(r, "\\\\");
Append(r, "\\\\");
} else if (s[j] == '\'') {
Append(r, "\\\'");
Append(r, "\\\'");
} else if (s[j] == '\"') {
Append(r, "\\\"");
Append(r, "\\\"");
} else
Putc(s[j], r);
Putc(s[j], r);
}
return r;
}
@ -288,11 +286,11 @@ public:
String *escaped_doc_str = texinfo_escape(doc_str);
if (Len(doc_str)>0) {
Printf(f_doc,"static const char* %s_texinfo = ",wrap_name);
Printf(f_doc,"\"-*- texinfo -*-\\n\\\n%s", escaped_doc_str);
if (Len(decl_info))
Printf(f_doc,"\\n\\\n@end deftypefn");
Printf(f_doc,"\";\n");
Printf(f_doc,"static const char* %s_texinfo = ",wrap_name);
Printf(f_doc,"\"-*- texinfo -*-\\n\\\n%s", escaped_doc_str);
if (Len(decl_info))
Printf(f_doc,"\\n\\\n@end deftypefn");
Printf(f_doc,"\";\n");
}
Delete(escaped_doc_str);
@ -308,7 +306,7 @@ public:
String *decl_info = Getattr(n, "decl_info");
String *cdecl_info = Getattr(n, "cdecl_info");
String *args_info = Getattr(n, "args_info");
return !Len(synopsis) && !Len(decl_info) &&
return !Len(synopsis) && !Len(decl_info) &&
!Len(cdecl_info) && !Len(args_info);
}
String *texinfo_name(Node* n, const char* defval = "0") {
@ -355,11 +353,11 @@ public:
SwigType *type = Getattr(n, "type");
if (type && Strcmp(type, "void")) {
Node *nn = classLookup(Getattr(n, "type"));
String *type_str = nn ? Copy(Getattr(nn, "sym:name")) : SwigType_str(type, 0);
Append(decl_info, "@var{retval} = ");
Printf(args_str, "%s@var{retval} is of type %s. ", args_str, type_str);
Delete(type_str);
Node *nn = classLookup(Getattr(n, "type"));
String *type_str = nn ? Copy(Getattr(nn, "sym:name")) : SwigType_str(type, 0);
Append(decl_info, "@var{retval} = ");
Printf(args_str, "%s@var{retval} is of type %s. ", args_str, type_str);
Delete(type_str);
}
Append(decl_info, name);
@ -375,8 +373,8 @@ public:
// strip off {} if necessary
char *t = Char(str);
if (*t == '{') {
Delitem(str, 0);
Delitem(str, DOH_END);
Delitem(str, 0);
Delitem(str, DOH_END);
}
// emit into synopsis section
@ -403,7 +401,7 @@ public:
* addMissingParameterNames()
* For functions that have not had nameless parameters set in the Language class.
*
* Inputs:
* Inputs:
* plist - entire parameter list
* arg_offset - argument number for first parameter
* Side effects:
@ -415,8 +413,8 @@ public:
int i = arg_offset;
while (p) {
if (!Getattr(p, "lname")) {
String *pname = Swig_cparm_name(p, i);
Delete(pname);
String *pname = Swig_cparm_name(p, i);
Delete(pname);
}
i++;
p = nextSibling(p);
@ -439,12 +437,12 @@ public:
String *tm = Getattr(p, "tmap:in");
if (tm) {
pnext = Getattr(p, "tmap:in:next");
if (checkAttribute(p, "tmap:in:numinputs", "0")) {
continue;
}
pnext = Getattr(p, "tmap:in:next");
if (checkAttribute(p, "tmap:in:numinputs", "0")) {
continue;
}
} else {
pnext = nextSibling(p);
pnext = nextSibling(p);
}
String *name = 0;
@ -452,9 +450,9 @@ public:
String *value = 0;
String *pdoc = Getattr(p, "tmap:doc");
if (pdoc) {
name = Getattr(p, "tmap:doc:name");
type = Getattr(p, "tmap:doc:type");
value = Getattr(p, "tmap:doc:value");
name = Getattr(p, "tmap:doc:name");
type = Getattr(p, "tmap:doc:type");
value = Getattr(p, "tmap:doc:value");
}
// Note: the generated name should be consistent with that in kwnames[]
@ -466,28 +464,28 @@ public:
value = value ? value : Getattr(p, "value");
if (SwigType_isvarargs(type))
break;
break;
String *tex_name = NewString("");
if (name)
Printf(tex_name, "@var{%s}", name);
Printf(tex_name, "@var{%s}", name);
else
Printf(tex_name, "@var{?}");
Printf(tex_name, "@var{?}");
if (Len(decl_str))
Append(decl_str, ", ");
Append(decl_str, ", ");
Append(decl_str, tex_name);
if (value) {
String *new_value = convertValue(value, Getattr(p, "type"));
if (new_value) {
value = new_value;
} else {
Node *lookup = Swig_symbol_clookup(value, 0);
if (lookup)
value = Getattr(lookup, "sym:name");
}
Printf(decl_str, " = %s", value);
String *new_value = convertValue(value, Getattr(p, "type"));
if (new_value) {
value = new_value;
} else {
Node *lookup = Swig_symbol_clookup(value, 0);
if (lookup)
value = Getattr(lookup, "sym:name");
}
Printf(decl_str, " = %s", value);
}
Node *nn = classLookup(Getattr(p, "type"));
@ -512,18 +510,18 @@ public:
if (v && Len(v) > 0) {
char fc = (Char(v))[0];
if (('0' <= fc && fc <= '9') || '\'' == fc || '"' == fc) {
/* number or string (or maybe NULL pointer) */
if (SwigType_ispointer(t) && Strcmp(v, "0") == 0)
return NewString("None");
else
return v;
/* number or string (or maybe NULL pointer) */
if (SwigType_ispointer(t) && Strcmp(v, "0") == 0)
return NewString("None");
else
return v;
}
if (Strcmp(v, "NULL") == 0)
return SwigType_ispointer(t) ? NewString("nil") : NewString("0");
if (Strcmp(v, "NULL") == 0 || Strcmp(v, "nullptr") == 0)
return SwigType_ispointer(t) ? NewString("nil") : NewString("0");
if (Strcmp(v, "true") == 0 || Strcmp(v, "TRUE") == 0)
return NewString("true");
return NewString("true");
if (Strcmp(v, "false") == 0 || Strcmp(v, "FALSE") == 0)
return NewString("false");
return NewString("false");
}
return 0;
}
@ -567,89 +565,89 @@ public:
int varargs = emit_isvarargs(l);
char source[64];
Printf(f->code, "if (!SWIG_check_num_args(\"%s\",args.length(),%i,%i,%i)) "
"{\n SWIG_fail;\n }\n", iname, num_arguments, num_required, varargs);
Printf(f->code, "if (!SWIG_check_num_args(\"%s\",args.length(),%i,%i,%i)) "
"{\n SWIG_fail;\n }\n", iname, num_arguments, num_required, varargs);
if (constructor && num_arguments == 1 && num_required == 1) {
if (Cmp(storage, "explicit") == 0) {
Node *parent = Swig_methodclass(n);
if (GetFlag(parent, "feature:implicitconv")) {
String *desc = NewStringf("SWIGTYPE%s", SwigType_manglestr(Getattr(n, "type")));
Printf(f->code, "if (SWIG_CheckImplicit(%s)) SWIG_fail;\n", desc);
Delete(desc);
}
Node *parent = Swig_methodclass(n);
if (GetFlag(parent, "feature:implicitconv")) {
String *desc = NewStringf("SWIGTYPE%s", SwigType_manglestr(Getattr(n, "type")));
Printf(f->code, "if (SWIG_CheckImplicit(%s)) SWIG_fail;\n", desc);
Delete(desc);
}
}
}
for (j = 0, p = l; j < num_arguments; ++j) {
while (checkAttribute(p, "tmap:in:numinputs", "0")) {
p = Getattr(p, "tmap:in:next");
p = Getattr(p, "tmap:in:next");
}
SwigType *pt = Getattr(p, "type");
String *tm = Getattr(p, "tmap:in");
if (tm) {
if (!tm || checkAttribute(p, "tmap:in:numinputs", "0")) {
p = nextSibling(p);
continue;
}
if (!tm || checkAttribute(p, "tmap:in:numinputs", "0")) {
p = nextSibling(p);
continue;
}
sprintf(source, "args(%d)", j);
Setattr(p, "emit:input", source);
sprintf(source, "args(%d)", j);
Setattr(p, "emit:input", source);
Replaceall(tm, "$source", Getattr(p, "emit:input"));
Replaceall(tm, "$input", Getattr(p, "emit:input"));
Replaceall(tm, "$target", Getattr(p, "lname"));
Replaceall(tm, "$source", Getattr(p, "emit:input"));
Replaceall(tm, "$input", Getattr(p, "emit:input"));
Replaceall(tm, "$target", Getattr(p, "lname"));
if (Getattr(p, "wrap:disown") || (Getattr(p, "tmap:in:disown"))) {
Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN");
} else {
Replaceall(tm, "$disown", "0");
}
if (Getattr(p, "wrap:disown") || (Getattr(p, "tmap:in:disown"))) {
Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN");
} else {
Replaceall(tm, "$disown", "0");
}
if (Getattr(p, "tmap:in:implicitconv")) {
const char *convflag = "0";
if (!Getattr(p, "hidden")) {
SwigType *ptype = Getattr(p, "type");
convflag = get_implicitconv_flag(classLookup(ptype));
}
Replaceall(tm, "$implicitconv", convflag);
Setattr(p, "implicitconv", convflag);
}
if (Getattr(p, "tmap:in:implicitconv")) {
const char *convflag = "0";
if (!Getattr(p, "hidden")) {
SwigType *ptype = Getattr(p, "type");
convflag = get_implicitconv_flag(classLookup(ptype));
}
Replaceall(tm, "$implicitconv", convflag);
Setattr(p, "implicitconv", convflag);
}
String *getargs = NewString("");
if (j >= num_required)
Printf(getargs, "if (%d<args.length()) {\n%s\n}", j, tm);
else
Printv(getargs, tm, NIL);
Printv(f->code, getargs, "\n", NIL);
Delete(getargs);
String *getargs = NewString("");
if (j >= num_required)
Printf(getargs, "if (%d<args.length()) {\n%s\n}", j, tm);
else
Printv(getargs, tm, NIL);
Printv(f->code, getargs, "\n", NIL);
Delete(getargs);
p = Getattr(p, "tmap:in:next");
continue;
p = Getattr(p, "tmap:in:next");
continue;
} else {
Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0));
break;
Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0));
break;
}
}
// Check for trailing varargs
if (varargs) {
if (p && (tm = Getattr(p, "tmap:in"))) {
Replaceall(tm, "$input", "varargs");
Printv(f->code, tm, "\n", NIL);
Replaceall(tm, "$input", "varargs");
Printv(f->code, tm, "\n", NIL);
}
}
// Insert constraint checking code
for (p = l; p;) {
if ((tm = Getattr(p, "tmap:check"))) {
Replaceall(tm, "$target", Getattr(p, "lname"));
Printv(f->code, tm, "\n", NIL);
p = Getattr(p, "tmap:check:next");
Replaceall(tm, "$target", Getattr(p, "lname"));
Printv(f->code, tm, "\n", NIL);
p = Getattr(p, "tmap:check:next");
} else {
p = nextSibling(p);
p = nextSibling(p);
}
}
@ -657,23 +655,23 @@ public:
String *cleanup = NewString("");
for (p = l; p;) {
if ((tm = Getattr(p, "tmap:freearg"))) {
if (Getattr(p, "tmap:freearg:implicitconv")) {
const char *convflag = "0";
if (!Getattr(p, "hidden")) {
SwigType *ptype = Getattr(p, "type");
convflag = get_implicitconv_flag(classLookup(ptype));
}
if (strcmp(convflag, "0") == 0) {
tm = 0;
}
}
if (tm && (Len(tm) != 0)) {
Replaceall(tm, "$source", Getattr(p, "lname"));
Printv(cleanup, tm, "\n", NIL);
}
p = Getattr(p, "tmap:freearg:next");
if (Getattr(p, "tmap:freearg:implicitconv")) {
const char *convflag = "0";
if (!Getattr(p, "hidden")) {
SwigType *ptype = Getattr(p, "type");
convflag = get_implicitconv_flag(classLookup(ptype));
}
if (strcmp(convflag, "0") == 0) {
tm = 0;
}
}
if (tm && (Len(tm) != 0)) {
Replaceall(tm, "$source", Getattr(p, "lname"));
Printv(cleanup, tm, "\n", NIL);
}
p = Getattr(p, "tmap:freearg:next");
} else {
p = nextSibling(p);
p = nextSibling(p);
}
}
@ -681,15 +679,15 @@ public:
String *outarg = NewString("");
for (p = l; p;) {
if ((tm = Getattr(p, "tmap:argout"))) {
Replaceall(tm, "$source", Getattr(p, "lname"));
Replaceall(tm, "$target", "_outp");
Replaceall(tm, "$result", "_outp");
Replaceall(tm, "$arg", Getattr(p, "emit:input"));
Replaceall(tm, "$input", Getattr(p, "emit:input"));
Printv(outarg, tm, "\n", NIL);
p = Getattr(p, "tmap:argout:next");
Replaceall(tm, "$source", Getattr(p, "lname"));
Replaceall(tm, "$target", "_outp");
Replaceall(tm, "$result", "_outp");
Replaceall(tm, "$arg", Getattr(p, "emit:input"));
Replaceall(tm, "$input", Getattr(p, "emit:input"));
Printv(outarg, tm, "\n", NIL);
p = Getattr(p, "tmap:argout:next");
} else {
p = nextSibling(p);
p = nextSibling(p);
}
}
@ -715,9 +713,9 @@ public:
Replaceall(tm, "$result", "_outv");
if (GetFlag(n, "feature:new"))
Replaceall(tm, "$owner", "1");
Replaceall(tm, "$owner", "1");
else
Replaceall(tm, "$owner", "0");
Replaceall(tm, "$owner", "0");
Printf(f->code, "%s\n", tm);
Printf(f->code, "if (_outv.is_defined()) _outp = " "SWIG_Octave_AppendOutput(_outp, _outv);\n");
@ -732,8 +730,8 @@ public:
if (GetFlag(n, "feature:new")) {
if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) {
Replaceall(tm, "$source", Swig_cresult_name());
Printf(f->code, "%s\n", tm);
Replaceall(tm, "$source", Swig_cresult_name());
Printf(f->code, "%s\n", tm);
}
}
@ -825,16 +823,16 @@ public:
if (is_assignable(n)) {
Setattr(n, "wrap:name", setname);
if ((tm = Swig_typemap_lookup("varin", n, name, 0))) {
Replaceall(tm, "$source", "args(0)");
Replaceall(tm, "$target", name);
Replaceall(tm, "$input", "args(0)");
if (Getattr(n, "tmap:varin:implicitconv")) {
Replaceall(tm, "$implicitconv", get_implicitconv_flag(n));
}
emit_action_code(n, setf->code, tm);
Delete(tm);
Replaceall(tm, "$source", "args(0)");
Replaceall(tm, "$target", name);
Replaceall(tm, "$input", "args(0)");
if (Getattr(n, "tmap:varin:implicitconv")) {
Replaceall(tm, "$implicitconv", get_implicitconv_flag(n));
}
emit_action_code(n, setf->code, tm);
Delete(tm);
} else {
Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(t, 0));
Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(t, 0));
}
Append(setf->code, "fail:\n");
Printf(setf->code, "return octave_value_list();\n");
@ -990,18 +988,18 @@ public:
int index = 0;
b = First(baselist);
while (b.item) {
String *bname = Getattr(b.item, "name");
if ((!bname) || GetFlag(b.item, "feature:ignore") || (!Getattr(b.item, "module"))) {
b = Next(b);
continue;
}
String *bname = Getattr(b.item, "name");
if ((!bname) || GetFlag(b.item, "feature:ignore") || (!Getattr(b.item, "module"))) {
b = Next(b);
continue;
}
String *bname_mangled = SwigType_manglestr(SwigType_add_pointer(Copy(bname)));
Printf(base_class_names, "\"%s\",", bname_mangled);
Printf(base_class, "0,");
b = Next(b);
index++;
Delete(bname_mangled);
String *bname_mangled = SwigType_manglestr(SwigType_add_pointer(Copy(bname)));
Printf(base_class_names, "\"%s\",", bname_mangled);
Printf(base_class, "0,");
b = Next(b);
index++;
Delete(bname_mangled);
}
}
@ -1058,8 +1056,8 @@ public:
bool overloaded = !!Getattr(n, "sym:overloaded");
if (overloaded)
Delslice(rname, Len(rname) - Len(Getattr(n, "sym:overname")), DOH_END);
Printf(s_members_tab, "{\"%s\",%s,0,0,0,%s},\n",
realname, rname, tname);
Printf(s_members_tab, "{\"%s\",%s,0,0,0,%s},\n",
realname, rname, tname);
Delete(rname);
Delete(tname);
}
@ -1107,7 +1105,7 @@ public:
Delete(name);
Setattr(self, "lname", "self_obj");
if (parms)
set_nextSibling(self, parms);
set_nextSibling(self, parms);
Setattr(n, "parms", self);
Setattr(n, "wrap:self", "1");
Setattr(n, "hidden", "1");
@ -1139,12 +1137,12 @@ public:
bool overloaded = !!Getattr(n, "sym:overloaded");
if (overloaded)
Delslice(rname, Len(rname) - Len(Getattr(n, "sym:overname")), DOH_END);
Printf(s_members_tab, "{\"%s\",%s,0,0,1,%s},\n",
realname, rname, tname);
Printf(s_members_tab, "{\"%s\",%s,0,0,1,%s},\n",
realname, rname, tname);
Delete(rname);
Delete(tname);
}
return SWIG_OK;
}
@ -1212,24 +1210,24 @@ public:
if (!Getattr(n, "defaultargs")) {
// constructor
{
Wrapper *w = NewWrapper();
String *call;
String *basetype = Getattr(parent, "classtype");
String *target = Swig_method_decl(0, decl, classname, parms, 0, 0);
call = Swig_csuperclass_call(0, basetype, superparms);
Printf(w->def, "%s::%s: %s," "\nSwig::Director(static_cast<%s*>(this)) { \n", classname, target, call, basetype);
Append(w->def, "}\n");
Delete(target);
Wrapper_print(w, f_directors);
Delete(call);
DelWrapper(w);
Wrapper *w = NewWrapper();
String *call;
String *basetype = Getattr(parent, "classtype");
String *target = Swig_method_decl(0, decl, classname, parms, 0, 0);
call = Swig_csuperclass_call(0, basetype, superparms);
Printf(w->def, "%s::%s: %s," "\nSwig::Director(static_cast<%s*>(this)) { \n", classname, target, call, basetype);
Append(w->def, "}\n");
Delete(target);
Wrapper_print(w, f_directors);
Delete(call);
DelWrapper(w);
}
// constructor header
{
String *target = Swig_method_decl(0, decl, classname, parms, 0, 1);
Printf(f_directors_h, " %s;\n", target);
Delete(target);
String *target = Swig_method_decl(0, decl, classname, parms, 0, 1);
Printf(f_directors_h, " %s;\n", target);
Delete(target);
}
}
@ -1245,7 +1243,7 @@ public:
{
Wrapper *w = NewWrapper();
Printf(w->def, "SwigDirector_%s::SwigDirector_%s(void* self) :"
"\nSwig::Director((octave_swig_type*)self,static_cast<%s*>(this)) { \n", classname, classname, classname);
"\nSwig::Director((octave_swig_type*)self,static_cast<%s*>(this)) { \n", classname, classname, classname);
Append(w->def, "}\n");
Wrapper_print(w, f_directors);
DelWrapper(w);
@ -1278,7 +1276,7 @@ public:
if (Cmp(storage, "virtual") == 0) {
if (Cmp(value, "0") == 0) {
pure_virtual = true;
pure_virtual = true;
}
}
@ -1312,18 +1310,18 @@ public:
Append(declaration, " throw(");
if (throw_parm_list)
Swig_typemap_attach_parms("throws", throw_parm_list, 0);
Swig_typemap_attach_parms("throws", throw_parm_list, 0);
for (p = throw_parm_list; p; p = nextSibling(p)) {
if (Getattr(p, "tmap:throws")) {
if (gencomma++) {
Append(w->def, ", ");
Append(declaration, ", ");
}
String *str = SwigType_str(Getattr(p, "type"), 0);
Append(w->def, str);
Append(declaration, str);
Delete(str);
}
if (Getattr(p, "tmap:throws")) {
if (gencomma++) {
Append(w->def, ", ");
Append(declaration, ", ");
}
String *str = SwigType_str(Getattr(p, "type"), 0);
Append(w->def, str);
Append(declaration, str);
Delete(str);
}
}
Append(w->def, ")");
@ -1333,27 +1331,27 @@ public:
Append(w->def, " {");
Append(declaration, ";\n");
// declare method return value
// declare method return value
// if the return value is a reference or const reference, a specialized typemap must
// handle it, including declaration of c_result ($result).
if (!is_void) {
if (!(ignored_method && !pure_virtual)) {
String *cres = SwigType_lstr(returntype, "c_result");
Printf(w->code, "%s;\n", cres);
Delete(cres);
String *cres = SwigType_lstr(returntype, "c_result");
Printf(w->code, "%s;\n", cres);
Delete(cres);
}
}
if (ignored_method) {
if (!pure_virtual) {
if (!is_void)
Printf(w->code, "return ");
String *super_call = Swig_method_call(super, l);
Printf(w->code, "%s;\n", super_call);
Delete(super_call);
if (!is_void)
Printf(w->code, "return ");
String *super_call = Swig_method_call(super, l);
Printf(w->code, "%s;\n", super_call);
Delete(super_call);
} else {
Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"Attempted to invoke pure virtual method %s::%s\");\n", SwigType_namestr(c_classname),
SwigType_namestr(name));
Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"Attempted to invoke pure virtual method %s::%s\");\n", SwigType_namestr(c_classname),
SwigType_namestr(name));
}
} else {
// attach typemaps to arguments (C/C++ -> Python)
@ -1369,50 +1367,50 @@ public:
int outputs = 0;
if (!is_void)
outputs++;
outputs++;
// build argument list and type conversion string
p = l;
while (p) {
if (checkAttribute(p, "tmap:in:numinputs", "0")) {
p = Getattr(p, "tmap:in:next");
continue;
}
if (checkAttribute(p, "tmap:in:numinputs", "0")) {
p = Getattr(p, "tmap:in:next");
continue;
}
if (Getattr(p, "tmap:directorargout") != 0)
outputs++;
if (Getattr(p, "tmap:directorargout") != 0)
outputs++;
String *pname = Getattr(p, "name");
String *ptype = Getattr(p, "type");
Wrapper_add_local(w, "tmpv", "octave_value tmpv");
String *pname = Getattr(p, "name");
String *ptype = Getattr(p, "type");
Wrapper_add_local(w, "tmpv", "octave_value tmpv");
if ((tm = Getattr(p, "tmap:directorin")) != 0) {
String *parse = Getattr(p, "tmap:directorin:parse");
if (!parse) {
Setattr(p, "emit:directorinput", "tmpv");
Replaceall(tm, "$input", "tmpv");
Replaceall(tm, "$owner", "0");
Printv(wrap_args, tm, "\n", NIL);
Printf(wrap_args, "args.append(tmpv);\n");
Putc('O', parse_args);
} else {
Append(parse_args, parse);
Setattr(p, "emit:directorinput", pname);
Replaceall(tm, "$input", pname);
Replaceall(tm, "$owner", "0");
if (Len(tm) == 0)
Append(tm, pname);
}
p = Getattr(p, "tmap:directorin:next");
continue;
} else if (Cmp(ptype, "void")) {
Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number,
"Unable to use type %s as a function argument in director method %s::%s (skipping method).\n", SwigType_str(ptype, 0),
SwigType_namestr(c_classname), SwigType_namestr(name));
status = SWIG_NOWRAP;
break;
}
p = nextSibling(p);
if ((tm = Getattr(p, "tmap:directorin")) != 0) {
String *parse = Getattr(p, "tmap:directorin:parse");
if (!parse) {
Setattr(p, "emit:directorinput", "tmpv");
Replaceall(tm, "$input", "tmpv");
Replaceall(tm, "$owner", "0");
Printv(wrap_args, tm, "\n", NIL);
Printf(wrap_args, "args.append(tmpv);\n");
Putc('O', parse_args);
} else {
Append(parse_args, parse);
Setattr(p, "emit:directorinput", pname);
Replaceall(tm, "$input", pname);
Replaceall(tm, "$owner", "0");
if (Len(tm) == 0)
Append(tm, pname);
}
p = Getattr(p, "tmap:directorin:next");
continue;
} else if (Cmp(ptype, "void")) {
Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number,
"Unable to use type %s as a function argument in director method %s::%s (skipping method).\n", SwigType_str(ptype, 0),
SwigType_namestr(c_classname), SwigType_namestr(name));
status = SWIG_NOWRAP;
break;
}
p = nextSibling(p);
}
String *method_name = Getattr(n, "sym:name");
@ -1433,45 +1431,45 @@ public:
// marshal return value
if (!is_void) {
Printf(w->code, "if (out.length()<%d) {\n", outputs);
Printf(w->code, "Swig::DirectorTypeMismatchException::raise(\"Octave "
"method %s.%s failed to return the required number " "of arguments.\");\n", classname, method_name);
Printf(w->code, "}\n");
Printf(w->code, "if (out.length()<%d) {\n", outputs);
Printf(w->code, "Swig::DirectorTypeMismatchException::raise(\"Octave "
"method %s.%s failed to return the required number " "of arguments.\");\n", classname, method_name);
Printf(w->code, "}\n");
tm = Swig_typemap_lookup("directorout", n, Swig_cresult_name(), w);
if (tm != 0) {
char temp[24];
sprintf(temp, "out(%d)", idx);
Replaceall(tm, "$input", temp);
// Replaceall(tm, "$argnum", temp);
Replaceall(tm, "$disown", Getattr(n, "wrap:disown") ? "SWIG_POINTER_DISOWN" : "0");
if (Getattr(n, "tmap:directorout:implicitconv")) {
Replaceall(tm, "$implicitconv", get_implicitconv_flag(n));
}
Replaceall(tm, "$result", "c_result");
Printv(w->code, tm, "\n", NIL);
Delete(tm);
} else {
Swig_warning(WARN_TYPEMAP_DIRECTOROUT_UNDEF, input_file, line_number,
"Unable to use return type %s in director method %s::%s (skipping method).\n",
SwigType_str(returntype, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
status = SWIG_ERROR;
}
tm = Swig_typemap_lookup("directorout", n, Swig_cresult_name(), w);
if (tm != 0) {
char temp[24];
sprintf(temp, "out(%d)", idx);
Replaceall(tm, "$input", temp);
// Replaceall(tm, "$argnum", temp);
Replaceall(tm, "$disown", Getattr(n, "wrap:disown") ? "SWIG_POINTER_DISOWN" : "0");
if (Getattr(n, "tmap:directorout:implicitconv")) {
Replaceall(tm, "$implicitconv", get_implicitconv_flag(n));
}
Replaceall(tm, "$result", "c_result");
Printv(w->code, tm, "\n", NIL);
Delete(tm);
} else {
Swig_warning(WARN_TYPEMAP_DIRECTOROUT_UNDEF, input_file, line_number,
"Unable to use return type %s in director method %s::%s (skipping method).\n",
SwigType_str(returntype, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
status = SWIG_ERROR;
}
}
idx++;
// marshal outputs
for (p = l; p;) {
if ((tm = Getattr(p, "tmap:directorargout")) != 0) {
char temp[24];
sprintf(temp, "out(%d)", idx);
Replaceall(tm, "$result", temp);
Replaceall(tm, "$input", Getattr(p, "emit:directorinput"));
Printv(w->code, tm, "\n", NIL);
p = Getattr(p, "tmap:directorargout:next");
} else {
p = nextSibling(p);
}
if ((tm = Getattr(p, "tmap:directorargout")) != 0) {
char temp[24];
sprintf(temp, "out(%d)", idx);
Replaceall(tm, "$result", temp);
Replaceall(tm, "$input", Getattr(p, "emit:directorinput"));
Printv(w->code, tm, "\n", NIL);
p = Getattr(p, "tmap:directorargout:next");
} else {
p = nextSibling(p);
}
}
Delete(parse_args);
@ -1481,13 +1479,13 @@ public:
if (!is_void) {
if (!(ignored_method && !pure_virtual)) {
String *rettype = SwigType_str(returntype, 0);
if (!SwigType_isreference(returntype)) {
Printf(w->code, "return (%s) c_result;\n", rettype);
} else {
Printf(w->code, "return (%s) *c_result;\n", rettype);
}
Delete(rettype);
String *rettype = SwigType_str(returntype, 0);
if (!SwigType_isreference(returntype)) {
Printf(w->code, "return (%s) c_result;\n", rettype);
} else {
Printf(w->code, "return (%s) *c_result;\n", rettype);
}
Delete(rettype);
}
}
@ -1501,7 +1499,7 @@ public:
Replaceall(inline_extra_method, name, extra_method_name);
Replaceall(inline_extra_method, ";\n", " {\n ");
if (!is_void)
Printf(inline_extra_method, "return ");
Printf(inline_extra_method, "return ");
String *methodcall = Swig_method_call(super, l);
Printv(inline_extra_method, methodcall, ";\n }\n", NIL);
Delete(methodcall);
@ -1510,10 +1508,10 @@ public:
// emit the director method
if (status == SWIG_OK) {
if (!Getattr(n, "defaultargs")) {
Replaceall(w->code, "$symname", symname);
Wrapper_print(w, f_directors);
Printv(f_directors_h, declaration, NIL);
Printv(f_directors_h, inline_extra_method, NIL);
Replaceall(w->code, "$symname", symname);
Wrapper_print(w, f_directors);
Printv(f_directors_h, declaration, NIL);
Printv(f_directors_h, inline_extra_method, NIL);
}
}
// clean up

View file

@ -17,7 +17,7 @@ static int treduce = SWIG_cparse_template_reduce(0);
#include <ctype.h>
static const char *usage = (char *) "\
static const char *usage = "\
Perl5 Options (available with -perl5)\n\
-compat - Compatibility mode\n\
-const - Wrap constants as constants and not variables (implies -proxy)\n\
@ -79,8 +79,11 @@ static String *variable_tab = 0;
static File *f_begin = 0;
static File *f_runtime = 0;
static File *f_runtime_h = 0;
static File *f_header = 0;
static File *f_wrappers = 0;
static File *f_directors = 0;
static File *f_directors_h = 0;
static File *f_init = 0;
static File *f_pm = 0;
static String *pm; /* Package initialization code */
@ -124,6 +127,7 @@ public:
Printv(argc_template_string, "items", NIL);
Clear(argv_template_string);
Printv(argv_template_string, "ST(%d)", NIL);
director_language = 1;
}
/* Test to see if a type corresponds to something wrapped with a shadow class */
@ -219,9 +223,63 @@ public:
* ------------------------------------------------------------ */
virtual int top(Node *n) {
/* check if directors are enabled for this module. note: this
* is a "master" switch, without which no director code will be
* emitted. %feature("director") statements are also required
* to enable directors for individual classes or methods.
*
* use %module(directors="1") modulename at the start of the
* interface file to enable director generation.
*
* TODO: directors are disallowed in conjunction with many command
* line options. Some of them are probably safe, but it will take
* some effort to validate each one.
*/
{
Node *mod = Getattr(n, "module");
if (mod) {
Node *options = Getattr(mod, "options");
if (options) {
int dirprot = 0;
if (Getattr(options, "dirprot"))
dirprot = 1;
if (Getattr(options, "nodirprot"))
dirprot = 0;
if (Getattr(options, "directors")) {
int allow = 1;
if (export_all) {
Printv(stderr, "*** directors are not supported with -exportall\n", NIL);
allow = 0;
}
if (staticoption) {
Printv(stderr, "*** directors are not supported with -static\n", NIL);
allow = 0;
}
if (!blessed) {
Printv(stderr, "*** directors are not supported with -noproxy\n", NIL);
allow = 0;
}
if (no_pmfile) {
Printv(stderr, "*** directors are not supported with -nopm\n", NIL);
allow = 0;
}
if (compat) {
Printv(stderr, "*** directors are not supported with -compat\n", NIL);
allow = 0;
}
if (allow) {
allow_directors();
if (dirprot)
allow_dirprot();
}
}
}
}
}
/* Initialize all of the output files */
String *outfile = Getattr(n, "outfile");
String *outfile_h = Getattr(n, "outfile_h");
f_begin = NewFile(outfile, "w", SWIG_output_files());
if (!f_begin) {
@ -232,6 +290,16 @@ public:
f_init = NewString("");
f_header = NewString("");
f_wrappers = NewString("");
f_directors_h = NewString("");
f_directors = NewString("");
if (directorsEnabled()) {
f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files());
if (!f_runtime_h) {
FileErrorDisplay(outfile_h);
SWIG_exit(EXIT_FAILURE);
}
}
/* Register file targets with the SWIG file handler */
Swig_register_filebyname("header", f_header);
@ -239,6 +307,8 @@ public:
Swig_register_filebyname("begin", f_begin);
Swig_register_filebyname("runtime", f_runtime);
Swig_register_filebyname("init", f_init);
Swig_register_filebyname("director", f_directors);
Swig_register_filebyname("director_h", f_directors_h);
classlist = NewList();
@ -259,6 +329,9 @@ public:
Printf(f_runtime, "\n");
Printf(f_runtime, "#define SWIGPERL\n");
if (directorsEnabled()) {
Printf(f_runtime, "#define SWIG_DIRECTORS\n");
}
Printf(f_runtime, "#define SWIG_CASTRANK_MODE\n");
Printf(f_runtime, "\n");
@ -269,6 +342,27 @@ public:
Node *options = Getattr(mod, "options");
module = Copy(Getattr(n,"name"));
if (directorsEnabled()) {
Swig_banner(f_directors_h);
Printf(f_directors_h, "\n");
Printf(f_directors_h, "#ifndef SWIG_%s_WRAP_H_\n", module);
Printf(f_directors_h, "#define SWIG_%s_WRAP_H_\n\n", module);
if (dirprot_mode()) {
Printf(f_directors_h, "#include <map>\n");
Printf(f_directors_h, "#include <string>\n\n");
}
Printf(f_directors, "\n\n");
Printf(f_directors, "/* ---------------------------------------------------\n");
Printf(f_directors, " * C++ director class methods\n");
Printf(f_directors, " * --------------------------------------------------- */\n\n");
if (outfile_h) {
String *filename = Swig_file_filename(outfile_h);
Printf(magic, "#include \"%s\"\n\n", filename);
Delete(filename);
}
}
if (verbose > 0) {
fprintf(stdout, "top: using module: %s\n", Char(module));
}
@ -374,6 +468,11 @@ public:
/* emit wrappers */
Language::top(n);
if (directorsEnabled()) {
// Insert director runtime into the f_runtime file (make it occur before %header section)
Swig_insert_file("director.swg", f_runtime);
}
String *base = NewString("");
/* Dump out variable wrappers */
@ -526,11 +625,21 @@ public:
/* Close all of the files */
Dump(f_runtime, f_begin);
Dump(f_header, f_begin);
if (directorsEnabled()) {
Dump(f_directors_h, f_runtime_h);
Printf(f_runtime_h, "\n");
Printf(f_runtime_h, "#endif\n");
Dump(f_directors, f_begin);
}
Dump(f_wrappers, f_begin);
Wrapper_pretty_print(f_init, f_begin);
Delete(f_header);
Delete(f_wrappers);
Delete(f_init);
Delete(f_directors);
Delete(f_directors_h);
Delete(f_runtime);
Delete(f_begin);
return SWIG_OK;
@ -560,6 +669,7 @@ public:
SwigType *d = Getattr(n, "type");
ParmList *l = Getattr(n, "parms");
String *overname = 0;
int director_method = 0;
Parm *p;
int i;
@ -720,11 +830,36 @@ public:
Wrapper_add_localv(f, "_saved", "SV *", temp, NIL);
}
director_method = is_member_director(n) && !is_smart_pointer() && 0 != Cmp(nodeType(n), "destructor");
if (director_method) {
Wrapper_add_local(f, "director", "Swig::Director *director = 0");
Append(f->code, "director = SWIG_DIRECTOR_CAST(arg1);\n");
if (dirprot_mode() && !is_public(n)) {
Printf(f->code, "if (!director || !(director->swig_get_inner(\"%s\"))) {\n", name);
Printf(f->code, "SWIG_exception_fail(SWIG_RuntimeError, \"accessing protected member %s\");\n", name);
Append(f->code, "}\n");
}
Wrapper_add_local(f, "upcall", "bool upcall = false");
Printf(f->code, "upcall = director && SvSTASH(SvRV(ST(0))) == gv_stashpv(director->swig_get_class(), 0);\n");
}
/* Emit the function call */
if (director_method) {
Append(f->code, "try {\n");
}
/* Now write code to make the function call */
Swig_director_emit_dynamic_cast(n, f);
String *actioncode = emit_action(n);
if (director_method) {
Append(actioncode, "} catch (Swig::DirectorException& swig_err) {\n");
Append(actioncode, " sv_setsv(ERRSV, swig_err.getNative());\n");
Append(actioncode, " SWIG_fail;\n");
Append(actioncode, "}\n");
}
if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) {
SwigType *t = Getattr(n, "type");
Replaceall(tm, "$source", Swig_cresult_name());
@ -1335,17 +1470,67 @@ public:
/* Output methods for managing ownership */
String *director_disown;
if (Getattr(n, "perl5:directordisown")) {
director_disown = NewStringf("%s%s($self);\n", tab4, Getattr(n, "perl5:directordisown"));
} else {
director_disown = NewString("");
}
Printv(pm,
"sub DISOWN {\n",
tab4, "my $self = shift;\n",
director_disown,
tab4, "my $ptr = tied(%$self);\n",
tab4, "delete $OWNER{$ptr};\n",
"}\n\n", "sub ACQUIRE {\n", tab4, "my $self = shift;\n", tab4, "my $ptr = tied(%$self);\n", tab4, "$OWNER{$ptr} = 1;\n", "}\n\n", NIL);
Delete(director_disown);
/* Only output the following methods if a class has member data */
Delete(operators);
operators = 0;
if (Swig_directorclass(n)) {
/* director classes need a way to recover subclass instance attributes */
Node *get_attr = NewHash();
String *mrename;
String *symname = Getattr(n, "sym:name");
mrename = Swig_name_disown(NSPACE_TODO, symname);
Replaceall(mrename, "disown", "swig_get_attr");
String *type = NewString(getClassType());
String *name = NewString("self");
SwigType_add_pointer(type);
Parm *p = NewParm(type, name, n);
Delete(name);
Delete(type);
type = NewString("SV");
SwigType_add_pointer(type);
String *action = NewString("");
Printv(action, "{\n", " Swig::Director *director = SWIG_DIRECTOR_CAST(arg1);\n",
" result = sv_newmortal();\n" " if (director) sv_setsv(result, director->swig_get_self());\n", "}\n", NIL);
Setfile(get_attr, Getfile(n));
Setline(get_attr, Getline(n));
Setattr(get_attr, "wrap:action", action);
Setattr(get_attr, "name", mrename);
Setattr(get_attr, "sym:name", mrename);
Setattr(get_attr, "type", type);
Setattr(get_attr, "parms", p);
Delete(action);
Delete(type);
Delete(p);
member_func = 1;
functionWrapper(get_attr);
member_func = 0;
Delete(get_attr);
Printv(pm, "sub FETCH {\n", tab4, "my ($self,$field) = @_;\n", tab4, "my $member_func = \"swig_${field}_get\";\n", tab4,
"if (not $self->can($member_func)) {\n", tab8, "my $h = ", cmodule, "::", mrename, "($self);\n", tab8, "return $h->{$field} if $h;\n",
tab4, "}\n", tab4, "return $self->$member_func;\n", "}\n", "\n", "sub STORE {\n", tab4, "my ($self,$field,$newval) = @_;\n", tab4,
"my $member_func = \"swig_${field}_set\";\n", tab4, "if (not $self->can($member_func)) {\n", tab8, "my $h = ", cmodule, "::", mrename,
"($self);\n", tab8, "return $h->{$field} = $newval if $h;\n", tab4, "}\n", tab4, "return $self->$member_func($newval);\n", "}\n", NIL);
Delete(mrename);
}
}
return SWIG_OK;
}
@ -1494,7 +1679,37 @@ public:
String *symname = Getattr(n, "sym:name");
member_func = 1;
Swig_save("perl5:constructorHandler", n, "parms", NIL);
if (Swig_directorclass(n)) {
Parm *parms = Getattr(n, "parms");
Parm *self;
String *name = NewString("self");
String *type = NewString("SV");
SwigType_add_pointer(type);
self = NewParm(type, name, n);
Delete(type);
Delete(name);
Setattr(self, "lname", "O");
if (parms)
set_nextSibling(self, parms);
Setattr(n, "parms", self);
Setattr(n, "wrap:self", "1");
Setattr(n, "hidden", "1");
Delete(self);
}
String *saved_nc = none_comparison;
none_comparison = NewStringf("strcmp(SvPV_nolen(ST(0)), \"%s::%s\") != 0", module, class_name);
String *saved_director_prot_ctor_code = director_prot_ctor_code;
director_prot_ctor_code = NewStringf("if ($comparison) { /* subclassed */\n" " $director_new\n" "} else {\n"
"SWIG_exception_fail(SWIG_RuntimeError, \"accessing abstract class or protected constructor\");\n" "}\n");
Language::constructorHandler(n);
Delete(none_comparison);
none_comparison = saved_nc;
Delete(director_prot_ctor_code);
director_prot_ctor_code = saved_director_prot_ctor_code;
Swig_restore(n);
if ((blessed) && (!Getattr(n, "sym:nextSibling"))) {
if (Getattr(n, "feature:shadow")) {
@ -1512,8 +1727,9 @@ public:
Printv(pcode, "sub ", Swig_name_construct(NSPACE_TODO, symname), " {\n", NIL);
}
const char *pkg = getCurrentClass() && Swig_directorclass(getCurrentClass())? "$_[0]" : "shift";
Printv(pcode,
tab4, "my $pkg = shift;\n",
tab4, "my $pkg = ", pkg, ";\n",
tab4, "my $self = ", cmodule, "::", Swig_name_construct(NSPACE_TODO, symname), "(@_);\n", tab4, "bless $self, $pkg if defined($self);\n", "}\n\n", NIL);
have_constructor = 1;
@ -1752,6 +1968,543 @@ public:
String *defaultExternalRuntimeFilename() {
return NewString("swigperlrun.h");
}
virtual int classDirectorInit(Node *n) {
String *declaration = Swig_director_declaration(n);
Printf(f_directors_h, "\n");
Printf(f_directors_h, "%s\n", declaration);
Printf(f_directors_h, "public:\n");
Delete(declaration);
return Language::classDirectorInit(n);
}
virtual int classDirectorEnd(Node *n) {
if (dirprot_mode()) {
/*
This implementation uses a std::map<std::string,int>.
It should be possible to rewrite it using a more elegant way,
like copying the Java approach for the 'override' array.
But for now, this seems to be the least intrusive way.
*/
Printf(f_directors_h, "\n");
Printf(f_directors_h, "/* Internal director utilities */\n");
Printf(f_directors_h, "public:\n");
Printf(f_directors_h, " bool swig_get_inner(const char *swig_protected_method_name) const {\n");
Printf(f_directors_h, " std::map<std::string, bool>::const_iterator iv = swig_inner.find(swig_protected_method_name);\n");
Printf(f_directors_h, " return (iv != swig_inner.end() ? iv->second : false);\n");
Printf(f_directors_h, " }\n");
Printf(f_directors_h, " void swig_set_inner(const char *swig_protected_method_name, bool val) const {\n");
Printf(f_directors_h, " swig_inner[swig_protected_method_name] = val;\n");
Printf(f_directors_h, " }\n");
Printf(f_directors_h, "private:\n");
Printf(f_directors_h, " mutable std::map<std::string, bool> swig_inner;\n");
}
Printf(f_directors_h, "};\n");
return Language::classDirectorEnd(n);
}
virtual int classDirectorConstructor(Node *n) {
Node *parent = Getattr(n, "parentNode");
String *sub = NewString("");
String *decl = Getattr(n, "decl");
String *supername = Swig_class_name(parent);
String *classname = NewString("");
Printf(classname, "SwigDirector_%s", supername);
/* insert self parameter */
Parm *p;
ParmList *superparms = Getattr(n, "parms");
ParmList *parms = CopyParmList(superparms);
String *type = NewString("SV");
SwigType_add_pointer(type);
p = NewParm(type, NewString("self"), n);
set_nextSibling(p, parms);
parms = p;
if (!Getattr(n, "defaultargs")) {
/* constructor */
{
Wrapper *w = NewWrapper();
String *call;
String *basetype = Getattr(parent, "classtype");
String *target = Swig_method_decl(0, decl, classname, parms, 0, 0);
call = Swig_csuperclass_call(0, basetype, superparms);
Printf(w->def, "%s::%s: %s, Swig::Director(self) { \n", classname, target, call);
Printf(w->def, " SWIG_DIRECTOR_RGTR((%s *)this, this); \n", basetype);
Append(w->def, "}\n");
Delete(target);
Wrapper_print(w, f_directors);
Delete(call);
DelWrapper(w);
}
/* constructor header */
{
String *target = Swig_method_decl(0, decl, classname, parms, 0, 1);
Printf(f_directors_h, " %s;\n", target);
Delete(target);
}
}
Delete(sub);
Delete(classname);
Delete(supername);
Delete(parms);
return Language::classDirectorConstructor(n);
}
virtual int classDirectorMethod(Node *n, Node *parent, String *super) {
int is_void = 0;
int is_pointer = 0;
String *decl = Getattr(n, "decl");
String *name = Getattr(n, "name");
String *classname = Getattr(parent, "sym:name");
String *c_classname = Getattr(parent, "name");
String *symname = Getattr(n, "sym:name");
String *declaration = NewString("");
ParmList *l = Getattr(n, "parms");
Wrapper *w = NewWrapper();
String *tm;
String *wrap_args = NewString("");
String *returntype = Getattr(n, "type");
String *value = Getattr(n, "value");
String *storage = Getattr(n, "storage");
bool pure_virtual = false;
int status = SWIG_OK;
int idx;
bool ignored_method = GetFlag(n, "feature:ignore") ? true : false;
if (Cmp(storage, "virtual") == 0) {
if (Cmp(value, "0") == 0) {
pure_virtual = true;
}
}
/* determine if the method returns a pointer */
is_pointer = SwigType_ispointer_return(decl);
is_void = (!Cmp(returntype, "void") && !is_pointer);
/* virtual method definition */
String *target;
String *pclassname = NewStringf("SwigDirector_%s", classname);
String *qualified_name = NewStringf("%s::%s", pclassname, name);
SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type");
target = Swig_method_decl(rtype, decl, qualified_name, l, 0, 0);
Printf(w->def, "%s", target);
Delete(qualified_name);
Delete(target);
/* header declaration */
target = Swig_method_decl(rtype, decl, name, l, 0, 1);
Printf(declaration, " virtual %s", target);
Delete(target);
// Get any exception classes in the throws typemap
ParmList *throw_parm_list = 0;
if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) {
Parm *p;
int gencomma = 0;
Append(w->def, " throw(");
Append(declaration, " throw(");
if (throw_parm_list)
Swig_typemap_attach_parms("throws", throw_parm_list, 0);
for (p = throw_parm_list; p; p = nextSibling(p)) {
if (Getattr(p, "tmap:throws")) {
if (gencomma++) {
Append(w->def, ", ");
Append(declaration, ", ");
}
String *str = SwigType_str(Getattr(p, "type"), 0);
Append(w->def, str);
Append(declaration, str);
Delete(str);
}
}
Append(w->def, ")");
Append(declaration, ")");
}
Append(w->def, " {");
Append(declaration, ";\n");
/* declare method return value
* if the return value is a reference or const reference, a specialized typemap must
* handle it, including declaration of c_result ($result).
*/
if (!is_void) {
if (!(ignored_method && !pure_virtual)) {
String *cres = SwigType_lstr(returntype, "c_result");
Printf(w->code, "%s;\n", cres);
Delete(cres);
String *pres = NewStringf("SV *%s", Swig_cresult_name());
Wrapper_add_local(w, Swig_cresult_name(), pres);
Delete(pres);
}
}
if (ignored_method) {
if (!pure_virtual) {
if (!is_void)
Printf(w->code, "return ");
String *super_call = Swig_method_call(super, l);
Printf(w->code, "%s;\n", super_call);
Delete(super_call);
} else {
Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"Attempted to invoke pure virtual method %s::%s\");\n", SwigType_namestr(c_classname),
SwigType_namestr(name));
}
} else {
/* attach typemaps to arguments (C/C++ -> Perl) */
String *parse_args = NewString("");
String *pstack = NewString("");
Swig_director_parms_fixup(l);
/* remove the wrapper 'w' since it was producing spurious temps */
Swig_typemap_attach_parms("in", l, 0);
Swig_typemap_attach_parms("directorin", l, 0);
Swig_typemap_attach_parms("directorargout", l, w);
Wrapper_add_local(w, "SP", "dSP");
{
String *ptype = Copy(getClassType());
SwigType_add_pointer(ptype);
String *mangle = SwigType_manglestr(ptype);
Wrapper_add_local(w, "self", "SV *self");
Printf(w->code, "self = SWIG_NewPointerObj(SWIG_as_voidptr(this), SWIGTYPE%s, SWIG_SHADOW);\n", mangle);
Printf(w->code, "sv_bless(self, gv_stashpv(swig_get_class(), 0));\n");
Delete(mangle);
Delete(ptype);
Append(pstack, "XPUSHs(self);\n");
}
Parm *p;
char source[256];
int outputs = 0;
if (!is_void)
outputs++;
/* build argument list and type conversion string */
idx = 0;
p = l;
while (p) {
if (checkAttribute(p, "tmap:in:numinputs", "0")) {
p = Getattr(p, "tmap:in:next");
continue;
}
/* old style? caused segfaults without the p!=0 check
in the for() condition, and seems dangerous in the
while loop as well.
while (Getattr(p, "tmap:ignore")) {
p = Getattr(p, "tmap:ignore:next");
}
*/
if (Getattr(p, "tmap:directorargout") != 0)
outputs++;
String *pname = Getattr(p, "name");
String *ptype = Getattr(p, "type");
if ((tm = Getattr(p, "tmap:directorin")) != 0) {
sprintf(source, "obj%d", idx++);
String *input = NewString(source);
Setattr(p, "emit:directorinput", input);
Replaceall(tm, "$input", input);
Delete(input);
Replaceall(tm, "$owner", "0");
Replaceall(tm, "$shadow", "0");
/* Wrapper_add_localv(w, source, "SV *", source, "= 0", NIL); */
Printv(wrap_args, "SV *", source, ";\n", NIL);
Printv(wrap_args, tm, "\n", NIL);
Putc('O', parse_args);
Printv(pstack, "XPUSHs(", source, ");\n", NIL);
p = Getattr(p, "tmap:directorin:next");
continue;
} else if (Cmp(ptype, "void")) {
/* special handling for pointers to other C++ director classes.
* ideally this would be left to a typemap, but there is currently no
* way to selectively apply the dynamic_cast<> to classes that have
* directors. in other words, the type "SwigDirector_$1_lname" only exists
* for classes with directors. we avoid the problem here by checking
* module.wrap::directormap, but it's not clear how to get a typemap to
* do something similar. perhaps a new default typemap (in addition
* to SWIGTYPE) called DIRECTORTYPE?
*/
if (SwigType_ispointer(ptype) || SwigType_isreference(ptype)) {
Node *module = Getattr(parent, "module");
Node *target = Swig_directormap(module, ptype);
sprintf(source, "obj%d", idx++);
String *nonconst = 0;
/* strip pointer/reference --- should move to Swig/stype.c */
String *nptype = NewString(Char(ptype) + 2);
/* name as pointer */
String *ppname = Copy(pname);
if (SwigType_isreference(ptype)) {
Insert(ppname, 0, "&");
}
/* if necessary, cast away const since Python doesn't support it! */
if (SwigType_isconst(nptype)) {
nonconst = NewStringf("nc_tmp_%s", pname);
String *nonconst_i = NewStringf("= const_cast< %s >(%s)", SwigType_lstr(ptype, 0), ppname);
Wrapper_add_localv(w, nonconst, SwigType_lstr(ptype, 0), nonconst, nonconst_i, NIL);
Delete(nonconst_i);
Swig_warning(WARN_LANG_DISCARD_CONST, input_file, line_number,
"Target language argument '%s' discards const in director method %s::%s.\n",
SwigType_str(ptype, pname), SwigType_namestr(c_classname), SwigType_namestr(name));
} else {
nonconst = Copy(ppname);
}
Delete(nptype);
Delete(ppname);
String *mangle = SwigType_manglestr(ptype);
if (target) {
String *director = NewStringf("director_%s", mangle);
Wrapper_add_localv(w, director, "Swig::Director *", director, "= 0", NIL);
Wrapper_add_localv(w, source, "SV *", source, "= 0", NIL);
Printf(wrap_args, "%s = SWIG_DIRECTOR_CAST(%s);\n", director, nonconst);
Printf(wrap_args, "if (!%s) {\n", director);
Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle);
Append(wrap_args, "} else {\n");
Printf(wrap_args, "%s = %s->swig_get_self();\n", source, director);
Printf(wrap_args, "SvREFCNT_inc((SV *)%s);\n", source);
Append(wrap_args, "}\n");
Delete(director);
} else {
Wrapper_add_localv(w, source, "SV *", source, "= 0", NIL);
Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle);
Printf(pstack, "XPUSHs(sv_2mortal(%s));\n", source);
}
Putc('O', parse_args);
Delete(mangle);
Delete(nonconst);
} else {
Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number,
"Unable to use type %s as a function argument in director method %s::%s (skipping method).\n", SwigType_str(ptype, 0),
SwigType_namestr(c_classname), SwigType_namestr(name));
status = SWIG_NOWRAP;
break;
}
}
p = nextSibling(p);
}
/* add the method name as a PyString */
String *pyname = Getattr(n, "sym:name");
/* wrap complex arguments to PyObjects */
Printv(w->code, wrap_args, NIL);
/* pass the method call on to the Python object */
if (dirprot_mode() && !is_public(n)) {
Printf(w->code, "swig_set_inner(\"%s\", true);\n", name);
}
Append(w->code, "ENTER;\n");
Append(w->code, "SAVETMPS;\n");
Append(w->code, "PUSHMARK(SP);\n");
Append(w->code, pstack);
Delete(pstack);
Append(w->code, "PUTBACK;\n");
Printf(w->code, "call_method(\"%s\", G_EVAL | G_SCALAR);\n", pyname);
if (dirprot_mode() && !is_public(n))
Printf(w->code, "swig_set_inner(\"%s\", false);\n", name);
/* exception handling */
tm = Swig_typemap_lookup("director:except", n, Swig_cresult_name(), 0);
if (!tm) {
tm = Getattr(n, "feature:director:except");
if (tm)
tm = Copy(tm);
}
Append(w->code, "if (SvTRUE(ERRSV)) {\n");
Append(w->code, " PUTBACK;\n FREETMPS;\n LEAVE;\n");
if ((tm) && Len(tm) && (Strcmp(tm, "1") != 0)) {
Replaceall(tm, "$error", "ERRSV");
Printv(w->code, Str(tm), "\n", NIL);
} else {
Printf(w->code, " Swig::DirectorMethodException::raise(ERRSV);\n", classname, pyname);
}
Append(w->code, "}\n");
Delete(tm);
/*
* Python method may return a simple object, or a tuple.
* for in/out aruments, we have to extract the appropriate PyObjects from the tuple,
* then marshal everything back to C/C++ (return value and output arguments).
*
*/
/* marshal return value and other outputs (if any) from PyObject to C/C++ type */
String *cleanup = NewString("");
String *outarg = NewString("");
if (outputs > 1) {
Wrapper_add_local(w, "output", "SV *output");
Printf(w->code, "if (count != %d) {\n", outputs);
Printf(w->code, " Swig::DirectorTypeMismatchException::raise(\"Perl method %s.%sfailed to return a list.\");\n", classname, pyname);
Append(w->code, "}\n");
}
idx = 0;
/* marshal return value */
if (!is_void) {
Append(w->code, "SPAGAIN;\n");
Printf(w->code, "%s = POPs;\n", Swig_cresult_name());
tm = Swig_typemap_lookup("directorout", n, Swig_cresult_name(), w);
if (tm != 0) {
if (outputs > 1) {
Printf(w->code, "output = POPs;\n");
Replaceall(tm, "$input", "output");
} else {
Replaceall(tm, "$input", Swig_cresult_name());
}
char temp[24];
sprintf(temp, "%d", idx);
Replaceall(tm, "$argnum", temp);
/* TODO check this */
if (Getattr(n, "wrap:disown")) {
Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN");
} else {
Replaceall(tm, "$disown", "0");
}
Replaceall(tm, "$result", "c_result");
Printv(w->code, tm, "\n", NIL);
Delete(tm);
} else {
Swig_warning(WARN_TYPEMAP_DIRECTOROUT_UNDEF, input_file, line_number,
"Unable to use return type %s in director method %s::%s (skipping method).\n", SwigType_str(returntype, 0),
SwigType_namestr(c_classname), SwigType_namestr(name));
status = SWIG_ERROR;
}
}
/* marshal outputs */
for (p = l; p;) {
if ((tm = Getattr(p, "tmap:directorargout")) != 0) {
if (outputs > 1) {
Printf(w->code, "output = POPs;\n");
Replaceall(tm, "$result", "output");
} else {
Replaceall(tm, "$result", Swig_cresult_name());
}
Replaceall(tm, "$input", Getattr(p, "emit:directorinput"));
Printv(w->code, tm, "\n", NIL);
p = Getattr(p, "tmap:directorargout:next");
} else {
p = nextSibling(p);
}
}
Delete(parse_args);
Delete(cleanup);
Delete(outarg);
}
if (!ignored_method) {
Append(w->code, "PUTBACK;\n");
Append(w->code, "FREETMPS;\n");
Append(w->code, "LEAVE;\n");
}
if (!is_void) {
if (!(ignored_method && !pure_virtual)) {
String *rettype = SwigType_str(returntype, 0);
if (!SwigType_isreference(returntype)) {
Printf(w->code, "return (%s) c_result;\n", rettype);
} else {
Printf(w->code, "return (%s) *c_result;\n", rettype);
}
Delete(rettype);
}
}
Append(w->code, "}\n");
// We expose protected methods via an extra public inline method which makes a straight call to the wrapped class' method
String *inline_extra_method = NewString("");
if (dirprot_mode() && !is_public(n) && !pure_virtual) {
Printv(inline_extra_method, declaration, NIL);
String *extra_method_name = NewStringf("%sSwigPublic", name);
Replaceall(inline_extra_method, name, extra_method_name);
Replaceall(inline_extra_method, ";\n", " {\n ");
if (!is_void)
Printf(inline_extra_method, "return ");
String *methodcall = Swig_method_call(super, l);
Printv(inline_extra_method, methodcall, ";\n }\n", NIL);
Delete(methodcall);
Delete(extra_method_name);
}
/* emit the director method */
if (status == SWIG_OK) {
if (!Getattr(n, "defaultargs")) {
Replaceall(w->code, "$symname", symname);
Wrapper_print(w, f_directors);
Printv(f_directors_h, declaration, NIL);
Printv(f_directors_h, inline_extra_method, NIL);
}
}
/* clean up */
Delete(wrap_args);
Delete(pclassname);
DelWrapper(w);
return status;
}
int classDirectorDisown(Node *n) {
int rv;
member_func = 1;
rv = Language::classDirectorDisown(n);
member_func = 0;
if (rv == SWIG_OK && Swig_directorclass(n)) {
String *symname = Getattr(n, "sym:name");
String *disown = Swig_name_disown(NSPACE_TODO, symname);
Setattr(n, "perl5:directordisown", NewStringf("%s::%s", cmodule, disown));
}
return rv;
}
int classDirectorDestructor(Node *n) {
/* TODO: it would be nice if this didn't have to copy the body of Language::classDirectorDestructor() */
String *DirectorClassName = directorClassName(getCurrentClass());
String *body = NewString("\n");
String *ptype = Copy(getClassType());
SwigType_add_pointer(ptype);
String *mangle = SwigType_manglestr(ptype);
Printv(body, tab4, "dSP;\n", tab4, "SV *self = SWIG_NewPointerObj(SWIG_as_voidptr(this), SWIGTYPE", mangle, ", SWIG_SHADOW);\n", tab4, "\n", tab4,
"sv_bless(self, gv_stashpv(swig_get_class(), 0));\n", tab4, "ENTER;\n", tab4, "SAVETMPS;\n", tab4, "PUSHMARK(SP);\n", tab4,
"XPUSHs(self);\n", tab4, "XPUSHs(&PL_sv_yes);\n", tab4, "PUTBACK;\n", tab4, "call_method(\"DESTROY\", G_EVAL | G_VOID);\n", tab4,
"FREETMPS;\n", tab4, "LEAVE;\n", NIL);
Delete(mangle);
Delete(ptype);
if (Getattr(n, "throw")) {
Printf(f_directors_h, " virtual ~%s() throw ();\n", DirectorClassName);
Printf(f_directors, "%s::~%s() throw () {%s}\n\n", DirectorClassName, DirectorClassName, body);
} else {
Printf(f_directors_h, " virtual ~%s();\n", DirectorClassName);
Printf(f_directors, "%s::~%s() {%s}\n\n", DirectorClassName, DirectorClassName, body);
}
return SWIG_OK;
}
};
/* -----------------------------------------------------------------------------

View file

@ -42,7 +42,7 @@
#include <ctype.h>
#include <errno.h>
static const char *usage = (char *) "\
static const char *usage = "\
PHP Options (available with -php)\n\
-cppext <ext> - Change C++ file extension to <ext> (default is cpp)\n\
-noproxy - Don't generate proxy classes.\n\
@ -90,6 +90,7 @@ static String *s_vinit; // varinit initialization code.
static String *s_vdecl;
static String *s_cinit; // consttab initialization code.
static String *s_oinit;
static String *s_arginfo;
static String *s_entry;
static String *cs_entry;
static String *all_cs_entry;
@ -413,10 +414,9 @@ public:
* which has to be dynamically generated as it depends on the module name.
*/
Append(s_header, "#ifdef __GNUC__\n");
Append(s_header, "static void SWIG_FAIL() __attribute__ ((__noreturn__));\n");
Append(s_header, "static void SWIG_FAIL(TSRMLS_D) __attribute__ ((__noreturn__));\n");
Append(s_header, "#endif\n\n");
Append(s_header, "static void SWIG_FAIL() {\n");
Append(s_header, " TSRMLS_FETCH();\n");
Append(s_header, "static void SWIG_FAIL(TSRMLS_D) {\n");
Append(s_header, " zend_error(SWIG_ErrorCode(), \"%s\", SWIG_ErrorMsg());\n");
// zend_error() should never return with the parameters we pass, but if it
// does, we really don't want to let SWIG_FAIL() return. This also avoids
@ -432,8 +432,7 @@ public:
Printf(s_header, "static void %s_destroy_globals(zend_%s_globals * globals) { (void)globals; }\n", module, module);
Printf(s_header, "\n");
Printf(s_header, "static void SWIG_ResetError() {\n");
Printf(s_header, " TSRMLS_FETCH();\n");
Printf(s_header, "static void SWIG_ResetError(TSRMLS_D) {\n");
Printf(s_header, " SWIG_ErrorMsg() = default_error_msg;\n");
Printf(s_header, " SWIG_ErrorCode() = default_error_code;\n");
Printf(s_header, "}\n");
@ -443,9 +442,8 @@ public:
Append(s_header, " zval **args[2];\n");
Append(s_header, " swig_object_wrapper *value;\n");
Append(s_header, " int type;\n");
Append(s_header, " int thisown;\n");
Append(s_header, "\n");
Append(s_header, " SWIG_ResetError();\n");
Append(s_header, " SWIG_ResetError(TSRMLS_C);\n");
Append(s_header, " if(ZEND_NUM_ARGS() != 2 || zend_get_parameters_array_ex(2, args) != SUCCESS) {\n");
Append(s_header, " WRONG_PARAM_COUNT;\n");
Append(s_header, " }\n");
@ -460,7 +458,7 @@ public:
Append(s_header, " swig_object_wrapper *value;\n");
Append(s_header, " int type;\n");
Append(s_header, "\n");
Append(s_header, " SWIG_ResetError();\n");
Append(s_header, " SWIG_ResetError(TSRMLS_C);\n");
Append(s_header, " if(ZEND_NUM_ARGS() != 1 || zend_get_parameters_array_ex(1, args) != SUCCESS) {\n");
Append(s_header, " WRONG_PARAM_COUNT;\n");
Append(s_header, " }\n");
@ -518,6 +516,9 @@ public:
Printf(f_h, "PHP_RSHUTDOWN_FUNCTION(%s);\n", module);
Printf(f_h, "PHP_MINFO_FUNCTION(%s);\n\n", module);
/* start the arginfo section */
s_arginfo = NewString("/* arginfo subsection */\n");
/* start the function entry section */
s_entry = NewString("/* entry subsection */\n");
@ -644,7 +645,7 @@ public:
Dump(f_directors, f_begin);
}
Printv(f_begin, s_vdecl, s_wrappers, NIL);
Printv(f_begin, all_cs_entry, "\n\n", s_entry,
Printv(f_begin, all_cs_entry, "\n\n", s_arginfo, "\n\n", s_entry,
" SWIG_ZEND_NAMED_FE(swig_", module, "_alter_newobject,_wrap_swig_", module, "_alter_newobject,NULL)\n"
" SWIG_ZEND_NAMED_FE(swig_", module, "_get_newobject,_wrap_swig_", module, "_get_newobject,NULL)\n"
"{NULL, NULL, NULL}\n};\n\n", NIL);
@ -655,6 +656,7 @@ public:
Delete(s_vdecl);
Delete(all_cs_entry);
Delete(s_entry);
Delete(s_arginfo);
Delete(f_runtime);
Delete(f_begin);
@ -673,12 +675,25 @@ public:
}
/* Just need to append function names to function table to register with PHP. */
void create_command(String *cname, String *iname) {
void create_command(String *cname, String *iname, Node *n) {
// This is for the single main zend_function_entry record
Printf(f_h, "ZEND_NAMED_FUNCTION(%s);\n", iname);
String * s = cs_entry;
if (!s) s = s_entry;
Printf(s, " SWIG_ZEND_NAMED_FE(%(lower)s,%s,NULL)\n", cname, iname);
Printf(s, " SWIG_ZEND_NAMED_FE(%(lower)s,%s,swig_arginfo_%(lower)s)\n", cname, iname, cname);
// This is the above referenced arginfo structure.
ParmList *l = Getattr(n, "parms");
Printf(s_arginfo, "ZEND_BEGIN_ARG_INFO_EX(swig_arginfo_%(lower)s, 0, 0, 0)\n", cname);
for (Parm *p = l; p; p = Getattr(p, "tmap:in:next")) {
/* Ignored parameters */
if (checkAttribute(p, "tmap:in:numinputs", "0")) {
continue;
}
int byref = GetFlag(p, "tmap:in:byref");
Printf(s_arginfo, " ZEND_ARG_PASS_INFO(%d)\n", byref);
}
Printf(s_arginfo, "ZEND_END_ARG_INFO()\n");
}
/* ------------------------------------------------------------
@ -701,7 +716,7 @@ public:
String *symname = Getattr(n, "sym:name");
String *wname = Swig_name_wrapper(symname);
create_command(symname, wname);
create_command(symname, wname, n);
Printv(f->def, "ZEND_NAMED_FUNCTION(", wname, ") {\n", NIL);
Wrapper_add_local(f, "argc", "int argc");
@ -719,7 +734,7 @@ public:
Printf(f->code, "SWIG_ErrorCode() = E_ERROR;\n");
Printf(f->code, "SWIG_ErrorMsg() = \"No matching function for overloaded '%s'\";\n", symname);
Printv(f->code, "SWIG_FAIL();\n", NIL);
Printv(f->code, "SWIG_FAIL(TSRMLS_C);\n", NIL);
Printv(f->code, "}\n", NIL);
Wrapper_print(f, s_wrappers);
@ -791,16 +806,16 @@ public:
String *outarg = NewStringEmpty();
String *cleanup = NewStringEmpty();
// Not issued for overloaded functions.
if (!overloaded) {
create_command(iname, wname);
}
Printv(f->def, "ZEND_NAMED_FUNCTION(", wname, ") {\n", NIL);
emit_parameter_variables(l, f);
/* Attach standard typemaps */
emit_attach_parmmaps(l, f);
// Not issued for overloaded functions.
if (!overloaded) {
create_command(iname, wname, n);
}
// wrap:parms is used by overload resolution.
Setattr(n, "wrap:parms", l);
@ -837,7 +852,7 @@ public:
// NOTE: possible we ignore this_ptr as a param for native constructor
Printf(f->code, "SWIG_ResetError();\n");
Printf(f->code, "SWIG_ResetError(TSRMLS_C);\n");
if (numopt > 0) { // membervariable wrappers do not have optional args
Wrapper_add_local(f, "arg_count", "int arg_count");
@ -1002,7 +1017,7 @@ public:
/* Error handling code */
Printf(f->code, "fail:\n");
Printv(f->code, cleanup, NIL);
Append(f->code, "SWIG_FAIL();\n");
Append(f->code, "SWIG_FAIL(TSRMLS_C);\n");
Printf(f->code, "}\n");
@ -1324,6 +1339,7 @@ public:
break;
}
case T_REFERENCE:
case T_RVALUE_REFERENCE:
case T_USER:
case T_ARRAY:
Clear(value);
@ -1366,6 +1382,7 @@ public:
}
}
if (Strcmp(value, "NULL") == 0 ||
Strcmp(value, "nullptr") == 0 ||
Strcmp(value, "0") == 0 ||
Strcmp(value, "0L") == 0) {
Clear(value);
@ -2037,7 +2054,6 @@ done:
// Write property SET handlers
ki = First(shadow_set_vars);
if (ki.key) {
// This class has setters.
Printf(s_phpclasses, "\n\tfunction __set($var,$value) {\n");
@ -2060,17 +2076,6 @@ done:
Printf(s_phpclasses, "\t\t$this->%s[$var] = $value;\n", SWIG_DATA);
}
Printf(s_phpclasses, "\t}\n");
/* Create __isset for PHP 5.1 and later; PHP 5.0 will just ignore it. */
Printf(s_phpclasses, "\n\tfunction __isset($var) {\n");
Printf(s_phpclasses, "\t\tif (function_exists('%s_'.$var.'_set')) return true;\n", shadow_classname);
Printf(s_phpclasses, "\t\tif ($var === 'thisown') return true;\n");
if (baseclass) {
Printf(s_phpclasses, "\t\treturn %s%s::__isset($var);\n", prefix, baseclass);
} else {
Printf(s_phpclasses, "\t\treturn array_key_exists($var, $this->%s);\n", SWIG_DATA);
}
Printf(s_phpclasses, "\t}\n");
} else {
Printf(s_phpclasses, "\n\tfunction __set($var,$value) {\n");
Printf(s_phpclasses, "\t\tif ($var === 'thisown') return swig_%s_alter_newobject($this->%s,$value);\n", module, SWIG_PTR);
@ -2080,18 +2085,10 @@ done:
Printf(s_phpclasses, "\t\t$this->%s[$var] = $value;\n", SWIG_DATA);
}
Printf(s_phpclasses, "\t}\n");
Printf(s_phpclasses, "\n\tfunction __isset($var) {\n");
Printf(s_phpclasses, "\t\tif ($var === 'thisown') return true;\n");
if (baseclass) {
Printf(s_phpclasses, "\t\treturn %s%s::__isset($var);\n", prefix, baseclass);
} else {
Printf(s_phpclasses, "\t\treturn array_key_exists($var, $this->%s);\n", SWIG_DATA);
}
Printf(s_phpclasses, "\t}\n");
}
// Write property GET handlers
ki = First(shadow_get_vars);
if (ki.key) {
// This class has getters.
Printf(s_phpclasses, "\n\tfunction __get($var) {\n");
@ -2127,6 +2124,19 @@ done:
Printf(s_phpclasses, "\t\treturn $this->%s[$var];\n", SWIG_DATA);
}
Printf(s_phpclasses, "\t}\n");
/* Create __isset for PHP 5.1 and later; PHP 5.0 will just ignore it. */
/* __isset() should return true for read-only properties, so check for
* *_get() not *_set(). */
Printf(s_phpclasses, "\n\tfunction __isset($var) {\n");
Printf(s_phpclasses, "\t\tif (function_exists('%s_'.$var.'_get')) return true;\n", shadow_classname);
Printf(s_phpclasses, "\t\tif ($var === 'thisown') return true;\n");
if (baseclass) {
Printf(s_phpclasses, "\t\treturn %s%s::__isset($var);\n", prefix, baseclass);
} else {
Printf(s_phpclasses, "\t\treturn array_key_exists($var, $this->%s);\n", SWIG_DATA);
}
Printf(s_phpclasses, "\t}\n");
} else {
Printf(s_phpclasses, "\n\tfunction __get($var) {\n");
Printf(s_phpclasses, "\t\tif ($var === 'thisown') return swig_%s_get_newobject($this->%s);\n", module, SWIG_PTR);
@ -2136,6 +2146,14 @@ done:
Printf(s_phpclasses, "\t\treturn $this->%s[$var];\n", SWIG_DATA);
}
Printf(s_phpclasses, "\t}\n");
Printf(s_phpclasses, "\n\tfunction __isset($var) {\n");
Printf(s_phpclasses, "\t\tif ($var === 'thisown') return true;\n");
if (baseclass) {
Printf(s_phpclasses, "\t\treturn %s%s::__isset($var);\n", prefix, baseclass);
} else {
Printf(s_phpclasses, "\t\treturn array_key_exists($var, $this->%s);\n", SWIG_DATA);
}
Printf(s_phpclasses, "\t}\n");
}
if (!class_has_ctor) {
@ -2255,8 +2273,8 @@ done:
if (i) {
Insert(args, 0, ", ");
}
Printf(director_ctor_code, "} else {\n %s = (%s *)new SwigDirector_%s(arg0%s TSRMLS_CC);\n}\n", Swig_cresult_name(), ctype, sname, args);
Printf(director_prot_ctor_code, "} else {\n %s = (%s *)new SwigDirector_%s(arg0%s TSRMLS_CC);\n}\n", Swig_cresult_name(), ctype, sname, args);
Printf(director_ctor_code, "} else {\n %s = (%s *)new SwigDirector_%s(arg0 TSRMLS_CC%s);\n}\n", Swig_cresult_name(), ctype, sname, args);
Printf(director_prot_ctor_code, "} else {\n %s = (%s *)new SwigDirector_%s(arg0 TSRMLS_CC%s);\n}\n", Swig_cresult_name(), ctype, sname, args);
Delete(args);
wrapperType = directorconstructor;
@ -2317,7 +2335,7 @@ done:
Append(f->code, "return;\n");
Append(f->code, "fail:\n");
Append(f->code, "SWIG_FAIL();\n");
Append(f->code, "SWIG_FAIL(TSRMLS_C);\n");
Printf(f->code, "}\n");
Wrapper_print(f, s_wrappers);
@ -2368,17 +2386,23 @@ done:
parms = p;
if (!Getattr(n, "defaultargs")) {
// There should always be a "self" parameter first.
assert(ParmList_len(parms) > 0);
/* constructor */
{
Wrapper *w = NewWrapper();
String *call;
String *basetype = Getattr(parent, "classtype");
// We put TSRMLS_DC after the self parameter in order to cope with
// any default parameters.
String *target = Swig_method_decl(0, decl, classname, parms, 0, 0);
if (((const char *)Char(target))[Len(target) - 2] == '(') {
Insert(target, Len(target) - 1, "TSRMLS_D");
} else {
Insert(target, Len(target) - 1, " TSRMLS_DC");
}
const char * p = Char(target);
const char * comma = strchr(p, ',');
size_t ins = comma ? comma - p : Len(target) - 1;
Insert(target, ins, " TSRMLS_DC");
call = Swig_csuperclass_call(0, basetype, superparms);
Printf(w->def, "%s::%s: %s, Swig::Director(self TSRMLS_CC) {", classname, target, call);
Append(w->def, "}");
@ -2390,12 +2414,14 @@ done:
/* constructor header */
{
// We put TSRMLS_DC after the self parameter in order to cope with
// any default parameters.
String *target = Swig_method_decl(0, decl, classname, parms, 0, 1);
if (((const char *)Char(target))[Len(target) - 2] == '(') {
Insert(target, Len(target) - 1, "TSRMLS_D");
} else {
Insert(target, Len(target) - 1, " TSRMLS_DC");
}
const char * p = Char(target);
const char * comma = strchr(p, ',');
size_t ins = comma ? comma - p : Len(target) - 1;
Insert(target, ins, " TSRMLS_DC");
Printf(f_directors_h, " %s;\n", target);
Delete(target);
}
@ -2625,8 +2651,7 @@ done:
if (!is_void) {
tm = Swig_typemap_lookup("directorout", n, Swig_cresult_name(), w);
if (tm != 0) {
static const String *amp_result = NewStringf("&%s", Swig_cresult_name());
Replaceall(tm, "$input", amp_result);
Replaceall(tm, "$input", Swig_cresult_name());
char temp[24];
sprintf(temp, "%d", idx);
Replaceall(tm, "$argnum", temp);
@ -2682,7 +2707,7 @@ done:
}
Append(w->code, "fail:\n");
Append(w->code, "SWIG_FAIL();\n");
Append(w->code, "SWIG_FAIL(TSRMLS_C);\n");
Append(w->code, "}\n");
// We expose protected methods via an extra public inline method which makes a straight call to the wrapped class' method

View file

@ -33,7 +33,7 @@
#include <ctype.h> // for isalnum()
static const char *usage = (char *) "\
static const char *usage = "\
Pike Options (available with -pike)\n\
[no additional options]\n\
\n";

View file

@ -94,6 +94,7 @@ static int castmode = 0;
static int extranative = 0;
static int outputtuple = 0;
static int nortti = 0;
static int relativeimport = 0;
/* flags for the make_autodoc function */
enum autodoc_t {
@ -106,7 +107,7 @@ enum autodoc_t {
};
static const char *usage1 = (char *) "\
static const char *usage1 = "\
Python Options (available with -python)\n\
-aliasobj0 - Alias obj0 when using fastunpack, needed for some old typemaps \n\
-buildnone - Use Py_BuildValue(" ") to obtain Py_None (default in Windows)\n\
@ -126,7 +127,7 @@ Python Options (available with -python)\n\
-keyword - Use keyword arguments\n\
-modern - Use modern python features only, without compatibility code\n\
-modernargs - Use \"modern\" args mechanism to pack/unpack the function arguments\n";
static const char *usage2 = (char *) "\
static const char *usage2 = "\
-newrepr - Use more informative version of __repr__ in proxy classes (default) \n\
-newvwm - New value wrapper mode, use only when everything else fails \n\
-noaliasobj0 - Don't generate an obj0 alias when using fastunpack (default) \n\
@ -143,7 +144,7 @@ static const char *usage2 = (char *) "\
-noh - Don't generate the output header file\n\
-nomodern - Don't use modern python features which are not backwards compatible \n\
-nomodernargs - Use classic ParseTuple/CallFunction methods to pack/unpack the function arguments (default) \n";
static const char *usage3 = (char *) "\
static const char *usage3 = "\
-noolddefs - Don't emit the old method definitions even when using fastproxy (default) \n\
-nooutputtuple - Use a PyList for appending output values (default) \n\
-noproxy - Don't generate proxy classes \n\
@ -156,6 +157,7 @@ static const char *usage3 = (char *) "\
-oldrepr - Use shorter and old version of __repr__ in proxy classes\n\
-outputtuple - Use a PyTuple for outputs instead of a PyList (use carefully with legacy interfaces) \n\
-proxydel - Generate a __del__ method even though it is now redundant (default) \n\
-relativeimport - Use relative python imports \n\
-safecstrings - Use safer (but slower) C string mapping, generating copies from Python -> C/C++\n\
-threads - Add thread support for all the interface\n\
-O - Enable the following optimization options: \n\
@ -520,6 +522,9 @@ public:
builtin = 1;
Preprocessor_define("SWIGPYTHON_BUILTIN", 0);
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-relativeimport") == 0) {
relativeimport = 1;
Swig_mark_arg(i);
}
}
@ -1028,6 +1033,267 @@ public:
return 0;
}
/* ------------------------------------------------------------
* subpkg_tail()
*
* Return the name of 'other' package relative to 'base'.
*
* 1. If 'other' is a sub-package of 'base', returns the 'other' relative to
* 'base'.
* 2. If 'other' and 'base' are equal, returns empty string "".
* 3. In any other case, NULL pointer is returned.
*
* The 'base' and 'other' are expected to be fully qualified names.
*
* NOTE: none of 'base' nor 'other' can be null.
*
* Examples:
*
* # base other tail
* -- ---- ----- ----
* 1 "Foo" "Foo.Bar" -> "Bar"
* 2 "Foo" "Foo." -> ""
* 3 "Foo" "FooB.ar" -> NULL
* 4 "Foo.Bar" "Foo.Bar" -> ""
* 5 "Foo.Bar" "Foo" -> NULL
* 6 "Foo.Bar" "Foo.Gez" -> NULL
*
* NOTE: the example #2 is actually a syntax error (at input). I believe
* swig parser prevents us from this case happening here.
* ------------------------------------------------------------ */
static String *subpkg_tail(const String *base, const String *other) {
int baselen = Len(base);
int otherlen = Len(other);
if (Strncmp(other, base, baselen) == 0) {
if ((baselen < otherlen) && (Char(other))[baselen] == '.') {
return NewString((Char(other)) + baselen + 1);
} else if (baselen == otherlen) {
return NewString("");
} else {
return 0;
}
} else {
return 0;
}
}
/* ------------------------------------------------------------
* abs_import_directive_string()
*
* Return a string containing python code to import module.
*
* pkg package name or the module being imported
* mod module name of the module being imported
* pfx optional prefix to module name
*
* NOTE: keep this function consistent with abs_import_name_string().
* ------------------------------------------------------------ */
static String *abs_import_directive_string(const String *pkg, const String *mod, const char *pfx = "") {
String *out = NewString("");
if (pkg && *Char(pkg)) {
Printf(out, "import %s.%s%s\n", pkg, pfx, mod);
} else {
Printf(out, "import %s%s\n", pfx, mod);
}
return out;
}
/* ------------------------------------------------------------
* rel_import_directive_string()
*
* Return a string containing python code to import module that
* is potentially within a package.
*
* mainpkg package name of the module which imports the other module
* pkg package name or the module being imported
* mod module name of the module being imported
* pfx optional prefix to module name
*
* NOTE: keep this function consistent with rel_import_name_string().
* ------------------------------------------------------------ */
static String *rel_import_directive_string(const String *mainpkg, const String *pkg, const String *mod, const char *pfx = "") {
/* NOTE: things are not so trivial. This is what we do here (by examples):
*
* 0. To import module 'foo', which is not in any package, we do absolute
* import:
*
* import foo
*
* 1. To import 'pkg1.pkg2.foo', when mainpkg != "pkg1" and
* mainpkg != "pkg1.pkg2" or when mainpkg is not given we do absolute
* import:
*
* import pkg1.pkg2.foo
*
* 2. To import module pkg1.foo, when mainpkg == "pkg1", we do:
*
* - for py3 = 0:
*
* import foo
*
* - for py3 = 1:
*
* from . import foo
*
* 3. To import "pkg1.pkg2.pkg3.foo", when mainpkg = "pkg1", we do:
*
* - for py3 == 0:
*
* import pkg2.pkg3.foo
*
* - for py3 == 1:
*
* from . import pkg2 # [1]
* import pkg1.pkg2.pkg3.foo
*
* NOTE: [1] is necessary for pkg2.foo to be present in the importing module
*/
String *apkg = 0; // absolute (FQDN) package name of pkg
String *rpkg = 0; // relative package name
int py3_rlen1 = 0; // length of 1st level sub-package name, used by py3
String *out = NewString("");
if (pkg && *Char(pkg)) {
if (mainpkg) {
String *tail = subpkg_tail(mainpkg, pkg);
if (tail) {
if (*Char(tail)) {
rpkg = NewString(tail);
const char *py3_end1 = Strchr(rpkg, '.');
if (!py3_end1)
py3_end1 = (Char(rpkg)) + Len(rpkg);
py3_rlen1 = py3_end1 - (Char(rpkg));
} else {
rpkg = NewString("");
}
Delete(tail);
} else {
apkg = NewString(pkg);
}
} else {
apkg = NewString(pkg);
}
} else {
apkg = NewString("");
}
if (apkg) {
Printf(out, "import %s%s%s%s\n", apkg, *Char(apkg) ? "." : "", pfx, mod);
Delete(apkg);
} else {
if (py3) {
if (py3_rlen1)
Printf(out, "from . import %.*s\n", py3_rlen1, rpkg);
Printf(out, "from .%s import %s%s\n", rpkg, pfx, mod);
} else {
Printf(out, "import %s%s%s%s\n", rpkg, *Char(rpkg) ? "." : "", pfx, mod);
}
Delete(rpkg);
}
return out;
}
/* ------------------------------------------------------------
* import_directive_string()
* ------------------------------------------------------------ */
static String *import_directive_string(const String *mainpkg, const String *pkg, const String *mod, const char *pfx = "") {
if (!relativeimport) {
return abs_import_directive_string(pkg, mod, pfx);
} else {
return rel_import_directive_string(mainpkg, pkg, mod, pfx);
}
}
/* ------------------------------------------------------------
* abs_import_name_string()
*
* Return a string with the name of a symbol (perhaps imported
* from external module by absolute import directive).
*
* mainpkg package name of current module
* mainmod module name of current module
* pkg package name of (perhaps other) module
* mod module name of (perhaps other) module
* sym symbol name
*
* NOTE: mainmod, mod, and sym can't be NULL.
* NOTE: keep this function consistent with abs_import_directive_string()
* ------------------------------------------------------------ */
static String *abs_import_name_string(const String *mainpkg, const String *mainmod, const String *pkg, const String *mod, const String *sym) {
String *out = NewString("");
if (pkg && *Char(pkg)) {
if (mainpkg && *Char(mainpkg)) {
if (Strcmp(mainpkg,pkg) != 0 || Strcmp(mainmod, mod) != 0) {
Printf(out, "%s.%s.", pkg, mod);
}
} else {
Printf(out, "%s.%s.", pkg, mod);
}
} else if ((mainpkg && *Char(mainpkg)) || Strcmp(mainmod, mod) != 0) {
Printf(out, "%s.", mod);
}
Append(out, sym);
return out;
}
/* ------------------------------------------------------------
* rel_import_name_string()
*
* Return a string with the name of a symbol (perhaps imported
* from external module by relative import directive).
*
* mainpkg package name of current module
* mainmod module name of current module
* pkg package name of (perhaps other) module
* mod module name of (perhaps other) module
* sym symbol name
*
* NOTE: mainmod, mod, and sym can't be NULL.
* NOTE: keep this function consistent with rel_import_directive_string()
* ------------------------------------------------------------ */
static String *rel_import_name_string(const String *mainpkg, const String *mainmod, const String *pkg, const String *mod, const String *sym) {
String *out = NewString("");
if (pkg && *Char(pkg)) {
String *tail = 0;
if (mainpkg)
tail = subpkg_tail(mainpkg, pkg);
if (!tail)
tail = NewString(pkg);
if (*Char(tail)) {
Printf(out, "%s.%s.", tail, mod);
} else if (Strcmp(mainmod, mod) != 0) {
Printf(out, "%s.", mod);
}
Delete(tail);
} else if ((mainpkg && *Char(mainpkg)) || Strcmp(mainmod, mod) != 0) {
Printf(out, "%s.", mod);
}
Append(out, sym);
return out;
}
/* ------------------------------------------------------------
* import_name_string()
* ------------------------------------------------------------ */
static String *import_name_string(const String *mainpkg, const String *mainmod, const String *pkg, const String *mod, const String *sym) {
if (!relativeimport) {
return abs_import_name_string(mainpkg,mainmod,pkg,mod,sym);
} else {
return rel_import_name_string(mainpkg,mainmod,pkg,mod,sym);
}
}
/* ------------------------------------------------------------
* importDirective()
* ------------------------------------------------------------ */
@ -1037,38 +1303,26 @@ public:
String *modname = Getattr(n, "module");
if (modname) {
String *import = NewString("import ");
// Find the module node for this imported module. It should be the
// first child but search just in case.
Node *mod = firstChild(n);
while (mod && Strcmp(nodeType(mod), "module") != 0)
mod = nextSibling(mod);
// Is the imported module in another package? (IOW, does it use the
// %module(package="name") option and it's different than the package
// of this module.)
Node *options = Getattr(mod, "options");
String *pkg = options ? Getattr(options, "package") : 0;
if (pkg) {
Printf(import, "%s.", pkg);
}
// finally, output the name of the imported module
if (shadowimport) {
if (!options || (!Getattr(options, "noshadow") && !Getattr(options, "noproxy"))) {
Printf(import, "_%s\n", modname);
if (!GetFlagAttr(f_shadow_imports, import)) {
if (pkg) {
Printf(builtin ? f_shadow_builtin_imports : f_shadow, "import %s.%s\n", pkg, modname);
} else {
Printf(builtin ? f_shadow_builtin_imports : f_shadow, "import %s\n", modname);
}
SetFlag(f_shadow_imports, import);
String *_import = import_directive_string(package, pkg, modname, "_");
if (!GetFlagAttr(f_shadow_imports, _import)) {
String *import = import_directive_string(package, pkg, modname);
Printf(builtin ? f_shadow_builtin_imports : f_shadow, "%s", import);
Delete(import);
SetFlag(f_shadow_imports, _import);
}
Delete(_import);
}
}
Delete(import);
}
}
return Language::importDirective(n);
@ -1563,7 +1817,7 @@ public:
return NewString("True");
if (Strcmp(v, "false") == 0 || Strcmp(v, "FALSE") == 0)
return NewString("False");
if (Strcmp(v, "NULL") == 0)
if (Strcmp(v, "NULL") == 0 || Strcmp(v, "nullptr") == 0)
return SwigType_ispointer(t) ? NewString("None") : NewString("0");
}
return 0;
@ -2311,7 +2565,7 @@ public:
Printf(parse_args, "if (!SWIG_Python_UnpackTuple(args,\"%s\",%d,%d,0)) SWIG_fail;\n", iname, num_fixed_arguments, tuple_arguments);
}
}
} else if (tuple_arguments > 0) {
} else {
Printf(parse_args, "if(!PyArg_UnpackTuple(args,(char *)\"%s\",%d,%d", iname, num_fixed_arguments, tuple_arguments);
Printv(parse_args, arglist, ")) SWIG_fail;\n", NIL);
}
@ -3074,22 +3328,23 @@ public:
But for now, this seems to be the least intrusive way.
*/
Printf(f_directors_h, "\n\n");
Printf(f_directors_h, "/* Internal Director utilities */\n");
Printf(f_directors_h, "\n");
Printf(f_directors_h, "/* Internal director utilities */\n");
Printf(f_directors_h, "public:\n");
Printf(f_directors_h, " bool swig_get_inner(const char* swig_protected_method_name) const {\n");
Printf(f_directors_h, " bool swig_get_inner(const char *swig_protected_method_name) const {\n");
Printf(f_directors_h, " std::map<std::string, bool>::const_iterator iv = swig_inner.find(swig_protected_method_name);\n");
Printf(f_directors_h, " return (iv != swig_inner.end() ? iv->second : false);\n");
Printf(f_directors_h, " }\n\n");
Printf(f_directors_h, " }\n");
Printf(f_directors_h, " void swig_set_inner(const char* swig_protected_method_name, bool val) const\n");
Printf(f_directors_h, " { swig_inner[swig_protected_method_name] = val;}\n\n");
Printf(f_directors_h, " void swig_set_inner(const char *swig_protected_method_name, bool val) const {\n");
Printf(f_directors_h, " swig_inner[swig_protected_method_name] = val;\n");
Printf(f_directors_h, " }\n");
Printf(f_directors_h, "private:\n");
Printf(f_directors_h, " mutable std::map<std::string, bool> swig_inner;\n");
}
if (director_method_index) {
Printf(f_directors_h, "\n\n");
Printf(f_directors_h, "\n");
Printf(f_directors_h, "#if defined(SWIG_PYTHON_DIRECTOR_VTABLE)\n");
Printf(f_directors_h, "/* VTable implementation */\n");
Printf(f_directors_h, " PyObject *swig_get_method(size_t method_index, const char *method_name) const {\n");
@ -3163,19 +3418,13 @@ public:
if (shadow && !Getattr(n, "feature:onlychildren")) {
Node *mod = Getattr(n, "module");
if (mod) {
String *importname = NewString("");
String *modname = Getattr(mod, "name");
if (Strcmp(modname, mainmodule) != 0) {
// check if the module has a package option
Node *options = Getattr(mod, "options");
String *pkg = options ? Getattr(options, "package") : 0;
if (pkg) {
Printf(importname, "%s.", pkg);
}
Printf(importname, "%s.", modname);
}
Append(importname, Getattr(n, "sym:name"));
Node *options = Getattr(mod, "options");
String *pkg = options ? Getattr(options, "package") : 0;
String *sym = Getattr(n, "sym:name");
String *importname = import_name_string(package, mainmodule, pkg, modname, sym);
Setattr(n, "python:proxy", importname);
Delete(importname);
}
}
int result = Language::classDeclaration(n);
@ -3343,7 +3592,20 @@ public:
if (GetFlag(n, "feature:python:nondynamic"))
Setattr(n, "feature:python:tp_setattro", "SWIG_Python_NonDynamicSetAttr");
String *quoted_symname = NewStringf("\"%s\"", symname);
Node *mod = Getattr(n, "module");
String *modname = mod ? Getattr(mod, "name") : 0;
String *quoted_symname;
if (package) {
if (modname)
quoted_symname = NewStringf("\"%s.%s.%s\"", package, modname, symname);
else
quoted_symname = NewStringf("\"%s.%s\"", package, symname);
} else {
if (modname)
quoted_symname = NewStringf("\"%s.%s\"", modname, symname);
else
quoted_symname = NewStringf("\"%s\"", symname);
}
String *quoted_rname = NewStringf("\"%s\"", rname);
char const *tp_init = builtin_tp_init ? Char(builtin_tp_init) : Swig_directorclass(n) ? "0" : "SwigPyBuiltin_BadInit";
String *tp_flags = NewString("Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_CHECKTYPES");

View file

@ -14,7 +14,6 @@
#include "swigmod.h"
static const double DEFAULT_NUMBER = .0000123456712312312323;
static const int MAX_OVERLOAD_ARGS = 5;
static String* replaceInitialDash(const String *name)
{
@ -206,7 +205,7 @@ static void writeListByLine(List *l, File *out, bool quote = 0) {
}
static const char *usage = (char *)"\
static const char *usage = "\
R Options (available with -r)\n\
-copystruct - Emit R code to copy C structs (on by default)\n\
-cppcast - Enable C++ casting operators (default) \n\
@ -2161,7 +2160,7 @@ int R::functionWrapper(Node *n) {
/* If we are dealing with a method in an C++ class, then
add the name of the R function and its definition.
XXX need to figure out how to store the Wrapper if possible in the hash/list.
Would like to be able to do this so that we can potentialy insert
Would like to be able to do this so that we can potentially insert
*/
if(processing_member_access_function || processing_class_member_function) {
addAccessor(member_name, sfun, iname);
@ -2299,7 +2298,7 @@ int R::classDeclaration(Node *n) {
/* If we have a typedef union { ... } U, then we never get to see the typedef
via a regular call to typedefHandler. Instead, */
if(Getattr(n, "unnamed") && Strcmp(Getattr(n, "storage"), "typedef") == 0
if(Getattr(n, "unnamed") && Getattr(n, "storage") && Strcmp(Getattr(n, "storage"), "typedef") == 0
&& Getattr(n, "tdname") && Strcmp(Getattr(n, "tdname"), name) == 0) {
if (debugMode)
Printf(stdout, "Typedef in the class declaration for %s\n", name);

View file

@ -130,7 +130,7 @@ enum autodoc_t {
AUTODOC_NONE
};
static const char *usage = (char *) "\
static const char *usage = "\
Ruby Options (available with -ruby)\n\
-autorename - Enable renaming of classes and methods to follow Ruby coding standards\n\
-cppcast - Enable C++ casting operators (default)\n\
@ -788,7 +788,7 @@ private:
else
return v;
}
if (Strcmp(v, "NULL") == 0)
if (Strcmp(v, "NULL") == 0 || Strcmp(v, "nullptr") == 0)
return SwigType_ispointer(t) ? NewString("nil") : NewString("0");
if (Strcmp(v, "true") == 0 || Strcmp(v, "TRUE") == 0)
return NewString("True");
@ -1111,7 +1111,7 @@ public:
/* typedef void *VALUE */
SwigType *value = NewSwigType(T_VOID);
SwigType_add_pointer(value);
SwigType_typedef(value, (char *) "VALUE");
SwigType_typedef(value, "VALUE");
Delete(value);
/* Set module name */

View file

@ -52,6 +52,7 @@ extern "C" {
Language *swig_scilab(void);
Language *swig_go(void);
Language *swig_d(void);
Language *swig_javascript(void);
}
struct swig_module {
@ -74,6 +75,7 @@ static swig_module modules[] = {
{"-go", swig_go, "Go"},
{"-guile", swig_guile, "Guile"},
{"-java", swig_java, "Java"},
{"-javascript", swig_javascript, "Javascript"},
{"-lua", swig_lua, "Lua"},
{"-modula3", swig_modula3, "Modula 3"},
{"-mzscheme", swig_mzscheme, "Mzscheme"},

View file

@ -99,6 +99,7 @@ public:
virtual int usingDeclaration(Node *n);
virtual int namespaceDeclaration(Node *n);
virtual int templateDeclaration(Node *n);
virtual int lambdaDeclaration(Node *n);
enum AccessMode { PUBLIC, PRIVATE, PROTECTED };
@ -214,7 +215,10 @@ public:
virtual int validIdentifier(String *s); /* valid identifier? */
virtual int addSymbol(const String *s, const Node *n, const_String_or_char_ptr scope = ""); /* Add symbol */
virtual void dumpSymbols();
virtual Node *symbolLookup(String *s, const_String_or_char_ptr scope = ""); /* Symbol lookup */
virtual Node *symbolLookup(String *s, const_String_or_char_ptr scope = ""); /* Symbol lookup */
virtual Hash* symbolAddScope(const_String_or_char_ptr scope);
virtual Hash* symbolScopeLookup(const_String_or_char_ptr scope);
virtual Hash* symbolScopePseudoSymbolLookup(const_String_or_char_ptr scope);
virtual Node *classLookup(const SwigType *s) const; /* Class lookup */
virtual Node *enumLookup(SwigType *s); /* Enum lookup */
virtual int abstractClassTest(Node *n); /* Is class really abstract? */
@ -296,6 +300,22 @@ protected:
/* Some language modules require additional wrappers for virtual methods not declared in sub-classes */
virtual bool extraDirectorProtectedCPPMethodsRequired() const;
public:
enum NestedClassSupport {
NCS_None, // Target language does not have an equivalent to nested classes
NCS_Full, // Target language does have an equivalent to nested classes and is fully implemented
NCS_Unknown // Target language may or may not have an equivalent to nested classes. If it does, it has not been implemented yet.
};
/* Does target language support nested classes? Default is NCS_Unknown.
If NCS_Unknown is returned, then the nested classes will be ignored unless
%feature "flatnested" is applied to them, in which case they will appear in global space.
If the target language does not support the notion of class
nesting, the language module should return NCS_None from this function, and
the nested classes will be moved to the global scope (like implicit global %feature "flatnested").
*/
virtual NestedClassSupport nestedClassesSupport() const;
protected:
/* Identifies if a protected members that are generated when the allprotected option is used.
This does not include protected virtual methods as they are turned on with the dirprot option. */
bool isNonVirtualProtectedAccess(Node *n) const;
@ -409,5 +429,19 @@ int Swig_contract_mode_get();
void Swig_browser(Node *n, int);
void Swig_default_allocators(Node *n);
void Swig_process_types(Node *n);
void Swig_nested_process_classes(Node *n);
void Swig_nested_name_unnamed_c_structs(Node *n);
template <class T> class save_value {
T _value;
T& _value_ptr;
save_value(const save_value&);
save_value& operator=(const save_value&);
public:
save_value(T& value) : _value(value), _value_ptr(value) {}
save_value(T& value, T new_val) : _value(value), _value_ptr(value) { value = new_val; }
~save_value() { _value_ptr = _value; }
};
#endif

View file

@ -15,7 +15,7 @@
#include "cparse.h"
static int treduce = SWIG_cparse_template_reduce(0);
static const char *usage = (char *) "\
static const char *usage = "\
Tcl 8 Options (available with -tcl)\n\
-itcl - Enable ITcl support\n\
-nosafe - Leave out SafeInit module function.\n\

View file

@ -178,6 +178,20 @@ class TypePass:private Dispatcher {
}
continue;
}
// A case when both outer and nested classes inherit from the same parent. Constructor may be found instead of the class itself.
} else if (GetFlag(cls, "nested") && checkAttribute(bcls, "nodeType", "constructor")) {
bcls = Getattr(bcls, "parentNode");
if (Getattr(bcls, "typepass:visit")) {
if (!Getattr(bcls, "feature:onlychildren")) {
if (!ilist)
ilist = alist = NewList();
Append(ilist, bcls);
} else {
Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bname), Getline(bname), "Base class '%s' has no name as it is an empty template instantiated with '%%template()'. Ignored.\n", SwigType_namestr(bname));
Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bcls), Getline(bcls), "The %%template directive must be written before '%s' is used as a base class and be declared with a name.\n", SwigType_namestr(bname));
}
}
break;
}
if (Strcmp(nodeType(bcls), "classforward") != 0) {
Swig_error(Getfile(bname), Getline(bname), "'%s' is not a valid base class.\n", SwigType_namestr(bname));
@ -403,7 +417,7 @@ class TypePass:private Dispatcher {
String *unnamed = Getattr(n, "unnamed");
String *storage = Getattr(n, "storage");
String *kind = Getattr(n, "kind");
Node *oldinclass = inclass;
save_value<Node*> oldinclass(inclass);
List *olist = normalize;
Symtab *symtab;
String *nname = 0;
@ -462,6 +476,17 @@ class TypePass:private Dispatcher {
if (unnamed && tdname && (Cmp(storage, "typedef") == 0)) {
SwigType_typedef(unnamed, tdname);
}
// name of the outer class should already be patched to contain its outer classes names, but not to contain namespaces
// namespace name (if present) is added after processing child nodes
if (Getattr(n, "nested:outer") && name) {
String *outerName = Getattr(Getattr(n, "nested:outer"), "name");
name = NewStringf("%s::%s", outerName, name);
Setattr(n, "name", name);
if (tdname) {
tdname = NewStringf("%s::%s", outerName, tdname);
Setattr(n, "tdname", tdname);
}
}
if (nsname && name) {
nname = NewStringf("%s::%s", nsname, name);
@ -479,7 +504,8 @@ class TypePass:private Dispatcher {
SwigType_attach_symtab(Getattr(n, "symtab"));
/* Inherit type definitions into the class */
if (name) {
if (name && !(GetFlag(n, "nested") && !checkAttribute(n, "access", "public") &&
(GetFlag(n, "feature:flatnested") || Language::instance()->nestedClassesSupport() == Language::NCS_None))) {
cplus_inherit_types(n, 0, nname ? nname : (fname ? fname : name));
}
@ -512,8 +538,6 @@ class TypePass:private Dispatcher {
normalize = olist;
inclass = oldinclass;
/* If in a namespace, patch the class name */
if (nname) {
Setattr(n, "name", nname);
@ -524,7 +548,7 @@ class TypePass:private Dispatcher {
}
/* ------------------------------------------------------------
* namespaceDeclaration()
* templateDeclaration()
* ------------------------------------------------------------ */
virtual int templateDeclaration(Node *n) {
@ -543,6 +567,14 @@ class TypePass:private Dispatcher {
return SWIG_OK;
}
/* ------------------------------------------------------------
* lambdaDeclaration()
* ------------------------------------------------------------ */
virtual int lambdaDeclaration(Node *) {
return SWIG_OK;
}
/* ------------------------------------------------------------
* classforwardDeclaration()
* ------------------------------------------------------------ */
@ -635,6 +667,9 @@ class TypePass:private Dispatcher {
/* Normalize types. */
SwigType *ty = Getattr(n, "type");
if (!ty) {
return SWIG_OK;
}
normalize_type(ty);
SwigType *decl = Getattr(n, "decl");
if (decl) {
@ -645,7 +680,7 @@ class TypePass:private Dispatcher {
if (GetFlag(n, "conversion_operator")) {
/* The call to the operator in the generated wrapper must be fully qualified in order to compile */
SwigType *name = Getattr(n, "name");
SwigType *qualifiedname = Swig_symbol_string_qualify(name,0);
SwigType *qualifiedname = Swig_symbol_string_qualify(name, 0);
Clear(name);
Append(name, qualifiedname);
Delete(qualifiedname);
@ -844,16 +879,17 @@ class TypePass:private Dispatcher {
virtual int enumvalueDeclaration(Node *n) {
String *name = Getattr(n, "name");
String *value = Getattr(n, "value");
String *scopedenum = Getattr(parentNode(n), "scopedenum");
if (!value)
value = name;
if (Strcmp(value, name) == 0) {
String *new_value;
if ((nsname || inclass) && cparse_cplusplus) {
if ((nsname || inclass || scopedenum) && cparse_cplusplus) {
new_value = NewStringf("%s::%s", SwigType_namestr(Swig_symbol_qualified(n)), value);
} else {
new_value = NewString(value);
}
if ((nsname || inclass) && !cparse_cplusplus) {
if ((nsname || inclass || scopedenum) && !cparse_cplusplus) {
String *cppvalue = NewStringf("%s::%s", SwigType_namestr(Swig_symbol_qualified(n)), value);
Setattr(n, "cppvalue", cppvalue); /* for target languages that always generate C++ code even when wrapping C code */
}
@ -986,7 +1022,7 @@ class TypePass:private Dispatcher {
String *symname = Getattr(n, "sym:name");
while (c) {
if (Strcmp(nodeType(c), "cdecl") == 0) {
if (!(checkAttribute(c, "storage", "static")
if (!(Swig_storage_isstatic(c)
|| checkAttribute(c, "storage", "typedef")
|| checkAttribute(c, "storage", "friend")
|| (Getattr(c, "feature:extend") && !Getattr(c, "code"))
@ -1081,8 +1117,7 @@ class TypePass:private Dispatcher {
* list of overloaded methods we have just added in as child nodes to the "using" node.
* The node will still exist, it is just the symbol table linked list of overloaded methods
* which is hacked. */
if (Getattr(n, "sym:overloaded"))
{
if (Getattr(n, "sym:overloaded")) {
int cnt = 0;
#ifdef DEBUG_OVERLOADED
Node *debugnode = n;
@ -1145,7 +1180,7 @@ class TypePass:private Dispatcher {
#ifdef DEBUG_OVERLOADED
show_overloaded(debugnode);
#endif
clean_overloaded(n); // Needed?
clean_overloaded(n); // Needed?
}
}
}
@ -1249,3 +1284,4 @@ void Swig_process_types(Node *n) {
return;
TypePass::pass(n);
}

View file

@ -15,7 +15,7 @@
#include "swigmod.h"
static const char *usage = (char *) "\
static const char *usage = "\
UFFI Options (available with -uffi)\n\
-identifier-converter <type or funcname> - \n\
Specifies the type of conversion to do on C identifiers\n\

View file

@ -13,8 +13,8 @@
* ----------------------------------------------------------------------------- */
#include "swig.h"
#include "cparse.h"
extern int cparse_cplusplus;
static const char *cresult_variable_name = "result";
static Parm *nonvoid_parms(Parm *p) {
@ -88,6 +88,19 @@ static String *Swig_clocal(SwigType *t, const_String_or_char_ptr name, const_Str
Delete(lstrname);
}
break;
case T_RVALUE_REFERENCE:
if (value) {
String *lstrname = SwigType_lstr(t, name);
String *lstr = SwigType_lstr(t, 0);
Printf(decl, "%s = (%s) &%s_defrvalue", lstrname, lstr, name);
Delete(lstrname);
Delete(lstr);
} else {
String *lstrname = SwigType_lstr(t, name);
Printf(decl, "%s = 0", lstrname);
Delete(lstrname);
}
break;
case T_VOID:
break;
case T_VARARGS:
@ -253,7 +266,35 @@ int Swig_cargs(Wrapper *w, ParmList *p) {
Delete(defname);
Delete(defvalue);
}
} else if (!pvalue && ((tycode == T_POINTER) || (tycode == T_STRING))) {
} else if (tycode == T_RVALUE_REFERENCE) {
if (pvalue) {
SwigType *tvalue;
String *defname, *defvalue, *rvalue, *qvalue;
rvalue = SwigType_typedef_resolve_all(pvalue);
qvalue = SwigType_typedef_qualified(rvalue);
defname = NewStringf("%s_defrvalue", lname);
tvalue = Copy(type);
SwigType_del_rvalue_reference(tvalue);
tycode = SwigType_type(tvalue);
if (tycode != T_USER) {
/* plain primitive type, we copy the the def value */
String *lstr = SwigType_lstr(tvalue, defname);
defvalue = NewStringf("%s = %s", lstr, qvalue);
Delete(lstr);
} else {
/* user type, we copy the reference value */
String *str = SwigType_str(type, defname);
defvalue = NewStringf("%s = %s", str, qvalue);
Delete(str);
}
Wrapper_add_localv(w, defname, defvalue, NIL);
Delete(tvalue);
Delete(rvalue);
Delete(qvalue);
Delete(defname);
Delete(defvalue);
}
} else if (!pvalue && ((tycode == T_POINTER) || (tycode == T_STRING) || (tycode == T_WSTRING))) {
pvalue = (String *) "0";
}
if (!altty) {
@ -293,6 +334,23 @@ String *Swig_cresult(SwigType *t, const_String_or_char_ptr name, const_String_or
Delete(lstr);
}
break;
case T_RVALUE_REFERENCE:
{
String *const_lvalue_str;
String *lstr = SwigType_lstr(t, 0);
SwigType *tt = Copy(t);
SwigType_del_rvalue_reference(tt);
SwigType_add_qualifier(tt, "const");
SwigType_add_reference(tt);
const_lvalue_str = SwigType_rcaststr(tt, 0);
Printf(fcall, "%s = (%s) &%s", name, lstr, const_lvalue_str);
Delete(const_lvalue_str);
Delete(tt);
Delete(lstr);
}
break;
case T_USER:
Printf(fcall, "%s = ", name);
break;
@ -409,7 +467,7 @@ static String *Swig_cmethod_call(const_String_or_char_ptr name, ParmList *parms,
return func;
if (!self)
self = (char *) "(this)->";
self = "(this)->";
Append(func, self);
if (SwigType_istemplate(name) && (strncmp(Char(name), "operator ", 9) == 0)) {
@ -717,7 +775,25 @@ String *Swig_cmemberset_call(const_String_or_char_ptr name, SwigType *type, Stri
if (SwigType_type(type) != T_ARRAY) {
if (!Strstr(type, "enum $unnamed")) {
String *dref = Swig_wrapped_var_deref(type, pname1, varcref);
Printf(func, "if (%s) %s%s = %s", pname0, self, name, dref);
int extra_cast = 0;
if (cparse_cplusplusout) {
/* Required for C nested structs compiled as C++ as a duplicate of the nested struct is put into the global namespace.
* We could improve this by adding the extra casts just for nested structs rather than all structs. */
String *base = SwigType_base(type);
extra_cast = SwigType_isclass(base);
Delete(base);
}
if (extra_cast) {
String *lstr;
SwigType *ptype = Copy(type);
SwigType_add_pointer(ptype);
lstr = SwigType_lstr(ptype, 0);
Printf(func, "if (%s) *(%s)&%s%s = %s", pname0, lstr, self, name, dref);
Delete(lstr);
Delete(ptype);
} else {
Printf(func, "if (%s) %s%s = %s", pname0, self, name, dref);
}
Delete(dref);
} else {
Printf(func, "if (%s && sizeof(int) == sizeof(%s%s)) *(int*)(void*)&(%s%s) = %s", pname0, self, name, self, name, pname1);
@ -864,8 +940,8 @@ int Swig_MethodToFunction(Node *n, const_String_or_char_ptr nspace, String *clas
self = NewString("(*(this))->");
is_smart_pointer_overload = 1;
}
else if (Cmp(Getattr(n, "storage"), "static") == 0) {
String *cname = Getattr(n, "classname") ? Getattr(n, "classname") : classname;
else if (Swig_storage_isstatic(n)) {
String *cname = Getattr(n, "extendsmartclassname") ? Getattr(n, "extendsmartclassname") : classname;
String *ctname = SwigType_namestr(cname);
self = NewStringf("(*(%s const *)this)->", ctname);
is_smart_pointer_overload = 1;
@ -982,7 +1058,7 @@ int Swig_MethodToFunction(Node *n, const_String_or_char_ptr nspace, String *clas
String *defaultargs = Getattr(n, "defaultargs");
String *code = Getattr(n, "code");
String *cname = Getattr(n, "classname") ? Getattr(n, "classname") : classname;
String *cname = Getattr(n, "extendsmartclassname") ? Getattr(n, "extendsmartclassname") : classname;
String *membername = Swig_name_member(nspace, cname, name);
String *mangled = Swig_name_mangle(membername);
int is_smart_pointer = flags & CWRAP_SMART_POINTER;
@ -1006,7 +1082,7 @@ int Swig_MethodToFunction(Node *n, const_String_or_char_ptr nspace, String *clas
String *func = NewStringf("%s(", mangled);
String *cres;
if (Cmp(Getattr(n, "storage"), "static") != 0) {
if (!Swig_storage_isstatic(n)) {
String *pname = Swig_cparm_name(pp, i);
String *ctname = SwigType_namestr(cname);
String *fadd = 0;
@ -1105,23 +1181,14 @@ Node *Swig_directormap(Node *module, String *type) {
* This function creates a C wrapper for a C constructor function.
* ----------------------------------------------------------------------------- */
int Swig_ConstructorToFunction(Node *n, const_String_or_char_ptr nspace, String *classname, String *none_comparison, String *director_ctor, int cplus, int flags) {
ParmList *parms;
Parm *prefix_args;
int Swig_ConstructorToFunction(Node *n, const_String_or_char_ptr nspace, String *classname, String *none_comparison, String *director_ctor, int cplus, int flags, String *directorname) {
Parm *p;
ParmList *directorparms;
SwigType *type;
int use_director;
String *directorScope = NewString(nspace);
Replace(directorScope, NSPACE_SEPARATOR, "_", DOH_REPLACE_ANY);
use_director = Swig_directorclass(n);
parms = CopyParmList(nonvoid_parms(Getattr(n, "parms")));
int use_director = Swig_directorclass(n);
ParmList *parms = CopyParmList(nonvoid_parms(Getattr(n, "parms")));
/* Prepend the list of prefix_args (if any) */
prefix_args = Getattr(n, "director:prefix_args");
Parm *prefix_args = Getattr(n, "director:prefix_args");
if (prefix_args != NIL) {
Parm *p2, *p3;
@ -1174,18 +1241,11 @@ int Swig_ConstructorToFunction(Node *n, const_String_or_char_ptr nspace, String
if (use_director) {
Node *parent = Swig_methodclass(n);
int abstract = Getattr(parent, "abstracts") != 0;
String *name = Getattr(parent, "sym:name");
String *directorname;
String *action = NewStringEmpty();
String *tmp_none_comparison = Copy(none_comparison);
String *director_call;
String *nodirector_call;
if (Len(directorScope) > 0)
directorname = NewStringf("SwigDirector_%s_%s", directorScope, name);
else
directorname = NewStringf("SwigDirector_%s", name);
Replaceall(tmp_none_comparison, "$arg", "arg1");
director_call = Swig_cppconstructor_director_call(directorname, directorparms);
@ -1224,7 +1284,6 @@ int Swig_ConstructorToFunction(Node *n, const_String_or_char_ptr nspace, String
Setattr(n, "wrap:action", action);
Delete(tmp_none_comparison);
Delete(action);
Delete(directorname);
} else {
String *call = Swig_cppconstructor_call(classname, parms);
String *cres = Swig_cresult(type, Swig_cresult_name(), call);
@ -1246,7 +1305,6 @@ int Swig_ConstructorToFunction(Node *n, const_String_or_char_ptr nspace, String
if (directorparms != parms)
Delete(directorparms);
Delete(parms);
Delete(directorScope);
return SWIG_OK;
}
@ -1409,7 +1467,7 @@ int Swig_MembergetToFunction(Node *n, String *classname, int flags) {
int varcref = flags & CWRAP_NATURAL_VAR;
if (flags & CWRAP_SMART_POINTER) {
if (checkAttribute(n, "storage", "static")) {
if (Swig_storage_isstatic(n)) {
Node *sn = Getattr(n, "cplus:staticbase");
String *base = Getattr(sn, "name");
self = NewStringf("%s::", base);

141
Source/Swig/extend.c Normal file
View file

@ -0,0 +1,141 @@
/* -----------------------------------------------------------------------------
* This file is part of SWIG, which is licensed as a whole under version 3
* (or any later version) of the GNU General Public License. Some additional
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
* and at http://www.swig.org/legal.html.
*
* extend.c
*
* Extensions support (%extend)
* ----------------------------------------------------------------------------- */
#include "swig.h"
#include "cparse.h"
static Hash *extendhash = 0; /* Hash table of added methods */
/* -----------------------------------------------------------------------------
* Swig_extend_hash()
*
* Access the extend hash
* ----------------------------------------------------------------------------- */
Hash *Swig_extend_hash(void) {
if (!extendhash)
extendhash = NewHash();
return extendhash;
}
/* -----------------------------------------------------------------------------
* Swig_extend_merge()
*
* Extension merge. This function is used to handle the %extend directive
* when it appears before a class definition. To handle this, the %extend
* actually needs to take precedence. Therefore, we will selectively nuke symbols
* from the current symbol table, replacing them with the added methods.
* ----------------------------------------------------------------------------- */
void Swig_extend_merge(Node *cls, Node *am) {
Node *n;
Node *csym;
n = firstChild(am);
while (n) {
String *symname;
if (Strcmp(nodeType(n),"constructor") == 0) {
symname = Getattr(n,"sym:name");
if (symname) {
if (Strcmp(symname,Getattr(n,"name")) == 0) {
/* If the name and the sym:name of a constructor are the same,
then it hasn't been renamed. However---the name of the class
itself might have been renamed so we need to do a consistency
check here */
if (Getattr(cls,"sym:name")) {
Setattr(n,"sym:name", Getattr(cls,"sym:name"));
}
}
}
}
symname = Getattr(n,"sym:name");
DohIncref(symname);
if ((symname) && (!Getattr(n,"error"))) {
/* Remove node from its symbol table */
Swig_symbol_remove(n);
csym = Swig_symbol_add(symname,n);
if (csym != n) {
/* Conflict with previous definition. Nuke previous definition */
String *e = NewStringEmpty();
String *en = NewStringEmpty();
String *ec = NewStringEmpty();
Printf(ec,"Identifier '%s' redefined by %%extend (ignored),",symname);
Printf(en,"%%extend definition of '%s'.",symname);
SWIG_WARN_NODE_BEGIN(n);
Swig_warning(WARN_PARSE_REDEFINED,Getfile(csym),Getline(csym),"%s\n",ec);
Swig_warning(WARN_PARSE_REDEFINED,Getfile(n),Getline(n),"%s\n",en);
SWIG_WARN_NODE_END(n);
Printf(e,"%s:%d:%s\n%s:%d:%s\n",Getfile(csym),Getline(csym),ec,
Getfile(n),Getline(n),en);
Setattr(csym,"error",e);
Delete(e);
Delete(en);
Delete(ec);
Swig_symbol_remove(csym); /* Remove class definition */
Swig_symbol_add(symname,n); /* Insert extend definition */
}
}
n = nextSibling(n);
}
}
/* -----------------------------------------------------------------------------
* Swig_extend_append_previous()
* ----------------------------------------------------------------------------- */
void Swig_extend_append_previous(Node *cls, Node *am) {
Node *n, *ne;
Node *pe = 0;
Node *ae = 0;
if (!am) return;
n = firstChild(am);
while (n) {
ne = nextSibling(n);
set_nextSibling(n,0);
/* typemaps and fragments need to be prepended */
if (((Cmp(nodeType(n),"typemap") == 0) || (Cmp(nodeType(n),"fragment") == 0))) {
if (!pe) pe = new_node("extend");
appendChild(pe, n);
} else {
if (!ae) ae = new_node("extend");
appendChild(ae, n);
}
n = ne;
}
if (pe) prependChild(cls,pe);
if (ae) appendChild(cls,ae);
}
/* -----------------------------------------------------------------------------
* Swig_extend_unused_check()
*
* Check for unused %extend. Special case, don't report unused
* extensions for templates
* ----------------------------------------------------------------------------- */
void Swig_extend_unused_check(void) {
Iterator ki;
if (!extendhash) return;
for (ki = First(extendhash); ki.key; ki = Next(ki)) {
if (!Strchr(ki.key,'<')) {
SWIG_WARN_NODE_BEGIN(ki.item);
Swig_warning(WARN_PARSE_EXTEND_UNDEF,Getfile(ki.item), Getline(ki.item), "%%extend defined for an undeclared class %s.\n", SwigType_namestr(ki.key));
SWIG_WARN_NODE_END(ki.item);
}
}
}

View file

@ -94,16 +94,16 @@ void Swig_fragment_emit(Node *n) {
String *name = 0;
String *type = 0;
name = Getattr(n, "value");
if (!name) {
name = n;
}
if (!fragments) {
Swig_warning(WARN_FRAGMENT_NOT_FOUND, Getfile(n), Getline(n), "Fragment '%s' not found.\n", name);
return;
}
name = Getattr(n, "value");
if (!name) {
name = n;
}
type = Getattr(n, "type");
if (type) {
mangle = Swig_string_mangle(type);

View file

@ -262,6 +262,49 @@ void Swig_filename_unescape(String *filename) {
#endif
}
/* -----------------------------------------------------------------------------
* Swig_storage_isextern()
*
* Determine if the storage class specifier is extern (but not externc)
* ----------------------------------------------------------------------------- */
int Swig_storage_isextern(Node *n) {
const String *storage = Getattr(n, "storage");
return storage ? Strcmp(storage, "extern") == 0 || Strncmp(storage, "extern ", 7) == 0 : 0;
}
/* -----------------------------------------------------------------------------
* Swig_storage_isexternc()
*
* Determine if the storage class specifier is externc (but not plain extern)
* ----------------------------------------------------------------------------- */
int Swig_storage_isexternc(Node *n) {
const String *storage = Getattr(n, "storage");
return storage ? Strcmp(storage, "externc") == 0 || Strncmp(storage, "externc ", 8) == 0 : 0;
}
/* -----------------------------------------------------------------------------
* Swig_storage_isstatic_custom()
*
* Determine if the storage class specifier is static
* ----------------------------------------------------------------------------- */
int Swig_storage_isstatic_custom(Node *n, const_String_or_char_ptr storage_name) {
const String *storage = Getattr(n, storage_name);
return storage ? Strncmp(storage, "static", 6) == 0 : 0;
}
/* -----------------------------------------------------------------------------
* Swig_storage_isstatic()
*
* Determine if the storage class specifier is static
* ----------------------------------------------------------------------------- */
int Swig_storage_isstatic(Node *n) {
return Swig_storage_isstatic_custom(n, "storage");
}
/* -----------------------------------------------------------------------------
* Swig_string_escape()
*
@ -1104,6 +1147,55 @@ String *Swig_string_strip(String *s) {
return ns;
}
/* -----------------------------------------------------------------------------
* Swig_offset_string()
*
* Insert number tabs before each new line in s
* ----------------------------------------------------------------------------- */
void Swig_offset_string(String *s, int number) {
char *res, *p, *end, *start;
/* count a number of lines in s */
int lines = 1;
int len = Len(s);
if (len == 0)
return;
start = strchr(Char(s), '\n');
while (start) {
++lines;
start = strchr(start + 1, '\n');
}
/* do not count pending new line */
if ((Char(s))[len-1] == '\n')
--lines;
/* allocate a temporary storage for a padded string */
res = (char*)malloc(len + lines * number * 2 + 1);
res[len + lines * number * 2] = 0;
/* copy lines to res, prepending tabs to each line */
p = res; /* output pointer */
start = Char(s); /* start of a current line */
end = strchr(start, '\n'); /* end of a current line */
while (end) {
memset(p, ' ', number*2);
p += number*2;
memcpy(p, start, end - start + 1);
p += end - start + 1;
start = end + 1;
end = strchr(start, '\n');
}
/* process the last line */
if (*start) {
memset(p, ' ', number*2);
p += number*2;
strcpy(p, start);
}
/* replace 's' contents with 'res' */
Clear(s);
Append(s, res);
free(res);
}
#ifdef HAVE_PCRE
#include <pcre.h>
@ -1137,8 +1229,40 @@ err_out:
exit(1);
}
/* This function copies len characters from src to dst, possibly applying case conversions to them: if convertCase is 1, to upper case and if it is -1, to lower
* case. If convertNextOnly is 1, only a single character is converted (and convertCase is reset), otherwise all of them are. */
static void copy_with_maybe_case_conversion(String *dst, const char *src, int len, int *convertCase, int convertNextOnly)
{
/* Deal with the trivial cases first. */
if (!len)
return;
if (!*convertCase) {
Write(dst, src, len);
return;
}
/* If we must convert only the first character, do it and write the rest at once. */
if (convertNextOnly) {
int src_char = *src;
Putc(*convertCase == 1 ? toupper(src_char) : tolower(src_char), dst);
*convertCase = 0;
if (len > 1) {
Write(dst, src + 1, len - 1);
}
} else {
/* We need to convert all characters. */
int i;
for (i = 0; i < len; i++, src++) {
int src_char = *src;
Putc(*convertCase == 1 ? toupper(src_char) : tolower(src_char), dst);
}
}
}
String *replace_captures(int num_captures, const char *input, String *subst, int captures[], String *pattern, String *s)
{
int convertCase = 0, convertNextOnly = 0;
String *result = NewStringEmpty();
const char *p = Char(subst);
@ -1146,10 +1270,10 @@ String *replace_captures(int num_captures, const char *input, String *subst, int
/* Copy part without substitutions */
const char *q = strchr(p, '\\');
if (!q) {
Write(result, p, strlen(p));
copy_with_maybe_case_conversion(result, p, strlen(p), &convertCase, convertNextOnly);
break;
}
Write(result, p, q - p);
copy_with_maybe_case_conversion(result, p, q - p, &convertCase, convertNextOnly);
p = q + 1;
/* Handle substitution */
@ -1160,12 +1284,39 @@ String *replace_captures(int num_captures, const char *input, String *subst, int
if (group < num_captures) {
int l = captures[group*2], r = captures[group*2 + 1];
if (l != -1) {
Write(result, input + l, r - l);
copy_with_maybe_case_conversion(result, input + l, r - l, &convertCase, convertNextOnly);
}
} else {
Swig_error("SWIG", Getline(s), "PCRE capture replacement failed while matching \"%s\" using \"%s\" - request for group %d is greater than the number of captures %d.\n",
Char(pattern), input, group, num_captures-1);
}
} else {
/* Handle Perl-like case conversion escapes. */
switch (*p) {
case 'u':
convertCase = 1;
convertNextOnly = 1;
break;
case 'U':
convertCase = 1;
convertNextOnly = 0;
break;
case 'l':
convertCase = -1;
convertNextOnly = 1;
break;
case 'L':
convertCase = -1;
convertNextOnly = 0;
break;
case 'E':
convertCase = 0;
break;
default:
Swig_error("SWIG", Getline(s), "Unrecognized escape character '%c' in the replacement string \"%s\".\n",
*p, Char(subst));
}
p++;
}
}

View file

@ -774,7 +774,7 @@ void Swig_features_get(Hash *features, String *prefix, String *name, SwigType *d
* concatenating the feature name plus ':' plus the attribute name.
* ----------------------------------------------------------------------------- */
void Swig_feature_set(Hash *features, const_String_or_char_ptr name, SwigType *decl, const_String_or_char_ptr featurename, String *value, Hash *featureattribs) {
void Swig_feature_set(Hash *features, const_String_or_char_ptr name, SwigType *decl, const_String_or_char_ptr featurename, const_String_or_char_ptr value, Hash *featureattribs) {
Hash *n;
Hash *fhash;
@ -938,8 +938,7 @@ static int nodes_are_equivalent(Node *a, Node *b, int a_inclass) {
}
/* static functions */
if ((Cmp(a_storage, "static") == 0)
|| (Cmp(b_storage, "static") == 0)) {
if (Swig_storage_isstatic(a) || Swig_storage_isstatic(b)) {
if (Cmp(a_storage, b_storage) != 0)
return 0;
}
@ -1649,6 +1648,80 @@ void Swig_name_inherit(String *base, String *derived) {
Swig_name_object_inherit(Swig_cparse_features(), base, derived);
}
/* -----------------------------------------------------------------------------
* Swig_inherit_base_symbols()
* ----------------------------------------------------------------------------- */
void Swig_inherit_base_symbols(List *bases) {
if (bases) {
Iterator s;
for (s = First(bases); s.item; s = Next(s)) {
Symtab *st = Getattr(s.item, "symtab");
if (st) {
Setfile(st, Getfile(s.item));
Setline(st, Getline(s.item));
Swig_symbol_inherit(st);
}
}
Delete(bases);
}
}
/* -----------------------------------------------------------------------------
* Swig_make_inherit_list()
* ----------------------------------------------------------------------------- */
List *Swig_make_inherit_list(String *clsname, List *names, String *Namespaceprefix) {
int i, ilen;
String *derived;
List *bases = NewList();
if (Namespaceprefix)
derived = NewStringf("%s::%s", Namespaceprefix, clsname);
else
derived = NewString(clsname);
ilen = Len(names);
for (i = 0; i < ilen; i++) {
String *base;
String *n = Getitem(names, i);
/* Try to figure out where this symbol is */
Node *s = Swig_symbol_clookup(n, 0);
if (s) {
while (s && (Strcmp(nodeType(s), "class") != 0)) {
/* Not a class. Could be a typedef though. */
String *storage = Getattr(s, "storage");
if (storage && (Strcmp(storage, "typedef") == 0)) {
String *nn = Getattr(s, "type");
s = Swig_symbol_clookup(nn, Getattr(s, "sym:symtab"));
} else {
break;
}
}
if (s && ((Strcmp(nodeType(s), "class") == 0) || (Strcmp(nodeType(s), "template") == 0))) {
String *q = Swig_symbol_qualified(s);
Append(bases, s);
if (q) {
base = NewStringf("%s::%s", q, Getattr(s, "name"));
Delete(q);
} else {
base = NewString(Getattr(s, "name"));
}
} else {
base = NewString(n);
}
} else {
base = NewString(n);
}
if (base) {
Swig_name_inherit(base, derived);
Delete(base);
}
}
return bases;
}
/* -----------------------------------------------------------------------------
* void Swig_name_str()
*

View file

@ -35,6 +35,7 @@ struct Scanner {
String *error; /* Last error message (if any) */
int error_line; /* Error line number */
int freeze_line; /* Suspend line number updates */
List *brackets; /* Current level of < > brackets on each level */
};
typedef struct Locator {
@ -44,6 +45,9 @@ typedef struct Locator {
} Locator;
static int follow_locators = 0;
static void brackets_push(Scanner *);
static void brackets_clear(Scanner *);
/* -----------------------------------------------------------------------------
* NewScanner()
*
@ -65,6 +69,8 @@ Scanner *NewScanner(void) {
s->error = 0;
s->error_line = 0;
s->freeze_line = 0;
s->brackets = NewList();
brackets_push(s);
return s;
}
@ -74,15 +80,16 @@ Scanner *NewScanner(void) {
* Delete a scanner object.
* ----------------------------------------------------------------------------- */
void DelScanner(Scanner * s) {
void DelScanner(Scanner *s) {
assert(s);
Delete(s->scanobjs);
Delete(s->brackets);
Delete(s->text);
Delete(s->file);
Delete(s->error);
Delete(s->str);
free(s->idstart);
free(s);
free(s);
}
/* -----------------------------------------------------------------------------
@ -91,11 +98,12 @@ void DelScanner(Scanner * s) {
* Clear the contents of a scanner object.
* ----------------------------------------------------------------------------- */
void Scanner_clear(Scanner * s) {
void Scanner_clear(Scanner *s) {
assert(s);
Delete(s->str);
Clear(s->text);
Clear(s->scanobjs);
brackets_clear(s);
Delete(s->error);
s->str = 0;
s->error = 0;
@ -118,7 +126,7 @@ void Scanner_clear(Scanner * s) {
* immediately before returning to the old text.
* ----------------------------------------------------------------------------- */
void Scanner_push(Scanner * s, String *txt) {
void Scanner_push(Scanner *s, String *txt) {
assert(s && txt);
Push(s->scanobjs, txt);
if (s->str) {
@ -137,7 +145,7 @@ void Scanner_push(Scanner * s, String *txt) {
* call to Scanner_token().
* ----------------------------------------------------------------------------- */
void Scanner_pushtoken(Scanner * s, int nt, const_String_or_char_ptr val) {
void Scanner_pushtoken(Scanner *s, int nt, const_String_or_char_ptr val) {
assert(s);
assert((nt >= 0) && (nt < SWIG_MAXTOKENS));
s->nexttoken = nt;
@ -153,7 +161,7 @@ void Scanner_pushtoken(Scanner * s, int nt, const_String_or_char_ptr val) {
* Set the file and line number location of the scanner.
* ----------------------------------------------------------------------------- */
void Scanner_set_location(Scanner * s, String *file, int line) {
void Scanner_set_location(Scanner *s, String *file, int line) {
Setline(s->str, line);
Setfile(s->str, file);
s->line = line;
@ -165,7 +173,7 @@ void Scanner_set_location(Scanner * s, String *file, int line) {
* Get the current file.
* ----------------------------------------------------------------------------- */
String *Scanner_file(Scanner * s) {
String *Scanner_file(Scanner *s) {
return Getfile(s->str);
}
@ -174,7 +182,7 @@ String *Scanner_file(Scanner * s) {
*
* Get the current line number
* ----------------------------------------------------------------------------- */
int Scanner_line(Scanner * s) {
int Scanner_line(Scanner *s) {
return s->line;
}
@ -183,7 +191,7 @@ int Scanner_line(Scanner * s) {
*
* Get the line number on which the current token starts
* ----------------------------------------------------------------------------- */
int Scanner_start_line(Scanner * s) {
int Scanner_start_line(Scanner *s) {
return s->start_line;
}
@ -193,7 +201,7 @@ int Scanner_start_line(Scanner * s) {
* Change the set of additional characters that can be used to start an identifier.
* ----------------------------------------------------------------------------- */
void Scanner_idstart(Scanner * s, const char *id) {
void Scanner_idstart(Scanner *s, const char *id) {
free(s->idstart);
s->idstart = Swig_copy_string(id);
}
@ -203,7 +211,7 @@ void Scanner_idstart(Scanner * s, const char *id) {
*
* Returns the next character from the scanner or 0 if end of the string.
* ----------------------------------------------------------------------------- */
static char nextchar(Scanner * s) {
static char nextchar(Scanner *s) {
int nc;
if (!s->str)
return 0;
@ -245,8 +253,7 @@ String *Scanner_errmsg(Scanner *s) {
return s->error;
}
int
Scanner_errline(Scanner *s) {
int Scanner_errline(Scanner *s) {
return s->error_line;
}
@ -260,12 +267,108 @@ static void freeze_line(Scanner *s, int val) {
s->freeze_line = val;
}
/* -----------------------------------------------------------------------------
* brackets_count()
*
* Returns the number of brackets at the current depth.
* A syntax error with unbalanced ) brackets will result in a NULL pointer return.
* ----------------------------------------------------------------------------- */
static int *brackets_count(Scanner *s) {
int *count;
if (Len(s->brackets) > 0)
count = (int *)Data(Getitem(s->brackets, 0));
else
count = 0;
return count;
}
/* -----------------------------------------------------------------------------
* brackets_clear()
*
* Resets the current depth and clears all brackets.
* Usually called at the end of statements;
* ----------------------------------------------------------------------------- */
static void brackets_clear(Scanner *s) {
Clear(s->brackets);
brackets_push(s); /* base bracket count should always be created */
}
/* -----------------------------------------------------------------------------
* brackets_increment()
*
* Increases the number of brackets at the current depth.
* Usually called when a single '<' is found.
* ----------------------------------------------------------------------------- */
static void brackets_increment(Scanner *s) {
int *count = brackets_count(s);
if (count)
(*count)++;
}
/* -----------------------------------------------------------------------------
* brackets_decrement()
*
* Decreases the number of brackets at the current depth.
* Usually called when a single '>' is found.
* ----------------------------------------------------------------------------- */
static void brackets_decrement(Scanner *s) {
int *count = brackets_count(s);
if (count)
(*count)--;
}
/* -----------------------------------------------------------------------------
* brackets_reset()
*
* Sets the number of '<' brackets back to zero. Called at the point where
* it is no longer possible to have a matching closing >> pair for a template.
* ----------------------------------------------------------------------------- */
static void brackets_reset(Scanner *s) {
int *count = brackets_count(s);
if (count)
*count = 0;
}
/* -----------------------------------------------------------------------------
* brackets_push()
*
* Increases the depth of brackets.
* Usually called when '(' is found.
* ----------------------------------------------------------------------------- */
static void brackets_push(Scanner *s) {
int *newInt = malloc(sizeof(int));
*newInt = 0;
Push(s->brackets, NewVoid(newInt, free));
}
/* -----------------------------------------------------------------------------
* brackets_pop()
*
* Decreases the depth of brackets.
* Usually called when ')' is found.
* ----------------------------------------------------------------------------- */
static void brackets_pop(Scanner *s) {
if (Len(s->brackets) > 0) /* protect against unbalanced ')' brackets */
Delitem(s->brackets, 0);
}
/* -----------------------------------------------------------------------------
* brackets_allow_shift()
*
* Return 1 to allow shift (>>), or 0 if (>>) should be split into (> >).
* This is for C++11 template syntax for closing templates.
* ----------------------------------------------------------------------------- */
static int brackets_allow_shift(Scanner *s) {
int *count = brackets_count(s);
return !count || (*count <= 0);
}
/* -----------------------------------------------------------------------------
* retract()
*
* Retract n characters
* ----------------------------------------------------------------------------- */
static void retract(Scanner * s, int n) {
static void retract(Scanner *s, int n) {
int i, l;
char *str;
@ -406,14 +509,16 @@ static void get_escape(Scanner *s) {
* Return the raw value of the next token.
* ----------------------------------------------------------------------------- */
static int look(Scanner * s) {
int state;
static int look(Scanner *s) {
int state = 0;
int c = 0;
String *str_delimiter = 0;
state = 0;
Clear(s->text);
s->start_line = s->line;
Setfile(s->text, Getfile(s->str));
while (1) {
switch (state) {
case 0:
@ -435,32 +540,40 @@ static int look(Scanner * s) {
case 1000:
if ((c = nextchar(s)) == 0)
return (0);
return (0);
if (c == '%')
state = 4; /* Possibly a SWIG directive */
/* Look for possible identifiers */
/* Look for possible identifiers or unicode/delimiter strings */
else if ((isalpha(c)) || (c == '_') ||
(s->idstart && strchr(s->idstart, c)))
(s->idstart && strchr(s->idstart, c))) {
state = 7;
}
/* Look for single character symbols */
else if (c == '(')
else if (c == '(') {
brackets_push(s);
return SWIG_TOKEN_LPAREN;
else if (c == ')')
}
else if (c == ')') {
brackets_pop(s);
return SWIG_TOKEN_RPAREN;
else if (c == ';')
}
else if (c == ';') {
brackets_clear(s);
return SWIG_TOKEN_SEMI;
}
else if (c == ',')
return SWIG_TOKEN_COMMA;
else if (c == '*')
state = 220;
else if (c == '}')
return SWIG_TOKEN_RBRACE;
else if (c == '{')
else if (c == '{') {
brackets_reset(s);
return SWIG_TOKEN_LBRACE;
}
else if (c == '=')
state = 33;
else if (c == '+')
@ -502,16 +615,16 @@ static int look(Scanner * s) {
state = 1; /* Comment (maybe) */
s->start_line = s->line;
}
else if (c == '\"') {
state = 2; /* Possibly a string */
s->start_line = s->line;
Clear(s->text);
}
else if (c == ':')
state = 5; /* maybe double colon */
else if (c == '0')
state = 83; /* An octal or hex value */
else if (c == '\"') {
state = 2; /* A string constant */
s->start_line = s->line;
Clear(s->text);
}
else if (c == '\'') {
s->start_line = s->line;
Clear(s->text);
@ -590,18 +703,63 @@ static int look(Scanner * s) {
break;
case 2: /* Processing a string */
if (!str_delimiter) {
state=20;
break;
}
if ((c = nextchar(s)) == 0) {
Swig_error(cparse_file, cparse_start_line, "Unterminated string\n");
return SWIG_TOKEN_ERROR;
}
if (c == '\"') {
Delitem(s->text, DOH_END);
return SWIG_TOKEN_STRING;
} else if (c == '\\') {
Delitem(s->text, DOH_END);
get_escape(s);
} else
state = 2;
else if (c == '(') {
state = 20;
}
else {
char temp[2] = { 0, 0 };
temp[0] = c;
Append( str_delimiter, temp );
}
break;
case 20: /* Inside the string */
if ((c = nextchar(s)) == 0) {
Swig_error(cparse_file, cparse_start_line, "Unterminated string\n");
return SWIG_TOKEN_ERROR;
}
if (!str_delimiter) { /* Ordinary string: "value" */
if (c == '\"') {
Delitem(s->text, DOH_END);
return SWIG_TOKEN_STRING;
} else if (c == '\\') {
Delitem(s->text, DOH_END);
get_escape(s);
}
} else { /* Custom delimiter string: R"XXXX(value)XXXX" */
if (c==')') {
int i=0;
String *end_delimiter = NewStringEmpty();
while ((c = nextchar(s)) != 0 && c!='\"') {
char temp[2] = { 0, 0 };
temp[0] = c;
Append( end_delimiter, temp );
i++;
}
if (Strcmp( str_delimiter, end_delimiter )==0) {
Delete( end_delimiter ); /* Correct end delimiter )XXXX" occured */
Delete( str_delimiter );
str_delimiter = 0;
return SWIG_TOKEN_STRING;
} else { /* Incorrect end delimiter occured */
retract( s, i );
Delete( end_delimiter );
}
}
}
break;
case 3: /* Maybe a not equals */
@ -719,41 +877,137 @@ static int look(Scanner * s) {
break;
case 60: /* shift operators */
if ((c = nextchar(s)) == 0)
if ((c = nextchar(s)) == 0) {
brackets_increment(s);
return SWIG_TOKEN_LESSTHAN;
}
if (c == '<')
state = 240;
else if (c == '=')
return SWIG_TOKEN_LTEQUAL;
else {
retract(s, 1);
brackets_increment(s);
return SWIG_TOKEN_LESSTHAN;
}
break;
case 61:
if ((c = nextchar(s)) == 0)
if ((c = nextchar(s)) == 0) {
brackets_decrement(s);
return SWIG_TOKEN_GREATERTHAN;
if (c == '>')
}
if (c == '>' && brackets_allow_shift(s))
state = 250;
else if (c == '=')
return SWIG_TOKEN_GTEQUAL;
else {
retract(s, 1);
brackets_decrement(s);
return SWIG_TOKEN_GREATERTHAN;
}
break;
case 7: /* Identifier */
if ((c = nextchar(s)) == 0)
state = 71;
else if (isalnum(c) || (c == '_') || (c == '$')) {
state = 7;
} else {
case 7: /* Identifier or true/false or unicode/custom delimiter string */
if (c == 'R') { /* Possibly CUSTOM DELIMITER string */
state = 72;
break;
}
else if (c == 'L') { /* Probably identifier but may be a wide string literal */
state = 77;
break;
}
else if (c != 'u' && c != 'U') { /* Definitely an identifier */
state = 70;
break;
}
if ((c = nextchar(s)) == 0) {
state = 76;
}
else if (c == '\"') { /* Definitely u, U or L string */
retract(s, 1);
state = 1000;
}
else if (c == 'R') { /* Possibly CUSTOM DELIMITER u, U, L string */
state = 73;
}
else if (c == '8') { /* Possibly u8 string */
state = 71;
}
else {
retract(s, 1); /* Definitely an identifier */
state = 70;
}
break;
case 71: /* Identifier or true/false */
case 70: /* Identifier */
if ((c = nextchar(s)) == 0)
state = 76;
else if (isalnum(c) || (c == '_') || (c == '$')) {
state = 70;
} else {
retract(s, 1);
state = 76;
}
break;
case 71: /* Possibly u8 string */
if ((c = nextchar(s)) == 0) {
state = 76;
}
else if (c=='\"') {
retract(s, 1); /* Definitely u8 string */
state = 1000;
}
else if (c=='R') {
state = 74; /* Possibly CUSTOM DELIMITER u8 string */
}
else {
retract(s, 2); /* Definitely an identifier. Retract 8" */
state = 70;
}
break;
case 72: /* Possibly CUSTOM DELIMITER string */
case 73:
case 74:
if ((c = nextchar(s)) == 0) {
state = 76;
}
else if (c=='\"') {
retract(s, 1); /* Definitely custom delimiter u, U or L string */
str_delimiter = NewStringEmpty();
state = 1000;
}
else {
if (state==72) {
retract(s, 1); /* Definitely an identifier. Retract ? */
}
else if (state==73) {
retract(s, 2); /* Definitely an identifier. Retract R? */
}
else if (state==74) {
retract(s, 3); /* Definitely an identifier. Retract 8R? */
}
state = 70;
}
break;
case 75: /* Special identifier $ */
if ((c = nextchar(s)) == 0)
return SWIG_TOKEN_DOLLAR;
if (isalnum(c) || (c == '_') || (c == '*') || (c == '&')) {
state = 70;
} else {
retract(s,1);
if (Len(s->text) == 1) return SWIG_TOKEN_DOLLAR;
state = 76;
}
break;
case 76: /* Identifier or true/false */
if (cparse_cplusplus) {
if (Strcmp(s->text, "true") == 0)
return SWIG_TOKEN_BOOL;
@ -763,15 +1017,56 @@ static int look(Scanner * s) {
return SWIG_TOKEN_ID;
break;
case 75: /* Special identifier $ */
case 77: /*identifier or wide string literal*/
if ((c = nextchar(s)) == 0)
return SWIG_TOKEN_DOLLAR;
if (isalnum(c) || (c == '_') || (c == '*') || (c == '&')) {
return SWIG_TOKEN_ID;
else if (c == '\"') {
s->start_line = s->line;
Clear(s->text);
state = 78;
}
else if (c == '\'') {
s->start_line = s->line;
Clear(s->text);
state = 79;
}
else if (isalnum(c) || (c == '_') || (c == '$'))
state = 7;
} else {
retract(s,1);
if (Len(s->text) == 1) return SWIG_TOKEN_DOLLAR;
state = 71;
else {
retract(s, 1);
return SWIG_TOKEN_ID;
}
break;
case 78: /* Processing a wide string literal*/
if ((c = nextchar(s)) == 0) {
Swig_error(cparse_file, cparse_start_line, "Unterminated wide string\n");
return SWIG_TOKEN_ERROR;
}
if (c == '\"') {
Delitem(s->text, DOH_END);
return SWIG_TOKEN_WSTRING;
} else if (c == '\\') {
if ((c = nextchar(s)) == 0) {
Swig_error(cparse_file, cparse_start_line, "Unterminated wide string\n");
return SWIG_TOKEN_ERROR;
}
}
break;
case 79: /* Processing a wide char literal */
if ((c = nextchar(s)) == 0) {
Swig_error(cparse_file, cparse_start_line, "Unterminated wide character constant\n");
return SWIG_TOKEN_ERROR;
}
if (c == '\'') {
Delitem(s->text, DOH_END);
return (SWIG_TOKEN_WCHAR);
} else if (c == '\\') {
if ((c = nextchar(s)) == 0) {
Swig_error(cparse_file, cparse_start_line, "Unterminated wide character literal\n");
return SWIG_TOKEN_ERROR;
}
}
break;
@ -1097,7 +1392,7 @@ static int look(Scanner * s) {
* Real entry point to return the next token. Returns 0 if at end of input.
* ----------------------------------------------------------------------------- */
int Scanner_token(Scanner * s) {
int Scanner_token(Scanner *s) {
int t;
Delete(s->error);
if (s->nexttoken >= 0) {
@ -1121,7 +1416,7 @@ int Scanner_token(Scanner * s) {
* Return the lexene associated with the last returned token.
* ----------------------------------------------------------------------------- */
String *Scanner_text(Scanner * s) {
String *Scanner_text(Scanner *s) {
return s->text;
}
@ -1131,7 +1426,7 @@ String *Scanner_text(Scanner * s) {
* Skips to the end of a line
* ----------------------------------------------------------------------------- */
void Scanner_skip_line(Scanner * s) {
void Scanner_skip_line(Scanner *s) {
char c;
int done = 0;
Clear(s->text);
@ -1156,7 +1451,7 @@ void Scanner_skip_line(Scanner * s) {
* (...). Ignores symbols inside comments or strings.
* ----------------------------------------------------------------------------- */
int Scanner_skip_balanced(Scanner * s, int startchar, int endchar) {
int Scanner_skip_balanced(Scanner *s, int startchar, int endchar) {
char c;
int num_levels = 1;
int state = 0;
@ -1282,6 +1577,114 @@ int Scanner_skip_balanced(Scanner * s, int startchar, int endchar) {
return 0;
}
/* -----------------------------------------------------------------------------
* Scanner_get_raw_text_balanced()
*
* Returns raw text between 2 braces, does not change scanner state in any way
* ----------------------------------------------------------------------------- */
String *Scanner_get_raw_text_balanced(Scanner *s, int startchar, int endchar) {
String *result = 0;
char c;
int old_line = s->line;
String *old_text = Copy(s->text);
long position = Tell(s->str);
int num_levels = 1;
int state = 0;
char temp[2] = { 0, 0 };
temp[0] = (char) startchar;
Clear(s->text);
Setfile(s->text, Getfile(s->str));
Setline(s->text, s->line);
Append(s->text, temp);
while (num_levels > 0) {
if ((c = nextchar(s)) == 0) {
Clear(s->text);
Append(s->text, old_text);
Delete(old_text);
s->line = old_line;
return 0;
}
switch (state) {
case 0:
if (c == startchar)
num_levels++;
else if (c == endchar)
num_levels--;
else if (c == '/')
state = 10;
else if (c == '\"')
state = 20;
else if (c == '\'')
state = 30;
break;
case 10:
if (c == '/')
state = 11;
else if (c == '*')
state = 12;
else if (c == startchar) {
state = 0;
num_levels++;
}
else
state = 0;
break;
case 11:
if (c == '\n')
state = 0;
else
state = 11;
break;
case 12: /* first character inside C comment */
if (c == '*')
state = 14;
else
state = 13;
break;
case 13:
if (c == '*')
state = 14;
break;
case 14: /* possible end of C comment */
if (c == '*')
state = 14;
else if (c == '/')
state = 0;
else
state = 13;
break;
case 20:
if (c == '\"')
state = 0;
else if (c == '\\')
state = 21;
break;
case 21:
state = 20;
break;
case 30:
if (c == '\'')
state = 0;
else if (c == '\\')
state = 31;
break;
case 31:
state = 30;
break;
default:
break;
}
}
Seek(s->str, position, SEEK_SET);
result = Copy(s->text);
Clear(s->text);
Append(s->text, old_text);
Delete(old_text);
s->line = old_line;
return result;
}
/* -----------------------------------------------------------------------------
* Scanner_isoperator()
*

View file

@ -41,6 +41,7 @@
*
* 'p.' = Pointer (*)
* 'r.' = Reference (&)
* 'z.' = Rvalue reference (&&)
* 'a(n).' = Array of size n [n]
* 'f(..,..).' = Function with arguments (args)
* 'q(str).' = Qualifier (such as const or volatile) (const, volatile)
@ -128,12 +129,22 @@ SwigType *NewSwigType(int t) {
case T_UCHAR:
return NewString("unsigned char");
break;
case T_STRING:{
case T_STRING: {
SwigType *t = NewString("char");
SwigType_add_qualifier(t, "const");
SwigType_add_pointer(t);
return t;
break;
}
case T_WCHAR:
return NewString("wchar_t");
break;
case T_WSTRING: {
SwigType *t = NewString("wchar_t");
SwigType_add_pointer(t);
return t;
break;
}
case T_LONGLONG:
return NewString("long long");
break;
@ -143,6 +154,9 @@ SwigType *NewSwigType(int t) {
case T_VOID:
return NewString("void");
break;
case T_AUTO:
return NewString("auto");
break;
default:
break;
}
@ -230,7 +244,7 @@ int SwigType_isconst(const SwigType *t) {
int SwigType_ismutable(const SwigType *t) {
int r;
SwigType *qt = SwigType_typedef_resolve_all(t);
if (SwigType_isreference(qt) || SwigType_isarray(qt)) {
if (SwigType_isreference(qt) || SwigType_isrvalue_reference(qt) || SwigType_isarray(qt)) {
Delete(SwigType_pop(qt));
}
r = SwigType_isconst(qt);
@ -573,6 +587,12 @@ String *SwigType_str(const SwigType *s, const_String_or_char_ptr id) {
Insert(result, 0, "(");
Append(result, ")");
}
} else if (SwigType_isrvalue_reference(element)) {
Insert(result, 0, "&&");
if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) {
Insert(result, 0, "(");
Append(result, ")");
}
} else if (SwigType_isarray(element)) {
DOH *size;
Append(result, "[");
@ -637,7 +657,7 @@ SwigType *SwigType_ltype(const SwigType *s) {
SwigType *tt = Copy(tc);
td = 0;
while ((td = SwigType_typedef_resolve(tt))) {
if (td && (SwigType_isconst(td) || SwigType_isarray(td) || SwigType_isreference(td))) {
if (td && (SwigType_isconst(td) || SwigType_isarray(td) || SwigType_isreference(td) || SwigType_isrvalue_reference(td))) {
/* We need to use the typedef type */
Delete(tt);
break;
@ -676,6 +696,13 @@ SwigType *SwigType_ltype(const SwigType *s) {
Append(result, "p.");
}
firstarray = 0;
} else if (SwigType_isrvalue_reference(element)) {
if (notypeconv) {
Append(result, element);
} else {
Append(result, "p.");
}
firstarray = 0;
} else if (SwigType_isarray(element) && firstarray) {
if (notypeconv) {
Append(result, element);
@ -755,14 +782,14 @@ String *SwigType_rcaststr(const SwigType *s, const_String_or_char_ptr name) {
rs = s;
}
if ((SwigType_isconst(rs) || SwigType_isarray(rs) || SwigType_isreference(rs))) {
if ((SwigType_isconst(rs) || SwigType_isarray(rs) || SwigType_isreference(rs) || SwigType_isrvalue_reference(rs))) {
td = 0;
} else {
td = SwigType_typedef_resolve(rs);
}
if (td) {
if ((SwigType_isconst(td) || SwigType_isarray(td) || SwigType_isreference(td))) {
if ((SwigType_isconst(td) || SwigType_isarray(td) || SwigType_isreference(td) || SwigType_isrvalue_reference(td))) {
elements = SwigType_split(td);
} else {
elements = SwigType_split(rs);
@ -821,6 +848,15 @@ String *SwigType_rcaststr(const SwigType *s, const_String_or_char_ptr name) {
}
if (!isfunction)
isreference = 1;
} else if (SwigType_isrvalue_reference(element)) {
Insert(result, 0, "&&");
if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) {
Insert(result, 0, "(");
Append(result, ")");
}
if (!isfunction)
isreference = 1;
clear = 0;
} else if (SwigType_isarray(element)) {
DOH *size;
if (firstarray && !isreference) {
@ -897,6 +933,12 @@ String *SwigType_lcaststr(const SwigType *s, const_String_or_char_ptr name) {
Delete(str);
if (name)
Append(result, name);
} else if (SwigType_isrvalue_reference(s)) {
String *str = SwigType_str(s, 0);
Printf(result, "(%s)", str);
Delete(str);
if (name)
Append(result, name);
} else if (SwigType_isqualifier(s)) {
String *lstr = SwigType_lstr(s, 0);
Printf(result, "(%s)%s", lstr, name);

View file

@ -79,6 +79,7 @@ extern "C" {
#define T_FLTCPLX 23
#define T_DBLCPLX 24
#define T_NUMERIC 25
#define T_AUTO 26
#define T_COMPLEX T_DBLCPLX
@ -95,10 +96,14 @@ extern "C" {
#define T_FUNCTION 37
#define T_MPOINTER 38
#define T_VARARGS 39
#define T_RVALUE_REFERENCE 40
#define T_WSTRING 41
#define T_SYMBOL 98
#define T_ERROR 99
/* --- File interface --- */
#include "swigfile.h"
@ -124,6 +129,8 @@ extern "C" {
extern SwigType *SwigType_pop_arrays(SwigType *t);
extern SwigType *SwigType_add_reference(SwigType *t);
extern SwigType *SwigType_del_reference(SwigType *t);
extern SwigType *SwigType_add_rvalue_reference(SwigType *t);
extern SwigType *SwigType_del_rvalue_reference(SwigType *t);
extern SwigType *SwigType_add_qualifier(SwigType *t, const_String_or_char_ptr qual);
extern SwigType *SwigType_del_qualifier(SwigType *t);
extern SwigType *SwigType_add_function(SwigType *t, ParmList *parms);
@ -147,6 +154,7 @@ extern "C" {
extern int SwigType_ismemberpointer(const SwigType *t);
extern int SwigType_isreference(const SwigType *t);
extern int SwigType_isreference_return(const SwigType *t);
extern int SwigType_isrvalue_reference(const SwigType *t);
extern int SwigType_isarray(const SwigType *t);
extern int SwigType_prefix_is_simple_1D_array(const SwigType *t);
extern int SwigType_isfunction(const SwigType *t);
@ -278,6 +286,8 @@ extern int ParmList_is_compactdefargs(ParmList *p);
extern Hash *Swig_name_namewarn_get(Node *n, String *prefix, String *name, SwigType *decl);
extern void Swig_name_rename_add(String *prefix, String *name, SwigType *decl, Hash *namewrn, ParmList *declaratorparms);
extern void Swig_name_inherit(String *base, String *derived);
extern List *Swig_make_inherit_list(String *clsname, List *names, String *Namespaceprefix);
extern void Swig_inherit_base_symbols(List *bases);
extern int Swig_need_protected(Node *n);
extern int Swig_need_name_warning(Node *n);
extern int Swig_need_redefined_warn(Node *a, Node *b, int InClass);
@ -294,7 +304,7 @@ extern int ParmList_is_compactdefargs(ParmList *p);
extern DOH *Swig_name_object_get(Hash *namehash, String *prefix, String *name, SwigType *decl);
extern void Swig_name_object_inherit(Hash *namehash, String *base, String *derived);
extern void Swig_features_get(Hash *features, String *prefix, String *name, SwigType *decl, Node *n);
extern void Swig_feature_set(Hash *features, const_String_or_char_ptr name, SwigType *decl, const_String_or_char_ptr featurename, String *value, Hash *featureattribs);
extern void Swig_feature_set(Hash *features, const_String_or_char_ptr name, SwigType *decl, const_String_or_char_ptr featurename, const_String_or_char_ptr value, Hash *featureattribs);
/* --- Misc --- */
extern char *Swig_copy_string(const char *c);
@ -307,6 +317,10 @@ extern int ParmList_is_compactdefargs(ParmList *p);
extern void Swig_filename_correct(String *filename);
extern String *Swig_filename_escape(String *filename);
extern void Swig_filename_unescape(String *filename);
extern int Swig_storage_isextern(Node *n);
extern int Swig_storage_isexternc(Node *n);
extern int Swig_storage_isstatic_custom(Node *n, const_String_or_char_ptr storage);
extern int Swig_storage_isstatic(Node *n);
extern String *Swig_string_escape(String *s);
extern String *Swig_string_mangle(const String *s);
extern void Swig_scopename_split(const String *s, String **prefix, String **last);
@ -318,6 +332,7 @@ extern int ParmList_is_compactdefargs(ParmList *p);
extern String *Swig_string_lower(String *s);
extern String *Swig_string_upper(String *s);
extern String *Swig_string_title(String *s);
extern void Swig_offset_string(String *s, int number);
extern String *Swig_pcre_version(void);
extern void Swig_init(void);
extern int Swig_value_wrapper_mode(int mode);
@ -359,7 +374,7 @@ extern int ParmList_is_compactdefargs(ParmList *p);
/* --- Transformations --- */
extern int Swig_MethodToFunction(Node *n, const_String_or_char_ptr nspace, String *classname, int flags, SwigType *director_type, int is_director);
extern int Swig_ConstructorToFunction(Node *n, const_String_or_char_ptr nspace, String *classname, String *none_comparison, String *director_ctor, int cplus, int flags);
extern int Swig_ConstructorToFunction(Node *n, const_String_or_char_ptr nspace, String *classname, String *none_comparison, String *director_ctor, int cplus, int flags, String *directorname);
extern int Swig_DestructorToFunction(Node *n, const_String_or_char_ptr nspace, String *classname, int cplus, int flags);
extern int Swig_MembersetToFunction(Node *n, String *classname, int flags);
extern int Swig_MembergetToFunction(Node *n, String *classname, int flags);
@ -405,6 +420,13 @@ extern int ParmList_is_compactdefargs(ParmList *p);
extern void Swig_fragment_emit(String *name);
extern void Swig_fragment_clear(String *section);
/* --- Extension support --- */
extern Hash *Swig_extend_hash(void);
extern void Swig_extend_merge(Node *cls, Node *am);
extern void Swig_extend_append_previous(Node *cls, Node *am);
extern void Swig_extend_unused_check(void);
/* hacks defined in C++ ! */
extern int Swig_director_mode(void);
extern int Swig_director_protected_mode(void);

View file

@ -22,6 +22,7 @@ extern int Scanner_token(Scanner *);
extern String *Scanner_text(Scanner *);
extern void Scanner_skip_line(Scanner *);
extern int Scanner_skip_balanced(Scanner *, int startchar, int endchar);
extern String *Scanner_get_raw_text_balanced(Scanner *, int startchar, int endchar);
extern void Scanner_set_location(Scanner *, String *file, int line);
extern String *Scanner_file(Scanner *);
extern int Scanner_line(Scanner *);
@ -67,6 +68,9 @@ extern void Scanner_locator(Scanner *, String *loc);
#define SWIG_TOKEN_QUESTION 30 /* ? */
#define SWIG_TOKEN_COMMENT 31 /* C or C++ comment */
#define SWIG_TOKEN_BOOL 32 /* true or false */
#define SWIG_TOKEN_WSTRING 33 /* L"str" */
#define SWIG_TOKEN_WCHAR 34 /* L'c' */
#define SWIG_TOKEN_ILLEGAL 99
#define SWIG_TOKEN_ERROR -1

View file

@ -38,6 +38,7 @@ extern void appendChild(Node *node, Node *child);
extern void prependChild(Node *node, Node *child);
extern void removeNode(Node *node);
extern Node *copyNode(Node *node);
extern void appendSibling(Node *node, Node *child);
/* Node restoration/restore functions */

View file

@ -171,6 +171,24 @@ void prependChild(Node *node, Node *chd) {
}
}
void appendSibling(Node *node, Node *chd) {
Node *parent;
Node *lc = node;
while (nextSibling(lc))
lc = nextSibling(lc);
set_nextSibling(lc, chd);
set_previousSibling(chd, lc);
parent = parentNode(node);
if (parent) {
while (chd) {
lc = chd;
set_parentNode(chd, parent);
chd = nextSibling(chd);
}
set_lastChild(parent, lc);
}
}
/* -----------------------------------------------------------------------------
* removeNode()
*

View file

@ -1039,13 +1039,13 @@ static int typemap_replace_vars(String *s, ParmList *locals, SwigType *type, Swi
$*n_ltype
*/
if (SwigType_ispointer(ftype) || (SwigType_isarray(ftype)) || (SwigType_isreference(ftype))) {
if (!(SwigType_isarray(type) || SwigType_ispointer(type) || SwigType_isreference(type))) {
if (SwigType_ispointer(ftype) || (SwigType_isarray(ftype)) || (SwigType_isreference(ftype)) || (SwigType_isrvalue_reference(ftype))) {
if (!(SwigType_isarray(type) || SwigType_ispointer(type) || SwigType_isreference(type) || SwigType_isrvalue_reference(type))) {
star_type = Copy(ftype);
} else {
star_type = Copy(type);
}
if (!SwigType_isreference(star_type)) {
if (!(SwigType_isreference(star_type) || SwigType_isrvalue_reference(star_type))) {
if (SwigType_isarray(star_type)) {
SwigType_del_element(star_type);
} else {
@ -1200,7 +1200,7 @@ static int typemap_replace_vars(String *s, ParmList *locals, SwigType *type, Swi
* creates the local variables.
* ------------------------------------------------------------------------ */
static void typemap_locals(DOHString * s, ParmList *l, Wrapper *f, int argnum) {
static void typemap_locals(String *s, ParmList *l, Wrapper *f, int argnum) {
Parm *p;
char *new_name;

View file

@ -44,6 +44,7 @@
*
* 'p.' = Pointer (*)
* 'r.' = Reference (&)
* 'z.' = Rvalue reference (&&)
* 'a(n).' = Array of size n [n]
* 'f(..,..).' = Function with arguments (args)
* 'q(str).' = Qualifier (such as const or volatile) (const, volatile)
@ -77,6 +78,7 @@
*
* SwigType_add_pointer()
* SwigType_add_reference()
* SwigType_add_rvalue_reference()
* SwigType_add_array()
*
* These are used to build new types. There are also functions to undo these
@ -84,12 +86,14 @@
*
* SwigType_del_pointer()
* SwigType_del_reference()
* SwigType_del_rvalue_reference()
* SwigType_del_array()
*
* In addition, there are query functions
*
* SwigType_ispointer()
* SwigType_isreference()
* SwigType_isrvalue_reference()
* SwigType_isarray()
*
* Finally, there are some data extraction functions that can be used to
@ -236,7 +240,7 @@ String *SwigType_parm(const SwigType *t) {
/* -----------------------------------------------------------------------------
* SwigType_split()
*
* Splits a type into it's component parts and returns a list of string.
* Splits a type into its component parts and returns a list of string.
* ----------------------------------------------------------------------------- */
List *SwigType_split(const SwigType *t) {
@ -414,6 +418,41 @@ int SwigType_isreference(const SwigType *t) {
return 0;
}
/* -----------------------------------------------------------------------------
* Rvalue References
*
* SwigType_add_rvalue_reference()
* SwigType_del_rvalue_reference()
* SwigType_isrvalue_reference()
*
* Add, remove, and test if a type is a rvalue reference. The deletion and query
* functions take into account qualifiers (if any).
* ----------------------------------------------------------------------------- */
SwigType *SwigType_add_rvalue_reference(SwigType *t) {
Insert(t, 0, "z.");
return t;
}
SwigType *SwigType_del_rvalue_reference(SwigType *t) {
char *c = Char(t);
int check = strncmp(c, "z.", 2);
assert(check == 0);
Delslice(t, 0, 2);
return t;
}
int SwigType_isrvalue_reference(const SwigType *t) {
char *c;
if (!t)
return 0;
c = Char(t);
if (strncmp(c, "z.", 2) == 0) {
return 1;
}
return 0;
}
/* -----------------------------------------------------------------------------
* Qualifiers
*

View file

@ -602,7 +602,7 @@ SwigType *SwigType_typedef_resolve(const SwigType *t) {
Typetab *s;
Hash *ttab;
String *namebase = 0;
String *nameprefix = 0;
String *nameprefix = 0, *rnameprefix = 0;
int newtype = 0;
resolved_scope = 0;
@ -647,51 +647,66 @@ SwigType *SwigType_typedef_resolve(const SwigType *t) {
Printf(stdout, "nameprefix = '%s'\n", nameprefix);
#endif
if (nameprefix) {
/* Name had a prefix on it. See if we can locate the proper scope for it */
String *rnameprefix = template_parameters_resolve(nameprefix);
nameprefix = rnameprefix ? Copy(rnameprefix) : nameprefix;
Delete(rnameprefix);
s = SwigType_find_scope(s, nameprefix);
/* Couldn't locate a scope for the type. */
if (!s) {
Delete(base);
Delete(namebase);
Delete(nameprefix);
r = 0;
goto return_result;
}
/* Try to locate the name starting in the scope */
rnameprefix = SwigType_typedef_resolve(nameprefix);
if(rnameprefix != NULL) {
#ifdef SWIG_DEBUG
Printf(stdout, "namebase = '%s'\n", namebase);
Printf(stdout, "nameprefix '%s' is a typedef to '%s'\n", nameprefix, rnameprefix);
#endif
type = typedef_resolve(s, namebase);
if (type && resolved_scope) {
/* we need to look for the resolved type, this will also
fix the resolved_scope if 'type' and 'namebase' are
declared in different scopes */
String *rtype = 0;
rtype = typedef_resolve(resolved_scope, type);
if (rtype)
type = rtype;
}
#ifdef SWIG_DEBUG
Printf(stdout, "%s type = '%s'\n", Getattr(s, "name"), type);
#endif
if (type && (!Swig_scopename_check(type)) && resolved_scope) {
Typetab *rtab = resolved_scope;
String *qname = Getattr(resolved_scope, "qname");
/* If qualified *and* the typename is defined from the resolved scope, we qualify */
if ((qname) && typedef_resolve(resolved_scope, type)) {
type = Copy(type);
Insert(type, 0, "::");
Insert(type, 0, qname);
#ifdef SWIG_DEBUG
Printf(stdout, "qual %s \n", type);
#endif
newtype = 1;
type = Copy(namebase);
Insert(type, 0, "::");
Insert(type, 0, rnameprefix);
if (strncmp(Char(type), "::", 2) == 0) {
Delitem(type, 0);
Delitem(type, 0);
}
newtype = 1;
} else {
/* Name had a prefix on it. See if we can locate the proper scope for it */
String *rnameprefix = template_parameters_resolve(nameprefix);
nameprefix = rnameprefix ? Copy(rnameprefix) : nameprefix;
Delete(rnameprefix);
s = SwigType_find_scope(s, nameprefix);
/* Couldn't locate a scope for the type. */
if (!s) {
Delete(base);
Delete(namebase);
Delete(nameprefix);
r = 0;
goto return_result;
}
/* Try to locate the name starting in the scope */
#ifdef SWIG_DEBUG
Printf(stdout, "namebase = '%s'\n", namebase);
#endif
type = typedef_resolve(s, namebase);
if (type && resolved_scope) {
/* we need to look for the resolved type, this will also
fix the resolved_scope if 'type' and 'namebase' are
declared in different scopes */
String *rtype = 0;
rtype = typedef_resolve(resolved_scope, type);
if (rtype)
type = rtype;
}
#ifdef SWIG_DEBUG
Printf(stdout, "%s type = '%s'\n", Getattr(s, "name"), type);
#endif
if ((type) && (!Swig_scopename_check(type)) && resolved_scope) {
Typetab *rtab = resolved_scope;
String *qname = Getattr(resolved_scope, "qname");
/* If qualified *and* the typename is defined from the resolved scope, we qualify */
if ((qname) && typedef_resolve(resolved_scope, type)) {
type = Copy(type);
Insert(type, 0, "::");
Insert(type, 0, qname);
#ifdef SWIG_DEBUG
Printf(stdout, "qual %s \n", type);
#endif
newtype = 1;
}
resolved_scope = rtab;
}
resolved_scope = rtab;
}
} else {
/* Name is unqualified. */
@ -1282,6 +1297,8 @@ int SwigType_type(const SwigType *t) {
if (strncmp(c, "p.", 2) == 0) {
if (SwigType_type(c + 2) == T_CHAR)
return T_STRING;
else if (SwigType_type(c + 2) == T_WCHAR)
return T_WSTRING;
else
return T_POINTER;
}
@ -1289,6 +1306,8 @@ int SwigType_type(const SwigType *t) {
return T_ARRAY;
if (strncmp(c, "r.", 2) == 0)
return T_REFERENCE;
if (strncmp(c, "z.", 2) == 0)
return T_RVALUE_REFERENCE;
if (strncmp(c, "m(", 2) == 0)
return T_MPOINTER;
if (strncmp(c, "q(", 2) == 0) {
@ -1322,6 +1341,8 @@ int SwigType_type(const SwigType *t) {
return T_SCHAR;
if (strcmp(c, "unsigned char") == 0)
return T_UCHAR;
if (strcmp(c, "wchar_t") == 0)
return T_WCHAR;
if (strcmp(c, "float") == 0)
return T_FLOAT;
if (strcmp(c, "double") == 0)
@ -1344,6 +1365,8 @@ int SwigType_type(const SwigType *t) {
return T_ULONGLONG;
if (strncmp(c, "enum ", 5) == 0)
return T_INT;
if (strcmp(c, "auto") == 0)
return T_AUTO;
if (strcmp(c, "v(...)") == 0)
return T_VARARGS;
@ -1373,13 +1396,13 @@ int SwigType_type(const SwigType *t) {
*
* 2.- swig doesn't mark 'type' as non-assignable.
*
* 3.- the user specify that the value wrapper is not needed by using
* the %feature("novaluewrapper"), in that case the user need to type
* 3.- the user specifies that the value wrapper is not needed by using
* %feature("novaluewrapper") like so:
*
* %feature("novaluewrapper") MyOpaqueClass;
* class MyOpaqueClass;
*
* Users can also force the use of the value wrapper by using the
* The user can also force the use of the value wrapper with
* %feature("valuewrapper").
* ----------------------------------------------------------------------------- */
@ -1621,6 +1644,11 @@ void SwigType_remember_clientdata(const SwigType *t, const_String_or_char_ptr cl
SwigType_del_reference(tt);
SwigType_add_pointer(tt);
SwigType_remember_clientdata(tt, clientdata);
} else if (SwigType_isrvalue_reference(t)) {
SwigType *tt = Copy(t);
SwigType_del_rvalue_reference(tt);
SwigType_add_pointer(tt);
SwigType_remember_clientdata(tt, clientdata);
}
}