Merge branch 'master' into C
This commit is contained in:
commit
55741f9e31
1702 changed files with 57386 additions and 21599 deletions
|
|
@ -28,6 +28,7 @@ extern "C" {
|
|||
extern int cparse_cplusplusout;
|
||||
extern int cparse_start_line;
|
||||
extern String *cparse_unknown_directive;
|
||||
extern int scan_doxygen_comments;
|
||||
|
||||
extern void Swig_cparse_cplusplus(int);
|
||||
extern void Swig_cparse_cplusplusout(int);
|
||||
|
|
@ -61,7 +62,7 @@ extern "C" {
|
|||
extern void cparse_normalize_void(Node *);
|
||||
extern Parm *Swig_cparse_parm(String *s);
|
||||
extern ParmList *Swig_cparse_parms(String *s, Node *file_line_node);
|
||||
extern Node *new_node(const_String_or_char_ptr tag);
|
||||
extern Node *Swig_cparse_new_node(const_String_or_char_ptr tag);
|
||||
|
||||
/* templ.c */
|
||||
extern int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab *tscope);
|
||||
|
|
@ -78,4 +79,7 @@ extern "C" {
|
|||
#define SWIG_WARN_NODE_END(Node) \
|
||||
if (wrnfilter) Swig_warnfilter(wrnfilter,0); \
|
||||
}
|
||||
|
||||
#define COMPOUND_EXPR_VAL(dtype) \
|
||||
((dtype).type == T_CHAR || (dtype).type == T_WCHAR ? (dtype).rawval : (dtype).val)
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -50,6 +50,57 @@ static int last_brace = 0;
|
|||
static int last_id = 0;
|
||||
static int rename_active = 0;
|
||||
|
||||
/* Doxygen comments scanning */
|
||||
int scan_doxygen_comments = 0;
|
||||
|
||||
int isStructuralDoxygen(String *s) {
|
||||
static const char* const structuralTags[] = {
|
||||
"addtogroup",
|
||||
"callgraph",
|
||||
"callergraph",
|
||||
"category",
|
||||
"def",
|
||||
"defgroup",
|
||||
"dir",
|
||||
"example",
|
||||
"file",
|
||||
"headerfile",
|
||||
"internal",
|
||||
"mainpage",
|
||||
"name",
|
||||
"nosubgrouping",
|
||||
"overload",
|
||||
"package",
|
||||
"page",
|
||||
"protocol",
|
||||
"relates",
|
||||
"relatesalso",
|
||||
"showinitializer",
|
||||
"weakgroup",
|
||||
};
|
||||
|
||||
unsigned n;
|
||||
char *slashPointer = Strchr(s, '\\');
|
||||
char *atPointer = Strchr(s,'@');
|
||||
if (slashPointer == NULL && atPointer == NULL)
|
||||
return 0;
|
||||
else if(slashPointer == NULL)
|
||||
slashPointer = atPointer;
|
||||
|
||||
slashPointer++; /* skip backslash or at sign */
|
||||
|
||||
for (n = 0; n < sizeof(structuralTags)/sizeof(structuralTags[0]); n++) {
|
||||
const size_t len = strlen(structuralTags[n]);
|
||||
if (strncmp(slashPointer, structuralTags[n], len) == 0) {
|
||||
/* Take care to avoid false positives with prefixes of other tags. */
|
||||
if (slashPointer[len] == '\0' || isspace(slashPointer[len]))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_cparse_cplusplus()
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
|
@ -367,10 +418,70 @@ static int yylook(void) {
|
|||
|
||||
case SWIG_TOKEN_COMMENT:
|
||||
{
|
||||
String *cmt = Scanner_text(scan);
|
||||
char *loc = Char(cmt);
|
||||
if ((strncmp(loc,"/*@SWIG",7) == 0) && (loc[Len(cmt)-3] == '@')) {
|
||||
Scanner_locator(scan, cmt);
|
||||
typedef enum {
|
||||
DOX_COMMENT_PRE = -1,
|
||||
DOX_COMMENT_NONE,
|
||||
DOX_COMMENT_POST
|
||||
} comment_kind_t;
|
||||
comment_kind_t existing_comment = DOX_COMMENT_NONE;
|
||||
|
||||
/* Concatenate or skip all consecutive comments at once. */
|
||||
do {
|
||||
String *cmt = Scanner_text(scan);
|
||||
char *loc = Char(cmt);
|
||||
if ((strncmp(loc, "/*@SWIG", 7) == 0) && (loc[Len(cmt)-3] == '@')) {
|
||||
Scanner_locator(scan, cmt);
|
||||
}
|
||||
if (scan_doxygen_comments) { /* else just skip this node, to avoid crashes in parser module*/
|
||||
/* Check for all possible Doxygen comment start markers while ignoring
|
||||
comments starting with a row of asterisks or slashes just as
|
||||
Doxygen itself does. */
|
||||
if (Len(cmt) > 3 && loc[0] == '/' &&
|
||||
((loc[1] == '/' && ((loc[2] == '/' && loc[3] != '/') || loc[2] == '!')) ||
|
||||
(loc[1] == '*' && ((loc[2] == '*' && loc[3] != '*') || loc[2] == '!')))) {
|
||||
comment_kind_t this_comment = loc[3] == '<' ? DOX_COMMENT_POST : DOX_COMMENT_PRE;
|
||||
if (existing_comment != DOX_COMMENT_NONE && this_comment != existing_comment) {
|
||||
/* We can't concatenate together Doxygen pre- and post-comments. */
|
||||
break;
|
||||
}
|
||||
|
||||
if (this_comment == DOX_COMMENT_POST || !isStructuralDoxygen(loc)) {
|
||||
String *str;
|
||||
|
||||
int begin = this_comment == DOX_COMMENT_POST ? 4 : 3;
|
||||
int end = Len(cmt);
|
||||
if (loc[end - 1] == '/' && loc[end - 2] == '*') {
|
||||
end -= 2;
|
||||
}
|
||||
|
||||
str = NewStringWithSize(loc + begin, end - begin);
|
||||
|
||||
if (existing_comment == DOX_COMMENT_NONE) {
|
||||
yylval.str = str;
|
||||
Setline(yylval.str, Scanner_start_line(scan));
|
||||
Setfile(yylval.str, Scanner_file(scan));
|
||||
} else {
|
||||
Append(yylval.str, str);
|
||||
}
|
||||
|
||||
existing_comment = this_comment;
|
||||
}
|
||||
}
|
||||
}
|
||||
do {
|
||||
tok = Scanner_token(scan);
|
||||
} while (tok == SWIG_TOKEN_ENDLINE);
|
||||
} while (tok == SWIG_TOKEN_COMMENT);
|
||||
|
||||
Scanner_pushtoken(scan, tok, Scanner_text(scan));
|
||||
|
||||
switch (existing_comment) {
|
||||
case DOX_COMMENT_PRE:
|
||||
return DOXYGENSTRING;
|
||||
case DOX_COMMENT_NONE:
|
||||
break;
|
||||
case DOX_COMMENT_POST:
|
||||
return DOXYGENPOSTSTRING;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -907,6 +1018,8 @@ int yylex(void) {
|
|||
return (ID);
|
||||
case POUND:
|
||||
return yylex();
|
||||
case SWIG_TOKEN_COMMENT:
|
||||
return yylex();
|
||||
default:
|
||||
return (l);
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -30,8 +30,10 @@ static void add_parms(ParmList *p, List *patchlist, List *typelist) {
|
|||
while (p) {
|
||||
SwigType *ty = Getattr(p, "type");
|
||||
SwigType *val = Getattr(p, "value");
|
||||
SwigType *name = Getattr(p, "name");
|
||||
Append(typelist, ty);
|
||||
Append(typelist, val);
|
||||
Append(typelist, name);
|
||||
Append(patchlist, val);
|
||||
p = nextSibling(p);
|
||||
}
|
||||
|
|
@ -49,32 +51,31 @@ void Swig_cparse_debug_templates(int x) {
|
|||
* template parameters
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
static int cparse_template_expand(Node *n, String *tname, String *rname, String *templateargs, List *patchlist, List *typelist, List *cpatchlist) {
|
||||
static void cparse_template_expand(Node *templnode, Node *n, String *tname, String *rname, String *templateargs, List *patchlist, List *typelist, List *cpatchlist) {
|
||||
static int expanded = 0;
|
||||
int ret;
|
||||
String *nodeType;
|
||||
if (!n)
|
||||
return 0;
|
||||
return;
|
||||
nodeType = nodeType(n);
|
||||
if (Getattr(n, "error"))
|
||||
return 0;
|
||||
return;
|
||||
|
||||
if (Equal(nodeType, "template")) {
|
||||
/* Change the node type back to normal */
|
||||
if (!expanded) {
|
||||
expanded = 1;
|
||||
set_nodeType(n, Getattr(n, "templatetype"));
|
||||
ret = cparse_template_expand(n, tname, rname, templateargs, patchlist, typelist, cpatchlist);
|
||||
cparse_template_expand(templnode, n, tname, rname, templateargs, patchlist, typelist, cpatchlist);
|
||||
expanded = 0;
|
||||
return ret;
|
||||
return;
|
||||
} else {
|
||||
/* Called when template appears inside another template */
|
||||
/* Member templates */
|
||||
|
||||
set_nodeType(n, Getattr(n, "templatetype"));
|
||||
ret = cparse_template_expand(n, tname, rname, templateargs, patchlist, typelist, cpatchlist);
|
||||
cparse_template_expand(templnode, n, tname, rname, templateargs, patchlist, typelist, cpatchlist);
|
||||
set_nodeType(n, "template");
|
||||
return ret;
|
||||
return;
|
||||
}
|
||||
} else if (Equal(nodeType, "cdecl")) {
|
||||
/* A simple C declaration */
|
||||
|
|
@ -131,7 +132,7 @@ static int cparse_template_expand(Node *n, String *tname, String *rname, String
|
|||
{
|
||||
Node *cn = firstChild(n);
|
||||
while (cn) {
|
||||
cparse_template_expand(cn, tname, rname, templateargs, patchlist, typelist, cpatchlist);
|
||||
cparse_template_expand(templnode, cn, tname, rname, templateargs, patchlist, typelist, cpatchlist);
|
||||
cn = nextSibling(cn);
|
||||
}
|
||||
}
|
||||
|
|
@ -177,25 +178,30 @@ static int cparse_template_expand(Node *n, String *tname, String *rname, String
|
|||
add_parms(Getattr(n, "parms"), cpatchlist, typelist);
|
||||
add_parms(Getattr(n, "throws"), cpatchlist, typelist);
|
||||
} else if (Equal(nodeType, "destructor")) {
|
||||
String *name = Getattr(n, "name");
|
||||
if (name) {
|
||||
if (strchr(Char(name), '<'))
|
||||
Append(patchlist, Getattr(n, "name"));
|
||||
else
|
||||
Append(name, templateargs);
|
||||
}
|
||||
name = Getattr(n, "sym:name");
|
||||
if (name) {
|
||||
if (strchr(Char(name), '<')) {
|
||||
String *sn = Copy(tname);
|
||||
Setattr(n, "sym:name", sn);
|
||||
Delete(sn);
|
||||
} else {
|
||||
Replace(name, tname, rname, DOH_REPLACE_ANY);
|
||||
/* We only need to patch the dtor of the template itself, not the destructors of any nested classes, so check that the parent of this node is the root
|
||||
* template node, with the special exception for %extend which adds its methods under an intermediate node. */
|
||||
Node* parent = parentNode(n);
|
||||
if (parent == templnode || (parentNode(parent) == templnode && Equal(nodeType(parent), "extend"))) {
|
||||
String *name = Getattr(n, "name");
|
||||
if (name) {
|
||||
if (strchr(Char(name), '<'))
|
||||
Append(patchlist, Getattr(n, "name"));
|
||||
else
|
||||
Append(name, templateargs);
|
||||
}
|
||||
name = Getattr(n, "sym:name");
|
||||
if (name) {
|
||||
if (strchr(Char(name), '<')) {
|
||||
String *sn = Copy(tname);
|
||||
Setattr(n, "sym:name", sn);
|
||||
Delete(sn);
|
||||
} else {
|
||||
Replace(name, tname, rname, DOH_REPLACE_ANY);
|
||||
}
|
||||
}
|
||||
/* Setattr(n,"sym:name",name); */
|
||||
Append(cpatchlist, Getattr(n, "code"));
|
||||
}
|
||||
/* Setattr(n,"sym:name",name); */
|
||||
Append(cpatchlist, Getattr(n, "code"));
|
||||
} else if (Equal(nodeType, "using")) {
|
||||
String *uname = Getattr(n, "uname");
|
||||
if (uname && strchr(Char(uname), '<')) {
|
||||
|
|
@ -217,11 +223,10 @@ static int cparse_template_expand(Node *n, String *tname, String *rname, String
|
|||
add_parms(Getattr(n, "throws"), cpatchlist, typelist);
|
||||
cn = firstChild(n);
|
||||
while (cn) {
|
||||
cparse_template_expand(cn, tname, rname, templateargs, patchlist, typelist, cpatchlist);
|
||||
cparse_template_expand(templnode, cn, tname, rname, templateargs, patchlist, typelist, cpatchlist);
|
||||
cn = nextSibling(cn);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
|
|
@ -306,7 +311,7 @@ int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab
|
|||
/* Printf(stdout,"targs = '%s'\n", templateargs);
|
||||
Printf(stdout,"rname = '%s'\n", rname);
|
||||
Printf(stdout,"tname = '%s'\n", tname); */
|
||||
cparse_template_expand(n, tname, rname, templateargs, patchlist, typelist, cpatchlist);
|
||||
cparse_template_expand(n, n, tname, rname, templateargs, patchlist, typelist, cpatchlist);
|
||||
|
||||
/* Set the name */
|
||||
{
|
||||
|
|
|
|||
|
|
@ -112,12 +112,12 @@ void cparse_normalize_void(Node *n) {
|
|||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* new_node()
|
||||
* Swig_cparse_new_node()
|
||||
*
|
||||
* Create an empty parse node, setting file and line number information
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
Node *new_node(const_String_or_char_ptr tag) {
|
||||
Node *Swig_cparse_new_node(const_String_or_char_ptr tag) {
|
||||
Node *n = NewHash();
|
||||
set_nodeType(n,tag);
|
||||
Setfile(n,cparse_file);
|
||||
|
|
|
|||
|
|
@ -81,8 +81,8 @@ static void InitPools() {
|
|||
* ---------------------------------------------------------------------- */
|
||||
|
||||
int DohCheck(const DOH *ptr) {
|
||||
register Pool *p = Pools;
|
||||
register char *cptr = (char *) ptr;
|
||||
Pool *p = Pools;
|
||||
char *cptr = (char *) ptr;
|
||||
while (p) {
|
||||
if ((cptr >= p->pbeg) && (cptr < p->pend)) {
|
||||
#ifdef DOH_DEBUG_MEMORY_POOLS
|
||||
|
|
|
|||
|
|
@ -141,15 +141,15 @@ static int String_cmp(DOH *so1, DOH *so2) {
|
|||
static int String_equal(DOH *so1, DOH *so2) {
|
||||
String *s1 = (String *) ObjData(so1);
|
||||
String *s2 = (String *) ObjData(so2);
|
||||
register int len = s1->len;
|
||||
int len = s1->len;
|
||||
if (len != s2->len) {
|
||||
return 0;
|
||||
} else {
|
||||
register char *c1 = s1->str;
|
||||
register char *c2 = s2->str;
|
||||
char *c1 = s1->str;
|
||||
char *c2 = s2->str;
|
||||
#if 0
|
||||
register int mlen = len >> 2;
|
||||
register int i = mlen;
|
||||
int mlen = len >> 2;
|
||||
int i = mlen;
|
||||
for (; i; --i) {
|
||||
if (*(c1++) != *(c2++))
|
||||
return 0;
|
||||
|
|
@ -180,11 +180,11 @@ static int String_hash(DOH *so) {
|
|||
if (s->hashkey >= 0) {
|
||||
return s->hashkey;
|
||||
} else {
|
||||
register char *c = s->str;
|
||||
register unsigned int len = s->len > 50 ? 50 : s->len;
|
||||
register unsigned int h = 0;
|
||||
register unsigned int mlen = len >> 2;
|
||||
register unsigned int i = mlen;
|
||||
char *c = s->str;
|
||||
unsigned int len = s->len > 50 ? 50 : s->len;
|
||||
unsigned int h = 0;
|
||||
unsigned int mlen = len >> 2;
|
||||
unsigned int i = mlen;
|
||||
for (; i; --i) {
|
||||
h = (h << 5) + *(c++);
|
||||
h = (h << 5) + *(c++);
|
||||
|
|
@ -463,9 +463,9 @@ static int String_seek(DOH *so, long offset, int whence) {
|
|||
|
||||
{
|
||||
#if 0
|
||||
register int sp = s->sp;
|
||||
register char *tc = s->str;
|
||||
register int len = s->len;
|
||||
int sp = s->sp;
|
||||
char *tc = s->str;
|
||||
int len = s->len;
|
||||
while (sp != nsp) {
|
||||
int prev = sp + inc;
|
||||
if (prev >= 0 && prev <= len && tc[prev] == '\n')
|
||||
|
|
@ -473,8 +473,8 @@ static int String_seek(DOH *so, long offset, int whence) {
|
|||
sp += inc;
|
||||
}
|
||||
#else
|
||||
register int sp = s->sp;
|
||||
register char *tc = s->str;
|
||||
int sp = s->sp;
|
||||
char *tc = s->str;
|
||||
if (inc > 0) {
|
||||
while (sp != nsp) {
|
||||
if (tc[++sp] == '\n')
|
||||
|
|
@ -508,12 +508,12 @@ static long String_tell(DOH *so) {
|
|||
|
||||
static int String_putc(DOH *so, int ch) {
|
||||
String *s = (String *) ObjData(so);
|
||||
register int len = s->len;
|
||||
register int sp = s->sp;
|
||||
int len = s->len;
|
||||
int sp = s->sp;
|
||||
s->hashkey = -1;
|
||||
if (sp >= len) {
|
||||
register int maxsize = s->maxsize;
|
||||
register char *tc = s->str;
|
||||
int maxsize = s->maxsize;
|
||||
char *tc = s->str;
|
||||
if (len > (maxsize - 2)) {
|
||||
maxsize *= 2;
|
||||
tc = (char *) DohRealloc(tc, maxsize);
|
||||
|
|
@ -679,7 +679,7 @@ static int replace_simple(String *str, char *token, char *rep, int flags, int co
|
|||
int noquote = 0;
|
||||
char *c, *s, *t, *first;
|
||||
char *q, *q2;
|
||||
register char *base;
|
||||
char *base;
|
||||
int i;
|
||||
|
||||
/* Figure out if anything gets replaced */
|
||||
|
|
|
|||
170
Source/Doxygen/doxycommands.h
Normal file
170
Source/Doxygen/doxycommands.h
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
/* -----------------------------------------------------------------------------
|
||||
* 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.
|
||||
*
|
||||
* doxycommands.h
|
||||
*
|
||||
* Part of the Doxygen comment translation module of SWIG.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
#ifndef DOXYGENCOMMANDS_H
|
||||
#define DOXYGENCOMMANDS_H
|
||||
|
||||
// doxy commands are not processed inside this block
|
||||
const char *CMD_HTML_ONLY = "htmlonly";
|
||||
// doxy commands are not processed inside this block
|
||||
const char *CMD_VERBATIM = "verbatim";
|
||||
const char *CMD_LATEX_1 = "f$";
|
||||
const char *CMD_LATEX_2 = "f{";
|
||||
const char *CMD_LATEX_3 = "f[";
|
||||
const char *CMD_END_HTML_ONLY = "endhtmlonly";
|
||||
const char *CMD_END_VERBATIM = "endverbatim";
|
||||
const char *CMD_END_LATEX_1 = "f$";
|
||||
const char *CMD_END_LATEX_2 = "f}";
|
||||
const char *CMD_END_LATEX_3 = "f]";
|
||||
|
||||
const char *sectionIndicators[] = {
|
||||
"attention", "author", "authors", "brief", "bug", "cond", "date",
|
||||
"deprecated", "details", "else", "elseif", "endcond", "endif",
|
||||
"exception", "if", "ifnot", "invariant", "note", "par", "param",
|
||||
"tparam", "post", "pre", "remarks", "remark", "result", "return",
|
||||
"returns", "retval", "sa", "see", "since", "test", "throw", "throws",
|
||||
"todo", "version", "warning", "xrefitem"
|
||||
};
|
||||
|
||||
const int sectionIndicatorsSize = sizeof(sectionIndicators) / sizeof(*sectionIndicators);
|
||||
|
||||
/* All of the doxygen commands divided up by how they are parsed */
|
||||
const char *simpleCommands[] = {
|
||||
// the first line are escaped chars, except \~, which is a language ID command.
|
||||
"n", "$", "@", "\\", "&", "~", "<", ">", "#", "%", "\"", ".", "::",
|
||||
"endcond",
|
||||
"callgraph", "callergraph", "showinitializer", "hideinitializer", "internal",
|
||||
"nosubgrouping", "public", "publicsection", "private", "privatesection",
|
||||
"protected", "protectedsection", "tableofcontents"
|
||||
};
|
||||
|
||||
const int simpleCommandsSize = sizeof(simpleCommands) / sizeof(*simpleCommands);
|
||||
|
||||
const char *commandWords[] = {
|
||||
"a", "b", "c", "e", "em", "p", "def", "enum", "package", "relates",
|
||||
"namespace", "relatesalso", "anchor", "dontinclude", "include",
|
||||
"includelineno", "copydoc", "copybrief", "copydetails", "verbinclude",
|
||||
"htmlinclude", "extends", "implements", "memberof", "related", "relatedalso",
|
||||
"cite"
|
||||
};
|
||||
|
||||
const int commandWordsSize = sizeof(commandWords) / sizeof(*commandWords);
|
||||
|
||||
const char *commandLines[] = {
|
||||
"addindex", "fn", "name", "line", "var", "skipline", "typedef", "skip",
|
||||
"until", "property"
|
||||
};
|
||||
|
||||
const int commandLinesSize = sizeof(commandLines) / sizeof(*commandLines);
|
||||
|
||||
const char *commandParagraph[] = {
|
||||
"partofdescription", "result", "return", "returns", "remarks", "remark",
|
||||
"since", "test", "sa", "see", "pre", "post", "details", "invariant",
|
||||
"deprecated", "date", "note", "warning", "version", "todo", "bug",
|
||||
"attention", "brief", "author", "authors", "copyright", "short"
|
||||
};
|
||||
|
||||
const int commandParagraphSize = sizeof(commandParagraph) / sizeof(*commandParagraph);
|
||||
|
||||
const char *commandEndCommands[] = {
|
||||
CMD_HTML_ONLY, "latexonly", "manonly", "xmlonly", "link", "rtfonly"
|
||||
};
|
||||
|
||||
const int commandEndCommandsSize = sizeof(commandEndCommands) / sizeof(*commandEndCommands);
|
||||
|
||||
const char *commandWordParagraphs[] = {
|
||||
"param", "tparam", "throw", "throws", "retval", "exception", "example"
|
||||
};
|
||||
|
||||
const int commandWordParagraphsSize = sizeof(commandWordParagraphs) / sizeof(*commandWordParagraphs);
|
||||
|
||||
const char *commandWordLines[] = {
|
||||
"page", "subsection", "subsubsection", "section", "paragraph", "defgroup",
|
||||
"snippet", "mainpage"
|
||||
};
|
||||
|
||||
const int commandWordLinesSize = sizeof(commandWordLines) / sizeof(*commandWordLines);
|
||||
|
||||
const char *commandWordOWordOWords[] = {
|
||||
"category", "class", "protocol", "interface", "struct", "union"
|
||||
};
|
||||
|
||||
const int commandWordOWordOWordsSize = sizeof(commandWordOWordOWords) / sizeof(*commandWordOWordOWords);
|
||||
|
||||
const char *commandOWords[] = {
|
||||
"dir", "file", "cond"
|
||||
};
|
||||
|
||||
const int commandOWordsSize = sizeof(commandOWords) / sizeof(*commandOWords);
|
||||
|
||||
const char *commandErrorThrowings[] = {
|
||||
"annotatedclassstd::list", "classhierarchy", "define", "functionindex", "header",
|
||||
"headerfilestd::list", "inherit", "l", "postheader", "endcode", "enddot", "endmsc", "endhtmlonly",
|
||||
"endlatexonly", "endmanonly", "endlink", "endverbatim", "endxmlonly", "f]", "f}", "endif", "else",
|
||||
"endrtfonly"
|
||||
};
|
||||
|
||||
const int commandErrorThrowingsSize = sizeof(commandErrorThrowings) / sizeof(*commandErrorThrowings);
|
||||
|
||||
const char *commandUniques[] = {
|
||||
"xrefitem", "arg", "ingroup", "par", "headerfile", "overload", "weakgroup", "ref", "subpage", "dotfile", "image", "addtogroup", "li",
|
||||
"if", "ifnot", "elseif", "else", "mscfile", "code", CMD_VERBATIM, "f{", "f[", "f$", "dot", "msc"
|
||||
};
|
||||
|
||||
const int commandUniquesSize = sizeof(commandUniques) / sizeof(*commandUniques);
|
||||
|
||||
// These HTML commands are transformed when producing output in other formats.
|
||||
// Other commands are left intact, but '<' and '> are replaced with entities in HTML
|
||||
// output. So <varName> appears as <varName> in HTML output. The same
|
||||
// behavior must be repeated by SWIG. See Doxygen doc for the list of commands.
|
||||
// '<' is prepended to distinguish HTML tags from Doxygen commands.
|
||||
const char *commandHtml[] = {
|
||||
"<a", "<b", "<blockquote", "<body", "<br", "<center", "<caption", "<code", "<dd", "<dfn",
|
||||
"<div", "<dl", "<dt", "<em", "<form", "<hr", "<h1", "<h2", "<h3", "<i", "<input", "<img",
|
||||
"<li", "<meta", "<multicol", "<ol", "<p", "<pre", "<small", "<span", "<strong",
|
||||
"<sub", "<sup", "<table", "<td", "<th", "<tr", "<tt", "<kbd", "<ul", "<var"
|
||||
};
|
||||
|
||||
const int commandHtmlSize = sizeof(commandHtml) / sizeof(*commandHtml);
|
||||
|
||||
// Only entities which are translatable to plain text are used here. Others
|
||||
// are copied unchanged to output.
|
||||
const char *commandHtmlEntities[] = {
|
||||
"©", // (C)
|
||||
"&trade", // (TM)
|
||||
"®", // (R)
|
||||
"<", // less-than symbol
|
||||
">", // greater-than symbol
|
||||
"&", // ampersand
|
||||
"&apos", // single quotation mark (straight)
|
||||
""", // double quotation mark (straight)
|
||||
"&lsquo", // left single quotation mark
|
||||
"&rsquo", // right single quotation mark
|
||||
"&ldquo", // left double quotation mark
|
||||
"&rdquo", // right double quotation mark
|
||||
"&ndash", // n-dash (for numeric ranges, e.g. 2–8)
|
||||
"&mdash", // --
|
||||
" ", //
|
||||
"×", // x
|
||||
"&minus", // -
|
||||
"&sdot", // .
|
||||
"&sim", // ~
|
||||
"&le", // <=
|
||||
"&ge", // >=
|
||||
"&larr", // <--
|
||||
"&rarr" // -->
|
||||
};
|
||||
|
||||
const int commandHtmlEntitiesSize = sizeof(commandHtmlEntities) / sizeof(*commandHtmlEntities);
|
||||
|
||||
#endif
|
||||
69
Source/Doxygen/doxyentity.cxx
Normal file
69
Source/Doxygen/doxyentity.cxx
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/* -----------------------------------------------------------------------------
|
||||
* 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.
|
||||
*
|
||||
* doxyentity.cxx
|
||||
*
|
||||
* Part of the Doxygen comment translation module of SWIG.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
#include "doxyentity.h"
|
||||
#include <iostream>
|
||||
|
||||
using std::cout;
|
||||
|
||||
DoxygenEntity::DoxygenEntity(const std::string &typeEnt):typeOfEntity(typeEnt), isLeaf(true) {
|
||||
}
|
||||
|
||||
|
||||
/* Basic node for commands that have
|
||||
* only 1 item after them
|
||||
* example: \b word
|
||||
* OR holding a std::string
|
||||
*/
|
||||
DoxygenEntity::DoxygenEntity(const std::string &typeEnt, const std::string ¶m1) : typeOfEntity(typeEnt), data(param1), isLeaf(true) {
|
||||
}
|
||||
|
||||
|
||||
/* Nonterminal node
|
||||
* contains
|
||||
*/
|
||||
DoxygenEntity::DoxygenEntity(const std::string &typeEnt, const DoxygenEntityList &entList) : typeOfEntity(typeEnt), isLeaf(false), entityList(entList) {
|
||||
}
|
||||
|
||||
|
||||
void DoxygenEntity::printEntity(int level) const {
|
||||
|
||||
int thisLevel = level;
|
||||
|
||||
if (isLeaf) {
|
||||
for (int i = 0; i < thisLevel; i++) {
|
||||
cout << "\t";
|
||||
}
|
||||
|
||||
cout << "Node Leaf Command: '" << typeOfEntity << "', ";
|
||||
|
||||
if (!data.empty()) {
|
||||
cout << "Node Data: '" << data << "'";
|
||||
}
|
||||
cout << std::endl;
|
||||
|
||||
} else {
|
||||
|
||||
for (int i = 0; i < thisLevel; i++) {
|
||||
cout << "\t";
|
||||
}
|
||||
|
||||
cout << "Node Command: '" << typeOfEntity << "'" << std::endl;
|
||||
|
||||
thisLevel++;
|
||||
|
||||
for (DoxygenEntityListCIt p = entityList.begin(); p != entityList.end(); p++) {
|
||||
p->printEntity(thisLevel);
|
||||
}
|
||||
}
|
||||
}
|
||||
45
Source/Doxygen/doxyentity.h
Normal file
45
Source/Doxygen/doxyentity.h
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/* -----------------------------------------------------------------------------
|
||||
* 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.
|
||||
*
|
||||
* doxyentity.h
|
||||
*
|
||||
* Part of the Doxygen comment translation module of SWIG.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
#ifndef DOXYGENENTITY_H_
|
||||
#define DOXYGENENTITY_H_
|
||||
|
||||
#include <string>
|
||||
#include <list>
|
||||
|
||||
|
||||
class DoxygenEntity;
|
||||
|
||||
typedef std::list<DoxygenEntity> DoxygenEntityList;
|
||||
typedef DoxygenEntityList::iterator DoxygenEntityListIt;
|
||||
typedef DoxygenEntityList::const_iterator DoxygenEntityListCIt;
|
||||
|
||||
|
||||
/*
|
||||
* Structure to represent a doxygen comment entry
|
||||
*/
|
||||
class DoxygenEntity {
|
||||
public:
|
||||
std::string typeOfEntity;
|
||||
std::string data;
|
||||
bool isLeaf;
|
||||
DoxygenEntityList entityList;
|
||||
|
||||
DoxygenEntity(const std::string &typeEnt);
|
||||
DoxygenEntity(const std::string &typeEnt, const std::string ¶m1);
|
||||
DoxygenEntity(const std::string &typeEnt, const DoxygenEntityList &entList);
|
||||
|
||||
void printEntity(int level) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
1439
Source/Doxygen/doxyparser.cxx
Normal file
1439
Source/Doxygen/doxyparser.cxx
Normal file
File diff suppressed because it is too large
Load diff
372
Source/Doxygen/doxyparser.h
Normal file
372
Source/Doxygen/doxyparser.h
Normal file
|
|
@ -0,0 +1,372 @@
|
|||
/* -----------------------------------------------------------------------------
|
||||
* 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.
|
||||
*
|
||||
* doxyparser.h
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
#ifndef DOXYGENPARSER_H_
|
||||
#define DOXYGENPARSER_H_
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
#include "swig.h"
|
||||
|
||||
#include "doxyentity.h"
|
||||
|
||||
class DoxygenParser {
|
||||
private:
|
||||
|
||||
enum DoxyCommandEnum {
|
||||
NONE = -1,
|
||||
SIMPLECOMMAND,
|
||||
COMMANDWORD,
|
||||
COMMANDLINE,
|
||||
COMMANDPARAGRAPH,
|
||||
COMMANDENDCOMMAND,
|
||||
COMMANDWORDPARAGRAPH,
|
||||
COMMANDWORDLINE,
|
||||
COMMANDWORDOWORDWORD,
|
||||
COMMANDOWORD,
|
||||
COMMANDERRORTHROW,
|
||||
COMMANDUNIQUE,
|
||||
COMMAND_HTML,
|
||||
COMMAND_HTML_ENTITY,
|
||||
COMMAND_ALIAS,
|
||||
COMMAND_IGNORE,
|
||||
END_LINE,
|
||||
PARAGRAPH_END,
|
||||
PLAINSTRING,
|
||||
COMMAND
|
||||
};
|
||||
|
||||
|
||||
/** This class contains parts of Doxygen comment as a token. */
|
||||
class Token {
|
||||
public:
|
||||
DoxyCommandEnum m_tokenType;
|
||||
std::string m_tokenString; /* the data , such as param for @param */
|
||||
|
||||
Token(DoxyCommandEnum tType, std::string tString) : m_tokenType(tType), m_tokenString(tString) {
|
||||
}
|
||||
|
||||
std::string toString() const {
|
||||
switch (m_tokenType) {
|
||||
case END_LINE:
|
||||
return "{END OF LINE}";
|
||||
case PARAGRAPH_END:
|
||||
return "{END OF PARAGRAPH}";
|
||||
case PLAINSTRING:
|
||||
return "{PLAINSTRING :" + m_tokenString + "}";
|
||||
case COMMAND:
|
||||
return "{COMMAND : " + m_tokenString + "}";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
typedef std::vector<Token> TokenList;
|
||||
typedef TokenList::const_iterator TokenListCIt;
|
||||
typedef TokenList::iterator TokenListIt;
|
||||
|
||||
TokenList m_tokenList;
|
||||
TokenListCIt m_tokenListIt;
|
||||
|
||||
typedef std::map<std::string, DoxyCommandEnum> DoxyCommandsMap;
|
||||
typedef DoxyCommandsMap::iterator DoxyCommandsMapIt;
|
||||
|
||||
/*
|
||||
* Map of Doxygen commands to determine if a string is a
|
||||
* command and how it needs to be parsed
|
||||
*/
|
||||
static DoxyCommandsMap doxygenCommands;
|
||||
static std::set<std::string> doxygenSectionIndicators;
|
||||
|
||||
bool m_isVerbatimText; // used to handle \htmlonly and \verbatim commands
|
||||
bool m_isInQuotedString;
|
||||
|
||||
Node *m_node;
|
||||
std::string m_fileName;
|
||||
int m_fileLineNo;
|
||||
|
||||
/*
|
||||
* Return the end command for a command appearing in "ignore" feature or empty
|
||||
* string if this is a simple command and not a block one.
|
||||
*/
|
||||
std::string getIgnoreFeatureEndCommand(const std::string &theCommand) const;
|
||||
|
||||
/*
|
||||
* Helper for getting the value of doxygen:ignore feature or its argument.
|
||||
*/
|
||||
String *getIgnoreFeature(const std::string &theCommand, const char *argument = NULL) const;
|
||||
|
||||
/*
|
||||
* Whether to print lots of debug info during parsing
|
||||
*/
|
||||
bool noisy;
|
||||
|
||||
/*
|
||||
*Changes a std::string to all lower case
|
||||
*/
|
||||
std::string stringToLower(const std::string &stringToConvert);
|
||||
|
||||
/*
|
||||
* isSectionIndicator returns a boolean if the command is a section indicator
|
||||
* This is a helper method for finding the end of a paragraph
|
||||
* by Doxygen's terms
|
||||
*/
|
||||
bool isSectionIndicator(const std::string &smallString);
|
||||
/*
|
||||
* Determines how a command should be handled (what group it belongs to
|
||||
* for parsing rules
|
||||
*/
|
||||
DoxyCommandEnum commandBelongs(const std::string &theCommand);
|
||||
|
||||
/*
|
||||
*prints the parse tree
|
||||
*/
|
||||
void printTree(const std::list<DoxygenEntity> &rootList);
|
||||
|
||||
/**
|
||||
* Returns true if the next token is end of line token. This is important
|
||||
* when single word commands like \c are at the end of line.
|
||||
*/
|
||||
bool isEndOfLine();
|
||||
|
||||
/**
|
||||
* Skips spaces, tabs, and end of line tokens.
|
||||
*/
|
||||
void skipWhitespaceTokens();
|
||||
|
||||
/**
|
||||
* Removes all spaces and tabs from beginning end end of string.
|
||||
*/
|
||||
std::string trim(const std::string &text);
|
||||
|
||||
/*
|
||||
* Returns string of the next token if the next token is PLAINSTRING. Returns
|
||||
* empty string otherwise.
|
||||
*/
|
||||
std::string getNextToken();
|
||||
|
||||
/*
|
||||
* Returns the next word ON THE CURRENT LINE ONLY
|
||||
* if a new line is encountered, returns a blank std::string.
|
||||
* Updates the iterator if successful.
|
||||
*/
|
||||
std::string getNextWord();
|
||||
|
||||
/*
|
||||
* Returns the next word, which is not necessarily on the same line.
|
||||
* Updates the iterator if successful.
|
||||
*/
|
||||
std::string getNextWordInComment();
|
||||
|
||||
/*
|
||||
* Returns the location of the end of the line as
|
||||
* an iterator.
|
||||
*/
|
||||
TokenListCIt getOneLine(const TokenList &tokList);
|
||||
|
||||
/*
|
||||
* Returns a properly formatted std::string
|
||||
* up til ANY command or end of line is encountered.
|
||||
*/
|
||||
std::string getStringTilCommand(const TokenList &tokList);
|
||||
|
||||
/*
|
||||
* Returns a properly formatted std::string
|
||||
* up til the command specified is encountered
|
||||
*/
|
||||
//TODO check that this behaves properly for formulas
|
||||
std::string getStringTilEndCommand(const std::string &theCommand, const TokenList &tokList);
|
||||
|
||||
/*
|
||||
* Returns the end of a Paragraph as an iterator-
|
||||
* Paragraph is defined in Doxygen to be a paragraph of text
|
||||
* separated by either a structural command or a blank line
|
||||
*/
|
||||
TokenListCIt getEndOfParagraph(const TokenList &tokList);
|
||||
|
||||
/*
|
||||
* Returns the end of a section, defined as the first blank line OR first
|
||||
* encounter of the same command. Example of this behaviour is \arg.
|
||||
* If no end is encountered, returns the last token of the std::list.
|
||||
*/
|
||||
TokenListCIt getEndOfSection(const std::string &theCommand, const TokenList &tokList);
|
||||
|
||||
/*
|
||||
* This method is for returning the end of a specific form of doxygen command
|
||||
* that begins with a \command and ends in \endcommand
|
||||
* such as \code and \endcode. The proper usage is
|
||||
* progressTilEndCommand("endcode", tokenList);
|
||||
* If the end is never encountered, it returns the end of the std::list.
|
||||
*/
|
||||
TokenListCIt getEndCommand(const std::string &theCommand, const TokenList &tokList);
|
||||
/*
|
||||
* A special method for commands such as \arg that end at the end of a
|
||||
* paragraph OR when another \arg is encountered
|
||||
//TODO getTilAnyCommand
|
||||
TokenListCIt getTilAnyCommand(const std::string &theCommand, const TokenList &tokList);
|
||||
*/
|
||||
|
||||
/**
|
||||
* This methods skips end of line token, if it is the next token to be
|
||||
* processed. It is called with comment commands which have args till the
|
||||
* end of line, such as 'addtogroup' or 'addindex'.
|
||||
* It is up to translator to specific language to decide whether
|
||||
* to insert eol or not. For example, if a command is ignored in target
|
||||
* language, new lines may make formatting ugly (Python).
|
||||
*/
|
||||
void skipEndOfLine();
|
||||
|
||||
/*
|
||||
* Method for Adding a Simple Command
|
||||
* Format: @command
|
||||
* Plain commands, such as newline etc, they contain no other data
|
||||
* \n \\ \@ \& \$ \# \< \> \%
|
||||
*/
|
||||
void addSimpleCommand(const std::string &theCommand, DoxygenEntityList &doxyList);
|
||||
/*
|
||||
* CommandWord
|
||||
* Format: @command <word>
|
||||
* Commands with a single WORD after then such as @b
|
||||
* "a", "b", "c", "e", "em", "p", "def", "enum", "example", "package",
|
||||
* "relates", "namespace", "relatesalso","anchor", "dontinclude", "include",
|
||||
* "includelineno"
|
||||
*/
|
||||
void addCommandWord(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList);
|
||||
/*
|
||||
* CommandLine
|
||||
* Format: @command (line)
|
||||
* Commands with a single LINE after then such as @var
|
||||
* "addindex", "fn", "name", "line", "var", "skipline", "typedef", "skip",
|
||||
* "until", "property"
|
||||
*/
|
||||
void addCommandLine(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList);
|
||||
/*
|
||||
* CommandParagraph
|
||||
* Format: @command {paragraph}
|
||||
* Commands with a single paragraph after then such as @return
|
||||
* "return", "remarks", "since", "test", "sa", "see", "pre", "post",
|
||||
* "details", "invariant", "deprecated", "date", "note", "warning",
|
||||
* "version", "todo", "bug", "attention", "brief", "arg", "author"
|
||||
*/
|
||||
void addCommandParagraph(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList);
|
||||
/*
|
||||
* Command EndCommand
|
||||
* Format: @command and ends at @endcommand
|
||||
* Commands that take in a block of text such as @code:
|
||||
* "code", "dot", "msc", "f$", "f[", "f{environment}{", "htmlonly",
|
||||
* "latexonly", "manonly", "verbatim", "xmlonly", "cond", "if", "ifnot",
|
||||
* "link"
|
||||
* Returns 1 if success, 0 if the endcommand is never encountered.
|
||||
*/
|
||||
void addCommandEndCommand(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList);
|
||||
/*
|
||||
* CommandWordParagraph
|
||||
* Format: @command <word> {paragraph}
|
||||
* Commands such as param
|
||||
* "param", "tparam", "throw", "throws", "retval", "exception"
|
||||
*/
|
||||
void addCommandWordParagraph(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList);
|
||||
/*
|
||||
* CommandWordLine
|
||||
* Format: @command <word> (line)
|
||||
* Commands such as param
|
||||
* "page", "subsection", "subsubsection", "section", "paragraph", "defgroup"
|
||||
*/
|
||||
void addCommandWordLine(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList);
|
||||
/*
|
||||
* Command Word Optional Word Optional Word
|
||||
* Format: @command <word> [<header-file>] [<header-name>]
|
||||
* Commands such as class
|
||||
* "category", "class", "protocol", "interface", "struct", "union"
|
||||
*/
|
||||
void addCommandWordOWordOWord(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList);
|
||||
/*
|
||||
* Command Optional Word
|
||||
* Format: @command [<word>]
|
||||
* Commands such as dir
|
||||
* "dir", "file", "cond"
|
||||
*/
|
||||
void addCommandOWord(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList);
|
||||
|
||||
/*
|
||||
* Commands that should not be encountered (such as PHP only)
|
||||
* goes til the end of line then returns
|
||||
*/
|
||||
void addCommandErrorThrow(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList);
|
||||
|
||||
void addCommandHtml(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList);
|
||||
|
||||
void addCommandHtmlEntity(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList);
|
||||
|
||||
/*
|
||||
*Adds the unique commands- different process for each unique command
|
||||
*/
|
||||
void addCommandUnique(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList);
|
||||
|
||||
/*
|
||||
* Replace the given command with its predefined alias expansion.
|
||||
*/
|
||||
void aliasCommand(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList);
|
||||
|
||||
/*
|
||||
* Simply ignore the given command, possibly with the word following it or
|
||||
* until the matching end command.
|
||||
*/
|
||||
void ignoreCommand(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList);
|
||||
|
||||
/*
|
||||
* The actual "meat" of the doxygen parser. Calls the correct addCommand...()
|
||||
* function.
|
||||
*/
|
||||
void addCommand(const std::string &commandString, const TokenList &tokList, DoxygenEntityList &doxyList);
|
||||
|
||||
DoxygenEntityList parse(TokenListCIt endParsingIndex, const TokenList &tokList, bool root = false);
|
||||
|
||||
/*
|
||||
* Fill static doxygenCommands and sectionIndicators containers
|
||||
*/
|
||||
void fillTables();
|
||||
|
||||
/** Processes comment when \htmlonly and \verbatim commands are encountered. */
|
||||
size_t processVerbatimText(size_t pos, const std::string &line);
|
||||
|
||||
bool processEscapedChars(size_t &pos, const std::string &line);
|
||||
void processWordCommands(size_t &pos, const std::string &line);
|
||||
void processHtmlTags(size_t &pos, const std::string &line);
|
||||
void processHtmlEntities(size_t &pos, const std::string &line);
|
||||
|
||||
|
||||
/** Processes comment outside \htmlonly and \verbatim commands. */
|
||||
size_t processNormalComment(size_t pos, const std::string &line);
|
||||
|
||||
void tokenizeDoxygenComment(const std::string &doxygenComment, const std::string &fileName, int fileLine);
|
||||
void printList();
|
||||
void printListError(int warningType, const std::string &message);
|
||||
|
||||
typedef std::vector<std::string> StringVector;
|
||||
typedef StringVector::const_iterator StringVectorCIt;
|
||||
|
||||
StringVector split(const std::string &text, char separator);
|
||||
bool isStartOfDoxyCommentChar(char c);
|
||||
bool addDoxyCommand(DoxygenParser::TokenList &tokList, const std::string &cmd);
|
||||
|
||||
public:
|
||||
DoxygenParser(bool noisy = false);
|
||||
virtual ~DoxygenParser();
|
||||
DoxygenEntityList createTree(Node *node, String *documentation);
|
||||
};
|
||||
|
||||
#endif
|
||||
69
Source/Doxygen/doxytranslator.cxx
Normal file
69
Source/Doxygen/doxytranslator.cxx
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/* -----------------------------------------------------------------------------
|
||||
* 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.
|
||||
*
|
||||
* doxytranslator.cxx
|
||||
*
|
||||
* Module to return documentation for nodes formatted for various documentation
|
||||
* systems.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
#include "doxytranslator.h"
|
||||
|
||||
DoxygenTranslator::DoxygenTranslator(int flags) : m_flags(flags), parser((flags &debug_parser) != 0) {
|
||||
}
|
||||
|
||||
|
||||
DoxygenTranslator::~DoxygenTranslator() {
|
||||
}
|
||||
|
||||
|
||||
bool DoxygenTranslator::hasDocumentation(Node *node) {
|
||||
return getDoxygenComment(node) != NULL;
|
||||
}
|
||||
|
||||
|
||||
String *DoxygenTranslator::getDoxygenComment(Node *node) {
|
||||
return Getattr(node, "doxygen");
|
||||
}
|
||||
|
||||
/**
|
||||
* Indent all lines in the comment by given indentation string
|
||||
*/
|
||||
void DoxygenTranslator::extraIndentation(String *comment, const_String_or_char_ptr indentationString) {
|
||||
if (indentationString || Len(indentationString) > 0) {
|
||||
int len = Len(comment);
|
||||
bool trailing_newline = len > 0 && *(Char(comment) + len - 1) == '\n';
|
||||
Insert(comment, 0, indentationString);
|
||||
String *replace = NewStringf("\n%s", indentationString);
|
||||
Replaceall(comment, "\n", replace);
|
||||
if (trailing_newline) {
|
||||
len = Len(comment);
|
||||
Delslice(comment, len - 2, len); // Remove added trailing spaces on last line
|
||||
}
|
||||
Delete(replace);
|
||||
}
|
||||
}
|
||||
|
||||
String *DoxygenTranslator::getDocumentation(Node *node, const_String_or_char_ptr indentationString) {
|
||||
|
||||
if (!hasDocumentation(node)) {
|
||||
return NewString("");
|
||||
}
|
||||
|
||||
String *documentation = makeDocumentation(node);
|
||||
extraIndentation(documentation, indentationString);
|
||||
return documentation;
|
||||
}
|
||||
|
||||
|
||||
void DoxygenTranslator::printTree(const DoxygenEntityList &entityList) {
|
||||
|
||||
for (DoxygenEntityListCIt p = entityList.begin(); p != entityList.end(); p++) {
|
||||
p->printEntity(0);
|
||||
}
|
||||
}
|
||||
90
Source/Doxygen/doxytranslator.h
Normal file
90
Source/Doxygen/doxytranslator.h
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
/* -----------------------------------------------------------------------------
|
||||
* 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.
|
||||
*
|
||||
* doxytranslator.h
|
||||
*
|
||||
* Module to return documentation for nodes formatted for various documentation
|
||||
* systems.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
#ifndef DOXYGENTRANSLATOR_H_
|
||||
#define DOXYGENTRANSLATOR_H_
|
||||
|
||||
#include "swig.h"
|
||||
#include "doxyentity.h"
|
||||
#include "doxyparser.h"
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
|
||||
/*
|
||||
* This is a base class for translator classes. It defines the basic interface
|
||||
* for translators, which convert Doxygen comments into alternative formats for
|
||||
* target languages.
|
||||
*/
|
||||
class DoxygenTranslator {
|
||||
public:
|
||||
/*
|
||||
* Bit flags for the translator ctor.
|
||||
*
|
||||
* Derived classes may define additional flags.
|
||||
*/
|
||||
enum {
|
||||
// Use DoxygenParser in "noisy" mode.
|
||||
debug_parser = 1,
|
||||
|
||||
// Output results of translating Doxygen comments.
|
||||
debug_translator = 2
|
||||
};
|
||||
|
||||
/*
|
||||
* Constructor
|
||||
*/
|
||||
DoxygenTranslator(int flags = 0);
|
||||
|
||||
/*
|
||||
* Virtual destructor.
|
||||
*/
|
||||
virtual ~DoxygenTranslator();
|
||||
|
||||
/*
|
||||
* Return the documentation for a given node formated for the correct
|
||||
* documentation system.
|
||||
*/
|
||||
String *getDocumentation(Node *node, const_String_or_char_ptr indentationString);
|
||||
|
||||
/*
|
||||
* Returns truem is the specified node has comment attached.
|
||||
*/
|
||||
bool hasDocumentation(Node *node);
|
||||
|
||||
/*
|
||||
* Get original comment string in Doxygen-format.
|
||||
*/
|
||||
String *getDoxygenComment(Node *node);
|
||||
|
||||
protected:
|
||||
// The flags passed to the ctor.
|
||||
const int m_flags;
|
||||
|
||||
DoxygenParser parser;
|
||||
|
||||
/*
|
||||
* Returns the documentation formatted for a target language.
|
||||
*/
|
||||
virtual String *makeDocumentation(Node *node) = 0;
|
||||
|
||||
/*
|
||||
* Prints the details of a parsed entity list to stdout (for debugging).
|
||||
*/
|
||||
void printTree(const DoxygenEntityList &entityList);
|
||||
|
||||
void extraIndentation(String *comment, const_String_or_char_ptr indentationString);
|
||||
};
|
||||
|
||||
#endif
|
||||
845
Source/Doxygen/javadoc.cxx
Normal file
845
Source/Doxygen/javadoc.cxx
Normal file
|
|
@ -0,0 +1,845 @@
|
|||
/* -----------------------------------------------------------------------------
|
||||
* 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.
|
||||
*
|
||||
* javadoc.cxx
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
#include "javadoc.h"
|
||||
#include "doxyparser.h"
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include "swigmod.h"
|
||||
#define APPROX_LINE_LENGTH 64 // characters per line allowed
|
||||
#define TAB_SIZE 8 // current tab size in spaces
|
||||
//TODO {@link} {@linkplain} {@docRoot}, and other useful doxy commands that are not a javadoc tag
|
||||
|
||||
// define static tables, they are filled in JavaDocConverter's constructor
|
||||
std::map<std::string, std::pair<JavaDocConverter::tagHandler, std::string> > JavaDocConverter::tagHandlers;
|
||||
|
||||
using std::string;
|
||||
using std::list;
|
||||
using std::vector;
|
||||
|
||||
void JavaDocConverter::fillStaticTables() {
|
||||
if (tagHandlers.size()) // fill only once
|
||||
return;
|
||||
|
||||
/*
|
||||
* Some translation rules:
|
||||
*
|
||||
* @ and \ must be escaped for both Java and Python to appear on output: \@, \\,
|
||||
* while Doxygen produces output in both cases.
|
||||
* Rule: @ and \ with space on the right should get to output.
|
||||
*
|
||||
* :: remains intact, even in class::method(). But you can use class#method also
|
||||
* in C++ comment and it is properly translated to C++ output (changed by doxygen to ::)
|
||||
* and Java output (remains #).
|
||||
* Rule: SWIG type system can't be used to convert C::m to C#m, because in Java it is C.m
|
||||
* Use string replacement :: --> # in tag see and links.
|
||||
*
|
||||
* HTML tags must be translated - remain in Java, to markdown in Python
|
||||
*
|
||||
* Unknown HTML tags, for example <x> is translated to <x> by doxygen, while
|
||||
* Java src is <x> and therefore invisible on output - browser ignores unknown command.
|
||||
* This is handy in syntax descriptions, for example: more <fileName>.
|
||||
*
|
||||
* Standalone < and > need not be translated, they are rendered properly in
|
||||
* all three outputs.
|
||||
*
|
||||
* ., %, and " need not to be translated
|
||||
*
|
||||
* entities must be translated - remain in Java, something meaningful in Python (<, ...)
|
||||
*
|
||||
* - Python
|
||||
* - add comments also to auto-generated methods like equals(), delete() in Java,
|
||||
* and methods for std::vector(), ...
|
||||
* Commenting methods of std types is simple - add comment to std_*.i file.
|
||||
*/
|
||||
|
||||
// these commands insert HTML tags
|
||||
tagHandlers["a"] = make_pair(&JavaDocConverter::handleTagHtml, "i");
|
||||
tagHandlers["arg"] = make_pair(&JavaDocConverter::handleTagHtml, "li");
|
||||
tagHandlers["b"] = make_pair(&JavaDocConverter::handleTagHtml, "b");
|
||||
tagHandlers["c"] = make_pair(&JavaDocConverter::handleTagHtml, "code");
|
||||
tagHandlers["cite"] = make_pair(&JavaDocConverter::handleTagHtml, "i");
|
||||
tagHandlers["e"] = make_pair(&JavaDocConverter::handleTagHtml, "i");
|
||||
tagHandlers["em"] = make_pair(&JavaDocConverter::handleTagHtml, "i");
|
||||
tagHandlers["li"] = make_pair(&JavaDocConverter::handleTagHtml, "li");
|
||||
tagHandlers["p"] = make_pair(&JavaDocConverter::handleTagHtml, "code");
|
||||
// these commands insert just a single char, some of them need to be escaped
|
||||
tagHandlers["$"] = make_pair(&JavaDocConverter::handleTagChar, "");
|
||||
tagHandlers["@"] = make_pair(&JavaDocConverter::handleTagChar, "");
|
||||
tagHandlers["\\"] = make_pair(&JavaDocConverter::handleTagChar, "");
|
||||
tagHandlers["<"] = make_pair(&JavaDocConverter::handleTagChar, "<");
|
||||
tagHandlers[">"] = make_pair(&JavaDocConverter::handleTagChar, ">");
|
||||
tagHandlers["&"] = make_pair(&JavaDocConverter::handleTagChar, "&");
|
||||
tagHandlers["#"] = make_pair(&JavaDocConverter::handleTagChar, "");
|
||||
tagHandlers["%"] = make_pair(&JavaDocConverter::handleTagChar, "");
|
||||
tagHandlers["~"] = make_pair(&JavaDocConverter::handleTagChar, "");
|
||||
tagHandlers["\""] = make_pair(&JavaDocConverter::handleTagChar, """);
|
||||
tagHandlers["."] = make_pair(&JavaDocConverter::handleTagChar, "");
|
||||
tagHandlers["::"] = make_pair(&JavaDocConverter::handleTagChar, "");
|
||||
// these commands are stripped out
|
||||
tagHandlers["attention"] = make_pair(&JavaDocConverter::handleParagraph, "");
|
||||
tagHandlers["anchor"] = make_pair(&JavaDocConverter::handleTagAnchor, "");
|
||||
tagHandlers["brief"] = make_pair(&JavaDocConverter::handleParagraph, "");
|
||||
tagHandlers["bug"] = make_pair(&JavaDocConverter::handleParagraph, "");
|
||||
tagHandlers["date"] = make_pair(&JavaDocConverter::handleParagraph, "");
|
||||
tagHandlers["details"] = make_pair(&JavaDocConverter::handleParagraph, "");
|
||||
// this command is inserts text accumulated after cmd htmlonly -
|
||||
// see DoxygenParser - CMD_HTML_ONLY.
|
||||
tagHandlers["htmlonly"] = make_pair(&JavaDocConverter::handleParagraph, "");
|
||||
tagHandlers["invariant"] = make_pair(&JavaDocConverter::handleParagraph, "");
|
||||
tagHandlers["latexonly"] = make_pair(&JavaDocConverter::handleParagraph, "");
|
||||
tagHandlers["manonly"] = make_pair(&JavaDocConverter::handleParagraph, "");
|
||||
tagHandlers["partofdescription"] = make_pair(&JavaDocConverter::handleParagraph, "");
|
||||
tagHandlers["rtfonly"] = make_pair(&JavaDocConverter::handleParagraph, "");
|
||||
tagHandlers["short"] = make_pair(&JavaDocConverter::handleParagraph, "");
|
||||
tagHandlers["xmlonly"] = make_pair(&JavaDocConverter::handleParagraph, "");
|
||||
// these commands are kept as-is, they are supported by JavaDoc
|
||||
tagHandlers["author"] = make_pair(&JavaDocConverter::handleTagSame, "");
|
||||
tagHandlers["authors"] = make_pair(&JavaDocConverter::handleTagSame, "author");
|
||||
tagHandlers["deprecated"] = make_pair(&JavaDocConverter::handleTagSame, "");
|
||||
tagHandlers["exception"] = make_pair(&JavaDocConverter::handleTagSame, "");
|
||||
tagHandlers["package"] = make_pair(&JavaDocConverter::handleTagSame, "");
|
||||
tagHandlers["param"] = make_pair(&JavaDocConverter::handleTagParam, "");
|
||||
tagHandlers["tparam"] = make_pair(&JavaDocConverter::handleTagParam, "");
|
||||
tagHandlers["ref"] = make_pair(&JavaDocConverter::handleTagRef, "");
|
||||
tagHandlers["result"] = make_pair(&JavaDocConverter::handleTagSame, "return");
|
||||
tagHandlers["return"] = make_pair(&JavaDocConverter::handleTagSame, "");
|
||||
tagHandlers["returns"] = make_pair(&JavaDocConverter::handleTagSame, "return");
|
||||
//tagHandlers["see"] = make_pair(&JavaDocConverter::handleTagSame, "");
|
||||
//tagHandlers["sa"] = make_pair(&JavaDocConverter::handleTagSame, "see");
|
||||
tagHandlers["since"] = make_pair(&JavaDocConverter::handleTagSame, "");
|
||||
tagHandlers["throws"] = make_pair(&JavaDocConverter::handleTagSame, "");
|
||||
tagHandlers["throw"] = make_pair(&JavaDocConverter::handleTagSame, "throws");
|
||||
tagHandlers["version"] = make_pair(&JavaDocConverter::handleTagSame, "");
|
||||
// these commands have special handlers
|
||||
tagHandlers["code"] = make_pair(&JavaDocConverter::handleTagExtended, "code");
|
||||
tagHandlers["cond"] = make_pair(&JavaDocConverter::handleTagMessage, "Conditional comment: ");
|
||||
tagHandlers["copyright"] = make_pair(&JavaDocConverter::handleTagMessage, "Copyright: ");
|
||||
tagHandlers["else"] = make_pair(&JavaDocConverter::handleTagIf, "Else: ");
|
||||
tagHandlers["elseif"] = make_pair(&JavaDocConverter::handleTagIf, "Else if: ");
|
||||
tagHandlers["endcond"] = make_pair(&JavaDocConverter::handleTagMessage, "End of conditional comment.");
|
||||
// space in second arg prevents Javadoc to treat '@ example' as command. File name of
|
||||
// example is still informative to user.
|
||||
tagHandlers["example"] = make_pair(&JavaDocConverter::handleTagSame, " example");
|
||||
tagHandlers["if"] = make_pair(&JavaDocConverter::handleTagIf, "If: ");
|
||||
tagHandlers["ifnot"] = make_pair(&JavaDocConverter::handleTagIf, "If not: ");
|
||||
tagHandlers["image"] = make_pair(&JavaDocConverter::handleTagImage, "");
|
||||
tagHandlers["link"] = make_pair(&JavaDocConverter::handleTagLink, "");
|
||||
tagHandlers["see"] = make_pair(&JavaDocConverter::handleTagSee, "");
|
||||
tagHandlers["sa"] = make_pair(&JavaDocConverter::handleTagSee, "");
|
||||
tagHandlers["note"] = make_pair(&JavaDocConverter::handleTagMessage, "Note: ");
|
||||
tagHandlers["overload"] = make_pair(&JavaDocConverter::handleTagMessage,
|
||||
"This is an overloaded member function, provided for"
|
||||
" convenience. It differs from the above function only in what" " argument(s) it accepts.");
|
||||
tagHandlers["par"] = make_pair(&JavaDocConverter::handleTagPar, "");
|
||||
tagHandlers["remark"] = make_pair(&JavaDocConverter::handleTagMessage, "Remarks: ");
|
||||
tagHandlers["remarks"] = make_pair(&JavaDocConverter::handleTagMessage, "Remarks: ");
|
||||
tagHandlers["todo"] = make_pair(&JavaDocConverter::handleTagMessage, "TODO: ");
|
||||
tagHandlers["verbatim"] = make_pair(&JavaDocConverter::handleTagExtended, "literal");
|
||||
|
||||
// \f commands output literal Latex formula, which is still better than nothing.
|
||||
tagHandlers["f$"] = make_pair(&JavaDocConverter::handleTagVerbatim, "");
|
||||
tagHandlers["f["] = make_pair(&JavaDocConverter::handleTagVerbatim, "");
|
||||
tagHandlers["f{"] = make_pair(&JavaDocConverter::handleTagVerbatim, "");
|
||||
|
||||
tagHandlers["warning"] = make_pair(&JavaDocConverter::handleTagMessage, "Warning: ");
|
||||
// this command just prints it's contents
|
||||
// (it is internal command of swig's parser, contains plain text)
|
||||
tagHandlers["plainstd::string"] = make_pair(&JavaDocConverter::handlePlainString, "");
|
||||
tagHandlers["plainstd::endl"] = make_pair(&JavaDocConverter::handleNewLine, "");
|
||||
tagHandlers["n"] = make_pair(&JavaDocConverter::handleNewLine, "");
|
||||
|
||||
// HTML tags
|
||||
tagHandlers["<a"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<a");
|
||||
tagHandlers["<b"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<b");
|
||||
tagHandlers["<blockquote"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<blockquote");
|
||||
tagHandlers["<body"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<body");
|
||||
tagHandlers["<br"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<br");
|
||||
tagHandlers["<center"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<center");
|
||||
tagHandlers["<caption"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<caption");
|
||||
tagHandlers["<code"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<code");
|
||||
tagHandlers["<dd"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<dd");
|
||||
tagHandlers["<dfn"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<dfn");
|
||||
tagHandlers["<div"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<div");
|
||||
tagHandlers["<dl"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<dl");
|
||||
tagHandlers["<dt"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<dt");
|
||||
tagHandlers["<em"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<em");
|
||||
tagHandlers["<form"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<form");
|
||||
tagHandlers["<hr"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<hr");
|
||||
tagHandlers["<h1"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<h1");
|
||||
tagHandlers["<h2"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<h2");
|
||||
tagHandlers["<h3"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<h3");
|
||||
tagHandlers["<i"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<i");
|
||||
tagHandlers["<input"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<input");
|
||||
tagHandlers["<img"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<img");
|
||||
tagHandlers["<li"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<li");
|
||||
tagHandlers["<meta"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<meta");
|
||||
tagHandlers["<multicol"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<multicol");
|
||||
tagHandlers["<ol"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<ol");
|
||||
tagHandlers["<p"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<p");
|
||||
tagHandlers["<pre"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<pre");
|
||||
tagHandlers["<small"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<small");
|
||||
tagHandlers["<span"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<span");
|
||||
tagHandlers["<strong"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<strong");
|
||||
tagHandlers["<sub"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<sub");
|
||||
tagHandlers["<sup"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<sup");
|
||||
tagHandlers["<table"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<table");
|
||||
tagHandlers["<td"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<td");
|
||||
tagHandlers["<th"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<th");
|
||||
tagHandlers["<tr"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<tr");
|
||||
tagHandlers["<tt"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<tt");
|
||||
tagHandlers["<kbd"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<kbd");
|
||||
tagHandlers["<ul"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<ul");
|
||||
tagHandlers["<var"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<var");
|
||||
|
||||
// HTML entities
|
||||
tagHandlers["©"] = make_pair(&JavaDocConverter::handleHtmlEntity, "©");
|
||||
tagHandlers["&trade"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&trade");
|
||||
tagHandlers["®"] = make_pair(&JavaDocConverter::handleHtmlEntity, "®");
|
||||
tagHandlers["<"] = make_pair(&JavaDocConverter::handleHtmlEntity, "<");
|
||||
tagHandlers[">"] = make_pair(&JavaDocConverter::handleHtmlEntity, ">");
|
||||
tagHandlers["&"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&");
|
||||
tagHandlers["&apos"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&apos");
|
||||
tagHandlers["""] = make_pair(&JavaDocConverter::handleHtmlEntity, """);
|
||||
tagHandlers["&lsquo"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&lsquo");
|
||||
tagHandlers["&rsquo"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&rsquo");
|
||||
tagHandlers["&ldquo"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&ldquo");
|
||||
tagHandlers["&rdquo"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&rdquo");
|
||||
tagHandlers["&ndash"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&ndash");
|
||||
tagHandlers["&mdash"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&mdash");
|
||||
tagHandlers[" "] = make_pair(&JavaDocConverter::handleHtmlEntity, " ");
|
||||
tagHandlers["×"] = make_pair(&JavaDocConverter::handleHtmlEntity, "×");
|
||||
tagHandlers["&minus"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&minus");
|
||||
tagHandlers["&sdot"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&sdot");
|
||||
tagHandlers["&sim"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&sim");
|
||||
tagHandlers["&le"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&le");
|
||||
tagHandlers["&ge"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&ge");
|
||||
tagHandlers["&larr"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&larr");
|
||||
tagHandlers["&rarr"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&rarr");
|
||||
}
|
||||
|
||||
JavaDocConverter::JavaDocConverter(int flags) :
|
||||
DoxygenTranslator(flags) {
|
||||
fillStaticTables();
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats comment lines by inserting '\n *' at to long lines and tabs for
|
||||
* indent. Currently it is disabled, which means original comment format is
|
||||
* preserved. Experience shows, that this is usually better than breaking
|
||||
* lines automatically, especially because original line endings are not removed,
|
||||
* which results in short lines. To be useful, this function should have much
|
||||
* better algorithm.
|
||||
*/
|
||||
std::string JavaDocConverter::formatCommand(std::string unformattedLine, int indent) {
|
||||
std::string formattedLines;
|
||||
return unformattedLine; // currently disabled
|
||||
std::string::size_type lastPosition = 0;
|
||||
std::string::size_type i = 0;
|
||||
int isFirstLine = 1;
|
||||
while (i != std::string::npos && i < unformattedLine.length()) {
|
||||
lastPosition = i;
|
||||
if (isFirstLine) {
|
||||
i += APPROX_LINE_LENGTH;
|
||||
} else {
|
||||
i += APPROX_LINE_LENGTH - indent * TAB_SIZE;
|
||||
}
|
||||
|
||||
i = unformattedLine.find(" ", i);
|
||||
|
||||
if (i > 0 && i + 1 < unformattedLine.length()) {
|
||||
if (!isFirstLine)
|
||||
for (int j = 0; j < indent; j++) {
|
||||
formattedLines.append("\t");
|
||||
} else {
|
||||
isFirstLine = 0;
|
||||
}
|
||||
formattedLines.append(unformattedLine.substr(lastPosition, i - lastPosition + 1));
|
||||
formattedLines.append("\n *");
|
||||
|
||||
}
|
||||
}
|
||||
if (lastPosition < unformattedLine.length()) {
|
||||
if (!isFirstLine) {
|
||||
for (int j = 0; j < indent; j++) {
|
||||
formattedLines.append("\t");
|
||||
}
|
||||
}
|
||||
formattedLines.append(unformattedLine.substr(lastPosition, unformattedLine.length() - lastPosition));
|
||||
}
|
||||
|
||||
return formattedLines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true, if the given parameter exists in the current node
|
||||
* (for example param is a name of function parameter). If feature
|
||||
* 'doxygen:nostripparams' is set, then this method always returns
|
||||
* true - parameters are copied to output regardless of presence in
|
||||
* function params list.
|
||||
*/
|
||||
bool JavaDocConverter::paramExists(std::string param) {
|
||||
|
||||
if (GetFlag(currentNode, "feature:doxygen:nostripparams")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
ParmList *plist = CopyParmList(Getattr(currentNode, "parms"));
|
||||
|
||||
for (Parm *p = plist; p;) {
|
||||
|
||||
if (Getattr(p, "name") && Char(Getattr(p, "name")) == param) {
|
||||
return true;
|
||||
}
|
||||
/* doesn't seem to work always: in some cases (especially for 'self' parameters)
|
||||
* tmap:in is present, but tmap:in:next is not and so this code skips all the parameters
|
||||
*/
|
||||
//p = Getattr(p, "tmap:in") ? Getattr(p, "tmap:in:next") : nextSibling(p);
|
||||
p = nextSibling(p);
|
||||
}
|
||||
|
||||
Delete(plist);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string JavaDocConverter::translateSubtree(DoxygenEntity &doxygenEntity) {
|
||||
std::string translatedComment;
|
||||
|
||||
if (doxygenEntity.isLeaf) {
|
||||
return translatedComment;
|
||||
}
|
||||
|
||||
for (DoxygenEntityListIt p = doxygenEntity.entityList.begin(); p != doxygenEntity.entityList.end(); p++) {
|
||||
|
||||
translateEntity(*p, translatedComment);
|
||||
translateSubtree(*p);
|
||||
}
|
||||
|
||||
return translatedComment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a handler for the given tag exists, and calls it.
|
||||
*/
|
||||
void JavaDocConverter::translateEntity(DoxygenEntity &tag, std::string &translatedComment) {
|
||||
|
||||
std::map<std::string, std::pair<tagHandler, std::string> >::iterator it;
|
||||
it = tagHandlers.find(tag.typeOfEntity);
|
||||
|
||||
if (it != tagHandlers.end()) {
|
||||
(this->*(it->second.first))(tag, translatedComment, it->second.second);
|
||||
} else {
|
||||
// do NOT print warning, since there are many tags, which are not
|
||||
// translatable - many warnings hide important ones
|
||||
// addError(WARN_DOXYGEN_COMMAND_ERROR, "Unknown doxygen or HTML tag: " + tag.typeOfEntity);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void JavaDocConverter::handleTagAnchor(DoxygenEntity &tag, std::string &translatedComment, std::string &) {
|
||||
translatedComment += "<a id=\"" + translateSubtree(tag) + "\"></a>";
|
||||
}
|
||||
|
||||
|
||||
void JavaDocConverter::handleTagHtml(DoxygenEntity &tag, std::string &translatedComment, std::string &arg) {
|
||||
if (tag.entityList.size()) { // do not include empty tags
|
||||
std::string tagData = translateSubtree(tag);
|
||||
// wrap the thing, ignoring whitespace
|
||||
size_t wsPos = tagData.find_last_not_of("\n\t ");
|
||||
if (wsPos != std::string::npos)
|
||||
translatedComment += "<" + arg + ">" + tagData.substr(0, wsPos + 1) + "</" + arg + ">" + tagData.substr(wsPos + 1);
|
||||
else
|
||||
translatedComment += "<" + arg + ">" + translateSubtree(tag) + "</" + arg + "> ";
|
||||
}
|
||||
}
|
||||
|
||||
void JavaDocConverter::handleDoxyHtmlTag(DoxygenEntity &tag, std::string &translatedComment, std::string &arg) {
|
||||
std::string htmlTagArgs = tag.data;
|
||||
if (htmlTagArgs == "/") {
|
||||
// end html tag, for example "</ul>
|
||||
translatedComment += "</" + arg.substr(1) + ">";
|
||||
} else {
|
||||
translatedComment += arg + htmlTagArgs + ">";
|
||||
}
|
||||
}
|
||||
|
||||
void JavaDocConverter::handleHtmlEntity(DoxygenEntity &, std::string &translatedComment, std::string &arg) {
|
||||
// html entities can be preserved for Java
|
||||
translatedComment += arg + ';';
|
||||
}
|
||||
|
||||
void JavaDocConverter::handleNewLine(DoxygenEntity &, std::string &translatedComment, std::string &) {
|
||||
// <br> tag is added, because otherwise to much text is joined
|
||||
// into same paragraph by javadoc. For example, doxy list:
|
||||
// - item one
|
||||
// - item two
|
||||
// becomes one paragraph with surrounding text without newlines.
|
||||
// This way we get to many empty lines in javadoc output, but this
|
||||
// is still better than joined lines. Possibility for improvements
|
||||
// exists.
|
||||
translatedComment += "<br>\n * ";
|
||||
}
|
||||
|
||||
void JavaDocConverter::handleTagChar(DoxygenEntity &tag, std::string &translatedComment, std::string &arg) {
|
||||
// escape it if we need to, else just print
|
||||
if (arg.size())
|
||||
translatedComment += arg;
|
||||
else
|
||||
translatedComment += tag.typeOfEntity;
|
||||
}
|
||||
|
||||
// handles tags which are the same in Doxygen and Javadoc.
|
||||
void JavaDocConverter::handleTagSame(DoxygenEntity &tag, std::string &translatedComment, std::string &arg) {
|
||||
if (arg.size())
|
||||
tag.typeOfEntity = arg;
|
||||
translatedComment += formatCommand(std::string("@" + tag.typeOfEntity + " " + translateSubtree(tag)), 2);
|
||||
}
|
||||
|
||||
void JavaDocConverter::handleParagraph(DoxygenEntity &tag, std::string &translatedComment, std::string &) {
|
||||
translatedComment += formatCommand(translateSubtree(tag), 0);
|
||||
}
|
||||
|
||||
void JavaDocConverter::handlePlainString(DoxygenEntity &tag, std::string &translatedComment, std::string &) {
|
||||
translatedComment += tag.data;
|
||||
// if (tag.data.size() && tag.data[tag.data.size()-1] != ' ')
|
||||
// translatedComment += " ";
|
||||
}
|
||||
|
||||
void JavaDocConverter::handleTagVerbatim(DoxygenEntity &tag, std::string &translatedComment, std::string &arg) {
|
||||
translatedComment += arg + " ";
|
||||
for (DoxygenEntityListCIt it = tag.entityList.begin(); it != tag.entityList.end(); it++) {
|
||||
translatedComment += it->data;
|
||||
}
|
||||
}
|
||||
|
||||
void JavaDocConverter::handleTagExtended(DoxygenEntity &tag, std::string &translatedComment, std::string &arg) {
|
||||
std::string dummy;
|
||||
translatedComment += "{@" + arg + " ";
|
||||
handleParagraph(tag, translatedComment, dummy);
|
||||
translatedComment += "}";
|
||||
}
|
||||
|
||||
void JavaDocConverter::handleTagIf(DoxygenEntity &tag, std::string &translatedComment, std::string &arg) {
|
||||
std::string dummy;
|
||||
translatedComment += arg;
|
||||
if (tag.entityList.size()) {
|
||||
translatedComment += tag.entityList.begin()->data;
|
||||
tag.entityList.pop_front();
|
||||
translatedComment += " {" + translateSubtree(tag) + "}";
|
||||
}
|
||||
}
|
||||
|
||||
void JavaDocConverter::handleTagMessage(DoxygenEntity &tag, std::string &translatedComment, std::string &arg) {
|
||||
std::string dummy;
|
||||
translatedComment += formatCommand(arg, 0);
|
||||
handleParagraph(tag, translatedComment, dummy);
|
||||
}
|
||||
|
||||
void JavaDocConverter::handleTagImage(DoxygenEntity &tag, std::string &translatedComment, std::string &) {
|
||||
if (tag.entityList.size() < 2)
|
||||
return;
|
||||
|
||||
std::string file;
|
||||
std::string title;
|
||||
|
||||
std::list<DoxygenEntity>::iterator it = tag.entityList.begin();
|
||||
if (it->data != "html")
|
||||
return;
|
||||
|
||||
it++;
|
||||
file = it->data;
|
||||
|
||||
it++;
|
||||
if (it != tag.entityList.end())
|
||||
title = it->data;
|
||||
|
||||
translatedComment += "<img src=" + file;
|
||||
if (title.size())
|
||||
translatedComment += " alt=" + title;
|
||||
|
||||
// the size indication is supported for Latex only in Doxygen, see manual
|
||||
|
||||
translatedComment += "/>";
|
||||
}
|
||||
|
||||
void JavaDocConverter::handleTagPar(DoxygenEntity &tag, std::string &translatedComment, std::string &) {
|
||||
std::string dummy;
|
||||
translatedComment += "<p";
|
||||
if (tag.entityList.size()) {
|
||||
translatedComment += " alt=\"" + tag.entityList.begin()->data + "\"";
|
||||
translatedComment += ">";
|
||||
tag.entityList.pop_front();
|
||||
handleParagraph(tag, translatedComment, dummy);
|
||||
}
|
||||
translatedComment += "</p>";
|
||||
}
|
||||
|
||||
|
||||
void JavaDocConverter::handleTagParam(DoxygenEntity &tag, std::string &translatedComment, std::string &) {
|
||||
std::string dummy;
|
||||
|
||||
if (!tag.entityList.size())
|
||||
return;
|
||||
if (!paramExists(tag.entityList.begin()->data))
|
||||
return;
|
||||
|
||||
translatedComment += "@param ";
|
||||
translatedComment += tag.entityList.begin()->data;
|
||||
tag.entityList.pop_front();
|
||||
handleParagraph(tag, translatedComment, dummy);
|
||||
}
|
||||
|
||||
|
||||
void JavaDocConverter::handleTagRef(DoxygenEntity &tag, std::string &translatedComment, std::string &) {
|
||||
std::string dummy;
|
||||
if (!tag.entityList.size())
|
||||
return;
|
||||
|
||||
// we translate to link, although \page is not supported in Java, but
|
||||
// reader at least knows what to look at. Also for \anchor tag on the same
|
||||
// page this link works.
|
||||
string anchor = tag.entityList.begin()->data;
|
||||
tag.entityList.pop_front();
|
||||
string anchorText = anchor;
|
||||
if (!tag.entityList.empty()) {
|
||||
anchorText = tag.entityList.begin()->data;
|
||||
}
|
||||
translatedComment += "<a href=\"#" + anchor + "\">" + anchorText + "</a>";
|
||||
}
|
||||
|
||||
|
||||
string JavaDocConverter::convertLink(string linkObject) {
|
||||
if (GetFlag(currentNode, "feature:doxygen:nolinktranslate"))
|
||||
return linkObject;
|
||||
// find the params in function in linkObject (if any)
|
||||
size_t lbracePos = linkObject.find('(', 0);
|
||||
size_t rbracePos = linkObject.find(')', 0);
|
||||
if (lbracePos == string::npos || rbracePos == string::npos || lbracePos >= rbracePos)
|
||||
return "";
|
||||
|
||||
string paramsStr = linkObject.substr(lbracePos + 1,
|
||||
rbracePos - lbracePos - 1);
|
||||
// strip the params, to fill them later
|
||||
string additionalObject = linkObject.substr(rbracePos + 1, string::npos);
|
||||
linkObject = linkObject.substr(0, lbracePos);
|
||||
|
||||
// find all the params
|
||||
vector<string> params;
|
||||
size_t lastPos = 0, commaPos = 0;
|
||||
while (true) {
|
||||
commaPos = paramsStr.find(',', lastPos);
|
||||
if (commaPos == string::npos)
|
||||
commaPos = paramsStr.size();
|
||||
string param = paramsStr.substr(lastPos, commaPos - lastPos);
|
||||
// if any param type is empty, we are failed
|
||||
if (!param.size())
|
||||
return "";
|
||||
params.push_back(param);
|
||||
lastPos = commaPos + 1;
|
||||
if (lastPos >= paramsStr.size())
|
||||
break;
|
||||
}
|
||||
|
||||
linkObject += "(";
|
||||
for (size_t i = 0; i < params.size(); i++) {
|
||||
// translate c/c++ type string to swig's type
|
||||
// i e 'int **arr[100][10]' -> 'a(100).a(10).p.p.int'
|
||||
// also converting arrays to pointers
|
||||
string paramStr = params[i];
|
||||
String *swigType = NewString("");
|
||||
|
||||
// handle const qualifier
|
||||
if (paramStr.find("const") != string::npos)
|
||||
SwigType_add_qualifier(swigType, "const");
|
||||
|
||||
// handle pointers, references and arrays
|
||||
for (int j = (int)params[i].size() - 1; j >= 0; j--) {
|
||||
// skip all the [...] blocks, write 'p.' for every of it
|
||||
if (paramStr[j] == ']') {
|
||||
while (j >= 0 && paramStr[j] != '[')
|
||||
j--;
|
||||
// no closing brace
|
||||
if (j < 0)
|
||||
return "";
|
||||
SwigType_add_pointer(swigType);
|
||||
continue;
|
||||
} else if (paramStr[j] == '*')
|
||||
SwigType_add_pointer(swigType);
|
||||
else if (paramStr[j] == '&')
|
||||
SwigType_add_reference(swigType);
|
||||
else if (isalnum(paramStr[j])) {
|
||||
size_t typeNameStart = paramStr.find_last_of(' ', j + 1);
|
||||
if (typeNameStart == string::npos)
|
||||
typeNameStart = 0;
|
||||
else
|
||||
typeNameStart++;
|
||||
Append(swigType, paramStr.substr(typeNameStart, j - typeNameStart + 1).c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// make dummy param list, to lookup typemaps for it
|
||||
Parm *dummyParam = NewParm(swigType, "", 0);
|
||||
Swig_typemap_attach_parms("jstype", dummyParam, NULL);
|
||||
Language::instance()->replaceSpecialVariables(0, Getattr(dummyParam, "tmap:jstype"), dummyParam);
|
||||
|
||||
//Swig_print(dummyParam, 1);
|
||||
linkObject += Char(Getattr(dummyParam, "tmap:jstype"));
|
||||
if (i != params.size() - 1)
|
||||
linkObject += ",";
|
||||
|
||||
Delete(dummyParam);
|
||||
Delete(swigType);
|
||||
}
|
||||
linkObject += ")";
|
||||
|
||||
return linkObject + additionalObject;
|
||||
}
|
||||
|
||||
void JavaDocConverter::handleTagLink(DoxygenEntity &tag, std::string &translatedComment, std::string &) {
|
||||
std::string dummy;
|
||||
if (!tag.entityList.size())
|
||||
return;
|
||||
|
||||
string linkObject = convertLink(tag.entityList.begin()->data);
|
||||
if (!linkObject.size())
|
||||
linkObject = tag.entityList.begin()->data;
|
||||
tag.entityList.pop_front();
|
||||
|
||||
translatedComment += "{@link ";
|
||||
translatedComment += linkObject + " ";
|
||||
handleParagraph(tag, translatedComment, dummy);
|
||||
translatedComment += "}";
|
||||
}
|
||||
|
||||
void JavaDocConverter::handleTagSee(DoxygenEntity &tag, std::string &translatedComment, std::string &) {
|
||||
std::string dummy;
|
||||
if (!tag.entityList.size())
|
||||
return;
|
||||
|
||||
// tag.entity list contains contents of the @see paragraph. It should contain
|
||||
// one link (references) to method with or without parameters. Doxygen supports
|
||||
// arbitrary text and types mixed, but this feature is not supported here.
|
||||
// :: or # may be used as a separator between class name and method name.
|
||||
list<DoxygenEntity>::iterator it;
|
||||
string methodRef;
|
||||
for (it = tag.entityList.begin(); it != tag.entityList.end(); it++) {
|
||||
if (it->typeOfEntity == "plainstd::endl") {
|
||||
// handleNewLine(*it, translatedComment, dummy);
|
||||
continue;
|
||||
}
|
||||
// restore entities which may be used in C++ type declaration
|
||||
if (it->typeOfEntity == "&") {
|
||||
methodRef += '&';
|
||||
} else if (it->typeOfEntity == "<") {
|
||||
methodRef += '<';
|
||||
} else if (it->typeOfEntity == ">") {
|
||||
methodRef += '>';
|
||||
} else {
|
||||
methodRef += it->data;
|
||||
}
|
||||
}
|
||||
|
||||
// replace :: with #, but only if it appears before left brace
|
||||
size_t lbrace = methodRef.find('(');
|
||||
size_t dblColon = methodRef.find("::");
|
||||
if (dblColon < lbrace) {
|
||||
methodRef = methodRef.substr(0, dblColon) + '#' + methodRef.substr(dblColon + 2);
|
||||
}
|
||||
|
||||
translatedComment += "@see ";
|
||||
string linkObject = convertLink(methodRef);
|
||||
if (!linkObject.size()) {
|
||||
linkObject = methodRef;
|
||||
}
|
||||
translatedComment += linkObject;
|
||||
}
|
||||
|
||||
/* This function moves all line endings at the end of child entities
|
||||
* out of the child entities to the parent.
|
||||
* For example, entity tree:
|
||||
|
||||
-root
|
||||
|-param
|
||||
|-paramText
|
||||
|-endline
|
||||
|
||||
should be turned to
|
||||
|
||||
-root
|
||||
|-param
|
||||
|-paramText
|
||||
|-endline
|
||||
*
|
||||
*/
|
||||
int JavaDocConverter::shiftEndlinesUpTree(DoxygenEntity &root, int level) {
|
||||
DoxygenEntityListIt it = root.entityList.begin();
|
||||
while (it != root.entityList.end()) {
|
||||
// remove line endings
|
||||
int ret = shiftEndlinesUpTree(*it, level + 1);
|
||||
// insert them after this element
|
||||
it++;
|
||||
for (int i = 0; i < ret; i++) {
|
||||
root.entityList.insert(it, DoxygenEntity("plainstd::endl"));
|
||||
}
|
||||
}
|
||||
|
||||
// continue only if we are not root
|
||||
if (!level) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int removedCount = 0;
|
||||
while (!root.entityList.empty()
|
||||
&& root.entityList.rbegin()->typeOfEntity == "plainstd::endl") {
|
||||
root.entityList.pop_back();
|
||||
removedCount++;
|
||||
}
|
||||
return removedCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* This makes sure that all comment lines contain '*'. It is not mandatory in doxygen,
|
||||
* but highly recommended for Javadoc. '*' in empty lines are indented according
|
||||
* to indentation of the first line. Indentation of non-empty lines is not
|
||||
* changed - garbage in garbage out.
|
||||
*/
|
||||
std::string JavaDocConverter::indentAndInsertAsterisks(const string &doc) {
|
||||
|
||||
size_t idx = doc.find('\n');
|
||||
size_t indent = 0;
|
||||
bool singleLineComment = idx == string::npos;
|
||||
// Detect indentation.
|
||||
// The first line in comment is the one after '/**', which may be
|
||||
// spaces and '\n' or the text. In any case it is not suitable to detect
|
||||
// indentation, so we have to skip the first '\n'.
|
||||
// However, if there is just one line, then use that line to detect indentation.
|
||||
if (idx != string::npos) {
|
||||
size_t nonspaceIdx = doc.find_first_not_of(" \t", idx + 1);
|
||||
if (nonspaceIdx != string::npos) {
|
||||
indent = nonspaceIdx - idx;
|
||||
}
|
||||
}
|
||||
|
||||
if (indent == 0) {
|
||||
// we can't indent the first line less than 0
|
||||
indent = 1;
|
||||
}
|
||||
// Create the first line of Javadoc comment.
|
||||
string indentStr(indent - 1, ' ');
|
||||
string translatedStr = indentStr + "/**";
|
||||
if (indent > 1) {
|
||||
// remove the first space, so that '*' will be aligned
|
||||
translatedStr = translatedStr.substr(1);
|
||||
}
|
||||
|
||||
translatedStr += doc;
|
||||
|
||||
// insert '*' before each comment line, if it does not have it
|
||||
idx = translatedStr.find('\n');
|
||||
|
||||
while (idx != string::npos) {
|
||||
|
||||
size_t nonspaceIdx = translatedStr.find_first_not_of(" \t", idx + 1);
|
||||
if (nonspaceIdx != string::npos && translatedStr[nonspaceIdx] != '*') {
|
||||
// line without '*' found - is it empty?
|
||||
if (translatedStr[nonspaceIdx] != '\n') {
|
||||
// add '* ' to each line without it
|
||||
translatedStr = translatedStr.substr(0, nonspaceIdx) + "* " + translatedStr.substr(nonspaceIdx);
|
||||
//printf(translatedStr.c_str());
|
||||
} else {
|
||||
// we found empty line, replace it with indented '*'
|
||||
translatedStr = translatedStr.substr(0, idx + 1) + indentStr + "* " + translatedStr.substr(nonspaceIdx);
|
||||
}
|
||||
}
|
||||
idx = translatedStr.find('\n', nonspaceIdx);
|
||||
}
|
||||
|
||||
// Add the last comment line properly indented
|
||||
size_t nonspaceEndIdx = translatedStr.find_last_not_of(" \t");
|
||||
if (nonspaceEndIdx != string::npos) {
|
||||
if (translatedStr[nonspaceEndIdx] != '\n') {
|
||||
if (!singleLineComment)
|
||||
translatedStr += '\n';
|
||||
} else {
|
||||
// remove trailing spaces
|
||||
translatedStr = translatedStr.substr(0, nonspaceEndIdx + 1);
|
||||
}
|
||||
}
|
||||
translatedStr += indentStr + "*/\n";
|
||||
|
||||
return translatedStr;
|
||||
}
|
||||
|
||||
String *JavaDocConverter::makeDocumentation(Node *node) {
|
||||
|
||||
String *documentation = getDoxygenComment(node);
|
||||
|
||||
if (documentation == NULL) {
|
||||
return NewString("");
|
||||
}
|
||||
|
||||
if (GetFlag(node, "feature:doxygen:notranslate")) {
|
||||
|
||||
string doc = Char(documentation);
|
||||
|
||||
string translatedStr = indentAndInsertAsterisks(doc);
|
||||
|
||||
return NewString(translatedStr.c_str());
|
||||
}
|
||||
|
||||
DoxygenEntityList entityList = parser.createTree(node, documentation);
|
||||
|
||||
// entityList.sort(CompareDoxygenEntities()); sorting currently not used,
|
||||
|
||||
if (m_flags & debug_translator) {
|
||||
std::cout << "---RESORTED LIST---" << std::endl;
|
||||
printTree(entityList);
|
||||
}
|
||||
// store the current node
|
||||
// (currently just to handle params)
|
||||
currentNode = node;
|
||||
|
||||
std::string javaDocString = "/**\n * ";
|
||||
|
||||
DoxygenEntity root("root", entityList);
|
||||
|
||||
shiftEndlinesUpTree(root);
|
||||
|
||||
// strip line endings at the beginning
|
||||
while (!root.entityList.empty()
|
||||
&& root.entityList.begin()->typeOfEntity == "plainstd::endl") {
|
||||
root.entityList.pop_front();
|
||||
}
|
||||
|
||||
// and at the end
|
||||
while (!root.entityList.empty()
|
||||
&& root.entityList.rbegin()->typeOfEntity == "plainstd::endl") {
|
||||
root.entityList.pop_back();
|
||||
}
|
||||
|
||||
javaDocString += translateSubtree(root);
|
||||
|
||||
javaDocString += "\n */\n";
|
||||
|
||||
if (m_flags & debug_translator) {
|
||||
std::cout << "\n---RESULT IN JAVADOC---" << std::endl;
|
||||
std::cout << javaDocString;
|
||||
}
|
||||
|
||||
return NewString(javaDocString.c_str());
|
||||
}
|
||||
|
||||
void JavaDocConverter::addError(int warningType, const std::string &message) {
|
||||
Swig_warning(warningType, "", 0, "Doxygen parser warning: %s. \n", message.c_str());
|
||||
}
|
||||
169
Source/Doxygen/javadoc.h
Normal file
169
Source/Doxygen/javadoc.h
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
/* -----------------------------------------------------------------------------
|
||||
* 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.
|
||||
*
|
||||
* javadoc.h
|
||||
*
|
||||
* Module to return documentation for nodes formatted for JavaDoc
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
#ifndef JAVADOCCONVERTER_H_
|
||||
#define JAVADOCCONVERTER_H_
|
||||
|
||||
#include "doxytranslator.h"
|
||||
#include <map>
|
||||
|
||||
/*
|
||||
* A class to translate doxygen comments into JavaDoc style comments.
|
||||
*/
|
||||
class JavaDocConverter : public DoxygenTranslator {
|
||||
public:
|
||||
JavaDocConverter(int flags = 0);
|
||||
String *makeDocumentation(Node *node);
|
||||
|
||||
protected:
|
||||
/*
|
||||
* Used to properly format JavaDoc-style command
|
||||
*/
|
||||
std::string formatCommand(std::string unformattedLine, int indent);
|
||||
|
||||
/*
|
||||
* Translate every entity in a tree.
|
||||
*/
|
||||
std::string translateSubtree(DoxygenEntity &doxygenEntity);
|
||||
|
||||
/*
|
||||
* Translate one entity with the appropriate handler, according
|
||||
* to the tagHandlers
|
||||
*/
|
||||
void translateEntity(DoxygenEntity &tag, std::string &translatedComment);
|
||||
|
||||
/*
|
||||
* Fix all endlines location, etc
|
||||
*/
|
||||
int shiftEndlinesUpTree(DoxygenEntity &root, int level = 0);
|
||||
|
||||
/*
|
||||
* Convert params in link-objects and references
|
||||
*/
|
||||
std::string convertLink(std::string linkObject);
|
||||
|
||||
/*
|
||||
* Typedef for the function that handles one tag
|
||||
* arg - some string argument to easily pass it through lookup table
|
||||
*/
|
||||
typedef void (JavaDocConverter::*tagHandler) (DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
|
||||
|
||||
/**
|
||||
* Copies verbatim args of the tag to output, used for commands like \f$, ...
|
||||
*/
|
||||
void handleTagVerbatim(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
|
||||
|
||||
/** Creates anchor link. */
|
||||
void handleTagAnchor(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
|
||||
|
||||
/*
|
||||
* Wrap the command data with the html tag
|
||||
* arg - html tag, with no braces
|
||||
*/
|
||||
void handleTagHtml(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
|
||||
|
||||
/* Handles HTML tags recognized by Doxygen, like <A ...>, <ul>, <table>, ... */
|
||||
void handleDoxyHtmlTag(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
|
||||
|
||||
/* Handles HTML entities recognized by Doxygen, like <, ©, ... */
|
||||
void handleHtmlEntity(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
|
||||
|
||||
/*
|
||||
* Just prints new line
|
||||
*/
|
||||
void handleNewLine(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
|
||||
|
||||
/*
|
||||
* Print the name of tag to the output, used for escape-commands
|
||||
* arg - html-escaped variant, if not provided the command data is used
|
||||
*/
|
||||
void handleTagChar(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
|
||||
|
||||
/*
|
||||
* Do not translate and print as-is
|
||||
* arg - the new tag name, if it needs to be renamed
|
||||
*/
|
||||
void handleTagSame(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
|
||||
|
||||
/*
|
||||
* Print only the content and strip original tag
|
||||
*/
|
||||
void handleParagraph(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
|
||||
|
||||
/*
|
||||
* Print only data part of code
|
||||
*/
|
||||
void handlePlainString(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
|
||||
|
||||
/*
|
||||
* Print extended Javadoc command, like {@code ...} or {@literal ...}
|
||||
* arg - command name
|
||||
*/
|
||||
void handleTagExtended(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
|
||||
|
||||
/*
|
||||
* Print the if-elseif-else-endif section
|
||||
*/
|
||||
void handleTagIf(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
|
||||
|
||||
/*
|
||||
* Prints the specified message, than the contents of the tag
|
||||
* arg - message
|
||||
*/
|
||||
void handleTagMessage(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
|
||||
|
||||
/*
|
||||
* Insert <img src=... /> tag if the 'format' field is specified as 'html'
|
||||
*/
|
||||
void handleTagImage(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
|
||||
|
||||
/*
|
||||
* Insert <p alt='title'>...</p>
|
||||
*/
|
||||
void handleTagPar(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
|
||||
|
||||
/*
|
||||
* Insert \@param command, if it is really a function param
|
||||
*/
|
||||
void handleTagParam(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
|
||||
|
||||
/*
|
||||
* Writes link for \ref tag.
|
||||
*/
|
||||
void handleTagRef(DoxygenEntity &tag, std::string &translatedComment, std::string &);
|
||||
|
||||
/*
|
||||
* Insert {@link...} command, and handle all the <link-object>s correctly
|
||||
* (like converting types of params, etc)
|
||||
*/
|
||||
void handleTagLink(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
|
||||
|
||||
/*
|
||||
* Insert @see command, and handle all the <link-object>s correctly
|
||||
* (like converting types of params, etc)
|
||||
*/
|
||||
void handleTagSee(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
|
||||
|
||||
private:
|
||||
Node *currentNode;
|
||||
// this contains the handler pointer and one string argument
|
||||
static std::map<std::string, std::pair<tagHandler, std::string> > tagHandlers;
|
||||
void fillStaticTables();
|
||||
|
||||
bool paramExists(std::string param);
|
||||
std::string indentAndInsertAsterisks(const std::string &doc);
|
||||
|
||||
void addError(int warningType, const std::string &message);
|
||||
};
|
||||
|
||||
#endif
|
||||
911
Source/Doxygen/pydoc.cxx
Normal file
911
Source/Doxygen/pydoc.cxx
Normal file
|
|
@ -0,0 +1,911 @@
|
|||
/* -----------------------------------------------------------------------------
|
||||
* 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.
|
||||
*
|
||||
* pydoc.cxx
|
||||
*
|
||||
* Module to return documentation for nodes formatted for PyDoc
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
#include "pydoc.h"
|
||||
#include "doxyparser.h"
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
#include "swigmod.h"
|
||||
|
||||
// define static tables, they are filled in PyDocConverter's constructor
|
||||
PyDocConverter::TagHandlersMap PyDocConverter::tagHandlers;
|
||||
std::map<std::string, std::string> PyDocConverter::sectionTitles;
|
||||
|
||||
using std::string;
|
||||
|
||||
// Helper class increasing the provided indent string in its ctor and decreasing
|
||||
// it in its dtor.
|
||||
class IndentGuard {
|
||||
public:
|
||||
// One indent level.
|
||||
static const char *Level() {
|
||||
return " ";
|
||||
}
|
||||
// Default ctor doesn't do anything and prevents the dtor from doing anything// too and should only be used when the guard needs to be initialized// conditionally as Init() can then be called after checking some condition.// Otherwise, prefer to use the non default ctor below.
|
||||
IndentGuard() {
|
||||
m_initialized = false;
|
||||
}
|
||||
|
||||
// Ctor takes the output to determine the current indent and to remove the
|
||||
// extra indent added to it in the dtor and the variable containing the indent
|
||||
// to use, which must be used after every new line by the code actually
|
||||
// updating the output.
|
||||
IndentGuard(string &output, string &indent) {
|
||||
Init(output, indent);
|
||||
}
|
||||
|
||||
// Really initializes the object created using the default ctor.
|
||||
void Init(string &output, string &indent) {
|
||||
m_output = &output;
|
||||
m_indent = &indent;
|
||||
|
||||
const string::size_type lastNonSpace = m_output->find_last_not_of(' ');
|
||||
if (lastNonSpace == string::npos) {
|
||||
m_firstLineIndent = m_output->length();
|
||||
} else if ((*m_output)[lastNonSpace] == '\n') {
|
||||
m_firstLineIndent = m_output->length() - (lastNonSpace + 1);
|
||||
} else {
|
||||
m_firstLineIndent = 0;
|
||||
}
|
||||
|
||||
// Notice that the indent doesn't include the first line indent because it's
|
||||
// implicit, i.e. it is present in the input and so is copied into the
|
||||
// output anyhow.
|
||||
*m_indent = Level();
|
||||
|
||||
m_initialized = true;
|
||||
}
|
||||
|
||||
// Get the indent for the first line of the paragraph, which is smaller than
|
||||
// the indent for the subsequent lines.
|
||||
string getFirstLineIndent() const {
|
||||
return string(m_firstLineIndent, ' ');
|
||||
}
|
||||
|
||||
~IndentGuard() {
|
||||
if (!m_initialized)
|
||||
return;
|
||||
|
||||
m_indent->clear();
|
||||
|
||||
// Get rid of possible remaining extra indent, e.g. if there were any trailing
|
||||
// new lines: we shouldn't add the extra indent level to whatever follows
|
||||
// this paragraph.
|
||||
static const size_t lenIndentLevel = strlen(Level());
|
||||
if (m_output->length() > lenIndentLevel) {
|
||||
const size_t start = m_output->length() - lenIndentLevel;
|
||||
if (m_output->compare(start, string::npos, Level()) == 0)
|
||||
m_output->erase(start);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
string *m_output;
|
||||
string *m_indent;
|
||||
string::size_type m_firstLineIndent;
|
||||
bool m_initialized;
|
||||
|
||||
IndentGuard(const IndentGuard &);
|
||||
IndentGuard &operator=(const IndentGuard &);
|
||||
};
|
||||
|
||||
// Return the indent of the given multiline string, i.e. the maximal number of
|
||||
// spaces present in the beginning of all its non-empty lines.
|
||||
static size_t determineIndent(const string &s) {
|
||||
size_t minIndent = static_cast<size_t>(-1);
|
||||
|
||||
for (size_t lineStart = 0; lineStart < s.length();) {
|
||||
const size_t lineEnd = s.find('\n', lineStart);
|
||||
const size_t firstNonSpace = s.find_first_not_of(' ', lineStart);
|
||||
|
||||
// If inequality doesn't hold, it means that this line contains only spaces
|
||||
// (notice that this works whether lineEnd is valid or string::npos), in
|
||||
// which case it doesn't matter when determining the indent.
|
||||
if (firstNonSpace < lineEnd) {
|
||||
// Here we can be sure firstNonSpace != string::npos.
|
||||
const size_t lineIndent = firstNonSpace - lineStart;
|
||||
if (lineIndent < minIndent)
|
||||
minIndent = lineIndent;
|
||||
}
|
||||
|
||||
if (lineEnd == string::npos)
|
||||
break;
|
||||
|
||||
lineStart = lineEnd + 1;
|
||||
}
|
||||
|
||||
return minIndent;
|
||||
}
|
||||
|
||||
static void trimWhitespace(string &s) {
|
||||
const string::size_type lastNonSpace = s.find_last_not_of(' ');
|
||||
if (lastNonSpace == string::npos)
|
||||
s.clear();
|
||||
else
|
||||
s.erase(lastNonSpace + 1);
|
||||
}
|
||||
|
||||
// Erase the first character in the string if it is a newline
|
||||
static void eraseLeadingNewLine(string &s) {
|
||||
if (!s.empty() && s[0] == '\n')
|
||||
s.erase(s.begin());
|
||||
}
|
||||
|
||||
// Erase the last character in the string if it is a newline
|
||||
static void eraseTrailingNewLine(string &s) {
|
||||
if (!s.empty() && s[s.size() - 1] == '\n')
|
||||
s.erase(s.size() - 1);
|
||||
}
|
||||
|
||||
// Check the generated docstring line by line and make sure that any
|
||||
// code and verbatim blocks have an empty line preceding them, which
|
||||
// is necessary for Sphinx. Additionally, this strips any empty lines
|
||||
// appearing at the beginning of the docstring.
|
||||
static string padCodeAndVerbatimBlocks(const string &docString) {
|
||||
std::string result;
|
||||
|
||||
std::istringstream iss(docString);
|
||||
|
||||
// Initialize to false because there is no previous line yet
|
||||
bool lastLineWasNonBlank = false;
|
||||
|
||||
for (string line; std::getline(iss, line); result += line) {
|
||||
if (!result.empty()) {
|
||||
// Terminate the previous line
|
||||
result += '\n';
|
||||
}
|
||||
|
||||
const size_t pos = line.find_first_not_of(" \t");
|
||||
if (pos == string::npos) {
|
||||
lastLineWasNonBlank = false;
|
||||
} else {
|
||||
if (lastLineWasNonBlank &&
|
||||
(line.compare(pos, 13, ".. code-block") == 0 ||
|
||||
line.compare(pos, 7, ".. math") == 0)) {
|
||||
// Must separate code or math blocks from the previous line
|
||||
result += '\n';
|
||||
}
|
||||
lastLineWasNonBlank = true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/* static */
|
||||
PyDocConverter::TagHandlersMap::mapped_type PyDocConverter::make_handler(tagHandler handler) {
|
||||
return make_pair(handler, std::string());
|
||||
}
|
||||
|
||||
/* static */
|
||||
PyDocConverter::TagHandlersMap::mapped_type PyDocConverter::make_handler(tagHandler handler, const char *arg) {
|
||||
return make_pair(handler, arg);
|
||||
}
|
||||
|
||||
void PyDocConverter::fillStaticTables() {
|
||||
if (tagHandlers.size()) // fill only once
|
||||
return;
|
||||
|
||||
// table of section titles, they are printed only once
|
||||
// for each group of specified doxygen commands
|
||||
sectionTitles["author"] = "Author: ";
|
||||
sectionTitles["authors"] = "Authors: ";
|
||||
sectionTitles["copyright"] = "Copyright: ";
|
||||
sectionTitles["deprecated"] = "Deprecated: ";
|
||||
sectionTitles["example"] = "Example: ";
|
||||
sectionTitles["note"] = "Notes: ";
|
||||
sectionTitles["remark"] = "Remarks: ";
|
||||
sectionTitles["remarks"] = "Remarks: ";
|
||||
sectionTitles["warning"] = "Warning: ";
|
||||
// sectionTitles["sa"] = "See also: ";
|
||||
// sectionTitles["see"] = "See also: ";
|
||||
sectionTitles["since"] = "Since: ";
|
||||
sectionTitles["todo"] = "TODO: ";
|
||||
sectionTitles["version"] = "Version: ";
|
||||
|
||||
tagHandlers["a"] = make_handler(&PyDocConverter::handleTagWrap, "*");
|
||||
tagHandlers["b"] = make_handler(&PyDocConverter::handleTagWrap, "**");
|
||||
// \c command is translated as single quotes around next word
|
||||
tagHandlers["c"] = make_handler(&PyDocConverter::handleTagWrap, "``");
|
||||
tagHandlers["cite"] = make_handler(&PyDocConverter::handleTagWrap, "'");
|
||||
tagHandlers["e"] = make_handler(&PyDocConverter::handleTagWrap, "*");
|
||||
// these commands insert just a single char, some of them need to be escaped
|
||||
tagHandlers["$"] = make_handler(&PyDocConverter::handleTagChar);
|
||||
tagHandlers["@"] = make_handler(&PyDocConverter::handleTagChar);
|
||||
tagHandlers["\\"] = make_handler(&PyDocConverter::handleTagChar);
|
||||
tagHandlers["<"] = make_handler(&PyDocConverter::handleTagChar);
|
||||
tagHandlers[">"] = make_handler(&PyDocConverter::handleTagChar);
|
||||
tagHandlers["&"] = make_handler(&PyDocConverter::handleTagChar);
|
||||
tagHandlers["#"] = make_handler(&PyDocConverter::handleTagChar);
|
||||
tagHandlers["%"] = make_handler(&PyDocConverter::handleTagChar);
|
||||
tagHandlers["~"] = make_handler(&PyDocConverter::handleTagChar);
|
||||
tagHandlers["\""] = make_handler(&PyDocConverter::handleTagChar);
|
||||
tagHandlers["."] = make_handler(&PyDocConverter::handleTagChar);
|
||||
tagHandlers["::"] = make_handler(&PyDocConverter::handleTagChar);
|
||||
// these commands are stripped out, and only their content is printed
|
||||
tagHandlers["attention"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["author"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["authors"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["brief"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["bug"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["code"] = make_handler(&PyDocConverter::handleCode);
|
||||
tagHandlers["copyright"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["date"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["deprecated"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["details"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["em"] = make_handler(&PyDocConverter::handleParagraph, " ");
|
||||
tagHandlers["example"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["exception"] = tagHandlers["throw"] = tagHandlers["throws"] = make_handler(&PyDocConverter::handleTagException);
|
||||
tagHandlers["htmlonly"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["invariant"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["latexonly"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["link"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["manonly"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["note"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["p"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["partofdescription"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["rtfonly"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["remark"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["remarks"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["sa"] = make_handler(&PyDocConverter::handleTagMessage, "See also: ");
|
||||
tagHandlers["see"] = make_handler(&PyDocConverter::handleTagMessage, "See also: ");
|
||||
tagHandlers["since"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["short"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["todo"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["version"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["verbatim"] = make_handler(&PyDocConverter::handleVerbatimBlock);
|
||||
tagHandlers["warning"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
tagHandlers["xmlonly"] = make_handler(&PyDocConverter::handleParagraph);
|
||||
// these commands have special handlers
|
||||
tagHandlers["arg"] = make_handler(&PyDocConverter::handleTagMessage, "* ");
|
||||
tagHandlers["cond"] = make_handler(&PyDocConverter::handleTagMessage, "Conditional comment: ");
|
||||
tagHandlers["else"] = make_handler(&PyDocConverter::handleTagIf, "Else: ");
|
||||
tagHandlers["elseif"] = make_handler(&PyDocConverter::handleTagIf, "Else if: ");
|
||||
tagHandlers["endcond"] = make_handler(&PyDocConverter::handleTagMessage, "End of conditional comment.");
|
||||
tagHandlers["if"] = make_handler(&PyDocConverter::handleTagIf, "If: ");
|
||||
tagHandlers["ifnot"] = make_handler(&PyDocConverter::handleTagIf, "If not: ");
|
||||
tagHandlers["image"] = make_handler(&PyDocConverter::handleTagImage);
|
||||
tagHandlers["li"] = make_handler(&PyDocConverter::handleTagMessage, "* ");
|
||||
tagHandlers["overload"] = make_handler(&PyDocConverter::handleTagMessage,
|
||||
"This is an overloaded member function, provided for"
|
||||
" convenience.\nIt differs from the above function only in what" " argument(s) it accepts.");
|
||||
tagHandlers["par"] = make_handler(&PyDocConverter::handleTagPar);
|
||||
tagHandlers["param"] = tagHandlers["tparam"] = make_handler(&PyDocConverter::handleTagParam);
|
||||
tagHandlers["ref"] = make_handler(&PyDocConverter::handleTagRef);
|
||||
tagHandlers["result"] = tagHandlers["return"] = tagHandlers["returns"] = make_handler(&PyDocConverter::handleTagReturn);
|
||||
|
||||
// this command just prints it's contents
|
||||
// (it is internal command of swig's parser, contains plain text)
|
||||
tagHandlers["plainstd::string"] = make_handler(&PyDocConverter::handlePlainString);
|
||||
tagHandlers["plainstd::endl"] = make_handler(&PyDocConverter::handleNewLine);
|
||||
tagHandlers["n"] = make_handler(&PyDocConverter::handleNewLine);
|
||||
|
||||
// \f commands output literal Latex formula, which is still better than nothing.
|
||||
tagHandlers["f$"] = tagHandlers["f["] = tagHandlers["f{"] = make_handler(&PyDocConverter::handleMath);
|
||||
|
||||
// HTML tags
|
||||
tagHandlers["<a"] = make_handler(&PyDocConverter::handleDoxyHtmlTag_A);
|
||||
tagHandlers["<b"] = make_handler(&PyDocConverter::handleDoxyHtmlTag2, "**");
|
||||
tagHandlers["<blockquote"] = make_handler(&PyDocConverter::handleDoxyHtmlTag_A, "Quote: ");
|
||||
tagHandlers["<body"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<br"] = make_handler(&PyDocConverter::handleDoxyHtmlTag, "\n");
|
||||
|
||||
// there is no formatting for this tag as it was deprecated in HTML 4.01 and
|
||||
// not used in HTML 5
|
||||
tagHandlers["<center"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<caption"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<code"] = make_handler(&PyDocConverter::handleDoxyHtmlTag2, "``");
|
||||
|
||||
tagHandlers["<dl"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<dd"] = make_handler(&PyDocConverter::handleDoxyHtmlTag, " ");
|
||||
tagHandlers["<dt"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
|
||||
|
||||
tagHandlers["<dfn"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<div"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<em"] = make_handler(&PyDocConverter::handleDoxyHtmlTag2, "**");
|
||||
tagHandlers["<form"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<hr"] = make_handler(&PyDocConverter::handleDoxyHtmlTag, "--------------------------------------------------------------------\n");
|
||||
tagHandlers["<h1"] = make_handler(&PyDocConverter::handleDoxyHtmlTag, "# ");
|
||||
tagHandlers["<h2"] = make_handler(&PyDocConverter::handleDoxyHtmlTag, "## ");
|
||||
tagHandlers["<h3"] = make_handler(&PyDocConverter::handleDoxyHtmlTag, "### ");
|
||||
tagHandlers["<i"] = make_handler(&PyDocConverter::handleDoxyHtmlTag2, "*");
|
||||
tagHandlers["<input"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<img"] = make_handler(&PyDocConverter::handleDoxyHtmlTag, "Image:");
|
||||
tagHandlers["<li"] = make_handler(&PyDocConverter::handleDoxyHtmlTag, "* ");
|
||||
tagHandlers["<meta"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<multicol"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<ol"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<p"] = make_handler(&PyDocConverter::handleDoxyHtmlTag, "\n");
|
||||
tagHandlers["<pre"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<small"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<span"] = make_handler(&PyDocConverter::handleDoxyHtmlTag2, "'");
|
||||
tagHandlers["<strong"] = make_handler(&PyDocConverter::handleDoxyHtmlTag2, "**");
|
||||
|
||||
// make a space between text and super/sub script.
|
||||
tagHandlers["<sub"] = make_handler(&PyDocConverter::handleDoxyHtmlTag, " ");
|
||||
tagHandlers["<sup"] = make_handler(&PyDocConverter::handleDoxyHtmlTag, " ");
|
||||
|
||||
tagHandlers["<table"] = make_handler(&PyDocConverter::handleDoxyHtmlTagNoParam);
|
||||
tagHandlers["<td"] = make_handler(&PyDocConverter::handleDoxyHtmlTag_td);
|
||||
tagHandlers["<th"] = make_handler(&PyDocConverter::handleDoxyHtmlTag_th);
|
||||
tagHandlers["<tr"] = make_handler(&PyDocConverter::handleDoxyHtmlTag_tr);
|
||||
tagHandlers["<tt"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<kbd"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<ul"] = make_handler(&PyDocConverter::handleDoxyHtmlTag);
|
||||
tagHandlers["<var"] = make_handler(&PyDocConverter::handleDoxyHtmlTag2, "*");
|
||||
|
||||
// HTML entities
|
||||
tagHandlers["©"] = make_handler(&PyDocConverter::handleHtmlEntity, "(C)");
|
||||
tagHandlers["&trade"] = make_handler(&PyDocConverter::handleHtmlEntity, " TM");
|
||||
tagHandlers["®"] = make_handler(&PyDocConverter::handleHtmlEntity, "(R)");
|
||||
tagHandlers["<"] = make_handler(&PyDocConverter::handleHtmlEntity, "<");
|
||||
tagHandlers[">"] = make_handler(&PyDocConverter::handleHtmlEntity, ">");
|
||||
tagHandlers["&"] = make_handler(&PyDocConverter::handleHtmlEntity, "&");
|
||||
tagHandlers["&apos"] = make_handler(&PyDocConverter::handleHtmlEntity, "'");
|
||||
tagHandlers["""] = make_handler(&PyDocConverter::handleHtmlEntity, "\"");
|
||||
tagHandlers["&lsquo"] = make_handler(&PyDocConverter::handleHtmlEntity, "`");
|
||||
tagHandlers["&rsquo"] = make_handler(&PyDocConverter::handleHtmlEntity, "'");
|
||||
tagHandlers["&ldquo"] = make_handler(&PyDocConverter::handleHtmlEntity, "\"");
|
||||
tagHandlers["&rdquo"] = make_handler(&PyDocConverter::handleHtmlEntity, "\"");
|
||||
tagHandlers["&ndash"] = make_handler(&PyDocConverter::handleHtmlEntity, "-");
|
||||
tagHandlers["&mdash"] = make_handler(&PyDocConverter::handleHtmlEntity, "--");
|
||||
tagHandlers[" "] = make_handler(&PyDocConverter::handleHtmlEntity, " ");
|
||||
tagHandlers["×"] = make_handler(&PyDocConverter::handleHtmlEntity, "x");
|
||||
tagHandlers["&minus"] = make_handler(&PyDocConverter::handleHtmlEntity, "-");
|
||||
tagHandlers["&sdot"] = make_handler(&PyDocConverter::handleHtmlEntity, ".");
|
||||
tagHandlers["&sim"] = make_handler(&PyDocConverter::handleHtmlEntity, "~");
|
||||
tagHandlers["&le"] = make_handler(&PyDocConverter::handleHtmlEntity, "<=");
|
||||
tagHandlers["&ge"] = make_handler(&PyDocConverter::handleHtmlEntity, ">=");
|
||||
tagHandlers["&larr"] = make_handler(&PyDocConverter::handleHtmlEntity, "<--");
|
||||
tagHandlers["&rarr"] = make_handler(&PyDocConverter::handleHtmlEntity, "-->");
|
||||
}
|
||||
|
||||
PyDocConverter::PyDocConverter(int flags):
|
||||
DoxygenTranslator(flags), m_tableLineLen(0), m_prevRowIsTH(false) {
|
||||
fillStaticTables();
|
||||
}
|
||||
|
||||
// Return the type as it should appear in the output documentation.
|
||||
static std::string getPyDocType(Node *n, const_String_or_char_ptr lname = "") {
|
||||
std::string type;
|
||||
|
||||
String *s = Swig_typemap_lookup("doctype", n, lname, 0);
|
||||
if (!s) {
|
||||
if (String *t = Getattr(n, "type"))
|
||||
s = SwigType_str(t, "");
|
||||
}
|
||||
|
||||
if (!s)
|
||||
return type;
|
||||
|
||||
if (Language::classLookup(s)) {
|
||||
// In Python C++ namespaces are flattened, so remove all but last component
|
||||
// of the name.
|
||||
String *const last = Swig_scopename_last(s);
|
||||
|
||||
// We are not actually sure whether it's a documented class or not, but
|
||||
// there doesn't seem to be any harm in making it a reference if it isn't,
|
||||
// while there is a lot of benefit in having a hyperlink if it is.
|
||||
type = ":py:class:`";
|
||||
type += Char(last);
|
||||
type += "`";
|
||||
|
||||
Delete(last);
|
||||
} else {
|
||||
type = Char(s);
|
||||
}
|
||||
|
||||
Delete(s);
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
std::string PyDocConverter::getParamType(std::string param) {
|
||||
std::string type;
|
||||
|
||||
ParmList *plist = CopyParmList(Getattr(currentNode, "parms"));
|
||||
for (Parm *p = plist; p; p = nextSibling(p)) {
|
||||
String *pname = Getattr(p, "name");
|
||||
if (Char(pname) != param)
|
||||
continue;
|
||||
|
||||
type = getPyDocType(p, pname);
|
||||
break;
|
||||
}
|
||||
Delete(plist);
|
||||
return type;
|
||||
}
|
||||
|
||||
std::string PyDocConverter::translateSubtree(DoxygenEntity &doxygenEntity) {
|
||||
std::string translatedComment;
|
||||
|
||||
if (doxygenEntity.isLeaf)
|
||||
return translatedComment;
|
||||
|
||||
std::string currentSection;
|
||||
std::list<DoxygenEntity>::iterator p = doxygenEntity.entityList.begin();
|
||||
while (p != doxygenEntity.entityList.end()) {
|
||||
std::map<std::string, std::string>::iterator it;
|
||||
it = sectionTitles.find(p->typeOfEntity);
|
||||
if (it != sectionTitles.end()) {
|
||||
if (it->second != currentSection) {
|
||||
currentSection = it->second;
|
||||
translatedComment += currentSection;
|
||||
}
|
||||
}
|
||||
translateEntity(*p, translatedComment);
|
||||
translateSubtree(*p);
|
||||
p++;
|
||||
}
|
||||
|
||||
return translatedComment;
|
||||
}
|
||||
|
||||
void PyDocConverter::translateEntity(DoxygenEntity &doxyEntity, std::string &translatedComment) {
|
||||
// check if we have needed handler and call it
|
||||
std::map<std::string, std::pair<tagHandler, std::string> >::iterator it;
|
||||
it = tagHandlers.find(doxyEntity.typeOfEntity);
|
||||
if (it != tagHandlers.end())
|
||||
(this->*(it->second.first)) (doxyEntity, translatedComment, it->second.second);
|
||||
}
|
||||
|
||||
void PyDocConverter::handleParagraph(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
|
||||
translatedComment += translateSubtree(tag);
|
||||
}
|
||||
|
||||
void PyDocConverter::handleVerbatimBlock(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
|
||||
string verb = translateSubtree(tag);
|
||||
|
||||
eraseLeadingNewLine(verb);
|
||||
|
||||
// Remove the last newline to prevent doubling the newline already present after \endverbatim
|
||||
trimWhitespace(verb); // Needed to catch trailing newline below
|
||||
eraseTrailingNewLine(verb);
|
||||
translatedComment += verb;
|
||||
}
|
||||
|
||||
void PyDocConverter::handleMath(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) {
|
||||
IndentGuard indent;
|
||||
|
||||
// Only \f$ is translated to inline formulae, \f[ and \f{ are for the block ones.
|
||||
const bool inlineFormula = tag.typeOfEntity == "f$";
|
||||
|
||||
string formulaNL;
|
||||
|
||||
if (inlineFormula) {
|
||||
translatedComment += ":math:`";
|
||||
} else {
|
||||
indent.Init(translatedComment, m_indent);
|
||||
|
||||
trimWhitespace(translatedComment);
|
||||
|
||||
const string formulaIndent = indent.getFirstLineIndent();
|
||||
translatedComment += formulaIndent;
|
||||
translatedComment += ".. math::\n";
|
||||
|
||||
formulaNL = '\n';
|
||||
formulaNL += formulaIndent;
|
||||
formulaNL += m_indent;
|
||||
translatedComment += formulaNL;
|
||||
}
|
||||
|
||||
std::string formula;
|
||||
handleTagVerbatim(tag, formula, arg);
|
||||
|
||||
// It is important to ensure that we have no spaces around the inline math
|
||||
// contents, so strip them.
|
||||
const size_t start = formula.find_first_not_of(" \t\n");
|
||||
const size_t end = formula.find_last_not_of(" \t\n");
|
||||
if (start != std::string::npos) {
|
||||
for (size_t n = start; n <= end; n++) {
|
||||
if (formula[n] == '\n') {
|
||||
// New lines must be suppressed in inline maths and indented in the block ones.
|
||||
if (!inlineFormula)
|
||||
translatedComment += formulaNL;
|
||||
} else {
|
||||
// Just copy everything else.
|
||||
translatedComment += formula[n];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (inlineFormula) {
|
||||
translatedComment += "`";
|
||||
}
|
||||
}
|
||||
|
||||
void PyDocConverter::handleCode(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) {
|
||||
IndentGuard indent(translatedComment, m_indent);
|
||||
|
||||
trimWhitespace(translatedComment);
|
||||
|
||||
// Use the current indent for the code-block line itself.
|
||||
translatedComment += indent.getFirstLineIndent();
|
||||
|
||||
// Go out on a limb and assume that examples in the C or C++ sources use C++.
|
||||
// In the worst case, we'll highlight C code using C++ syntax which is not a
|
||||
// big deal (TODO: handle Doxygen code command language argument).
|
||||
translatedComment += ".. code-block:: c++\n\n";
|
||||
|
||||
// Specify the level of extra indentation that will be used for
|
||||
// subsequent lines within the code block. Note that the correct
|
||||
// "starting indentation" is already present in the input, so we
|
||||
// only need to add the desired code block indentation.
|
||||
string codeIndent = m_indent;
|
||||
|
||||
std::string code;
|
||||
handleTagVerbatim(tag, code, arg);
|
||||
|
||||
// Try and remove leading newline, which is present for block \code
|
||||
// command:
|
||||
eraseLeadingNewLine(code);
|
||||
|
||||
translatedComment += codeIndent;
|
||||
for (size_t n = 0; n < code.length(); n++) {
|
||||
if (code[n] == '\n') {
|
||||
// Don't leave trailing white space, this results in PEP8 validation
|
||||
// errors in Python code (which are performed by our own unit tests).
|
||||
trimWhitespace(translatedComment);
|
||||
translatedComment += '\n';
|
||||
|
||||
// Ensure that we indent all the lines by the code indent.
|
||||
translatedComment += codeIndent;
|
||||
} else {
|
||||
// Just copy everything else.
|
||||
translatedComment += code[n];
|
||||
}
|
||||
}
|
||||
|
||||
trimWhitespace(translatedComment);
|
||||
|
||||
// For block commands, the translator adds the newline after
|
||||
// \endcode, so try and compensate by removing the last newline from
|
||||
// the code text:
|
||||
eraseTrailingNewLine(translatedComment);
|
||||
}
|
||||
|
||||
void PyDocConverter::handlePlainString(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
|
||||
translatedComment += tag.data;
|
||||
}
|
||||
|
||||
void PyDocConverter::handleTagVerbatim(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) {
|
||||
translatedComment += arg;
|
||||
for (DoxygenEntityListCIt it = tag.entityList.begin(); it != tag.entityList.end(); it++) {
|
||||
translatedComment += it->data;
|
||||
}
|
||||
}
|
||||
|
||||
void PyDocConverter::handleTagMessage(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) {
|
||||
translatedComment += arg;
|
||||
handleParagraph(tag, translatedComment);
|
||||
}
|
||||
|
||||
void PyDocConverter::handleTagChar(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
|
||||
translatedComment += tag.typeOfEntity;
|
||||
}
|
||||
|
||||
void PyDocConverter::handleTagIf(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) {
|
||||
translatedComment += arg;
|
||||
if (tag.entityList.size()) {
|
||||
translatedComment += tag.entityList.begin()->data;
|
||||
tag.entityList.pop_front();
|
||||
translatedComment += " {" + translateSubtree(tag) + "}";
|
||||
}
|
||||
}
|
||||
|
||||
void PyDocConverter::handleTagPar(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
|
||||
translatedComment += "Title: ";
|
||||
if (tag.entityList.size())
|
||||
translatedComment += tag.entityList.begin()->data;
|
||||
tag.entityList.pop_front();
|
||||
handleParagraph(tag, translatedComment);
|
||||
}
|
||||
|
||||
void PyDocConverter::handleTagImage(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
|
||||
if (tag.entityList.size() < 2)
|
||||
return;
|
||||
tag.entityList.pop_front();
|
||||
translatedComment += "Image: ";
|
||||
translatedComment += tag.entityList.begin()->data;
|
||||
tag.entityList.pop_front();
|
||||
if (tag.entityList.size())
|
||||
translatedComment += "(" + tag.entityList.begin()->data + ")";
|
||||
}
|
||||
|
||||
void PyDocConverter::handleTagParam(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
|
||||
if (tag.entityList.size() < 2)
|
||||
return;
|
||||
|
||||
IndentGuard indent(translatedComment, m_indent);
|
||||
|
||||
DoxygenEntity paramNameEntity = *tag.entityList.begin();
|
||||
tag.entityList.pop_front();
|
||||
|
||||
const std::string ¶mName = paramNameEntity.data;
|
||||
|
||||
const std::string paramType = getParamType(paramName);
|
||||
if (!paramType.empty()) {
|
||||
translatedComment += ":type " + paramName + ": " + paramType + "\n";
|
||||
translatedComment += indent.getFirstLineIndent();
|
||||
}
|
||||
|
||||
translatedComment += ":param " + paramName + ":";
|
||||
|
||||
handleParagraph(tag, translatedComment);
|
||||
}
|
||||
|
||||
|
||||
void PyDocConverter::handleTagReturn(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
|
||||
IndentGuard indent(translatedComment, m_indent);
|
||||
|
||||
const std::string pytype = getPyDocType(currentNode);
|
||||
if (!pytype.empty()) {
|
||||
translatedComment += ":rtype: ";
|
||||
translatedComment += pytype;
|
||||
translatedComment += "\n";
|
||||
translatedComment += indent.getFirstLineIndent();
|
||||
}
|
||||
|
||||
translatedComment += ":return: ";
|
||||
handleParagraph(tag, translatedComment);
|
||||
}
|
||||
|
||||
|
||||
void PyDocConverter::handleTagException(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
|
||||
IndentGuard indent(translatedComment, m_indent);
|
||||
|
||||
translatedComment += ":raises: ";
|
||||
handleParagraph(tag, translatedComment);
|
||||
}
|
||||
|
||||
|
||||
void PyDocConverter::handleTagRef(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
|
||||
if (!tag.entityList.size())
|
||||
return;
|
||||
|
||||
string anchor = tag.entityList.begin()->data;
|
||||
tag.entityList.pop_front();
|
||||
string anchorText = anchor;
|
||||
if (!tag.entityList.empty()) {
|
||||
anchorText = tag.entityList.begin()->data;
|
||||
}
|
||||
translatedComment += "'" + anchorText + "'";
|
||||
}
|
||||
|
||||
|
||||
void PyDocConverter::handleTagWrap(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) {
|
||||
if (tag.entityList.size()) { // do not include empty tags
|
||||
std::string tagData = translateSubtree(tag);
|
||||
// wrap the thing, ignoring whitespace
|
||||
size_t wsPos = tagData.find_last_not_of("\n\t ");
|
||||
if (wsPos != std::string::npos && wsPos != tagData.size() - 1)
|
||||
translatedComment += arg + tagData.substr(0, wsPos + 1) + arg + tagData.substr(wsPos + 1);
|
||||
else
|
||||
translatedComment += arg + tagData + arg;
|
||||
}
|
||||
}
|
||||
|
||||
void PyDocConverter::handleDoxyHtmlTag(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) {
|
||||
std::string htmlTagArgs = tag.data;
|
||||
if (htmlTagArgs == "/") {
|
||||
// end html tag, for example "</ul>
|
||||
// translatedComment += "</" + arg.substr(1) + ">";
|
||||
} else {
|
||||
translatedComment += arg + htmlTagArgs;
|
||||
}
|
||||
}
|
||||
|
||||
void PyDocConverter::handleDoxyHtmlTagNoParam(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) {
|
||||
std::string htmlTagArgs = tag.data;
|
||||
if (htmlTagArgs == "/") {
|
||||
// end html tag, for example "</ul>
|
||||
} else {
|
||||
translatedComment += arg;
|
||||
}
|
||||
}
|
||||
|
||||
void PyDocConverter::handleDoxyHtmlTag_A(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) {
|
||||
std::string htmlTagArgs = tag.data;
|
||||
if (htmlTagArgs == "/") {
|
||||
// end html tag, "</a>
|
||||
translatedComment += " (" + m_url + ')';
|
||||
m_url.clear();
|
||||
} else {
|
||||
m_url.clear();
|
||||
size_t pos = htmlTagArgs.find('=');
|
||||
if (pos != string::npos) {
|
||||
m_url = htmlTagArgs.substr(pos + 1);
|
||||
}
|
||||
translatedComment += arg;
|
||||
}
|
||||
}
|
||||
|
||||
void PyDocConverter::handleDoxyHtmlTag2(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) {
|
||||
std::string htmlTagArgs = tag.data;
|
||||
if (htmlTagArgs == "/") {
|
||||
// end html tag, for example "</em>
|
||||
translatedComment += arg;
|
||||
} else {
|
||||
translatedComment += arg;
|
||||
}
|
||||
}
|
||||
|
||||
void PyDocConverter::handleDoxyHtmlTag_tr(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
|
||||
std::string htmlTagArgs = tag.data;
|
||||
size_t nlPos = translatedComment.rfind('\n');
|
||||
if (htmlTagArgs == "/") {
|
||||
// end tag, </tr> appends vertical table line '|'
|
||||
translatedComment += '|';
|
||||
if (nlPos != string::npos) {
|
||||
size_t startOfTableLinePos = translatedComment.find_first_not_of(" \t", nlPos + 1);
|
||||
if (startOfTableLinePos != string::npos) {
|
||||
m_tableLineLen = translatedComment.size() - startOfTableLinePos;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (m_prevRowIsTH) {
|
||||
// if previous row contained <th> tag, add horizontal separator
|
||||
// but first get leading spaces, because they'll be needed for the next row
|
||||
size_t numLeadingSpaces = translatedComment.size() - nlPos - 1;
|
||||
|
||||
translatedComment += string(m_tableLineLen, '-') + '\n';
|
||||
|
||||
if (nlPos != string::npos) {
|
||||
translatedComment += string(numLeadingSpaces, ' ');
|
||||
}
|
||||
m_prevRowIsTH = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PyDocConverter::handleDoxyHtmlTag_th(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
|
||||
std::string htmlTagArgs = tag.data;
|
||||
if (htmlTagArgs == "/") {
|
||||
// end tag, </th> is ignored
|
||||
} else {
|
||||
translatedComment += '|';
|
||||
m_prevRowIsTH = true;
|
||||
}
|
||||
}
|
||||
|
||||
void PyDocConverter::handleDoxyHtmlTag_td(DoxygenEntity &tag, std::string &translatedComment, const std::string &) {
|
||||
std::string htmlTagArgs = tag.data;
|
||||
if (htmlTagArgs == "/") {
|
||||
// end tag, </td> is ignored
|
||||
} else {
|
||||
translatedComment += '|';
|
||||
}
|
||||
}
|
||||
|
||||
void PyDocConverter::handleHtmlEntity(DoxygenEntity &, std::string &translatedComment, const std::string &arg) {
|
||||
// html entities
|
||||
translatedComment += arg;
|
||||
}
|
||||
|
||||
void PyDocConverter::handleNewLine(DoxygenEntity &, std::string &translatedComment, const std::string &) {
|
||||
trimWhitespace(translatedComment);
|
||||
|
||||
translatedComment += "\n";
|
||||
if (!m_indent.empty())
|
||||
translatedComment += m_indent;
|
||||
}
|
||||
|
||||
String *PyDocConverter::makeDocumentation(Node *n) {
|
||||
String *documentation;
|
||||
std::string pyDocString;
|
||||
|
||||
// store the node, we may need it later
|
||||
currentNode = n;
|
||||
|
||||
// for overloaded functions we must concat documentation for underlying overloads
|
||||
if (Getattr(n, "sym:overloaded")) {
|
||||
// rewind to the first overload
|
||||
while (Getattr(n, "sym:previousSibling"))
|
||||
n = Getattr(n, "sym:previousSibling");
|
||||
|
||||
std::vector<std::string> allDocumentation;
|
||||
|
||||
// minimal indent of any documentation comments, not initialized yet
|
||||
size_t minIndent = static_cast<size_t>(-1);
|
||||
|
||||
// for each real method (not a generated overload) append the documentation
|
||||
string oneDoc;
|
||||
while (n) {
|
||||
documentation = getDoxygenComment(n);
|
||||
if (!Swig_is_generated_overload(n) && documentation) {
|
||||
currentNode = n;
|
||||
if (GetFlag(n, "feature:doxygen:notranslate")) {
|
||||
String *comment = NewString("");
|
||||
Append(comment, documentation);
|
||||
Replaceall(comment, "\n *", "\n");
|
||||
oneDoc = Char(comment);
|
||||
Delete(comment);
|
||||
} else {
|
||||
std::list<DoxygenEntity> entityList = parser.createTree(n, documentation);
|
||||
DoxygenEntity root("root", entityList);
|
||||
|
||||
oneDoc = translateSubtree(root);
|
||||
}
|
||||
|
||||
// find the minimal indent of this documentation comment, we need to
|
||||
// ensure that the entire comment is indented by it to avoid the leading
|
||||
// parts of the other lines being simply discarded later
|
||||
const size_t oneIndent = determineIndent(oneDoc);
|
||||
if (oneIndent < minIndent)
|
||||
minIndent = oneIndent;
|
||||
|
||||
allDocumentation.push_back(oneDoc);
|
||||
}
|
||||
n = Getattr(n, "sym:nextSibling");
|
||||
}
|
||||
|
||||
// construct final documentation string
|
||||
if (allDocumentation.size() > 1) {
|
||||
string indentStr;
|
||||
if (minIndent != static_cast<size_t>(-1))
|
||||
indentStr.assign(minIndent, ' ');
|
||||
|
||||
std::ostringstream concatDocString;
|
||||
for (size_t realOverloadCount = 0; realOverloadCount < allDocumentation.size(); realOverloadCount++) {
|
||||
if (realOverloadCount != 0) {
|
||||
// separate it from the preceding one.
|
||||
concatDocString << "\n" << indentStr << "|\n\n";
|
||||
}
|
||||
|
||||
oneDoc = allDocumentation[realOverloadCount];
|
||||
trimWhitespace(oneDoc);
|
||||
concatDocString << indentStr << "*Overload " << (realOverloadCount + 1) << ":*\n" << oneDoc;
|
||||
}
|
||||
pyDocString = concatDocString.str();
|
||||
} else if (allDocumentation.size() == 1) {
|
||||
pyDocString = *(allDocumentation.begin());
|
||||
}
|
||||
}
|
||||
// for other nodes just process as normal
|
||||
else {
|
||||
documentation = getDoxygenComment(n);
|
||||
if (documentation != NULL) {
|
||||
if (GetFlag(n, "feature:doxygen:notranslate")) {
|
||||
String *comment = NewString("");
|
||||
Append(comment, documentation);
|
||||
Replaceall(comment, "\n *", "\n");
|
||||
pyDocString = Char(comment);
|
||||
Delete(comment);
|
||||
} else {
|
||||
std::list<DoxygenEntity> entityList = parser.createTree(n, documentation);
|
||||
DoxygenEntity root("root", entityList);
|
||||
pyDocString = translateSubtree(root);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if we got something log the result
|
||||
if (!pyDocString.empty()) {
|
||||
|
||||
// remove the last '\n' since additional one is added during writing to file
|
||||
eraseTrailingNewLine(pyDocString);
|
||||
|
||||
// ensure that a blank line occurs before code or math blocks
|
||||
pyDocString = padCodeAndVerbatimBlocks(pyDocString);
|
||||
|
||||
if (m_flags & debug_translator) {
|
||||
std::cout << "\n---RESULT IN PYDOC---" << std::endl;
|
||||
std::cout << pyDocString;
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
return NewString(pyDocString.c_str());
|
||||
}
|
||||
203
Source/Doxygen/pydoc.h
Normal file
203
Source/Doxygen/pydoc.h
Normal file
|
|
@ -0,0 +1,203 @@
|
|||
/* -----------------------------------------------------------------------------
|
||||
* 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.
|
||||
*
|
||||
* pydoc.h
|
||||
*
|
||||
* Module to return documentation for nodes formatted for PyDoc
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
#ifndef PYDOCCONVERTER_H_
|
||||
#define PYDOCCONVERTER_H_
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include "swig.h"
|
||||
#include "doxyentity.h"
|
||||
#include "doxytranslator.h"
|
||||
|
||||
#define DOC_STRING_LENGTH 64 // characters per line allowed
|
||||
#define DOC_PARAM_STRING_LENGTH 30 // characters reserved for param name / type
|
||||
|
||||
class PyDocConverter : public DoxygenTranslator {
|
||||
public:
|
||||
PyDocConverter(int flags = 0);
|
||||
String *makeDocumentation(Node *node);
|
||||
|
||||
protected:
|
||||
|
||||
size_t m_tableLineLen;
|
||||
bool m_prevRowIsTH;
|
||||
std::string m_url;
|
||||
|
||||
/*
|
||||
* Translate every entity in a tree, also manages sections
|
||||
* display. Prints title for every group of tags that have
|
||||
* a section title associated with them
|
||||
*/
|
||||
std::string translateSubtree(DoxygenEntity &doxygenEntity);
|
||||
|
||||
/*
|
||||
* Translate one entity with the appropriate handler, according
|
||||
* to the tagHandlers
|
||||
*/
|
||||
void translateEntity(DoxygenEntity &doxyEntity, std::string &translatedComment);
|
||||
|
||||
/*
|
||||
* Typedef for the function that handles one tag
|
||||
* arg - some string argument to easily pass it through lookup table
|
||||
*/
|
||||
typedef void (PyDocConverter::*tagHandler) (DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Wrap the command data with the some string
|
||||
* arg - string to wrap with, like '_' or '*'
|
||||
*/
|
||||
void handleTagWrap(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Just prints new line
|
||||
*/
|
||||
void handleNewLine(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Print the name of tag to the output, used for escape-commands
|
||||
*/
|
||||
void handleTagChar(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Format the contents of the \exception tag or its synonyms.
|
||||
*/
|
||||
void handleTagException(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Print only the content and strip original tag
|
||||
*/
|
||||
void handleParagraph(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg = std::string());
|
||||
|
||||
/*
|
||||
* Handle Doxygen verbatim tag
|
||||
*/
|
||||
void handleVerbatimBlock(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg = std::string());
|
||||
|
||||
/*
|
||||
* Handle one of the Doxygen formula-related tags.
|
||||
*/
|
||||
void handleMath(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Handle a code snippet.
|
||||
*/
|
||||
void handleCode(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Print only data part of code
|
||||
*/
|
||||
void handlePlainString(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/**
|
||||
* Copies verbatim args of the tag to output, used for commands like \f$, ...
|
||||
*/
|
||||
void handleTagVerbatim(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Print the if-elseif-else-endif section
|
||||
*/
|
||||
void handleTagIf(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Prints the specified message, than the contents of the tag
|
||||
* arg - message
|
||||
*/
|
||||
void handleTagMessage(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Insert 'Title: ...'
|
||||
*/
|
||||
void handleTagPar(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Insert 'Image: ...'
|
||||
*/
|
||||
void handleTagImage(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Format nice param description with type information
|
||||
*/
|
||||
void handleTagParam(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Format the contents of the \return tag or its synonyms.
|
||||
*/
|
||||
void handleTagReturn(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Writes text for \ref tag.
|
||||
*/
|
||||
void handleTagRef(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/* Handles HTML tags recognized by Doxygen, like <A ...>, <ul>, <table>, ... */
|
||||
|
||||
void handleDoxyHtmlTag(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/** Does not output params of HTML tag, for example in <table border='1'>
|
||||
* 'border=1' is not written to output.
|
||||
*/
|
||||
void handleDoxyHtmlTagNoParam(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/** Translates tag <a href = "url">text</a> to: text ("url"). */
|
||||
void handleDoxyHtmlTag_A(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/*
|
||||
* Handles HTML tags, which are translated to markdown-like syntax, for example
|
||||
* <i>text</i> --> _text_. Appends arg for start HTML tag and end HTML tag.
|
||||
*/
|
||||
void handleDoxyHtmlTag2(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/* Handles HTML table, tag <tr> */
|
||||
void handleDoxyHtmlTag_tr(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/* Handles HTML table, tag <th> */
|
||||
void handleDoxyHtmlTag_th(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/* Handles HTML table, tag <td> */
|
||||
void handleDoxyHtmlTag_td(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
/* Handles HTML entities recognized by Doxygen, like <, ©, ... */
|
||||
void handleHtmlEntity(DoxygenEntity &, std::string &translatedComment, const std::string &arg);
|
||||
|
||||
|
||||
/*
|
||||
* Simple helper function that calculates correct parameter type
|
||||
* of the node stored in 'currentNode'
|
||||
* If param with specified name is not found, empty string is returned
|
||||
*/
|
||||
std::string getParamType(std::string name);
|
||||
|
||||
private:
|
||||
// temporary thing, should be refactored somehow
|
||||
Node *currentNode;
|
||||
|
||||
// Extra indent for the current paragraph, must be output after each new line.
|
||||
std::string m_indent;
|
||||
|
||||
|
||||
// this contains the handler pointer and one string argument
|
||||
typedef std::map<std::string, std::pair<tagHandler, std::string> >TagHandlersMap;
|
||||
static TagHandlersMap tagHandlers;
|
||||
|
||||
// this contains the sections tittles, like 'Arguments:' or 'Notes:', that are printed only once
|
||||
static std::map<std::string, std::string> sectionTitles;
|
||||
|
||||
// Helper functions for fillStaticTables(): make a new tag handler object.
|
||||
TagHandlersMap::mapped_type make_handler(tagHandler handler);
|
||||
TagHandlersMap::mapped_type make_handler(tagHandler handler, const char *arg);
|
||||
|
||||
void fillStaticTables();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -18,6 +18,8 @@
|
|||
* Even though symbolic constants are used in the SWIG source, this is
|
||||
* not always the case in SWIG interface files. Do not change the
|
||||
* numbers in this file.
|
||||
*
|
||||
* This file is used as the input for generating Lib/swigwarn.swg.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
#ifndef SWIGWARN_H_
|
||||
|
|
@ -93,8 +95,8 @@
|
|||
#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_ALIAS_DECLARATION 341 /* redundant now */
|
||||
#define WARN_CPP11_ALIAS_TEMPLATE 342 /* redundant now */
|
||||
#define WARN_CPP11_VARIADIC_TEMPLATE 343
|
||||
|
||||
#define WARN_IGNORE_OPERATOR_NEW 350 /* new */
|
||||
|
|
@ -153,6 +155,7 @@
|
|||
#define WARN_TYPE_INCOMPLETE 402
|
||||
#define WARN_TYPE_ABSTRACT 403
|
||||
#define WARN_TYPE_REDEFINED 404
|
||||
#define WARN_TYPE_RVALUE_REF_QUALIFIER_IGNORED 405
|
||||
|
||||
#define WARN_TYPEMAP_SOURCETARGET 450
|
||||
#define WARN_TYPEMAP_CHARLEAK 451
|
||||
|
|
@ -207,6 +210,18 @@
|
|||
#define WARN_LANG_ILLEGAL_DESTRUCTOR 521
|
||||
#define WARN_LANG_EXTEND_CONSTRUCTOR 522
|
||||
#define WARN_LANG_EXTEND_DESTRUCTOR 523
|
||||
#define WARN_LANG_EXPERIMENTAL 524
|
||||
#define WARN_LANG_DIRECTOR_FINAL 525
|
||||
|
||||
/* -- Doxygen comments -- */
|
||||
|
||||
#define WARN_DOXYGEN_UNKNOWN_COMMAND 560
|
||||
#define WARN_DOXYGEN_UNEXPECTED_END_OF_COMMENT 561
|
||||
#define WARN_DOXYGEN_COMMAND_EXPECTED 562
|
||||
#define WARN_DOXYGEN_HTML_ERROR 563
|
||||
#define WARN_DOXYGEN_COMMAND_ERROR 564
|
||||
#define WARN_DOXYGEN_UNKNOWN_CHARACTER 565
|
||||
#define WARN_DOXYGEN_UNEXPECTED_ITERATOR_VALUE 566
|
||||
|
||||
/* -- Reserved (600-799) -- */
|
||||
|
||||
|
|
@ -215,9 +230,9 @@
|
|||
/* Feel free to claim any number in this space that's not currently being used. Just make sure you
|
||||
add an entry here */
|
||||
|
||||
#define WARN_D_TYPEMAP_CTYPE_UNDEF 700
|
||||
#define WARN_D_TYPEMAP_CTYPE_UNDEF 700
|
||||
#define WARN_D_TYPEMAP_IMTYPE_UNDEF 701
|
||||
#define WARN_D_TYPEMAP_DTYPE_UNDEF 702
|
||||
#define WARN_D_TYPEMAP_DTYPE_UNDEF 702
|
||||
#define WARN_D_MULTIPLE_INHERITANCE 703
|
||||
#define WARN_D_TYPEMAP_CLASSMOD_UNDEF 704
|
||||
#define WARN_D_TYPEMAP_DBODY_UNDEF 705
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ AM_CPPFLAGS = -I$(BUILD_SOURCE_DIR)/Include \
|
|||
-I$(SOURCE_DIR)/Include \
|
||||
-I$(SOURCE_DIR)/DOH \
|
||||
-I$(SOURCE_DIR)/CParse \
|
||||
-I$(SOURCE_DIR)/Doxygen \
|
||||
-I$(SOURCE_DIR)/Preprocessor \
|
||||
-I$(SOURCE_DIR)/Swig \
|
||||
-I$(SOURCE_DIR)/Modules
|
||||
|
|
@ -34,12 +35,18 @@ eswig_SOURCES = CParse/cscanner.c \
|
|||
DOH/memory.c \
|
||||
DOH/string.c \
|
||||
DOH/void.c \
|
||||
Modules/allegrocl.cxx \
|
||||
Doxygen/doxyentity.cxx \
|
||||
Doxygen/doxyentity.h \
|
||||
Doxygen/doxyparser.cxx \
|
||||
Doxygen/doxyparser.h \
|
||||
Doxygen/doxytranslator.cxx \
|
||||
Doxygen/doxytranslator.h \
|
||||
Doxygen/javadoc.cxx \
|
||||
Doxygen/javadoc.h \
|
||||
Doxygen/pydoc.cxx \
|
||||
Doxygen/pydoc.h \
|
||||
Modules/allocate.cxx \
|
||||
Modules/browser.cxx \
|
||||
Modules/cffi.cxx \
|
||||
Modules/chicken.cxx \
|
||||
Modules/clisp.cxx \
|
||||
Modules/contract.cxx \
|
||||
Modules/c.cxx \
|
||||
Modules/csharp.cxx \
|
||||
|
|
@ -54,25 +61,20 @@ eswig_SOURCES = CParse/cscanner.c \
|
|||
Modules/lang.cxx \
|
||||
Modules/lua.cxx \
|
||||
Modules/main.cxx \
|
||||
Modules/modula3.cxx \
|
||||
Modules/module.cxx \
|
||||
Modules/mzscheme.cxx \
|
||||
Modules/nested.cxx \
|
||||
Modules/nested.cxx \
|
||||
Modules/ocaml.cxx \
|
||||
Modules/octave.cxx \
|
||||
Modules/overload.cxx \
|
||||
Modules/perl5.cxx \
|
||||
Modules/php.cxx \
|
||||
Modules/pike.cxx \
|
||||
Modules/python.cxx \
|
||||
Modules/r.cxx \
|
||||
Modules/ruby.cxx \
|
||||
Modules/s-exp.cxx \
|
||||
Modules/scilab.cxx \
|
||||
Modules/swigmain.cxx \
|
||||
Modules/tcl8.cxx \
|
||||
Modules/typepass.cxx \
|
||||
Modules/uffi.cxx \
|
||||
Modules/utils.cxx \
|
||||
Modules/xml.cxx \
|
||||
Preprocessor/cpp.c \
|
||||
|
|
@ -91,8 +93,8 @@ eswig_SOURCES = CParse/cscanner.c \
|
|||
Swig/stype.c \
|
||||
Swig/symbol.c \
|
||||
Swig/tree.c \
|
||||
Swig/typeobj.c \
|
||||
Swig/typemap.c \
|
||||
Swig/typeobj.c \
|
||||
Swig/typesys.c \
|
||||
Swig/wrapfunc.c
|
||||
|
||||
|
|
@ -122,7 +124,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 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
|
||||
SWIGTYPEDEFS=-T bool -T File -T DohObjInfo -T Parm -T Language -T List -T TargetLanguageModule -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:
|
||||
|
|
|
|||
|
|
@ -471,7 +471,7 @@ void add_defined_foreign_type(Node *n, int overwrite = 0, String *k = 0,
|
|||
// a synonym type was found (held in variable 'match')
|
||||
// Printf(stderr, "setting primary synonym of %p to %p\n", new_node, match);
|
||||
if (new_node == match)
|
||||
Printf(stderr, "Hey-4 * - '%s' is a synonym of iteself!\n", Getattr(new_node, "name"));
|
||||
Printf(stderr, "Hey-4 * - '%s' is a synonym of itself!\n", Getattr(new_node, "name"));
|
||||
Setattr(new_node, "allegrocl:synonym-of", match);
|
||||
// Printf(stderr,"*** 4\n");
|
||||
add_linked_type(new_node);
|
||||
|
|
@ -1685,285 +1685,6 @@ int ALLEGROCL::top(Node *n) {
|
|||
return SWIG_OK;
|
||||
}
|
||||
|
||||
/* very shamelessly 'borrowed' from overload.cxx, which
|
||||
keeps the below Swig_overload_rank() code to itself.
|
||||
We don't need a dispatch function in the C++ wrapper
|
||||
code; we want it over on the lisp side. */
|
||||
|
||||
#define Swig_overload_rank Allegrocl_swig_overload_rank
|
||||
|
||||
#define MAX_OVERLOAD 256
|
||||
|
||||
/* Overload "argc" and "argv" */
|
||||
// String *argv_template_string;
|
||||
// String *argc_template_string;
|
||||
|
||||
struct Overloaded {
|
||||
Node *n; /* Node */
|
||||
int argc; /* Argument count */
|
||||
ParmList *parms; /* Parameters used for overload check */
|
||||
int error; /* Ambiguity error */
|
||||
};
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_overload_rank()
|
||||
*
|
||||
* This function takes an overloaded declaration and creates a list that ranks
|
||||
* all overloaded methods in an order that can be used to generate a dispatch
|
||||
* function.
|
||||
* Slight difference in the way this function is used by scripting languages and
|
||||
* statically typed languages. The script languages call this method via
|
||||
* Swig_overload_dispatch() - where wrappers for all overloaded methods are generated,
|
||||
* however sometimes the code can never be executed. The non-scripting languages
|
||||
* call this method via Swig_overload_check() for each overloaded method in order
|
||||
* to determine whether or not the method should be wrapped. Note the slight
|
||||
* difference when overloading methods that differ by const only. The
|
||||
* scripting languages will ignore the const method, whereas the non-scripting
|
||||
* languages ignore the first method parsed.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
static List *Swig_overload_rank(Node *n, bool script_lang_wrapping) {
|
||||
Overloaded nodes[MAX_OVERLOAD];
|
||||
int nnodes = 0;
|
||||
Node *o = Getattr(n, "sym:overloaded");
|
||||
Node *c;
|
||||
|
||||
if (!o)
|
||||
return 0;
|
||||
|
||||
c = o;
|
||||
while (c) {
|
||||
if (Getattr(c, "error")) {
|
||||
c = Getattr(c, "sym:nextSibling");
|
||||
continue;
|
||||
}
|
||||
/* if (SmartPointer && Getattr(c,"cplus:staticbase")) {
|
||||
c = Getattr(c,"sym:nextSibling");
|
||||
continue;
|
||||
} */
|
||||
|
||||
/* Make a list of all the declarations (methods) that are overloaded with
|
||||
* this one particular method name */
|
||||
if (Getattr(c, "wrap:name")) {
|
||||
nodes[nnodes].n = c;
|
||||
nodes[nnodes].parms = Getattr(c, "wrap:parms");
|
||||
nodes[nnodes].argc = emit_num_required(nodes[nnodes].parms);
|
||||
nodes[nnodes].error = 0;
|
||||
nnodes++;
|
||||
}
|
||||
c = Getattr(c, "sym:nextSibling");
|
||||
}
|
||||
|
||||
/* Sort the declarations by required argument count */
|
||||
{
|
||||
int i, j;
|
||||
for (i = 0; i < nnodes; i++) {
|
||||
for (j = i + 1; j < nnodes; j++) {
|
||||
if (nodes[i].argc > nodes[j].argc) {
|
||||
Overloaded t = nodes[i];
|
||||
nodes[i] = nodes[j];
|
||||
nodes[j] = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Sort the declarations by argument types */
|
||||
{
|
||||
int i, j;
|
||||
for (i = 0; i < nnodes - 1; i++) {
|
||||
if (nodes[i].argc == nodes[i + 1].argc) {
|
||||
for (j = i + 1; (j < nnodes) && (nodes[j].argc == nodes[i].argc); j++) {
|
||||
Parm *p1 = nodes[i].parms;
|
||||
Parm *p2 = nodes[j].parms;
|
||||
int differ = 0;
|
||||
int num_checked = 0;
|
||||
while (p1 && p2 && (num_checked < nodes[i].argc)) {
|
||||
// Printf(stdout,"p1 = '%s', p2 = '%s'\n", Getattr(p1,"type"), Getattr(p2,"type"));
|
||||
if (checkAttribute(p1, "tmap:in:numinputs", "0")) {
|
||||
p1 = Getattr(p1, "tmap:in:next");
|
||||
continue;
|
||||
}
|
||||
if (checkAttribute(p2, "tmap:in:numinputs", "0")) {
|
||||
p2 = Getattr(p2, "tmap:in:next");
|
||||
continue;
|
||||
}
|
||||
String *t1 = Getattr(p1, "tmap:typecheck:precedence");
|
||||
String *t2 = Getattr(p2, "tmap:typecheck:precedence");
|
||||
if ((!t1) && (!nodes[i].error)) {
|
||||
Swig_warning(WARN_TYPEMAP_TYPECHECK, Getfile(nodes[i].n), Getline(nodes[i].n),
|
||||
"Overloaded method %s not supported (incomplete type checking rule - no precedence level in typecheck typemap for '%s').\n",
|
||||
Swig_name_decl(nodes[i].n), SwigType_str(Getattr(p1, "type"), 0));
|
||||
nodes[i].error = 1;
|
||||
} else if ((!t2) && (!nodes[j].error)) {
|
||||
Swig_warning(WARN_TYPEMAP_TYPECHECK, Getfile(nodes[j].n), Getline(nodes[j].n),
|
||||
"Overloaded method %s not supported (incomplete type checking rule - no precedence level in typecheck typemap for '%s').\n",
|
||||
Swig_name_decl(nodes[j].n), SwigType_str(Getattr(p2, "type"), 0));
|
||||
nodes[j].error = 1;
|
||||
}
|
||||
if (t1 && t2) {
|
||||
int t1v, t2v;
|
||||
t1v = atoi(Char(t1));
|
||||
t2v = atoi(Char(t2));
|
||||
differ = t1v - t2v;
|
||||
} else if (!t1 && t2)
|
||||
differ = 1;
|
||||
else if (t1 && !t2)
|
||||
differ = -1;
|
||||
else if (!t1 && !t2)
|
||||
differ = -1;
|
||||
num_checked++;
|
||||
if (differ > 0) {
|
||||
Overloaded t = nodes[i];
|
||||
nodes[i] = nodes[j];
|
||||
nodes[j] = t;
|
||||
break;
|
||||
} else if ((differ == 0) && (Strcmp(t1, "0") == 0)) {
|
||||
t1 = Getattr(p1, "ltype");
|
||||
if (!t1) {
|
||||
t1 = SwigType_ltype(Getattr(p1, "type"));
|
||||
if (Getattr(p1, "tmap:typecheck:SWIGTYPE")) {
|
||||
SwigType_add_pointer(t1);
|
||||
}
|
||||
Setattr(p1, "ltype", t1);
|
||||
}
|
||||
t2 = Getattr(p2, "ltype");
|
||||
if (!t2) {
|
||||
t2 = SwigType_ltype(Getattr(p2, "type"));
|
||||
if (Getattr(p2, "tmap:typecheck:SWIGTYPE")) {
|
||||
SwigType_add_pointer(t2);
|
||||
}
|
||||
Setattr(p2, "ltype", t2);
|
||||
}
|
||||
|
||||
/* Need subtype check here. If t2 is a subtype of t1, then we need to change the
|
||||
order */
|
||||
|
||||
if (SwigType_issubtype(t2, t1)) {
|
||||
Overloaded t = nodes[i];
|
||||
nodes[i] = nodes[j];
|
||||
nodes[j] = t;
|
||||
}
|
||||
|
||||
if (Strcmp(t1, t2) != 0) {
|
||||
differ = 1;
|
||||
break;
|
||||
}
|
||||
} else if (differ) {
|
||||
break;
|
||||
}
|
||||
if (Getattr(p1, "tmap:in:next")) {
|
||||
p1 = Getattr(p1, "tmap:in:next");
|
||||
} else {
|
||||
p1 = nextSibling(p1);
|
||||
}
|
||||
if (Getattr(p2, "tmap:in:next")) {
|
||||
p2 = Getattr(p2, "tmap:in:next");
|
||||
} else {
|
||||
p2 = nextSibling(p2);
|
||||
}
|
||||
}
|
||||
if (!differ) {
|
||||
/* See if declarations differ by const only */
|
||||
String *d1 = Getattr(nodes[i].n, "decl");
|
||||
String *d2 = Getattr(nodes[j].n, "decl");
|
||||
if (d1 && d2) {
|
||||
String *dq1 = Copy(d1);
|
||||
String *dq2 = Copy(d2);
|
||||
if (SwigType_isconst(d1)) {
|
||||
Delete(SwigType_pop(dq1));
|
||||
}
|
||||
if (SwigType_isconst(d2)) {
|
||||
Delete(SwigType_pop(dq2));
|
||||
}
|
||||
if (Strcmp(dq1, dq2) == 0) {
|
||||
|
||||
if (SwigType_isconst(d1) && !SwigType_isconst(d2)) {
|
||||
if (script_lang_wrapping) {
|
||||
// Swap nodes so that the const method gets ignored (shadowed by the non-const method)
|
||||
Overloaded t = nodes[i];
|
||||
nodes[i] = nodes[j];
|
||||
nodes[j] = t;
|
||||
}
|
||||
differ = 1;
|
||||
if (!nodes[j].error) {
|
||||
if (script_lang_wrapping) {
|
||||
Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[j].n), Getline(nodes[j].n),
|
||||
"Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n));
|
||||
Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[i].n), Getline(nodes[i].n),
|
||||
"using non-const method %s instead.\n", Swig_name_decl(nodes[i].n));
|
||||
} else {
|
||||
if (!Getattr(nodes[j].n, "overload:ignore")) {
|
||||
Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n),
|
||||
"Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n));
|
||||
Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[i].n), Getline(nodes[i].n),
|
||||
"using %s instead.\n", Swig_name_decl(nodes[i].n));
|
||||
}
|
||||
}
|
||||
}
|
||||
nodes[j].error = 1;
|
||||
} else if (!SwigType_isconst(d1) && SwigType_isconst(d2)) {
|
||||
differ = 1;
|
||||
if (!nodes[j].error) {
|
||||
if (script_lang_wrapping) {
|
||||
Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[j].n), Getline(nodes[j].n),
|
||||
"Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n));
|
||||
Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[i].n), Getline(nodes[i].n),
|
||||
"using non-const method %s instead.\n", Swig_name_decl(nodes[i].n));
|
||||
} else {
|
||||
if (!Getattr(nodes[j].n, "overload:ignore")) {
|
||||
Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n),
|
||||
"Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n));
|
||||
Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[i].n), Getline(nodes[i].n),
|
||||
"using %s instead.\n", Swig_name_decl(nodes[i].n));
|
||||
}
|
||||
}
|
||||
}
|
||||
nodes[j].error = 1;
|
||||
}
|
||||
}
|
||||
Delete(dq1);
|
||||
Delete(dq2);
|
||||
}
|
||||
}
|
||||
if (!differ) {
|
||||
if (!nodes[j].error) {
|
||||
if (script_lang_wrapping) {
|
||||
Swig_warning(WARN_LANG_OVERLOAD_SHADOW, Getfile(nodes[j].n), Getline(nodes[j].n),
|
||||
"Overloaded method %s effectively ignored,\n", Swig_name_decl(nodes[j].n));
|
||||
Swig_warning(WARN_LANG_OVERLOAD_SHADOW, Getfile(nodes[i].n), Getline(nodes[i].n),
|
||||
"as it is shadowed by %s.\n", Swig_name_decl(nodes[i].n));
|
||||
} else {
|
||||
if (!Getattr(nodes[j].n, "overload:ignore")) {
|
||||
Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n),
|
||||
"Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n));
|
||||
Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[i].n), Getline(nodes[i].n),
|
||||
"using %s instead.\n", Swig_name_decl(nodes[i].n));
|
||||
}
|
||||
}
|
||||
nodes[j].error = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
List *result = NewList();
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < nnodes; i++) {
|
||||
if (nodes[i].error)
|
||||
Setattr(nodes[i].n, "overload:ignore", "1");
|
||||
Append(result, nodes[i].n);
|
||||
// Printf(stdout,"[ %d ] %s\n", i, ParmList_errorstr(nodes[i].parms));
|
||||
// Swig_print_node(nodes[i].n);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/* end shameless borrowing */
|
||||
|
||||
int any_varargs(ParmList *pl) {
|
||||
Parm *p;
|
||||
|
||||
|
|
@ -2722,6 +2443,13 @@ int ALLEGROCL::functionWrapper(Node *n) {
|
|||
}
|
||||
}
|
||||
|
||||
/* See if there is any return cleanup code */
|
||||
if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
|
||||
Replaceall(tm, "$source", Swig_cresult_name());
|
||||
Printf(f->code, "%s\n", tm);
|
||||
Delete(tm);
|
||||
}
|
||||
|
||||
emit_return_variable(n, t, f);
|
||||
|
||||
if (CPlusPlus) {
|
||||
|
|
|
|||
|
|
@ -197,15 +197,17 @@ class Allocate:public Dispatcher {
|
|||
// Found a polymorphic method.
|
||||
// Mark the polymorphic method, in case the virtual keyword was not used.
|
||||
Setattr(n, "storage", "virtual");
|
||||
|
||||
if (both_have_public_access || both_have_protected_access) {
|
||||
if (!is_non_public_base(inclass, b))
|
||||
Setattr(n, "override", base); // Note C# definition of override, ie access must be the same
|
||||
} else if (!both_have_private_access) {
|
||||
// Different access
|
||||
if (this_wrapping_protected_members || base_wrapping_protected_members)
|
||||
if (!Getattr(b, "feature:interface")) { // interface implementation neither hides nor overrides
|
||||
if (both_have_public_access || both_have_protected_access) {
|
||||
if (!is_non_public_base(inclass, b))
|
||||
Setattr(n, "hides", base); // Note C# definition of hiding, ie hidden if access is different
|
||||
Setattr(n, "override", base); // Note C# definition of override, ie access must be the same
|
||||
}
|
||||
else if (!both_have_private_access) {
|
||||
// Different access
|
||||
if (this_wrapping_protected_members || base_wrapping_protected_members)
|
||||
if (!is_non_public_base(inclass, b))
|
||||
Setattr(n, "hides", base); // Note C# definition of hiding, ie hidden if access is different
|
||||
}
|
||||
}
|
||||
// Try and find the most base's covariant return type
|
||||
SwigType *most_base_covariant_type = Getattr(base, "covariant");
|
||||
|
|
@ -502,7 +504,7 @@ class Allocate:public Dispatcher {
|
|||
|
||||
in emit.cxx
|
||||
|
||||
and is either constructued from the "feature:catches" feature
|
||||
and is either constructed from the "feature:catches" feature
|
||||
or copied from the node "throws" list.
|
||||
*/
|
||||
String *scatchlist = Getattr(n, "feature:catches");
|
||||
|
|
|
|||
|
|
@ -543,6 +543,14 @@ int CFFI::functionWrapper(Node *n) {
|
|||
|
||||
cleanupFunction(n, f, parms);
|
||||
|
||||
/* See if there is any return cleanup code */
|
||||
String *tm = 0;
|
||||
if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
|
||||
Replaceall(tm, "$source", Swig_cresult_name());
|
||||
Printf(f->code, "%s\n", tm);
|
||||
Delete(tm);
|
||||
}
|
||||
|
||||
if (!is_void_return) {
|
||||
Printf(f->code, " return lresult;\n");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -547,7 +547,7 @@ int CHICKEN::functionWrapper(Node *n) {
|
|||
}
|
||||
emit_return_variable(n, d, f);
|
||||
|
||||
/* Insert the argumetn output code */
|
||||
/* Insert the argument output code */
|
||||
Printv(f->code, argout, NIL);
|
||||
|
||||
/* Output cleanup code */
|
||||
|
|
@ -1456,7 +1456,7 @@ String *CHICKEN::chickenPrimitiveName(String *name) {
|
|||
if (value)
|
||||
return value;
|
||||
else {
|
||||
Swig_error(input_file, line_number, "Internal Error: attempting to reference non-existant primitive name %s\n", name);
|
||||
Swig_error(input_file, line_number, "Internal Error: attempting to reference non-existent primitive name %s\n", name);
|
||||
return NewString("#f");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,8 +68,8 @@ class CSHARP:public Language {
|
|||
String *module_baseclass; //inheritance for module class from %pragma
|
||||
String *imclass_interfaces; //interfaces for intermediary class class from %pragma
|
||||
String *module_interfaces; //interfaces for module class from %pragma
|
||||
String *imclass_class_modifiers; //class modifiers for intermediary class overriden by %pragma
|
||||
String *module_class_modifiers; //class modifiers for module class overriden by %pragma
|
||||
String *imclass_class_modifiers; //class modifiers for intermediary class overridden by %pragma
|
||||
String *module_class_modifiers; //class modifiers for module class overridden by %pragma
|
||||
String *upcasts_code; //C++ casts for inheritance hierarchies C++ code
|
||||
String *imclass_cppcasts_code; //C++ casts up inheritance hierarchies intermediary class code
|
||||
String *director_callback_typedefs; // Director function pointer typedefs for callbacks
|
||||
|
|
@ -683,7 +683,7 @@ public:
|
|||
String *filen = NewStringf("%s%s.cs", dir, name);
|
||||
File *f = NewFile(filen, "w", SWIG_output_files());
|
||||
if (!f) {
|
||||
FileErrorDisplay(f);
|
||||
FileErrorDisplay(filen);
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
}
|
||||
Append(filenames_list, Copy(filen));
|
||||
|
|
@ -1384,7 +1384,7 @@ public:
|
|||
// Wrap C/C++ enums with constant integers or use the typesafe enum pattern
|
||||
SwigType *typemap_lookup_type = parent_name ? parent_name : NewString("enum ");
|
||||
Setattr(n, "type", typemap_lookup_type);
|
||||
const String *tm = typemapLookup(n, "cstype", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CSTYPE_UNDEF);
|
||||
const String *tm = typemapLookup(n, "cstype", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF);
|
||||
|
||||
String *return_type = Copy(tm);
|
||||
substituteClassname(typemap_lookup_type, return_type);
|
||||
|
|
@ -1584,11 +1584,23 @@ public:
|
|||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
virtual int insertDirective(Node *n) {
|
||||
int ret = SWIG_OK;
|
||||
String *code = Getattr(n, "code");
|
||||
String *section = Getattr(n, "section");
|
||||
Replaceall(code, "$module", module_class_name);
|
||||
Replaceall(code, "$imclassname", imclass_name);
|
||||
Replaceall(code, "$dllimport", dllimport);
|
||||
return Language::insertDirective(n);
|
||||
|
||||
if (!ImportMode && (Cmp(section, "proxycode") == 0)) {
|
||||
if (proxy_class_code) {
|
||||
Swig_typemap_replace_embedded_typemap(code, n);
|
||||
int offset = Len(code) > 0 && *Char(code) == '\n' ? 1 : 0;
|
||||
Printv(proxy_class_code, Char(code) + offset, "\n", NIL);
|
||||
}
|
||||
} else {
|
||||
ret = Language::insertDirective(n);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
|
|
@ -1720,7 +1732,7 @@ public:
|
|||
Replaceall(cptr_method_name, ".", "_");
|
||||
Replaceall(cptr_method_name, "$interfacename", interface_name);
|
||||
|
||||
String *upcast_method_name = Swig_name_member(getNSpace(), proxy_class_name, cptr_method_name);
|
||||
String *upcast_method_name = Swig_name_member(getNSpace(), getClassPrefix(), cptr_method_name);
|
||||
upcastsCode(smart, upcast_method_name, c_classname, c_baseclass);
|
||||
|
||||
Delete(upcast_method_name);
|
||||
|
|
@ -1861,46 +1873,70 @@ public:
|
|||
typemapLookup(n, "csbody", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CSBODY_UNDEF), // main body of class
|
||||
NIL);
|
||||
|
||||
// C++ destructor is wrapped by the Dispose method
|
||||
// Note that the method name is specified in a typemap attribute called methodname
|
||||
// C++ destructor is wrapped by the Finalize and Dispose methods
|
||||
|
||||
const char *tmap_method = derived ? "csdestruct_derived" : "csdestruct";
|
||||
const String *tm = typemapExists(n, tmap_method, typemap_lookup_type);
|
||||
if (tm) {
|
||||
Swig_error(Getfile(tm), Getline(tm),
|
||||
"A deprecated %s typemap was found for %s, please remove it and replace all csdestruct, csdestruct_derived and csfinalize typemaps by the csdispose, csdispose_derived, csdisposing and csdisposing_derived typemaps.\n",
|
||||
tmap_method, proxy_class_name);
|
||||
}
|
||||
tmap_method = "csfinalize";
|
||||
tm = typemapExists(n, tmap_method, typemap_lookup_type);
|
||||
if (tm) {
|
||||
Swig_error(Getfile(tm), Getline(tm),
|
||||
"A deprecated %s typemap was found for %s, please remove it and replace all csdestruct, csdestruct_derived and csfinalize typemaps by the csdispose, csdispose_derived, csdisposing and csdisposing_derived typemaps.\n",
|
||||
tmap_method, proxy_class_name);
|
||||
}
|
||||
|
||||
tmap_method = derived ? "csdisposing_derived" : "csdisposing";
|
||||
String *destruct = NewString("");
|
||||
const String *tm = NULL;
|
||||
attributes = NewHash();
|
||||
String *destruct_methodname = NULL;
|
||||
String *destruct_methodmodifiers = NULL;
|
||||
const String *destruct_methodname = NULL;
|
||||
const String *destruct_methodmodifiers = NULL;
|
||||
const String *destruct_parameters = NULL;
|
||||
if (derived) {
|
||||
tm = typemapLookup(n, "csdestruct_derived", typemap_lookup_type, WARN_NONE, attributes);
|
||||
destruct_methodname = Getattr(attributes, "tmap:csdestruct_derived:methodname");
|
||||
destruct_methodmodifiers = Getattr(attributes, "tmap:csdestruct_derived:methodmodifiers");
|
||||
tm = typemapLookup(n, "csdisposing_derived", typemap_lookup_type, WARN_NONE, attributes);
|
||||
destruct_methodname = Getattr(attributes, "tmap:csdisposing_derived:methodname");
|
||||
destruct_methodmodifiers = Getattr(attributes, "tmap:csdisposing_derived:methodmodifiers");
|
||||
destruct_parameters = Getattr(attributes, "tmap:csdisposing_derived:parameters");
|
||||
} else {
|
||||
tm = typemapLookup(n, "csdestruct", typemap_lookup_type, WARN_NONE, attributes);
|
||||
destruct_methodname = Getattr(attributes, "tmap:csdestruct:methodname");
|
||||
destruct_methodmodifiers = Getattr(attributes, "tmap:csdestruct:methodmodifiers");
|
||||
tm = typemapLookup(n, "csdisposing", typemap_lookup_type, WARN_NONE, attributes);
|
||||
destruct_methodname = Getattr(attributes, "tmap:csdisposing:methodname");
|
||||
destruct_methodmodifiers = Getattr(attributes, "tmap:csdisposing:methodmodifiers");
|
||||
destruct_parameters = Getattr(attributes, "tmap:csdisposing:parameters");
|
||||
}
|
||||
if (tm && *Char(tm)) {
|
||||
if (!destruct_methodname) {
|
||||
Swig_error(Getfile(n), Getline(n), "No methodname attribute defined in csdestruct%s typemap for %s\n", (derived ? "_derived" : ""), proxy_class_name);
|
||||
Swig_error(Getfile(n), Getline(n), "No methodname attribute defined in %s typemap for %s\n", tmap_method, proxy_class_name);
|
||||
}
|
||||
if (!destruct_methodmodifiers) {
|
||||
Swig_error(Getfile(n), Getline(n),
|
||||
"No methodmodifiers attribute defined in csdestruct%s typemap for %s.\n", (derived ? "_derived" : ""), proxy_class_name);
|
||||
"No methodmodifiers attribute defined in %s typemap for %s.\n", tmap_method, proxy_class_name);
|
||||
}
|
||||
if (!destruct_parameters)
|
||||
destruct_parameters = empty_string;
|
||||
}
|
||||
// Emit the Finalize and Dispose methods
|
||||
if (tm) {
|
||||
// Finalize method
|
||||
if (*Char(destructor_call)) {
|
||||
Printv(proxy_class_def, typemapLookup(n, "csfinalize", typemap_lookup_type, WARN_NONE), NIL);
|
||||
}
|
||||
// Dispose method
|
||||
// Finalize and Dispose methods
|
||||
Printv(proxy_class_def, typemapLookup(n, derived ? "csdispose_derived" : "csdispose", typemap_lookup_type, WARN_NONE), NIL);
|
||||
// Dispose(bool disposing) method
|
||||
Printv(destruct, tm, NIL);
|
||||
if (*Char(destructor_call))
|
||||
Replaceall(destruct, "$imcall", destructor_call);
|
||||
else
|
||||
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);
|
||||
if (*Char(destruct)) {
|
||||
Printv(proxy_class_def, "\n ", NIL);
|
||||
const String *methodmods = Getattr(n, "destructmethodmodifiers");
|
||||
if (methodmods)
|
||||
Printv(proxy_class_def, methodmods, NIL);
|
||||
else
|
||||
Printv(proxy_class_def, destruct_methodmodifiers, " ", derived ? "override" : "virtual", NIL);
|
||||
Printv(proxy_class_def, " void ", destruct_methodname, "(", destruct_parameters, ") ", destruct, "\n", NIL);
|
||||
}
|
||||
}
|
||||
if (*Char(interface_upcasts))
|
||||
Printv(proxy_class_def, interface_upcasts, NIL);
|
||||
|
|
@ -1917,7 +1953,7 @@ public:
|
|||
String *methid = Getattr(udata, "class_methodidx");
|
||||
String *overname = Getattr(udata, "overname");
|
||||
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);
|
||||
Printf(proxy_class_code, " swigDelegate%s = new SwigDelegate%s_%s(SwigDirectorMethod%s);\n", methid, proxy_class_name, methid, overname);
|
||||
}
|
||||
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);
|
||||
|
|
@ -2044,34 +2080,6 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* calculateDirectBase()
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
||||
void calculateDirectBase(Node* n) {
|
||||
Node* direct_base = 0;
|
||||
// C++ inheritance
|
||||
Node *attributes = NewHash();
|
||||
SwigType *typemap_lookup_type = Getattr(n, "classtypeobj");
|
||||
const String *pure_baseclass = typemapLookup(n, "csbase", typemap_lookup_type, WARN_NONE, attributes);
|
||||
bool purebase_replace = GetFlag(attributes, "tmap:csbase:replace") ? true : false;
|
||||
bool purebase_notderived = GetFlag(attributes, "tmap:csbase:notderived") ? true : false;
|
||||
Delete(attributes);
|
||||
if (!purebase_replace) {
|
||||
if (List *baselist = Getattr(n, "bases")) {
|
||||
Iterator base = First(baselist);
|
||||
while (base.item && (GetFlag(base.item, "feature:ignore") || Getattr(base.item, "feature:interface")))
|
||||
base = Next(base);
|
||||
direct_base = base.item;
|
||||
}
|
||||
if (!direct_base && purebase_notderived)
|
||||
direct_base = symbolLookup(const_cast<String*>(pure_baseclass));
|
||||
} else {
|
||||
direct_base = symbolLookup(const_cast<String*>(pure_baseclass));
|
||||
}
|
||||
Setattr(n, "direct_base", direct_base);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* classHandler()
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
|
@ -2157,7 +2165,6 @@ public:
|
|||
emitInterfaceDeclaration(n, interface_name, interface_class_code);
|
||||
Delete(output_directory);
|
||||
}
|
||||
calculateDirectBase(n);
|
||||
}
|
||||
|
||||
Language::classHandler(n);
|
||||
|
|
@ -2224,37 +2231,6 @@ public:
|
|||
--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:csdowncast")) {
|
||||
String *downcast_method = Swig_name_member(getNSpace(), proxy_class_name, "SWIGDowncast");
|
||||
String *wname = Swig_name_wrapper(downcast_method);
|
||||
|
||||
String *norm_name = SwigType_namestr(Getattr(n, "name"));
|
||||
|
||||
Printf(imclass_class_code, " public final static native %s %s(long cPtrBase, boolean cMemoryOwn);\n", proxy_class_name, downcast_method);
|
||||
|
||||
Wrapper *dcast_wrap = NewWrapper();
|
||||
|
||||
Printf(dcast_wrap->def, "SWIGEXPORT jobject SWIGSTDCALL %s(JNIEnv *jenv, jclass jcls, jlong jCPtrBase, jboolean cMemoryOwn) {", wname);
|
||||
Printf(dcast_wrap->code, " Swig::Director *director = (Swig::Director *) 0;\n");
|
||||
Printf(dcast_wrap->code, " jobject jresult = (jobject) 0;\n");
|
||||
Printf(dcast_wrap->code, " %s *obj = *((%s **)&jCPtrBase);\n", norm_name, norm_name);
|
||||
Printf(dcast_wrap->code, " if (obj) director = dynamic_cast<Swig::Director *>(obj);\n");
|
||||
Printf(dcast_wrap->code, " if (director) jresult = director->swig_get_self(jenv);\n");
|
||||
Printf(dcast_wrap->code, " return jresult;\n");
|
||||
Printf(dcast_wrap->code, "}\n");
|
||||
|
||||
Wrapper_print(dcast_wrap, f_wrappers);
|
||||
DelWrapper(dcast_wrap);
|
||||
|
||||
Delete(norm_name);
|
||||
Delete(wname);
|
||||
Delete(downcast_method);
|
||||
}
|
||||
|
||||
if (f_interface) {
|
||||
Printv(f_interface, interface_class_code, "}\n", NIL);
|
||||
addCloseNamespace(nspace, f_interface);
|
||||
|
|
@ -2426,21 +2402,8 @@ public:
|
|||
Printf(function_code, " %s ", methodmods);
|
||||
if (!is_smart_pointer()) {
|
||||
// Smart pointer classes do not mirror the inheritance hierarchy of the underlying pointer type, so no virtual/override/new required.
|
||||
if (Node *base_ovr = Getattr(n, "override")) {
|
||||
if (GetFlag(n, "isextendmember"))
|
||||
if (Getattr(n, "override"))
|
||||
Printf(function_code, "override ");
|
||||
else {
|
||||
Node* base = parentNode(base_ovr);
|
||||
bool ovr = false;
|
||||
for (Node* direct_base = Getattr(parentNode(n), "direct_base"); direct_base; direct_base = Getattr(direct_base, "direct_base")) {
|
||||
if (direct_base == base) { // "override" only applies if the base was not discarded (e.g. in case of multiple inheritance or via "ignore")
|
||||
ovr = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Printf(function_code, ovr ? "override " : "virtual ");
|
||||
}
|
||||
}
|
||||
else if (checkAttribute(n, "storage", "virtual"))
|
||||
Printf(function_code, "virtual ");
|
||||
if (Getattr(n, "hides"))
|
||||
|
|
@ -2843,7 +2806,8 @@ public:
|
|||
|
||||
/* Insert the csconstruct typemap, doing the replacement for $directorconnect, as needed */
|
||||
Hash *attributes = NewHash();
|
||||
String *construct_tm = Copy(typemapLookup(n, "csconstruct", Getattr(n, "name"),
|
||||
String *typemap_lookup_type = Getattr(getCurrentClass(), "classtypeobj");
|
||||
String *construct_tm = Copy(typemapLookup(n, "csconstruct", typemap_lookup_type,
|
||||
WARN_CSHARP_TYPEMAP_CSCONSTRUCT_UNDEF, attributes));
|
||||
if (construct_tm) {
|
||||
if (!feature_director) {
|
||||
|
|
@ -2921,7 +2885,11 @@ public:
|
|||
|
||||
if (proxy_flag) {
|
||||
Printv(destructor_call, full_imclass_name, ".", Swig_name_destroy(getNSpace(), symname), "(swigCPtr)", NIL);
|
||||
const String *methodmods = Getattr(n, "feature:cs:methodmodifiers");
|
||||
if (methodmods)
|
||||
Setattr(getCurrentClass(), "destructmethodmodifiers", methodmods);
|
||||
}
|
||||
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
|
|
@ -3602,6 +3570,24 @@ public:
|
|||
return tm;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* typemapExists()
|
||||
* n - for input only and must contain info for Getfile(n) and Getline(n) to work
|
||||
* tmap_method - typemap method name
|
||||
* type - typemap type to lookup
|
||||
* returns found typemap or NULL if not found
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
const String *typemapExists(Node *n, const_String_or_char_ptr tmap_method, SwigType *type) {
|
||||
Node *node = NewHash();
|
||||
Setattr(node, "type", type);
|
||||
Setfile(node, Getfile(n));
|
||||
Setline(node, Getline(n));
|
||||
const String *tm = Swig_typemap_lookup(tmap_method, node, "", 0);
|
||||
Delete(node);
|
||||
return tm;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* canThrow()
|
||||
* Determine whether the code in the typemap can throw a C# exception.
|
||||
|
|
@ -3764,16 +3750,13 @@ public:
|
|||
Printf(code_wrap->code, " %s *obj = (%s *)objarg;\n", smartptr, smartptr);
|
||||
Printf(code_wrap->code, " // Keep a local instance of the smart pointer around while we are using the raw pointer\n");
|
||||
Printf(code_wrap->code, " // Avoids using smart pointer specific API.\n");
|
||||
Printf(code_wrap->code, " %s *director = dynamic_cast<%s *>(obj->operator->());\n", dirClassName, dirClassName);
|
||||
}
|
||||
else {
|
||||
Printf(code_wrap->code, " %s *director = static_cast<%s *>(obj->operator->());\n", dirClassName, dirClassName);
|
||||
} else {
|
||||
Printf(code_wrap->code, " %s *obj = (%s *)objarg;\n", norm_name, norm_name);
|
||||
Printf(code_wrap->code, " %s *director = dynamic_cast<%s *>(obj);\n", dirClassName, dirClassName);
|
||||
Printf(code_wrap->code, " %s *director = static_cast<%s *>(obj);\n", dirClassName, dirClassName);
|
||||
}
|
||||
|
||||
// TODO: if statement not needed?? - Java too
|
||||
Printf(code_wrap->code, " if (director) {\n");
|
||||
Printf(code_wrap->code, " director->swig_connect_director(");
|
||||
Printf(code_wrap->code, " director->swig_connect_director(");
|
||||
|
||||
for (int i = first_class_dmethod; i < curr_class_dmethod; ++i) {
|
||||
UpcallData *udata = Getitem(dmethods_seq, i);
|
||||
|
|
@ -3790,7 +3773,6 @@ public:
|
|||
Printf(code_wrap->def, ") {\n");
|
||||
Printf(code_wrap->code, ");\n");
|
||||
Printf(imclass_class_code, ");\n");
|
||||
Printf(code_wrap->code, " }\n");
|
||||
Printf(code_wrap->code, "}\n");
|
||||
|
||||
Wrapper_print(code_wrap, f_wrappers);
|
||||
|
|
@ -3856,7 +3838,7 @@ public:
|
|||
|
||||
qualified_return = SwigType_rcaststr(returntype, "c_result");
|
||||
|
||||
if (!is_void && !ignored_method) {
|
||||
if (!is_void && (!ignored_method || pure_virtual)) {
|
||||
if (!SwigType_isclass(returntype)) {
|
||||
if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) {
|
||||
String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(returntype, 0));
|
||||
|
|
@ -3876,15 +3858,17 @@ public:
|
|||
/* If returning a reference, initialize the pointer to a sane
|
||||
default - if a C# exception occurs, then the pointer returns
|
||||
something other than a NULL-initialized reference. */
|
||||
String *non_ref_type = Copy(returntype);
|
||||
SwigType *noref_type = SwigType_del_reference(Copy(returntype));
|
||||
String *noref_ltype = SwigType_lstr(noref_type, 0);
|
||||
String *return_ltype = SwigType_lstr(returntype, 0);
|
||||
|
||||
/* Remove reference and const qualifiers */
|
||||
Replaceall(non_ref_type, "r.", "");
|
||||
Replaceall(non_ref_type, "q(const).", "");
|
||||
Wrapper_add_localv(w, "result_default", "static", SwigType_str(non_ref_type, "result_default"), "=", SwigType_str(non_ref_type, "()"), NIL);
|
||||
Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= &result_default", NIL);
|
||||
|
||||
Delete(non_ref_type);
|
||||
Wrapper_add_localv(w, "result_default", "static", noref_ltype, "result_default", NIL);
|
||||
Wrapper_add_localv(w, "c_result", return_ltype, "c_result", NIL);
|
||||
Printf(w->code, "result_default = SwigValueInit< %s >();\n", noref_ltype);
|
||||
Printf(w->code, "c_result = &result_default;\n");
|
||||
Delete(return_ltype);
|
||||
Delete(noref_ltype);
|
||||
Delete(noref_type);
|
||||
}
|
||||
|
||||
Delete(base_typename);
|
||||
|
|
@ -3916,9 +3900,13 @@ public:
|
|||
Printf(director_delegate_definitions, " %s\n", im_directoroutattributes);
|
||||
}
|
||||
|
||||
Printf(callback_def, " private %s SwigDirector%s(", tm, overloaded_name);
|
||||
if (!ignored_method)
|
||||
Printf(director_delegate_definitions, " public delegate %s", tm);
|
||||
Printf(callback_def, " private %s SwigDirectorMethod%s(", tm, overloaded_name);
|
||||
if (!ignored_method) {
|
||||
const String *csdirectordelegatemodifiers = Getattr(n, "feature:csdirectordelegatemodifiers");
|
||||
String *modifiers = (csdirectordelegatemodifiers ? NewStringf("%s%s", csdirectordelegatemodifiers, Len(csdirectordelegatemodifiers) > 0 ? " " : "") : NewStringf("public "));
|
||||
Printf(director_delegate_definitions, " %sdelegate %s", modifiers, tm);
|
||||
Delete(modifiers);
|
||||
}
|
||||
} else {
|
||||
Swig_warning(WARN_CSHARP_TYPEMAP_CSTYPE_UNDEF, input_file, line_number, "No imtype typemap defined for %s\n", SwigType_str(returntype, 0));
|
||||
}
|
||||
|
|
@ -3942,7 +3930,7 @@ public:
|
|||
Swig_typemap_attach_parms("ctype", l, 0);
|
||||
Swig_typemap_attach_parms("imtype", l, 0);
|
||||
Swig_typemap_attach_parms("cstype", l, 0);
|
||||
Swig_typemap_attach_parms("directorin", l, 0);
|
||||
Swig_typemap_attach_parms("directorin", l, w);
|
||||
Swig_typemap_attach_parms("csdirectorin", l, 0);
|
||||
Swig_typemap_attach_parms("directorargout", l, w);
|
||||
|
||||
|
|
@ -3961,7 +3949,11 @@ public:
|
|||
}
|
||||
Delete(super_call);
|
||||
} else {
|
||||
Printf(w->code, " throw Swig::DirectorPureVirtualException(\"%s::%s\");\n", SwigType_namestr(c_classname), SwigType_namestr(name));
|
||||
Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"%s::%s\");\n", SwigType_namestr(c_classname), SwigType_namestr(name));
|
||||
if (!is_void)
|
||||
Printf(w->code, "return %s;", qualified_return);
|
||||
else if (!ignored_method)
|
||||
Printf(w->code, "return;\n");
|
||||
}
|
||||
|
||||
if (!ignored_method)
|
||||
|
|
@ -4119,15 +4111,19 @@ public:
|
|||
/* header declaration, start wrapper definition */
|
||||
String *target;
|
||||
SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type");
|
||||
target = Swig_method_decl(rtype, decl, qualified_name, l, 0, 0);
|
||||
target = Swig_method_decl(rtype, decl, qualified_name, l, 0);
|
||||
Printf(w->def, "%s", target);
|
||||
Delete(qualified_name);
|
||||
Delete(target);
|
||||
target = Swig_method_decl(rtype, decl, name, l, 0, 1);
|
||||
target = Swig_method_decl(rtype, decl, name, l, 1);
|
||||
Printf(declaration, " virtual %s", target);
|
||||
Delete(target);
|
||||
|
||||
// Add any exception specifications to the methods in the director class
|
||||
if (Getattr(n, "noexcept")) {
|
||||
Append(w->def, " noexcept");
|
||||
Append(declaration, " noexcept");
|
||||
}
|
||||
ParmList *throw_parm_list = NULL;
|
||||
if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) {
|
||||
int gencomma = 0;
|
||||
|
|
@ -4336,7 +4332,7 @@ public:
|
|||
/* constructor */
|
||||
{
|
||||
String *basetype = Getattr(parent, "classtype");
|
||||
String *target = Swig_method_decl(0, decl, dirclassname, parms, 0, 0);
|
||||
String *target = Swig_method_decl(0, decl, dirclassname, parms, 0);
|
||||
String *call = Swig_csuperclass_call(0, basetype, superparms);
|
||||
|
||||
Printf(f_directors, "%s::%s : %s, %s {\n", dirclassname, target, call, Getattr(parent, "director:ctor"));
|
||||
|
|
@ -4349,7 +4345,7 @@ public:
|
|||
|
||||
/* constructor header */
|
||||
{
|
||||
String *target = Swig_method_decl(0, decl, dirclassname, parms, 0, 1);
|
||||
String *target = Swig_method_decl(0, decl, dirclassname, parms, 1);
|
||||
Printf(f_directors_h, " %s;\n", target);
|
||||
Delete(target);
|
||||
}
|
||||
|
|
@ -4445,9 +4441,12 @@ public:
|
|||
String *dirclassname = directorClassName(current_class);
|
||||
Wrapper *w = NewWrapper();
|
||||
|
||||
if (Getattr(n, "throw")) {
|
||||
Printf(f_directors_h, " virtual ~%s() throw ();\n", dirclassname);
|
||||
Printf(w->def, "%s::~%s() throw () {\n", dirclassname, dirclassname);
|
||||
if (Getattr(n, "noexcept")) {
|
||||
Printf(f_directors_h, " virtual ~%s() noexcept;\n", dirclassname);
|
||||
Printf(w->def, "%s::~%s() noexcept {\n", dirclassname, dirclassname);
|
||||
} else if (Getattr(n, "throw")) {
|
||||
Printf(f_directors_h, " virtual ~%s() throw();\n", dirclassname);
|
||||
Printf(w->def, "%s::~%s() throw() {\n", dirclassname, dirclassname);
|
||||
} else {
|
||||
Printf(f_directors_h, " virtual ~%s();\n", dirclassname);
|
||||
Printf(w->def, "%s::~%s() {\n", dirclassname, dirclassname);
|
||||
|
|
|
|||
|
|
@ -717,9 +717,20 @@ public:
|
|||
* D::insertDirective()
|
||||
* --------------------------------------------------------------------------- */
|
||||
virtual int insertDirective(Node *n) {
|
||||
int ret = SWIG_OK;
|
||||
String *code = Getattr(n, "code");
|
||||
String *section = Getattr(n, "section");
|
||||
replaceModuleVariables(code);
|
||||
return Language::insertDirective(n);
|
||||
|
||||
if (!ImportMode && (Cmp(section, "proxycode") == 0)) {
|
||||
if (proxy_class_body_code) {
|
||||
Swig_typemap_replace_embedded_typemap(code, n);
|
||||
Printv(proxy_class_body_code, code, NIL);
|
||||
}
|
||||
} else {
|
||||
ret = Language::insertDirective(n);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------------
|
||||
|
|
@ -978,7 +989,7 @@ public:
|
|||
// Smart pointer classes do not mirror the inheritance hierarchy of the
|
||||
// underlying types, so aliasing the base class methods in is not required
|
||||
// for them.
|
||||
// DMD BUG: We have to emit the alias after the last function becasue
|
||||
// DMD BUG: We have to emit the alias after the last function because
|
||||
// taking a delegate in the overload checking code fails otherwise
|
||||
// (http://d.puremagic.com/issues/show_bug.cgi?id=4860).
|
||||
if (!Getattr(n, "sym:nextSibling") && !is_smart_pointer() &&
|
||||
|
|
@ -1216,8 +1227,9 @@ public:
|
|||
|
||||
// Insert the dconstructor typemap (replacing $directorconnect as needed).
|
||||
Hash *attributes = NewHash();
|
||||
String *typemap_lookup_type = Getattr(getCurrentClass(), "classtypeobj");
|
||||
String *construct_tm = Copy(lookupCodeTypemap(n, "dconstructor",
|
||||
Getattr(n, "name"), WARN_D_TYPEMAP_DCONSTRUCTOR_UNDEF, attributes));
|
||||
typemap_lookup_type, WARN_D_TYPEMAP_DCONSTRUCTOR_UNDEF, attributes));
|
||||
if (construct_tm) {
|
||||
const bool use_director = (parentNode(n) && Swig_directorclass(n));
|
||||
if (!use_director) {
|
||||
|
|
@ -1287,7 +1299,12 @@ public:
|
|||
virtual int destructorHandler(Node *n) {
|
||||
Language::destructorHandler(n);
|
||||
String *symname = Getattr(n, "sym:name");
|
||||
|
||||
Printv(destructor_call, im_dmodule_fq_name, ".", Swig_name_destroy(getNSpace(),symname), "(cast(void*)swigCPtr)", NIL);
|
||||
const String *methodmods = Getattr(n, "feature:d:methodmodifiers");
|
||||
if (methodmods)
|
||||
Setattr(getCurrentClass(), "destructmethodmodifiers", methodmods);
|
||||
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
|
|
@ -1465,7 +1482,7 @@ public:
|
|||
}
|
||||
Delete(attributes);
|
||||
|
||||
// Retrive the override value set via %dconstvalue, if any.
|
||||
// Retrieve the override value set via %dconstvalue, if any.
|
||||
String *override_value = Getattr(n, "feature:d:constvalue");
|
||||
if (override_value) {
|
||||
Printf(constants_code, "%s;\n", override_value);
|
||||
|
|
@ -1964,7 +1981,7 @@ public:
|
|||
|
||||
qualified_return = SwigType_rcaststr(returntype, "c_result");
|
||||
|
||||
if (!is_void && !ignored_method) {
|
||||
if (!is_void && (!ignored_method || pure_virtual)) {
|
||||
if (!SwigType_isclass(returntype)) {
|
||||
if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) {
|
||||
String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(returntype, 0));
|
||||
|
|
@ -1984,15 +2001,17 @@ public:
|
|||
/* If returning a reference, initialize the pointer to a sane
|
||||
default - if a D exception occurs, then the pointer returns
|
||||
something other than a NULL-initialized reference. */
|
||||
String *non_ref_type = Copy(returntype);
|
||||
SwigType *noref_type = SwigType_del_reference(Copy(returntype));
|
||||
String *noref_ltype = SwigType_lstr(noref_type, 0);
|
||||
String *return_ltype = SwigType_lstr(returntype, 0);
|
||||
|
||||
/* Remove reference and const qualifiers */
|
||||
Replaceall(non_ref_type, "r.", "");
|
||||
Replaceall(non_ref_type, "q(const).", "");
|
||||
Wrapper_add_localv(w, "result_default", "static", SwigType_str(non_ref_type, "result_default"), "=", SwigType_str(non_ref_type, "()"), NIL);
|
||||
Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= &result_default", NIL);
|
||||
|
||||
Delete(non_ref_type);
|
||||
Wrapper_add_localv(w, "result_default", "static", noref_ltype, "result_default", NIL);
|
||||
Wrapper_add_localv(w, "c_result", return_ltype, "c_result", NIL);
|
||||
Printf(w->code, "result_default = SwigValueInit< %s >();\n", noref_ltype);
|
||||
Printf(w->code, "c_result = &result_default;\n");
|
||||
Delete(return_ltype);
|
||||
Delete(noref_ltype);
|
||||
Delete(noref_type);
|
||||
}
|
||||
|
||||
Delete(base_typename);
|
||||
|
|
@ -2047,7 +2066,7 @@ public:
|
|||
Swig_typemap_attach_parms("ctype", l, 0);
|
||||
Swig_typemap_attach_parms("imtype", l, 0);
|
||||
Swig_typemap_attach_parms("dtype", l, 0);
|
||||
Swig_typemap_attach_parms("directorin", l, 0);
|
||||
Swig_typemap_attach_parms("directorin", l, w);
|
||||
Swig_typemap_attach_parms("ddirectorin", l, 0);
|
||||
Swig_typemap_attach_parms("directorargout", l, w);
|
||||
|
||||
|
|
@ -2066,7 +2085,11 @@ public:
|
|||
}
|
||||
Delete(super_call);
|
||||
} else {
|
||||
Printf(w->code, " throw Swig::DirectorPureVirtualException(\"%s::%s\");\n", SwigType_namestr(c_classname), SwigType_namestr(name));
|
||||
Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"%s::%s\");\n", SwigType_namestr(c_classname), SwigType_namestr(name));
|
||||
if (!is_void)
|
||||
Printf(w->code, "return %s;", qualified_return);
|
||||
else if (!ignored_method)
|
||||
Printf(w->code, "return;\n");
|
||||
}
|
||||
|
||||
if (!ignored_method)
|
||||
|
|
@ -2197,15 +2220,19 @@ public:
|
|||
/* header declaration, start wrapper definition */
|
||||
String *target;
|
||||
SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type");
|
||||
target = Swig_method_decl(rtype, decl, qualified_name, l, 0, 0);
|
||||
target = Swig_method_decl(rtype, decl, qualified_name, l, 0);
|
||||
Printf(w->def, "%s", target);
|
||||
Delete(qualified_name);
|
||||
Delete(target);
|
||||
target = Swig_method_decl(rtype, decl, name, l, 0, 1);
|
||||
target = Swig_method_decl(rtype, decl, name, l, 1);
|
||||
Printf(declaration, " virtual %s", target);
|
||||
Delete(target);
|
||||
|
||||
// Add any exception specifications to the methods in the director class
|
||||
if (Getattr(n, "noexcept")) {
|
||||
Append(w->def, " noexcept");
|
||||
Append(declaration, " noexcept");
|
||||
}
|
||||
ParmList *throw_parm_list = NULL;
|
||||
if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) {
|
||||
int gencomma = 0;
|
||||
|
|
@ -2417,7 +2444,7 @@ public:
|
|||
/* constructor */
|
||||
{
|
||||
String *basetype = Getattr(parent, "classtype");
|
||||
String *target = Swig_method_decl(0, decl, dirclassname, parms, 0, 0);
|
||||
String *target = Swig_method_decl(0, decl, dirclassname, parms, 0);
|
||||
String *call = Swig_csuperclass_call(0, basetype, superparms);
|
||||
String *classtype = SwigType_namestr(Getattr(n, "name"));
|
||||
|
||||
|
|
@ -2432,7 +2459,7 @@ public:
|
|||
|
||||
/* constructor header */
|
||||
{
|
||||
String *target = Swig_method_decl(0, decl, dirclassname, parms, 0, 1);
|
||||
String *target = Swig_method_decl(0, decl, dirclassname, parms, 1);
|
||||
Printf(f_directors_h, " %s;\n", target);
|
||||
Delete(target);
|
||||
}
|
||||
|
|
@ -2472,9 +2499,12 @@ public:
|
|||
String *dirclassname = directorClassName(current_class);
|
||||
Wrapper *w = NewWrapper();
|
||||
|
||||
if (Getattr(n, "throw")) {
|
||||
Printf(f_directors_h, " virtual ~%s() throw ();\n", dirclassname);
|
||||
Printf(w->def, "%s::~%s() throw () {\n", dirclassname, dirclassname);
|
||||
if (Getattr(n, "noexcept")) {
|
||||
Printf(f_directors_h, " virtual ~%s() noexcept;\n", dirclassname);
|
||||
Printf(w->def, "%s::~%s() noexcept {\n", dirclassname, dirclassname);
|
||||
} else if (Getattr(n, "throw")) {
|
||||
Printf(f_directors_h, " virtual ~%s() throw();\n", dirclassname);
|
||||
Printf(w->def, "%s::~%s() throw() {\n", dirclassname, dirclassname);
|
||||
} else {
|
||||
Printf(f_directors_h, " virtual ~%s();\n", dirclassname);
|
||||
Printf(w->def, "%s::~%s() {\n", dirclassname, dirclassname);
|
||||
|
|
@ -3244,17 +3274,20 @@ private:
|
|||
// attribute called »methodname«.
|
||||
const String *tm = NULL;
|
||||
|
||||
String *dispose_methodname;
|
||||
String *dispose_methodmodifiers;
|
||||
const String *dispose_methodname;
|
||||
const String *dispose_methodmodifiers;
|
||||
const String *dispose_parameters;
|
||||
attributes = NewHash();
|
||||
if (derived) {
|
||||
tm = lookupCodeTypemap(n, "ddispose_derived", typemap_lookup_type, WARN_NONE, attributes);
|
||||
dispose_methodname = Getattr(attributes, "tmap:ddispose_derived:methodname");
|
||||
dispose_methodmodifiers = Getattr(attributes, "tmap:ddispose_derived:methodmodifiers");
|
||||
dispose_parameters = Getattr(attributes, "tmap:ddispose_derived:parameters");
|
||||
} else {
|
||||
tm = lookupCodeTypemap(n, "ddispose", typemap_lookup_type, WARN_NONE, attributes);
|
||||
dispose_methodname = Getattr(attributes, "tmap:ddispose:methodname");
|
||||
dispose_methodmodifiers = Getattr(attributes, "tmap:ddispose:methodmodifiers");
|
||||
dispose_parameters = Getattr(attributes, "tmap:ddispose:parameters");
|
||||
}
|
||||
|
||||
if (tm && *Char(tm)) {
|
||||
|
|
@ -3268,6 +3301,8 @@ private:
|
|||
"No methodmodifiers attribute defined in ddispose%s typemap for %s.\n",
|
||||
(derived ? "_derived" : ""), proxy_class_name);
|
||||
}
|
||||
if (!dispose_parameters)
|
||||
dispose_parameters = empty_string;
|
||||
}
|
||||
|
||||
if (tm) {
|
||||
|
|
@ -3288,9 +3323,13 @@ private:
|
|||
}
|
||||
|
||||
if (*Char(dispose_code)) {
|
||||
Printv(body, "\n", dispose_methodmodifiers,
|
||||
(derived ? " override" : ""), " void ", dispose_methodname, "() ",
|
||||
dispose_code, "\n", NIL);
|
||||
Printv(body, "\n", NIL);
|
||||
const String *methodmods = Getattr(n, "destructmethodmodifiers");
|
||||
if (methodmods)
|
||||
Printv(body, methodmods, NIL);
|
||||
else
|
||||
Printv(body, dispose_methodmodifiers, (derived ? " override" : ""), NIL);
|
||||
Printv(body, " void ", dispose_methodname, "(", dispose_parameters, ") ", dispose_code, "\n", NIL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3545,10 +3584,9 @@ private:
|
|||
Printf(code_wrap->def, "SWIGEXPORT void D_%s(void *objarg, void *dobj", connect_name);
|
||||
|
||||
Printf(code_wrap->code, " %s *obj = (%s *)objarg;\n", norm_name, norm_name);
|
||||
Printf(code_wrap->code, " %s *director = dynamic_cast<%s *>(obj);\n", dirClassName, dirClassName);
|
||||
Printf(code_wrap->code, " %s *director = static_cast<%s *>(obj);\n", dirClassName, dirClassName);
|
||||
|
||||
Printf(code_wrap->code, " if (director) {\n");
|
||||
Printf(code_wrap->code, " director->swig_connect_director(dobj");
|
||||
Printf(code_wrap->code, " director->swig_connect_director(dobj");
|
||||
|
||||
for (int i = first_class_dmethod; i < curr_class_dmethod; ++i) {
|
||||
UpcallData *udata = Getitem(dmethods_seq, i);
|
||||
|
|
@ -3562,7 +3600,6 @@ private:
|
|||
Printf(code_wrap->def, ") {\n");
|
||||
Printf(code_wrap->code, ");\n");
|
||||
Printf(im_dmodule_code, ") %s;\n", connect_name);
|
||||
Printf(code_wrap->code, " }\n");
|
||||
Printf(code_wrap->code, "}\n");
|
||||
|
||||
Wrapper_print(code_wrap, f_wrappers);
|
||||
|
|
@ -4321,7 +4358,7 @@ private:
|
|||
*
|
||||
* Determines whether the class the passed function node belongs to overrides
|
||||
* all the overlaods for the passed function node defined somewhere up the
|
||||
* inheritance hierachy.
|
||||
* inheritance hierarchy.
|
||||
* --------------------------------------------------------------------------- */
|
||||
bool areAllOverloadsOverridden(Node *n) const {
|
||||
List *base_list = Getattr(parentNode(n), "bases");
|
||||
|
|
@ -4346,7 +4383,7 @@ private:
|
|||
}
|
||||
|
||||
// We try to find at least a single overload which exists in the base class
|
||||
// so we can progress up the inheritance hierachy even if there have been
|
||||
// so we can progress up the inheritance hierarchy even if there have been
|
||||
// new overloads introduced after the topmost class.
|
||||
Node *base_function = NULL;
|
||||
String *symname = Getattr(n, "sym:name");
|
||||
|
|
@ -4372,7 +4409,7 @@ private:
|
|||
!(Swig_director_mode() && Swig_director_protected_mode() && Swig_all_protected_mode())) {
|
||||
// If the base class function is »protected« and were are not in
|
||||
// director mode, it is not emitted to the base class and thus we do
|
||||
// not count it. Otherwise, we would run into issues if the visiblity
|
||||
// not count it. Otherwise, we would run into issues if the visibility
|
||||
// of some functions was changed from protected to public in a child
|
||||
// class with the using directive.
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -15,12 +15,12 @@
|
|||
|
||||
#include "swigmod.h"
|
||||
|
||||
/* Swig_csuperclass_call()
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_csuperclass_call()
|
||||
*
|
||||
* Generates a fully qualified method call, including the full parameter list.
|
||||
* e.g. "base::method(i, j)"
|
||||
*
|
||||
*/
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
String *Swig_csuperclass_call(String *base, String *method, ParmList *l) {
|
||||
String *call = NewString("");
|
||||
|
|
@ -44,12 +44,12 @@ String *Swig_csuperclass_call(String *base, String *method, ParmList *l) {
|
|||
return call;
|
||||
}
|
||||
|
||||
/* Swig_class_declaration()
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_class_declaration()
|
||||
*
|
||||
* Generate the start of a class/struct declaration.
|
||||
* e.g. "class myclass"
|
||||
*
|
||||
*/
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
String *Swig_class_declaration(Node *n, String *name) {
|
||||
if (!name) {
|
||||
|
|
@ -61,18 +61,22 @@ String *Swig_class_declaration(Node *n, String *name) {
|
|||
return result;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_class_name()
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
String *Swig_class_name(Node *n) {
|
||||
String *name;
|
||||
name = Copy(Getattr(n, "sym:name"));
|
||||
return name;
|
||||
}
|
||||
|
||||
/* Swig_director_declaration()
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_director_declaration()
|
||||
*
|
||||
* Generate the full director class declaration, complete with base classes.
|
||||
* e.g. "class SwigDirector_myclass : public myclass, public Swig::Director {"
|
||||
*
|
||||
*/
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
String *Swig_director_declaration(Node *n) {
|
||||
String *classname = Swig_class_name(n);
|
||||
|
|
@ -87,6 +91,10 @@ String *Swig_director_declaration(Node *n) {
|
|||
}
|
||||
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_method_call()
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
String *Swig_method_call(const_String_or_char_ptr name, ParmList *parms) {
|
||||
String *func;
|
||||
int i = 0;
|
||||
|
|
@ -115,153 +123,67 @@ String *Swig_method_call(const_String_or_char_ptr name, ParmList *parms) {
|
|||
return func;
|
||||
}
|
||||
|
||||
/* Swig_method_decl
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_method_decl()
|
||||
*
|
||||
* Misnamed and misappropriated! Taken from SWIG's type string manipulation utilities
|
||||
* and modified to generate full (or partial) type qualifiers for method declarations,
|
||||
* local variable declarations, and return value casting. More importantly, it merges
|
||||
* parameter type information with actual parameter names to produce a complete method
|
||||
* declaration that fully mirrors the original method declaration.
|
||||
*
|
||||
* There is almost certainly a saner way to do this.
|
||||
*
|
||||
* This function needs to be cleaned up and possibly split into several smaller
|
||||
* functions. For instance, attaching default names to parameters should be done in a
|
||||
* separate function.
|
||||
*
|
||||
*/
|
||||
* Return a stringified version of a C/C++ declaration.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
String *Swig_method_decl(SwigType *rettype, SwigType *decl, const_String_or_char_ptr id, List *args, int strip, int values) {
|
||||
String *result;
|
||||
List *elements;
|
||||
String *element = 0, *nextelement;
|
||||
int is_const = 0;
|
||||
int nelements, i;
|
||||
int is_func = 0;
|
||||
String *Swig_method_decl(SwigType *return_base_type, SwigType *decl, const_String_or_char_ptr id, List *args, int default_args) {
|
||||
String *result = NewString("");
|
||||
bool conversion_operator = Strstr(id, "operator ") != 0 && !return_base_type;
|
||||
|
||||
Parm *parm = args;
|
||||
int arg_idx = 0;
|
||||
|
||||
if (id) {
|
||||
result = NewString(Char(id));
|
||||
} else {
|
||||
result = NewString("");
|
||||
}
|
||||
|
||||
elements = SwigType_split(decl);
|
||||
nelements = Len(elements);
|
||||
if (nelements > 0) {
|
||||
element = Getitem(elements, 0);
|
||||
}
|
||||
for (i = 0; i < nelements; i++) {
|
||||
if (i < (nelements - 1)) {
|
||||
nextelement = Getitem(elements, i + 1);
|
||||
} else {
|
||||
nextelement = 0;
|
||||
while (parm) {
|
||||
String *type = Getattr(parm, "type");
|
||||
String *name = Getattr(parm, "name");
|
||||
if (!name && Cmp(type, "void")) {
|
||||
name = NewString("");
|
||||
Printf(name, "arg%d", arg_idx++);
|
||||
Setattr(parm, "name", name);
|
||||
}
|
||||
if (SwigType_isqualifier(element)) {
|
||||
int skip = 0;
|
||||
DOH *q = 0;
|
||||
if (!strip) {
|
||||
q = SwigType_parm(element);
|
||||
if (!Cmp(q, "const")) {
|
||||
is_const = 1;
|
||||
is_func = SwigType_isfunction(nextelement);
|
||||
if (is_func)
|
||||
skip = 1;
|
||||
skip = 1;
|
||||
}
|
||||
if (!skip) {
|
||||
Insert(result, 0, " ");
|
||||
Insert(result, 0, q);
|
||||
}
|
||||
Delete(q);
|
||||
}
|
||||
} else if (SwigType_isfunction(element)) {
|
||||
Parm *parm;
|
||||
String *p;
|
||||
Append(result, "(");
|
||||
parm = args;
|
||||
while (parm != 0) {
|
||||
String *type = Getattr(parm, "type");
|
||||
String *name = Getattr(parm, "name");
|
||||
if (!name && Cmp(type, "void")) {
|
||||
name = NewString("");
|
||||
Printf(name, "arg%d", arg_idx++);
|
||||
Setattr(parm, "name", name);
|
||||
}
|
||||
if (!name) {
|
||||
name = NewString("");
|
||||
}
|
||||
p = SwigType_str(type, name);
|
||||
Append(result, p);
|
||||
String *value = Getattr(parm, "value");
|
||||
if (values && (value != 0)) {
|
||||
Printf(result, " = %s", value);
|
||||
}
|
||||
parm = nextSibling(parm);
|
||||
if (parm != 0)
|
||||
Append(result, ", ");
|
||||
}
|
||||
Append(result, ")");
|
||||
} else if (rettype) { // This check is intended for conversion operators to a pointer/reference which needs the pointer/reference ignoring in the declaration
|
||||
if (SwigType_ispointer(element)) {
|
||||
Insert(result, 0, "*");
|
||||
if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) {
|
||||
Insert(result, 0, "(");
|
||||
Append(result, ")");
|
||||
}
|
||||
} else if (SwigType_ismemberpointer(element)) {
|
||||
String *q;
|
||||
q = SwigType_parm(element);
|
||||
Insert(result, 0, "::*");
|
||||
Insert(result, 0, q);
|
||||
if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) {
|
||||
Insert(result, 0, "(");
|
||||
Append(result, ")");
|
||||
}
|
||||
Delete(q);
|
||||
} else if (SwigType_isreference(element)) {
|
||||
Insert(result, 0, "&");
|
||||
} else if (SwigType_isarray(element)) {
|
||||
DOH *size;
|
||||
Append(result, "[");
|
||||
size = SwigType_parm(element);
|
||||
Append(result, size);
|
||||
Append(result, "]");
|
||||
Delete(size);
|
||||
} else {
|
||||
if (Strcmp(element, "v(...)") == 0) {
|
||||
Insert(result, 0, "...");
|
||||
} else {
|
||||
String *bs = SwigType_namestr(element);
|
||||
Insert(result, 0, " ");
|
||||
Insert(result, 0, bs);
|
||||
Delete(bs);
|
||||
}
|
||||
}
|
||||
}
|
||||
element = nextelement;
|
||||
parm = nextSibling(parm);
|
||||
}
|
||||
|
||||
Delete(elements);
|
||||
String *rettype = Copy(decl);
|
||||
String *quals = SwigType_pop_function_qualifiers(rettype);
|
||||
String *qualifiers = 0;
|
||||
if (quals)
|
||||
qualifiers = SwigType_str(quals, 0);
|
||||
|
||||
if (is_const) {
|
||||
if (is_func) {
|
||||
Append(result, " ");
|
||||
Append(result, "const");
|
||||
} else {
|
||||
Insert(result, 0, "const ");
|
||||
}
|
||||
}
|
||||
String *popped_decl = SwigType_pop_function(rettype);
|
||||
if (return_base_type)
|
||||
Append(rettype, return_base_type);
|
||||
|
||||
Chop(result);
|
||||
|
||||
if (rettype) {
|
||||
Insert(result, 0, " ");
|
||||
if (!conversion_operator) {
|
||||
SwigType *rettype_stripped = SwigType_strip_qualifiers(rettype);
|
||||
String *rtype = SwigType_str(rettype, 0);
|
||||
Insert(result, 0, rtype);
|
||||
Append(result, rtype);
|
||||
if (SwigType_issimple(rettype_stripped) && return_base_type)
|
||||
Append(result, " ");
|
||||
Delete(rtype);
|
||||
Delete(rettype_stripped);
|
||||
}
|
||||
|
||||
if (id)
|
||||
Append(result, id);
|
||||
|
||||
String *args_string = default_args ? ParmList_str_defaultargs(args) : ParmList_str(args);
|
||||
Printv(result, "(", args_string, ")", NIL);
|
||||
|
||||
if (qualifiers)
|
||||
Printv(result, " ", qualifiers, NIL);
|
||||
|
||||
// Reformat result to how it has been historically
|
||||
Replaceall(result, ",", ", ");
|
||||
Replaceall(result, "=", " = ");
|
||||
|
||||
Delete(args_string);
|
||||
Delete(popped_decl);
|
||||
Delete(qualifiers);
|
||||
Delete(quals);
|
||||
Delete(rettype);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -272,6 +194,7 @@ String *Swig_method_decl(SwigType *rettype, SwigType *decl, const_String_or_char
|
|||
* to add an extra dynamic_cast to call the public C++ wrapper in the director class.
|
||||
* Also for non-static protected members when the allprotected option is on.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
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"))) ||
|
||||
|
|
@ -290,13 +213,13 @@ void Swig_director_emit_dynamic_cast(Node *n, Wrapper *f) {
|
|||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_director_parms_fixup()
|
||||
*
|
||||
* For each parameter in the C++ member function, copy the parameter name
|
||||
* to its "lname"; this ensures that Swig_typemap_attach_parms() will do
|
||||
* the right thing when it sees strings like "$1" in "directorin" typemaps.
|
||||
* ------------------------------------------------------------ */
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
void Swig_director_parms_fixup(ParmList *parms) {
|
||||
Parm *p;
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
#include "swigmod.h"
|
||||
#include "cparse.h"
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* emit_return_variable()
|
||||
|
|
@ -112,9 +113,8 @@ void emit_attach_parmmaps(ParmList *l, Wrapper *f) {
|
|||
/* This is compatibility code to deal with the deprecated "ignore" typemap */
|
||||
Parm *p = l;
|
||||
Parm *np;
|
||||
String *tm;
|
||||
while (p) {
|
||||
tm = Getattr(p, "tmap:in");
|
||||
String *tm = Getattr(p, "tmap:in");
|
||||
if (tm && checkAttribute(p, "tmap:in:numinputs", "0")) {
|
||||
Replaceall(tm, "$target", Getattr(p, "lname"));
|
||||
Printv(f->code, tm, "\n", NIL);
|
||||
|
|
@ -134,7 +134,6 @@ void emit_attach_parmmaps(ParmList *l, Wrapper *f) {
|
|||
/* Perform a sanity check on "in" and "freearg" typemaps. These
|
||||
must exactly match to avoid chaos. If a mismatch occurs, we
|
||||
nuke the freearg typemap */
|
||||
|
||||
{
|
||||
Parm *p = l;
|
||||
Parm *npin, *npfreearg;
|
||||
|
|
@ -189,13 +188,45 @@ void emit_attach_parmmaps(ParmList *l, Wrapper *f) {
|
|||
p = lp;
|
||||
while (p) {
|
||||
if (SwigType_isvarargs(Getattr(p, "type"))) {
|
||||
// Mark the head of the ParmList that it has varargs
|
||||
Setattr(l, "emit:varargs", lp);
|
||||
//Printf(stdout, "setting emit:varargs %s ... %s +++ %s\n", Getattr(l, "emit:varargs"), Getattr(l, "type"), Getattr(p, "type"));
|
||||
break;
|
||||
}
|
||||
p = nextSibling(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* An equivalent type can be used in the typecheck typemap for SWIG to detect the overloading of equivalent
|
||||
* target language types. This is primarily for the smartptr feature, where a pointer and a smart pointer
|
||||
* are seen as equivalent types in the target language.
|
||||
*/
|
||||
{
|
||||
Parm *p = l;
|
||||
while (p) {
|
||||
String *tm = Getattr(p, "tmap:typecheck");
|
||||
if (tm) {
|
||||
String *equivalent = Getattr(p, "tmap:typecheck:equivalent");
|
||||
if (equivalent) {
|
||||
String *precedence = Getattr(p, "tmap:typecheck:precedence");
|
||||
if (precedence && Strcmp(precedence, "0") != 0)
|
||||
Swig_error(Getfile(tm), Getline(tm), "The 'typecheck' typemap for %s contains an 'equivalent' attribute for a 'precedence' that is not set to SWIG_TYPECHECK_POINTER or 0.\n", SwigType_str(Getattr(p, "type"), 0));
|
||||
SwigType *cpt = Swig_cparse_type(equivalent);
|
||||
if (cpt) {
|
||||
Setattr(p, "equivtype", cpt);
|
||||
Delete(cpt);
|
||||
} else {
|
||||
Swig_error(Getfile(tm), Getline(tm), "Invalid type (%s) in 'equivalent' attribute in 'typecheck' typemap for type %s.\n", equivalent, SwigType_str(Getattr(p, "type"), 0));
|
||||
}
|
||||
}
|
||||
p = Getattr(p, "tmap:typecheck:next");
|
||||
} else {
|
||||
p = nextSibling(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
|
|
@ -300,7 +331,8 @@ int emit_num_required(ParmList *parms) {
|
|||
/* -----------------------------------------------------------------------------
|
||||
* emit_isvarargs()
|
||||
*
|
||||
* Checks if a function is a varargs function
|
||||
* Checks if a ParmList is a parameter list containing varargs.
|
||||
* This function requires emit_attach_parmmaps to have been called beforehand.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
int emit_isvarargs(ParmList *p) {
|
||||
|
|
@ -311,6 +343,28 @@ int emit_isvarargs(ParmList *p) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* emit_isvarargs_function()
|
||||
*
|
||||
* Checks for varargs in a function/constructor (can be overloaded)
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
bool emit_isvarargs_function(Node *n) {
|
||||
bool has_varargs = false;
|
||||
Node *over = Getattr(n, "sym:overloaded");
|
||||
if (over) {
|
||||
for (Node *sibling = over; sibling; sibling = Getattr(sibling, "sym:nextSibling")) {
|
||||
if (ParmList_has_varargs(Getattr(sibling, "parms"))) {
|
||||
has_varargs = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
has_varargs = ParmList_has_varargs(Getattr(n, "parms")) ? true : false;
|
||||
}
|
||||
return has_varargs;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* void emit_mark_vararg_parms()
|
||||
*
|
||||
|
|
@ -454,29 +508,29 @@ String *emit_action(Node *n) {
|
|||
if (catchlist) {
|
||||
int unknown_catch = 0;
|
||||
int has_varargs = 0;
|
||||
Printf(eaction, "}\n");
|
||||
Printf(eaction, "}");
|
||||
for (Parm *ep = catchlist; ep; ep = nextSibling(ep)) {
|
||||
String *em = Swig_typemap_lookup("throws", ep, "_e", 0);
|
||||
if (em) {
|
||||
SwigType *et = Getattr(ep, "type");
|
||||
SwigType *etr = SwigType_typedef_resolve_all(et);
|
||||
if (SwigType_isreference(etr) || SwigType_ispointer(etr) || SwigType_isarray(etr)) {
|
||||
Printf(eaction, "catch(%s) {", SwigType_str(et, "_e"));
|
||||
Printf(eaction, " catch(%s) {", SwigType_str(et, "_e"));
|
||||
} else if (SwigType_isvarargs(etr)) {
|
||||
Printf(eaction, "catch(...) {");
|
||||
Printf(eaction, " catch(...) {");
|
||||
has_varargs = 1;
|
||||
} else {
|
||||
Printf(eaction, "catch(%s) {", SwigType_str(et, "&_e"));
|
||||
Printf(eaction, " catch(%s) {", SwigType_str(et, "&_e"));
|
||||
}
|
||||
Printv(eaction, em, "\n", NIL);
|
||||
Printf(eaction, "}\n");
|
||||
Printf(eaction, "}");
|
||||
} else {
|
||||
Swig_warning(WARN_TYPEMAP_THROW, Getfile(n), Getline(n), "No 'throws' typemap defined for exception type '%s'\n", SwigType_str(Getattr(ep, "type"), 0));
|
||||
unknown_catch = 1;
|
||||
}
|
||||
}
|
||||
if (unknown_catch && !has_varargs) {
|
||||
Printf(eaction, "catch(...) { throw; }\n");
|
||||
Printf(eaction, " catch(...) {\nthrow;\n}");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -125,6 +125,8 @@ class GO:public Language {
|
|||
String *prefix_option;
|
||||
// -fgo-pkgpath option.
|
||||
String *pkgpath_option;
|
||||
// Prefix for translating %import directive to import statements.
|
||||
String *import_prefix;
|
||||
// Whether to use a shared library.
|
||||
bool use_shlib;
|
||||
// Name of shared library to import.
|
||||
|
|
@ -199,11 +201,12 @@ class GO:public Language {
|
|||
public:
|
||||
GO():package(NULL),
|
||||
module(NULL),
|
||||
cgo_flag(false),
|
||||
cgo_flag(true),
|
||||
gccgo_flag(false),
|
||||
go_prefix(NULL),
|
||||
prefix_option(NULL),
|
||||
pkgpath_option(NULL),
|
||||
import_prefix(NULL),
|
||||
use_shlib(false),
|
||||
soname(NULL),
|
||||
intgo_type_size(0),
|
||||
|
|
@ -269,6 +272,9 @@ private:
|
|||
} else if (strcmp(argv[i], "-cgo") == 0) {
|
||||
Swig_mark_arg(i);
|
||||
cgo_flag = true;
|
||||
} else if (strcmp(argv[i], "-no-cgo") == 0) {
|
||||
Swig_mark_arg(i);
|
||||
cgo_flag = false;
|
||||
} else if (strcmp(argv[i], "-gccgo") == 0) {
|
||||
Swig_mark_arg(i);
|
||||
gccgo_flag = true;
|
||||
|
|
@ -290,6 +296,15 @@ private:
|
|||
} else {
|
||||
Swig_arg_error();
|
||||
}
|
||||
} else if (strcmp(argv[i], "-import-prefix") == 0) {
|
||||
if (argv[i + 1]) {
|
||||
import_prefix = 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;
|
||||
|
|
@ -615,6 +630,12 @@ private:
|
|||
|
||||
Language::top(n);
|
||||
|
||||
if (directorsEnabled()) {
|
||||
// Insert director runtime into the f_runtime file (make it occur before %header section)
|
||||
Swig_insert_file("director_common.swg", f_c_runtime);
|
||||
Swig_insert_file("director.swg", f_c_runtime);
|
||||
}
|
||||
|
||||
Delete(go_imports);
|
||||
|
||||
// Write out definitions for the types not defined by SWIG.
|
||||
|
|
@ -734,7 +755,11 @@ private:
|
|||
if (modname) {
|
||||
if (!Getattr(go_imports, modname)) {
|
||||
Setattr(go_imports, modname, modname);
|
||||
Printv(f_go_imports, "import \"", modname, "\"\n", NULL);
|
||||
Printv(f_go_imports, "import \"", NULL);
|
||||
if (import_prefix) {
|
||||
Printv(f_go_imports, import_prefix, "/", NULL);
|
||||
}
|
||||
Printv(f_go_imports, modname, "\"\n", NULL);
|
||||
}
|
||||
imported_package = modname;
|
||||
saw_import = true;
|
||||
|
|
@ -990,7 +1015,7 @@ private:
|
|||
* overname: The overload string for overloaded function.
|
||||
* wname: The SWIG wrapped name--the name of the C function.
|
||||
* base: A list of the names of base classes, in the case where this
|
||||
* is is a vritual method not defined in the current class.
|
||||
* is a virtual method not defined in the current class.
|
||||
* parms: The parameters.
|
||||
* result: The result type.
|
||||
* is_static: Whether this is a static method or member.
|
||||
|
|
@ -2445,7 +2470,8 @@ private:
|
|||
}
|
||||
|
||||
String *code = Copy(Getattr(n, "wrap:action"));
|
||||
Replaceall(code, Getattr(parms, "lname"), current);
|
||||
Replace(code, Getattr(parms, "lname"), current, DOH_REPLACE_ANY | DOH_REPLACE_ID);
|
||||
Delete(current);
|
||||
Printv(actioncode, code, "\n", NULL);
|
||||
}
|
||||
|
||||
|
|
@ -2598,6 +2624,14 @@ private:
|
|||
Replaceall(f->code, "$cleanup", cleanup);
|
||||
Delete(cleanup);
|
||||
|
||||
/* See if there is any return cleanup code */
|
||||
String *tm;
|
||||
if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
|
||||
Replaceall(tm, "$source", Swig_cresult_name());
|
||||
Printf(f->code, "%s\n", tm);
|
||||
Delete(tm);
|
||||
}
|
||||
|
||||
Replaceall(f->code, "$symname", Getattr(n, "sym:name"));
|
||||
}
|
||||
|
||||
|
|
@ -2797,34 +2831,53 @@ private:
|
|||
return SWIG_NOWRAP;
|
||||
}
|
||||
|
||||
String *get = NewString("");
|
||||
Printv(get, Swig_cresult_name(), " = ", NULL);
|
||||
|
||||
char quote;
|
||||
if (Getattr(n, "wrappedasconstant")) {
|
||||
quote = '\0';
|
||||
} else if (SwigType_type(type) == T_CHAR) {
|
||||
quote = '\'';
|
||||
} else if (SwigType_type(type) == T_STRING) {
|
||||
Printv(get, "(char *)", NULL);
|
||||
quote = '"';
|
||||
String *rawval = Getattr(n, "rawval");
|
||||
if (rawval && Len(rawval)) {
|
||||
// Based on Swig_VargetToFunction
|
||||
String *nname = NewStringf("(%s)", rawval);
|
||||
String *call;
|
||||
if (SwigType_isclass(type)) {
|
||||
call = NewStringf("%s", nname);
|
||||
} else {
|
||||
call = SwigType_lcaststr(type, nname);
|
||||
}
|
||||
String *cres = Swig_cresult(type, Swig_cresult_name(), call);
|
||||
Setattr(n, "wrap:action", cres);
|
||||
Delete(nname);
|
||||
Delete(call);
|
||||
Delete(cres);
|
||||
} else {
|
||||
quote = '\0';
|
||||
String *get = NewString("");
|
||||
Printv(get, Swig_cresult_name(), " = ", NULL);
|
||||
|
||||
char quote;
|
||||
if (Getattr(n, "wrappedasconstant")) {
|
||||
quote = '\0';
|
||||
} else if (SwigType_type(type) == T_CHAR) {
|
||||
quote = '\'';
|
||||
} else if (SwigType_type(type) == T_STRING) {
|
||||
Printv(get, "(char *)", NULL);
|
||||
quote = '"';
|
||||
} else {
|
||||
quote = '\0';
|
||||
}
|
||||
|
||||
if (quote != '\0') {
|
||||
Printf(get, "%c", quote);
|
||||
}
|
||||
|
||||
Printv(get, Getattr(n, "value"), NULL);
|
||||
|
||||
if (quote != '\0') {
|
||||
Printf(get, "%c", quote);
|
||||
}
|
||||
|
||||
Printv(get, ";\n", NULL);
|
||||
|
||||
Setattr(n, "wrap:action", get);
|
||||
Delete(get);
|
||||
}
|
||||
|
||||
if (quote != '\0') {
|
||||
Printf(get, "%c", quote);
|
||||
}
|
||||
|
||||
Printv(get, Getattr(n, "value"), NULL);
|
||||
|
||||
if (quote != '\0') {
|
||||
Printf(get, "%c", quote);
|
||||
}
|
||||
|
||||
Printv(get, ";\n", NULL);
|
||||
Setattr(n, "wrap:action", get);
|
||||
|
||||
String *sname = Copy(symname);
|
||||
if (class_name) {
|
||||
Append(sname, "_");
|
||||
|
|
@ -3829,12 +3882,11 @@ private:
|
|||
String *cxx_director_name = NewString("SwigDirector_");
|
||||
Append(cxx_director_name, class_name);
|
||||
|
||||
String *decl = Swig_method_decl(NULL, Getattr(n, "decl"),
|
||||
cxx_director_name, first_parm, 0, 0);
|
||||
String *decl = Swig_method_decl(NULL, Getattr(n, "decl"), cxx_director_name, first_parm, 0);
|
||||
Printv(f_c_directors_h, " ", decl, ";\n", NULL);
|
||||
Delete(decl);
|
||||
|
||||
decl = Swig_method_decl(NULL, Getattr(n, "decl"), cxx_director_name, first_parm, 0, 0);
|
||||
decl = Swig_method_decl(NULL, Getattr(n, "decl"), cxx_director_name, first_parm, 0);
|
||||
Printv(f_c_directors, cxx_director_name, "::", decl, "\n", NULL);
|
||||
Delete(decl);
|
||||
|
||||
|
|
@ -4559,7 +4611,7 @@ private:
|
|||
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);
|
||||
String *upcall_decl = Swig_method_decl(rtype, Getattr(n, "decl"), upcall_method_name, parms, 0);
|
||||
Printv(f_c_directors_h, " ", upcall_decl, " {\n", NULL);
|
||||
Delete(upcall_decl);
|
||||
|
||||
|
|
@ -5007,13 +5059,13 @@ private:
|
|||
// Declare the method for the director class.
|
||||
|
||||
SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type");
|
||||
String *decl = Swig_method_decl(rtype, Getattr(n, "decl"), Getattr(n, "name"), parms, 0, 0);
|
||||
String *decl = Swig_method_decl(rtype, Getattr(n, "decl"), Getattr(n, "name"), parms, 0);
|
||||
Printv(f_c_directors_h, " virtual ", decl, NULL);
|
||||
Delete(decl);
|
||||
|
||||
String *qname = NewString("");
|
||||
Printv(qname, "SwigDirector_", class_name, "::", Getattr(n, "name"), NULL);
|
||||
decl = Swig_method_decl(rtype, Getattr(n, "decl"), qname, parms, 0, 0);
|
||||
decl = Swig_method_decl(rtype, Getattr(n, "decl"), qname, parms, 0);
|
||||
Printv(w->def, decl, NULL);
|
||||
Delete(decl);
|
||||
Delete(qname);
|
||||
|
|
@ -5030,7 +5082,19 @@ private:
|
|||
Printv(w->def, " {\n", NULL);
|
||||
|
||||
if (SwigType_type(result) != T_VOID) {
|
||||
Wrapper_add_local(w, "c_result", SwigType_lstr(result, "c_result"));
|
||||
if (!SwigType_isclass(result)) {
|
||||
if (!(SwigType_ispointer(result) || SwigType_isreference(result))) {
|
||||
String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(result, 0));
|
||||
Wrapper_add_localv(w, "c_result", SwigType_lstr(result, "c_result"), construct_result, NIL);
|
||||
Delete(construct_result);
|
||||
} else {
|
||||
Wrapper_add_localv(w, "c_result", SwigType_lstr(result, "c_result"), "= 0", NIL);
|
||||
}
|
||||
} else {
|
||||
String *cres = SwigType_lstr(result, "c_result");
|
||||
Printf(w->code, "%s;\n", cres);
|
||||
Delete(cres);
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_ignored) {
|
||||
|
|
@ -5464,6 +5528,8 @@ private:
|
|||
*--------------------------------------------------------------------*/
|
||||
|
||||
String *buildThrow(Node *n) {
|
||||
if (Getattr(n, "noexcept"))
|
||||
return NewString("noexcept");
|
||||
ParmList *throw_parm_list = Getattr(n, "throws");
|
||||
if (!throw_parm_list && !Getattr(n, "throw"))
|
||||
return NULL;
|
||||
|
|
@ -5893,7 +5959,7 @@ private:
|
|||
*
|
||||
* Given a C/C++ name, return a name in Go which will be exported.
|
||||
* If the first character is an upper case letter, this returns a
|
||||
* copy of its argment. If the first character is a lower case
|
||||
* copy of its argument. If the first character is a lower case
|
||||
* letter, this forces it to upper case. Otherwise, this prepends
|
||||
* 'X'.
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
|
@ -6213,9 +6279,9 @@ private:
|
|||
Setattr(undefined_enum_types, t, ret);
|
||||
Delete(tt);
|
||||
}
|
||||
} else if (SwigType_isfunctionpointer(type) || SwigType_isfunction(type)) {
|
||||
} else if (SwigType_isfunctionpointer(t) || SwigType_isfunction(t)) {
|
||||
ret = NewString("_swig_fnptr");
|
||||
} else if (SwigType_ismemberpointer(type)) {
|
||||
} else if (SwigType_ismemberpointer(t)) {
|
||||
ret = NewString("_swig_memberptr");
|
||||
} else if (SwigType_issimple(t)) {
|
||||
Node *cn = classLookup(t);
|
||||
|
|
@ -6932,9 +6998,11 @@ extern "C" Language *swig_go(void) {
|
|||
const char * const GO::usage = "\
|
||||
Go Options (available with -go)\n\
|
||||
-cgo - Generate cgo input files\n\
|
||||
-gccgo - Generate code for gccgo rather than 6g/8g\n\
|
||||
-no-cgo - Do not generate cgo input files\n\
|
||||
-gccgo - Generate code for gccgo rather than gc\n\
|
||||
-go-pkgpath <p> - Like gccgo -fgo-pkgpath option\n\
|
||||
-go-prefix <p> - Like gccgo -fgo-prefix option\n\
|
||||
-import-prefix <p> - Prefix to add to %import directives\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\
|
||||
|
|
|
|||
|
|
@ -151,12 +151,14 @@ void Swig_interface_propagate_methods(Node *n) {
|
|||
for (Node *child = firstChild(n); child; child = nextSibling(child)) {
|
||||
if (Getattr(child, "interface:owner"))
|
||||
break; // at the end of the list are newly appended methods
|
||||
if (checkAttribute(child, "name", name)) {
|
||||
String *decl = SwigType_typedef_resolve_all(Getattr(child, "decl"));
|
||||
identically_overloaded_method = Strcmp(decl, this_decl_resolved) == 0;
|
||||
Delete(decl);
|
||||
if (identically_overloaded_method)
|
||||
break;
|
||||
if (Cmp(nodeType(child), "cdecl") == 0) {
|
||||
if (checkAttribute(child, "name", name)) {
|
||||
String *decl = SwigType_typedef_resolve_all(Getattr(child, "decl"));
|
||||
identically_overloaded_method = Strcmp(decl, this_decl_resolved) == 0;
|
||||
Delete(decl);
|
||||
if (identically_overloaded_method)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
#include <limits.h> // for INT_MAX
|
||||
#include "cparse.h"
|
||||
#include <ctype.h>
|
||||
#include "javadoc.h"
|
||||
|
||||
/* Hash type used for upcalls from C/C++ */
|
||||
typedef DOH UpcallData;
|
||||
|
|
@ -46,7 +47,9 @@ class JAVA:public Language {
|
|||
bool global_variable_flag; // Flag for when wrapping a global variable
|
||||
bool old_variable_names; // Flag for old style variable names in the intermediary class
|
||||
bool member_func_flag; // flag set when wrapping a member function
|
||||
|
||||
bool doxygen; //flag for converting found doxygen to javadoc
|
||||
bool comment_creation_chatter; //flag for getting information about where comments were created in java.cxx
|
||||
|
||||
String *imclass_name; // intermediary class name
|
||||
String *module_class_name; // module class name
|
||||
String *constants_interface_name; // constants interface name
|
||||
|
|
@ -72,8 +75,8 @@ class JAVA:public Language {
|
|||
String *module_baseclass; //inheritance for module class from %pragma
|
||||
String *imclass_interfaces; //interfaces for intermediary class class from %pragma
|
||||
String *module_interfaces; //interfaces for module class from %pragma
|
||||
String *imclass_class_modifiers; //class modifiers for intermediary class overriden by %pragma
|
||||
String *module_class_modifiers; //class modifiers for module class overriden by %pragma
|
||||
String *imclass_class_modifiers; //class modifiers for intermediary class overridden by %pragma
|
||||
String *module_class_modifiers; //class modifiers for module class overridden by %pragma
|
||||
String *upcasts_code; //C++ casts for inheritance hierarchies C++ code
|
||||
String *imclass_cppcasts_code; //C++ casts up inheritance hierarchies intermediary class code
|
||||
String *imclass_directors; // Intermediate class director code
|
||||
|
|
@ -120,6 +123,8 @@ public:
|
|||
global_variable_flag(false),
|
||||
old_variable_names(false),
|
||||
member_func_flag(false),
|
||||
doxygen(false),
|
||||
comment_creation_chatter(false),
|
||||
imclass_name(NULL),
|
||||
module_class_name(NULL),
|
||||
constants_interface_name(NULL),
|
||||
|
|
@ -164,11 +169,15 @@ public:
|
|||
director_multiple_inheritance = 0;
|
||||
director_language = 1;
|
||||
}
|
||||
|
||||
~JAVA() {
|
||||
delete doxygenTranslator;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* constructIntermediateClassName()
|
||||
*
|
||||
* Construct the fully qualified name of the intermidiate class and set
|
||||
* Construct the fully qualified name of the intermediate class and set
|
||||
* the full_imclass_name attribute accordingly.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
void constructIntermediateClassName(Node *n) {
|
||||
|
|
@ -256,6 +265,8 @@ public:
|
|||
|
||||
SWIG_library_directory("java");
|
||||
|
||||
int doxygen_translator_flags = 0;
|
||||
|
||||
// Look for certain command line options
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (argv[i]) {
|
||||
|
|
@ -277,6 +288,16 @@ public:
|
|||
Printf(stderr, "Deprecated command line option: %s. Proxy classes are now generated by default.\n", argv[i]);
|
||||
Swig_mark_arg(i);
|
||||
proxy_flag = true;
|
||||
} else if ((strcmp(argv[i], "-doxygen") == 0)) {
|
||||
Swig_mark_arg(i);
|
||||
doxygen = true;
|
||||
scan_doxygen_comments = true;
|
||||
} else if ((strcmp(argv[i], "-debug-doxygen-translator") == 0)) {
|
||||
Swig_mark_arg(i);
|
||||
doxygen_translator_flags |= DoxygenTranslator::debug_translator;
|
||||
} else if ((strcmp(argv[i], "-debug-doxygen-parser") == 0)) {
|
||||
Swig_mark_arg(i);
|
||||
doxygen_translator_flags |= DoxygenTranslator::debug_parser;
|
||||
} else if ((strcmp(argv[i], "-noproxy") == 0)) {
|
||||
Swig_mark_arg(i);
|
||||
proxy_flag = false;
|
||||
|
|
@ -300,6 +321,9 @@ public:
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (doxygen)
|
||||
doxygenTranslator = new JavaDocConverter(doxygen_translator_flags);
|
||||
|
||||
// Add a symbol to the parser for conditional compilation
|
||||
Preprocessor_define("SWIGJAVA 1", 0);
|
||||
|
|
@ -567,6 +591,13 @@ public:
|
|||
if (module_imports)
|
||||
Printf(f_module, "%s\n", module_imports);
|
||||
|
||||
if (doxygen && doxygenTranslator->hasDocumentation(n)) {
|
||||
String *doxygen_comments = doxygenTranslator->getDocumentation(n, 0);
|
||||
if (comment_creation_chatter)
|
||||
Printf(f_module, "/* This was generated from top() */\n");
|
||||
Printv(f_module, Char(doxygen_comments), NIL);
|
||||
Delete(doxygen_comments);
|
||||
}
|
||||
if (Len(module_class_modifiers) > 0)
|
||||
Printf(f_module, "%s ", module_class_modifiers);
|
||||
Printf(f_module, "%s ", module_class_name);
|
||||
|
|
@ -1246,6 +1277,14 @@ public:
|
|||
if ((enum_feature != SimpleEnum) && symname && typemap_lookup_type) {
|
||||
// Wrap (non-anonymous) C/C++ enum within a typesafe, typeunsafe or proper Java enum
|
||||
|
||||
if (doxygen && doxygenTranslator->hasDocumentation(n)) {
|
||||
String *doxygen_comments = doxygenTranslator->getDocumentation(n, 0);
|
||||
if (comment_creation_chatter)
|
||||
Printf(enum_code, "/* This was generated from enumDeclaration() */\n");
|
||||
Printv(enum_code, Char(doxygen_comments), NIL);
|
||||
Delete(doxygen_comments);
|
||||
}
|
||||
|
||||
String *scope = getCurrentScopeName(nspace);
|
||||
if (!addSymbol(symname, n, scope))
|
||||
return SWIG_ERROR;
|
||||
|
|
@ -1265,9 +1304,17 @@ public:
|
|||
Replaceall(enum_code, "$static ", "");
|
||||
Delete(scope);
|
||||
} else {
|
||||
// Wrap C++ enum with integers - just indicate start of enum with a comment, no comment for anonymous enums of any sort
|
||||
if (symname && !Getattr(n, "unnamedinstance"))
|
||||
Printf(constants_code, " // %s \n", symname);
|
||||
// Translate and write javadoc comment for the enum itself if flagged
|
||||
if (doxygen && doxygenTranslator->hasDocumentation(n)) {
|
||||
String *doxygen_comments = doxygenTranslator->getDocumentation(n, " ");
|
||||
if (comment_creation_chatter)
|
||||
Printf(constants_code, "/* This was generated from enumDeclaration() */\n");
|
||||
Printf(constants_code, Char(doxygen_comments));
|
||||
Printf(constants_code, "\n");
|
||||
Delete(doxygen_comments);
|
||||
}
|
||||
}
|
||||
|
||||
// Emit each enum item
|
||||
|
|
@ -1418,12 +1465,24 @@ public:
|
|||
}
|
||||
if (!addSymbol(symname, n, scope))
|
||||
return SWIG_ERROR;
|
||||
|
||||
if ((enum_feature == ProperEnum) && parent_name && !unnamedinstance) {
|
||||
if (!GetFlag(n, "firstenumitem"))
|
||||
Printf(enum_code, ",\n");
|
||||
}
|
||||
|
||||
// Translate and write javadoc comment if flagged
|
||||
if (doxygen && doxygenTranslator->hasDocumentation(n)) {
|
||||
String *doxygen_comments = doxygenTranslator->getDocumentation(n, " ");
|
||||
if (comment_creation_chatter)
|
||||
Printf(enum_code, "/* This was generated from enumvalueDeclaration() */\n");
|
||||
Printv(enum_code, Char(doxygen_comments), NIL);
|
||||
Delete(doxygen_comments);
|
||||
}
|
||||
|
||||
if ((enum_feature == ProperEnum) && parent_name && !unnamedinstance) {
|
||||
// Wrap (non-anonymous) C/C++ enum with a proper Java enum
|
||||
// Emit the enum item.
|
||||
if (!GetFlag(n, "firstenumitem"))
|
||||
Printf(enum_code, ",\n");
|
||||
Printf(enum_code, " %s", symname);
|
||||
if (Getattr(n, "enumvalue")) {
|
||||
String *value = enumValue(n);
|
||||
|
|
@ -1497,6 +1556,15 @@ public:
|
|||
String *constants_code = NewString("");
|
||||
Swig_save("constantWrapper", n, "value", NIL);
|
||||
|
||||
// Translate and write javadoc comment if flagged
|
||||
if (doxygen && doxygenTranslator->hasDocumentation(n)) {
|
||||
String *doxygen_comments = doxygenTranslator->getDocumentation(n, " ");
|
||||
if (comment_creation_chatter)
|
||||
Printf(constants_code, "/* This was generated from constantWrapper() */\n");
|
||||
Printv(constants_code, Char(doxygen_comments), NIL);
|
||||
Delete(doxygen_comments);
|
||||
}
|
||||
|
||||
bool is_enum_item = (Cmp(nodeType(n), "enumitem") == 0);
|
||||
|
||||
const String *itemname = (proxy_flag && wrapping_member_flag) ? variable_name : symname;
|
||||
|
|
@ -1612,10 +1680,22 @@ public:
|
|||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
virtual int insertDirective(Node *n) {
|
||||
int ret = SWIG_OK;
|
||||
String *code = Getattr(n, "code");
|
||||
String *section = Getattr(n, "section");
|
||||
Replaceall(code, "$module", module_class_name);
|
||||
Replaceall(code, "$imclassname", imclass_name);
|
||||
return Language::insertDirective(n);
|
||||
|
||||
if (!ImportMode && (Cmp(section, "proxycode") == 0)) {
|
||||
if (proxy_class_code) {
|
||||
Swig_typemap_replace_embedded_typemap(code, n);
|
||||
int offset = Len(code) > 0 && *Char(code) == '\n' ? 1 : 0;
|
||||
Printv(proxy_class_code, Char(code) + offset, "\n", NIL);
|
||||
}
|
||||
} else {
|
||||
ret = Language::insertDirective(n);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
|
|
@ -1796,7 +1876,7 @@ public:
|
|||
Replaceall(cptr_method_name, ".", "_");
|
||||
Replaceall(cptr_method_name, "$interfacename", interface_name);
|
||||
|
||||
String *upcast_method_name = Swig_name_member(getNSpace(), proxy_class_name, cptr_method_name);
|
||||
String *upcast_method_name = Swig_name_member(getNSpace(), getClassPrefix(), cptr_method_name);
|
||||
upcastsCode(smart, upcast_method_name, c_classname, c_baseclass);
|
||||
Delete(upcast_method_name);
|
||||
Delete(cptr_method_name);
|
||||
|
|
@ -1924,13 +2004,24 @@ public:
|
|||
|
||||
// Pure Java interfaces
|
||||
const String *pure_interfaces = typemapLookup(n, "javainterfaces", typemap_lookup_type, WARN_NONE);
|
||||
|
||||
if (*Char(interface_list) && *Char(pure_interfaces))
|
||||
Append(interface_list, ", ");
|
||||
Append(interface_list, pure_interfaces);
|
||||
// Start writing the proxy class
|
||||
if (!has_outerclass) // Import statements
|
||||
Printv(proxy_class_def, typemapLookup(n, "javaimports", typemap_lookup_type, WARN_NONE),"\n", NIL);
|
||||
else
|
||||
|
||||
// Translate and write javadoc comment if flagged
|
||||
if (doxygen && doxygenTranslator->hasDocumentation(n)) {
|
||||
String *doxygen_comments = doxygenTranslator->getDocumentation(n, 0);
|
||||
if (comment_creation_chatter)
|
||||
Printf(proxy_class_def, "/* This was generated from emitProxyClassDefAndCPPCasts() */\n");
|
||||
Printv(proxy_class_def, Char(doxygen_comments), NIL);
|
||||
Delete(doxygen_comments);
|
||||
}
|
||||
|
||||
if (has_outerclass)
|
||||
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
|
||||
|
|
@ -1944,16 +2035,19 @@ public:
|
|||
String *destruct = NewString("");
|
||||
const String *tm = NULL;
|
||||
attributes = NewHash();
|
||||
String *destruct_methodname = NULL;
|
||||
String *destruct_methodmodifiers = NULL;
|
||||
const String *destruct_methodname = NULL;
|
||||
const String *destruct_methodmodifiers = NULL;
|
||||
const String *destruct_parameters = NULL;
|
||||
if (derived) {
|
||||
tm = typemapLookup(n, "javadestruct_derived", typemap_lookup_type, WARN_NONE, attributes);
|
||||
destruct_methodname = Getattr(attributes, "tmap:javadestruct_derived:methodname");
|
||||
destruct_methodmodifiers = Getattr(attributes, "tmap:javadestruct_derived:methodmodifiers");
|
||||
destruct_parameters = Getattr(attributes, "tmap:javadestruct_derived:parameters");
|
||||
} else {
|
||||
tm = typemapLookup(n, "javadestruct", typemap_lookup_type, WARN_NONE, attributes);
|
||||
destruct_methodname = Getattr(attributes, "tmap:javadestruct:methodname");
|
||||
destruct_methodmodifiers = Getattr(attributes, "tmap:javadestruct:methodmodifiers");
|
||||
destruct_parameters = Getattr(attributes, "tmap:javadestruct:parameters");
|
||||
}
|
||||
if (tm && *Char(tm)) {
|
||||
if (!destruct_methodname) {
|
||||
|
|
@ -1962,6 +2056,8 @@ public:
|
|||
if (!destruct_methodmodifiers) {
|
||||
Swig_error(Getfile(n), Getline(n), "No methodmodifiers attribute defined in javadestruct%s typemap for %s.\n", (derived ? "_derived" : ""), proxy_class_name);
|
||||
}
|
||||
if (!destruct_parameters)
|
||||
destruct_parameters = empty_string;
|
||||
}
|
||||
// Emit the finalize and delete methods
|
||||
if (tm) {
|
||||
|
|
@ -1975,8 +2071,15 @@ public:
|
|||
Replaceall(destruct, "$jnicall", destructor_call);
|
||||
else
|
||||
Replaceall(destruct, "$jnicall", "throw new UnsupportedOperationException(\"C++ destructor does not have public access\")");
|
||||
if (*Char(destruct))
|
||||
Printv(proxy_class_def, "\n ", destruct_methodmodifiers, " void ", destruct_methodname, "()", destructor_throws_clause, " ", destruct, "\n", NIL);
|
||||
if (*Char(destruct)) {
|
||||
Printv(proxy_class_def, "\n ", NIL);
|
||||
const String *methodmods = Getattr(n, "destructmethodmodifiers");
|
||||
if (methodmods)
|
||||
Printv(proxy_class_def, methodmods, NIL);
|
||||
else
|
||||
Printv(proxy_class_def, destruct_methodmodifiers, NIL);
|
||||
Printv(proxy_class_def, " void ", destruct_methodname, "(", destruct_parameters, ")", destructor_throws_clause, " ", destruct, "\n", NIL);
|
||||
}
|
||||
}
|
||||
if (*Char(interface_upcasts))
|
||||
Printv(proxy_class_def, interface_upcasts, NIL);
|
||||
|
|
@ -2260,39 +2363,6 @@ public:
|
|||
--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(), getClassPrefix(), "SWIGDowncast");
|
||||
String *jniname = makeValidJniName(downcast_method);
|
||||
String *wname = Swig_name_wrapper(jniname);
|
||||
|
||||
String *norm_name = SwigType_namestr(Getattr(n, "name"));
|
||||
|
||||
Printf(imclass_class_code, " public final static native %s %s(long cPtrBase, boolean cMemoryOwn);\n", proxy_class_name, downcast_method);
|
||||
|
||||
Wrapper *dcast_wrap = NewWrapper();
|
||||
|
||||
Printf(dcast_wrap->def, "SWIGEXPORT jobject JNICALL %s(JNIEnv *jenv, jclass jcls, jlong jCPtrBase, jboolean cMemoryOwn) {", wname);
|
||||
Printf(dcast_wrap->code, " Swig::Director *director = (Swig::Director *) 0;\n");
|
||||
Printf(dcast_wrap->code, " jobject jresult = (jobject) 0;\n");
|
||||
Printf(dcast_wrap->code, " %s *obj = *((%s **)&jCPtrBase);\n", norm_name, norm_name);
|
||||
Printf(dcast_wrap->code, " if (obj) director = dynamic_cast<Swig::Director *>(obj);\n");
|
||||
Printf(dcast_wrap->code, " if (director) jresult = director->swig_get_self(jenv);\n");
|
||||
Printf(dcast_wrap->code, " return jresult;\n");
|
||||
Printf(dcast_wrap->code, "}\n");
|
||||
|
||||
Wrapper_print(dcast_wrap, f_wrappers);
|
||||
DelWrapper(dcast_wrap);
|
||||
|
||||
Delete(norm_name);
|
||||
Delete(wname);
|
||||
Delete(jniname);
|
||||
Delete(downcast_method);
|
||||
}
|
||||
|
||||
if (f_interface) {
|
||||
Printv(f_interface, interface_class_code, "}\n", NIL);
|
||||
Delete(f_interface);
|
||||
|
|
@ -2438,6 +2508,15 @@ public:
|
|||
setter_flag = (Cmp(Getattr(n, "sym:name"), Swig_name_set(getNSpace(), Swig_name_member(0, getClassPrefix(), variable_name))) == 0);
|
||||
}
|
||||
|
||||
// Translate and write javadoc comment if flagged
|
||||
if (doxygen && doxygenTranslator->hasDocumentation(n)) {
|
||||
String *doxygen_comments = doxygenTranslator->getDocumentation(n, " ");
|
||||
if (comment_creation_chatter)
|
||||
Printf(function_code, "/* This was generated from proxyclassfunctionhandler() */\n");
|
||||
Printv(function_code, Char(doxygen_comments), NIL);
|
||||
Delete(doxygen_comments);
|
||||
}
|
||||
|
||||
/* Start generating the proxy function */
|
||||
const String *methodmods = Getattr(n, "feature:java:methodmodifiers");
|
||||
methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string);
|
||||
|
|
@ -2445,7 +2524,7 @@ public:
|
|||
if (static_flag)
|
||||
Printf(function_code, "static ");
|
||||
Printf(function_code, "%s %s(", return_type, proxy_function_name);
|
||||
|
||||
|
||||
if (is_interface)
|
||||
Printf(interface_class_code, " %s %s(", return_type, proxy_function_name);
|
||||
|
||||
|
|
@ -2565,8 +2644,6 @@ public:
|
|||
|
||||
Printf(imcall, ")");
|
||||
Printf(function_code, ")");
|
||||
if (is_interface)
|
||||
Printf(interface_class_code, ");\n");
|
||||
|
||||
// Transform return type used in JNI function (in intermediary class) to type used in Java wrapper function (in proxy class)
|
||||
if ((tm = Swig_typemap_lookup("javaout", n, "", 0))) {
|
||||
|
|
@ -2624,8 +2701,13 @@ public:
|
|||
Swig_warning(WARN_JAVA_TYPEMAP_JAVAOUT_UNDEF, input_file, line_number, "No javaout typemap defined for %s\n", SwigType_str(t, 0));
|
||||
}
|
||||
|
||||
if (is_interface) {
|
||||
Printf(interface_class_code, ")");
|
||||
generateThrowsClause(n, interface_class_code);
|
||||
Printf(interface_class_code, ";\n");
|
||||
}
|
||||
generateThrowsClause(n, function_code);
|
||||
Printf(function_code, " %s\n\n", tm ? (const String *) tm : empty_string);
|
||||
Printf(function_code, " %s\n\n", tm ? tm : empty_string);
|
||||
Printv(proxy_class_code, function_code, NIL);
|
||||
|
||||
Delete(pre_code);
|
||||
|
|
@ -2670,6 +2752,15 @@ public:
|
|||
tm = Getattr(n, "tmap:jtype"); // typemaps were attached earlier to the node
|
||||
Printf(im_return_type, "%s", tm);
|
||||
|
||||
// Translate and write javadoc comment if flagged
|
||||
if (doxygen && doxygenTranslator->hasDocumentation(n)) {
|
||||
String *doxygen_comments = doxygenTranslator->getDocumentation(n, " ");
|
||||
if (comment_creation_chatter)
|
||||
Printf(function_code, "/* This was generated from constructionhandler() */\n");
|
||||
Printv(function_code, Char(doxygen_comments), NIL);
|
||||
Delete(doxygen_comments);
|
||||
}
|
||||
|
||||
Printf(function_code, " %s %s(", methodmods, proxy_class_name);
|
||||
Printf(helper_code, " static private %s SwigConstruct%s(", im_return_type, proxy_class_name);
|
||||
|
||||
|
|
@ -2778,7 +2869,8 @@ public:
|
|||
|
||||
/* Insert the javaconstruct typemap, doing the replacement for $directorconnect, as needed */
|
||||
Hash *attributes = NewHash();
|
||||
String *construct_tm = Copy(typemapLookup(n, "javaconstruct", Getattr(n, "name"),
|
||||
String *typemap_lookup_type = Getattr(getCurrentClass(), "classtypeobj");
|
||||
String *construct_tm = Copy(typemapLookup(n, "javaconstruct", typemap_lookup_type,
|
||||
WARN_JAVA_TYPEMAP_JAVACONSTRUCT_UNDEF, attributes));
|
||||
if (construct_tm) {
|
||||
if (!feature_director) {
|
||||
|
|
@ -2848,6 +2940,9 @@ public:
|
|||
if (proxy_flag) {
|
||||
Printv(destructor_call, full_imclass_name, ".", Swig_name_destroy(getNSpace(), symname), "(swigCPtr)", NIL);
|
||||
generateThrowsClause(n, destructor_throws_clause);
|
||||
const String *methodmods = Getattr(n, "feature:java:methodmodifiers");
|
||||
if (methodmods)
|
||||
Setattr(getCurrentClass(), "destructmethodmodifiers", methodmods);
|
||||
}
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
|
@ -2931,6 +3026,15 @@ public:
|
|||
String *pre_code = NewString("");
|
||||
String *post_code = NewString("");
|
||||
|
||||
// Translate and write javadoc comment if flagged
|
||||
if (doxygen && doxygenTranslator->hasDocumentation(n)) {
|
||||
String *doxygen_comments = doxygenTranslator->getDocumentation(n, " ");
|
||||
if (comment_creation_chatter)
|
||||
Printf(function_code, "/* This was generated from moduleClassFunctionHandler() */\n");
|
||||
Printv(function_code, doxygen_comments, NIL);
|
||||
Delete(doxygen_comments);
|
||||
}
|
||||
|
||||
if (l) {
|
||||
if (SwigType_type(Getattr(l, "type")) == T_VOID) {
|
||||
l = nextSibling(l);
|
||||
|
|
@ -3083,7 +3187,7 @@ public:
|
|||
}
|
||||
|
||||
generateThrowsClause(n, function_code);
|
||||
Printf(function_code, " %s\n\n", tm ? (const String *) tm : empty_string);
|
||||
Printf(function_code, " %s\n\n", tm ? tm : empty_string);
|
||||
Printv(module_class_code, function_code, NIL);
|
||||
|
||||
Delete(pre_code);
|
||||
|
|
@ -3748,18 +3852,16 @@ public:
|
|||
Printf(code_wrap->code, " (void)jcls;\n");
|
||||
Printf(code_wrap->code, " // Keep a local instance of the smart pointer around while we are using the raw pointer\n");
|
||||
Printf(code_wrap->code, " // Avoids using smart pointer specific API.\n");
|
||||
Printf(code_wrap->code, " %s *director = dynamic_cast<%s *>(obj->operator->());\n", dirClassName, dirClassName);
|
||||
Printf(code_wrap->code, " %s *director = static_cast<%s *>(obj->operator->());\n", dirClassName, dirClassName);
|
||||
}
|
||||
else {
|
||||
Printf(code_wrap->code, " %s *obj = *((%s **)&objarg);\n", norm_name, norm_name);
|
||||
Printf(code_wrap->code, " (void)jcls;\n");
|
||||
Printf(code_wrap->code, " %s *director = dynamic_cast<%s *>(obj);\n", dirClassName, dirClassName);
|
||||
Printf(code_wrap->code, " %s *director = static_cast<%s *>(obj);\n", dirClassName, dirClassName);
|
||||
}
|
||||
|
||||
Printf(code_wrap->code, " if (director) {\n");
|
||||
Printf(code_wrap->code, " director->swig_connect_director(jenv, jself, jenv->GetObjectClass(jself), "
|
||||
Printf(code_wrap->code, " director->swig_connect_director(jenv, jself, jenv->GetObjectClass(jself), "
|
||||
"(jswig_mem_own == JNI_TRUE), (jweak_global == JNI_TRUE));\n");
|
||||
Printf(code_wrap->code, " }\n");
|
||||
Printf(code_wrap->code, "}\n");
|
||||
|
||||
Wrapper_print(code_wrap, f_wrappers);
|
||||
|
|
@ -3778,8 +3880,17 @@ public:
|
|||
Printf(code_wrap->def,
|
||||
"SWIGEXPORT void JNICALL Java_%s%s_%s(JNIEnv *jenv, jclass jcls, jobject jself, jlong objarg, jboolean jtake_or_release) {\n",
|
||||
jnipackage, jni_imclass_name, changeown_jnimethod_name);
|
||||
Printf(code_wrap->code, " %s *obj = *((%s **)&objarg);\n", norm_name, norm_name);
|
||||
Printf(code_wrap->code, " %s *director = dynamic_cast<%s *>(obj);\n", dirClassName, dirClassName);
|
||||
|
||||
if (Len(smartptr)) {
|
||||
Printf(code_wrap->code, " %s *obj = *((%s **)&objarg);\n", smartptr, smartptr);
|
||||
Printf(code_wrap->code, " // Keep a local instance of the smart pointer around while we are using the raw pointer\n");
|
||||
Printf(code_wrap->code, " // Avoids using smart pointer specific API.\n");
|
||||
Printf(code_wrap->code, " %s *director = dynamic_cast<%s *>(obj->operator->());\n", dirClassName, dirClassName);
|
||||
} else {
|
||||
Printf(code_wrap->code, " %s *obj = *((%s **)&objarg);\n", norm_name, norm_name);
|
||||
Printf(code_wrap->code, " %s *director = dynamic_cast<%s *>(obj);\n", dirClassName, dirClassName);
|
||||
}
|
||||
|
||||
Printf(code_wrap->code, " (void)jcls;\n");
|
||||
Printf(code_wrap->code, " if (director) {\n");
|
||||
Printf(code_wrap->code, " director->swig_java_change_ownership(jenv, jself, jtake_or_release ? true : false);\n");
|
||||
|
|
@ -3960,15 +4071,17 @@ public:
|
|||
/* If returning a reference, initialize the pointer to a sane
|
||||
default - if a Java exception occurs, then the pointer returns
|
||||
something other than a NULL-initialized reference. */
|
||||
String *non_ref_type = Copy(returntype);
|
||||
SwigType *noref_type = SwigType_del_reference(Copy(returntype));
|
||||
String *noref_ltype = SwigType_lstr(noref_type, 0);
|
||||
String *return_ltype = SwigType_lstr(returntype, 0);
|
||||
|
||||
/* Remove reference and const qualifiers */
|
||||
Replaceall(non_ref_type, "r.", "");
|
||||
Replaceall(non_ref_type, "q(const).", "");
|
||||
Wrapper_add_localv(w, "result_default", "static", SwigType_str(non_ref_type, "result_default"), "=", SwigType_str(non_ref_type, "()"), NIL);
|
||||
Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= &result_default", NIL);
|
||||
|
||||
Delete(non_ref_type);
|
||||
Wrapper_add_localv(w, "result_default", "static", noref_ltype, "result_default", NIL);
|
||||
Wrapper_add_localv(w, "c_result", return_ltype, "c_result", NIL);
|
||||
Printf(w->code, "result_default = SwigValueInit< %s >();\n", noref_ltype);
|
||||
Printf(w->code, "c_result = &result_default;\n");
|
||||
Delete(return_ltype);
|
||||
Delete(noref_ltype);
|
||||
Delete(noref_type);
|
||||
}
|
||||
|
||||
Delete(base_typename);
|
||||
|
|
@ -4059,7 +4172,7 @@ public:
|
|||
Swig_typemap_attach_parms("out", l, 0);
|
||||
Swig_typemap_attach_parms("jni", l, 0);
|
||||
Swig_typemap_attach_parms("jtype", l, 0);
|
||||
Swig_typemap_attach_parms("directorin", l, 0);
|
||||
Swig_typemap_attach_parms("directorin", l, w);
|
||||
Swig_typemap_attach_parms("javadirectorin", l, 0);
|
||||
Swig_typemap_attach_parms("directorargout", l, w);
|
||||
|
||||
|
|
@ -4258,11 +4371,11 @@ public:
|
|||
/* header declaration, start wrapper definition */
|
||||
String *target;
|
||||
SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type");
|
||||
target = Swig_method_decl(rtype, decl, qualified_name, l, 0, 0);
|
||||
target = Swig_method_decl(rtype, decl, qualified_name, l, 0);
|
||||
Printf(w->def, "%s", target);
|
||||
Delete(qualified_name);
|
||||
Delete(target);
|
||||
target = Swig_method_decl(rtype, decl, name, l, 0, 1);
|
||||
target = Swig_method_decl(rtype, decl, name, l, 1);
|
||||
Printf(declaration, " virtual %s", target);
|
||||
Delete(target);
|
||||
|
||||
|
|
@ -4281,6 +4394,10 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
if (Getattr(n, "noexcept")) {
|
||||
Append(w->def, " noexcept");
|
||||
Append(declaration, " noexcept");
|
||||
}
|
||||
if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) {
|
||||
int gencomma = 0;
|
||||
|
||||
|
|
@ -4387,7 +4504,7 @@ public:
|
|||
for (p = l; p;) {
|
||||
if ((tm = Getattr(p, "tmap:directorargout"))) {
|
||||
addThrows(n, "tmap:directorargout", p);
|
||||
Replaceall(tm, "$result", "jresult");
|
||||
Replaceall(tm, "$result", makeParameterName(n, p, i, false));
|
||||
Replaceall(tm, "$input", Getattr(p, "emit:directorinput"));
|
||||
Printv(w->code, tm, "\n", NIL);
|
||||
p = Getattr(p, "tmap:directorargout:next");
|
||||
|
|
@ -4472,9 +4589,9 @@ public:
|
|||
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, "if ($error) {");
|
||||
Printf(directorexcept, "$directorthrowshandlers\n");
|
||||
Printf(directorexcept, " Swig::DirectorException::raise(jenv, $error);\n");
|
||||
Printf(directorexcept, "}\n");
|
||||
} else {
|
||||
directorexcept = Copy(directorexcept);
|
||||
|
|
@ -4573,7 +4690,7 @@ public:
|
|||
/* constructor */
|
||||
{
|
||||
String *basetype = Getattr(parent, "classtype");
|
||||
String *target = Swig_method_decl(0, decl, dirclassname, parms, 0, 0);
|
||||
String *target = Swig_method_decl(0, decl, dirclassname, parms, 0);
|
||||
String *call = Swig_csuperclass_call(0, basetype, superparms);
|
||||
String *classtype = SwigType_namestr(Getattr(n, "name"));
|
||||
|
||||
|
|
@ -4587,7 +4704,7 @@ public:
|
|||
|
||||
/* constructor header */
|
||||
{
|
||||
String *target = Swig_method_decl(0, decl, dirclassname, parms, 0, 1);
|
||||
String *target = Swig_method_decl(0, decl, dirclassname, parms, 1);
|
||||
Printf(f_directors_h, " %s;\n", target);
|
||||
Delete(target);
|
||||
}
|
||||
|
|
@ -4659,9 +4776,12 @@ public:
|
|||
String *dirClassName = directorClassName(current_class);
|
||||
Wrapper *w = NewWrapper();
|
||||
|
||||
if (Getattr(n, "throw")) {
|
||||
Printf(f_directors_h, " virtual ~%s() throw ();\n", dirClassName);
|
||||
Printf(w->def, "%s::~%s() throw () {\n", dirClassName, dirClassName);
|
||||
if (Getattr(n, "noexcept")) {
|
||||
Printf(f_directors_h, " virtual ~%s() noexcept;\n", dirClassName);
|
||||
Printf(w->def, "%s::~%s() noexcept {\n", dirClassName, dirClassName);
|
||||
} else if (Getattr(n, "throw")) {
|
||||
Printf(f_directors_h, " virtual ~%s() throw();\n", dirClassName);
|
||||
Printf(w->def, "%s::~%s() throw() {\n", dirClassName, dirClassName);
|
||||
} else {
|
||||
Printf(f_directors_h, " virtual ~%s();\n", dirClassName);
|
||||
Printf(w->def, "%s::~%s() {\n", dirClassName, dirClassName);
|
||||
|
|
@ -4864,6 +4984,9 @@ extern "C" Language *swig_java(void) {
|
|||
|
||||
const char *JAVA::usage = "\
|
||||
Java Options (available with -java)\n\
|
||||
-doxygen - Convert C++ doxygen comments to JavaDoc comments in proxy classes\n\
|
||||
-debug-doxygen-parser - Display doxygen parser module debugging information\n\
|
||||
-debug-doxygen-translator - Display doxygen translator module debugging information\n\
|
||||
-nopgcpp - Suppress premature garbage collection prevention parameter\n\
|
||||
-noproxy - Generate the low-level functional interface instead\n\
|
||||
of proxy classes\n\
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ static bool js_template_enable_debug = false;
|
|||
#define GETTER "getter"
|
||||
#define SETTER "setter"
|
||||
#define PARENT "parent"
|
||||
#define PARENT_MANGLED "parent_mangled"
|
||||
#define CTOR "ctor"
|
||||
#define CTOR_WRAPPERS "ctor_wrappers"
|
||||
#define CTOR_DISPATCHERS "ctor_dispatchers"
|
||||
|
|
@ -262,7 +263,7 @@ protected:
|
|||
|
||||
virtual int createNamespace(String *scope);
|
||||
|
||||
virtual Hash *createNamespaceEntry(const char *name, const char *parent);
|
||||
virtual Hash *createNamespaceEntry(const char *name, const char *parent, const char *parent_mangled);
|
||||
|
||||
virtual int emitNamespaces() = 0;
|
||||
|
||||
|
|
@ -462,10 +463,10 @@ int JAVASCRIPT::fragmentDirective(Node *n) {
|
|||
// and register them at the emitter.
|
||||
String *section = Getattr(n, "section");
|
||||
|
||||
if (Equal(section, "templates")) {
|
||||
if (Equal(section, "templates") && !ImportMode) {
|
||||
emitter->registerTemplate(Getattr(n, "value"), Getattr(n, "code"));
|
||||
} else {
|
||||
Swig_fragment_register(n);
|
||||
return Language::fragmentDirective(n);
|
||||
}
|
||||
|
||||
return SWIG_OK;
|
||||
|
|
@ -552,7 +553,7 @@ void JAVASCRIPT::main(int argc, char *argv[]) {
|
|||
emitter = swig_javascript_create_V8Emitter();
|
||||
Preprocessor_define("SWIG_JAVASCRIPT_V8 1", 0);
|
||||
SWIG_library_directory("javascript/v8");
|
||||
// V8 API is C++, so output must be C++ compatibile even when wrapping C code
|
||||
// V8 API is C++, so output must be C++ compatible even when wrapping C code
|
||||
if (!cparse_cplusplus) {
|
||||
Swig_cparse_cplusplusout(1);
|
||||
}
|
||||
|
|
@ -664,7 +665,7 @@ int JSEmitter::initialize(Node * /*n */ ) {
|
|||
Delete(namespaces);
|
||||
}
|
||||
namespaces = NewHash();
|
||||
Hash *global_namespace = createNamespaceEntry("exports", 0);
|
||||
Hash *global_namespace = createNamespaceEntry("exports", 0, 0);
|
||||
|
||||
Setattr(namespaces, "::", global_namespace);
|
||||
current_namespace = global_namespace;
|
||||
|
|
@ -993,7 +994,7 @@ int JSEmitter::emitDtor(Node *n) {
|
|||
|
||||
Also, there is a problem where destructor_action is always true for me, even when not requesting %extend as above.
|
||||
So this code doesn't actually quite work as I expect. The end result is that the code still works because
|
||||
destructor_action calls free like the original template. The one caveat is the string in destructor_action casts to char* which is wierd.
|
||||
destructor_action calls free like the original template. The one caveat is the string in destructor_action casts to char* which is weird.
|
||||
I think there is a deeper underlying SWIG issue because I don't think it should be char*. However, it doesn't really matter for free.
|
||||
|
||||
Maybe the fix for the destructor_action always true problem is that this is supposed to be embedded in the if(Extend) block above.
|
||||
|
|
@ -1124,7 +1125,7 @@ int JSEmitter::emitConstant(Node *n) {
|
|||
Template t_getter(getTemplate("js_getter"));
|
||||
|
||||
// call the variable methods as a constants are
|
||||
// registred in same way
|
||||
// registered in same way
|
||||
enterVariable(n);
|
||||
state.variable(GETTER, wname);
|
||||
// TODO: why do we need this?
|
||||
|
|
@ -1354,6 +1355,11 @@ void JSEmitter::emitCleanupCode(Node *n, Wrapper *wrapper, ParmList *params) {
|
|||
}
|
||||
}
|
||||
|
||||
/* See if there is any return cleanup code */
|
||||
if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
|
||||
Printf(wrapper->code, "%s\n", tm);
|
||||
Delete(tm);
|
||||
}
|
||||
}
|
||||
|
||||
int JSEmitter::switchNamespace(Node *n) {
|
||||
|
|
@ -1423,19 +1429,20 @@ int JSEmitter::createNamespace(String *scope) {
|
|||
}
|
||||
assert(parent_namespace != 0);
|
||||
|
||||
Hash *new_namespace = createNamespaceEntry(Char(scope), Char(Getattr(parent_namespace, "name")));
|
||||
Hash *new_namespace = createNamespaceEntry(Char(scope), Char(Getattr(parent_namespace, "name")), Char(Getattr(parent_namespace, "name_mangled")));
|
||||
Setattr(namespaces, scope, new_namespace);
|
||||
|
||||
Delete(parent_scope);
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
Hash *JSEmitter::createNamespaceEntry(const char *_name, const char *parent) {
|
||||
Hash *JSEmitter::createNamespaceEntry(const char *_name, const char *parent, const char *parent_mangled) {
|
||||
Hash *entry = NewHash();
|
||||
String *name = NewString(_name);
|
||||
Setattr(entry, NAME, Swig_scopename_last(name));
|
||||
Setattr(entry, NAME_MANGLED, Swig_name_mangle(name));
|
||||
Setattr(entry, PARENT, NewString(parent));
|
||||
Setattr(entry, PARENT_MANGLED, NewString(parent_mangled));
|
||||
|
||||
Delete(name);
|
||||
return entry;
|
||||
|
|
@ -1462,7 +1469,7 @@ protected:
|
|||
virtual int enterClass(Node *n);
|
||||
virtual int exitClass(Node *n);
|
||||
virtual void marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static);
|
||||
virtual Hash *createNamespaceEntry(const char *name, const char *parent);
|
||||
virtual Hash *createNamespaceEntry(const char *name, const char *parent, const char *parent_mangled);
|
||||
virtual int emitNamespaces();
|
||||
|
||||
private:
|
||||
|
|
@ -1768,8 +1775,8 @@ int JSCEmitter::exitClass(Node *n) {
|
|||
return SWIG_OK;
|
||||
}
|
||||
|
||||
Hash *JSCEmitter::createNamespaceEntry(const char *name, const char *parent) {
|
||||
Hash *entry = JSEmitter::createNamespaceEntry(name, parent);
|
||||
Hash *JSCEmitter::createNamespaceEntry(const char *name, const char *parent, const char *parent_mangled) {
|
||||
Hash *entry = JSEmitter::createNamespaceEntry(name, parent, parent_mangled);
|
||||
Setattr(entry, "functions", NewString(""));
|
||||
Setattr(entry, "values", NewString(""));
|
||||
return entry;
|
||||
|
|
@ -1781,8 +1788,7 @@ int JSCEmitter::emitNamespaces() {
|
|||
Hash *entry = it.item;
|
||||
String *name = Getattr(entry, NAME);
|
||||
String *name_mangled = Getattr(entry, NAME_MANGLED);
|
||||
String *parent = Getattr(entry, PARENT);
|
||||
String *parent_mangled = Swig_name_mangle(parent);
|
||||
String *parent_mangled = Getattr(entry, PARENT_MANGLED);
|
||||
String *functions = Getattr(entry, "functions");
|
||||
String *variables = Getattr(entry, "values");
|
||||
|
||||
|
|
@ -2032,7 +2038,7 @@ int V8Emitter::exitClass(Node *n) {
|
|||
.pretty_print(f_init_inheritance);
|
||||
Delete(base_name_mangled);
|
||||
}
|
||||
// emit registeration of class template
|
||||
// emit registration of class template
|
||||
Template t_register = getTemplate("jsv8_register_class");
|
||||
t_register.replace("$jsmangledname", state.clazz(NAME_MANGLED))
|
||||
.replace("$jsname", state.clazz(NAME))
|
||||
|
|
@ -2201,7 +2207,7 @@ int V8Emitter::emitNamespaces() {
|
|||
String *name = Getattr(entry, NAME);
|
||||
String *name_mangled = Getattr(entry, NAME_MANGLED);
|
||||
String *parent = Getattr(entry, PARENT);
|
||||
String *parent_mangled = Swig_name_mangle(parent);
|
||||
String *parent_mangled = Getattr(entry, PARENT_MANGLED);
|
||||
|
||||
bool do_create = true;
|
||||
bool do_register = true;
|
||||
|
|
@ -2422,7 +2428,7 @@ Template & Template::trim() {
|
|||
/* -----------------------------------------------------------------------------
|
||||
* Template& Template::replace(const String* pattern, const String* repl) :
|
||||
*
|
||||
* replaces all occurences of a given pattern with a given replacement.
|
||||
* replaces all occurrences of a given pattern with a given replacement.
|
||||
*
|
||||
* - pattern: the pattern to be replaced
|
||||
* - repl: the replacement string
|
||||
|
|
|
|||
|
|
@ -81,7 +81,6 @@ extern int AddExtern;
|
|||
/* import modes */
|
||||
|
||||
#define IMPORT_MODE 1
|
||||
#define IMPORT_MODULE 2
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Dispatcher::emit_one()
|
||||
|
|
@ -308,15 +307,12 @@ int Dispatcher::namespaceDeclaration(Node *n) {
|
|||
return defaultHandler(n);
|
||||
}
|
||||
|
||||
|
||||
/* Allocators */
|
||||
Language::Language():
|
||||
none_comparison(NewString("$arg != 0")),
|
||||
director_ctor_code(NewString("")),
|
||||
director_prot_ctor_code(0),
|
||||
symtabs(NewHash()),
|
||||
classtypes(NewHash()),
|
||||
enumtypes(NewHash()),
|
||||
overloading(0),
|
||||
multiinput(0),
|
||||
cplus_runtime(0),
|
||||
|
|
@ -337,12 +333,12 @@ directors(0) {
|
|||
director_language = 0;
|
||||
assert(!this_);
|
||||
this_ = this;
|
||||
|
||||
doxygenTranslator = NULL;
|
||||
}
|
||||
|
||||
Language::~Language() {
|
||||
Delete(symtabs);
|
||||
Delete(classtypes);
|
||||
Delete(enumtypes);
|
||||
Delete(director_ctor_code);
|
||||
Delete(none_comparison);
|
||||
this_ = 0;
|
||||
|
|
@ -625,7 +621,8 @@ int Language::constantDirective(Node *n) {
|
|||
* ---------------------------------------------------------------------- */
|
||||
|
||||
int Language::fragmentDirective(Node *n) {
|
||||
Swig_fragment_register(n);
|
||||
if (!(Getattr(n, "emitonly") && ImportMode))
|
||||
Swig_fragment_register(n);
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
|
|
@ -870,7 +867,7 @@ int Language::cDeclaration(Node *n) {
|
|||
} else {
|
||||
// Found an unignored templated method that has an empty template instantiation (%template())
|
||||
// Ignore it unless it has been %rename'd
|
||||
if (Strncmp(symname, "__dummy_", 8) == 0) {
|
||||
if (Strncmp(symname, "__dummy_", 8) == 0 && Cmp(storage, "typedef") != 0) {
|
||||
SetFlag(n, "feature:ignore");
|
||||
Swig_warning(WARN_LANG_TEMPLATE_METHOD_IGNORE, input_file, line_number,
|
||||
"%%template() contains no name. Template method ignored: %s\n", Swig_name_decl(n));
|
||||
|
|
@ -1084,6 +1081,8 @@ int Language::functionHandler(Node *n) {
|
|||
globalfunctionHandler(n);
|
||||
InClass = oldInClass;
|
||||
} else {
|
||||
// This is a member function, set a flag so the documentation type is correct
|
||||
SetFlag(n, "memberfunction");
|
||||
Node *explicit_n = 0;
|
||||
if (directorsEnabled() && is_member_director(CurrentClass, n) && !extraDirectorProtectedCPPMethodsRequired()) {
|
||||
bool virtual_but_not_pure_virtual = (!(Cmp(storage, "virtual")) && (Cmp(Getattr(n, "value"), "0") != 0));
|
||||
|
|
@ -1145,7 +1144,9 @@ int Language::globalfunctionHandler(Node *n) {
|
|||
Delete(cbname);
|
||||
}
|
||||
Setattr(n, "parms", nonvoid_parms(parms));
|
||||
String *call = Swig_cfunction_call(name, parms);
|
||||
|
||||
String *extendname = Getattr(n, "extendname");
|
||||
String *call = Swig_cfunction_call(extendname ? extendname : name, parms);
|
||||
String *cres = Swig_cresult(type, Swig_cresult_name(), call);
|
||||
Setattr(n, "wrap:action", cres);
|
||||
Delete(cres);
|
||||
|
|
@ -1267,9 +1268,13 @@ int Language::memberfunctionHandler(Node *n) {
|
|||
if (GetFlag(n, "explicitcall"))
|
||||
DirectorExtraCall = CWRAP_DIRECTOR_ONE_CALL;
|
||||
|
||||
Swig_MethodToFunction(n, NSpace, ClassType, Getattr(n, "template") ? SmartPointer : Extend | SmartPointer | DirectorExtraCall, director_type,
|
||||
is_member_director(CurrentClass, n));
|
||||
int extendmember = GetFlag(n, "isextendmember") ? Extend : 0;
|
||||
int flags = Getattr(n, "template") ? extendmember | SmartPointer : Extend | SmartPointer | DirectorExtraCall;
|
||||
Swig_MethodToFunction(n, NSpace, ClassType, flags, director_type, is_member_director(CurrentClass, n));
|
||||
Setattr(n, "sym:name", fname);
|
||||
/* Explicitly save low-level and high-level documentation names */
|
||||
Setattr(n, "doc:low:name", fname);
|
||||
Setattr(n, "doc:high:name", symname);
|
||||
|
||||
functionWrapper(n);
|
||||
|
||||
|
|
@ -1321,12 +1326,18 @@ int Language::staticmemberfunctionHandler(Node *n) {
|
|||
|
||||
if (!defaultargs && code) {
|
||||
/* Hmmm. An added static member. We have to create a little wrapper for this */
|
||||
Swig_add_extension_code(n, cname, parms, type, code, CPlusPlus, 0);
|
||||
String *mangled_cname = Swig_name_mangle(cname);
|
||||
Swig_add_extension_code(n, mangled_cname, parms, type, code, CPlusPlus, 0);
|
||||
Setattr(n, "extendname", mangled_cname);
|
||||
Delete(mangled_cname);
|
||||
}
|
||||
}
|
||||
|
||||
Setattr(n, "name", cname);
|
||||
Setattr(n, "sym:name", mrename);
|
||||
/* Explicitly save low-level and high-level documentation names */
|
||||
Setattr(n, "doc:low:name", mrename);
|
||||
Setattr(n, "doc:high:name", symname);
|
||||
|
||||
if (cb) {
|
||||
String *cbname = NewStringf(cb, symname);
|
||||
|
|
@ -1883,6 +1894,8 @@ int Language::unrollVirtualMethods(Node *n, Node *parent, List *vm, int default_
|
|||
}
|
||||
if (!checkAttribute(nn, "storage", "virtual"))
|
||||
continue;
|
||||
if (GetFlag(nn, "final"))
|
||||
continue;
|
||||
/* we need to add methods(cdecl) and destructor (to check for throw decl) */
|
||||
int is_destructor = (Cmp(nodeType, "destructor") == 0);
|
||||
if ((Cmp(nodeType, "cdecl") == 0) || is_destructor) {
|
||||
|
|
@ -1943,7 +1956,7 @@ int Language::unrollVirtualMethods(Node *n, Node *parent, List *vm, int default_
|
|||
generation of 'empty' director classes.
|
||||
|
||||
But this has to be done outside the previous 'for'
|
||||
an the recursive loop!.
|
||||
and the recursive loop!.
|
||||
*/
|
||||
if (n == parent) {
|
||||
int len = Len(vm);
|
||||
|
|
@ -2072,7 +2085,7 @@ int Language::classDirectorConstructors(Node *n) {
|
|||
needed, since there is a public constructor already defined.
|
||||
|
||||
(scottm) This code is needed here to make the director_abstract +
|
||||
test generate compilable code (Example2 in director_abastract.i).
|
||||
test generate compilable code (Example2 in director_abstract.i).
|
||||
|
||||
(mmatus) This is very strange, since swig compiled with gcc3.2.3
|
||||
doesn't need it here....
|
||||
|
|
@ -2098,7 +2111,7 @@ int Language::classDirectorMethods(Node *n) {
|
|||
Node *item = Getitem(vtable, i);
|
||||
String *method = Getattr(item, "methodNode");
|
||||
String *fqdname = Getattr(item, "fqdname");
|
||||
if (GetFlag(method, "feature:nodirector"))
|
||||
if (GetFlag(method, "feature:nodirector") || GetFlag(method, "final"))
|
||||
continue;
|
||||
|
||||
String *wrn = Getattr(method, "feature:warnfilter");
|
||||
|
|
@ -2145,8 +2158,8 @@ int Language::classDirectorDestructor(Node *n) {
|
|||
File *f_directors = Swig_filebyname("director");
|
||||
File *f_directors_h = Swig_filebyname("director_h");
|
||||
if (Getattr(n, "throw")) {
|
||||
Printf(f_directors_h, " virtual ~%s() throw ();\n", DirectorClassName);
|
||||
Printf(f_directors, "%s::~%s() throw () {\n}\n\n", DirectorClassName, DirectorClassName);
|
||||
Printf(f_directors_h, " virtual ~%s() throw();\n", DirectorClassName);
|
||||
Printf(f_directors, "%s::~%s() throw() {\n}\n\n", DirectorClassName, DirectorClassName);
|
||||
} else {
|
||||
Printf(f_directors_h, " virtual ~%s();\n", DirectorClassName);
|
||||
Printf(f_directors, "%s::~%s() {\n}\n\n", DirectorClassName, DirectorClassName);
|
||||
|
|
@ -2187,6 +2200,16 @@ int Language::classDirector(Node *n) {
|
|||
String *using_protected_members_code = NewString("");
|
||||
for (ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) {
|
||||
Node *nodeType = Getattr(ni, "nodeType");
|
||||
if (Cmp(nodeType, "destructor") == 0 && GetFlag(ni, "final")) {
|
||||
String *classtype = Getattr(n, "classtype");
|
||||
SWIG_WARN_NODE_BEGIN(ni);
|
||||
Swig_warning(WARN_LANG_DIRECTOR_FINAL, input_file, line_number, "Destructor %s is final, %s cannot be a director class.\n", Swig_name_decl(ni), classtype);
|
||||
SWIG_WARN_NODE_END(ni);
|
||||
SetFlag(n, "feature:nodirector");
|
||||
Delete(vtable);
|
||||
Delete(using_protected_members_code);
|
||||
return SWIG_OK;
|
||||
}
|
||||
bool cdeclaration = (Cmp(nodeType, "cdecl") == 0);
|
||||
if (cdeclaration && !GetFlag(ni, "feature:ignore")) {
|
||||
if (isNonVirtualProtectedAccess(ni)) {
|
||||
|
|
@ -2785,7 +2808,9 @@ int Language::constructorHandler(Node *n) {
|
|||
Setattr(n, "handled_as_constructor", "1");
|
||||
}
|
||||
|
||||
Swig_ConstructorToFunction(n, NSpace, ClassType, none_comparison, director_ctor, CPlusPlus, Getattr(n, "template") ? 0 : Extend, DirectorClassName);
|
||||
int extendmember = GetFlag(n, "isextendmember") ? Extend : 0;
|
||||
int flags = Getattr(n, "template") ? extendmember : Extend;
|
||||
Swig_ConstructorToFunction(n, NSpace, ClassType, none_comparison, director_ctor, CPlusPlus, flags, DirectorClassName);
|
||||
Setattr(n, "sym:name", mrename);
|
||||
functionWrapper(n);
|
||||
Delete(mrename);
|
||||
|
|
@ -3256,11 +3281,13 @@ Node *Language::symbolLookup(const String *s, const_String_or_char_ptr scope) {
|
|||
* Tries to locate a class from a type definition
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
Node *Language::classLookup(const SwigType *s) const {
|
||||
Node *Language::classLookup(const SwigType *s) {
|
||||
static Hash *classtypes = 0;
|
||||
|
||||
Node *n = 0;
|
||||
|
||||
/* Look in hash of cached values */
|
||||
n = Getattr(classtypes, s);
|
||||
n = classtypes ? Getattr(classtypes, s) : 0;
|
||||
if (!n) {
|
||||
Symtab *stab = 0;
|
||||
SwigType *ty1 = SwigType_typedef_resolve_all(s);
|
||||
|
|
@ -3288,6 +3315,14 @@ Node *Language::classLookup(const SwigType *s) const {
|
|||
break;
|
||||
if (Strcmp(nodeType(n), "class") == 0)
|
||||
break;
|
||||
Node *sibling = n;
|
||||
while (sibling) {
|
||||
sibling = Getattr(sibling, "csym:nextSibling");
|
||||
if (sibling && Strcmp(nodeType(sibling), "class") == 0)
|
||||
break;
|
||||
}
|
||||
if (sibling)
|
||||
break;
|
||||
n = parentNode(n);
|
||||
if (!n)
|
||||
break;
|
||||
|
|
@ -3300,7 +3335,7 @@ Node *Language::classLookup(const SwigType *s) const {
|
|||
}
|
||||
if (n) {
|
||||
/* Found a match. Look at the prefix. We only allow
|
||||
the cases where where we want a proxy class for the particular type */
|
||||
the cases where we want a proxy class for the particular type */
|
||||
bool acceptable_prefix =
|
||||
(Len(prefix) == 0) || // simple type (pass by value)
|
||||
(Strcmp(prefix, "p.") == 0) || // pointer
|
||||
|
|
@ -3315,6 +3350,8 @@ Node *Language::classLookup(const SwigType *s) const {
|
|||
}
|
||||
if (acceptable_prefix) {
|
||||
SwigType *cs = Copy(s);
|
||||
if (!classtypes)
|
||||
classtypes = NewHash();
|
||||
Setattr(classtypes, cs, n);
|
||||
Delete(cs);
|
||||
} else {
|
||||
|
|
@ -3341,10 +3378,12 @@ Node *Language::classLookup(const SwigType *s) const {
|
|||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
Node *Language::enumLookup(SwigType *s) {
|
||||
static Hash *enumtypes = 0;
|
||||
|
||||
Node *n = 0;
|
||||
|
||||
/* Look in hash of cached values */
|
||||
n = Getattr(enumtypes, s);
|
||||
n = enumtypes ? Getattr(enumtypes, s) : 0;
|
||||
if (!n) {
|
||||
Symtab *stab = 0;
|
||||
SwigType *lt = SwigType_ltype(s);
|
||||
|
|
@ -3385,6 +3424,8 @@ Node *Language::enumLookup(SwigType *s) {
|
|||
if (n) {
|
||||
/* Found a match. Look at the prefix. We only allow simple types. */
|
||||
if (Len(prefix) == 0) { /* Simple type */
|
||||
if (!enumtypes)
|
||||
enumtypes = NewHash();
|
||||
Setattr(enumtypes, Copy(s), n);
|
||||
} else {
|
||||
n = 0;
|
||||
|
|
@ -3505,7 +3546,7 @@ int Language::need_nonpublic_ctor(Node *n) {
|
|||
|
||||
Note: given all the complications here, I am always in favor to
|
||||
always enable 'dirprot', since is the C++ idea of protected
|
||||
members, and use %ignore for the method you don't whan to add in
|
||||
members, and use %ignore for the method you don't want to add in
|
||||
the director class.
|
||||
*/
|
||||
if (directorsEnabled()) {
|
||||
|
|
@ -3581,7 +3622,7 @@ String *Language::makeParameterName(Node *n, Parm *p, int arg_num, bool setter)
|
|||
String *arg = 0;
|
||||
String *pn = Getattr(p, "name");
|
||||
|
||||
// Use C parameter name unless it is a duplicate or an empty parameter name
|
||||
// Check if parameter name is a duplicate.
|
||||
int count = 0;
|
||||
ParmList *plist = Getattr(n, "parms");
|
||||
while (plist) {
|
||||
|
|
@ -3589,8 +3630,14 @@ String *Language::makeParameterName(Node *n, Parm *p, int arg_num, bool setter)
|
|||
count++;
|
||||
plist = nextSibling(plist);
|
||||
}
|
||||
String *wrn = pn ? Swig_name_warning(p, 0, pn, 0) : 0;
|
||||
arg = (!pn || (count > 1) || wrn) ? NewStringf("arg%d", arg_num) : Copy(pn);
|
||||
|
||||
// If the parameter has no name at all or has a non-unique name, replace it with "argN".
|
||||
if (!pn || count > 1) {
|
||||
arg = NewStringf("arg%d", arg_num);
|
||||
} else {
|
||||
// Otherwise, try to use the original C name, but modify it if necessary to avoid conflicting with the language keywords.
|
||||
arg = Swig_name_make(p, 0, pn, 0, 0);
|
||||
}
|
||||
|
||||
if (setter && Cmp(arg, "self") != 0) {
|
||||
// Some languages (C#) insist on calling the input variable "value" while
|
||||
|
|
@ -3765,7 +3812,7 @@ int Language::abstractClassTest(Node *n) {
|
|||
if (dirabstract) {
|
||||
if (is_public(dirabstract)) {
|
||||
Swig_warning(WARN_LANG_DIRECTOR_ABSTRACT, Getfile(n), Getline(n),
|
||||
"Director class '%s' is abstract, abstract method '%s' is not accesible, maybe due to multiple inheritance or 'nodirector' feature\n",
|
||||
"Director class '%s' is abstract, abstract method '%s' is not accessible, maybe due to multiple inheritance or 'nodirector' feature\n",
|
||||
SwigType_namestr(Getattr(n, "name")), Getattr(dirabstract, "name"));
|
||||
} else {
|
||||
Swig_warning(WARN_LANG_DIRECTOR_ABSTRACT, Getfile(n), Getline(n),
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ private:
|
|||
// This variable holds the name of the current class in Lua. Usually it is
|
||||
// the same as C++ class name, but rename directives can change it.
|
||||
String *proxy_class_name;
|
||||
// This is a so calld fully qualified symname - the above proxy class name
|
||||
// This is a so called fully qualified symname - the above proxy class name
|
||||
// prepended with class namespace. If class Lua name is the same as class C++ name,
|
||||
// then it is basically C++ fully qualified name with colons replaced with dots.
|
||||
String *full_proxy_class_name;
|
||||
|
|
@ -1359,7 +1359,7 @@ public:
|
|||
String *rt = Copy(getClassType());
|
||||
SwigType_add_pointer(rt);
|
||||
|
||||
// Adding class to apropriate namespace
|
||||
// Adding class to appropriate namespace
|
||||
registerClass(nspace, wrap_class_name);
|
||||
Hash *nspaceHash = getCArraysHash(nspace);
|
||||
|
||||
|
|
@ -1461,7 +1461,7 @@ public:
|
|||
assert(proxy_class_name);
|
||||
assert(full_proxy_class_name);
|
||||
|
||||
// Then print class isntance part
|
||||
// Then print class instance part
|
||||
Printv(f_wrappers, "static swig_lua_class *swig_", mangled_full_proxy_class_name, "_bases[] = {", base_class, "0};\n", NIL);
|
||||
Delete(base_class);
|
||||
Printv(f_wrappers, "static const char *swig_", mangled_full_proxy_class_name, "_base_names[] = {", base_class_names, "0};\n", NIL);
|
||||
|
|
@ -1755,7 +1755,7 @@ public:
|
|||
*
|
||||
* This is to convert the string of Lua code into a proper string, which can then be
|
||||
* emitted into the C/C++ code.
|
||||
* Basically is is a lot of search & replacing of odd sequences
|
||||
* Basically it is a lot of search & replacing of odd sequences
|
||||
* ---------------------------------------------------------------------------- */
|
||||
|
||||
void escapeCode(String *str) {
|
||||
|
|
@ -1770,7 +1770,7 @@ public:
|
|||
/* -----------------------------------------------------------------------------
|
||||
* rawGetCArraysHash(String *name)
|
||||
*
|
||||
* A small helper to hide impelementation of how CArrays hashes are stored
|
||||
* A small helper to hide implementation of how CArrays hashes are stored
|
||||
* ---------------------------------------------------------------------------- */
|
||||
|
||||
Hash *rawGetCArraysHash(const_String_or_char_ptr name) {
|
||||
|
|
@ -2110,7 +2110,7 @@ public:
|
|||
// variable in resulting file
|
||||
getCArraysHash(0);
|
||||
}
|
||||
// Because we cant access directly 'symtabs', instead we access
|
||||
// Because we can't directly access 'symtabs', instead we access
|
||||
// top-level scope and look on all scope pseudo-symbols in it.
|
||||
Hash *top_scope = symbolScopeLookup("");
|
||||
assert(top_scope);
|
||||
|
|
@ -2193,7 +2193,7 @@ public:
|
|||
|
||||
String *luaCurrentSymbolNSpace() {
|
||||
String *scope = 0;
|
||||
// If ouside class, than NSpace is used.
|
||||
// If outside class, than NSpace is used.
|
||||
// If inside class, but current[NO_CPP], then this is friend function. It belongs to NSpace
|
||||
if (!getCurrentClass() || current[NO_CPP]) {
|
||||
scope = getNSpace();
|
||||
|
|
|
|||
|
|
@ -38,14 +38,15 @@ int NoExcept = 0;
|
|||
int SwigRuntime = 0; // 0 = no option, 1 = -runtime, 2 = -noruntime
|
||||
|
||||
/* Suppress warning messages for private inheritance, preprocessor evaluation etc...
|
||||
WARN_PP_EVALUATION 202
|
||||
WARN_PARSE_PRIVATE_INHERIT 309
|
||||
WARN_TYPE_ABSTRACT 403
|
||||
WARN_LANG_OVERLOAD_CONST 512
|
||||
WARN_PARSE_BUILTIN_NAME 321
|
||||
WARN_PARSE_REDUNDANT 322
|
||||
WARN_PP_EVALUATION 202
|
||||
WARN_PARSE_PRIVATE_INHERIT 309
|
||||
WARN_PARSE_BUILTIN_NAME 321
|
||||
WARN_PARSE_REDUNDANT 322
|
||||
WARN_TYPE_ABSTRACT 403
|
||||
WARN_TYPE_RVALUE_REF_QUALIFIER_IGNORED 405
|
||||
WARN_LANG_OVERLOAD_CONST 512
|
||||
*/
|
||||
#define EXTRA_WARNINGS "202,309,403,512,321,322"
|
||||
#define EXTRA_WARNINGS "202,309,403,405,512,321,322"
|
||||
|
||||
extern "C" {
|
||||
extern String *ModuleName;
|
||||
|
|
@ -64,7 +65,7 @@ static const char *usage1 = (const char *) "\
|
|||
-copyctor - Automatically generate copy constructors wherever possible\n\
|
||||
-cpperraswarn - Treat the preprocessor #error statement as #warning (default)\n\
|
||||
-cppext <ext> - Change file extension of generated C++ files to <ext>\n\
|
||||
(default is cxx, except for PHP which uses cpp)\n\
|
||||
(default is cxx)\n\
|
||||
-copyright - Display copyright notices\n\
|
||||
-debug-classes - Display information about the classes found in the interface\n\
|
||||
-debug-module <n>- Display module parse tree at stages 1-4, <n> is a csv list of stages\n\
|
||||
|
|
@ -96,7 +97,7 @@ static const char *usage2 = (const char *) "\
|
|||
-Fmicrosoft - Display error/warning messages in Microsoft format\n\
|
||||
-Fstandard - Display error/warning messages in commonly used format\n\
|
||||
-fvirtual - Compile in virtual elimination mode\n\
|
||||
-help - This output\n\
|
||||
-help - Display help\n\
|
||||
-I- - Don't search the current directory\n\
|
||||
-I<dir> - Look for SWIG files in directory <dir>\n\
|
||||
-ignoremissing - Ignore missing include files\n\
|
||||
|
|
@ -129,14 +130,14 @@ static const char *usage3 = (const char *) "\
|
|||
";
|
||||
|
||||
static const char *usage4 = (const char *) "\
|
||||
-O - Enable the optimization options: \n\
|
||||
-fastdispatch -fvirtual \n\
|
||||
-O - Enable the optimization options:\n\
|
||||
-fastdispatch -fvirtual\n\
|
||||
-o <outfile> - Set name of C/C++ output file to <outfile>\n\
|
||||
-oh <headfile> - Set name of C++ output header file for directors to <headfile>\n\
|
||||
-outcurrentdir - Set default output dir to current dir instead of input file's path\n\
|
||||
-outdir <dir> - Set language specific files output directory to <dir>\n\
|
||||
-pcreversion - Display PCRE version information\n\
|
||||
-small - Compile in virtual elimination & compact mode\n\
|
||||
-small - Compile in virtual elimination and compact mode\n\
|
||||
-swiglib - Report location of SWIG library and exit\n\
|
||||
-templatereduce - Reduce all the typedefs in templates\n\
|
||||
-v - Run in verbose mode\n\
|
||||
|
|
@ -154,10 +155,14 @@ Options can also be defined using the SWIG_FEATURES environment variable, for ex
|
|||
$ export SWIG_FEATURES\n\
|
||||
$ swig -python interface.i\n\
|
||||
\n\
|
||||
is equivalent to: \n\
|
||||
is equivalent to:\n\
|
||||
\n\
|
||||
$ swig -Wall -python interface.i \n\
|
||||
$ swig -Wall -python interface.i\n\
|
||||
\n\
|
||||
Arguments may also be passed in a file, separated by whitespace. For example:\n\
|
||||
\n\
|
||||
$ echo \"-Wall -python interface.i\" > args.txt\n\
|
||||
$ swig @args.txt\n\
|
||||
\n";
|
||||
|
||||
// Local variables
|
||||
|
|
@ -454,7 +459,7 @@ static void SWIG_dump_runtime() {
|
|||
SWIG_exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
void SWIG_getoptions(int argc, char *argv[]) {
|
||||
static void getoptions(int argc, char *argv[]) {
|
||||
int i;
|
||||
// Get options
|
||||
for (i = 1; i < argc; i++) {
|
||||
|
|
@ -873,7 +878,7 @@ void SWIG_getoptions(int argc, char *argv[]) {
|
|||
}
|
||||
}
|
||||
|
||||
int SWIG_main(int argc, char *argv[], Language *l) {
|
||||
int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm) {
|
||||
char *c;
|
||||
|
||||
/* Initialize the SWIG core */
|
||||
|
|
@ -885,7 +890,9 @@ int SWIG_main(int argc, char *argv[], Language *l) {
|
|||
// Initialize the preprocessor
|
||||
Preprocessor_init();
|
||||
|
||||
lang = l;
|
||||
// Set lang to a dummy value if no target language was specified so we
|
||||
// can process options enough to handle -version, etc.
|
||||
lang = tlm ? tlm->fac() : new Language;
|
||||
|
||||
// Set up some default symbols (available in both SWIG interface files
|
||||
// and C files)
|
||||
|
|
@ -918,9 +925,9 @@ int SWIG_main(int argc, char *argv[], Language *l) {
|
|||
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;
|
||||
ignore_nested_classes = lang->nestedClassesSupport() == Language::NCS_Unknown ? 1 : 0;
|
||||
|
||||
kwargs_supported = l->kwargsSupport() ? 1 : 0;
|
||||
kwargs_supported = lang->kwargsSupport() ? 1 : 0;
|
||||
|
||||
// Create Library search directories
|
||||
|
||||
|
|
@ -949,7 +956,7 @@ int SWIG_main(int argc, char *argv[], Language *l) {
|
|||
|
||||
/* Check for SWIG_FEATURES environment variable */
|
||||
|
||||
SWIG_getoptions(argc, argv);
|
||||
getoptions(argc, argv);
|
||||
|
||||
// Define the __cplusplus symbol
|
||||
if (CPlusPlus)
|
||||
|
|
@ -962,6 +969,7 @@ int SWIG_main(int argc, char *argv[], Language *l) {
|
|||
Printf(stdout, "\nNote: 'swig -<lang> -help' displays options for a specific target language.\n\n");
|
||||
SWIG_exit(EXIT_SUCCESS); // Exit if we're in help mode
|
||||
}
|
||||
|
||||
// Check all of the options to make sure we're cool.
|
||||
// Don't check for an input file if -external-runtime is passed
|
||||
Swig_check_options(external_runtime ? 0 : 1);
|
||||
|
|
@ -1057,7 +1065,7 @@ int SWIG_main(int argc, char *argv[], Language *l) {
|
|||
char *cfile = Char(input_file);
|
||||
if (cfile && cfile[0] == '-') {
|
||||
Printf(stderr, "Unable to find option or file '%s', ", input_file);
|
||||
Printf(stderr, "use 'swig -help' for more information.\n");
|
||||
Printf(stderr, "Use 'swig -help' for more information.\n");
|
||||
} else {
|
||||
Printf(stderr, "Unable to find file '%s'.\n", input_file);
|
||||
}
|
||||
|
|
@ -1066,6 +1074,13 @@ int SWIG_main(int argc, char *argv[], Language *l) {
|
|||
Swig_warning(WARN_DEPRECATED_INPUT_FILE, "SWIG", 1, "Use of the include path to find the input file is deprecated and will not work with ccache. Please include the path when specifying the input file.\n"); // so that behaviour is like c/c++ compilers
|
||||
}
|
||||
}
|
||||
|
||||
if (!tlm) {
|
||||
Printf(stderr, "No target language specified.\n");
|
||||
Printf(stderr, "Use 'swig -help' for more information.\n");
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (!no_cpp) {
|
||||
fclose(df);
|
||||
Printf(fs, "%%include <swig.swg>\n");
|
||||
|
|
@ -1300,6 +1315,13 @@ int SWIG_main(int argc, char *argv[], Language *l) {
|
|||
// Check the extension for a c/c++ file. If so, we're going to declare everything we see as "extern"
|
||||
ForceExtern = check_extension(input_file);
|
||||
|
||||
if (tlm->status == Experimental) {
|
||||
Swig_warning(WARN_LANG_EXPERIMENTAL, "SWIG", 1, "Experimental target language. "
|
||||
"Target language %s specified by %s is an experimental language. "
|
||||
"Please read about SWIG experimental languages, http://swig.org/Doc4.0/Introduction.html#Introduction_experimental_status.\n",
|
||||
tlm->help ? tlm->help : "", tlm->name);
|
||||
}
|
||||
|
||||
lang->top(top);
|
||||
|
||||
if (browse) {
|
||||
|
|
|
|||
|
|
@ -219,8 +219,8 @@ private:
|
|||
String *module_baseclass; //inheritance for module class from %pragma
|
||||
String *m3raw_interfaces; //interfaces for intermediary class class from %pragma
|
||||
String *module_interfaces; //interfaces for module class from %pragma
|
||||
String *m3raw_class_modifiers; //class modifiers for intermediary class overriden by %pragma
|
||||
String *m3wrap_modifiers; //class modifiers for module class overriden by %pragma
|
||||
String *m3raw_class_modifiers; //class modifiers for intermediary class overridden by %pragma
|
||||
String *m3wrap_modifiers; //class modifiers for module class overridden by %pragma
|
||||
String *upcasts_code; //C++ casts for inheritance hierarchies C++ code
|
||||
String *m3raw_cppcasts_code; //C++ casts up inheritance hierarchies intermediary class code
|
||||
String *destructor_call; //C++ destructor call if any
|
||||
|
|
@ -822,7 +822,7 @@ MODULA3():
|
|||
Printf(file, "\n");
|
||||
Printf(file, "int main (int argc, char *argv[]) {\n");
|
||||
Printf(file, "\
|
||||
/*This progam must work for floating point numbers and integers.\n\
|
||||
/*This program must work for floating point numbers and integers.\n\
|
||||
Thus all numbers are converted to double precision floating point format.*/\n");
|
||||
scanConstant(file, n);
|
||||
Printf(file, " return 0;\n");
|
||||
|
|
@ -3214,7 +3214,7 @@ MODULA3():
|
|||
|
||||
tm = Getattr(p, "tmap:m3wrapargvar");
|
||||
if (tm != NIL) {
|
||||
/* exceptions that may be raised but can't be catched,
|
||||
/* exceptions that may be raised but can't be caught,
|
||||
thus we won't count them in num_exceptions */
|
||||
addImports(m3wrap_impl.import, "m3wrapargvar", p);
|
||||
addThrows(throws_hash, "m3wrapargvar", p);
|
||||
|
|
|
|||
|
|
@ -1,59 +0,0 @@
|
|||
/* -----------------------------------------------------------------------------
|
||||
* 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.
|
||||
*
|
||||
* module.cxx
|
||||
*
|
||||
* This file is responsible for the module system.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
#include "swigmod.h"
|
||||
|
||||
struct Module {
|
||||
ModuleFactory fac;
|
||||
char *name;
|
||||
Module *next;
|
||||
Module(const char *n, ModuleFactory f) {
|
||||
fac = f;
|
||||
name = new char[strlen(n) + 1];
|
||||
strcpy(name, n);
|
||||
next = 0;
|
||||
} ~Module() {
|
||||
delete[]name;
|
||||
}
|
||||
};
|
||||
|
||||
static Module *modules = 0;
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* void Swig_register_module()
|
||||
*
|
||||
* Register a module.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
void Swig_register_module(const char *n, ModuleFactory f) {
|
||||
Module *m = new Module(n, f);
|
||||
m->next = modules;
|
||||
modules = m;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Language *Swig_find_module()
|
||||
*
|
||||
* Given a command line option, locates the factory function.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
ModuleFactory Swig_find_module(const char *name) {
|
||||
Module *m = modules;
|
||||
while (m) {
|
||||
if (strcmp(m->name, name) == 0) {
|
||||
return m->fac;
|
||||
}
|
||||
m = m->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -17,12 +17,10 @@
|
|||
|
||||
static const char *usage = "\
|
||||
Mzscheme Options (available with -mzscheme)\n\
|
||||
-declaremodule - Create extension that declares a module\n\
|
||||
-dynamic-load <library>,[library,...] - Do not link with these libraries, dynamic load\n\
|
||||
them\n\
|
||||
-noinit - Do not emit scheme_initialize, scheme_reload,\n\
|
||||
scheme_module_name functions\n\
|
||||
-prefix <name> - Set a prefix <name> to be prepended to all names\n\
|
||||
-declaremodule - Create extension that declares a module\n\
|
||||
-dynamic-load <lib>,[lib,...] - Do not link with these libraries, dynamic load them\n\
|
||||
-noinit - Do not emit module initialization code\n\
|
||||
-prefix <name> - Set a prefix <name> to be prepended to all names\n\
|
||||
";
|
||||
|
||||
static String *fieldnames_tab = 0;
|
||||
|
|
@ -223,7 +221,6 @@ public:
|
|||
|
||||
Wrapper *f = NewWrapper();
|
||||
String *proc_name = NewString("");
|
||||
String *source = NewString("");
|
||||
String *target = NewString("");
|
||||
String *arg = NewString("");
|
||||
String *cleanup = NewString("");
|
||||
|
|
@ -314,10 +311,9 @@ public:
|
|||
String *ln = Getattr(p, "lname");
|
||||
|
||||
// Produce names of source and target
|
||||
Clear(source);
|
||||
Clear(target);
|
||||
Clear(arg);
|
||||
Printf(source, "argv[%d]", i);
|
||||
String *source = NewStringf("argv[%d]", i);
|
||||
Printf(target, "%s", ln);
|
||||
Printv(arg, Getattr(p, "name"), NIL);
|
||||
|
||||
|
|
@ -341,6 +337,7 @@ public:
|
|||
if (i >= numreq) {
|
||||
Printf(f->code, "}\n");
|
||||
}
|
||||
Delete(source);
|
||||
}
|
||||
|
||||
/* Insert constraint checking code */
|
||||
|
|
@ -439,9 +436,8 @@ public:
|
|||
sprintf(temp, "%d", numargs);
|
||||
if (exporting_destructor) {
|
||||
Printf(init_func_def, "SWIG_TypeClientData(SWIGTYPE%s, (void *) %s);\n", swigtype_ptr, wname);
|
||||
} else {
|
||||
Printf(init_func_def, "scheme_add_global(\"%s\", scheme_make_prim_w_arity(%s,\"%s\",%d,%d),menv);\n", proc_name, wname, proc_name, numreq, numargs);
|
||||
}
|
||||
Printf(init_func_def, "scheme_add_global(\"%s\", scheme_make_prim_w_arity(%s,\"%s\",%d,%d),menv);\n", proc_name, wname, proc_name, numreq, numargs);
|
||||
} else {
|
||||
if (!Getattr(n, "sym:nextSibling")) {
|
||||
/* Emit overloading dispatch function */
|
||||
|
|
@ -457,6 +453,7 @@ public:
|
|||
Printv(df->def, "static Scheme_Object *\n", dname, "(int argc, Scheme_Object **argv) {", NIL);
|
||||
Printv(df->code, dispatch, "\n", NIL);
|
||||
Printf(df->code, "scheme_signal_error(\"No matching function for overloaded '%s'\");\n", iname);
|
||||
Printf(df->code, "return NULL;\n", iname);
|
||||
Printv(df->code, "}\n", NIL);
|
||||
Wrapper_print(df, f_wrappers);
|
||||
Printf(init_func_def, "scheme_add_global(\"%s\", scheme_make_prim_w_arity(%s,\"%s\",%d,%d),menv);\n", proc_name, dname, proc_name, 0, maxargs);
|
||||
|
|
@ -467,7 +464,6 @@ public:
|
|||
}
|
||||
|
||||
Delete(proc_name);
|
||||
Delete(source);
|
||||
Delete(target);
|
||||
Delete(arg);
|
||||
Delete(outarg);
|
||||
|
|
@ -528,7 +524,7 @@ public:
|
|||
Replaceall(tm, "$source", "argv[0]");
|
||||
Replaceall(tm, "$target", name);
|
||||
Replaceall(tm, "$input", "argv[0]");
|
||||
/* Printv(f->code, tm, "\n",NIL); */
|
||||
Replaceall(tm, "$argnum", "1");
|
||||
emit_action_code(n, f->code, tm);
|
||||
} else {
|
||||
throw_unhandled_mzscheme_type_error(t);
|
||||
|
|
@ -765,7 +761,7 @@ public:
|
|||
|
||||
|
||||
/* ------------------------------------------------------------
|
||||
* validIdentifer()
|
||||
* validIdentifier()
|
||||
* ------------------------------------------------------------ */
|
||||
|
||||
virtual int validIdentifier(String *s) {
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ public:
|
|||
director_prot_ctor_code = NewString("");
|
||||
Printv(director_prot_ctor_code,
|
||||
"if ( $comparison ) { /* subclassed */\n",
|
||||
" $director_new \n", "} else {\n", " failwith(\"accessing abstract class or protected constructor\"); \n", "}\n", NIL);
|
||||
" $director_new \n", "} else {\n", " caml_failwith(\"accessing abstract class or protected constructor\"); \n", "}\n", NIL);
|
||||
director_multiple_inheritance = 1;
|
||||
director_language = 1;
|
||||
}
|
||||
|
|
@ -167,6 +167,12 @@ public:
|
|||
return declaration;
|
||||
}
|
||||
|
||||
void emitBanner(File *f) {
|
||||
Printf(f, "(* ----------------------------------------------------------------------------\n");
|
||||
Swig_banner_target_lang(f, " *");
|
||||
Printf(f, " * ---------------------------------------------------------------------------- *)\n\n");
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------
|
||||
* top()
|
||||
*
|
||||
|
|
@ -196,6 +202,7 @@ public:
|
|||
* use %module(directors="1") modulename at the start of the
|
||||
* interface file to enable director generation.
|
||||
*/
|
||||
String *mod_docstring = NULL;
|
||||
{
|
||||
Node *module = Getattr(n, "module");
|
||||
if (module) {
|
||||
|
|
@ -210,6 +217,7 @@ public:
|
|||
if (Getattr(options, "sizeof")) {
|
||||
generate_sizeof = 1;
|
||||
}
|
||||
mod_docstring = Getattr(options, "docstring");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -310,9 +318,19 @@ public:
|
|||
FileErrorDisplay(mlifilen);
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
}
|
||||
emitBanner(f_mlout);
|
||||
emitBanner(f_mliout);
|
||||
|
||||
Language::top(n);
|
||||
|
||||
if (mod_docstring) {
|
||||
if (Len(mod_docstring)) {
|
||||
Printv(f_mliout, "(** ", mod_docstring, " *)\n", NIL);
|
||||
}
|
||||
Delete(mod_docstring);
|
||||
mod_docstring = NULL;
|
||||
}
|
||||
|
||||
Printf(f_enum_to_int, ") | _ -> (C_int (get_int v))\n" "let _ = Callback.register \"%s_enum_to_int\" enum_to_int\n", module);
|
||||
Printf(f_mlibody, "val enum_to_int : c_enum_type -> c_obj -> Swig.c_obj\n");
|
||||
|
||||
|
|
@ -417,6 +435,29 @@ public:
|
|||
return SwigType_isarray(SwigType_typedef_resolve_all(t));
|
||||
}
|
||||
|
||||
virtual int membervariableHandler(Node *n) {
|
||||
String *symname = Getattr(n, "sym:name");
|
||||
Language::membervariableHandler(n);
|
||||
|
||||
String *mname = Swig_name_member(NSPACE_TODO, classname, symname);
|
||||
String *getname = Swig_name_get(NSPACE_TODO, mname);
|
||||
String *mangled_getname = mangleNameForCaml(getname);
|
||||
Delete(getname);
|
||||
|
||||
if (!GetFlag(n, "feature:immutable")) {
|
||||
String *setname = Swig_name_set(NSPACE_TODO, mname);
|
||||
String *mangled_setname = mangleNameForCaml(setname);
|
||||
Delete(setname);
|
||||
Printf(f_class_ctors, " \"[%s]\", (fun args -> " "if args = (C_list [ raw_ptr ]) then _%s args else _%s args) ;\n", symname, mangled_getname, mangled_setname);
|
||||
Delete(mangled_setname);
|
||||
} else {
|
||||
Printf(f_class_ctors, " \"[%s]\", (fun args -> " "if args = (C_list [ raw_ptr ]) then _%s args else C_void) ;\n", symname, mangled_getname);
|
||||
}
|
||||
Delete(mangled_getname);
|
||||
Delete(mname);
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------
|
||||
* functionWrapper()
|
||||
* Create a function declaration and register it with the interpreter.
|
||||
|
|
@ -432,7 +473,6 @@ public:
|
|||
|
||||
Wrapper *f = NewWrapper();
|
||||
String *proc_name = NewString("");
|
||||
String *source = NewString("");
|
||||
String *target = NewString("");
|
||||
String *arg = NewString("");
|
||||
String *cleanup = NewString("");
|
||||
|
|
@ -447,6 +487,8 @@ public:
|
|||
int destructor = (!Cmp(nodeType, "destructor"));
|
||||
String *overname = 0;
|
||||
bool isOverloaded = Getattr(n, "sym:overloaded") ? true : false;
|
||||
// For overloaded functions, only the dispatch function needs to be exposed in the ml and mli files.
|
||||
bool expose_func = !isOverloaded || !Getattr(n, "sym:nextSibling");
|
||||
|
||||
// Make a wrapper name for this
|
||||
String *wname = Swig_name_wrapper(iname);
|
||||
|
|
@ -470,33 +512,19 @@ public:
|
|||
Printv(proc_name, "_", iname, NIL);
|
||||
String *mangled_name = mangleNameForCaml(proc_name);
|
||||
|
||||
if (classmode && in_constructor) { // Emit constructor for object
|
||||
if (classmode && in_constructor && expose_func) { // Emit constructor for object
|
||||
String *mangled_name_nounder = NewString((char *) (Char(mangled_name)) + 1);
|
||||
Printf(f_class_ctors_end, "let %s clst = _%s clst\n", mangled_name_nounder, mangled_name_nounder);
|
||||
Printf(f_mlibody, "val %s : c_obj -> c_obj\n", mangled_name_nounder);
|
||||
Delete(mangled_name_nounder);
|
||||
} else if (classmode && in_destructor) {
|
||||
Printf(f_class_ctors, " \"~\", %s ;\n", mangled_name);
|
||||
} else if (classmode && !in_constructor && !in_destructor && !static_member_function) {
|
||||
} else if (classmode && !in_constructor && !in_destructor && !static_member_function &&
|
||||
!Getattr(n, "membervariableHandler:sym:name") && expose_func) {
|
||||
String *opname = Copy(Getattr(n, "memberfunctionHandler:sym:name"));
|
||||
|
||||
Replaceall(opname, "operator ", "");
|
||||
|
||||
if (strstr(Char(mangled_name), "__get__")) {
|
||||
String *set_name = Copy(mangled_name);
|
||||
if (!GetFlag(n, "feature:immutable")) {
|
||||
Replaceall(set_name, "__get__", "__set__");
|
||||
Printf(f_class_ctors, " \"%s\", (fun args -> " "if args = (C_list [ raw_ptr ]) then %s args else %s args) ;\n", opname, mangled_name, set_name);
|
||||
Delete(set_name);
|
||||
} else {
|
||||
Printf(f_class_ctors, " \"%s\", (fun args -> " "if args = (C_list [ raw_ptr ]) then %s args else C_void) ;\n", opname, mangled_name);
|
||||
}
|
||||
} else if (strstr(Char(mangled_name), "__set__")) {
|
||||
; /* Nothing ... handled by the case above */
|
||||
} else {
|
||||
Printf(f_class_ctors, " \"%s\", %s ;\n", opname, mangled_name);
|
||||
}
|
||||
|
||||
Printf(f_class_ctors, " \"%s\", %s ;\n", opname, mangled_name);
|
||||
Delete(opname);
|
||||
}
|
||||
|
||||
|
|
@ -515,16 +543,6 @@ public:
|
|||
// adds local variables
|
||||
Wrapper_add_local(f, "args", "CAMLparam1(args)");
|
||||
Wrapper_add_local(f, "ret", "SWIG_CAMLlocal2(swig_result,rv)");
|
||||
Wrapper_add_local(f, "_v", "int _v = 0");
|
||||
if (isOverloaded) {
|
||||
Wrapper_add_local(f, "i", "int i");
|
||||
Wrapper_add_local(f, "argc", "int argc = caml_list_length(args)");
|
||||
Wrapper_add_local(f, "argv", "CAML_VALUE *argv");
|
||||
|
||||
Printv(f->code,
|
||||
"argv = (CAML_VALUE *)malloc( argc * sizeof( CAML_VALUE ) );\n"
|
||||
"for( i = 0; i < argc; i++ ) {\n" " argv[i] = caml_list_nth(args,i);\n" "}\n", NIL);
|
||||
}
|
||||
d = SwigType_typedef_qualified(d);
|
||||
emit_parameter_variables(l, f);
|
||||
|
||||
|
|
@ -534,7 +552,18 @@ public:
|
|||
|
||||
numargs = emit_num_arguments(l);
|
||||
numreq = emit_num_required(l);
|
||||
|
||||
if (!isOverloaded) {
|
||||
if (numargs > 0) {
|
||||
if (numreq > 0) {
|
||||
Printf(f->code, "if (caml_list_length(args) < %d || caml_list_length(args) > %d) {\n", numreq, numargs);
|
||||
} else {
|
||||
Printf(f->code, "if (caml_list_length(args) > %d) {\n", numargs);
|
||||
}
|
||||
Printf(f->code, "caml_invalid_argument(\"Incorrect number of arguments passed to '%s'\");\n}\n", iname);
|
||||
} else {
|
||||
Printf(f->code, "if (caml_list_length(args) > 0) caml_invalid_argument(\"'%s' takes no arguments\");\n", iname);
|
||||
}
|
||||
}
|
||||
Printf(f->code, "swig_result = Val_unit;\n");
|
||||
|
||||
// Now write code to extract the parameters (this is super ugly)
|
||||
|
|
@ -550,10 +579,9 @@ public:
|
|||
pt = SwigType_typedef_qualified(pt);
|
||||
|
||||
// Produce names of source and target
|
||||
Clear(source);
|
||||
Clear(target);
|
||||
Clear(arg);
|
||||
Printf(source, "caml_list_nth(args,%d)", i);
|
||||
String *source = NewStringf("caml_list_nth(args,%d)", i);
|
||||
Printf(target, "%s", ln);
|
||||
Printv(arg, Getattr(p, "name"), NIL);
|
||||
|
||||
|
|
@ -577,6 +605,7 @@ public:
|
|||
if (i >= numreq) {
|
||||
Printf(f->code, "}\n");
|
||||
}
|
||||
Delete(source);
|
||||
}
|
||||
|
||||
/* Insert constraint checking code */
|
||||
|
|
@ -676,6 +705,14 @@ public:
|
|||
Printv(f->code, tm, "\n", NIL);
|
||||
}
|
||||
}
|
||||
|
||||
/* See if there is any return cleanup code */
|
||||
if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
|
||||
Replaceall(tm, "$source", Swig_cresult_name());
|
||||
Printf(f->code, "%s\n", tm);
|
||||
Delete(tm);
|
||||
}
|
||||
|
||||
// Free any memory allocated by the function being wrapped..
|
||||
|
||||
if ((tm = Swig_typemap_lookup("swig_result", n, Swig_cresult_name(), 0))) {
|
||||
|
|
@ -685,8 +722,6 @@ public:
|
|||
// Wrap things up (in a manner of speaking)
|
||||
|
||||
Printv(f->code, tab4, "swig_result = caml_list_append(swig_result,rv);\n", NIL);
|
||||
if (isOverloaded)
|
||||
Printv(f->code, "free(argv);\n", NIL);
|
||||
Printv(f->code, tab4, "CAMLreturn(swig_result);\n", NIL);
|
||||
Printv(f->code, "}\n", NIL);
|
||||
|
||||
|
|
@ -703,7 +738,6 @@ public:
|
|||
"free(argv);\n" "CAMLreturn(%s(args));\n",
|
||||
&maxargs);
|
||||
|
||||
Wrapper_add_local(df, "_v", "int _v = 0");
|
||||
Wrapper_add_local(df, "argv", "CAML_VALUE *argv");
|
||||
|
||||
/* Undifferentiate name .. this is the dispatch function */
|
||||
|
|
@ -717,8 +751,19 @@ public:
|
|||
Printv(df->code,
|
||||
"argv = (CAML_VALUE *)malloc( argc * sizeof( CAML_VALUE ) );\n"
|
||||
"for( i = 0; i < argc; i++ ) {\n" " argv[i] = caml_list_nth(args,i);\n" "}\n", NIL);
|
||||
Printv(df->code, dispatch, "\n", NIL);
|
||||
Printf(df->code, "failwith(\"No matching function for overloaded '%s'\");\n", iname);
|
||||
Printv(df->code, dispatch, "\nfree(argv);\n", NIL);
|
||||
Node *sibl = n;
|
||||
while (Getattr(sibl, "sym:previousSibling"))
|
||||
sibl = Getattr(sibl, "sym:previousSibling");
|
||||
String *protoTypes = NewString("");
|
||||
do {
|
||||
String *fulldecl = Swig_name_decl(sibl);
|
||||
Printf(protoTypes, "\n\" %s\\n\"", fulldecl);
|
||||
Delete(fulldecl);
|
||||
} while ((sibl = Getattr(sibl, "sym:nextSibling")));
|
||||
Printf(df->code, "caml_failwith(\"Wrong number or type of arguments for overloaded function '%s'.\\n\""
|
||||
"\n\" Possible C/C++ prototypes are:\\n\"%s);\n", iname, protoTypes);
|
||||
Delete(protoTypes);
|
||||
Printv(df->code, "}\n", NIL);
|
||||
Wrapper_print(df, f_wrappers);
|
||||
|
||||
|
|
@ -727,19 +772,20 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
Printf(f_mlbody,
|
||||
"external %s_f : c_obj list -> c_obj list = \"%s\" ;;\n"
|
||||
"let %s arg = match %s_f (fnhelper arg) with\n"
|
||||
" [] -> C_void\n"
|
||||
"| [x] -> (if %s then Gc.finalise \n"
|
||||
" (fun x -> ignore ((invoke x) \"~\" C_void)) x) ; x\n"
|
||||
"| lst -> C_list lst ;;\n", mangled_name, wname, mangled_name, mangled_name, newobj ? "true" : "false");
|
||||
if (expose_func) {
|
||||
Printf(f_mlbody, "external %s_f : c_obj list -> c_obj list = \"%s\" ;;\n", mangled_name, wname);
|
||||
Printf(f_mlbody, "let %s arg = match %s_f (%s(fnhelper arg)) with\n", mangled_name, mangled_name,
|
||||
in_constructor && Swig_directorclass(getCurrentClass()) ? "director_core_helper " : "");
|
||||
Printf(f_mlbody, " [] -> C_void\n"
|
||||
"| [x] -> (if %s then Gc.finalise \n"
|
||||
" (fun x -> ignore ((invoke x) \"~\" C_void)) x) ; x\n"
|
||||
"| lst -> C_list lst ;;\n", newobj ? "true" : "false");
|
||||
}
|
||||
|
||||
if (!classmode || in_constructor || in_destructor || static_member_function)
|
||||
if ((!classmode || in_constructor || in_destructor || static_member_function) && expose_func)
|
||||
Printf(f_mlibody, "val %s : c_obj -> c_obj\n", mangled_name);
|
||||
|
||||
Delete(proc_name);
|
||||
Delete(source);
|
||||
Delete(target);
|
||||
Delete(arg);
|
||||
Delete(outarg);
|
||||
|
|
@ -753,10 +799,11 @@ public:
|
|||
* variableWrapper()
|
||||
*
|
||||
* Create a link to a C variable.
|
||||
* This creates a single function _wrap_swig_var_varname().
|
||||
* This creates a single function _wrap_varname().
|
||||
* This function takes a single optional argument. If supplied, it means
|
||||
* we are setting this variable to some value. If omitted, it means we are
|
||||
* simply evaluating this variable. In the set case we return C_void.
|
||||
* simply evaluating this variable. We return the value of the variable
|
||||
* in both cases.
|
||||
*
|
||||
* symname is the name of the variable with respect to C. This
|
||||
* may need to differ from the original name in the case of enums.
|
||||
|
|
@ -772,9 +819,6 @@ public:
|
|||
|
||||
String *proc_name = NewString("");
|
||||
String *tm;
|
||||
String *tm2 = NewString("");
|
||||
String *argnum = NewString("0");
|
||||
String *arg = NewString("SWIG_Field(args,0)");
|
||||
Wrapper *f;
|
||||
|
||||
if (!name) {
|
||||
|
|
@ -794,14 +838,16 @@ public:
|
|||
// evaluation function names
|
||||
String *var_name = Swig_name_wrapper(iname);
|
||||
|
||||
// Build the name for scheme.
|
||||
// Build the name for OCaml.
|
||||
Printv(proc_name, iname, NIL);
|
||||
Setattr(n, "wrap:name", proc_name);
|
||||
|
||||
Printf(f->def, "SWIGEXT CAML_VALUE %s(CAML_VALUE args) {\n", var_name);
|
||||
// Printv(f->def, "#define FUNC_NAME \"", proc_name, "\"", NIL);
|
||||
|
||||
Wrapper_add_local(f, "swig_result", "CAML_VALUE swig_result");
|
||||
Wrapper_add_local(f, "args", "CAMLparam1(args)");
|
||||
Wrapper_add_local(f, "swig_result", "SWIG_CAMLlocal1(swig_result)");
|
||||
Printf(f->code, "swig_result = Val_unit;\n");
|
||||
|
||||
if (!GetFlag(n, "feature:immutable")) {
|
||||
/* Check for a setting of the variable value */
|
||||
|
|
@ -810,13 +856,12 @@ public:
|
|||
Replaceall(tm, "$source", "args");
|
||||
Replaceall(tm, "$target", name);
|
||||
Replaceall(tm, "$input", "args");
|
||||
/* Printv(f->code, tm, "\n",NIL); */
|
||||
emit_action_code(n, f->code, tm);
|
||||
} else if ((tm = Swig_typemap_lookup("in", n, name, 0))) {
|
||||
Replaceall(tm, "$source", "args");
|
||||
Replaceall(tm, "$target", name);
|
||||
Replaceall(tm, "$input", "args");
|
||||
Printv(f->code, tm, "\n", NIL);
|
||||
emit_action_code(n, f->code, tm);
|
||||
} else {
|
||||
throw_unhandled_ocaml_type_error(t, "varin/in");
|
||||
}
|
||||
|
|
@ -834,12 +879,12 @@ public:
|
|||
Replaceall(tm, "$source", name);
|
||||
Replaceall(tm, "$target", "swig_result");
|
||||
Replaceall(tm, "$result", "swig_result");
|
||||
Printf(f->code, "%s\n", tm);
|
||||
emit_action_code(n, f->code, tm);
|
||||
} else {
|
||||
throw_unhandled_ocaml_type_error(t, "varout/out");
|
||||
}
|
||||
|
||||
Printf(f->code, "\nreturn swig_result;\n");
|
||||
Printf(f->code, "\nCAMLreturn(swig_result);\n");
|
||||
Printf(f->code, "}\n");
|
||||
|
||||
Wrapper_print(f, f_wrappers);
|
||||
|
|
@ -860,9 +905,6 @@ public:
|
|||
|
||||
Delete(var_name);
|
||||
Delete(proc_name);
|
||||
Delete(argnum);
|
||||
Delete(arg);
|
||||
Delete(tm2);
|
||||
DelWrapper(f);
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
|
@ -890,10 +932,9 @@ public:
|
|||
virtual int constantWrapper(Node *n) {
|
||||
String *name = Getattr(n, "feature:symname");
|
||||
SwigType *type = Getattr(n, "type");
|
||||
String *value = Getattr(n, "value");
|
||||
String *rawval = Getattr(n, "rawval");
|
||||
String *value = rawval ? rawval : Getattr(n, "value");
|
||||
SwigType *qname = Getattr(n, "qualified:name");
|
||||
String *rvalue = NewString("");
|
||||
String *temp = 0;
|
||||
|
||||
if (qname)
|
||||
value = qname;
|
||||
|
|
@ -905,31 +946,8 @@ public:
|
|||
}
|
||||
// See if there's a typemap
|
||||
|
||||
Printv(rvalue, value, NIL);
|
||||
if ((SwigType_type(type) == T_CHAR) && (is_a_pointer(type) == 1)) {
|
||||
temp = Copy(rvalue);
|
||||
Clear(rvalue);
|
||||
Printv(rvalue, "\"", temp, "\"", NIL);
|
||||
Delete(temp);
|
||||
}
|
||||
if ((SwigType_type(type) == T_CHAR) && (is_a_pointer(type) == 0)) {
|
||||
temp = Copy(rvalue);
|
||||
Clear(rvalue);
|
||||
Printv(rvalue, "'", temp, "'", NIL);
|
||||
Delete(temp);
|
||||
}
|
||||
// Create variable and assign it a value
|
||||
|
||||
Printf(f_header, "static %s = ", SwigType_lstr(type, name));
|
||||
bool is_enum_item = (Cmp(nodeType(n), "enumitem") == 0);
|
||||
if ((SwigType_type(type) == T_STRING)) {
|
||||
Printf(f_header, "\"%s\";\n", value);
|
||||
} else if (SwigType_type(type) == T_CHAR && !is_enum_item) {
|
||||
Printf(f_header, "\'%s\';\n", value);
|
||||
} else {
|
||||
Printf(f_header, "%s;\n", value);
|
||||
}
|
||||
|
||||
Printf(f_header, "static %s = %s;\n", SwigType_str(type, name), value);
|
||||
SetFlag(n, "feature:immutable");
|
||||
variableWrapper(n);
|
||||
return SWIG_OK;
|
||||
|
|
@ -1096,11 +1114,12 @@ public:
|
|||
|
||||
int classHandler(Node *n) {
|
||||
String *name = Getattr(n, "name");
|
||||
classname = Getattr(n, "sym:name");
|
||||
|
||||
if (!name)
|
||||
return SWIG_OK;
|
||||
|
||||
String *mangled_sym_name = mangleNameForCaml(name);
|
||||
String *mangled_name = mangleNameForCaml(name);
|
||||
String *this_class_def = NewString(f_classtemplate);
|
||||
String *name_normalized = normalizeTemplatedClassName(name);
|
||||
String *old_class_ctors = f_class_ctors;
|
||||
|
|
@ -1109,7 +1128,6 @@ public:
|
|||
bool sizeof_feature = generate_sizeof && isSimpleType(name);
|
||||
|
||||
|
||||
classname = mangled_sym_name;
|
||||
classmode = true;
|
||||
int rv = Language::classHandler(n);
|
||||
classmode = false;
|
||||
|
|
@ -1117,15 +1135,15 @@ public:
|
|||
if (sizeof_feature) {
|
||||
Printf(f_wrappers,
|
||||
"SWIGEXT CAML_VALUE _wrap_%s_sizeof( CAML_VALUE args ) {\n"
|
||||
" CAMLparam1(args);\n" " CAMLreturn(Val_int(sizeof(%s)));\n" "}\n", mangled_sym_name, name_normalized);
|
||||
" CAMLparam1(args);\n" " CAMLreturn(Val_int(sizeof(%s)));\n" "}\n", mangled_name, name_normalized);
|
||||
|
||||
Printf(f_mlbody, "external __%s_sizeof : unit -> int = " "\"_wrap_%s_sizeof\"\n", classname, mangled_sym_name);
|
||||
Printf(f_mlbody, "external __%s_sizeof : unit -> int = " "\"_wrap_%s_sizeof\"\n", mangled_name, mangled_name);
|
||||
}
|
||||
|
||||
|
||||
/* Insert sizeof operator for concrete classes */
|
||||
if (sizeof_feature) {
|
||||
Printv(f_class_ctors, "\"sizeof\" , (fun args -> C_int (__", classname, "_sizeof ())) ;\n", NIL);
|
||||
Printv(f_class_ctors, "\"sizeof\" , (fun args -> C_int (__", mangled_name, "_sizeof ())) ;\n", NIL);
|
||||
}
|
||||
/* Handle up-casts in a nice way */
|
||||
List *baselist = Getattr(n, "bases");
|
||||
|
|
@ -1144,7 +1162,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
Replaceall(this_class_def, "$classname", classname);
|
||||
Replaceall(this_class_def, "$classname", mangled_name);
|
||||
Replaceall(this_class_def, "$normalized", name_normalized);
|
||||
Replaceall(this_class_def, "$realname", name);
|
||||
Replaceall(this_class_def, "$baselist", base_classes);
|
||||
|
|
@ -1157,7 +1175,7 @@ public:
|
|||
|
||||
Multiwrite(this_class_def);
|
||||
|
||||
Setattr(n, "ocaml:ctor", classname);
|
||||
Setattr(n, "ocaml:ctor", mangled_name);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
|
@ -1396,8 +1414,7 @@ public:
|
|||
pure_virtual = true;
|
||||
}
|
||||
}
|
||||
|
||||
Wrapper_add_local(w, "swig_result", "CAMLparam0();\n" "SWIG_CAMLlocal2(swig_result,args)");
|
||||
Printf(w->locals, "CAMLparam0();\n");
|
||||
|
||||
/* determine if the method returns a pointer */
|
||||
is_pointer = SwigType_ispointer_return(decl);
|
||||
|
|
@ -1408,44 +1425,88 @@ public:
|
|||
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);
|
||||
target = Swig_method_decl(rtype, decl, qualified_name, l, 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);
|
||||
target = Swig_method_decl(rtype, decl, name, l, 1);
|
||||
Printf(declaration, " virtual %s", target);
|
||||
Delete(target);
|
||||
|
||||
// Get any exception classes in the throws typemap
|
||||
if (Getattr(n, "noexcept")) {
|
||||
Append(w->def, " noexcept");
|
||||
Append(declaration, " noexcept");
|
||||
}
|
||||
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)) {
|
||||
Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), NIL);
|
||||
if (!is_void && (!ignored_method || pure_virtual)) {
|
||||
if (!SwigType_isclass(returntype)) {
|
||||
if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) {
|
||||
String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(returntype, 0));
|
||||
Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), construct_result, NIL);
|
||||
Delete(construct_result);
|
||||
} else {
|
||||
Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= 0", NIL);
|
||||
}
|
||||
} else {
|
||||
String *cres = SwigType_lstr(returntype, "c_result");
|
||||
Printf(w->code, "%s;\n", cres);
|
||||
Delete(cres);
|
||||
}
|
||||
}
|
||||
|
||||
if (ignored_method) {
|
||||
if (!pure_virtual) {
|
||||
if (!is_void)
|
||||
Printf(w->code, "return ");
|
||||
String *super_call = Swig_method_call(super, l);
|
||||
Printf(w->code, "%s;\n", super_call);
|
||||
if (is_void)
|
||||
Printf(w->code, "%s;\n", super_call);
|
||||
else
|
||||
Printf(w->code, "CAMLreturn_type(%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 {
|
||||
Wrapper_add_local(w, "swig_result", "SWIG_CAMLlocal2(swig_result, args)");
|
||||
/* attach typemaps to arguments (C/C++ -> Ocaml) */
|
||||
String *arglist = NewString("");
|
||||
|
||||
Swig_director_parms_fixup(l);
|
||||
|
||||
Swig_typemap_attach_parms("in", l, 0);
|
||||
Swig_typemap_attach_parms("directorin", l, 0);
|
||||
Swig_typemap_attach_parms("directorin", l, w);
|
||||
Swig_typemap_attach_parms("directorargout", l, w);
|
||||
|
||||
Parm *p;
|
||||
|
|
@ -1555,10 +1616,12 @@ public:
|
|||
/* wrap complex arguments to values */
|
||||
Printv(w->code, wrap_args, NIL);
|
||||
|
||||
/* pass the method call on to the Python object */
|
||||
/* pass the method call on to the OCaml object */
|
||||
Printv(w->code,
|
||||
"swig_result = caml_swig_alloc(1,C_list);\n" "SWIG_Store_field(swig_result,0,args);\n" "args = swig_result;\n" "swig_result = Val_unit;\n", 0);
|
||||
Printf(w->code, "swig_result = " "callback3(*caml_named_value(\"swig_runmethod\")," "swig_get_self(),copy_string(\"%s\"),args);\n", Getattr(n, "name"));
|
||||
Printf(w->code, "static CAML_VALUE *swig_ocaml_func_val = NULL;\n" "if (!swig_ocaml_func_val) {\n");
|
||||
Printf(w->code, " swig_ocaml_func_val = caml_named_value(\"swig_runmethod\");\n }\n");
|
||||
Printf(w->code, "swig_result = caml_callback3(*swig_ocaml_func_val,swig_get_self(),caml_copy_string(\"%s\"),args);\n", Getattr(n, "name"));
|
||||
/* exception handling */
|
||||
tm = Swig_typemap_lookup("director:except", n, Swig_cresult_name(), 0);
|
||||
if (!tm) {
|
||||
|
|
@ -1574,7 +1637,7 @@ public:
|
|||
|
||||
/*
|
||||
* Python method may return a simple object, or a tuple.
|
||||
* for in/out aruments, we have to extract the appropriate values from the
|
||||
* for in/out arguments, we have to extract the appropriate values from the
|
||||
* argument list, then marshal everything back to C/C++ (return value and
|
||||
* output arguments).
|
||||
*/
|
||||
|
|
@ -1633,6 +1696,8 @@ public:
|
|||
Printf(w->code, "CAMLreturn_type(*c_result);\n");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Printf(w->code, "CAMLreturn0;\n");
|
||||
}
|
||||
|
||||
Printf(w->code, "}\n");
|
||||
|
|
@ -1698,7 +1763,7 @@ public:
|
|||
Wrapper *w = NewWrapper();
|
||||
String *call;
|
||||
String *basetype = Getattr(parent, "classtype");
|
||||
String *target = Swig_method_decl(0, decl, classname, parms, 0, 0);
|
||||
String *target = Swig_method_decl(0, decl, classname, parms, 0);
|
||||
call = Swig_csuperclass_call(0, basetype, superparms);
|
||||
Printf(w->def, "%s::%s: %s, Swig::Director(self) { }", classname, target, call);
|
||||
Delete(target);
|
||||
|
|
@ -1709,7 +1774,7 @@ public:
|
|||
|
||||
/* constructor header */
|
||||
{
|
||||
String *target = Swig_method_decl(0, decl, classname, parms, 0, 1);
|
||||
String *target = Swig_method_decl(0, decl, classname, parms, 1);
|
||||
Printf(f_directors_h, " %s;\n", target);
|
||||
Delete(target);
|
||||
}
|
||||
|
|
@ -1799,9 +1864,9 @@ public:
|
|||
}
|
||||
|
||||
String *runtimeCode() {
|
||||
String *s = Swig_include_sys("ocaml.swg");
|
||||
String *s = Swig_include_sys("ocamlrun.swg");
|
||||
if (!s) {
|
||||
Printf(stderr, "*** Unable to open 'ocaml.swg'\n");
|
||||
Printf(stderr, "*** Unable to open 'ocamlrun.swg'\n");
|
||||
s = NewString("");
|
||||
}
|
||||
return s;
|
||||
|
|
|
|||
|
|
@ -19,10 +19,8 @@ static String *op_prefix = 0;
|
|||
|
||||
static const char *usage = "\
|
||||
Octave Options (available with -octave)\n\
|
||||
-cppcast - Enable C++ casting operators (default)\n\
|
||||
-globals <name> - Set <name> used to access C global variables [default: 'cvar']\n\
|
||||
Use '.' to load C global variables into module namespace\n\
|
||||
-nocppcast - Disable C++ casting operators\n\
|
||||
-opprefix <str> - Prefix <str> for global operator functions [default: 'op_']\n\
|
||||
\n";
|
||||
|
||||
|
|
@ -92,8 +90,7 @@ public:
|
|||
}
|
||||
|
||||
virtual void main(int argc, char *argv[]) {
|
||||
int cppcast = 1;
|
||||
|
||||
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (argv[i]) {
|
||||
if (strcmp(argv[i], "-help") == 0) {
|
||||
|
|
@ -116,12 +113,13 @@ public:
|
|||
} else {
|
||||
Swig_arg_error();
|
||||
}
|
||||
} else if (strcmp(argv[i], "-cppcast") == 0) {
|
||||
cppcast = 1;
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i], "-nocppcast") == 0) {
|
||||
cppcast = 0;
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i], "-cppcast") == 0) {
|
||||
Printf(stderr, "Deprecated command line option: %s. This option is now always on.\n", argv[i]);
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i], "-nocppcast") == 0) {
|
||||
Printf(stderr, "Deprecated command line option: %s. This option is no longer supported.\n", argv[i]);
|
||||
Swig_mark_arg(i);
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -130,8 +128,6 @@ public:
|
|||
global_name = NewString("cvar");
|
||||
if (!op_prefix)
|
||||
op_prefix = NewString("op_");
|
||||
if(cppcast)
|
||||
Preprocessor_define((DOH *) "SWIG_CPLUSPLUS_CAST", 0);
|
||||
|
||||
SWIG_library_directory("octave");
|
||||
Preprocessor_define("SWIGOCTAVE 1", 0);
|
||||
|
|
@ -139,7 +135,7 @@ public:
|
|||
SWIG_typemap_lang("octave");
|
||||
allow_overloading();
|
||||
|
||||
// Octave API is C++, so output must be C++ compatibile even when wrapping C code
|
||||
// Octave API is C++, so output must be C++ compatible even when wrapping C code
|
||||
if (!cparse_cplusplus)
|
||||
Swig_cparse_cplusplusout(1);
|
||||
}
|
||||
|
|
@ -422,13 +418,14 @@ public:
|
|||
* The "lname" attribute in each parameter in plist will be contain a parameter name
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
void addMissingParameterNames(ParmList *plist, int arg_offset) {
|
||||
void addMissingParameterNames(Node* n, ParmList *plist, int arg_offset) {
|
||||
Parm *p = plist;
|
||||
int i = arg_offset;
|
||||
while (p) {
|
||||
if (!Getattr(p, "lname")) {
|
||||
String *pname = Swig_cparm_name(p, i);
|
||||
Delete(pname);
|
||||
String *name = makeParameterName(n, p, i);
|
||||
Setattr(p, "lname", name);
|
||||
Delete(name);
|
||||
}
|
||||
i++;
|
||||
p = nextSibling(p);
|
||||
|
|
@ -440,14 +437,14 @@ public:
|
|||
ParmList *plist = CopyParmList(Getattr(n, "parms"));
|
||||
Parm *p;
|
||||
Parm *pnext;
|
||||
int start_arg_num = is_wrapping_class() ? 1 : 0;
|
||||
int arg_num = is_wrapping_class() ? 1 : 0;
|
||||
|
||||
addMissingParameterNames(plist, start_arg_num); // for $1_name substitutions done in Swig_typemap_attach_parms
|
||||
addMissingParameterNames(n, plist, arg_num); // for $1_name substitutions done in Swig_typemap_attach_parms
|
||||
|
||||
Swig_typemap_attach_parms("in", plist, 0);
|
||||
Swig_typemap_attach_parms("doc", plist, 0);
|
||||
|
||||
for (p = plist; p; p = pnext) {
|
||||
for (p = plist; p; p = pnext, arg_num++) {
|
||||
|
||||
String *tm = Getattr(p, "tmap:in");
|
||||
if (tm) {
|
||||
|
|
@ -469,9 +466,10 @@ public:
|
|||
value = Getattr(p, "tmap:doc:value");
|
||||
}
|
||||
|
||||
name = name ? name : Getattr(p, "name");
|
||||
name = name ? name : Getattr(p, "lname");
|
||||
name = Swig_name_make(p, 0, name, 0, 0); // rename parameter if a keyword
|
||||
String *made_name = 0;
|
||||
if (!name) {
|
||||
name = made_name = makeParameterName(n, p, arg_num);
|
||||
}
|
||||
|
||||
type = type ? type : Getattr(p, "type");
|
||||
value = value ? value : Getattr(p, "value");
|
||||
|
|
@ -507,7 +505,7 @@ public:
|
|||
|
||||
Delete(type_str);
|
||||
Delete(tex_name);
|
||||
Delete(name);
|
||||
Delete(made_name);
|
||||
}
|
||||
if (pdocs)
|
||||
Setattr(n, "feature:pdocs", pdocs);
|
||||
|
|
@ -1234,7 +1232,7 @@ public:
|
|||
Wrapper *w = NewWrapper();
|
||||
String *call;
|
||||
String *basetype = Getattr(parent, "classtype");
|
||||
String *target = Swig_method_decl(0, decl, classname, parms, 0, 0);
|
||||
String *target = Swig_method_decl(0, decl, classname, parms, 0);
|
||||
call = Swig_csuperclass_call(0, basetype, superparms);
|
||||
Printf(w->def, "%s::%s: %s," "\nSwig::Director(static_cast<%s*>(this)) { \n", classname, target, call, basetype);
|
||||
Append(w->def, "}\n");
|
||||
|
|
@ -1246,7 +1244,7 @@ public:
|
|||
|
||||
// constructor header
|
||||
{
|
||||
String *target = Swig_method_decl(0, decl, classname, parms, 0, 1);
|
||||
String *target = Swig_method_decl(0, decl, classname, parms, 1);
|
||||
Printf(f_directors_h, " %s;\n", target);
|
||||
Delete(target);
|
||||
}
|
||||
|
|
@ -1310,17 +1308,21 @@ public:
|
|||
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);
|
||||
target = Swig_method_decl(rtype, decl, qualified_name, l, 0);
|
||||
Printf(w->def, "%s", target);
|
||||
Delete(qualified_name);
|
||||
Delete(target);
|
||||
|
||||
// header declaration
|
||||
target = Swig_method_decl(rtype, decl, name, l, 0, 1);
|
||||
target = Swig_method_decl(rtype, decl, name, l, 1);
|
||||
Printf(declaration, " virtual %s", target);
|
||||
Delete(target);
|
||||
|
||||
// Get any exception classes in the throws typemap
|
||||
if (Getattr(n, "noexcept")) {
|
||||
Append(w->def, " noexcept");
|
||||
Append(declaration, " noexcept");
|
||||
}
|
||||
ParmList *throw_parm_list = 0;
|
||||
|
||||
if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) {
|
||||
|
|
@ -1355,11 +1357,19 @@ public:
|
|||
// 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);
|
||||
if (!is_void && (!ignored_method || pure_virtual)) {
|
||||
if (!SwigType_isclass(returntype)) {
|
||||
if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) {
|
||||
String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(returntype, 0));
|
||||
Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), construct_result, NIL);
|
||||
Delete(construct_result);
|
||||
} else {
|
||||
Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= 0", NIL);
|
||||
}
|
||||
} else {
|
||||
String *cres = SwigType_lstr(returntype, "c_result");
|
||||
Printf(w->code, "%s;\n", cres);
|
||||
Delete(cres);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1381,7 +1391,7 @@ public:
|
|||
Swig_director_parms_fixup(l);
|
||||
|
||||
Swig_typemap_attach_parms("in", l, 0);
|
||||
Swig_typemap_attach_parms("directorin", l, 0);
|
||||
Swig_typemap_attach_parms("directorin", l, w);
|
||||
Swig_typemap_attach_parms("directorargout", l, w);
|
||||
|
||||
Parm *p;
|
||||
|
|
|
|||
|
|
@ -185,7 +185,8 @@ List *Swig_overload_rank(Node *n, bool script_lang_wrapping) {
|
|||
nodes[j] = t;
|
||||
break;
|
||||
} else if ((differ == 0) && (Strcmp(t1, "0") == 0)) {
|
||||
t1 = Getattr(p1, "ltype");
|
||||
t1 = Getattr(p1, "equivtype");
|
||||
t1 = t1 ? t1 : Getattr(p1, "ltype");
|
||||
if (!t1) {
|
||||
t1 = SwigType_ltype(Getattr(p1, "type"));
|
||||
if (Getattr(p1, "tmap:typecheck:SWIGTYPE")) {
|
||||
|
|
@ -193,7 +194,8 @@ List *Swig_overload_rank(Node *n, bool script_lang_wrapping) {
|
|||
}
|
||||
Setattr(p1, "ltype", t1);
|
||||
}
|
||||
t2 = Getattr(p2, "ltype");
|
||||
t2 = Getattr(p2, "equivtype");
|
||||
t2 = t2 ? t2 : Getattr(p2, "ltype");
|
||||
if (!t2) {
|
||||
t2 = SwigType_ltype(Getattr(p2, "type"));
|
||||
if (Getattr(p2, "tmap:typecheck:SWIGTYPE")) {
|
||||
|
|
@ -231,9 +233,21 @@ List *Swig_overload_rank(Node *n, bool script_lang_wrapping) {
|
|||
}
|
||||
if (!differ) {
|
||||
/* See if declarations differ by const only */
|
||||
String *d1 = Getattr(nodes[i].n, "decl");
|
||||
String *d2 = Getattr(nodes[j].n, "decl");
|
||||
if (d1 && d2) {
|
||||
String *decl1 = Getattr(nodes[i].n, "decl");
|
||||
String *decl2 = Getattr(nodes[j].n, "decl");
|
||||
if (decl1 && decl2) {
|
||||
/* Remove ref-qualifiers. Note that rvalue ref-qualifiers are already ignored and
|
||||
* it is illegal to overload a function with and without ref-qualifiers. So with
|
||||
* all the combinations of ref-qualifiers and cv-qualifiers, we just detect
|
||||
* the cv-qualifier (const) overloading. */
|
||||
String *d1 = Copy(decl1);
|
||||
String *d2 = Copy(decl2);
|
||||
if (SwigType_isreference(d1) || SwigType_isrvalue_reference(d1)) {
|
||||
Delete(SwigType_pop(d1));
|
||||
}
|
||||
if (SwigType_isreference(d2) || SwigType_isrvalue_reference(d2)) {
|
||||
Delete(SwigType_pop(d2));
|
||||
}
|
||||
String *dq1 = Copy(d1);
|
||||
String *dq2 = Copy(d2);
|
||||
if (SwigType_isconst(d1)) {
|
||||
|
|
@ -428,7 +442,7 @@ String *Swig_overload_dispatch_cast(Node *n, const_String_or_char_ptr fmt, int *
|
|||
|
||||
/* Loop over the functions */
|
||||
|
||||
bool emitcheck = 1;
|
||||
bool emitcheck = true;
|
||||
for (i = 0; i < nfunc; i++) {
|
||||
int fn = 0;
|
||||
Node *ni = Getitem(dispatch, i);
|
||||
|
|
@ -504,7 +518,7 @@ String *Swig_overload_dispatch_cast(Node *n, const_String_or_char_ptr fmt, int *
|
|||
if (tml)
|
||||
Replaceid(tml, Getattr(pl, "lname"), "_v");
|
||||
if (!tml || Cmp(tm, tml))
|
||||
emitcheck = 1;
|
||||
emitcheck = true;
|
||||
//printf("tmap: %s[%d] (%d) => %s\n\n",
|
||||
// Char(Getattr(nk, "sym:name")),
|
||||
// l, emitcheck, tml?Char(tml):0);
|
||||
|
|
@ -596,7 +610,7 @@ String *Swig_overload_dispatch_cast(Node *n, const_String_or_char_ptr fmt, int *
|
|||
/*
|
||||
Fast dispatch mechanism, provided by Salvador Fandi~no Garc'ia (#930586).
|
||||
*/
|
||||
String *Swig_overload_dispatch_fast(Node *n, const_String_or_char_ptr fmt, int *maxargs) {
|
||||
static String *overload_dispatch_fast(Node *n, const_String_or_char_ptr fmt, int *maxargs, const_String_or_char_ptr fmt_fastdispatch) {
|
||||
int i, j;
|
||||
|
||||
*maxargs = 1;
|
||||
|
|
@ -639,6 +653,7 @@ String *Swig_overload_dispatch_fast(Node *n, const_String_or_char_ptr fmt, int *
|
|||
|
||||
// printf("overload: %s coll=%d\n", Char(Getattr(n, "sym:name")), Len(coll));
|
||||
|
||||
bool emitcheck = false;
|
||||
int num_braces = 0;
|
||||
bool test = (Len(coll) > 0 && num_arguments);
|
||||
if (test) {
|
||||
|
|
@ -659,7 +674,7 @@ String *Swig_overload_dispatch_fast(Node *n, const_String_or_char_ptr fmt, int *
|
|||
|
||||
/* if all the wrappers have the same type check on this
|
||||
argument we can optimize it out */
|
||||
bool emitcheck = 0;
|
||||
emitcheck = false;
|
||||
for (int k = 0; k < Len(coll) && !emitcheck; k++) {
|
||||
Node *nk = Getitem(coll, k);
|
||||
Parm *pk = Getattr(nk, "wrap:parms");
|
||||
|
|
@ -681,7 +696,7 @@ String *Swig_overload_dispatch_fast(Node *n, const_String_or_char_ptr fmt, int *
|
|||
if (tml)
|
||||
Replaceid(tml, Getattr(pl, "lname"), "_v");
|
||||
if (!tml || Cmp(tm, tml))
|
||||
emitcheck = 1;
|
||||
emitcheck = true;
|
||||
//printf("tmap: %s[%d] (%d) => %s\n\n",
|
||||
// Char(Getattr(nk, "sym:name")),
|
||||
// l, emitcheck, tml?Char(tml):0);
|
||||
|
|
@ -738,8 +753,8 @@ String *Swig_overload_dispatch_fast(Node *n, const_String_or_char_ptr fmt, int *
|
|||
for ( /* empty */ ; num_braces > 0; num_braces--)
|
||||
Printf(f, "}\n");
|
||||
|
||||
|
||||
String *lfmt = ReplaceFormat(fmt, num_arguments);
|
||||
// The language module may want to generate different code for last overloaded function called (with same number of arguments)
|
||||
String *lfmt = ReplaceFormat(!emitcheck && fmt_fastdispatch ? fmt_fastdispatch : fmt, num_arguments);
|
||||
Printf(f, Char(lfmt), Getattr(ni, "wrap:name"));
|
||||
|
||||
Printf(f, "}\n"); /* braces closes "if" for this method */
|
||||
|
|
@ -756,10 +771,10 @@ String *Swig_overload_dispatch_fast(Node *n, const_String_or_char_ptr fmt, int *
|
|||
return f;
|
||||
}
|
||||
|
||||
String *Swig_overload_dispatch(Node *n, const_String_or_char_ptr fmt, int *maxargs) {
|
||||
String *Swig_overload_dispatch(Node *n, const_String_or_char_ptr fmt, int *maxargs, const_String_or_char_ptr fmt_fastdispatch) {
|
||||
|
||||
if (fast_dispatch_mode || GetFlag(n, "feature:fastdispatch")) {
|
||||
return Swig_overload_dispatch_fast(n, fmt, maxargs);
|
||||
return overload_dispatch_fast(n, fmt, maxargs, fmt_fastdispatch);
|
||||
}
|
||||
|
||||
int i, j;
|
||||
|
|
|
|||
|
|
@ -16,11 +16,9 @@
|
|||
#include <ctype.h>
|
||||
|
||||
static const char *usage = "\
|
||||
Perl5 Options (available with -perl5)\n\
|
||||
Perl 5 Options (available with -perl5)\n\
|
||||
-compat - Compatibility mode\n\
|
||||
-const - Wrap constants as constants and not variables (implies -proxy)\n\
|
||||
-cppcast - Enable C++ casting operators\n\
|
||||
-nocppcast - Disable C++ casting operators, useful for generating bugs\n\
|
||||
-nopm - Do not generate the .pm file\n\
|
||||
-noproxy - Don't create proxy classes\n\
|
||||
-proxy - Create proxy classes\n\
|
||||
|
|
@ -148,7 +146,6 @@ public:
|
|||
|
||||
virtual void main(int argc, char *argv[]) {
|
||||
int i = 1;
|
||||
int cppcast = 1;
|
||||
|
||||
SWIG_library_directory("perl5");
|
||||
|
||||
|
|
@ -189,25 +186,22 @@ public:
|
|||
} else if (strcmp(argv[i],"-v") == 0) {
|
||||
Swig_mark_arg(i);
|
||||
verbose++;
|
||||
} else if (strcmp(argv[i], "-cppcast") == 0) {
|
||||
cppcast = 1;
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i], "-nocppcast") == 0) {
|
||||
cppcast = 0;
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i], "-compat") == 0) {
|
||||
compat = 1;
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i], "-help") == 0) {
|
||||
fputs(usage, stdout);
|
||||
} else if (strcmp(argv[i], "-cppcast") == 0) {
|
||||
Printf(stderr, "Deprecated command line option: %s. This option is now always on.\n", argv[i]);
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i], "-nocppcast") == 0) {
|
||||
Printf(stderr, "Deprecated command line option: %s. This option is no longer supported.\n", argv[i]);
|
||||
Swig_mark_arg(i);
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cppcast) {
|
||||
Preprocessor_define((DOH *) "SWIG_CPLUSPLUS_CAST", 0);
|
||||
}
|
||||
|
||||
Preprocessor_define("SWIGPERL 1", 0);
|
||||
// SWIGPERL5 is deprecated, and no longer documented.
|
||||
Preprocessor_define("SWIGPERL5 1", 0);
|
||||
|
|
@ -900,6 +894,15 @@ public:
|
|||
Printf(f->code, "%s\n", tm);
|
||||
}
|
||||
|
||||
if (director_method) {
|
||||
if ((tm = Swig_typemap_lookup("directorfree", n, Swig_cresult_name(), 0))) {
|
||||
Replaceall(tm, "$input", Swig_cresult_name());
|
||||
Replaceall(tm, "$result", "ST(argvi)");
|
||||
Printf(f->code, "%s\n", tm);
|
||||
Delete(tm);
|
||||
}
|
||||
}
|
||||
|
||||
Printv(f->code, "XSRETURN(argvi);\n", "fail:\n", cleanup, "SWIG_croak_null();\n" "}\n" "}\n", NIL);
|
||||
|
||||
/* Add the dXSARGS last */
|
||||
|
|
@ -2018,7 +2021,7 @@ public:
|
|||
Wrapper *w = NewWrapper();
|
||||
String *call;
|
||||
String *basetype = Getattr(parent, "classtype");
|
||||
String *target = Swig_method_decl(0, decl, classname, parms, 0, 0);
|
||||
String *target = Swig_method_decl(0, decl, classname, parms, 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);
|
||||
|
|
@ -2031,7 +2034,7 @@ public:
|
|||
|
||||
/* constructor header */
|
||||
{
|
||||
String *target = Swig_method_decl(0, decl, classname, parms, 0, 1);
|
||||
String *target = Swig_method_decl(0, decl, classname, parms, 1);
|
||||
Printf(f_directors_h, " %s;\n", target);
|
||||
Delete(target);
|
||||
}
|
||||
|
|
@ -2080,16 +2083,20 @@ public:
|
|||
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);
|
||||
target = Swig_method_decl(rtype, decl, qualified_name, l, 0);
|
||||
Printf(w->def, "%s", target);
|
||||
Delete(qualified_name);
|
||||
Delete(target);
|
||||
/* header declaration */
|
||||
target = Swig_method_decl(rtype, decl, name, l, 0, 1);
|
||||
target = Swig_method_decl(rtype, decl, name, l, 1);
|
||||
Printf(declaration, " virtual %s", target);
|
||||
Delete(target);
|
||||
|
||||
// Get any exception classes in the throws typemap
|
||||
if (Getattr(n, "noexcept")) {
|
||||
Append(w->def, " noexcept");
|
||||
Append(declaration, " noexcept");
|
||||
}
|
||||
ParmList *throw_parm_list = 0;
|
||||
|
||||
if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) {
|
||||
|
|
@ -2125,17 +2132,26 @@ public:
|
|||
* 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)) {
|
||||
if (!is_void && (!ignored_method || pure_virtual)) {
|
||||
if (!SwigType_isclass(returntype)) {
|
||||
if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) {
|
||||
String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(returntype, 0));
|
||||
Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), construct_result, NIL);
|
||||
Delete(construct_result);
|
||||
} else {
|
||||
Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= 0", NIL);
|
||||
}
|
||||
} else {
|
||||
String *cres = SwigType_lstr(returntype, "c_result");
|
||||
Printf(w->code, "%s;\n", cres);
|
||||
Delete(cres);
|
||||
}
|
||||
if (!ignored_method) {
|
||||
String *pres = NewStringf("SV *%s", Swig_cresult_name());
|
||||
Wrapper_add_local(w, Swig_cresult_name(), pres);
|
||||
Delete(pres);
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_void && !ignored_method) {
|
||||
String *pres = NewStringf("SV *%s", Swig_cresult_name());
|
||||
Wrapper_add_local(w, Swig_cresult_name(), pres);
|
||||
Delete(pres);
|
||||
}
|
||||
|
||||
if (ignored_method) {
|
||||
|
|
@ -2158,7 +2174,7 @@ public:
|
|||
|
||||
/* 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("directorin", l, w);
|
||||
Swig_typemap_attach_parms("directorargout", l, w);
|
||||
|
||||
Wrapper_add_local(w, "SP", "dSP");
|
||||
|
|
@ -2332,7 +2348,7 @@ public:
|
|||
|
||||
/*
|
||||
* Python method may return a simple object, or a tuple.
|
||||
* for in/out aruments, we have to extract the appropriate PyObjects from the tuple,
|
||||
* for in/out arguments, we have to extract the appropriate PyObjects from the tuple,
|
||||
* then marshal everything back to C/C++ (return value and output arguments).
|
||||
*
|
||||
*/
|
||||
|
|
@ -2486,9 +2502,12 @@ public:
|
|||
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);
|
||||
if (Getattr(n, "noexcept")) {
|
||||
Printf(f_directors_h, " virtual ~%s() noexcept;\n", DirectorClassName);
|
||||
Printf(f_directors, "%s::~%s() noexcept {%s}\n\n", DirectorClassName, DirectorClassName, body);
|
||||
} else 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);
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -261,10 +261,9 @@ public:
|
|||
rename = strip(name);
|
||||
Printf(f_classInit, "ADD_FUNCTION(\"%s\", %s, tFunc(%s), 0);\n", rename, function, description);
|
||||
break;
|
||||
case CLASS_CONST:
|
||||
assert(false); // shouldn't have gotten here for CLASS_CONST nodes
|
||||
default:
|
||||
assert(false); // what is this?
|
||||
case CLASS_CONST: // shouldn't have gotten here for CLASS_CONST nodes
|
||||
default: // what is this?
|
||||
assert(false);
|
||||
}
|
||||
Delete(rename);
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
1439
Source/Modules/r.cxx
1439
Source/Modules/r.cxx
File diff suppressed because it is too large
Load diff
|
|
@ -131,12 +131,10 @@ enum autodoc_t {
|
|||
static const char *usage = "\
|
||||
Ruby Options (available with -ruby)\n\
|
||||
-autorename - Enable renaming of classes and methods to follow Ruby coding standards\n\
|
||||
-cppcast - Enable C++ casting operators (default)\n\
|
||||
-globalmodule - Wrap everything into the global module\n\
|
||||
-initname <name>- Set entry function to Init_<name> (used by `require')\n\
|
||||
-minherit - Attempt to support multiple inheritance\n\
|
||||
-noautorename - Disable renaming of classes and methods (default)\n\
|
||||
-nocppcast - Disable C++ casting operators, useful for generating bugs\n\
|
||||
-prefix <name> - Set a prefix <name> to be prepended to all names\n\
|
||||
";
|
||||
|
||||
|
|
@ -257,32 +255,22 @@ private:
|
|||
autodoc = make_autodoc(n, ad_type);
|
||||
have_auto = (autodoc && Len(autodoc) > 0);
|
||||
}
|
||||
// If there is more than one line then make docstrings like this:
|
||||
//
|
||||
// This is line1
|
||||
// And here is line2 followed by the rest of them
|
||||
//
|
||||
// otherwise, put it all on a single line
|
||||
//
|
||||
|
||||
if (have_auto || have_ds)
|
||||
doc = NewString("/*");
|
||||
|
||||
if (have_auto && have_ds) { // Both autodoc and docstring are present
|
||||
doc = NewString("");
|
||||
Printv(doc, "\n", autodoc, "\n", str, NIL);
|
||||
Printv(doc, "\n", autodoc, "\n", str, "\n", NIL);
|
||||
} else if (!have_auto && have_ds) { // only docstring
|
||||
if (Strchr(str, '\n') == 0) {
|
||||
doc = NewString(str);
|
||||
} else {
|
||||
doc = NewString("");
|
||||
Printv(doc, str, NIL);
|
||||
}
|
||||
Printv(doc, str, NIL);
|
||||
} else if (have_auto && !have_ds) { // only autodoc
|
||||
if (Strchr(autodoc, '\n') == 0) {
|
||||
doc = NewStringf("%s", autodoc);
|
||||
} else {
|
||||
doc = NewString("");
|
||||
Printv(doc, "\n", autodoc, NIL);
|
||||
}
|
||||
} else
|
||||
Printv(doc, "\n", autodoc, "\n", NIL);
|
||||
} else {
|
||||
doc = NewString("");
|
||||
}
|
||||
|
||||
if (have_auto || have_ds)
|
||||
Append(doc, "*/\n");
|
||||
|
||||
// Save the generated strings in the parse tree in case they are used later
|
||||
// by post processing tools
|
||||
|
|
@ -302,13 +290,14 @@ private:
|
|||
* The "lname" attribute in each parameter in plist will be contain a parameter name
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
void addMissingParameterNames(ParmList *plist, int arg_offset) {
|
||||
void addMissingParameterNames(Node* n, ParmList *plist, int arg_offset) {
|
||||
Parm *p = plist;
|
||||
int i = arg_offset;
|
||||
while (p) {
|
||||
if (!Getattr(p, "lname")) {
|
||||
String *pname = Swig_cparm_name(p, i);
|
||||
Delete(pname);
|
||||
String *name = makeParameterName(n, p, i);
|
||||
Setattr(p, "lname", name);
|
||||
Delete(name);
|
||||
}
|
||||
i++;
|
||||
p = nextSibling(p);
|
||||
|
|
@ -327,10 +316,10 @@ private:
|
|||
Parm *p;
|
||||
Parm *pnext;
|
||||
int lines = 0;
|
||||
int start_arg_num = is_wrapping_class() ? 1 : 0;
|
||||
int arg_num = is_wrapping_class() ? 1 : 0;
|
||||
const int maxwidth = 80;
|
||||
|
||||
addMissingParameterNames(plist, start_arg_num); // for $1_name substitutions done in Swig_typemap_attach_parms
|
||||
addMissingParameterNames(n, plist, arg_num); // for $1_name substitutions done in Swig_typemap_attach_parms
|
||||
|
||||
Swig_typemap_attach_parms("in", plist, 0);
|
||||
Swig_typemap_attach_parms("doc", plist, 0);
|
||||
|
|
@ -340,7 +329,7 @@ private:
|
|||
return doc;
|
||||
}
|
||||
|
||||
for (p = plist; p; p = pnext) {
|
||||
for (p = plist; p; p = pnext, arg_num++) {
|
||||
|
||||
String *tm = Getattr(p, "tmap:in");
|
||||
if (tm) {
|
||||
|
|
@ -363,9 +352,10 @@ private:
|
|||
}
|
||||
|
||||
// Note: the generated name should be consistent with that in kwnames[]
|
||||
name = name ? name : Getattr(p, "name");
|
||||
name = name ? name : Getattr(p, "lname");
|
||||
name = Swig_name_make(p, 0, name, 0, 0); // rename parameter if a keyword
|
||||
String *made_name = 0;
|
||||
if (!name) {
|
||||
name = made_name = makeParameterName(n, p, arg_num);
|
||||
}
|
||||
|
||||
type = type ? type : Getattr(p, "type");
|
||||
value = value ? value : Getattr(p, "value");
|
||||
|
|
@ -416,7 +406,7 @@ private:
|
|||
Printf(doc, "=%s", value);
|
||||
}
|
||||
Delete(type_str);
|
||||
Delete(name);
|
||||
Delete(made_name);
|
||||
}
|
||||
if (pdocs)
|
||||
Setattr(n, "feature:pdocs", pdocs);
|
||||
|
|
@ -436,7 +426,7 @@ private:
|
|||
|
||||
String *make_autodoc(Node *n, autodoc_t ad_type) {
|
||||
int extended = 0;
|
||||
// If the function is overloaded then this funciton is called
|
||||
// If the function is overloaded then this function is called
|
||||
// for the last one. Rewind to the first so the docstrings are
|
||||
// in order.
|
||||
while (Getattr(n, "sym:previousSibling"))
|
||||
|
|
@ -522,7 +512,7 @@ private:
|
|||
last_mode = ad_type;
|
||||
last_autodoc = Copy(methodName);
|
||||
|
||||
String *doc = NewString("/*\n");
|
||||
String *doc = NewString("");
|
||||
int counter = 0;
|
||||
bool skipAuto = false;
|
||||
Node* on = n;
|
||||
|
|
@ -762,7 +752,6 @@ private:
|
|||
n = Getattr(n, "sym:nextSibling");
|
||||
}
|
||||
|
||||
Append(doc, "\n*/\n");
|
||||
Delete(full_name);
|
||||
Delete(class_name);
|
||||
Delete(super_names);
|
||||
|
|
@ -844,7 +833,6 @@ public:
|
|||
|
||||
virtual void main(int argc, char *argv[]) {
|
||||
|
||||
int cppcast = 1;
|
||||
int autorename = 0;
|
||||
|
||||
/* Set location of SWIG library */
|
||||
|
|
@ -883,12 +871,6 @@ public:
|
|||
multipleInheritance = true;
|
||||
director_multiple_inheritance = 1;
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i], "-cppcast") == 0) {
|
||||
cppcast = 1;
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i], "-nocppcast") == 0) {
|
||||
cppcast = 0;
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i], "-autorename") == 0) {
|
||||
autorename = 1;
|
||||
Swig_mark_arg(i);
|
||||
|
|
@ -907,15 +889,17 @@ public:
|
|||
}
|
||||
} else if (strcmp(argv[i], "-help") == 0) {
|
||||
Printf(stdout, "%s\n", usage);
|
||||
} else if (strcmp(argv[i], "-cppcast") == 0) {
|
||||
Printf(stderr, "Deprecated command line option: %s. This option is now always on.\n", argv[i]);
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i], "-nocppcast") == 0) {
|
||||
Printf(stderr, "Deprecated command line option: %s. This option is no longer supported.\n", argv[i]);
|
||||
Swig_mark_arg(i);
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cppcast) {
|
||||
/* Turn on cppcast mode */
|
||||
Preprocessor_define((DOH *) "SWIG_CPLUSPLUS_CAST", 0);
|
||||
}
|
||||
|
||||
if (autorename) {
|
||||
/* Turn on the autorename mode */
|
||||
Preprocessor_define((DOH *) "SWIG_RUBY_AUTORENAME", 0);
|
||||
|
|
@ -1316,7 +1300,13 @@ public:
|
|||
Iterator alias = First(aliases);
|
||||
while (alias.item) {
|
||||
if (Len(alias.item) > 0) {
|
||||
if (multipleInheritance) {
|
||||
if (current == NO_CPP) {
|
||||
if (useGlobalModule) {
|
||||
Printv(f_init, tab4, "rb_define_alias(rb_cObject, \"", alias.item, "\", \"", iname, "\");\n", NIL);
|
||||
} else {
|
||||
Printv(f_init, tab4, "rb_define_alias(rb_singleton_class(", modvar, "), \"", alias.item, "\", \"", iname, "\");\n", NIL);
|
||||
}
|
||||
} else if (multipleInheritance) {
|
||||
Printv(klass->init, tab4, "rb_define_alias(", klass->mImpl, ", \"", alias.item, "\", \"", iname, "\");\n", NIL);
|
||||
} else {
|
||||
Printv(klass->init, tab4, "rb_define_alias(", klass->vname, ", \"", alias.item, "\", \"", iname, "\");\n", NIL);
|
||||
|
|
@ -1419,9 +1409,8 @@ public:
|
|||
case DESTRUCTOR:
|
||||
case CLASS_CONST:
|
||||
case STATIC_VAR:
|
||||
assert(false); // Should not have gotten here for these types
|
||||
default:
|
||||
assert(false);
|
||||
assert(false); // Should not have gotten here for these types
|
||||
}
|
||||
|
||||
defineAliases(n, iname);
|
||||
|
|
@ -2926,7 +2915,7 @@ public:
|
|||
Wrapper *w = NewWrapper();
|
||||
String *call;
|
||||
String *basetype = Getattr(parent, "classtype");
|
||||
String *target = Swig_method_decl(0, decl, classname, parms, 0, 0);
|
||||
String *target = Swig_method_decl(0, decl, classname, parms, 0);
|
||||
call = Swig_csuperclass_call(0, basetype, superparms);
|
||||
Printf(w->def, "%s::%s: %s, Swig::Director(self) { }", classname, target, call);
|
||||
Delete(target);
|
||||
|
|
@ -2937,7 +2926,7 @@ public:
|
|||
|
||||
/* constructor header */
|
||||
{
|
||||
String *target = Swig_method_decl(0, decl, classname, parms, 0, 1);
|
||||
String *target = Swig_method_decl(0, decl, classname, parms, 1);
|
||||
Printf(f_directors_h, " %s;\n", target);
|
||||
Delete(target);
|
||||
}
|
||||
|
|
@ -3047,7 +3036,7 @@ public:
|
|||
if (argc > 0) {
|
||||
Printf(w->code, "%s = rb_funcall(swig_get_self(), rb_intern(\"%s\"), %d%s);\n", Swig_cresult_name(), methodName, argc, args);
|
||||
} else {
|
||||
Printf(w->code, "%s = rb_funcall(swig_get_self(), rb_intern(\"%s\"), 0, NULL);\n", Swig_cresult_name(), methodName);
|
||||
Printf(w->code, "%s = rb_funcall(swig_get_self(), rb_intern(\"%s\"), 0, Qnil);\n", Swig_cresult_name(), methodName);
|
||||
}
|
||||
if ( initstack ) Printf(w->code, "SWIG_RELEASE_STACK;\n");
|
||||
}
|
||||
|
|
@ -3103,16 +3092,20 @@ public:
|
|||
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);
|
||||
target = Swig_method_decl(rtype, decl, qualified_name, l, 0);
|
||||
Printf(w->def, "%s", target);
|
||||
Delete(qualified_name);
|
||||
Delete(target);
|
||||
/* header declaration */
|
||||
target = Swig_method_decl(rtype, decl, name, l, 0, 1);
|
||||
target = Swig_method_decl(rtype, decl, name, l, 1);
|
||||
Printf(declaration, " virtual %s", target);
|
||||
Delete(target);
|
||||
|
||||
// Get any exception classes in the throws typemap
|
||||
if (Getattr(n, "noexcept")) {
|
||||
Append(w->def, " noexcept");
|
||||
Append(declaration, " noexcept");
|
||||
}
|
||||
ParmList *throw_parm_list = 0;
|
||||
|
||||
if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) {
|
||||
|
|
@ -3151,9 +3144,19 @@ public:
|
|||
* 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)) {
|
||||
Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), NIL);
|
||||
if (!is_void && (!ignored_method || pure_virtual)) {
|
||||
if (!SwigType_isclass(returntype)) {
|
||||
if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) {
|
||||
String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(returntype, 0));
|
||||
Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), construct_result, NIL);
|
||||
Delete(construct_result);
|
||||
} else {
|
||||
Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= 0", NIL);
|
||||
}
|
||||
} else {
|
||||
String *cres = SwigType_lstr(returntype, "c_result");
|
||||
Printf(w->code, "%s;\n", cres);
|
||||
Delete(cres);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3175,7 +3178,7 @@ public:
|
|||
Swig_director_parms_fixup(l);
|
||||
|
||||
Swig_typemap_attach_parms("in", l, 0);
|
||||
Swig_typemap_attach_parms("directorin", l, 0);
|
||||
Swig_typemap_attach_parms("directorin", l, w);
|
||||
Swig_typemap_attach_parms("directorargout", l, w);
|
||||
|
||||
char source[256];
|
||||
|
|
@ -3288,7 +3291,7 @@ public:
|
|||
}
|
||||
|
||||
/* declare Ruby return value */
|
||||
String *value_result = NewStringf("VALUE %s", Swig_cresult_name());
|
||||
String *value_result = NewStringf("VALUE SWIGUNUSED %s", Swig_cresult_name());
|
||||
Wrapper_add_local(w, Swig_cresult_name(), value_result);
|
||||
Delete(value_result);
|
||||
|
||||
|
|
|
|||
|
|
@ -18,13 +18,14 @@ static const int SCILAB_VARIABLE_NAME_CHAR_MAX = SCILAB_IDENTIFIER_NAME_CHAR_MAX
|
|||
|
||||
static const char *usage = (char *) " \
|
||||
Scilab options (available with -scilab)\n \
|
||||
-builder - Generate a Scilab builder script\n \
|
||||
-buildercflags <cflags> - Add <cflags> to the builder compiler flags\n \
|
||||
-builderflagscript <file> - Set the Scilab script <file> to use by builder to configure the build flags\n \
|
||||
-builderldflags <ldflags> - Add <ldflags> to the builder linker flags\n \
|
||||
-buildersources <files> - Add the (comma separated) files <files> to the builder sources\n \
|
||||
-builderverbositylevel <level> - Set the builder verbosity level to <level> (default 0: off, 2: high)\n \
|
||||
-gatewayxml <gateway_id> - Generate gateway xml with the given <gateway_id>\n \
|
||||
-builder - Generate a Scilab builder script\n \
|
||||
-buildercflags <cflags> - Add <cflags> to the builder compiler flags\n \
|
||||
-builderflagscript <file> - Set the Scilab script <file> to use by builder to configure the build flags\n \
|
||||
-builderldflags <ldflags> - Add <ldflags> to the builder linker flags\n \
|
||||
-buildersources <files> - Add the (comma separated) files <files> to the builder sources\n \
|
||||
-builderverbositylevel <level> - Set the builder verbosity level to <level> (default 0: off, 2: high)\n \
|
||||
-gatewayxml <gateway_id> - Generate gateway xml with the given <gateway_id>\n \
|
||||
-targetversion <scilab_major_version> - Generate for Scilab target (major) version (default: 5)\n \
|
||||
\n";
|
||||
|
||||
|
||||
|
|
@ -39,6 +40,8 @@ protected:
|
|||
|
||||
String *variablesCode;
|
||||
|
||||
int targetVersion;
|
||||
|
||||
bool generateBuilder;
|
||||
File *builderFile;
|
||||
String *builderCode;
|
||||
|
|
@ -71,6 +74,7 @@ public:
|
|||
* ----------------------------------------------------------------------*/
|
||||
|
||||
virtual void main(int argc, char *argv[]) {
|
||||
targetVersion = 5;
|
||||
|
||||
generateBuilder = false;
|
||||
sourceFileList = NewList();
|
||||
|
|
@ -95,48 +99,54 @@ public:
|
|||
/* Manage command line arguments */
|
||||
for (int argIndex = 1; argIndex < argc; argIndex++) {
|
||||
if (argv[argIndex] != NULL) {
|
||||
if (strcmp(argv[argIndex], "-help") == 0) {
|
||||
Printf(stdout, "%s\n", usage);
|
||||
} else if (strcmp(argv[argIndex], "-builder") == 0) {
|
||||
Swig_mark_arg(argIndex);
|
||||
generateBuilder = true;
|
||||
createLoader = false;
|
||||
} else if (strcmp(argv[argIndex], "-buildersources") == 0) {
|
||||
if (argv[argIndex + 1] != NULL) {
|
||||
Swig_mark_arg(argIndex);
|
||||
char *sourceFile = strtok(argv[argIndex + 1], ",");
|
||||
while (sourceFile != NULL) {
|
||||
Insert(sourceFileList, Len(sourceFileList), sourceFile);
|
||||
sourceFile = strtok(NULL, ",");
|
||||
}
|
||||
Swig_mark_arg(argIndex + 1);
|
||||
}
|
||||
} else if (strcmp(argv[argIndex], "-buildercflags") == 0) {
|
||||
Swig_mark_arg(argIndex);
|
||||
if (argv[argIndex + 1] != NULL) {
|
||||
Insert(cflags, Len(cflags), argv[argIndex + 1]);
|
||||
Swig_mark_arg(argIndex + 1);
|
||||
}
|
||||
} else if (strcmp(argv[argIndex], "-builderldflags") == 0) {
|
||||
Swig_mark_arg(argIndex);
|
||||
if (argv[argIndex + 1] != NULL) {
|
||||
Insert(ldflags, Len(ldflags), argv[argIndex + 1]);
|
||||
Swig_mark_arg(argIndex + 1);
|
||||
}
|
||||
} else if (strcmp(argv[argIndex], "-builderverbositylevel") == 0) {
|
||||
Swig_mark_arg(argIndex);
|
||||
verboseBuildLevel = NewString(argv[argIndex + 1]);
|
||||
Swig_mark_arg(argIndex + 1);
|
||||
} else if (strcmp(argv[argIndex], "-builderflagscript") == 0) {
|
||||
Swig_mark_arg(argIndex);
|
||||
buildFlagsScript = NewString(argv[argIndex + 1]);
|
||||
Swig_mark_arg(argIndex + 1);
|
||||
} else if (strcmp(argv[argIndex], "-gatewayxml") == 0) {
|
||||
Swig_mark_arg(argIndex);
|
||||
createGatewayXML = true;
|
||||
gatewayID = NewString(argv[argIndex + 1]);
|
||||
Swig_mark_arg(argIndex + 1);
|
||||
}
|
||||
if (strcmp(argv[argIndex], "-help") == 0) {
|
||||
Printf(stdout, "%s\n", usage);
|
||||
} else if (strcmp(argv[argIndex], "-builder") == 0) {
|
||||
Swig_mark_arg(argIndex);
|
||||
generateBuilder = true;
|
||||
createLoader = false;
|
||||
} else if (strcmp(argv[argIndex], "-buildersources") == 0) {
|
||||
if (argv[argIndex + 1] != NULL) {
|
||||
Swig_mark_arg(argIndex);
|
||||
char *sourceFile = strtok(argv[argIndex + 1], ",");
|
||||
while (sourceFile != NULL) {
|
||||
Insert(sourceFileList, Len(sourceFileList), sourceFile);
|
||||
sourceFile = strtok(NULL, ",");
|
||||
}
|
||||
Swig_mark_arg(argIndex + 1);
|
||||
}
|
||||
} else if (strcmp(argv[argIndex], "-buildercflags") == 0) {
|
||||
Swig_mark_arg(argIndex);
|
||||
if (argv[argIndex + 1] != NULL) {
|
||||
Insert(cflags, Len(cflags), argv[argIndex + 1]);
|
||||
Swig_mark_arg(argIndex + 1);
|
||||
}
|
||||
} else if (strcmp(argv[argIndex], "-builderldflags") == 0) {
|
||||
Swig_mark_arg(argIndex);
|
||||
if (argv[argIndex + 1] != NULL) {
|
||||
Insert(ldflags, Len(ldflags), argv[argIndex + 1]);
|
||||
Swig_mark_arg(argIndex + 1);
|
||||
}
|
||||
} else if (strcmp(argv[argIndex], "-builderverbositylevel") == 0) {
|
||||
Swig_mark_arg(argIndex);
|
||||
verboseBuildLevel = NewString(argv[argIndex + 1]);
|
||||
Swig_mark_arg(argIndex + 1);
|
||||
} else if (strcmp(argv[argIndex], "-builderflagscript") == 0) {
|
||||
Swig_mark_arg(argIndex);
|
||||
buildFlagsScript = NewString(argv[argIndex + 1]);
|
||||
Swig_mark_arg(argIndex + 1);
|
||||
} else if (strcmp(argv[argIndex], "-gatewayxml") == 0) {
|
||||
Swig_mark_arg(argIndex);
|
||||
createGatewayXML = true;
|
||||
gatewayID = NewString(argv[argIndex + 1]);
|
||||
Swig_mark_arg(argIndex + 1);
|
||||
} else if (strcmp(argv[argIndex], "-targetversion") == 0) {
|
||||
if (argv[argIndex + 1] != NULL) {
|
||||
Swig_mark_arg(argIndex);
|
||||
targetVersion = atoi(argv[argIndex + 1]);
|
||||
Swig_mark_arg(argIndex + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -412,7 +422,7 @@ public:
|
|||
emit_return_variable(node, functionReturnType, wrapper);
|
||||
|
||||
/* Return the function value if necessary */
|
||||
String *functionReturnTypemap = Swig_typemap_lookup_out("out", node, "result", wrapper, functionActionCode);
|
||||
String *functionReturnTypemap = Swig_typemap_lookup_out("out", node, Swig_cresult_name(), wrapper, functionActionCode);
|
||||
if (functionReturnTypemap) {
|
||||
// Result is actually the position of output value on stack
|
||||
if (Len(functionReturnTypemap) > 0) {
|
||||
|
|
@ -471,6 +481,13 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
/* See if there is any return cleanup code */
|
||||
String *tm;
|
||||
if ((tm = Swig_typemap_lookup("ret", node, Swig_cresult_name(), 0))) {
|
||||
Replaceall(tm, "$source", Swig_cresult_name());
|
||||
Printf(wrapper->code, "%s\n", tm);
|
||||
Delete(tm);
|
||||
}
|
||||
|
||||
/* Close the function(ok) */
|
||||
Printv(wrapper->code, "return SWIG_OK;\n", NIL);
|
||||
|
|
@ -479,7 +496,7 @@ public:
|
|||
/* Add the failure cleanup code */
|
||||
/* TODO */
|
||||
|
||||
/* Final substititions if applicable */
|
||||
/* Final substitutions if applicable */
|
||||
Replaceall(wrapper->code, "$symname", functionName);
|
||||
|
||||
/* Set CheckInputArgument and CheckOutputArgument input arguments */
|
||||
|
|
@ -777,57 +794,61 @@ public:
|
|||
|
||||
/* -----------------------------------------------------------------------
|
||||
* checkIdentifierName()
|
||||
* Truncates (and displays a warning) for too long identifier names
|
||||
* (applies on functions, variables, constants...)
|
||||
* (Scilab identifiers names are limited to 24 chars max)
|
||||
* If Scilab target version is lower than 6:
|
||||
* truncates (and displays a warning) too long member identifier names
|
||||
* (applies on members of structs, classes...)
|
||||
* (Scilab 5 identifier names are limited to 24 chars max)
|
||||
* ----------------------------------------------------------------------- */
|
||||
|
||||
String *checkIdentifierName(String *name, int char_size_max) {
|
||||
String *scilabIdentifierName;
|
||||
if (Len(name) > char_size_max) {
|
||||
scilabIdentifierName = DohNewStringWithSize(name, char_size_max);
|
||||
Swig_warning(WARN_SCILAB_TRUNCATED_NAME, input_file, line_number,
|
||||
"Identifier name '%s' exceeds 24 characters and has been truncated to '%s'.\n", name, scilabIdentifierName);
|
||||
} else
|
||||
if (targetVersion <= 5) {
|
||||
if (Len(name) > char_size_max) {
|
||||
scilabIdentifierName = DohNewStringWithSize(name, char_size_max);
|
||||
Swig_warning(WARN_SCILAB_TRUNCATED_NAME, input_file, line_number,
|
||||
"Identifier name '%s' exceeds 24 characters and has been truncated to '%s'.\n", name, scilabIdentifierName);
|
||||
} else
|
||||
scilabIdentifierName = name;
|
||||
return scilabIdentifierName;
|
||||
} else {
|
||||
scilabIdentifierName = DohNewString(name);
|
||||
}
|
||||
return scilabIdentifierName;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------
|
||||
* checkMemberIdentifierName()
|
||||
* Truncates (and displays a warning) too long member identifier names
|
||||
* (applies on members of structs, classes...)
|
||||
* (Scilab identifiers names are limited to 24 chars max)
|
||||
* If Scilab target version is lower than 6:
|
||||
* truncates (and displays a warning) too long member identifier names
|
||||
* (applies on members of structs, classes...)
|
||||
* (Scilab 5 identifier names are limited to 24 chars max)
|
||||
* ----------------------------------------------------------------------- */
|
||||
|
||||
void checkMemberIdentifierName(Node *node, int char_size_max) {
|
||||
if (targetVersion <= 5) {
|
||||
String *memberName = Getattr(node, "sym:name");
|
||||
Node *containerNode = parentNode(node);
|
||||
String *containerName = Getattr(containerNode, "sym:name");
|
||||
int lenContainerName = Len(containerName);
|
||||
int lenMemberName = Len(memberName);
|
||||
|
||||
String *memberName = Getattr(node, "sym:name");
|
||||
if (lenContainerName + lenMemberName + 1 > char_size_max) {
|
||||
int lenScilabMemberName = char_size_max - lenContainerName - 1;
|
||||
|
||||
Node *containerNode = parentNode(node);
|
||||
String *containerName = Getattr(containerNode, "sym:name");
|
||||
|
||||
int lenContainerName = Len(containerName);
|
||||
int lenMemberName = Len(memberName);
|
||||
|
||||
if (lenContainerName + lenMemberName + 1 > char_size_max) {
|
||||
int lenScilabMemberName = char_size_max - lenContainerName - 1;
|
||||
|
||||
if (lenScilabMemberName > 0) {
|
||||
String *scilabMemberName = DohNewStringWithSize(memberName, lenScilabMemberName);
|
||||
Setattr(node, "sym:name", scilabMemberName);
|
||||
Swig_warning(WARN_SCILAB_TRUNCATED_NAME, input_file, line_number,
|
||||
"Wrapping functions names for member '%s.%s' will exceed 24 characters, "
|
||||
"so member name has been truncated to '%s'.\n", containerName, memberName, scilabMemberName);
|
||||
} else
|
||||
Swig_error(input_file, line_number,
|
||||
"Wrapping functions names for member '%s.%s' will exceed 24 characters, "
|
||||
"please rename the container of member '%s'.\n", containerName, memberName, containerName);
|
||||
if (lenScilabMemberName > 0) {
|
||||
String *scilabMemberName = DohNewStringWithSize(memberName, lenScilabMemberName);
|
||||
Setattr(node, "sym:name", scilabMemberName);
|
||||
Swig_warning(WARN_SCILAB_TRUNCATED_NAME, input_file, line_number,
|
||||
"Wrapping functions names for member '%s.%s' will exceed 24 characters, "
|
||||
"so member name has been truncated to '%s'.\n", containerName, memberName, scilabMemberName);
|
||||
} else {
|
||||
Swig_error(input_file, line_number,
|
||||
"Wrapping functions names for member '%s.%s' will exceed 24 characters, "
|
||||
"please rename the container of member '%s'.\n", containerName, memberName, containerName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* -----------------------------------------------------------------------
|
||||
* addHelperFunctions()
|
||||
* ----------------------------------------------------------------------- */
|
||||
|
|
@ -1006,8 +1027,14 @@ public:
|
|||
Printf(gatewayHeader, "\n");
|
||||
|
||||
gatewayHeaderV6 = NewString("");
|
||||
Printf(gatewayHeaderV6, "#ifdef __cplusplus\n");
|
||||
Printf(gatewayHeaderV6, "extern \"C\" {\n");
|
||||
Printf(gatewayHeaderV6, "#endif\n");
|
||||
Printf(gatewayHeaderV6, "#include \"c_gateway_prototype.h\"\n");
|
||||
Printf(gatewayHeaderV6, "#include \"addfunction.h\"\n");
|
||||
Printf(gatewayHeaderV6, "#ifdef __cplusplus\n");
|
||||
Printf(gatewayHeaderV6, "}\n");
|
||||
Printf(gatewayHeaderV6, "#endif\n");
|
||||
Printf(gatewayHeaderV6, "\n");
|
||||
Printf(gatewayHeaderV6, "#define MODULE_NAME L\"%s\"\n", gatewayLibraryName);
|
||||
Printf(gatewayHeaderV6, "#ifdef __cplusplus\n");
|
||||
|
|
|
|||
|
|
@ -26,79 +26,64 @@
|
|||
can be dynamically loaded in future versions. */
|
||||
|
||||
extern "C" {
|
||||
Language *swig_tcl(void);
|
||||
Language *swig_python(void);
|
||||
Language *swig_perl5(void);
|
||||
Language *swig_ruby(void);
|
||||
Language *swig_c(void);
|
||||
Language *swig_csharp(void);
|
||||
Language *swig_d(void);
|
||||
Language *swig_go(void);
|
||||
Language *swig_guile(void);
|
||||
Language *swig_modula3(void);
|
||||
Language *swig_mzscheme(void);
|
||||
Language *swig_java(void);
|
||||
Language *swig_php(void);
|
||||
Language *swig_php4(void);
|
||||
Language *swig_javascript(void);
|
||||
Language *swig_lua(void);
|
||||
Language *swig_mzscheme(void);
|
||||
Language *swig_ocaml(void);
|
||||
Language *swig_octave(void);
|
||||
Language *swig_pike(void);
|
||||
Language *swig_sexp(void);
|
||||
Language *swig_xml(void);
|
||||
Language *swig_chicken(void);
|
||||
Language *swig_csharp(void);
|
||||
Language *swig_allegrocl(void);
|
||||
Language *swig_lua(void);
|
||||
Language *swig_clisp(void);
|
||||
Language *swig_cffi(void);
|
||||
Language *swig_uffi(void);
|
||||
Language *swig_perl5(void);
|
||||
Language *swig_php(void);
|
||||
Language *swig_python(void);
|
||||
Language *swig_r(void);
|
||||
Language *swig_c(void);
|
||||
Language *swig_ruby(void);
|
||||
Language *swig_scilab(void);
|
||||
Language *swig_go(void);
|
||||
Language *swig_d(void);
|
||||
Language *swig_javascript(void);
|
||||
Language *swig_tcl(void);
|
||||
Language *swig_xml(void);
|
||||
}
|
||||
|
||||
struct swig_module {
|
||||
const char *name;
|
||||
ModuleFactory fac;
|
||||
const char *help;
|
||||
};
|
||||
|
||||
/* Association of command line options to language modules.
|
||||
Place an entry for new language modules here, keeping the
|
||||
list sorted alphabetically. */
|
||||
|
||||
static swig_module modules[] = {
|
||||
{"-allegrocl", swig_allegrocl, "ALLEGROCL"},
|
||||
{"-c", swig_c, "C"},
|
||||
{"-chicken", swig_chicken, "CHICKEN"},
|
||||
{"-clisp", swig_clisp, "CLISP"},
|
||||
{"-cffi", swig_cffi, "CFFI"},
|
||||
{"-csharp", swig_csharp, "C#"},
|
||||
{"-d", swig_d, "D"},
|
||||
{"-go", swig_go, "Go"},
|
||||
{"-guile", swig_guile, "Guile"},
|
||||
{"-java", swig_java, "Java"},
|
||||
{"-javascript", swig_javascript, "Javascript"},
|
||||
{"-lua", swig_lua, "Lua"},
|
||||
{"-modula3", swig_modula3, "Modula 3"},
|
||||
{"-mzscheme", swig_mzscheme, "Mzscheme"},
|
||||
{"-ocaml", swig_ocaml, "Ocaml"},
|
||||
{"-octave", swig_octave, "Octave"},
|
||||
{"-perl", swig_perl5, "Perl"},
|
||||
{"-perl5", swig_perl5, 0},
|
||||
{"-php", swig_php, "PHP"},
|
||||
{"-php4", swig_php4, 0},
|
||||
{"-php5", swig_php, 0},
|
||||
{"-pike", swig_pike, "Pike"},
|
||||
{"-python", swig_python, "Python"},
|
||||
{"-r", swig_r, "R (aka GNU S)"},
|
||||
{"-ruby", swig_ruby, "Ruby"},
|
||||
{"-scilab", swig_scilab, "Scilab"},
|
||||
{"-sexp", swig_sexp, "Lisp S-Expressions"},
|
||||
{"-tcl", swig_tcl, "Tcl"},
|
||||
{"-tcl8", swig_tcl, 0},
|
||||
{"-uffi", swig_uffi, "Common Lisp / UFFI"},
|
||||
{"-xml", swig_xml, "XML"},
|
||||
{NULL, NULL, NULL}
|
||||
static TargetLanguageModule modules[] = {
|
||||
{"-allegrocl", NULL, "ALLEGROCL", Disabled},
|
||||
{"-c", swig_c, "C", Experimental},
|
||||
{"-chicken", NULL, "CHICKEN", Disabled},
|
||||
{"-clisp", NULL, "CLISP", Disabled},
|
||||
{"-cffi", NULL, "CFFI", Disabled},
|
||||
{"-csharp", swig_csharp, "C#", Supported},
|
||||
{"-d", swig_d, "D", Supported},
|
||||
{"-go", swig_go, "Go", Supported},
|
||||
{"-guile", swig_guile, "Guile", Supported},
|
||||
{"-java", swig_java, "Java", Supported},
|
||||
{"-javascript", swig_javascript, "Javascript", Supported},
|
||||
{"-lua", swig_lua, "Lua", Supported},
|
||||
{"-modula3", NULL, "Modula 3", Disabled},
|
||||
{"-mzscheme", swig_mzscheme, "MzScheme/Racket", Experimental},
|
||||
{"-ocaml", swig_ocaml, "OCaml", Experimental},
|
||||
{"-octave", swig_octave, "Octave", Supported},
|
||||
{"-perl", swig_perl5, NULL, Supported},
|
||||
{"-perl5", swig_perl5, "Perl 5", Supported},
|
||||
{"-php", swig_php, NULL, Supported},
|
||||
{"-php5", NULL, "PHP 5", Disabled},
|
||||
{"-php7", swig_php, "PHP 7", Supported},
|
||||
{"-pike", NULL, "Pike", Disabled},
|
||||
{"-python", swig_python, "Python", Supported},
|
||||
{"-r", swig_r, "R (aka GNU S)", Supported},
|
||||
{"-ruby", swig_ruby, "Ruby", Supported},
|
||||
{"-scilab", swig_scilab, "Scilab", Supported},
|
||||
{"-sexp", NULL, "Lisp S-Expressions", Disabled},
|
||||
{"-tcl", swig_tcl, NULL, Supported},
|
||||
{"-tcl8", swig_tcl, "Tcl 8", Supported},
|
||||
{"-uffi", NULL, "Common Lisp / UFFI", Disabled},
|
||||
{"-xml", swig_xml, "XML", Supported},
|
||||
{NULL, NULL, NULL, Disabled}
|
||||
};
|
||||
|
||||
#ifdef MACSWIG
|
||||
|
|
@ -106,10 +91,6 @@ static swig_module modules[] = {
|
|||
#include <SIOUX.h>
|
||||
#endif
|
||||
|
||||
#ifndef SWIG_LANG
|
||||
#define SWIG_LANG "-python"
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
// main()
|
||||
//
|
||||
|
|
@ -119,13 +100,14 @@ static swig_module modules[] = {
|
|||
void SWIG_merge_envopt(const char *env, int oargc, char *oargv[], int *nargc, char ***nargv) {
|
||||
if (!env) {
|
||||
*nargc = oargc;
|
||||
*nargv = oargv;
|
||||
*nargv = (char **)malloc(sizeof(char *) * (oargc + 1));
|
||||
memcpy(*nargv, oargv, sizeof(char *) * (oargc + 1));
|
||||
return;
|
||||
}
|
||||
|
||||
int argc = 1;
|
||||
int arge = oargc + 1024;
|
||||
char **argv = (char **) malloc(sizeof(char *) * (arge));
|
||||
char **argv = (char **) malloc(sizeof(char *) * (arge + 1));
|
||||
char *buffer = (char *) malloc(2048);
|
||||
char *b = buffer;
|
||||
char *be = b + 1023;
|
||||
|
|
@ -147,49 +129,139 @@ void SWIG_merge_envopt(const char *env, int oargc, char *oargv[], int *nargc, ch
|
|||
for (int i = 1; (i < oargc) && (argc < arge); ++i, ++argc) {
|
||||
argv[argc] = oargv[i];
|
||||
}
|
||||
argv[argc] = NULL;
|
||||
|
||||
*nargc = argc;
|
||||
*nargv = argv;
|
||||
}
|
||||
|
||||
static void insert_option(int *argc, char ***argv, int index, char const *start, char const *end) {
|
||||
int new_argc = *argc;
|
||||
char **new_argv = *argv;
|
||||
size_t option_len = end - start;
|
||||
|
||||
// Preserve the NULL pointer at argv[argc]
|
||||
new_argv = (char **)realloc(new_argv, (new_argc + 2) * sizeof(char *));
|
||||
memmove(&new_argv[index + 1], &new_argv[index], sizeof(char *) * (new_argc + 1 - index));
|
||||
new_argc++;
|
||||
|
||||
new_argv[index] = (char *)malloc(option_len + 1);
|
||||
memcpy(new_argv[index], start, option_len);
|
||||
new_argv[index][option_len] = '\0';
|
||||
|
||||
*argc = new_argc;
|
||||
*argv = new_argv;
|
||||
}
|
||||
|
||||
static void merge_options_files(int *argc, char ***argv) {
|
||||
static const int BUFFER_SIZE = 4096;
|
||||
char buffer[BUFFER_SIZE];
|
||||
int i;
|
||||
int insert;
|
||||
char **new_argv = *argv;
|
||||
int new_argc = *argc;
|
||||
FILE *f;
|
||||
|
||||
i = 1;
|
||||
while (i < new_argc) {
|
||||
if (new_argv[i] && new_argv[i][0] == '@' && (f = fopen(&new_argv[i][1], "r"))) {
|
||||
char c;
|
||||
char *b;
|
||||
char *be = &buffer[BUFFER_SIZE];
|
||||
int quote = 0;
|
||||
bool escape = false;
|
||||
|
||||
new_argc--;
|
||||
memmove(&new_argv[i], &new_argv[i + 1], sizeof(char *) * (new_argc - i));
|
||||
insert = i;
|
||||
b = buffer;
|
||||
|
||||
while ((c = fgetc(f)) != EOF) {
|
||||
if (escape) {
|
||||
if (b != be) {
|
||||
*b = c;
|
||||
++b;
|
||||
}
|
||||
escape = false;
|
||||
} else if (c == '\\') {
|
||||
escape = true;
|
||||
} else if (!quote && (c == '\'' || c == '"')) {
|
||||
quote = c;
|
||||
} else if (quote && c == quote) {
|
||||
quote = 0;
|
||||
} else if (isspace(c) && !quote) {
|
||||
if (b != buffer) {
|
||||
insert_option(&new_argc, &new_argv, insert, buffer, b);
|
||||
insert++;
|
||||
|
||||
b = buffer;
|
||||
}
|
||||
} else if (b != be) {
|
||||
*b = c;
|
||||
++b;
|
||||
}
|
||||
}
|
||||
if (b != buffer)
|
||||
insert_option(&new_argc, &new_argv, insert, buffer, b);
|
||||
fclose(f);
|
||||
} else {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
*argv = new_argv;
|
||||
*argc = new_argc;
|
||||
}
|
||||
|
||||
int main(int margc, char **margv) {
|
||||
int i;
|
||||
Language *dl = 0;
|
||||
ModuleFactory fac = 0;
|
||||
const TargetLanguageModule *language_module = 0;
|
||||
|
||||
int argc;
|
||||
char **argv;
|
||||
|
||||
SWIG_merge_envopt(getenv("SWIG_FEATURES"), margc, margv, &argc, &argv);
|
||||
merge_options_files(&argc, &argv);
|
||||
|
||||
#ifdef MACSWIG
|
||||
SIOUXSettings.asktosaveonclose = false;
|
||||
argc = ccommand(&argv);
|
||||
#endif
|
||||
|
||||
/* Register built-in modules */
|
||||
for (i = 0; modules[i].name; i++) {
|
||||
Swig_register_module(modules[i].name, modules[i].fac);
|
||||
}
|
||||
|
||||
Swig_init_args(argc, argv);
|
||||
|
||||
/* Get options */
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (argv[i]) {
|
||||
fac = Swig_find_module(argv[i]);
|
||||
if (fac) {
|
||||
dl = (fac) ();
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i], "-nolang") == 0) {
|
||||
dl = new Language;
|
||||
bool is_target_language_module = false;
|
||||
for (int j = 0; modules[j].name; j++) {
|
||||
if (strcmp(modules[j].name, argv[i]) == 0) {
|
||||
language_module = &modules[j];
|
||||
is_target_language_module = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (is_target_language_module) {
|
||||
Swig_mark_arg(i);
|
||||
if (language_module->status == Disabled) {
|
||||
if (language_module->help)
|
||||
Printf(stderr, "Target language option %s (%s) is no longer supported.\n", language_module->name, language_module->help);
|
||||
else
|
||||
Printf(stderr, "Target language option %s is no longer supported.\n", language_module->name);
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
}
|
||||
} else if ((strcmp(argv[i], "-help") == 0) || (strcmp(argv[i], "--help") == 0)) {
|
||||
if (strcmp(argv[i], "--help") == 0)
|
||||
strcpy(argv[i], "-help");
|
||||
Printf(stdout, "Target Language Options\n");
|
||||
Printf(stdout, "Supported Target Language Options\n");
|
||||
for (int j = 0; modules[j].name; j++) {
|
||||
if (modules[j].help) {
|
||||
if (modules[j].help && modules[j].status == Supported) {
|
||||
Printf(stdout, " %-15s - Generate %s wrappers\n", modules[j].name, modules[j].help);
|
||||
}
|
||||
}
|
||||
Printf(stdout, "\nExperimental Target Language Options\n");
|
||||
for (int j = 0; modules[j].name; j++) {
|
||||
if (modules[j].help && modules[j].status == Experimental) {
|
||||
Printf(stdout, " %-15s - Generate %s wrappers\n", modules[j].name, modules[j].help);
|
||||
}
|
||||
}
|
||||
|
|
@ -197,14 +269,8 @@ int main(int margc, char **margv) {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (!dl) {
|
||||
fac = Swig_find_module(SWIG_LANG);
|
||||
if (fac) {
|
||||
dl = (fac) ();
|
||||
}
|
||||
}
|
||||
|
||||
int res = SWIG_main(argc, argv, dl);
|
||||
int res = SWIG_main(argc, argv, language_module);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -214,8 +214,8 @@ public:
|
|||
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 */
|
||||
static Node *classLookup(const SwigType *s); /* Class lookup */
|
||||
static Node *enumLookup(SwigType *s); /* Enum lookup */
|
||||
virtual int abstractClassTest(Node *n); /* Is class really abstract? */
|
||||
virtual int is_assignable(Node *n); /* Is variable assignable? */
|
||||
virtual String *runtimeCode(); /* returns the language specific runtime code */
|
||||
|
|
@ -342,10 +342,11 @@ protected:
|
|||
/* Director language module */
|
||||
int director_language;
|
||||
|
||||
/* Used to translate Doxygen comments to target documentation format */
|
||||
class DoxygenTranslator *doxygenTranslator;
|
||||
|
||||
private:
|
||||
Hash *symtabs; /* symbol tables */
|
||||
Hash *classtypes;
|
||||
Hash *enumtypes;
|
||||
int overloading;
|
||||
int multiinput;
|
||||
int cplus_runtime;
|
||||
|
|
@ -353,7 +354,21 @@ private:
|
|||
static Language *this_;
|
||||
};
|
||||
|
||||
int SWIG_main(int, char **, Language *);
|
||||
extern "C" {
|
||||
void SWIG_typemap_lang(const char *);
|
||||
typedef Language *(*ModuleFactory) (void);
|
||||
}
|
||||
|
||||
enum Status {Disabled, Experimental, Supported};
|
||||
|
||||
struct TargetLanguageModule {
|
||||
const char *name;
|
||||
ModuleFactory fac;
|
||||
const char *help;
|
||||
Status status;
|
||||
};
|
||||
|
||||
int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm);
|
||||
void emit_parameter_variables(ParmList *l, Wrapper *f);
|
||||
void emit_return_variable(Node *n, SwigType *rt, Wrapper *f);
|
||||
void SWIG_exit(int); /* use EXIT_{SUCCESS,FAILURE} */
|
||||
|
|
@ -368,15 +383,15 @@ List *SWIG_output_files();
|
|||
void SWIG_library_directory(const char *);
|
||||
int emit_num_arguments(ParmList *);
|
||||
int emit_num_required(ParmList *);
|
||||
int emit_isvarargs(ParmList *);
|
||||
int emit_isvarargs(ParmList *p);
|
||||
bool emit_isvarargs_function(Node *n);
|
||||
void emit_attach_parmmaps(ParmList *, Wrapper *f);
|
||||
void emit_mark_varargs(ParmList *l);
|
||||
String *emit_action(Node *n);
|
||||
int emit_action_code(Node *n, String *wrappercode, String *action);
|
||||
void Swig_overload_check(Node *n);
|
||||
String *Swig_overload_dispatch(Node *n, const_String_or_char_ptr fmt, int *);
|
||||
String *Swig_overload_dispatch(Node *n, const_String_or_char_ptr fmt, int *, const_String_or_char_ptr fmt_fastdispatch = 0);
|
||||
String *Swig_overload_dispatch_cast(Node *n, const_String_or_char_ptr fmt, int *);
|
||||
String *Swig_overload_dispatch_fast(Node *n, const_String_or_char_ptr fmt, int *);
|
||||
List *Swig_overload_rank(Node *n, bool script_lang_wrapping);
|
||||
SwigType *cplus_value_type(SwigType *t);
|
||||
|
||||
|
|
@ -385,20 +400,12 @@ String *Swig_csuperclass_call(String *base, String *method, ParmList *l);
|
|||
String *Swig_class_declaration(Node *n, String *name);
|
||||
String *Swig_class_name(Node *n);
|
||||
String *Swig_method_call(const_String_or_char_ptr name, ParmList *parms);
|
||||
String *Swig_method_decl(SwigType *rtype, SwigType *decl, const_String_or_char_ptr id, List *args, int strip, int values);
|
||||
String *Swig_method_decl(SwigType *return_base_type, SwigType *decl, const_String_or_char_ptr id, List *args, int default_args);
|
||||
String *Swig_director_declaration(Node *n);
|
||||
void Swig_director_emit_dynamic_cast(Node *n, Wrapper *f);
|
||||
void Swig_director_parms_fixup(ParmList *parms);
|
||||
/* directors.cxx end */
|
||||
|
||||
extern "C" {
|
||||
void SWIG_typemap_lang(const char *);
|
||||
typedef Language *(*ModuleFactory) (void);
|
||||
}
|
||||
|
||||
void Swig_register_module(const char *name, ModuleFactory fac);
|
||||
ModuleFactory Swig_find_module(const char *name);
|
||||
|
||||
/* Utilities */
|
||||
|
||||
int is_public(Node *n);
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
#include "cparse.h"
|
||||
|
||||
static const char *usage = "\
|
||||
Tcl 8 Options (available with -tcl)\n\
|
||||
Tcl 8 Options (available with -tcl8)\n\
|
||||
-itcl - Enable ITcl support\n\
|
||||
-nosafe - Leave out SafeInit module function.\n\
|
||||
-prefix <name> - Set a prefix <name> to be prepended to all names\n\
|
||||
|
|
@ -76,7 +76,6 @@ public:
|
|||
* ------------------------------------------------------------ */
|
||||
|
||||
virtual void main(int argc, char *argv[]) {
|
||||
int cppcast = 1;
|
||||
|
||||
SWIG_library_directory("tcl");
|
||||
|
||||
|
|
@ -106,22 +105,19 @@ public:
|
|||
} else if (strcmp(argv[i], "-nosafe") == 0) {
|
||||
nosafe = 1;
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i], "-cppcast") == 0) {
|
||||
cppcast = 1;
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i], "-nocppcast") == 0) {
|
||||
cppcast = 0;
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i], "-help") == 0) {
|
||||
fputs(usage, stdout);
|
||||
} else if (strcmp(argv[i], "-cppcast") == 0) {
|
||||
Printf(stderr, "Deprecated command line option: %s. This option is now always on.\n", argv[i]);
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i], "-nocppcast") == 0) {
|
||||
Printf(stderr, "Deprecated command line option: %s. This option is no longer supported.\n", argv[i]);
|
||||
Swig_mark_arg(i);
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cppcast) {
|
||||
Preprocessor_define((DOH *) "SWIG_CPLUSPLUS_CAST", 0);
|
||||
}
|
||||
|
||||
Preprocessor_define("SWIGTCL 1", 0);
|
||||
// SWIGTCL8 is deprecated, and no longer documented.
|
||||
Preprocessor_define("SWIGTCL8 1", 0);
|
||||
|
|
|
|||
|
|
@ -187,8 +187,10 @@ class TypePass:private Dispatcher {
|
|||
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));
|
||||
if (!GetFlag(bcls, "feature:ignore")) {
|
||||
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;
|
||||
|
|
@ -209,8 +211,10 @@ class TypePass:private Dispatcher {
|
|||
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));
|
||||
if (!GetFlag(bcls, "feature:ignore")) {
|
||||
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));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bname), Getline(bname), "Base class '%s' undefined.\n", SwigType_namestr(bname));
|
||||
|
|
@ -566,6 +570,10 @@ class TypePass:private Dispatcher {
|
|||
SwigType_typedef_class(rname);
|
||||
Delete(rname);
|
||||
/* SwigType_typedef_class(name); */
|
||||
} else if (Strcmp(ttype, "cdecl") == 0) {
|
||||
String *rname = SwigType_typedef_resolve_all(name);
|
||||
SwigType_typedef_class(rname);
|
||||
Delete(rname);
|
||||
}
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
|
@ -1195,10 +1203,7 @@ class TypePass:private Dispatcher {
|
|||
} else if (Strcmp(ntype, "enum") == 0) {
|
||||
SwigType_typedef_using(Getattr(n, "uname"));
|
||||
} else if (Strcmp(ntype, "template") == 0) {
|
||||
/*
|
||||
Printf(stdout, "usingDeclaration template %s --- %s\n", Getattr(n, "name"), Getattr(n, "uname"));
|
||||
SwigType_typedef_using(Getattr(n, "uname"));
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -363,23 +363,24 @@ int UFFI::classHandler(Node *n) {
|
|||
for (c = firstChild(n); c; c = nextSibling(c)) {
|
||||
SwigType *type = Getattr(c, "type");
|
||||
SwigType *decl = Getattr(c, "decl");
|
||||
type = Copy(type);
|
||||
SwigType_push(type, decl);
|
||||
String *lisp_type;
|
||||
if (type) {
|
||||
type = Copy(type);
|
||||
SwigType_push(type, decl);
|
||||
String *lisp_type;
|
||||
|
||||
if (Strcmp(nodeType(c), "cdecl")) {
|
||||
Printf(stderr, "Structure %s has a slot that we can't deal with.\n", name);
|
||||
Printf(stderr, "nodeType: %s, name: %s, type: %s\n", nodeType(c), Getattr(c, "name"), Getattr(c, "type"));
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
if (Strcmp(nodeType(c), "cdecl")) {
|
||||
Printf(stderr, "Structure %s has a slot that we can't deal with.\n", name);
|
||||
Printf(stderr, "nodeType: %s, name: %s, type: %s\n", nodeType(c), Getattr(c, "name"), Getattr(c, "type"));
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Printf(stdout, "Converting %s in %s\n", type, name); */
|
||||
lisp_type = get_ffi_type(n, type, Getattr(c, "sym:name"));
|
||||
|
||||
Printf(f_cl, " (#.(%s \"%s\" :type :slot) %s)\n", identifier_converter, Getattr(c, "sym:name"), lisp_type);
|
||||
|
||||
Delete(lisp_type);
|
||||
}
|
||||
|
||||
|
||||
/* Printf(stdout, "Converting %s in %s\n", type, name); */
|
||||
lisp_type = get_ffi_type(n, type, Getattr(c, "sym:name"));
|
||||
|
||||
Printf(f_cl, " (#.(%s \"%s\" :type :slot) %s)\n", identifier_converter, Getattr(c, "sym:name"), lisp_type);
|
||||
|
||||
Delete(lisp_type);
|
||||
}
|
||||
|
||||
// Language::classHandler(n);
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ int is_non_virtual_protected_access(Node *n) {
|
|||
// When vtable is empty, the director class does not get emitted, so a check for an empty vtable should be done.
|
||||
// However, vtable is set in Language and so is not yet set when methods in Typepass call clean_overloaded()
|
||||
// which calls is_non_virtual_protected_access. So commented out below.
|
||||
// Moving the director vtable creation into into Typepass should solve this problem.
|
||||
// Moving the director vtable creation into Typepass should solve this problem.
|
||||
if (is_member_director_helper(parentNode, n) /* && Getattr(parentNode, "vtable")*/)
|
||||
result = 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -144,8 +144,8 @@ public:
|
|||
Xml_print_kwargs(Getattr(obj, k));
|
||||
} else if (Cmp(k, "parms") == 0 || Cmp(k, "pattern") == 0) {
|
||||
Xml_print_parmlist(Getattr(obj, k));
|
||||
} else if (Cmp(k, "catchlist") == 0) {
|
||||
Xml_print_parmlist(Getattr(obj, k), "catchlist");
|
||||
} else if (Cmp(k, "catchlist") == 0 || Cmp(k, "templateparms") == 0) {
|
||||
Xml_print_parmlist(Getattr(obj, k), Char(k));
|
||||
} else {
|
||||
DOH *o;
|
||||
print_indent(0);
|
||||
|
|
|
|||
|
|
@ -109,6 +109,19 @@ static String *cpp_include(const_String_or_char_ptr fn, int sysfile) {
|
|||
return s;
|
||||
}
|
||||
|
||||
static int is_digits(const String *str) {
|
||||
const char *s = Char(str);
|
||||
int isdigits = (*s != 0);
|
||||
while (*s) {
|
||||
if (!isdigit(*s)) {
|
||||
isdigits = 0;
|
||||
break;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
return isdigits;
|
||||
}
|
||||
|
||||
List *Preprocessor_depend(void) {
|
||||
return dependencies;
|
||||
}
|
||||
|
|
@ -607,6 +620,34 @@ static List *find_args(String *s, int ismacro, String *macro_name) {
|
|||
skip_tochar(s, '\'', str);
|
||||
c = Getc(s);
|
||||
continue;
|
||||
} else if (c == '/') {
|
||||
/* Ensure comments are ignored by eating up the characters */
|
||||
c = Getc(s);
|
||||
/* Handle / * ... * / type comments (multi-line) */
|
||||
if (c == '*') {
|
||||
while ((c = Getc(s)) != EOF) {
|
||||
if (c == '*') {
|
||||
c = Getc(s);
|
||||
if (c == '/' || c == EOF)
|
||||
break;
|
||||
}
|
||||
}
|
||||
c = Getc(s);
|
||||
continue;
|
||||
}
|
||||
/* Handle // ... type comments (single-line) */
|
||||
if (c == '/') {
|
||||
while ((c = Getc(s)) != EOF) {
|
||||
if (c == '\n') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
c = Getc(s);
|
||||
continue;
|
||||
}
|
||||
/* ensure char is available in the stream as this was not a comment*/
|
||||
Ungetc(c, s);
|
||||
c = '/';
|
||||
}
|
||||
if ((c == ',') && (level == 0))
|
||||
break;
|
||||
|
|
@ -623,13 +664,8 @@ static List *find_args(String *s, int ismacro, String *macro_name) {
|
|||
goto unterm;
|
||||
}
|
||||
Chop(str);
|
||||
if (Len(args) || Len(str))
|
||||
Append(args, str);
|
||||
Append(args, str);
|
||||
Delete(str);
|
||||
|
||||
/* if (Len(str) && (c != ')'))
|
||||
Append(args,str); */
|
||||
|
||||
if (c == ')')
|
||||
return args;
|
||||
c = Getc(s);
|
||||
|
|
@ -800,11 +836,24 @@ static String *expand_macro(String *name, List *args, String *line_file) {
|
|||
Delete(vararg);
|
||||
}
|
||||
}
|
||||
|
||||
if (args && margs && Len(margs) == 0 && Len(args) == 1 && Len(Getitem(args, 0)) == 0) {
|
||||
/* FOO() can invoke a macro defined as FOO(X) as well as one defined FOO().
|
||||
*
|
||||
* Handle this by removing the only argument if it's empty and the macro
|
||||
* expects no arguments.
|
||||
*
|
||||
* We don't need to worry about varargs here - a varargs macro will always have
|
||||
* Len(margs) >= 1, since the varargs are put in the final macro argument.
|
||||
*/
|
||||
Delitem(args, 0);
|
||||
}
|
||||
|
||||
/* If there are arguments, see if they match what we were given */
|
||||
if (args && (margs) && (Len(margs) != Len(args))) {
|
||||
if (Len(margs) > (1 + isvarargs))
|
||||
if (args && (!margs || Len(margs) != Len(args))) {
|
||||
if (margs && Len(margs) > (1 + isvarargs))
|
||||
Swig_error(macro_start_file, macro_start_line, "Macro '%s' expects %d arguments\n", name, Len(margs) - isvarargs);
|
||||
else if (Len(margs) == (1 + isvarargs))
|
||||
else if (margs && Len(margs) == (1 + isvarargs))
|
||||
Swig_error(macro_start_file, macro_start_line, "Macro '%s' expects 1 argument\n", name);
|
||||
else
|
||||
Swig_error(macro_start_file, macro_start_line, "Macro '%s' expects no arguments\n", name);
|
||||
|
|
@ -813,7 +862,7 @@ static String *expand_macro(String *name, List *args, String *line_file) {
|
|||
}
|
||||
|
||||
/* If the macro expects arguments, but none were supplied, we leave it in place */
|
||||
if (!args && (margs) && Len(margs) > 0) {
|
||||
if (!args && margs) {
|
||||
macro_level--;
|
||||
return NewString(name);
|
||||
}
|
||||
|
|
@ -905,19 +954,21 @@ static String *expand_macro(String *name, List *args, String *line_file) {
|
|||
namelen = Len(aname);
|
||||
a = strstr(s, name);
|
||||
while (a) {
|
||||
char ca = a[namelen + 1];
|
||||
char ca = a[namelen];
|
||||
if (!isidchar((int) ca)) {
|
||||
/* Matched the entire vararg name, not just a prefix */
|
||||
t = a - 1;
|
||||
if (*t == '\002') {
|
||||
t--;
|
||||
while (t >= s) {
|
||||
if (isspace((int) *t))
|
||||
t--;
|
||||
else if (*t == ',') {
|
||||
*t = ' ';
|
||||
} else
|
||||
break;
|
||||
if (a > s) {
|
||||
t = a - 1;
|
||||
if (*t == '\002') {
|
||||
t--;
|
||||
while (t >= s) {
|
||||
if (isspace((int) *t))
|
||||
t--;
|
||||
else if (*t == ',') {
|
||||
*t = ' ';
|
||||
} else
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1139,10 +1190,6 @@ static DOH *Preprocessor_replace(DOH *s) {
|
|||
args = find_args(s, 1, id);
|
||||
macro_additional_lines = Getline(s) - line;
|
||||
assert(macro_additional_lines >= 0);
|
||||
if (!Len(args)) {
|
||||
Delete(args);
|
||||
args = 0;
|
||||
}
|
||||
} else {
|
||||
args = 0;
|
||||
}
|
||||
|
|
@ -1431,7 +1478,7 @@ String *Preprocessor_parse(String *s) {
|
|||
break;
|
||||
|
||||
case 41: /* Build up the name of the preprocessor directive */
|
||||
if ((isspace(c) || (!isalpha(c)))) {
|
||||
if ((isspace(c) || (!isidchar(c)))) {
|
||||
Clear(value);
|
||||
Clear(comment);
|
||||
if (c == '\n') {
|
||||
|
|
@ -1450,7 +1497,7 @@ String *Preprocessor_parse(String *s) {
|
|||
Putc(c, id);
|
||||
break;
|
||||
|
||||
case 42: /* Strip any leading space before preprocessor value */
|
||||
case 42: /* Strip any leading space after the preprocessor directive (before preprocessor value) */
|
||||
if (isspace(c)) {
|
||||
if (c == '\n') {
|
||||
Ungetc(c, s);
|
||||
|
|
@ -1459,7 +1506,7 @@ String *Preprocessor_parse(String *s) {
|
|||
break;
|
||||
}
|
||||
state = 43;
|
||||
/* no break intended here */
|
||||
/* FALL THRU */
|
||||
|
||||
case 43:
|
||||
/* Get preprocessor value */
|
||||
|
|
@ -1770,6 +1817,8 @@ String *Preprocessor_parse(String *s) {
|
|||
Swig_error(Getfile(s), Getline(id), "cpp debug: level = %d, startlevel = %d\n", level, start_level);
|
||||
} else if (Equal(id, "")) {
|
||||
/* Null directive */
|
||||
} else if (is_digits(id)) {
|
||||
/* A gcc linemarker of the form '# linenum filename flags' (resulting from running gcc -E) */
|
||||
} else {
|
||||
/* Ignore unknown preprocessor directives which are inside an inactive
|
||||
* conditional (github issue #394). */
|
||||
|
|
|
|||
|
|
@ -188,12 +188,22 @@ static int reduce_op() {
|
|||
sp--;
|
||||
break;
|
||||
case SWIG_TOKEN_SLASH:
|
||||
stack[sp - 2].value = stack[sp - 2].value / stack[sp].value;
|
||||
sp -= 2;
|
||||
if (stack[sp].value != 0) {
|
||||
stack[sp - 2].value = stack[sp - 2].value / stack[sp].value;
|
||||
sp -= 2;
|
||||
} else {
|
||||
errmsg = "Division by zero in expression";
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case SWIG_TOKEN_PERCENT:
|
||||
stack[sp - 2].value = stack[sp - 2].value % stack[sp].value;
|
||||
sp -= 2;
|
||||
if (stack[sp].value != 0) {
|
||||
stack[sp - 2].value = stack[sp - 2].value % stack[sp].value;
|
||||
sp -= 2;
|
||||
} else {
|
||||
errmsg = "Modulo by zero in expression";
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case SWIG_TOKEN_LSHIFT:
|
||||
stack[sp - 2].value = stack[sp - 2].value << stack[sp].value;
|
||||
|
|
@ -309,6 +319,10 @@ int Preprocessor_expr(DOH *s, int *error) {
|
|||
stack[sp].value = 0;
|
||||
stack[sp].svalue = 0;
|
||||
stack[sp].op = EXPR_VALUE;
|
||||
} else if ((token == SWIG_TOKEN_FLOAT) || (token == SWIG_TOKEN_DOUBLE)) {
|
||||
errmsg = "Floating point constant in preprocessor expression";
|
||||
*error = 1;
|
||||
return 0;
|
||||
} else
|
||||
goto syntax_error;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -277,7 +277,7 @@ int Swig_cargs(Wrapper *w, ParmList *p) {
|
|||
SwigType_del_rvalue_reference(tvalue);
|
||||
tycode = SwigType_type(tvalue);
|
||||
if (tycode != T_USER) {
|
||||
/* plain primitive type, we copy the the def value */
|
||||
/* plain primitive type, we copy the def value */
|
||||
String *lstr = SwigType_lstr(tvalue, defname);
|
||||
defvalue = NewStringf("%s = %s", lstr, qvalue);
|
||||
Delete(lstr);
|
||||
|
|
@ -1024,6 +1024,15 @@ int Swig_MethodToFunction(Node *n, const_String_or_char_ptr nspace, String *clas
|
|||
}
|
||||
}
|
||||
|
||||
if (!self && SwigType_isrvalue_reference(Getattr(n, "refqualifier"))) {
|
||||
String *memory_header = NewString("<memory>");
|
||||
Setfile(memory_header, Getfile(n));
|
||||
Setline(memory_header, Getline(n));
|
||||
Swig_fragment_emit(memory_header);
|
||||
self = NewString("std::move(*this).");
|
||||
Delete(memory_header);
|
||||
}
|
||||
|
||||
call = Swig_cmethod_call(explicitcall_name ? explicitcall_name : name, p, self, explicit_qualifier, director_type);
|
||||
cres = Swig_cresult(Getattr(n, "type"), Swig_cresult_name(), call);
|
||||
|
||||
|
|
|
|||
|
|
@ -106,13 +106,16 @@ void Swig_warning(int wnum, const_String_or_char_ptr filename, int line, const c
|
|||
}
|
||||
if (warnall || wrn) {
|
||||
String *formatted_filename = format_filename(filename);
|
||||
String *full_message = NewString("");
|
||||
if (wnum) {
|
||||
Printf(stderr, wrn_wnum_fmt, formatted_filename, line, wnum);
|
||||
Printf(full_message, wrn_wnum_fmt, formatted_filename, line, wnum);
|
||||
} else {
|
||||
Printf(stderr, wrn_nnum_fmt, formatted_filename, line);
|
||||
Printf(full_message, wrn_nnum_fmt, formatted_filename, line);
|
||||
}
|
||||
Printf(stderr, "%s", msg);
|
||||
Printf(full_message, "%s", msg);
|
||||
Printv(stderr, full_message, NIL);
|
||||
nwarning++;
|
||||
Delete(full_message);
|
||||
Delete(formatted_filename);
|
||||
}
|
||||
Delete(out);
|
||||
|
|
@ -128,6 +131,7 @@ void Swig_warning(int wnum, const_String_or_char_ptr filename, int line, const c
|
|||
void Swig_error(const_String_or_char_ptr filename, int line, const char *fmt, ...) {
|
||||
va_list ap;
|
||||
String *formatted_filename = NULL;
|
||||
String *full_message = NULL;
|
||||
|
||||
if (silence)
|
||||
return;
|
||||
|
|
@ -136,14 +140,17 @@ void Swig_error(const_String_or_char_ptr filename, int line, const char *fmt, ..
|
|||
|
||||
va_start(ap, fmt);
|
||||
formatted_filename = format_filename(filename);
|
||||
full_message = NewString("");
|
||||
if (line > 0) {
|
||||
Printf(stderr, err_line_fmt, formatted_filename, line);
|
||||
Printf(full_message, err_line_fmt, formatted_filename, line);
|
||||
} else {
|
||||
Printf(stderr, err_eof_fmt, formatted_filename);
|
||||
Printf(full_message, err_eof_fmt, formatted_filename);
|
||||
}
|
||||
vPrintf(stderr, fmt, ap);
|
||||
vPrintf(full_message, fmt, ap);
|
||||
Printv(stderr, full_message, NIL);
|
||||
va_end(ap);
|
||||
nerrors++;
|
||||
Delete(full_message);
|
||||
Delete(formatted_filename);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -106,10 +106,10 @@ void Swig_extend_append_previous(Node *cls, Node *am) {
|
|||
set_nextSibling(n,0);
|
||||
/* typemaps and fragments need to be prepended */
|
||||
if (((Cmp(nodeType(n),"typemap") == 0) || (Cmp(nodeType(n),"fragment") == 0))) {
|
||||
if (!pe) pe = new_node("extend");
|
||||
if (!pe) pe = Swig_cparse_new_node("extend");
|
||||
appendChild(pe, n);
|
||||
} else {
|
||||
if (!ae) ae = new_node("extend");
|
||||
if (!ae) ae = Swig_cparse_new_node("extend");
|
||||
appendChild(ae, n);
|
||||
}
|
||||
n = ne;
|
||||
|
|
|
|||
|
|
@ -523,7 +523,7 @@ String *Swig_string_ucase(String *s) {
|
|||
/* We insert a underscore when:
|
||||
1. Lower case char followed by upper case char
|
||||
getFoo > get_foo; getFOo > get_foo; GETFOO > getfoo
|
||||
2. Number proceded by char and not end of string
|
||||
2. Number preceded by char and not end of string
|
||||
get2D > get_2d; get22D > get_22d; GET2D > get_2d
|
||||
but:
|
||||
asFloat2 > as_float2
|
||||
|
|
@ -823,10 +823,11 @@ String *Swig_string_emangle(String *s) {
|
|||
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_scopename_prefix()
|
||||
* Swig_scopename_split()
|
||||
*
|
||||
* Take a qualified name like "A::B::C" and return the scope name.
|
||||
* In this case, "A::B". Returns NULL if there is no base.
|
||||
* Take a qualified name like "A::B::C" and splits off the last name.
|
||||
* In this case, returns "C" as last and "A::B" as prefix.
|
||||
* Always returns non NULL for last, but prefix may be NULL if there is no prefix.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
void Swig_scopename_split(const String *s, String **rprefix, String **rlast) {
|
||||
|
|
@ -882,6 +883,12 @@ void Swig_scopename_split(const String *s, String **rprefix, String **rlast) {
|
|||
}
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_scopename_prefix()
|
||||
*
|
||||
* Take a qualified name like "A::B::C" and return the scope name.
|
||||
* In this case, "A::B". Returns NULL if there is no base.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
String *Swig_scopename_prefix(const String *s) {
|
||||
char *tmp = Char(s);
|
||||
|
|
@ -1067,6 +1074,31 @@ String *Swig_scopename_suffix(const String *s) {
|
|||
}
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_scopename_tolist()
|
||||
*
|
||||
* Take a qualified scope name like "A::B::C" and convert it to a list.
|
||||
* In this case, return a list of 3 elements "A", "B", "C".
|
||||
* Returns an empty list if the input is empty.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
List *Swig_scopename_tolist(const String *s) {
|
||||
List *scopes = NewList();
|
||||
String *name = Len(s) == 0 ? 0 : NewString(s);
|
||||
|
||||
while (name) {
|
||||
String *last = 0;
|
||||
String *prefix = 0;
|
||||
Swig_scopename_split(name, &prefix, &last);
|
||||
Insert(scopes, 0, last);
|
||||
Delete(last);
|
||||
Delete(name);
|
||||
name = prefix;
|
||||
}
|
||||
Delete(name);
|
||||
return scopes;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_scopename_check()
|
||||
*
|
||||
|
|
@ -1117,19 +1149,17 @@ int Swig_scopename_check(const String *s) {
|
|||
*
|
||||
* Printf(stderr,"%(command:sed 's/[a-z]/\U\\1/' <<<)s","hello") -> Hello
|
||||
* ----------------------------------------------------------------------------- */
|
||||
#if defined(HAVE_POPEN)
|
||||
# if defined(_MSC_VER)
|
||||
# define popen _popen
|
||||
# define pclose _pclose
|
||||
# else
|
||||
extern FILE *popen(const char *command, const char *type);
|
||||
extern int pclose(FILE *stream);
|
||||
#if defined(_MSC_VER)
|
||||
# define popen _popen
|
||||
# define pclose _pclose
|
||||
# if !defined(HAVE_POPEN)
|
||||
# define HAVE_POPEN 1
|
||||
# endif
|
||||
#else
|
||||
# if defined(_MSC_VER)
|
||||
# define HAVE_POPEN 1
|
||||
# define popen _popen
|
||||
# define pclose _pclose
|
||||
# if !defined(_WIN32)
|
||||
/* These Posix functions are not ISO C and so are not always defined in stdio.h */
|
||||
extern FILE *popen(const char *command, const char *type);
|
||||
extern int pclose(FILE *stream);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
|
@ -1208,7 +1238,7 @@ String *Swig_string_rstrip(String *s) {
|
|||
String *suffix = NewStringf(fmt, cs+1);
|
||||
int suffix_len = Len(suffix);
|
||||
if (0 == Strncmp(cs+len-suffix_len, suffix, suffix_len)) {
|
||||
int copy_len = len-suffix_len-(ce+1-cs);
|
||||
int copy_len = len-suffix_len-(int)(ce+1-cs);
|
||||
ns = NewStringWithSize(ce+1, copy_len);
|
||||
} else {
|
||||
ns = NewString(ce+1);
|
||||
|
|
@ -1454,6 +1484,17 @@ String *Swig_pcre_version(void) {
|
|||
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------
|
||||
* Swig_is_generated_overload()
|
||||
* Check if the function is an automatically generated
|
||||
* overload created because a method has default parameters.
|
||||
* ------------------------------------------------------------ */
|
||||
int Swig_is_generated_overload(Node *n) {
|
||||
Node *base_method = Getattr(n, "sym:overloaded");
|
||||
Node *default_args = Getattr(n, "defaultargs");
|
||||
return ((base_method != NULL) && (default_args != NULL) && (base_method == default_args));
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_init()
|
||||
*
|
||||
|
|
|
|||
|
|
@ -404,7 +404,17 @@ DOH *Swig_name_object_get(Hash *namehash, String *prefix, String *name, SwigType
|
|||
}
|
||||
Delete(cls);
|
||||
}
|
||||
/* A template-based class lookup, check name first */
|
||||
/* Lookup a name within a templated-based class */
|
||||
if (!rn) {
|
||||
String *t_name = SwigType_istemplate_templateprefix(prefix);
|
||||
if (t_name) {
|
||||
Clear(tname);
|
||||
Printf(tname, "%s::%s", t_name, name);
|
||||
rn = name_object_get(namehash, tname, decl, ncdecl);
|
||||
Delete(t_name);
|
||||
}
|
||||
}
|
||||
/* Lookup a template-based name within a class */
|
||||
if (!rn) {
|
||||
String *t_name = SwigType_istemplate_templateprefix(name);
|
||||
if (t_name)
|
||||
|
|
@ -429,8 +439,8 @@ DOH *Swig_name_object_get(Hash *namehash, String *prefix, String *name, SwigType
|
|||
rn = name_object_get(namehash, name, decl, ncdecl);
|
||||
}
|
||||
if (!rn && Swig_scopename_check(name)) {
|
||||
String *nprefix = NewStringEmpty();
|
||||
String *nlast = NewStringEmpty();
|
||||
String *nprefix = 0;
|
||||
String *nlast = 0;
|
||||
Swig_scopename_split(name, &nprefix, &nlast);
|
||||
rn = name_object_get(namehash, nlast, decl, ncdecl);
|
||||
Delete(nlast);
|
||||
|
|
@ -569,8 +579,8 @@ void Swig_features_get(Hash *features, String *prefix, String *name, SwigType *d
|
|||
if (name && SwigType_istemplate(name)) {
|
||||
String *nodetype = nodeType(node);
|
||||
if (nodetype && (Equal(nodetype, "constructor") || Equal(nodetype, "destructor"))) {
|
||||
String *nprefix = NewStringEmpty();
|
||||
String *nlast = NewStringEmpty();
|
||||
String *nprefix = 0;
|
||||
String *nlast = 0;
|
||||
String *tprefix;
|
||||
Swig_scopename_split(name, &nprefix, &nlast);
|
||||
tprefix = SwigType_templateprefix(nlast);
|
||||
|
|
@ -789,6 +799,8 @@ static int need_name_warning(Node *n) {
|
|||
need = 0;
|
||||
} else if (Getattr(n, "templatetype")) {
|
||||
need = 0;
|
||||
} else if (GetFlag(n, "parsing_template_declaration")) {
|
||||
need = 0;
|
||||
}
|
||||
return need;
|
||||
}
|
||||
|
|
@ -1043,7 +1055,7 @@ static void name_nameobj_add(Hash *name_hash, List *name_list, String *prefix, S
|
|||
Setattr(nameobj, "decl", decl);
|
||||
if (nname && Len(nname))
|
||||
Setattr(nameobj, "targetname", nname);
|
||||
/* put the new nameobj at the beginnig of the list, such that the
|
||||
/* put the new nameobj at the beginning of the list, such that the
|
||||
last inserted rule take precedence */
|
||||
Insert(name_list, 0, nameobj);
|
||||
} else {
|
||||
|
|
@ -1365,12 +1377,15 @@ void Swig_name_rename_add(String *prefix, String *name, SwigType *decl, Hash *ne
|
|||
}
|
||||
|
||||
|
||||
/* Create a name applying rename/namewarn if needed */
|
||||
static String *apply_rename(String *newname, int fullname, String *prefix, String *name) {
|
||||
/* Create a name for the given node applying rename/namewarn if needed */
|
||||
static String *apply_rename(Node* n, String *newname, int fullname, String *prefix, String *name) {
|
||||
String *result = 0;
|
||||
if (newname && Len(newname)) {
|
||||
if (Strcmp(newname, "$ignore") == 0) {
|
||||
result = Copy(newname);
|
||||
/* $ignore doesn't apply to parameters and while it's rare to explicitly write %ignore directives for them they could be caught by a wildcard ignore using
|
||||
regex match, just ignore the attempt to ignore them in this case */
|
||||
if (!Equal(nodeType(n), "parm"))
|
||||
result = Copy(newname);
|
||||
} else {
|
||||
char *cnewname = Char(newname);
|
||||
if (cnewname) {
|
||||
|
|
@ -1419,8 +1434,8 @@ String *Swig_name_make(Node *n, String *prefix, const_String_or_char_ptr cname,
|
|||
if (name && n && SwigType_istemplate(name)) {
|
||||
String *nodetype = nodeType(n);
|
||||
if (nodetype && (Equal(nodetype, "constructor") || Equal(nodetype, "destructor"))) {
|
||||
String *nprefix = NewStringEmpty();
|
||||
String *nlast = NewStringEmpty();
|
||||
String *nprefix = 0;
|
||||
String *nlast = 0;
|
||||
String *tprefix;
|
||||
Swig_scopename_split(name, &nprefix, &nlast);
|
||||
tprefix = SwigType_templateprefix(nlast);
|
||||
|
|
@ -1468,7 +1483,7 @@ String *Swig_name_make(Node *n, String *prefix, const_String_or_char_ptr cname,
|
|||
if (rn) {
|
||||
String *newname = Getattr(rn, "name");
|
||||
int fullname = GetFlag(rn, "fullname");
|
||||
result = apply_rename(newname, fullname, prefix, name);
|
||||
result = apply_rename(n, newname, fullname, prefix, name);
|
||||
}
|
||||
if (result && !Equal(result, name)) {
|
||||
/* operators in C++ allow aliases, we look for them */
|
||||
|
|
@ -1492,13 +1507,19 @@ String *Swig_name_make(Node *n, String *prefix, const_String_or_char_ptr cname,
|
|||
int fullname = GetFlag(wrn, "fullname");
|
||||
if (result)
|
||||
Delete(result);
|
||||
result = apply_rename(rename, fullname, prefix, name);
|
||||
result = apply_rename(n, rename, fullname, prefix, name);
|
||||
if ((msg) && (Len(msg))) {
|
||||
if (!Getmeta(nname, "already_warned")) {
|
||||
if (n) {
|
||||
SWIG_WARN_NODE_BEGIN(n);
|
||||
Swig_warning(0, Getfile(n), Getline(n), "%s\n", msg);
|
||||
SWIG_WARN_NODE_END(n);
|
||||
/* Parameter renaming is not fully implemented. Mainly because there is no C/C++ syntax to
|
||||
* for %rename to fully qualify a function's parameter name from outside the function. Hence it
|
||||
* is not possible to implemented targetted warning suppression on one parameter in one function. */
|
||||
int suppress_parameter_rename_warning = Equal(nodeType(n), "parm");
|
||||
if (!suppress_parameter_rename_warning) {
|
||||
SWIG_WARN_NODE_BEGIN(n);
|
||||
Swig_warning(0, Getfile(n), Getline(n), "%s\n", msg);
|
||||
SWIG_WARN_NODE_END(n);
|
||||
}
|
||||
} else {
|
||||
Swig_warning(0, Getfile(name), Getline(name), "%s\n", msg);
|
||||
}
|
||||
|
|
@ -1638,12 +1659,13 @@ String *Swig_name_str(Node *n) {
|
|||
if (SwigType_istemplate(name)) {
|
||||
String *nodetype = nodeType(n);
|
||||
if (nodetype && (Equal(nodetype, "constructor") || Equal(nodetype, "destructor"))) {
|
||||
String *nprefix = NewStringEmpty();
|
||||
String *nlast = NewStringEmpty();
|
||||
String *nprefix = 0;
|
||||
String *nlast = 0;
|
||||
String *tprefix;
|
||||
Swig_scopename_split(name, &nprefix, &nlast);
|
||||
tprefix = SwigType_templateprefix(nlast);
|
||||
Delete(nlast);
|
||||
Delete(nprefix);
|
||||
Delete(name);
|
||||
name = tprefix;
|
||||
}
|
||||
|
|
@ -1669,6 +1691,7 @@ String *Swig_name_str(Node *n) {
|
|||
* "MyNameSpace::MyTemplate<MyNameSpace::ABC >::~MyTemplate()"
|
||||
* "MyNameSpace::ABC::ABC(int,double)"
|
||||
* "MyNameSpace::ABC::constmethod(int) const"
|
||||
* "MyNameSpace::ABC::refqualifiermethod(int) const &"
|
||||
* "MyNameSpace::ABC::variablename"
|
||||
*
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
|
@ -1678,11 +1701,22 @@ String *Swig_name_decl(Node *n) {
|
|||
String *decl;
|
||||
|
||||
qname = Swig_name_str(n);
|
||||
decl = NewStringf("%s", qname);
|
||||
|
||||
if (checkAttribute(n, "kind", "variable"))
|
||||
decl = NewStringf("%s", qname);
|
||||
else
|
||||
decl = NewStringf("%s(%s)%s", qname, ParmList_errorstr(Getattr(n, "parms")), SwigType_isconst(Getattr(n, "decl")) ? " const" : "");
|
||||
if (!checkAttribute(n, "kind", "variable")) {
|
||||
String *d = Getattr(n, "decl");
|
||||
Printv(decl, "(", ParmList_errorstr(Getattr(n, "parms")), ")", NIL);
|
||||
if (SwigType_isfunction(d)) {
|
||||
SwigType *decl_temp = Copy(d);
|
||||
SwigType *qualifiers = SwigType_pop_function_qualifiers(decl_temp);
|
||||
if (qualifiers) {
|
||||
String *qualifiers_string = SwigType_str(qualifiers, 0);
|
||||
Printv(decl, " ", qualifiers_string, NIL);
|
||||
Delete(qualifiers_string);
|
||||
}
|
||||
Delete(decl_temp);
|
||||
}
|
||||
}
|
||||
|
||||
Delete(qname);
|
||||
|
||||
|
|
|
|||
|
|
@ -254,3 +254,19 @@ int ParmList_has_defaultargs(ParmList *p) {
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* ParmList_has_varargs()
|
||||
*
|
||||
* Returns 1 if the parameter list passed in has varargs.
|
||||
* Otherwise returns 0.
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
||||
int ParmList_has_varargs(ParmList *p) {
|
||||
Parm *lp = 0;
|
||||
while (p) {
|
||||
lp = p;
|
||||
p = nextSibling(p);
|
||||
}
|
||||
return lp ? SwigType_isvarargs(Getattr(lp, "type")) : 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -749,11 +749,18 @@ static int look(Scanner *s) {
|
|||
}
|
||||
|
||||
if (Strcmp( str_delimiter, end_delimiter )==0) {
|
||||
Delete( end_delimiter ); /* Correct end delimiter )XXXX" occured */
|
||||
int len = Len(s->text);
|
||||
Delslice(s->text, len - 2 - Len(str_delimiter), len); /* Delete ending )XXXX" */
|
||||
Delslice(s->text, 0, Len(str_delimiter) + 1); /* Delete starting XXXX( */
|
||||
Delete( end_delimiter ); /* Correct end delimiter )XXXX" occurred */
|
||||
Delete( str_delimiter );
|
||||
str_delimiter = 0;
|
||||
return SWIG_TOKEN_STRING;
|
||||
} else { /* Incorrect end delimiter occured */
|
||||
} else { /* Incorrect end delimiter occurred */
|
||||
if (c == 0) {
|
||||
Swig_error(cparse_file, cparse_start_line, "Unterminated raw string, started with R\"%s( is not terminated by )%s\"\n", str_delimiter, str_delimiter);
|
||||
return SWIG_TOKEN_ERROR;
|
||||
}
|
||||
retract( s, i );
|
||||
Delete( end_delimiter );
|
||||
}
|
||||
|
|
@ -931,10 +938,14 @@ static int look(Scanner *s) {
|
|||
retract(s, 1);
|
||||
state = 1000;
|
||||
}
|
||||
else if (c == '\'') { /* Definitely u, U or L char */
|
||||
retract(s, 1);
|
||||
state = 77;
|
||||
}
|
||||
else if (c == 'R') { /* Possibly CUSTOM DELIMITER u, U, L string */
|
||||
state = 73;
|
||||
}
|
||||
else if (c == '8') { /* Possibly u8 string */
|
||||
else if (c == '8') { /* Possibly u8 string/char */
|
||||
state = 71;
|
||||
}
|
||||
else {
|
||||
|
|
@ -954,7 +965,7 @@ static int look(Scanner *s) {
|
|||
}
|
||||
break;
|
||||
|
||||
case 71: /* Possibly u8 string */
|
||||
case 71: /* Possibly u8 string/char */
|
||||
if ((c = nextchar(s)) == 0) {
|
||||
state = 76;
|
||||
}
|
||||
|
|
@ -962,6 +973,10 @@ static int look(Scanner *s) {
|
|||
retract(s, 1); /* Definitely u8 string */
|
||||
state = 1000;
|
||||
}
|
||||
else if (c=='\'') {
|
||||
retract(s, 1); /* Definitely u8 char */
|
||||
state = 77;
|
||||
}
|
||||
else if (c=='R') {
|
||||
state = 74; /* Possibly CUSTOM DELIMITER u8 string */
|
||||
}
|
||||
|
|
@ -1114,27 +1129,29 @@ static int look(Scanner *s) {
|
|||
break;
|
||||
case 82:
|
||||
if ((c = nextchar(s)) == 0) {
|
||||
retract(s, 1);
|
||||
return SWIG_TOKEN_INT;
|
||||
Swig_error(cparse_file, cparse_start_line, "Exponent does not have any digits\n");
|
||||
return SWIG_TOKEN_ERROR;
|
||||
}
|
||||
if ((isdigit(c)) || (c == '-') || (c == '+'))
|
||||
state = 86;
|
||||
else {
|
||||
retract(s, 2);
|
||||
return (SWIG_TOKEN_INT);
|
||||
Swig_error(cparse_file, cparse_start_line, "Exponent does not have any digits\n");
|
||||
return SWIG_TOKEN_ERROR;
|
||||
}
|
||||
break;
|
||||
case 820:
|
||||
/* Like case 82, but we've seen a decimal point. */
|
||||
if ((c = nextchar(s)) == 0) {
|
||||
retract(s, 1);
|
||||
return SWIG_TOKEN_DOUBLE;
|
||||
Swig_error(cparse_file, cparse_start_line, "Exponent does not have any digits\n");
|
||||
return SWIG_TOKEN_ERROR;
|
||||
}
|
||||
if ((isdigit(c)) || (c == '-') || (c == '+'))
|
||||
state = 86;
|
||||
else {
|
||||
retract(s, 2);
|
||||
return (SWIG_TOKEN_DOUBLE);
|
||||
Swig_error(cparse_file, cparse_start_line, "Exponent does not have any digits\n");
|
||||
return SWIG_TOKEN_ERROR;
|
||||
}
|
||||
break;
|
||||
case 83:
|
||||
|
|
@ -1143,8 +1160,12 @@ static int look(Scanner *s) {
|
|||
return SWIG_TOKEN_INT;
|
||||
if (isdigit(c))
|
||||
state = 84;
|
||||
else if ((c == 'e') || (c == 'E'))
|
||||
state = 82;
|
||||
else if ((c == 'x') || (c == 'X'))
|
||||
state = 85;
|
||||
else if ((c == 'b') || (c == 'B'))
|
||||
state = 850;
|
||||
else if (c == '.')
|
||||
state = 81;
|
||||
else if ((c == 'l') || (c == 'L')) {
|
||||
|
|
@ -1162,6 +1183,10 @@ static int look(Scanner *s) {
|
|||
return SWIG_TOKEN_INT;
|
||||
if (isdigit(c))
|
||||
state = 84;
|
||||
else if (c == '.')
|
||||
state = 81;
|
||||
else if ((c == 'e') || (c == 'E'))
|
||||
state = 82;
|
||||
else if ((c == 'l') || (c == 'L')) {
|
||||
state = 87;
|
||||
} else if ((c == 'u') || (c == 'U')) {
|
||||
|
|
@ -1177,6 +1202,10 @@ static int look(Scanner *s) {
|
|||
return SWIG_TOKEN_INT;
|
||||
if (isxdigit(c))
|
||||
state = 85;
|
||||
else if (c == '.') /* hexadecimal float */
|
||||
state = 860;
|
||||
else if ((c == 'p') || (c == 'P')) /* hexadecimal float */
|
||||
state = 820;
|
||||
else if ((c == 'l') || (c == 'L')) {
|
||||
state = 87;
|
||||
} else if ((c == 'u') || (c == 'U')) {
|
||||
|
|
@ -1186,7 +1215,37 @@ static int look(Scanner *s) {
|
|||
return SWIG_TOKEN_INT;
|
||||
}
|
||||
break;
|
||||
|
||||
case 850:
|
||||
/* This is a binary number */
|
||||
if ((c = nextchar(s)) == 0)
|
||||
return SWIG_TOKEN_INT;
|
||||
if ((c == '0') || (c == '1'))
|
||||
state = 850;
|
||||
else if ((c == 'l') || (c == 'L')) {
|
||||
state = 87;
|
||||
} else if ((c == 'u') || (c == 'U')) {
|
||||
state = 88;
|
||||
} else {
|
||||
retract(s, 1);
|
||||
return SWIG_TOKEN_INT;
|
||||
}
|
||||
break;
|
||||
case 860:
|
||||
/* hexadecimal float */
|
||||
if ((c = nextchar(s)) == 0) {
|
||||
Swig_error(cparse_file, cparse_start_line, "Hexadecimal floating literals require an exponent\n");
|
||||
return SWIG_TOKEN_ERROR;
|
||||
}
|
||||
if (isxdigit(c))
|
||||
state = 860;
|
||||
else if ((c == 'p') || (c == 'P'))
|
||||
state = 820;
|
||||
else {
|
||||
retract(s, 2);
|
||||
Swig_error(cparse_file, cparse_start_line, "Hexadecimal floating literals require an exponent\n");
|
||||
return SWIG_TOKEN_ERROR;
|
||||
}
|
||||
break;
|
||||
case 86:
|
||||
/* Rest of floating point number */
|
||||
|
||||
|
|
|
|||
|
|
@ -44,8 +44,8 @@
|
|||
* '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)
|
||||
* 'm(qual).' = Pointer to member (qual::*)
|
||||
* 'q(str).' = Qualifier, such as const or volatile (cv-qualifier)
|
||||
* 'm(cls).' = Pointer to member (cls::*)
|
||||
*
|
||||
* The encoding follows the order that you might describe a type in words.
|
||||
* For example "p.a(200).int" is "A pointer to array of int's" and
|
||||
|
|
@ -62,6 +62,22 @@
|
|||
*
|
||||
* Replace(t,"q(const).","",DOH_REPLACE_ANY)
|
||||
*
|
||||
* More examples:
|
||||
*
|
||||
* String Encoding C++ Example
|
||||
* --------------- -----------
|
||||
* p.f(bool).r.q(const).long const long & (*)(bool)
|
||||
* m(Funcs).q(const).f(bool).long long (Funcs::*)(bool) const
|
||||
* r.q(const).m(Funcs).f(int).long long (Funcs::*const &)(int)
|
||||
* m(Funcs).z.q(const).f(bool).long long (Funcs::*)(bool) const &&
|
||||
*
|
||||
* Function decl examples:
|
||||
*
|
||||
* f(bool). long a(bool);
|
||||
* r.f(bool). long b(bool) &;
|
||||
* z.f(bool). long c(bool) &&;
|
||||
* z.q(const).f(bool). long d(bool) const &&;
|
||||
*
|
||||
* For the most part, this module tries to minimize the use of special
|
||||
* characters (*, [, <, etc...) in its type encoding. One reason for this
|
||||
* is that SWIG might be extended to encode data in formats such as XML
|
||||
|
|
@ -372,7 +388,7 @@ SwigType *SwigType_default_create(const SwigType *ty) {
|
|||
* and is very close to the type deduction used in partial template class
|
||||
* specialization matching in that the most specialized type is always chosen.
|
||||
* SWIGTYPE is used as the generic type. The basic idea is to repeatedly call
|
||||
* this function to find a deduced type unless until nothing matches.
|
||||
* this function to find a deduced type until nothing matches.
|
||||
*
|
||||
* The type t must have already been converted to the default type via a call to
|
||||
* SwigType_default_create() before calling this function.
|
||||
|
|
@ -528,6 +544,7 @@ String *SwigType_str(const SwigType *s, const_String_or_char_ptr id) {
|
|||
String *element = 0;
|
||||
String *nextelement;
|
||||
String *forwardelement;
|
||||
SwigType *member_function_qualifiers = 0;
|
||||
List *elements;
|
||||
int nelements, i;
|
||||
|
||||
|
|
@ -560,11 +577,13 @@ String *SwigType_str(const SwigType *s, const_String_or_char_ptr id) {
|
|||
forwardelement = 0;
|
||||
}
|
||||
if (SwigType_isqualifier(element)) {
|
||||
DOH *q = 0;
|
||||
q = SwigType_parm(element);
|
||||
Insert(result, 0, " ");
|
||||
Insert(result, 0, q);
|
||||
Delete(q);
|
||||
if (!member_function_qualifiers) {
|
||||
DOH *q = 0;
|
||||
q = SwigType_parm(element);
|
||||
Insert(result, 0, " ");
|
||||
Insert(result, 0, q);
|
||||
Delete(q);
|
||||
}
|
||||
} else if (SwigType_ispointer(element)) {
|
||||
Insert(result, 0, "*");
|
||||
if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) {
|
||||
|
|
@ -580,16 +599,28 @@ String *SwigType_str(const SwigType *s, const_String_or_char_ptr id) {
|
|||
Insert(result, 0, "(");
|
||||
Append(result, ")");
|
||||
}
|
||||
{
|
||||
String *next3elements = NewStringEmpty();
|
||||
int j;
|
||||
for (j = i + 1; j < i + 4 && j < nelements; j++) {
|
||||
Append(next3elements, Getitem(elements, j));
|
||||
}
|
||||
if (SwigType_isfunction(next3elements))
|
||||
member_function_qualifiers = SwigType_pop_function_qualifiers(next3elements);
|
||||
Delete(next3elements);
|
||||
}
|
||||
Delete(q);
|
||||
} else if (SwigType_isreference(element)) {
|
||||
Insert(result, 0, "&");
|
||||
if (!member_function_qualifiers)
|
||||
Insert(result, 0, "&");
|
||||
if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) {
|
||||
Insert(result, 0, "(");
|
||||
Append(result, ")");
|
||||
}
|
||||
} else if (SwigType_isrvalue_reference(element)) {
|
||||
Insert(result, 0, "&&");
|
||||
if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) {
|
||||
if (!member_function_qualifiers)
|
||||
Insert(result, 0, "&&");
|
||||
if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) {
|
||||
Insert(result, 0, "(");
|
||||
Append(result, ")");
|
||||
}
|
||||
|
|
@ -613,6 +644,14 @@ String *SwigType_str(const SwigType *s, const_String_or_char_ptr id) {
|
|||
Append(result, ",");
|
||||
}
|
||||
Append(result, ")");
|
||||
if (member_function_qualifiers) {
|
||||
String *p = SwigType_str(member_function_qualifiers, 0);
|
||||
Append(result, " ");
|
||||
Append(result, p);
|
||||
Delete(p);
|
||||
Delete(member_function_qualifiers);
|
||||
member_function_qualifiers = 0;
|
||||
}
|
||||
Delete(parms);
|
||||
} else {
|
||||
if (strcmp(Char(element), "v(...)") == 0) {
|
||||
|
|
@ -645,6 +684,7 @@ SwigType *SwigType_ltype(const SwigType *s) {
|
|||
int nelements, i;
|
||||
int firstarray = 1;
|
||||
int notypeconv = 0;
|
||||
int ignore_member_function_qualifiers = 0;
|
||||
|
||||
result = NewStringEmpty();
|
||||
tc = Copy(s);
|
||||
|
|
@ -671,6 +711,7 @@ SwigType *SwigType_ltype(const SwigType *s) {
|
|||
tc = td;
|
||||
}
|
||||
}
|
||||
|
||||
elements = SwigType_split(tc);
|
||||
nelements = Len(elements);
|
||||
|
||||
|
|
@ -680,14 +721,33 @@ SwigType *SwigType_ltype(const SwigType *s) {
|
|||
/* when we see a function, we need to preserve the following types */
|
||||
if (SwigType_isfunction(element)) {
|
||||
notypeconv = 1;
|
||||
ignore_member_function_qualifiers = 0;
|
||||
}
|
||||
if (SwigType_isqualifier(element)) {
|
||||
/* Do nothing. Ignore */
|
||||
if (ignore_member_function_qualifiers) {
|
||||
/* cv-qualifiers and ref-qualifiers up until the f() element have already been added */
|
||||
} else if (SwigType_isqualifier(element)) {
|
||||
/* swallow cv-qualifiers */
|
||||
} else if (SwigType_ispointer(element)) {
|
||||
Append(result, element);
|
||||
firstarray = 0;
|
||||
} else if (SwigType_ismemberpointer(element)) {
|
||||
Append(result, element);
|
||||
{
|
||||
String *next3elements = NewStringEmpty();
|
||||
int j;
|
||||
for (j = i + 1; j < i + 4 && j < nelements; j++) {
|
||||
Append(next3elements, Getitem(elements, j));
|
||||
}
|
||||
if (SwigType_isfunction(next3elements)) {
|
||||
SwigType *member_function_qualifiers = SwigType_pop_function_qualifiers(next3elements);
|
||||
/* compilers won't let us cast from a member function without qualifiers to one with qualifiers, so the qualifiers are kept in the ltype */
|
||||
if (member_function_qualifiers)
|
||||
Append(result, member_function_qualifiers);
|
||||
Delete(member_function_qualifiers);
|
||||
ignore_member_function_qualifiers = 1;
|
||||
}
|
||||
Delete(next3elements);
|
||||
}
|
||||
firstarray = 0;
|
||||
} else if (SwigType_isreference(element)) {
|
||||
if (notypeconv) {
|
||||
|
|
@ -727,13 +787,14 @@ SwigType *SwigType_ltype(const SwigType *s) {
|
|||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* SwigType_lstr(DOH *s, DOH *id)
|
||||
* SwigType_lstr()
|
||||
*
|
||||
* Produces a type-string that is suitable as a lvalue in an expression.
|
||||
* That is, a type that can be freely assigned a value without violating
|
||||
* any C assignment rules.
|
||||
*
|
||||
* - Qualifiers such as 'const' and 'volatile' are stripped.
|
||||
* Except for member function cv-qualifiers and ref-qualifiers.
|
||||
* - Arrays are converted into a *single* pointer (i.e.,
|
||||
* double [][] becomes double *).
|
||||
* - References are converted into a pointer.
|
||||
|
|
@ -763,6 +824,7 @@ String *SwigType_rcaststr(const SwigType *s, const_String_or_char_ptr name) {
|
|||
String *element = 0;
|
||||
String *nextelement;
|
||||
String *forwardelement;
|
||||
String *member_function_qualifiers = 0;
|
||||
SwigType *td, *tc = 0;
|
||||
const SwigType *rs;
|
||||
List *elements;
|
||||
|
|
@ -777,7 +839,10 @@ String *SwigType_rcaststr(const SwigType *s, const_String_or_char_ptr name) {
|
|||
if (SwigType_isconst(s)) {
|
||||
tc = Copy(s);
|
||||
Delete(SwigType_pop(tc));
|
||||
rs = tc;
|
||||
if (SwigType_ismemberpointer(tc))
|
||||
rs = s;
|
||||
else
|
||||
rs = tc;
|
||||
} else {
|
||||
rs = s;
|
||||
}
|
||||
|
|
@ -816,12 +881,14 @@ String *SwigType_rcaststr(const SwigType *s, const_String_or_char_ptr name) {
|
|||
forwardelement = 0;
|
||||
}
|
||||
if (SwigType_isqualifier(element)) {
|
||||
DOH *q = 0;
|
||||
q = SwigType_parm(element);
|
||||
Insert(result, 0, " ");
|
||||
Insert(result, 0, q);
|
||||
Delete(q);
|
||||
clear = 0;
|
||||
if (!member_function_qualifiers) {
|
||||
DOH *q = 0;
|
||||
q = SwigType_parm(element);
|
||||
Insert(result, 0, " ");
|
||||
Insert(result, 0, q);
|
||||
Delete(q);
|
||||
clear = 0;
|
||||
}
|
||||
} else if (SwigType_ispointer(element)) {
|
||||
Insert(result, 0, "*");
|
||||
if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) {
|
||||
|
|
@ -834,28 +901,42 @@ String *SwigType_rcaststr(const SwigType *s, const_String_or_char_ptr name) {
|
|||
Insert(result, 0, "::*");
|
||||
q = SwigType_parm(element);
|
||||
Insert(result, 0, q);
|
||||
Delete(q);
|
||||
if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) {
|
||||
Insert(result, 0, "(");
|
||||
Append(result, ")");
|
||||
}
|
||||
{
|
||||
String *next3elements = NewStringEmpty();
|
||||
int j;
|
||||
for (j = i + 1; j < i + 4 && j < nelements; j++) {
|
||||
Append(next3elements, Getitem(elements, j));
|
||||
}
|
||||
if (SwigType_isfunction(next3elements))
|
||||
member_function_qualifiers = SwigType_pop_function_qualifiers(next3elements);
|
||||
Delete(next3elements);
|
||||
}
|
||||
firstarray = 0;
|
||||
Delete(q);
|
||||
} else if (SwigType_isreference(element)) {
|
||||
Insert(result, 0, "&");
|
||||
if (!member_function_qualifiers) {
|
||||
Insert(result, 0, "&");
|
||||
if (!isfunction)
|
||||
isreference = 1;
|
||||
}
|
||||
if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) {
|
||||
Insert(result, 0, "(");
|
||||
Append(result, ")");
|
||||
}
|
||||
if (!isfunction)
|
||||
isreference = 1;
|
||||
} else if (SwigType_isrvalue_reference(element)) {
|
||||
Insert(result, 0, "&&");
|
||||
if (!member_function_qualifiers) {
|
||||
Insert(result, 0, "&&");
|
||||
if (!isfunction)
|
||||
isreference = 1;
|
||||
}
|
||||
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;
|
||||
|
|
@ -885,6 +966,15 @@ String *SwigType_rcaststr(const SwigType *s, const_String_or_char_ptr name) {
|
|||
}
|
||||
Append(result, ")");
|
||||
Delete(parms);
|
||||
if (member_function_qualifiers) {
|
||||
String *p = SwigType_str(member_function_qualifiers, 0);
|
||||
Append(result, " ");
|
||||
Append(result, p);
|
||||
Delete(p);
|
||||
Delete(member_function_qualifiers);
|
||||
member_function_qualifiers = 0;
|
||||
clear = 0;
|
||||
}
|
||||
isfunction = 1;
|
||||
} else {
|
||||
String *bs = SwigType_namestr(element);
|
||||
|
|
@ -1220,6 +1310,7 @@ void SwigType_typename_replace(SwigType *t, String *pat, String *rep) {
|
|||
Putc(',', nt);
|
||||
}
|
||||
tsuffix = SwigType_templatesuffix(e);
|
||||
SwigType_typename_replace(tsuffix, pat, rep);
|
||||
Printf(nt, ")>%s", tsuffix);
|
||||
Delete(tsuffix);
|
||||
Clear(e);
|
||||
|
|
@ -1228,13 +1319,24 @@ void SwigType_typename_replace(SwigType *t, String *pat, String *rep) {
|
|||
Delete(tparms);
|
||||
}
|
||||
} else if (Swig_scopename_check(e)) {
|
||||
String *first, *rest;
|
||||
first = Swig_scopename_first(e);
|
||||
rest = Swig_scopename_suffix(e);
|
||||
SwigType_typename_replace(rest, pat, rep);
|
||||
SwigType_typename_replace(first, pat, rep);
|
||||
String *first = 0;
|
||||
String *rest = 0;
|
||||
Swig_scopename_split(e, &first, &rest);
|
||||
|
||||
/* Swig_scopename_split doesn't handle :: prefix very well ... could do with a rework */
|
||||
if (Strncmp(rest, "::", 2) == 0) {
|
||||
String *tmp = NewString(Char(rest) + 2);
|
||||
Clear(rest);
|
||||
Printv(rest, tmp, NIL);
|
||||
Delete(tmp);
|
||||
assert(!first);
|
||||
}
|
||||
|
||||
Clear(e);
|
||||
Printv(e, first, "::", rest, NIL);
|
||||
if (first)
|
||||
SwigType_typename_replace(first, pat, rep);
|
||||
SwigType_typename_replace(rest, pat, rep);
|
||||
Printv(e, first ? first : "", "::", rest, NIL);
|
||||
Delete(first);
|
||||
Delete(rest);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -136,6 +136,7 @@ extern "C" {
|
|||
extern SwigType *SwigType_add_function(SwigType *t, ParmList *parms);
|
||||
extern SwigType *SwigType_add_template(SwigType *t, ParmList *parms);
|
||||
extern SwigType *SwigType_pop_function(SwigType *t);
|
||||
extern SwigType *SwigType_pop_function_qualifiers(SwigType *t);
|
||||
extern ParmList *SwigType_function_parms(const SwigType *t, Node *file_line_node);
|
||||
extern List *SwigType_split(const SwigType *t);
|
||||
extern String *SwigType_pop(SwigType *t);
|
||||
|
|
@ -187,7 +188,7 @@ extern "C" {
|
|||
extern SwigType *SwigType_remove_global_scope_prefix(const SwigType *t);
|
||||
extern SwigType *SwigType_alttype(const SwigType *t, int ltmap);
|
||||
|
||||
/* --- Type-system managment --- */
|
||||
/* --- Type-system management --- */
|
||||
extern void SwigType_typesystem_init(void);
|
||||
extern int SwigType_typedef(const SwigType *type, const_String_or_char_ptr name);
|
||||
extern int SwigType_typedef_class(const_String_or_char_ptr name);
|
||||
|
|
@ -326,6 +327,7 @@ extern int ParmList_is_compactdefargs(ParmList *p);
|
|||
extern String *Swig_scopename_last(const String *s);
|
||||
extern String *Swig_scopename_first(const String *s);
|
||||
extern String *Swig_scopename_suffix(const String *s);
|
||||
extern List *Swig_scopename_tolist(const String *s);
|
||||
extern int Swig_scopename_check(const String *s);
|
||||
extern String *Swig_string_lower(String *s);
|
||||
extern String *Swig_string_upper(String *s);
|
||||
|
|
@ -333,7 +335,9 @@ extern int ParmList_is_compactdefargs(ParmList *p);
|
|||
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);
|
||||
extern int Swig_is_generated_overload(Node *n);
|
||||
|
||||
typedef enum { EMF_STANDARD, EMF_MICROSOFT } ErrorMessageFormat;
|
||||
|
||||
|
|
@ -400,6 +404,7 @@ extern int ParmList_is_compactdefargs(ParmList *p);
|
|||
extern void Swig_typemap_clear(const_String_or_char_ptr tmap_method, ParmList *pattern);
|
||||
extern int Swig_typemap_apply(ParmList *srcpat, ParmList *destpat);
|
||||
extern void Swig_typemap_clear_apply(ParmList *pattern);
|
||||
extern void Swig_typemap_replace_embedded_typemap(String *s, Node *file_line_node);
|
||||
extern void Swig_typemap_debug(void);
|
||||
extern void Swig_typemap_search_debug_set(void);
|
||||
extern void Swig_typemap_used_debug_set(void);
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ extern ParmList *CopyParmListMax(ParmList *, int count);
|
|||
extern int ParmList_len(ParmList *);
|
||||
extern int ParmList_numrequired(ParmList *);
|
||||
extern int ParmList_has_defaultargs(ParmList *p);
|
||||
extern int ParmList_has_varargs(ParmList *p);
|
||||
|
||||
/* Output functions */
|
||||
extern String *ParmList_str(ParmList *);
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ extern void Scanner_locator(Scanner *, String *loc);
|
|||
#define SWIG_TOKEN_COLON 12 /* : */
|
||||
#define SWIG_TOKEN_DCOLON 13 /* :: */
|
||||
#define SWIG_TOKEN_DCOLONSTAR 14 /* ::* */
|
||||
#define SWIG_TOKEN_ID 15 /* identifer */
|
||||
#define SWIG_TOKEN_ID 15 /* identifier */
|
||||
#define SWIG_TOKEN_FLOAT 16 /* 3.1415F */
|
||||
#define SWIG_TOKEN_DOUBLE 17 /* 3.1415 */
|
||||
#define SWIG_TOKEN_INT 18 /* 314 */
|
||||
|
|
|
|||
|
|
@ -210,9 +210,10 @@ void Swig_symbol_print_tables_summary(void) {
|
|||
* symbol_print_symbols()
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
static void symbol_print_symbols(const char *symboltabletype) {
|
||||
static void symbol_print_symbols(const char *symboltabletype, const char *nextSibling) {
|
||||
Node *table = symtabs;
|
||||
Iterator ki = First(table);
|
||||
int show_pointers = 0;
|
||||
while (ki.key) {
|
||||
String *k = ki.key;
|
||||
Printf(stdout, "===================================================\n");
|
||||
|
|
@ -222,10 +223,20 @@ static void symbol_print_symbols(const char *symboltabletype) {
|
|||
Iterator it = First(symtab);
|
||||
while (it.key) {
|
||||
String *symname = it.key;
|
||||
Printf(stdout, " %s (%s)\n", symname, nodeType(it.item));
|
||||
/*
|
||||
Printf(stdout, " %s - %p (%s)\n", symname, it.item, Getattr(it.item, "name"));
|
||||
*/
|
||||
Printf(stdout, " %s (%s)", symname, nodeType(it.item));
|
||||
if (show_pointers)
|
||||
Printf(stdout, " %p", it.item);
|
||||
Printf(stdout, "\n");
|
||||
{
|
||||
Node *sibling = Getattr(it.item, nextSibling);
|
||||
while (sibling) {
|
||||
Printf(stdout, " %s (%s)", symname, nodeType(sibling));
|
||||
if (show_pointers)
|
||||
Printf(stdout, " %p", sibling);
|
||||
Printf(stdout, "\n");
|
||||
sibling = Getattr(sibling, nextSibling);
|
||||
}
|
||||
}
|
||||
it = Next(it);
|
||||
}
|
||||
}
|
||||
|
|
@ -241,7 +252,7 @@ static void symbol_print_symbols(const char *symboltabletype) {
|
|||
|
||||
void Swig_symbol_print_symbols(void) {
|
||||
Printf(stdout, "SYMBOLS start =======================================\n");
|
||||
symbol_print_symbols("symtab");
|
||||
symbol_print_symbols("symtab", "sym:nextSibling");
|
||||
Printf(stdout, "SYMBOLS finish =======================================\n");
|
||||
}
|
||||
|
||||
|
|
@ -253,7 +264,7 @@ void Swig_symbol_print_symbols(void) {
|
|||
|
||||
void Swig_symbol_print_csymbols(void) {
|
||||
Printf(stdout, "CSYMBOLS start =======================================\n");
|
||||
symbol_print_symbols("csymtab");
|
||||
symbol_print_symbols("csymtab", "csym:nextSibling");
|
||||
Printf(stdout, "CSYMBOLS finish =======================================\n");
|
||||
}
|
||||
|
||||
|
|
@ -518,7 +529,6 @@ void Swig_symbol_inherit(Symtab *s) {
|
|||
|
||||
void Swig_symbol_cadd(const_String_or_char_ptr name, Node *n) {
|
||||
Node *append = 0;
|
||||
|
||||
Node *cn;
|
||||
/* There are a few options for weak symbols. A "weak" symbol
|
||||
is any symbol that can be replaced by another symbol in the C symbol
|
||||
|
|
@ -600,7 +610,7 @@ void Swig_symbol_cadd(const_String_or_char_ptr name, Node *n) {
|
|||
Setattr(ccurrent, name, n);
|
||||
}
|
||||
|
||||
/* Multiple entries in the C symbol table. We append to to the symbol table */
|
||||
/* Multiple entries in the C symbol table. We append to the symbol table */
|
||||
if (append) {
|
||||
Node *fn, *pn = 0;
|
||||
cn = Getattr(ccurrent, name);
|
||||
|
|
@ -691,7 +701,7 @@ void Swig_symbol_cadd(const_String_or_char_ptr name, Node *n) {
|
|||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
Node *Swig_symbol_add(const_String_or_char_ptr symname, Node *n) {
|
||||
Hash *c, *cn, *cl = 0;
|
||||
Hash *c, *cl = 0;
|
||||
SwigType *decl, *ndecl;
|
||||
String *cstorage, *nstorage;
|
||||
int nt = 0, ct = 0;
|
||||
|
|
@ -757,10 +767,9 @@ Node *Swig_symbol_add(const_String_or_char_ptr symname, Node *n) {
|
|||
(1) A conflict between a class/enum and a typedef declaration is okay.
|
||||
In this case, the symbol table entry is set to the class/enum declaration
|
||||
itself, not the typedef.
|
||||
|
||||
(2) A conflict between namespaces is okay--namespaces are open
|
||||
|
||||
(3) Otherwise, overloading is only allowed for functions
|
||||
(4) This special case is okay: a class template instantiated with same name as the template's name
|
||||
*/
|
||||
|
||||
/* Check for namespaces */
|
||||
|
|
@ -778,6 +787,25 @@ Node *Swig_symbol_add(const_String_or_char_ptr symname, Node *n) {
|
|||
Setattr(n, "sym:previousSibling", pcl);
|
||||
return n;
|
||||
}
|
||||
|
||||
/* Special case: class template instantiated with same name as the template's name eg: %template(X) X<int>; */
|
||||
if (Equal(nodeType(c), "template")) {
|
||||
String *nt1 = Getattr(c, "templatetype");
|
||||
String *nt2 = nodeType(n);
|
||||
if (Equal(nt1, "class") && Equal(nt1, nt2)) {
|
||||
if (Getattr(n, "template")) {
|
||||
/* Finally check that another %template with same name doesn't already exist */
|
||||
if (!Getattr(c, "sym:nextSibling")) {
|
||||
Setattr(c, "sym:nextSibling", n);
|
||||
Setattr(n, "sym:symtab", current_symtab);
|
||||
Setattr(n, "sym:name", symname);
|
||||
Setattr(n, "sym:previousSibling", c);
|
||||
return n;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Getattr(n, "allows_typedef"))
|
||||
nt = 1;
|
||||
if (Getattr(c, "allows_typedef"))
|
||||
|
|
@ -858,7 +886,7 @@ Node *Swig_symbol_add(const_String_or_char_ptr symname, Node *n) {
|
|||
String *nt = Getattr(n, "nodeType");
|
||||
int n_template = Equal(nt, "template") && Checkattr(n, "templatetype", "cdecl");
|
||||
int n_plain_cdecl = Equal(nt, "cdecl");
|
||||
cn = c;
|
||||
Node *cn = c;
|
||||
pn = 0;
|
||||
while (cn) {
|
||||
decl = Getattr(cn, "decl");
|
||||
|
|
@ -1011,8 +1039,8 @@ static Node *symbol_lookup_qualified(const_String_or_char_ptr name, Symtab *symt
|
|||
return 0;
|
||||
if (!prefix) {
|
||||
Node *n;
|
||||
String *bname;
|
||||
String *prefix;
|
||||
String *bname = 0;
|
||||
String *prefix = 0;
|
||||
Swig_scopename_split(name, &prefix, &bname);
|
||||
n = symbol_lookup_qualified(bname, symtab, prefix, local, checkfunc);
|
||||
Delete(bname);
|
||||
|
|
@ -1907,19 +1935,37 @@ SwigType *Swig_symbol_template_deftype(const SwigType *type, Symtab *tscope) {
|
|||
int len = Len(elements);
|
||||
int i;
|
||||
#ifdef SWIG_TEMPLATE_DEFTYPE_CACHE
|
||||
static Hash *deftype_cache = 0;
|
||||
String *scopetype = tscope ? NewStringf("%s::%s", Getattr(tscope, "name"), type)
|
||||
static Hash *s_cache = 0;
|
||||
Hash *scope_cache;
|
||||
/* The lookup depends on the current scope and potential namespace qualification.
|
||||
Looking up x in namespace y is not the same as looking up x::y in outer scope.
|
||||
-> we use a 2-level hash: first scope and then symbol. */
|
||||
String *scope_name = tscope
|
||||
? Swig_symbol_qualifiedscopename(tscope)
|
||||
: Swig_symbol_qualifiedscopename(current_symtab);
|
||||
String *type_name = tscope
|
||||
? NewStringf("%s::%s", Getattr(tscope, "name"), type)
|
||||
: NewStringf("%s::%s", Swig_symbol_getscopename(), type);
|
||||
if (!deftype_cache) {
|
||||
deftype_cache = NewHash();
|
||||
if (!scope_name) scope_name = NewString("::");
|
||||
if (!s_cache) {
|
||||
s_cache = NewHash();
|
||||
}
|
||||
if (scopetype) {
|
||||
String *cres = Getattr(deftype_cache, scopetype);
|
||||
scope_cache = Getattr(s_cache, scope_name);
|
||||
if (scope_cache) {
|
||||
String *cres = Getattr(scope_cache, type_name);
|
||||
if (cres) {
|
||||
Append(result, cres);
|
||||
Delete(scopetype);
|
||||
#ifdef SWIG_DEBUG
|
||||
Printf(stderr, "cached deftype %s(%s) -> %s\n", type, scope_name, result);
|
||||
#endif
|
||||
Delete(type_name);
|
||||
Delete(scope_name);
|
||||
return result;
|
||||
}
|
||||
} else {
|
||||
scope_cache = NewHash();
|
||||
Setattr(s_cache, scope_name, scope_cache);
|
||||
Delete(scope_name);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -2019,8 +2065,8 @@ SwigType *Swig_symbol_template_deftype(const SwigType *type, Symtab *tscope) {
|
|||
}
|
||||
Delete(elements);
|
||||
#ifdef SWIG_TEMPLATE_DEFTYPE_CACHE
|
||||
Setattr(deftype_cache, scopetype, result);
|
||||
Delete(scopetype);
|
||||
Setattr(scope_cache, type_name, result);
|
||||
Delete(type_name);
|
||||
#endif
|
||||
|
||||
return result;
|
||||
|
|
|
|||
|
|
@ -75,9 +75,11 @@ void Swig_print_node(Node *obj) {
|
|||
if ((Cmp(k, "nodeType") == 0) || (Cmp(k, "firstChild") == 0) || (Cmp(k, "lastChild") == 0) ||
|
||||
(Cmp(k, "parentNode") == 0) || (Cmp(k, "nextSibling") == 0) || (Cmp(k, "previousSibling") == 0) || (*(Char(k)) == '$')) {
|
||||
/* Do nothing */
|
||||
} else if (Cmp(k, "parms") == 0 || Cmp(k, "wrap:parms") == 0) {
|
||||
} else if (Cmp(k, "kwargs") == 0 || Cmp(k, "parms") == 0 || Cmp(k, "wrap:parms") == 0 ||
|
||||
Cmp(k, "pattern") == 0 || Cmp(k, "templateparms") == 0 || Cmp(k, "throws") == 0) {
|
||||
print_indent(2);
|
||||
Printf(stdout, "%-12s - %s\n", k, ParmList_str_defaultargs(Getattr(obj, k)));
|
||||
/* Differentiate parameter lists by displaying within single quotes */
|
||||
Printf(stdout, "%-12s - \'%s\'\n", k, ParmList_str_defaultargs(Getattr(obj, k)));
|
||||
} else {
|
||||
DOH *o;
|
||||
const char *trunc = "";
|
||||
|
|
|
|||
|
|
@ -61,13 +61,44 @@ static void replace_embedded_typemap(String *s, ParmList *parm_sublist, Wrapper
|
|||
|
||||
static Hash *typemaps;
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* typemap_identifier_fix()
|
||||
*
|
||||
* Create a type that can be used as a hash key lookup independent of the various
|
||||
* ways a template parameter list can be defined. This is achieved by fully
|
||||
* resolving the template parameters.
|
||||
*
|
||||
* This is a copy and modification of feature_identifier_fix in parser.y.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
static SwigType *typemap_identifier_fix(const SwigType *s) {
|
||||
String *tp = SwigType_istemplate_templateprefix(s);
|
||||
if (tp) {
|
||||
String *ts, *ta, *tq, *tr;
|
||||
ts = SwigType_templatesuffix(s);
|
||||
ta = SwigType_templateargs(s);
|
||||
tq = Swig_symbol_type_qualify(ta, 0);
|
||||
tr = SwigType_typedef_resolve_all(ta);
|
||||
Append(tp,tr);
|
||||
Append(tp,ts);
|
||||
Delete(ts);
|
||||
Delete(ta);
|
||||
Delete(tq);
|
||||
Delete(tr);
|
||||
return tp;
|
||||
} else {
|
||||
return NewString(s);
|
||||
}
|
||||
}
|
||||
|
||||
static Hash *get_typemap(const SwigType *type) {
|
||||
Hash *tm = 0;
|
||||
SwigType *dtype = 0;
|
||||
SwigType *hashtype;
|
||||
|
||||
if (SwigType_istemplate(type)) {
|
||||
String *ty = Swig_symbol_template_deftype(type, 0);
|
||||
SwigType *rty = typemap_identifier_fix(type);
|
||||
String *ty = Swig_symbol_template_deftype(rty, 0);
|
||||
dtype = Swig_symbol_type_qualify(ty, 0);
|
||||
type = dtype;
|
||||
Delete(ty);
|
||||
|
|
@ -88,7 +119,7 @@ static void set_typemap(const SwigType *type, Hash **tmhash) {
|
|||
Hash *new_tm = 0;
|
||||
assert(*tmhash == 0);
|
||||
if (SwigType_istemplate(type)) {
|
||||
SwigType *rty = SwigType_typedef_resolve_all(type);
|
||||
SwigType *rty = typemap_identifier_fix(type);
|
||||
String *ty = Swig_symbol_template_deftype(rty, 0);
|
||||
String *tyq = Swig_symbol_type_qualify(ty, 0);
|
||||
hashtype = SwigType_remove_global_scope_prefix(tyq);
|
||||
|
|
@ -733,6 +764,7 @@ static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type
|
|||
SwigType *oldctype = ctype;
|
||||
ctype = SwigType_typedef_resolve(ctype_unstripped);
|
||||
Delete(oldctype);
|
||||
Delete(ctype_unstripped);
|
||||
ctype_unstripped = Copy(ctype);
|
||||
}
|
||||
}
|
||||
|
|
@ -1876,6 +1908,21 @@ static List *split_embedded_typemap(String *s) {
|
|||
return args;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_typemap_replace_embedded_typemap()
|
||||
*
|
||||
* For special variable macro $typemap(...) expansion outside of typemaps.
|
||||
* Only limited usage works as most typemap special variables ($1, $input etc)
|
||||
* are not expanded correctly outside of typemaps.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
void Swig_typemap_replace_embedded_typemap(String *s, Node *file_line_node) {
|
||||
Setfile(s, Getfile(file_line_node));
|
||||
Setline(s, Getline(file_line_node));
|
||||
Replaceall(s, "$typemap", "$TYPEMAP");
|
||||
replace_embedded_typemap(s, 0, 0, file_line_node);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* replace_embedded_typemap()
|
||||
*
|
||||
|
|
|
|||
|
|
@ -43,12 +43,12 @@
|
|||
* All type constructors are denoted by a trailing '.':
|
||||
*
|
||||
* 'p.' = Pointer (*)
|
||||
* 'r.' = Reference (&)
|
||||
* 'z.' = Rvalue reference (&&)
|
||||
* 'r.' = Reference or ref-qualifier (&)
|
||||
* 'z.' = Rvalue reference or ref-qualifier (&&)
|
||||
* 'a(n).' = Array of size n [n]
|
||||
* 'f(..,..).' = Function with arguments (args)
|
||||
* 'q(str).' = Qualifier (such as const or volatile) (const, volatile)
|
||||
* 'm(qual).' = Pointer to member (qual::*)
|
||||
* 'q(str).' = Qualifier, such as const or volatile (cv-qualifier)
|
||||
* 'm(cls).' = Pointer to member (cls::*)
|
||||
*
|
||||
* The complete type representation for varargs is:
|
||||
* 'v(...)'
|
||||
|
|
@ -183,9 +183,10 @@ SwigType *SwigType_del_element(SwigType *t) {
|
|||
* SwigType_pop()
|
||||
*
|
||||
* Pop one type element off the type.
|
||||
* Example: t in: q(const).p.Integer
|
||||
* t out: p.Integer
|
||||
* result: q(const).
|
||||
* For example:
|
||||
* t in: q(const).p.Integer
|
||||
* t out: p.Integer
|
||||
* result: q(const).
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
SwigType *SwigType_pop(SwigType *t) {
|
||||
|
|
@ -771,7 +772,6 @@ SwigType *SwigType_array_type(const SwigType *ty) {
|
|||
* Functions
|
||||
*
|
||||
* SwigType_add_function()
|
||||
* SwigType_del_function()
|
||||
* SwigType_isfunction()
|
||||
* SwigType_pop_function()
|
||||
*
|
||||
|
|
@ -795,14 +795,36 @@ SwigType *SwigType_add_function(SwigType *t, ParmList *parms) {
|
|||
return t;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* SwigType_pop_function()
|
||||
*
|
||||
* Pop and return the function from the input type leaving the function's return
|
||||
* type, if any.
|
||||
* For example:
|
||||
* t in: q(const).f().p.
|
||||
* t out: p.
|
||||
* result: q(const).f().
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
SwigType *SwigType_pop_function(SwigType *t) {
|
||||
SwigType *f = 0;
|
||||
SwigType *g = 0;
|
||||
char *c = Char(t);
|
||||
if (strncmp(c, "q(", 2) == 0) {
|
||||
if (strncmp(c, "r.", 2) == 0 || strncmp(c, "z.", 2) == 0) {
|
||||
/* Remove ref-qualifier */
|
||||
f = SwigType_pop(t);
|
||||
c = Char(t);
|
||||
}
|
||||
if (strncmp(c, "q(", 2) == 0) {
|
||||
/* Remove cv-qualifier */
|
||||
String *qual = SwigType_pop(t);
|
||||
if (f) {
|
||||
SwigType_push(qual, f);
|
||||
Delete(f);
|
||||
}
|
||||
f = qual;
|
||||
c = Char(t);
|
||||
}
|
||||
if (strncmp(c, "f(", 2)) {
|
||||
printf("Fatal error. SwigType_pop_function applied to non-function.\n");
|
||||
abort();
|
||||
|
|
@ -814,14 +836,54 @@ SwigType *SwigType_pop_function(SwigType *t) {
|
|||
return g;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* SwigType_pop_function_qualifiers()
|
||||
*
|
||||
* Pop and return the function qualifiers from the input type leaving the rest of
|
||||
* function declaration. Returns NULL if no qualifiers.
|
||||
* For example:
|
||||
* t in: r.q(const).f().p.
|
||||
* t out: f().p.
|
||||
* result: r.q(const)
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
SwigType *SwigType_pop_function_qualifiers(SwigType *t) {
|
||||
SwigType *qualifiers = 0;
|
||||
char *c = Char(t);
|
||||
if (strncmp(c, "r.", 2) == 0 || strncmp(c, "z.", 2) == 0) {
|
||||
/* Remove ref-qualifier */
|
||||
String *qual = SwigType_pop(t);
|
||||
qualifiers = qual;
|
||||
c = Char(t);
|
||||
}
|
||||
if (strncmp(c, "q(", 2) == 0) {
|
||||
/* Remove cv-qualifier */
|
||||
String *qual = SwigType_pop(t);
|
||||
if (qualifiers) {
|
||||
SwigType_push(qual, qualifiers);
|
||||
Delete(qualifiers);
|
||||
}
|
||||
qualifiers = qual;
|
||||
}
|
||||
assert(Strncmp(t, "f(", 2) == 0);
|
||||
|
||||
return qualifiers;
|
||||
}
|
||||
|
||||
int SwigType_isfunction(const SwigType *t) {
|
||||
char *c;
|
||||
if (!t) {
|
||||
return 0;
|
||||
}
|
||||
c = Char(t);
|
||||
if (strncmp(c, "r.", 2) == 0 || strncmp(c, "z.", 2) == 0) {
|
||||
/* Might be a function with a ref-qualifier, skip over */
|
||||
c += 2;
|
||||
if (!*c)
|
||||
return 0;
|
||||
}
|
||||
if (strncmp(c, "q(", 2) == 0) {
|
||||
/* Might be a 'const' function. Try to skip over the 'const' */
|
||||
/* Might be a function with a cv-qualifier, skip over */
|
||||
c = strchr(c, '.');
|
||||
if (c)
|
||||
c++;
|
||||
|
|
|
|||
|
|
@ -42,10 +42,15 @@
|
|||
* "name" - Scope name
|
||||
* "qname" - Fully qualified typename
|
||||
* "typetab" - Type table containing typenames and typedef information
|
||||
* For a given key in the typetab table, the value is a fully
|
||||
* qualified name if not pointing to itself.
|
||||
* "symtab" - Hash table of symbols defined in a scope
|
||||
* "inherit" - List of inherited scopes
|
||||
* "parent" - Parent scope
|
||||
*
|
||||
* The contents of these tables can be viewed for debugging using the -debug-typedef
|
||||
* option which calls SwigType_print_scope().
|
||||
*
|
||||
* Typedef information is stored in the "typetab" hash table. For example,
|
||||
* if you have these declarations:
|
||||
*
|
||||
|
|
@ -53,8 +58,7 @@
|
|||
* typedef A B;
|
||||
* typedef B *C;
|
||||
*
|
||||
* typetab is built as follows:
|
||||
*
|
||||
* typetab in scope '' contains:
|
||||
* "A" : "int"
|
||||
* "B" : "A"
|
||||
* "C" : "p.B"
|
||||
|
|
@ -67,31 +71,76 @@
|
|||
* ---> a(40).p.p.A (B --> A)
|
||||
* ---> a(40).p.p.int (A --> int)
|
||||
*
|
||||
*
|
||||
* Using declarations are stored in the "typetab" hash table. For example,
|
||||
*
|
||||
* namespace NN {
|
||||
* struct SS {};
|
||||
* }
|
||||
* namespace N {
|
||||
* struct S {};
|
||||
* using NN::SS;
|
||||
* }
|
||||
* using N::S;
|
||||
*
|
||||
* typetab in scope '' contains:
|
||||
* "S" : "N::S"
|
||||
*
|
||||
* and typetab in scope 'N' contains:
|
||||
* "SS" : "NN::SS"
|
||||
* "S" : "S"
|
||||
*
|
||||
*
|
||||
* For inheritance, SWIG tries to resolve types back to the base class. For instance, if
|
||||
* you have this:
|
||||
*
|
||||
* class Foo {
|
||||
* public:
|
||||
* typedef int Integer;
|
||||
* };
|
||||
* class Foo {
|
||||
* public:
|
||||
* typedef int Integer;
|
||||
* };
|
||||
* struct Bar : public Foo {
|
||||
* void blah(Integer x);
|
||||
* };
|
||||
*
|
||||
* class Bar : public Foo {
|
||||
* void blah(Integer x);
|
||||
* };
|
||||
* In this case typetab in scope '' contains:
|
||||
* "Foo" : "Foo"
|
||||
* "Bar" : "Bar"
|
||||
* and scope 'Foo' contains:
|
||||
* "Integer" : "int"
|
||||
* and scope 'Bar' inherits from 'Foo' but is empty (observe that blah is not a scope or typedef)
|
||||
*
|
||||
* The argument type of Bar::blah will be set to Foo::Integer.
|
||||
*
|
||||
*
|
||||
* The scope-inheritance mechanism is used to manage C++ using directives.
|
||||
*
|
||||
* namespace XX {
|
||||
* class CC {};
|
||||
* }
|
||||
* namespace X {
|
||||
* class C {};
|
||||
* using namespace XX;
|
||||
* }
|
||||
* using namespace X;
|
||||
*
|
||||
* typetab in scope '' inherits from 'X'
|
||||
* typetab in scope 'X' inherits from 'XX' and contains:
|
||||
* "C" : "C"
|
||||
* typetab in scope 'XX' contains:
|
||||
* "CC" : "CC"
|
||||
*
|
||||
*
|
||||
* The scope-inheritance mechanism is used to manage C++ namespace aliases.
|
||||
* For example, if you have this:
|
||||
*
|
||||
* namespace Foo {
|
||||
* typedef int Integer;
|
||||
* }
|
||||
* namespace Foo {
|
||||
* typedef int Integer;
|
||||
* }
|
||||
*
|
||||
* namespace F = Foo;
|
||||
* namespace F = Foo;
|
||||
*
|
||||
* In this case, "F::" is defined as a scope that "inherits" from Foo. Internally,
|
||||
* "F::" will merely be an empty scope that refers to Foo. SWIG will never
|
||||
* In this case, F is defined as a scope that "inherits" from Foo. Internally,
|
||||
* F will merely be an empty scope that points to Foo. SWIG will never
|
||||
* place new type information into a namespace alias---attempts to do so
|
||||
* will generate a warning message (in the parser) and will place information into
|
||||
* Foo instead.
|
||||
|
|
@ -166,6 +215,7 @@ void SwigType_typesystem_init() {
|
|||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
int SwigType_typedef(const SwigType *type, const_String_or_char_ptr name) {
|
||||
/* Printf(stdout, "typedef %s %s\n", type, name); */
|
||||
if (Getattr(current_typetab, name))
|
||||
return -1; /* Already defined */
|
||||
if (Strcmp(type, name) == 0) { /* Can't typedef a name to itself */
|
||||
|
|
@ -248,10 +298,26 @@ void SwigType_new_scope(const_String_or_char_ptr name) {
|
|||
ttab = NewHash();
|
||||
Setattr(s, "typetab", ttab);
|
||||
|
||||
/* Build fully qualified name and */
|
||||
/* Build fully qualified name */
|
||||
qname = SwigType_scope_name(s);
|
||||
#if 1
|
||||
{
|
||||
/* TODO: only do with templates? What happens with non-templates with code below? */
|
||||
String *stripped_qname;
|
||||
stripped_qname = SwigType_remove_global_scope_prefix(qname);
|
||||
/* Use fully qualified name for hash key without unary scope prefix, qname may contain unary scope */
|
||||
Setattr(scopes, stripped_qname, s);
|
||||
Setattr(s, "qname", qname);
|
||||
/*
|
||||
Printf(stdout, "SwigType_new_scope stripped %s %s\n", qname, stripped_qname);
|
||||
*/
|
||||
Delete(stripped_qname);
|
||||
}
|
||||
#else
|
||||
Printf(stdout, "SwigType_new_scope %s\n", qname);
|
||||
Setattr(scopes, qname, s);
|
||||
Setattr(s, "qname", qname);
|
||||
#endif
|
||||
Delete(qname);
|
||||
|
||||
current_scope = s;
|
||||
|
|
@ -418,12 +484,14 @@ static Typetab *SwigType_find_scope(Typetab *s, const SwigType *nameprefix) {
|
|||
Typetab *s_orig = s;
|
||||
String *nnameprefix = 0;
|
||||
static int check_parent = 1;
|
||||
int is_template = 0;
|
||||
|
||||
if (Getmark(s))
|
||||
return 0;
|
||||
Setmark(s, 1);
|
||||
|
||||
if (SwigType_istemplate(nameprefix)) {
|
||||
is_template = SwigType_istemplate(nameprefix);
|
||||
if (is_template) {
|
||||
nnameprefix = SwigType_typedef_resolve_all(nameprefix);
|
||||
nameprefix = nnameprefix;
|
||||
}
|
||||
|
|
@ -437,10 +505,12 @@ static Typetab *SwigType_find_scope(Typetab *s, const SwigType *nameprefix) {
|
|||
} else {
|
||||
full = NewString(nameprefix);
|
||||
}
|
||||
if (Getattr(scopes, full)) {
|
||||
s = Getattr(scopes, full);
|
||||
} else {
|
||||
s = 0;
|
||||
s = Getattr(scopes, full);
|
||||
if (!s && is_template) {
|
||||
/* try look up scope with all the unary scope operators within the template parameter list removed */
|
||||
SwigType *full_stripped = SwigType_remove_global_scope_prefix(full);
|
||||
s = Getattr(scopes, full_stripped);
|
||||
Delete(full_stripped);
|
||||
}
|
||||
Delete(full);
|
||||
if (s) {
|
||||
|
|
@ -500,7 +570,7 @@ static SwigType *_typedef_resolve(Typetab *s, String *base, int look_parent) {
|
|||
List *inherit;
|
||||
Typetab *parent;
|
||||
|
||||
/* if (!s) return 0; *//* now is checked bellow */
|
||||
/* if (!s) return 0; *//* now is checked below */
|
||||
/* Printf(stdout,"Typetab %s : %s\n", Getattr(s,"name"), base); */
|
||||
|
||||
if (!Getmark(s)) {
|
||||
|
|
@ -541,8 +611,11 @@ static SwigType *_typedef_resolve(Typetab *s, String *base, int look_parent) {
|
|||
/* -----------------------------------------------------------------------------
|
||||
* template_parameters_resolve()
|
||||
*
|
||||
* For use with templates only. The template parameters are resolved. If none
|
||||
* of the parameters can be resolved, zero is returned.
|
||||
* For use with templates only. Attempts to resolve one template parameter.
|
||||
*
|
||||
* If one of the template parameters can be resolved, the type is returned with
|
||||
* just the one parameter resolved and the remaining parameters left as is.
|
||||
* If none of the template parameters can be resolved, zero is returned.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
static String *template_parameters_resolve(const String *base) {
|
||||
|
|
@ -574,14 +647,15 @@ static String *template_parameters_resolve(const String *base) {
|
|||
if ((i + 1) < sz)
|
||||
Append(type, ",");
|
||||
}
|
||||
Append(type, ")>");
|
||||
Append(type, suffix);
|
||||
Delete(suffix);
|
||||
Delete(tparms);
|
||||
if (!rep) {
|
||||
if (rep) {
|
||||
Append(type, ")>");
|
||||
Append(type, suffix);
|
||||
} else {
|
||||
Delete(type);
|
||||
type = 0;
|
||||
}
|
||||
Delete(suffix);
|
||||
Delete(tparms);
|
||||
return type;
|
||||
}
|
||||
|
||||
|
|
@ -592,6 +666,17 @@ static SwigType *typedef_resolve(Typetab *s, String *base) {
|
|||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* SwigType_typedef_resolve()
|
||||
*
|
||||
* Given a type declaration, this function looks to reduce/resolve the type via a
|
||||
* typedef (including via C++ using declarations).
|
||||
*
|
||||
* If it is able to find a typedef, the resolved type is returned. If no typedef
|
||||
* is found NULL is returned. The type name is resolved in the current scope.
|
||||
* The type returned is not always fully qualified for the global scope, it is
|
||||
* valid for use in the current scope. If the current scope is global scope, a
|
||||
* fully qualified type should be returned.
|
||||
*
|
||||
* Some additional notes are in Doc/Manual/Extending.html.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
/* #define SWIG_DEBUG */
|
||||
|
|
@ -718,6 +803,25 @@ SwigType *SwigType_typedef_resolve(const SwigType *t) {
|
|||
}
|
||||
}
|
||||
|
||||
if (!type && SwigType_istemplate(base)) {
|
||||
String *tprefix = SwigType_templateprefix(base);
|
||||
String *rtprefix = SwigType_typedef_resolve(tprefix);
|
||||
/* We're looking for a using declaration on the template prefix to resolve the template prefix
|
||||
* in another scope. Using declaration do not have template parameters. */
|
||||
if (rtprefix && !SwigType_istemplate(rtprefix)) {
|
||||
String *tsuffix = SwigType_templatesuffix(base);
|
||||
String *targs = SwigType_templateargs(base);
|
||||
type = NewString(rtprefix);
|
||||
newtype = 1;
|
||||
Append(type, targs);
|
||||
Append(type, tsuffix);
|
||||
Delete(targs);
|
||||
Delete(tsuffix);
|
||||
Delete(rtprefix);
|
||||
}
|
||||
Delete(tprefix);
|
||||
}
|
||||
|
||||
if (type && (Equal(base, type))) {
|
||||
if (newtype)
|
||||
Delete(type);
|
||||
|
|
@ -735,10 +839,8 @@ SwigType *SwigType_typedef_resolve(const SwigType *t) {
|
|||
newtype = 1;
|
||||
type = template_parameters_resolve(base);
|
||||
}
|
||||
if (namebase)
|
||||
Delete(namebase);
|
||||
if (nameprefix)
|
||||
Delete(nameprefix);
|
||||
Delete(namebase);
|
||||
Delete(nameprefix);
|
||||
} else {
|
||||
if (SwigType_isfunction(base)) {
|
||||
List *parms;
|
||||
|
|
@ -911,6 +1013,9 @@ SwigType *SwigType_typedef_resolve_all(const SwigType *t) {
|
|||
return Copy(r);
|
||||
}
|
||||
|
||||
#ifdef SWIG_DEBUG
|
||||
Printf(stdout, "SwigType_typedef_resolve_all start ... %s\n", t);
|
||||
#endif
|
||||
/* Recursively resolve the typedef */
|
||||
r = NewString(t);
|
||||
while ((n = SwigType_typedef_resolve(r))) {
|
||||
|
|
@ -931,6 +1036,9 @@ SwigType *SwigType_typedef_resolve_all(const SwigType *t) {
|
|||
Delete(key);
|
||||
Delete(rr);
|
||||
}
|
||||
#ifdef SWIG_DEBUG
|
||||
Printf(stdout, "SwigType_typedef_resolve_all end === %s => %s\n", t, r);
|
||||
#endif
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
@ -938,8 +1046,17 @@ SwigType *SwigType_typedef_resolve_all(const SwigType *t) {
|
|||
/* -----------------------------------------------------------------------------
|
||||
* SwigType_typedef_qualified()
|
||||
*
|
||||
* Given a type declaration, this function tries to fully qualify it according to
|
||||
* typedef scope rules.
|
||||
* Given a type declaration, this function tries to fully qualify it so that the
|
||||
* resulting type can be used in the global scope. The type name is resolved in
|
||||
* the current scope.
|
||||
*
|
||||
* It provides a fully qualified name, not necessarily a fully expanded name.
|
||||
* When a using declaration or using directive is found the type may not be fully
|
||||
* expanded, but it will be resolved and fully qualified for use in the global scope.
|
||||
*
|
||||
* This function is for looking up scopes to qualify a type. It does not resolve
|
||||
* C typedefs, it just qualifies them. See SwigType_typedef_resolve for resolving.
|
||||
*
|
||||
* If the unary scope operator (::) is used as a prefix to the type to denote global
|
||||
* scope, it is left in place.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
|
@ -1000,20 +1117,14 @@ SwigType *SwigType_typedef_qualified(const SwigType *t) {
|
|||
out of the current scope */
|
||||
|
||||
Typetab *cs = current_scope;
|
||||
while (cs) {
|
||||
String *qs = SwigType_scope_name(cs);
|
||||
if (Len(qs)) {
|
||||
Append(qs, "::");
|
||||
}
|
||||
Append(qs, e);
|
||||
if (Getattr(scopes, qs)) {
|
||||
if (cs) {
|
||||
Typetab *found_scope = SwigType_find_scope(cs, e);
|
||||
if (found_scope) {
|
||||
String *qs = SwigType_scope_name(found_scope);
|
||||
Clear(e);
|
||||
Append(e, qs);
|
||||
Delete(qs);
|
||||
break;
|
||||
}
|
||||
Delete(qs);
|
||||
cs = Getattr(cs, "parent");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1029,10 +1140,6 @@ SwigType *SwigType_typedef_qualified(const SwigType *t) {
|
|||
Parm *p;
|
||||
List *parms;
|
||||
ty = Swig_symbol_template_deftype(e, current_symtab);
|
||||
/*
|
||||
String *dt = Swig_symbol_template_deftype(e, current_symtab);
|
||||
ty = Swig_symbol_type_qualify(dt, 0);
|
||||
*/
|
||||
e = ty;
|
||||
parms = SwigType_parmlist(e);
|
||||
tprefix = SwigType_templateprefix(e);
|
||||
|
|
@ -1099,9 +1206,6 @@ SwigType *SwigType_typedef_qualified(const SwigType *t) {
|
|||
Delete(tprefix);
|
||||
Delete(qprefix);
|
||||
Delete(parms);
|
||||
/*
|
||||
Delete(dt);
|
||||
*/
|
||||
}
|
||||
Append(result, e);
|
||||
Delete(ty);
|
||||
|
|
@ -1181,7 +1285,7 @@ int SwigType_typedef_using(const_String_or_char_ptr name) {
|
|||
|
||||
String *defined_name = 0;
|
||||
|
||||
/* Printf(stdout,"using %s\n", name); */
|
||||
/* Printf(stdout, "using %s\n", name); */
|
||||
|
||||
if (!Swig_scopename_check(name))
|
||||
return -1; /* Not properly qualified */
|
||||
|
|
@ -1436,7 +1540,7 @@ SwigType *SwigType_alttype(const SwigType *t, int local_tmap) {
|
|||
}
|
||||
} else {
|
||||
if (SwigType_issimple(td) && SwigType_istemplate(td)) {
|
||||
use_wrapper = !n || !GetFlag(n, "feature:novaluewrapper");
|
||||
use_wrapper = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue