Merge branch 'master' into tmp
Conflicts: .travis.yml Examples/Makefile.in Examples/test-suite/director_nspace.i Examples/test-suite/nspace.i Examples/test-suite/nspace_extend.i Source/Modules/lang.cxx configure.ac
This commit is contained in:
commit
a234542543
871 changed files with 29690 additions and 7800 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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. */
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ eswig_SOURCES = CParse/cscanner.c \
|
|||
Modules/modula3.cxx \
|
||||
Modules/module.cxx \
|
||||
Modules/mzscheme.cxx \
|
||||
Modules/nested.cxx \
|
||||
Modules/ocaml.cxx \
|
||||
Modules/octave.cxx \
|
||||
Modules/overload.cxx \
|
||||
|
|
@ -117,7 +118,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:
|
||||
|
|
@ -141,8 +142,6 @@ beautify-file:
|
|||
test -n "$(INDENTFILE)" || (echo INDENTFILE not defined && exit 1;)
|
||||
test -e $(INDENTFILE) || (echo File does not exist: $(INDENTFILE) && exit 1;)
|
||||
cp $(INDENTFILE) $(INDENTBAKSDIR)/$(INDENTFILE);
|
||||
unix2dos $(INDENTFILE)
|
||||
dos2unix $(INDENTFILE)
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
|
@ -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"))) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,12 +196,33 @@ public:
|
|||
}
|
||||
Setattr(n, "proxyname", proxyname);
|
||||
Delete(proxyname);
|
||||
Delete(symname);
|
||||
}
|
||||
}
|
||||
}
|
||||
return proxyname;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* directorClassName()
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
String *directorClassName(Node *n) {
|
||||
String *dirclassname;
|
||||
const char *attrib = "director:classname";
|
||||
|
||||
if (!(dirclassname = Getattr(n, attrib))) {
|
||||
String *classname = getClassPrefix();
|
||||
|
||||
dirclassname = NewStringf("SwigDirector_%s", classname);
|
||||
Setattr(n, attrib, dirclassname);
|
||||
}
|
||||
else
|
||||
dirclassname = Copy(dirclassname);
|
||||
|
||||
return dirclassname;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------
|
||||
* main()
|
||||
* ------------------------------------------------------------ */
|
||||
|
|
@ -776,7 +803,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 +1052,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 +1107,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 +1174,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 +1322,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 +1632,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 +1692,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 +1744,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 +1764,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 +1777,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 +1840,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 +1891,35 @@ 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;
|
||||
|
||||
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 +1932,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;
|
||||
// inner class doesn't need this prologue
|
||||
if (!Getattr(n, "nested:outer")) {
|
||||
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 +1970,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 +1991,36 @@ 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);
|
||||
bool has_outerclass = Getattr(n, "nested:outer") != 0 && !GetFlag(n, "feature:flatnested");
|
||||
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 +2057,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 +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);
|
||||
|
|
@ -2014,7 +2101,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 +2181,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 +2351,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);
|
||||
|
|
@ -3376,19 +3463,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 +3509,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 +3526,7 @@ public:
|
|||
Delete(wname);
|
||||
Delete(swig_director_connect);
|
||||
Delete(qualified_classname);
|
||||
Delete(dirClassName);
|
||||
Delete(dirclassname);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------
|
||||
|
|
@ -3485,7 +3579,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 +4011,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 +4025,7 @@ public:
|
|||
Delete(proxy_method_types);
|
||||
Delete(callback_def);
|
||||
Delete(callback_code);
|
||||
Delete(dirclassname);
|
||||
DelWrapper(w);
|
||||
|
||||
return status;
|
||||
|
|
@ -3970,13 +4065,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);
|
||||
}
|
||||
|
|
@ -4028,7 +4121,7 @@ public:
|
|||
Delete(director_ctor_code);
|
||||
director_ctor_code = NewString("$director_new");
|
||||
|
||||
Java_director_declaration(n);
|
||||
directorDeclaration(n);
|
||||
|
||||
Printf(f_directors_h, "%s {\n", Getattr(n, "director:decl"));
|
||||
Printf(f_directors_h, "\npublic:\n");
|
||||
|
|
@ -4047,6 +4140,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 +4195,7 @@ public:
|
|||
|
||||
int classDirectorEnd(Node *n) {
|
||||
int i;
|
||||
String *director_classname = directorClassName(n);
|
||||
String *dirclassname = directorClassName(n);
|
||||
|
||||
Wrapper *w = NewWrapper();
|
||||
|
||||
|
|
@ -4089,7 +4205,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 +4232,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 +4243,7 @@ public:
|
|||
Wrapper_print(w, f_directors);
|
||||
|
||||
DelWrapper(w);
|
||||
Delete(dirclassname);
|
||||
|
||||
return Language::classDirectorEnd(n);
|
||||
}
|
||||
|
|
@ -4148,19 +4265,19 @@ public:
|
|||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
* Java_director_declaration()
|
||||
* directorDeclaration()
|
||||
*
|
||||
* Generate the director class's declaration
|
||||
* e.g. "class SwigDirector_myclass : public myclass, public Swig::Director {"
|
||||
*--------------------------------------------------------------------*/
|
||||
|
||||
void Java_director_declaration(Node *n) {
|
||||
void directorDeclaration(Node *n) {
|
||||
|
||||
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 +4285,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 */
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -80,14 +85,19 @@ class GO:public Language {
|
|||
// 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 +108,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),
|
||||
|
|
@ -114,7 +125,8 @@ public:
|
|||
making_variable_wrappers(false),
|
||||
is_static_member_function(false),
|
||||
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 +158,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 +187,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 +215,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 +226,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 +288,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 +368,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 +386,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 +398,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 +425,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 +438,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".
|
||||
|
||||
|
|
@ -405,11 +453,14 @@ private:
|
|||
|
||||
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.
|
||||
|
||||
Printv(f_go_wrappers, "\n", NULL);
|
||||
|
|
@ -453,6 +504,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 +518,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 +548,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 +560,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 +1155,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 +1405,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 +1434,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 +1697,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 +2880,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 +2901,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 +2996,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 +3091,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 +3138,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 +3218,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 +3480,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 +3523,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 +3632,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);
|
||||
|
|
@ -4694,6 +4794,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);
|
||||
}
|
||||
|
|
@ -4860,7 +4963,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")));
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
|
|
@ -4895,9 +4998,10 @@ extern "C" Language *swig_go(void) {
|
|||
const char * const GO::usage = (char *) "\
|
||||
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";
|
||||
|
|
|
|||
|
|
@ -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\
|
||||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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,29 @@ 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;
|
||||
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 +1971,72 @@ 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);
|
||||
if (!Getattr(n, "nested:outer")) {
|
||||
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 +2054,43 @@ 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);
|
||||
bool has_outerclass = Getattr(n, "nested:outer") != 0 && !GetFlag(n, "feature:flatnested");
|
||||
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 +2122,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 +2152,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 +2174,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 +2250,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 +2404,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 +2976,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 +2991,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 +3000,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 +3008,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 +3027,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 +3077,31 @@ 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);
|
||||
replacementname = Copy(enumname);
|
||||
else
|
||||
Replaceall(tm, classnamespecialvariable, NewStringf("int"));
|
||||
replacementname = NewString("int");
|
||||
} 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);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
|
|
@ -3388,7 +3487,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 +3527,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 +3596,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 +3636,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 +4037,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 +4126,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 +4168,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 +4225,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()
|
||||
* ------------------------------------------------------------ */
|
||||
|
|
@ -4221,7 +4403,7 @@ public:
|
|||
Delete(director_ctor_code);
|
||||
director_ctor_code = NewString("$director_new");
|
||||
|
||||
Java_director_declaration(n);
|
||||
directorDeclaration(n);
|
||||
|
||||
Printf(f_directors_h, "%s {\n", Getattr(n, "director:decl"));
|
||||
Printf(f_directors_h, "\npublic:\n");
|
||||
|
|
@ -4405,13 +4587,13 @@ public:
|
|||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
* Java_director_declaration()
|
||||
* directorDeclaration()
|
||||
*
|
||||
* Generate the director class's declaration
|
||||
* e.g. "class SwigDirector_myclass : public myclass, public Swig::Director {"
|
||||
*--------------------------------------------------------------------*/
|
||||
|
||||
void Java_director_declaration(Node *n) {
|
||||
void directorDeclaration(Node *n) {
|
||||
String *base = Getattr(n, "classtype");
|
||||
String *class_ctor = NewString("Swig::Director(jenv)");
|
||||
|
||||
|
|
@ -4425,6 +4607,9 @@ public:
|
|||
Setattr(n, "director:ctor", class_ctor);
|
||||
}
|
||||
|
||||
NestedClassSupport nestedClassesSupport() const {
|
||||
return NCS_Full;
|
||||
}
|
||||
}; /* class JAVA */
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -467,27 +471,44 @@ void swig_pragma(char *lang, char *name, char *value) {
|
|||
}
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
* use_naturalvar_mode()
|
||||
* Language::use_naturalvar_mode()
|
||||
*
|
||||
* Determine whether to use const ref typemaps instead of pointer typemaps
|
||||
* for variable access.
|
||||
* -------------------------------------------------------------------------- */
|
||||
int use_naturalvar_mode(Node *n) {
|
||||
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);
|
||||
if (SwigType_isclass(fullty)) {
|
||||
Node *m = Copy(n);
|
||||
SwigType *tys = SwigType_strip_qualifiers(fullty);
|
||||
Swig_features_get(Swig_cparse_features(), 0, tys, 0, m);
|
||||
nvar = GetFlag(m, "feature:naturalvar");
|
||||
if (!CPlusPlus) {
|
||||
Replaceall(tys, "struct ", "");
|
||||
Replaceall(tys, "union ", "");
|
||||
Replaceall(tys, "class ", "");
|
||||
}
|
||||
Node *typenode = Swig_symbol_clookup(tys, 0);
|
||||
if (typenode) {
|
||||
naturalvar = Getattr(typenode, "feature:naturalvar");
|
||||
explicitly_off = naturalvar && Strcmp(naturalvar, "0") == 0;
|
||||
nvar = nvar || GetFlag(typenode, "feature:naturalvar");
|
||||
}
|
||||
Delete(tys);
|
||||
Delete(m);
|
||||
}
|
||||
Delete(fullty);
|
||||
}
|
||||
return nvar ? CWRAP_NATURAL_VAR : 0;
|
||||
nvar = nvar || naturalvar_mode;
|
||||
return explicitly_off ? 0 : nvar ? CWRAP_NATURAL_VAR : 0;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
|
|
@ -502,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");
|
||||
|
|
@ -516,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;
|
||||
}
|
||||
|
||||
|
|
@ -947,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.
|
||||
|
|
@ -977,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);
|
||||
|
|
@ -1006,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);
|
||||
}
|
||||
}
|
||||
|
|
@ -1050,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 */
|
||||
|
|
@ -1358,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 */
|
||||
|
|
@ -1366,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);
|
||||
|
|
@ -1420,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);
|
||||
|
|
@ -1441,6 +1450,7 @@ int Language::membervariableHandler(Node *n) {
|
|||
tm = Swig_typemap_lookup("memberin", nin, target, 0);
|
||||
Delete(nin);
|
||||
}
|
||||
|
||||
int flags = Extend | SmartPointer | use_naturalvar_mode(n);
|
||||
if (isNonVirtualProtectedAccess(n))
|
||||
flags = flags | CWRAP_ALL_PROTECTED_ACCESS;
|
||||
|
|
@ -1471,9 +1481,7 @@ int Language::membervariableHandler(Node *n) {
|
|||
}
|
||||
if (make_set_wrapper) {
|
||||
Setattr(n, "sym:name", mrename_set);
|
||||
SetFlag(n, "wrap:issetter");
|
||||
functionWrapper(n);
|
||||
Delattr(n, "wrap:issetter");
|
||||
} else {
|
||||
SetFlag(n, "feature:immutable");
|
||||
}
|
||||
|
|
@ -1481,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;
|
||||
|
|
@ -1498,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);
|
||||
|
|
@ -2355,6 +2365,15 @@ 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;
|
||||
|
||||
String *kind = Getattr(n, "kind");
|
||||
String *name = Getattr(n, "name");
|
||||
String *tdname = Getattr(n, "tdname");
|
||||
|
|
@ -2363,6 +2382,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;
|
||||
|
|
@ -2373,15 +2394,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 {
|
||||
|
|
@ -2392,9 +2419,8 @@ 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) {
|
||||
|
|
@ -2436,25 +2462,27 @@ 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;
|
||||
ClassName = oldClassName;
|
||||
Delete(DirectorClassName);
|
||||
DirectorClassName = 0;
|
||||
DirectorClassName = oldDirectorClassName;
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
|
|
@ -2463,7 +2491,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 */
|
||||
|
|
@ -2496,7 +2526,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++) {
|
||||
|
|
@ -2515,7 +2545,7 @@ int Language::classHandler(Node *n) {
|
|||
Setattr(m, "parentNode", n);
|
||||
/*
|
||||
* There is a bug that needs fixing still...
|
||||
* This area of code is creating methods which have not been overidden in a derived class (director methods that are protected in the base)
|
||||
* This area of code is creating methods which have not been overridden in a derived class (director methods that are protected in the base)
|
||||
* If the method is overloaded, then Swig_overload_dispatch() incorrectly generates a call to the base wrapper, _wrap_xxx method
|
||||
* See director_protected_overloaded.i - Possibly sym:overname needs correcting here.
|
||||
Printf(stdout, "new method: %s::%s(%s)\n", Getattr(parentNode(m), "name"), Getattr(m, "name"), ParmList_str_defaultargs(Getattr(m, "parms")));
|
||||
|
|
@ -2525,7 +2555,6 @@ int Language::classHandler(Node *n) {
|
|||
}
|
||||
Delete(wrapname);
|
||||
}
|
||||
cplus_mode = old_mode;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2633,7 +2662,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
|
||||
|
|
@ -2923,11 +2952,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);
|
||||
|
|
@ -2958,14 +2990,16 @@ int Language::variableWrapper(Node *n) {
|
|||
Delete(pname0);
|
||||
}
|
||||
if (make_set_wrapper) {
|
||||
SetFlag(n, "wrap:issetter");
|
||||
Setattr(n, "varset", "1");
|
||||
functionWrapper(n);
|
||||
Delattr(n, "wrap:issetter");
|
||||
} 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;
|
||||
|
|
@ -2979,7 +3013,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;
|
||||
}
|
||||
|
|
@ -3023,17 +3059,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)) {
|
||||
|
|
@ -3049,6 +3078,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()
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
|
@ -3095,7 +3188,7 @@ Node *Language::symbolLookup(String *s, const_String_or_char_ptr scope) {
|
|||
* Tries to locate a class from a type definition
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
Node *Language::classLookup(const SwigType *s) {
|
||||
Node *Language::classLookup(const SwigType *s) const {
|
||||
Node *n = 0;
|
||||
|
||||
/* Look in hash of cached values */
|
||||
|
|
@ -3421,6 +3514,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
|
|
@ -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 */
|
||||
|
|
@ -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,11 @@ 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);
|
||||
}
|
||||
|
||||
if (Verbose) {
|
||||
Printf(stdout, "Processing types...\n");
|
||||
|
|
@ -1181,6 +1192,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);
|
||||
|
|
|
|||
446
Source/Modules/nested.cxx
Normal file
446
Source/Modules/nested.cxx
Normal file
|
|
@ -0,0 +1,446 @@
|
|||
/* -----------------------------------------------------------------------------
|
||||
* 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);
|
||||
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);
|
||||
// Check for extensions
|
||||
/* // TODO: we can save extensions hash like class hash and move check_extensions() after nesting processing
|
||||
if (extendhash) {
|
||||
if (Node *am = Getattr(extendhash, name)) {
|
||||
// Merge the extension into the symbol table
|
||||
merge_extensions(c, am);
|
||||
append_previous_extension(c, am);
|
||||
Delattr(extendhash, clsname);
|
||||
}
|
||||
}*/
|
||||
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
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -12,6 +12,7 @@
|
|||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
#include "swigmod.h"
|
||||
#include "cparse.h"
|
||||
|
||||
static String *global_name = 0;
|
||||
static String *op_prefix = 0;
|
||||
|
|
@ -132,6 +133,10 @@ 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) {
|
||||
|
|
@ -518,7 +523,7 @@ public:
|
|||
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");
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -443,7 +444,6 @@ 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, " if(ZEND_NUM_ARGS() != 2 || zend_get_parameters_array_ex(2, args) != SUCCESS) {\n");
|
||||
|
|
@ -518,6 +518,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 +647,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 +658,7 @@ public:
|
|||
Delete(s_vdecl);
|
||||
Delete(all_cs_entry);
|
||||
Delete(s_entry);
|
||||
Delete(s_arginfo);
|
||||
Delete(f_runtime);
|
||||
Delete(f_begin);
|
||||
|
||||
|
|
@ -673,12 +677,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 +718,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");
|
||||
|
|
@ -791,16 +808,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);
|
||||
|
|
@ -1324,6 +1341,7 @@ public:
|
|||
break;
|
||||
}
|
||||
case T_REFERENCE:
|
||||
case T_RVALUE_REFERENCE:
|
||||
case T_USER:
|
||||
case T_ARRAY:
|
||||
Clear(value);
|
||||
|
|
@ -1366,6 +1384,7 @@ public:
|
|||
}
|
||||
}
|
||||
if (Strcmp(value, "NULL") == 0 ||
|
||||
Strcmp(value, "nullptr") == 0 ||
|
||||
Strcmp(value, "0") == 0 ||
|
||||
Strcmp(value, "0L") == 0) {
|
||||
Clear(value);
|
||||
|
|
@ -2606,8 +2625,8 @@ done:
|
|||
/* wrap complex arguments to zvals */
|
||||
Printv(w->code, wrap_args, NIL);
|
||||
|
||||
Append(w->code, "call_user_function(EG(function_table), (zval**)&swig_self, &funcname,\n");
|
||||
Printf(w->code, " %s, %d, args TSRMLS_CC);\n", Swig_cresult_name(), idx);
|
||||
Append(w->code, "call_user_function(EG(function_table), (zval**)&swig_self, &funcname,");
|
||||
Printf(w->code, " %s, %d, args TSRMLS_CC);\n", Swig_cresult_name(), idx);
|
||||
|
||||
if (tm) {
|
||||
Printv(w->code, Str(tm), "\n", NIL);
|
||||
|
|
@ -2625,8 +2644,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);
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
@ -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");
|
||||
|
|
@ -3728,7 +3990,7 @@ public:
|
|||
if (builtin)
|
||||
builtin_pre_decl(n);
|
||||
|
||||
/* Overide the shadow file so we can capture its methods */
|
||||
/* Override the shadow file so we can capture its methods */
|
||||
f_shadow = NewString("");
|
||||
|
||||
// Set up type check for director class constructor
|
||||
|
|
|
|||
|
|
@ -2299,7 +2299,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);
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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,8 +215,11 @@ 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 *classLookup(const SwigType *s); /* Class 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? */
|
||||
virtual int is_assignable(Node *n); /* Is variable assignable? */
|
||||
|
|
@ -296,10 +300,29 @@ 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;
|
||||
|
||||
/* Identify if a wrapped global or member variable n should use the naturalvar feature */
|
||||
int use_naturalvar_mode(Node *n) const;
|
||||
|
||||
/* Director subclass comparison test */
|
||||
String *none_comparison;
|
||||
|
||||
|
|
@ -380,7 +403,6 @@ int is_protected(Node *n);
|
|||
int is_member_director(Node *parentnode, Node *member);
|
||||
int is_member_director(Node *member);
|
||||
int is_non_virtual_protected_access(Node *n); /* Check if the non-virtual protected members are required (for directors) */
|
||||
int use_naturalvar_mode(Node *n);
|
||||
|
||||
void Wrapper_virtual_elimination_mode_set(int);
|
||||
void Wrapper_fast_dispatch_mode_set(int);
|
||||
|
|
@ -407,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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
* ------------------------------------------------------------ */
|
||||
|
|
@ -645,7 +677,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 +876,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 +1019,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 +1114,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 +1177,7 @@ class TypePass:private Dispatcher {
|
|||
#ifdef DEBUG_OVERLOADED
|
||||
show_overloaded(debugnode);
|
||||
#endif
|
||||
clean_overloaded(n); // Needed?
|
||||
clean_overloaded(n); // Needed?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1249,3 +1281,4 @@ void Swig_process_types(Node *n) {
|
|||
return;
|
||||
TypePass::pass(n);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -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,7 +940,7 @@ 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) {
|
||||
else if (Swig_storage_isstatic(n)) {
|
||||
String *cname = Getattr(n, "classname") ? Getattr(n, "classname") : classname;
|
||||
String *ctname = SwigType_namestr(cname);
|
||||
self = NewStringf("(*(%s const *)this)->", ctname);
|
||||
|
|
@ -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;
|
||||
|
|
@ -1409,7 +1485,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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -72,11 +72,11 @@ void Swig_banner(File *f) {
|
|||
Printf(f, "/* ----------------------------------------------------------------------------\n\
|
||||
* This file was automatically generated by SWIG (http://www.swig.org).\n\
|
||||
* Version %s\n\
|
||||
* \n\
|
||||
* This file is not intended to be easily readable and contains a number of \n\
|
||||
*\n\
|
||||
* This file is not intended to be easily readable and contains a number of\n\
|
||||
* coding conventions designed to improve portability and efficiency. Do not make\n\
|
||||
* changes to this file unless you know what you are doing--modify the SWIG \n\
|
||||
* interface file instead. \n", Swig_package_version());
|
||||
* changes to this file unless you know what you are doing--modify the SWIG\n\
|
||||
* interface file instead.\n", Swig_package_version());
|
||||
/* String too long for ISO compliance */
|
||||
Printf(f, " * ----------------------------------------------------------------------------- */\n");
|
||||
|
||||
|
|
@ -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,38 @@ 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) {
|
||||
Putc(*convertCase == 1 ? toupper(*src) : tolower(*src), 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++) {
|
||||
Putc(*convertCase == 1 ? toupper(*src) : tolower(*src), 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 +1268,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 +1282,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++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
void Scanner_push_brackets(Scanner*);
|
||||
void Scanner_clear_brackets(Scanner*);
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* NewScanner()
|
||||
*
|
||||
|
|
@ -65,6 +69,8 @@ Scanner *NewScanner(void) {
|
|||
s->error = 0;
|
||||
s->error_line = 0;
|
||||
s->freeze_line = 0;
|
||||
s->brackets = NewList();
|
||||
Scanner_push_brackets(s);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
|
@ -77,12 +83,13 @@ Scanner *NewScanner(void) {
|
|||
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);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
|
|
@ -96,6 +103,7 @@ void Scanner_clear(Scanner * s) {
|
|||
Delete(s->str);
|
||||
Clear(s->text);
|
||||
Clear(s->scanobjs);
|
||||
Scanner_clear_brackets(s);
|
||||
Delete(s->error);
|
||||
s->str = 0;
|
||||
s->error = 0;
|
||||
|
|
@ -260,6 +268,74 @@ static void freeze_line(Scanner *s, int val) {
|
|||
s->freeze_line = val;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Scanner_brackets()
|
||||
*
|
||||
* Returns the number of brackets at the current depth.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
int*
|
||||
Scanner_brackets(Scanner *s) {
|
||||
return (int*)(**((void***)Getitem(s->brackets, 0))); /* TODO: Use VoidObj*->ptr instead of void** */
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Scanner_clear_brackets()
|
||||
*
|
||||
* Resets the current depth and clears all brackets.
|
||||
* Usually called at the end of statements;
|
||||
* ----------------------------------------------------------------------------- */
|
||||
void
|
||||
Scanner_clear_brackets(Scanner *s) {
|
||||
Clear(s->brackets);
|
||||
Scanner_push_brackets(s); /* base bracket count should always be created */
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Scanner_inc_brackets()
|
||||
*
|
||||
* Increases the number of brackets at the current depth.
|
||||
* Usually called when '<' was found.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
void
|
||||
Scanner_inc_brackets(Scanner *s) {
|
||||
(*Scanner_brackets(s))++;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Scanner_dec_brackets()
|
||||
*
|
||||
* Decreases the number of brackets at the current depth.
|
||||
* Usually called when '>' was found.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
void
|
||||
Scanner_dec_brackets(Scanner *s) {
|
||||
(*Scanner_brackets(s))--;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Scanner_push_brackets()
|
||||
*
|
||||
* Increases the depth of brackets.
|
||||
* Usually called when '(' was found.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
void
|
||||
Scanner_push_brackets(Scanner *s) {
|
||||
int *newInt = malloc(sizeof(int));
|
||||
*newInt = 0;
|
||||
Push(s->brackets, NewVoid(newInt, free));
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Scanner_pop_brackets()
|
||||
*
|
||||
* Decreases the depth of brackets.
|
||||
* Usually called when ')' was found.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
void
|
||||
Scanner_pop_brackets(Scanner *s) {
|
||||
Delitem(s->brackets, 0);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* retract()
|
||||
*
|
||||
|
|
@ -407,13 +483,15 @@ static void get_escape(Scanner *s) {
|
|||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
static int look(Scanner * s) {
|
||||
int state;
|
||||
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,24 +513,30 @@ 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 == '(') {
|
||||
Scanner_push_brackets(s);
|
||||
return SWIG_TOKEN_LPAREN;
|
||||
else if (c == ')')
|
||||
}
|
||||
else if (c == ')') {
|
||||
Scanner_pop_brackets(s);
|
||||
return SWIG_TOKEN_RPAREN;
|
||||
else if (c == ';')
|
||||
}
|
||||
else if (c == ';') {
|
||||
Scanner_clear_brackets(s);
|
||||
return SWIG_TOKEN_SEMI;
|
||||
}
|
||||
else if (c == ',')
|
||||
return SWIG_TOKEN_COMMA;
|
||||
else if (c == '*')
|
||||
|
|
@ -502,16 +586,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 +674,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,6 +848,7 @@ static int look(Scanner * s) {
|
|||
break;
|
||||
|
||||
case 60: /* shift operators */
|
||||
Scanner_inc_brackets(s);
|
||||
if ((c = nextchar(s)) == 0)
|
||||
return SWIG_TOKEN_LESSTHAN;
|
||||
if (c == '<')
|
||||
|
|
@ -731,9 +861,10 @@ static int look(Scanner * s) {
|
|||
}
|
||||
break;
|
||||
case 61:
|
||||
Scanner_dec_brackets(s);
|
||||
if ((c = nextchar(s)) == 0)
|
||||
return SWIG_TOKEN_GREATERTHAN;
|
||||
if (c == '>')
|
||||
if (c == '>' && ((*Scanner_brackets(s))<0)) /* go to double >> only, if no template < has been used */
|
||||
state = 250;
|
||||
else if (c == '=')
|
||||
return SWIG_TOKEN_GTEQUAL;
|
||||
|
|
@ -742,18 +873,108 @@ static int look(Scanner * 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 +984,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;
|
||||
|
||||
|
|
@ -1049,6 +1311,7 @@ static int look(Scanner * s) {
|
|||
break;
|
||||
|
||||
case 240: /* LSHIFT, LSEQUAL */
|
||||
Scanner_inc_brackets(s);
|
||||
if ((c = nextchar(s)) == 0)
|
||||
return SWIG_TOKEN_LSHIFT;
|
||||
else if (c == '=')
|
||||
|
|
@ -1060,6 +1323,7 @@ static int look(Scanner * s) {
|
|||
break;
|
||||
|
||||
case 250: /* RSHIFT, RSEQUAL */
|
||||
Scanner_dec_brackets(s);
|
||||
if ((c = nextchar(s)) == 0)
|
||||
return SWIG_TOKEN_RSHIFT;
|
||||
else if (c == '=')
|
||||
|
|
@ -1282,6 +1546,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);
|
||||
int 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()
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue