Merge branch 'master' into gsoc2017-php7-classes-via-c-api
This commit is contained in:
commit
8ded9d8dae
1906 changed files with 50934 additions and 30001 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);
|
||||
|
|
|
|||
|
|
@ -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,93 @@ 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);
|
||||
String *cmt_modified = 0;
|
||||
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*/
|
||||
|
||||
int slashStyle = 0; /* Flag for "///" style doxygen comments */
|
||||
if (strncmp(loc, "///", 3) == 0) {
|
||||
slashStyle = 1;
|
||||
if (Len(cmt) == 3) {
|
||||
/* Modify to make length=4 to ensure that the empty comment does
|
||||
get processed to preserve the newlines in the original comments. */
|
||||
cmt_modified = NewStringf("%s ", cmt);
|
||||
cmt = cmt_modified;
|
||||
loc = Char(cmt);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for all possible Doxygen comment start markers while ignoring
|
||||
comments starting with a row of asterisks or slashes just as
|
||||
Doxygen itself does. Also skip empty comment (slash-star-star-slash),
|
||||
which causes a crash due to begin > end. */
|
||||
if (Len(cmt) > 3 && loc[0] == '/' &&
|
||||
((loc[1] == '/' && ((loc[2] == '/' && loc[3] != '/') || loc[2] == '!')) ||
|
||||
(loc[1] == '*' && ((loc[2] == '*' && loc[3] != '*' && 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 {
|
||||
if (slashStyle) {
|
||||
/* Add a newline to the end of each doxygen "///" comment,
|
||||
since they are processed individually, unlike the
|
||||
slash-star style, which gets processed as a block with
|
||||
newlines included. */
|
||||
Append(yylval.str, "\n");
|
||||
}
|
||||
Append(yylval.str, str);
|
||||
}
|
||||
|
||||
existing_comment = this_comment;
|
||||
}
|
||||
}
|
||||
}
|
||||
do {
|
||||
tok = Scanner_token(scan);
|
||||
} while (tok == SWIG_TOKEN_ENDLINE);
|
||||
Delete(cmt_modified);
|
||||
} 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;
|
||||
|
|
@ -762,15 +896,19 @@ int yylex(void) {
|
|||
return (USING);
|
||||
if (strcmp(yytext, "namespace") == 0)
|
||||
return (NAMESPACE);
|
||||
if (strcmp(yytext, "override") == 0)
|
||||
if (strcmp(yytext, "override") == 0) {
|
||||
last_id = 1;
|
||||
return (OVERRIDE);
|
||||
if (strcmp(yytext, "final") == 0)
|
||||
}
|
||||
if (strcmp(yytext, "final") == 0) {
|
||||
last_id = 1;
|
||||
return (FINAL);
|
||||
}
|
||||
} else {
|
||||
if (strcmp(yytext, "class") == 0) {
|
||||
Swig_warning(WARN_PARSE_CLASS_KEYWORD, cparse_file, cparse_line, "class keyword used, but not in C++ mode.\n");
|
||||
}
|
||||
if (strcmp(yytext, "complex") == 0) {
|
||||
if (strcmp(yytext, "_Complex") == 0) {
|
||||
yylval.type = NewSwigType(T_COMPLEX);
|
||||
return (TYPE_COMPLEX);
|
||||
}
|
||||
|
|
@ -907,6 +1045,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
|
|
@ -26,12 +26,19 @@ void SwigType_template_init() {
|
|||
}
|
||||
|
||||
|
||||
static void add_parms(ParmList *p, List *patchlist, List *typelist) {
|
||||
static void add_parms(ParmList *p, List *patchlist, List *typelist, int is_pattern) {
|
||||
while (p) {
|
||||
SwigType *ty = Getattr(p, "type");
|
||||
SwigType *val = Getattr(p, "value");
|
||||
Append(typelist, ty);
|
||||
Append(typelist, val);
|
||||
if (is_pattern) {
|
||||
/* Typemap patterns are not simple parameter lists.
|
||||
* Output style ("out", "ret" etc) typemap names can be
|
||||
* qualified names and so may need template expansion */
|
||||
SwigType *name = Getattr(p, "name");
|
||||
Append(typelist, name);
|
||||
}
|
||||
Append(patchlist, val);
|
||||
p = nextSibling(p);
|
||||
}
|
||||
|
|
@ -49,32 +56,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 */
|
||||
|
|
@ -107,8 +113,8 @@ static int cparse_template_expand(Node *n, String *tname, String *rname, String
|
|||
Append(typelist, Getattr(n, "name"));
|
||||
}
|
||||
|
||||
add_parms(Getattr(n, "parms"), cpatchlist, typelist);
|
||||
add_parms(Getattr(n, "throws"), cpatchlist, typelist);
|
||||
add_parms(Getattr(n, "parms"), cpatchlist, typelist, 0);
|
||||
add_parms(Getattr(n, "throws"), cpatchlist, typelist, 0);
|
||||
|
||||
} else if (Equal(nodeType, "class")) {
|
||||
/* Patch base classes */
|
||||
|
|
@ -131,7 +137,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);
|
||||
}
|
||||
}
|
||||
|
|
@ -174,28 +180,33 @@ static int cparse_template_expand(Node *n, String *tname, String *rname, String
|
|||
}
|
||||
Append(cpatchlist, Getattr(n, "code"));
|
||||
Append(typelist, Getattr(n, "decl"));
|
||||
add_parms(Getattr(n, "parms"), cpatchlist, typelist);
|
||||
add_parms(Getattr(n, "throws"), cpatchlist, typelist);
|
||||
add_parms(Getattr(n, "parms"), cpatchlist, typelist, 0);
|
||||
add_parms(Getattr(n, "throws"), cpatchlist, typelist, 0);
|
||||
} 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), '<')) {
|
||||
|
|
@ -211,17 +222,16 @@ static int cparse_template_expand(Node *n, String *tname, String *rname, String
|
|||
Append(cpatchlist, Getattr(n, "code"));
|
||||
Append(typelist, Getattr(n, "type"));
|
||||
Append(typelist, Getattr(n, "decl"));
|
||||
add_parms(Getattr(n, "parms"), cpatchlist, typelist);
|
||||
add_parms(Getattr(n, "kwargs"), cpatchlist, typelist);
|
||||
add_parms(Getattr(n, "pattern"), cpatchlist, typelist);
|
||||
add_parms(Getattr(n, "throws"), cpatchlist, typelist);
|
||||
add_parms(Getattr(n, "parms"), cpatchlist, typelist, 0);
|
||||
add_parms(Getattr(n, "kwargs"), cpatchlist, typelist, 0);
|
||||
add_parms(Getattr(n, "pattern"), cpatchlist, typelist, 1);
|
||||
add_parms(Getattr(n, "throws"), cpatchlist, typelist, 0);
|
||||
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 +316,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 */
|
||||
{
|
||||
|
|
@ -829,6 +839,7 @@ Node *Swig_cparse_template_locate(String *name, Parm *tparms, Symtab *tscope) {
|
|||
String *nodeType = nodeType(n);
|
||||
int isclass = 0;
|
||||
assert(Equal(nodeType, "template"));
|
||||
(void)nodeType;
|
||||
isclass = (Equal(Getattr(n, "templatetype"), "class"));
|
||||
if (!isclass) {
|
||||
/* If not a templated class we must have a templated function.
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -73,11 +73,17 @@ Replace(obj, orig, rep, flags) Replace occurrences of orig with rep.
|
|||
Chop(obj) Remove trailing whitespace
|
||||
|
||||
flags is one of the following:
|
||||
DOH_REPLACE_ANY
|
||||
DOH_REPLACE_NOQUOTE
|
||||
DOH_REPLACE_ID
|
||||
DOH_REPLACE_FIRST
|
||||
|
||||
DOH_REPLACE_ID
|
||||
DOH_REPLACE_ID_BEGIN
|
||||
DOH_REPLACE_ID_END
|
||||
DOH_REPLACE_NUMBER_END
|
||||
|
||||
and can be combined with one or more of the following:
|
||||
DOH_REPLACE_ANY
|
||||
DOH_REPLACE_NOQUOTE
|
||||
DOH_REPLACE_NOCOMMENT
|
||||
DOH_REPLACE_FIRST
|
||||
|
||||
Callable Operations
|
||||
-------------------
|
||||
Call(obj, args) Perform a function call with arguments args.
|
||||
|
|
|
|||
|
|
@ -755,25 +755,6 @@ int DohUngetc(int ch, DOH *obj) {
|
|||
return ungetc(ch, (FILE *) b);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* DohClose()
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
int DohClose(DOH *obj) {
|
||||
DohBase *b = (DohBase *) obj;
|
||||
DohObjInfo *objinfo;
|
||||
if (DohCheck(obj)) {
|
||||
objinfo = b->type;
|
||||
if (objinfo->doh_file->doh_close) {
|
||||
return (objinfo->doh_file->doh_close) (b);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return fclose((FILE *) obj);
|
||||
}
|
||||
*/
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* DohIsString()
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
|
|
|||
|
|
@ -103,7 +103,6 @@
|
|||
#define DohNewFileFromFile DOH_NAMESPACE(NewFileFromFile)
|
||||
#define DohNewFileFromFd DOH_NAMESPACE(NewFileFromFd)
|
||||
#define DohFileErrorDisplay DOH_NAMESPACE(FileErrorDisplay)
|
||||
#define DohClose DOH_NAMESPACE(Close)
|
||||
#define DohCopyto DOH_NAMESPACE(Copyto)
|
||||
#define DohNewList DOH_NAMESPACE(NewList)
|
||||
#define DohNewHash DOH_NAMESPACE(NewHash)
|
||||
|
|
@ -290,11 +289,12 @@ extern char *DohStrchr(const DOHString_or_char *s1, int ch);
|
|||
|
||||
#define DOH_REPLACE_ANY 0x01
|
||||
#define DOH_REPLACE_NOQUOTE 0x02
|
||||
#define DOH_REPLACE_ID 0x04
|
||||
#define DOH_REPLACE_FIRST 0x08
|
||||
#define DOH_REPLACE_ID_BEGIN 0x10
|
||||
#define DOH_REPLACE_ID_END 0x20
|
||||
#define DOH_REPLACE_NUMBER_END 0x40
|
||||
#define DOH_REPLACE_NOCOMMENT 0x04
|
||||
#define DOH_REPLACE_ID 0x08
|
||||
#define DOH_REPLACE_FIRST 0x10
|
||||
#define DOH_REPLACE_ID_BEGIN 0x20
|
||||
#define DOH_REPLACE_ID_END 0x40
|
||||
#define DOH_REPLACE_NUMBER_END 0x80
|
||||
|
||||
#define Replaceall(s,t,r) DohReplace(s,t,r,DOH_REPLACE_ANY)
|
||||
#define Replaceid(s,t,r) DohReplace(s,t,r,DOH_REPLACE_ID)
|
||||
|
|
@ -303,15 +303,12 @@ extern char *DohStrchr(const DOHString_or_char *s1, int ch);
|
|||
* Files
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
extern DOHFile *DohNewFile(DOH *filename, const char *mode, DOHList *outfiles);
|
||||
extern DOHFile *DohNewFile(DOHString *filename, const char *mode, DOHList *outfiles);
|
||||
extern DOHFile *DohNewFileFromFile(FILE *f);
|
||||
extern DOHFile *DohNewFileFromFd(int fd);
|
||||
extern void DohFileErrorDisplay(DOHString * filename);
|
||||
/*
|
||||
Deprecated, just use DohDelete
|
||||
extern int DohClose(DOH *file);
|
||||
*/
|
||||
extern int DohCopyto(DOHFile * input, DOHFile * output);
|
||||
extern void DohCloseAllOpenFiles(void);
|
||||
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
|
|
@ -392,7 +389,6 @@ extern void DohMemoryDebug(void);
|
|||
/* #define StringChar DohStringChar */
|
||||
/* #define StringEqual DohStringEqual */
|
||||
|
||||
#define Close DohClose
|
||||
#define vPrintf DohvPrintf
|
||||
#define GetInt DohGetInt
|
||||
#define GetDouble DohGetDouble
|
||||
|
|
@ -424,7 +420,6 @@ extern void DohMemoryDebug(void);
|
|||
#define NewFileFromFile DohNewFileFromFile
|
||||
#define NewFileFromFd DohNewFileFromFd
|
||||
#define FileErrorDisplay DohFileErrorDisplay
|
||||
#define Close DohClose
|
||||
#define NewVoid DohNewVoid
|
||||
#define Keys DohKeys
|
||||
#define Strcmp DohStrcmp
|
||||
|
|
@ -432,6 +427,7 @@ extern void DohMemoryDebug(void);
|
|||
#define Strstr DohStrstr
|
||||
#define Strchr DohStrchr
|
||||
#define Copyto DohCopyto
|
||||
#define CloseAllOpenFiles DohCloseAllOpenFiles
|
||||
#define Split DohSplit
|
||||
#define SplitLines DohSplitLines
|
||||
#define Setmark DohSetmark
|
||||
|
|
|
|||
|
|
@ -49,7 +49,6 @@ typedef struct {
|
|||
int (*doh_ungetc) (DOH *obj, int ch); /* Unget character */
|
||||
int (*doh_seek) (DOH *obj, long offset, int whence); /* Seek */
|
||||
long (*doh_tell) (DOH *obj); /* Tell */
|
||||
int (*doh_close) (DOH *obj); /* Close */
|
||||
} DohFileMethods;
|
||||
|
||||
/* String methods */
|
||||
|
|
|
|||
|
|
@ -25,6 +25,75 @@ typedef struct {
|
|||
int closeondel;
|
||||
} DohFile;
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* open_files_list_instance
|
||||
* open_files_list_add
|
||||
* open_files_list_remove
|
||||
*
|
||||
* Singleton list containing all the files that have been opened by DohNewFile.
|
||||
* Open file pointers are held in the list as strings so as to not affect the
|
||||
* reference count of the underlying DOH objects.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
static DOHList *open_files_list_instance() {
|
||||
static DOHList *all_open_files = 0;
|
||||
if (!all_open_files)
|
||||
all_open_files = DohNewList();
|
||||
return all_open_files;
|
||||
}
|
||||
|
||||
static void open_files_list_add(DohFile *f) {
|
||||
DOHList *all_open_files = open_files_list_instance();
|
||||
DOHString *sf = NewStringf("%p", f);
|
||||
Append(all_open_files, sf);
|
||||
Delete(sf);
|
||||
}
|
||||
|
||||
static void open_files_list_remove(DohFile *f) {
|
||||
int i;
|
||||
int removed = 0;
|
||||
DOHList *all_open_files = open_files_list_instance();
|
||||
DOHString *sf = NewStringf("%p", f);
|
||||
for (i = 0; i < DohLen(all_open_files); i++) {
|
||||
DOHString *sf_i = Getitem(all_open_files, i);
|
||||
if (Strcmp(sf, sf_i) == 0) {
|
||||
DohDelitem(all_open_files, i);
|
||||
removed = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Delete(sf);
|
||||
assert(removed);
|
||||
(void)removed;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* DohCloseAllOpenFiles()
|
||||
*
|
||||
* Close all opened files, to be called on program termination
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
void DohCloseAllOpenFiles() {
|
||||
int i;
|
||||
DOHList *all_open_files = open_files_list_instance();
|
||||
for (i = 0; i < DohLen(all_open_files); i++) {
|
||||
DohFile *f = 0;
|
||||
DOHString *sf = Getitem(all_open_files, i);
|
||||
int check = sscanf(Char(sf), "%p", (void **)&f);
|
||||
assert(check == 1);
|
||||
(void)check;
|
||||
if (f->closeondel) {
|
||||
if (f->filep) {
|
||||
check = fclose(f->filep);
|
||||
assert(check == 0);
|
||||
}
|
||||
f->closeondel = 0;
|
||||
f->filep = 0;
|
||||
}
|
||||
}
|
||||
DohClear(all_open_files);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* DelFile()
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
|
@ -40,6 +109,7 @@ static void DelFile(DOH *fo) {
|
|||
close(f->fd);
|
||||
}
|
||||
#endif
|
||||
open_files_list_remove(f);
|
||||
}
|
||||
DohFree(f);
|
||||
}
|
||||
|
|
@ -166,27 +236,6 @@ static int File_ungetc(DOH *fo, int ch) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* File_close()
|
||||
*
|
||||
* Close the file
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
static int File_close(DOH *fo) {
|
||||
int ret = 0;
|
||||
DohFile *f = (DohFile *) ObjData(fo);
|
||||
if (f->filep) {
|
||||
ret = fclose(f->filep);
|
||||
f->filep = 0;
|
||||
} else if (f->fd) {
|
||||
#ifdef DOH_INTFILE
|
||||
ret = close(f->fd);
|
||||
f->fd = 0;
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static DohFileMethods FileFileMethods = {
|
||||
File_read,
|
||||
File_write,
|
||||
|
|
@ -195,7 +244,6 @@ static DohFileMethods FileFileMethods = {
|
|||
File_ungetc,
|
||||
File_seek,
|
||||
File_tell,
|
||||
File_close, /* close */
|
||||
};
|
||||
|
||||
static DohObjInfo DohFileType = {
|
||||
|
|
@ -231,8 +279,9 @@ static DohObjInfo DohFileType = {
|
|||
* If newfiles is non-zero, the filename is added to the list of new files.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
DOH *DohNewFile(DOH *filename, const char *mode, DOHList *newfiles) {
|
||||
DOH *DohNewFile(DOHString *filename, const char *mode, DOHList *newfiles) {
|
||||
DohFile *f;
|
||||
DOH *obj;
|
||||
FILE *file;
|
||||
char *filen;
|
||||
|
||||
|
|
@ -251,7 +300,9 @@ DOH *DohNewFile(DOH *filename, const char *mode, DOHList *newfiles) {
|
|||
f->filep = file;
|
||||
f->fd = 0;
|
||||
f->closeondel = 1;
|
||||
return DohObjMalloc(&DohFileType, f);
|
||||
obj = DohObjMalloc(&DohFileType, f);
|
||||
open_files_list_add(f);
|
||||
return obj;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
#include "dohint.h"
|
||||
|
||||
#ifndef DOH_POOL_SIZE
|
||||
#define DOH_POOL_SIZE 16384
|
||||
#define DOH_POOL_SIZE 4194304
|
||||
#endif
|
||||
|
||||
/* Checks stale DOH object use - will use a lot more memory as pool memory is not re-used. */
|
||||
|
|
@ -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);
|
||||
|
|
@ -595,6 +595,13 @@ static char *end_quote(char *s) {
|
|||
}
|
||||
}
|
||||
|
||||
static char *end_comment(char *s) {
|
||||
char *substring = strstr(s, "*/");
|
||||
if (substring)
|
||||
++substring;
|
||||
return substring;
|
||||
}
|
||||
|
||||
static char *match_simple(char *base, char *s, char *token, int tokenlen) {
|
||||
(void) base;
|
||||
(void) tokenlen;
|
||||
|
|
@ -677,9 +684,10 @@ static int replace_simple(String *str, char *token, char *rep, int flags, int co
|
|||
int ic;
|
||||
int rcount = 0;
|
||||
int noquote = 0;
|
||||
int nocomment = 0;
|
||||
char *c, *s, *t, *first;
|
||||
char *q, *q2;
|
||||
register char *base;
|
||||
char *base;
|
||||
int i;
|
||||
|
||||
/* Figure out if anything gets replaced */
|
||||
|
|
@ -698,6 +706,11 @@ static int replace_simple(String *str, char *token, char *rep, int flags, int co
|
|||
if (flags & DOH_REPLACE_NOQUOTE)
|
||||
noquote = 1;
|
||||
|
||||
if (flags & DOH_REPLACE_NOCOMMENT)
|
||||
nocomment = 1;
|
||||
|
||||
assert(!(noquote && nocomment)); /* quote and comment combination not implemented */
|
||||
|
||||
/* If we are not replacing inside quotes, we need to do a little extra work */
|
||||
if (noquote) {
|
||||
q = strpbrk(base, "\"\'");
|
||||
|
|
@ -723,6 +736,31 @@ static int replace_simple(String *str, char *token, char *rep, int flags, int co
|
|||
}
|
||||
}
|
||||
|
||||
/* If we are not replacing inside comments, we need to do a little extra work */
|
||||
if (nocomment) {
|
||||
q = strstr(base, "/*");
|
||||
if (!q) {
|
||||
nocomment = 0; /* Well, no comments to worry about. Oh well */
|
||||
} else {
|
||||
while (q && (q < s)) {
|
||||
/* First match was found inside a comment. Try to find another match */
|
||||
q2 = end_comment(q);
|
||||
if (!q2) {
|
||||
return 0;
|
||||
}
|
||||
if (q2 > s) {
|
||||
/* Find next match */
|
||||
s = (*match) (base, q2 + 1, token, tokenlen);
|
||||
}
|
||||
if (!s)
|
||||
return 0; /* Oh well, no matches */
|
||||
q = strstr(q2 + 1, "/*");
|
||||
if (!q)
|
||||
nocomment = 0; /* No more comments */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
first = s;
|
||||
replen = (int)strlen(rep);
|
||||
|
||||
|
|
@ -768,6 +806,28 @@ static int replace_simple(String *str, char *token, char *rep, int flags, int co
|
|||
}
|
||||
}
|
||||
}
|
||||
if (nocomment) {
|
||||
q = strstr(s, "/*");
|
||||
if (!q) {
|
||||
nocomment = 0;
|
||||
} else {
|
||||
while (q && (q < c)) {
|
||||
/* First match was found inside a comment. Try to find another match */
|
||||
q2 = end_comment(q);
|
||||
if (!q2) {
|
||||
c = 0;
|
||||
break;
|
||||
}
|
||||
if (q2 > c)
|
||||
c = (*match) (base, q2 + 1, token, tokenlen);
|
||||
if (!c)
|
||||
break;
|
||||
q = strstr(q2 + 1, "/*");
|
||||
if (!q)
|
||||
nocomment = 0; /* No more comments */
|
||||
}
|
||||
}
|
||||
}
|
||||
if (delta) {
|
||||
if (c) {
|
||||
memmove(t, s, c - s);
|
||||
|
|
@ -776,7 +836,9 @@ static int replace_simple(String *str, char *token, char *rep, int flags, int co
|
|||
memmove(t, s, (str->str + str->len) - s + 1);
|
||||
}
|
||||
} else {
|
||||
t += (c - s);
|
||||
if (c) {
|
||||
t += (c - s);
|
||||
}
|
||||
}
|
||||
s = c;
|
||||
ic--;
|
||||
|
|
@ -823,6 +885,29 @@ static int replace_simple(String *str, char *token, char *rep, int flags, int co
|
|||
}
|
||||
}
|
||||
}
|
||||
if (nocomment) {
|
||||
q = strstr(s, "/*");
|
||||
if (!q) {
|
||||
break;
|
||||
} else {
|
||||
while (q && (q < c)) {
|
||||
/* First match was found inside a comment. Try to find another match */
|
||||
q2 = end_comment(q);
|
||||
if (!q2) {
|
||||
c = 0;
|
||||
break;
|
||||
}
|
||||
if (q2 > c) {
|
||||
c = (*match) (base, q2 + 1, token, tokenlen);
|
||||
if (!c)
|
||||
break;
|
||||
}
|
||||
q = strstr(q2 + 1, "/*");
|
||||
if (!q)
|
||||
nocomment = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (c) {
|
||||
rcount++;
|
||||
ic--;
|
||||
|
|
@ -875,6 +960,29 @@ static int replace_simple(String *str, char *token, char *rep, int flags, int co
|
|||
}
|
||||
}
|
||||
}
|
||||
if (nocomment) {
|
||||
q = strstr(s, "/*");
|
||||
if (!q) {
|
||||
nocomment = 0;
|
||||
} else {
|
||||
while (q && (q < c)) {
|
||||
/* First match was found inside a comment. Try to find another match */
|
||||
q2 = end_comment(q);
|
||||
if (!q2) {
|
||||
c = 0;
|
||||
break;
|
||||
}
|
||||
if (q2 > c) {
|
||||
c = (*match) (base, q2 + 1, token, tokenlen);
|
||||
if (!c)
|
||||
break;
|
||||
}
|
||||
q = strstr(q2 + 1, "/*");
|
||||
if (!q)
|
||||
nocomment = 0; /* No more comments */
|
||||
}
|
||||
}
|
||||
}
|
||||
if (i < (rcount - 1)) {
|
||||
memcpy(t, s, c - s);
|
||||
t += (c - s);
|
||||
|
|
@ -987,7 +1095,6 @@ static DohFileMethods StringFileMethods = {
|
|||
String_ungetc,
|
||||
String_seek,
|
||||
String_tell,
|
||||
0, /* close */
|
||||
};
|
||||
|
||||
static DohStringMethods StringStringMethods = {
|
||||
|
|
|
|||
172
Source/Doxygen/doxycommands.h
Normal file
172
Source/Doxygen/doxycommands.h
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
/* -----------------------------------------------------------------------------
|
||||
* 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_CODE = "code";
|
||||
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_CODE = "endcode";
|
||||
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
|
||||
1491
Source/Doxygen/doxyparser.cxx
Normal file
1491
Source/Doxygen/doxyparser.cxx
Normal file
File diff suppressed because it is too large
Load diff
377
Source/Doxygen/doxyparser.h
Normal file
377
Source/Doxygen/doxyparser.h
Normal file
|
|
@ -0,0 +1,377 @@
|
|||
/* -----------------------------------------------------------------------------
|
||||
* 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"
|
||||
|
||||
// Utility function to return the base part of a command that may
|
||||
// include options, e.g. param[in] -> param
|
||||
std::string getBaseCommand(const std::string &cmd);
|
||||
|
||||
|
||||
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(getBaseCommand(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
|
||||
993
Source/Doxygen/pydoc.cxx
Normal file
993
Source/Doxygen/pydoc.cxx
Normal file
|
|
@ -0,0 +1,993 @@
|
|||
/* -----------------------------------------------------------------------------
|
||||
* 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 ||
|
||||
line.compare(pos, 3, ">>>") == 0)) {
|
||||
// Must separate code or math blocks from the previous line
|
||||
result += '\n';
|
||||
}
|
||||
lastLineWasNonBlank = true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Helper function to extract the option value from a command,
|
||||
// e.g. param[in] -> in
|
||||
static std::string getCommandOption(const std::string &command, char openChar, char closeChar) {
|
||||
string option;
|
||||
|
||||
size_t opt_begin, opt_end;
|
||||
opt_begin = command.find(openChar);
|
||||
opt_end = command.find(closeChar);
|
||||
if (opt_begin != string::npos && opt_end != string::npos)
|
||||
option = command.substr(opt_begin+1, opt_end-opt_begin-1);
|
||||
|
||||
return option;
|
||||
}
|
||||
|
||||
|
||||
/* 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::handleTagWrap, "*");
|
||||
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::handleTagWrap, "``");
|
||||
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 (pname && Char(pname) == param) {
|
||||
type = getPyDocType(p, pname);
|
||||
break;
|
||||
}
|
||||
}
|
||||
Delete(plist);
|
||||
return type;
|
||||
}
|
||||
|
||||
std::string PyDocConverter::getParamValue(std::string param) {
|
||||
std::string value;
|
||||
|
||||
ParmList *plist = CopyParmList(Getattr(currentNode, "parms"));
|
||||
for (Parm *p = plist; p; p = nextSibling(p)) {
|
||||
String *pname = Getattr(p, "name");
|
||||
if (pname && Char(pname) == param) {
|
||||
String *pval = Getattr(p, "value");
|
||||
if (pval)
|
||||
value = Char(pval);
|
||||
break;
|
||||
}
|
||||
}
|
||||
Delete(plist);
|
||||
return value;
|
||||
}
|
||||
|
||||
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(getBaseCommand(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);
|
||||
|
||||
// Check for an option given to the code command (e.g. code{.py}),
|
||||
// and try to set the code-block language accordingly.
|
||||
string option = getCommandOption(tag.typeOfEntity, '{', '}');
|
||||
// Set up the language option to the code-block command, which can
|
||||
// be any language supported by pygments:
|
||||
string codeLanguage;
|
||||
if (option == ".py")
|
||||
// Other possibilities here are "default" or "python3". In Sphinx
|
||||
// 2.1.2, basic syntax doesn't render quite the same in these as
|
||||
// with "python", which for basic keywords seems to provide
|
||||
// slightly richer formatting. Another option would be to leave
|
||||
// the language empty, but testing with Sphinx 1.8.5 has produced
|
||||
// an error "1 argument required".
|
||||
codeLanguage = "python";
|
||||
else if (option == ".java")
|
||||
codeLanguage = "java";
|
||||
else if (option == ".c")
|
||||
codeLanguage = "c";
|
||||
else
|
||||
// If there is not a match, or if no option was given, go out on a
|
||||
// limb and assume that the examples in the C or C++ sources use
|
||||
// C++.
|
||||
codeLanguage = "c++";
|
||||
|
||||
std::string code;
|
||||
handleTagVerbatim(tag, code, arg);
|
||||
|
||||
// Try and remove leading newline, which is present for block \code
|
||||
// command:
|
||||
eraseLeadingNewLine(code);
|
||||
|
||||
// Check for python doctest blocks, and treat them specially:
|
||||
bool isDocTestBlock = false;
|
||||
size_t startPos;
|
||||
// ">>>" would normally appear at the beginning, but doxygen comment
|
||||
// style may have space in front, so skip leading whitespace
|
||||
if ((startPos=code.find_first_not_of(" \t")) != string::npos && code.substr(startPos,3) == ">>>")
|
||||
isDocTestBlock = true;
|
||||
|
||||
string codeIndent;
|
||||
if (! isDocTestBlock) {
|
||||
// Use the current indent for the code-block line itself.
|
||||
translatedComment += indent.getFirstLineIndent();
|
||||
translatedComment += ".. code-block:: " + codeLanguage + "\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.
|
||||
codeIndent = m_indent;
|
||||
}
|
||||
|
||||
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);
|
||||
const std::string paramValue = getParamValue(paramName);
|
||||
|
||||
// Get command option, e.g. "in", "out", or "in,out"
|
||||
string commandOpt = getCommandOption(tag.typeOfEntity, '[', ']');
|
||||
if (commandOpt == "in,out") commandOpt = "in/out";
|
||||
|
||||
// If provided, append the parameter direction to the type
|
||||
// information via a suffix:
|
||||
std::string suffix;
|
||||
if (commandOpt.size() > 0)
|
||||
suffix = ", " + commandOpt;
|
||||
|
||||
// If the parameter has a default value, flag it as optional in the
|
||||
// generated type definition. Particularly helpful when the python
|
||||
// call is generated with *args, **kwargs.
|
||||
if (paramValue.size() > 0)
|
||||
suffix += ", optional";
|
||||
|
||||
if (!paramType.empty()) {
|
||||
translatedComment += ":type " + paramName + ": " + paramType + suffix + "\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());
|
||||
}
|
||||
|
||||
208
Source/Doxygen/pydoc.h
Normal file
208
Source/Doxygen/pydoc.h
Normal file
|
|
@ -0,0 +1,208 @@
|
|||
/* -----------------------------------------------------------------------------
|
||||
* 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);
|
||||
|
||||
/*
|
||||
* Simple helper function to retrieve the parameter value
|
||||
*/
|
||||
std::string getParamValue(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_
|
||||
|
|
@ -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) -- */
|
||||
|
||||
|
|
@ -262,6 +277,7 @@
|
|||
#define WARN_JAVA_TYPEMAP_DIRECTORIN_NODESC 824
|
||||
#define WARN_JAVA_NO_DIRECTORCONNECT_ATTR 825
|
||||
#define WARN_JAVA_NSPACE_WITHOUT_PACKAGE 826
|
||||
#define WARN_JAVA_TYPEMAP_INTERFACEMODIFIERS_UNDEF 847
|
||||
|
||||
/* please leave 810-829 free for Java */
|
||||
|
||||
|
|
@ -282,6 +298,7 @@
|
|||
#define WARN_CSHARP_EXCODE 844
|
||||
#define WARN_CSHARP_CANTHROW 845
|
||||
#define WARN_CSHARP_NO_DIRECTORCONNECT_ATTR 846
|
||||
#define WARN_CSHARP_TYPEMAP_INTERFACEMODIFIERS_UNDEF 847
|
||||
|
||||
/* please leave 830-849 free for C# */
|
||||
|
||||
|
|
|
|||
|
|
@ -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/csharp.cxx \
|
||||
Modules/d.cxx \
|
||||
|
|
@ -53,26 +60,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/php5.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 +92,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 +123,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;
|
||||
|
||||
|
|
|
|||
|
|
@ -504,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");
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
|
|
@ -1533,7 +1533,7 @@ public:
|
|||
if (classname_substituted_flag) {
|
||||
if (SwigType_isenum(t)) {
|
||||
// This handles wrapping of inline initialised const enum static member variables (not when wrapping enum items - ignored later on)
|
||||
Printf(constants_code, "(%s)%s.%s();\n", return_type, full_imclass_name, Swig_name_get(getNSpace(), symname));
|
||||
Printf(constants_code, "(%s)%s.%s();\n", return_type, full_imclass_name ? full_imclass_name : imclass_name, Swig_name_get(getNSpace(), symname));
|
||||
} else {
|
||||
// This handles function pointers using the %constant directive
|
||||
Printf(constants_code, "new %s(%s.%s(), false);\n", return_type, full_imclass_name ? full_imclass_name : imclass_name, Swig_name_get(getNSpace(), symname));
|
||||
|
|
@ -1709,11 +1709,11 @@ public:
|
|||
* addInterfaceNameAndUpcasts()
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
void addInterfaceNameAndUpcasts(SwigType *smart, String *interface_list, String *interface_upcasts, Hash *base_list, String *c_classname) {
|
||||
void addInterfaceNameAndUpcasts(SwigType *smart, String *interface_list, String *interface_upcasts, Hash *base_list, SwigType *c_classname) {
|
||||
List *keys = Keys(base_list);
|
||||
for (Iterator it = First(keys); it.item; it = Next(it)) {
|
||||
Node *base = Getattr(base_list, it.item);
|
||||
String *c_baseclass = SwigType_namestr(Getattr(base, "name"));
|
||||
SwigType *c_baseclassname = Getattr(base, "name");
|
||||
String *interface_name = Getattr(base, "interface:name");
|
||||
if (Len(interface_list))
|
||||
Append(interface_list, ", ");
|
||||
|
|
@ -1732,13 +1732,12 @@ 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);
|
||||
upcastsCode(smart, upcast_method_name, c_classname, c_baseclass);
|
||||
String *upcast_method_name = Swig_name_member(getNSpace(), getClassPrefix(), cptr_method_name);
|
||||
upcastsCode(smart, upcast_method_name, c_classname, c_baseclassname);
|
||||
|
||||
Delete(upcast_method_name);
|
||||
Delete(cptr_method_name);
|
||||
Delete(interface_code);
|
||||
Delete(c_baseclass);
|
||||
}
|
||||
Delete(keys);
|
||||
}
|
||||
|
|
@ -1749,7 +1748,7 @@ public:
|
|||
* Add code for C++ casting to base class
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
void upcastsCode(SwigType *smart, String *upcast_method_name, String *c_classname, String *c_baseclass) {
|
||||
void upcastsCode(SwigType *smart, String *upcast_method_name, SwigType *c_classname, SwigType *c_baseclassname) {
|
||||
String *wname = Swig_name_wrapper(upcast_method_name);
|
||||
|
||||
Printv(imclass_cppcasts_code, "\n [global::System.Runtime.InteropServices.DllImport(\"", dllimport, "\", EntryPoint=\"", wname, "\")]\n", NIL);
|
||||
|
|
@ -1757,28 +1756,35 @@ public:
|
|||
|
||||
Replaceall(imclass_cppcasts_code, "$csclassname", proxy_class_name);
|
||||
|
||||
String *classname = SwigType_namestr(c_classname);
|
||||
String *baseclassname = SwigType_namestr(c_baseclassname);
|
||||
if (smart) {
|
||||
SwigType *bsmart = Copy(smart);
|
||||
SwigType *rclassname = SwigType_typedef_resolve_all(c_classname);
|
||||
SwigType *rbaseclass = SwigType_typedef_resolve_all(c_baseclass);
|
||||
Replaceall(bsmart, rclassname, rbaseclass);
|
||||
Delete(rclassname);
|
||||
Delete(rbaseclass);
|
||||
String *smartnamestr = SwigType_namestr(smart);
|
||||
String *bsmartnamestr = SwigType_namestr(bsmart);
|
||||
String *bsmartnamestr = SwigType_namestr(smart);
|
||||
|
||||
// TODO: SwigType_typedef_resolve_all on a String instead of SwigType is incorrect for templates
|
||||
SwigType *rclassname = SwigType_typedef_resolve_all(classname);
|
||||
SwigType *rbaseclassname = SwigType_typedef_resolve_all(baseclassname);
|
||||
Replaceall(bsmartnamestr, rclassname, rbaseclassname);
|
||||
|
||||
Printv(upcasts_code,
|
||||
"SWIGEXPORT ", bsmartnamestr, " * SWIGSTDCALL ", wname, "(", smartnamestr, " *jarg1) {\n",
|
||||
" return jarg1 ? new ", bsmartnamestr, "(*jarg1) : 0;\n"
|
||||
"}\n", "\n", NIL);
|
||||
|
||||
Delete(rbaseclassname);
|
||||
Delete(rclassname);
|
||||
Delete(bsmartnamestr);
|
||||
Delete(smartnamestr);
|
||||
Delete(bsmart);
|
||||
} else {
|
||||
Printv(upcasts_code,
|
||||
"SWIGEXPORT ", c_baseclass, " * SWIGSTDCALL ", wname, "(", c_classname, " *jarg1) {\n",
|
||||
" return (", c_baseclass, " *)jarg1;\n"
|
||||
"SWIGEXPORT ", baseclassname, " * SWIGSTDCALL ", wname, "(", classname, " *jarg1) {\n",
|
||||
" return (", baseclassname, " *)jarg1;\n"
|
||||
"}\n", "\n", NIL);
|
||||
}
|
||||
|
||||
Delete(baseclassname);
|
||||
Delete(classname);
|
||||
Delete(wname);
|
||||
}
|
||||
|
||||
|
|
@ -1787,10 +1793,9 @@ public:
|
|||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
void emitProxyClassDefAndCPPCasts(Node *n) {
|
||||
String *c_classname = SwigType_namestr(Getattr(n, "name"));
|
||||
String *c_baseclass = NULL;
|
||||
SwigType *c_classname = Getattr(n, "name");
|
||||
SwigType *c_baseclassname = NULL;
|
||||
String *baseclass = NULL;
|
||||
String *c_baseclassname = NULL;
|
||||
String *interface_list = NewStringEmpty();
|
||||
String *interface_upcasts = NewStringEmpty();
|
||||
SwigType *typemap_lookup_type = Getattr(n, "classtypeobj");
|
||||
|
|
@ -1812,12 +1817,13 @@ public:
|
|||
Iterator base = First(baselist);
|
||||
while (base.item) {
|
||||
if (!(GetFlag(base.item, "feature:ignore") || Getattr(base.item, "feature:interface"))) {
|
||||
String *baseclassname = Getattr(base.item, "name");
|
||||
SwigType *baseclassname = Getattr(base.item, "name");
|
||||
if (!c_baseclassname) {
|
||||
c_baseclassname = baseclassname;
|
||||
baseclass = Copy(getProxyName(baseclassname));
|
||||
if (baseclass)
|
||||
c_baseclass = SwigType_namestr(baseclassname);
|
||||
String *name = getProxyName(baseclassname);
|
||||
if (name) {
|
||||
c_baseclassname = baseclassname;
|
||||
baseclass = name;
|
||||
}
|
||||
} else {
|
||||
/* Warn about multiple inheritance for additional base class(es) */
|
||||
String *proxyclassname = Getattr(n, "classtypeobj");
|
||||
|
|
@ -1833,7 +1839,7 @@ public:
|
|||
if (interface_bases)
|
||||
addInterfaceNameAndUpcasts(smart, interface_list, interface_upcasts, interface_bases, c_classname);
|
||||
|
||||
bool derived = baseclass && getProxyName(c_baseclassname);
|
||||
bool derived = baseclass != 0;
|
||||
if (derived && purebase_notderived)
|
||||
pure_baseclass = empty_string;
|
||||
const String *wanted_base = baseclass ? baseclass : pure_baseclass;
|
||||
|
|
@ -1841,7 +1847,6 @@ public:
|
|||
if (purebase_replace) {
|
||||
wanted_base = pure_baseclass;
|
||||
derived = false;
|
||||
Delete(baseclass);
|
||||
baseclass = NULL;
|
||||
if (purebase_notderived)
|
||||
Swig_error(Getfile(n), Getline(n), "The csbase typemap for proxy %s must contain just one of the 'replace' or 'notderived' attributes.\n", typemap_lookup_type);
|
||||
|
|
@ -1873,46 +1878,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);
|
||||
|
|
@ -1929,7 +1958,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);
|
||||
|
|
@ -2008,12 +2037,11 @@ public:
|
|||
|
||||
if (derived) {
|
||||
String *upcast_method_name = Swig_name_member(getNSpace(), getClassPrefix(), smart != 0 ? "SWIGSmartPtrUpcast" : "SWIGUpcast");
|
||||
upcastsCode(smart, upcast_method_name, c_classname, c_baseclass);
|
||||
upcastsCode(smart, upcast_method_name, c_classname, c_baseclassname);
|
||||
Delete(upcast_method_name);
|
||||
}
|
||||
|
||||
Delete(smart);
|
||||
Delete(baseclass);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
|
|
@ -2022,7 +2050,8 @@ public:
|
|||
|
||||
void emitInterfaceDeclaration(Node *n, String *interface_name, File *f_interface) {
|
||||
Printv(f_interface, typemapLookup(n, "csimports", Getattr(n, "classtypeobj"), WARN_NONE), "\n", NIL);
|
||||
Printf(f_interface, "public interface %s", interface_name);
|
||||
Printv(f_interface, typemapLookup(n, "csinterfacemodifiers", Getattr(n, "classtypeobj"), WARN_CSHARP_TYPEMAP_INTERFACEMODIFIERS_UNDEF), NIL);
|
||||
Printf(f_interface, " %s", interface_name);
|
||||
if (List *baselist = Getattr(n, "bases")) {
|
||||
String *bases = 0;
|
||||
for (Iterator base = First(baselist); base.item; base = Next(base)) {
|
||||
|
|
@ -2782,7 +2811,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) {
|
||||
|
|
@ -2860,7 +2890,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;
|
||||
}
|
||||
|
||||
|
|
@ -3541,6 +3575,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.
|
||||
|
|
@ -3811,15 +3863,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);
|
||||
|
|
@ -3851,7 +3905,7 @@ public:
|
|||
Printf(director_delegate_definitions, " %s\n", im_directoroutattributes);
|
||||
}
|
||||
|
||||
Printf(callback_def, " private %s SwigDirector%s(", tm, overloaded_name);
|
||||
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 "));
|
||||
|
|
@ -3881,7 +3935,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);
|
||||
|
||||
|
|
@ -4015,11 +4069,10 @@ public:
|
|||
/* Get the C# parameter type */
|
||||
if ((tm = Getattr(p, "tmap:cstype"))) {
|
||||
substituteClassname(pt, tm);
|
||||
if (Strncmp(tm, "ref ", 4) == 0) {
|
||||
Replace(tm, "ref ", "", DOH_REPLACE_FIRST);
|
||||
int flags = DOH_REPLACE_FIRST | DOH_REPLACE_ID_BEGIN | DOH_REPLACE_NOCOMMENT;
|
||||
if (Replace(tm, "ref ", "", flags) || Replace(tm, "ref\t", "", flags)) {
|
||||
Printf(proxy_method_types, "typeof(%s).MakeByRefType()", tm);
|
||||
} else if (Strncmp(tm, "out ", 4) == 0) {
|
||||
Replace(tm, "out ", "", DOH_REPLACE_FIRST);
|
||||
} else if (Replace(tm, "out ", "", flags) || Replace(tm, "out\t", "", flags)) {
|
||||
Printf(proxy_method_types, "typeof(%s).MakeByRefType()", tm);
|
||||
} else {
|
||||
Printf(proxy_method_types, "typeof(%s)", tm);
|
||||
|
|
@ -4062,11 +4115,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);
|
||||
|
||||
|
|
@ -4283,7 +4336,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"));
|
||||
|
|
@ -4296,7 +4349,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);
|
||||
}
|
||||
|
|
@ -4396,8 +4449,8 @@ public:
|
|||
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);
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -989,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() &&
|
||||
|
|
@ -1227,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) {
|
||||
|
|
@ -1298,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;
|
||||
}
|
||||
|
||||
|
|
@ -1476,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);
|
||||
|
|
@ -1995,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);
|
||||
|
|
@ -2058,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);
|
||||
|
||||
|
|
@ -2212,11 +2220,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);
|
||||
|
||||
|
|
@ -2436,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"));
|
||||
|
||||
|
|
@ -2451,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);
|
||||
}
|
||||
|
|
@ -2495,8 +2503,8 @@ public:
|
|||
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);
|
||||
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);
|
||||
|
|
@ -3132,11 +3140,10 @@ private:
|
|||
* Handle inheriting from D and C++ classes.
|
||||
*/
|
||||
|
||||
String *c_classname = SwigType_namestr(Getattr(n, "name"));
|
||||
String *c_baseclass = NULL;
|
||||
Node *basenode = NULL;
|
||||
String *basename = NULL;
|
||||
String *c_classname = Getattr(n, "name");
|
||||
String *c_baseclassname = NULL;
|
||||
Node *basenode = NULL;
|
||||
String *baseclass = NULL;
|
||||
|
||||
// Inheritance from pure D classes.
|
||||
Node *attributes = NewHash();
|
||||
|
|
@ -3153,13 +3160,14 @@ private:
|
|||
Iterator base = First(baselist);
|
||||
while (base.item) {
|
||||
if (!GetFlag(base.item, "feature:ignore")) {
|
||||
String *baseclassname = Getattr(base.item, "name");
|
||||
SwigType *baseclassname = Getattr(base.item, "name");
|
||||
if (!c_baseclassname) {
|
||||
basenode = base.item;
|
||||
c_baseclassname = baseclassname;
|
||||
basename = createProxyName(c_baseclassname);
|
||||
if (basename)
|
||||
c_baseclass = SwigType_namestr(baseclassname);
|
||||
String *name = createProxyName(baseclassname);
|
||||
if (name) {
|
||||
c_baseclassname = baseclassname;
|
||||
baseclass = name;
|
||||
}
|
||||
} else {
|
||||
/* Warn about multiple inheritance for additional base class(es) */
|
||||
String *proxyclassname = Getattr(n, "classtypeobj");
|
||||
|
|
@ -3172,25 +3180,24 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
bool derived = (basename != NULL);
|
||||
bool derived = baseclass != NULL;
|
||||
|
||||
if (derived && purebase_notderived) {
|
||||
pure_baseclass = empty_string;
|
||||
}
|
||||
const String *wanted_base = basename ? basename : pure_baseclass;
|
||||
const String *wanted_base = baseclass ? baseclass : pure_baseclass;
|
||||
|
||||
if (purebase_replace) {
|
||||
wanted_base = pure_baseclass;
|
||||
derived = false;
|
||||
basenode = NULL;
|
||||
Delete(basename);
|
||||
basename = NULL;
|
||||
baseclass = NULL;
|
||||
if (purebase_notderived) {
|
||||
Swig_error(Getfile(n), Getline(n),
|
||||
"The dbase typemap for proxy %s must contain just one of the 'replace' or 'notderived' attributes.\n",
|
||||
typemap_lookup_type);
|
||||
}
|
||||
} else if (basename && Len(pure_baseclass) > 0) {
|
||||
} else if (baseclass && Len(pure_baseclass) > 0) {
|
||||
Swig_warning(WARN_D_MULTIPLE_INHERITANCE, Getfile(n), Getline(n),
|
||||
"Warning for %s, base class %s ignored. Multiple inheritance is not supported in D. "
|
||||
"Perhaps you need one of the 'replace' or 'notderived' attributes in the dbase typemap?\n", typemap_lookup_type, pure_baseclass);
|
||||
|
|
@ -3198,7 +3205,7 @@ private:
|
|||
|
||||
// Add code to do C++ casting to base class (only for classes in an inheritance hierarchy)
|
||||
if (derived) {
|
||||
writeClassUpcast(n, proxy_class_name, c_classname, c_baseclass);
|
||||
writeClassUpcast(n, proxy_class_name, c_classname, c_baseclassname);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -3266,17 +3273,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)) {
|
||||
|
|
@ -3290,6 +3300,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) {
|
||||
|
|
@ -3310,9 +3322,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3337,8 +3353,7 @@ private:
|
|||
// Write the class body and the curly bracket closing the class definition
|
||||
// to the proxy module.
|
||||
indentCode(body);
|
||||
Replaceall(body, "$dbaseclass", basename);
|
||||
Delete(basename);
|
||||
Replaceall(body, "$dbaseclass", baseclass);
|
||||
|
||||
Printv(proxy_class_code, body, "\n}\n", NIL);
|
||||
Delete(body);
|
||||
|
|
@ -3351,7 +3366,7 @@ private:
|
|||
/* ---------------------------------------------------------------------------
|
||||
* D::writeClassUpcast()
|
||||
* --------------------------------------------------------------------------- */
|
||||
void writeClassUpcast(Node *n, const String* d_class_name, String* c_class_name, String* c_base_name) {
|
||||
void writeClassUpcast(Node *n, const String* d_class_name, SwigType* c_classname, SwigType* c_baseclassname) {
|
||||
|
||||
SwigType *smart = Swig_cparse_smartptr(n);
|
||||
String *upcast_name = Swig_name_member(getNSpace(), d_class_name, (smart != 0 ? "SmartPtrUpcast" : "Upcast"));
|
||||
|
|
@ -3360,36 +3375,42 @@ private:
|
|||
writeImDModuleFunction(upcast_name, "void*", "(void* objectRef)",
|
||||
upcast_wrapper_name);
|
||||
|
||||
String *classname = SwigType_namestr(c_classname);
|
||||
String *baseclassname = SwigType_namestr(c_baseclassname);
|
||||
if (smart) {
|
||||
SwigType *bsmart = Copy(smart);
|
||||
SwigType *rclassname = SwigType_typedef_resolve_all(c_class_name);
|
||||
SwigType *rbaseclass = SwigType_typedef_resolve_all(c_base_name);
|
||||
Replaceall(bsmart, rclassname, rbaseclass);
|
||||
Delete(rclassname);
|
||||
Delete(rbaseclass);
|
||||
String *smartnamestr = SwigType_namestr(smart);
|
||||
String *bsmartnamestr = SwigType_namestr(bsmart);
|
||||
String *bsmartnamestr = SwigType_namestr(smart);
|
||||
|
||||
// TODO: SwigType_typedef_resolve_all on a String instead of SwigType is incorrect for templates
|
||||
SwigType *rclassname = SwigType_typedef_resolve_all(classname);
|
||||
SwigType *rbaseclassname = SwigType_typedef_resolve_all(baseclassname);
|
||||
Replaceall(bsmartnamestr, rclassname, rbaseclassname);
|
||||
|
||||
Printv(upcasts_code,
|
||||
"SWIGEXPORT ", bsmartnamestr, " * ", upcast_wrapper_name,
|
||||
"(", smartnamestr, " *objectRef) {\n",
|
||||
" return objectRef ? new ", bsmartnamestr, "(*objectRef) : 0;\n"
|
||||
"}\n",
|
||||
"\n", NIL);
|
||||
|
||||
Delete(rbaseclassname);
|
||||
Delete(rclassname);
|
||||
Delete(bsmartnamestr);
|
||||
Delete(smartnamestr);
|
||||
Delete(bsmart);
|
||||
} else {
|
||||
Printv(upcasts_code,
|
||||
"SWIGEXPORT ", c_base_name, " * ", upcast_wrapper_name,
|
||||
"(", c_base_name, " *objectRef) {\n",
|
||||
" return (", c_base_name, " *)objectRef;\n"
|
||||
"SWIGEXPORT ", baseclassname, " * ", upcast_wrapper_name,
|
||||
"(", baseclassname, " *objectRef) {\n",
|
||||
" return (", baseclassname, " *)objectRef;\n"
|
||||
"}\n",
|
||||
"\n", NIL);
|
||||
}
|
||||
|
||||
Replaceall(upcasts_code, "$cclass", c_class_name);
|
||||
Replaceall(upcasts_code, "$cbaseclass", c_base_name);
|
||||
Replaceall(upcasts_code, "$cclass", classname);
|
||||
Replaceall(upcasts_code, "$cbaseclass", baseclassname);
|
||||
|
||||
Delete(baseclassname);
|
||||
Delete(classname);
|
||||
Delete(upcast_name);
|
||||
Delete(upcast_wrapper_name);
|
||||
Delete(smart);
|
||||
|
|
@ -4341,7 +4362,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");
|
||||
|
|
@ -4366,7 +4387,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");
|
||||
|
|
@ -4392,7 +4413,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,63 @@ 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) || SwigType_isqualifier(rettype))
|
||||
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);
|
||||
|
||||
Delete(args_string);
|
||||
Delete(popped_decl);
|
||||
Delete(qualifiers);
|
||||
Delete(quals);
|
||||
Delete(rettype);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -272,6 +190,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 +209,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;
|
||||
|
|
@ -3857,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);
|
||||
|
||||
|
|
@ -4091,6 +4115,7 @@ private:
|
|||
String *name = Getattr(n, "sym:name");
|
||||
if (!name) {
|
||||
assert(is_ignored);
|
||||
(void)is_ignored;
|
||||
name = Getattr(n, "name");
|
||||
}
|
||||
|
||||
|
|
@ -4587,7 +4612,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);
|
||||
|
||||
|
|
@ -5035,13 +5060,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);
|
||||
|
|
@ -5935,7 +5960,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'.
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
|
@ -6061,6 +6086,7 @@ private:
|
|||
}
|
||||
bool r = addSymbol(name, n, scope) ? true : false;
|
||||
assert(r);
|
||||
(void)r;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -6974,9 +7000,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\
|
||||
|
|
|
|||
|
|
@ -255,7 +255,7 @@ public:
|
|||
if (goops) {
|
||||
if (linkage != GUILE_LSTYLE_PASSIVE && linkage != GUILE_LSTYLE_MODULE) {
|
||||
Printf(stderr, "guile: GOOPS support requires passive or module linkage\n");
|
||||
exit(1);
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -1565,7 +1633,7 @@ public:
|
|||
if (classname_substituted_flag) {
|
||||
if (SwigType_isenum(t)) {
|
||||
// This handles wrapping of inline initialised const enum static member variables (not when wrapping enum items - ignored later on)
|
||||
Printf(constants_code, "%s.swigToEnum(%s.%s());\n", return_type, full_imclass_name, Swig_name_get(getNSpace(), symname));
|
||||
Printf(constants_code, "%s.swigToEnum(%s.%s());\n", return_type, full_imclass_name ? full_imclass_name : imclass_name, Swig_name_get(getNSpace(), symname));
|
||||
} else {
|
||||
// This handles function pointers using the %constant directive
|
||||
Printf(constants_code, "new %s(%s.%s(), false);\n", return_type, full_imclass_name ? full_imclass_name : imclass_name, Swig_name_get(getNSpace(), symname));
|
||||
|
|
@ -1785,11 +1853,11 @@ public:
|
|||
* addInterfaceNameAndUpcasts()
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
void addInterfaceNameAndUpcasts(SwigType *smart, String *interface_list, String *interface_upcasts, Hash *base_list, String *c_classname) {
|
||||
void addInterfaceNameAndUpcasts(SwigType *smart, String *interface_list, String *interface_upcasts, Hash *base_list, SwigType *c_classname) {
|
||||
List *keys = Keys(base_list);
|
||||
for (Iterator it = First(keys); it.item; it = Next(it)) {
|
||||
Node *base = Getattr(base_list, it.item);
|
||||
String *c_baseclass = SwigType_namestr(Getattr(base, "name"));
|
||||
SwigType *c_baseclassname = Getattr(base, "name");
|
||||
String *interface_name = Getattr(base, "interface:name");
|
||||
if (Len(interface_list))
|
||||
Append(interface_list, ", ");
|
||||
|
|
@ -1808,12 +1876,12 @@ 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);
|
||||
upcastsCode(smart, upcast_method_name, c_classname, c_baseclass);
|
||||
String *upcast_method_name = Swig_name_member(getNSpace(), getClassPrefix(), cptr_method_name);
|
||||
upcastsCode(smart, upcast_method_name, c_classname, c_baseclassname);
|
||||
|
||||
Delete(upcast_method_name);
|
||||
Delete(cptr_method_name);
|
||||
Delete(interface_code);
|
||||
Delete(c_baseclass);
|
||||
}
|
||||
Delete(keys);
|
||||
}
|
||||
|
|
@ -1824,19 +1892,23 @@ public:
|
|||
* Add code for C++ casting to base class
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
void upcastsCode(SwigType *smart, String *upcast_method_name, String *c_classname, String *c_baseclass) {
|
||||
void upcastsCode(SwigType *smart, String *upcast_method_name, SwigType *c_classname, SwigType *c_baseclassname) {
|
||||
String *jniname = makeValidJniName(upcast_method_name);
|
||||
String *wname = Swig_name_wrapper(jniname);
|
||||
|
||||
Printf(imclass_cppcasts_code, " public final static native long %s(long jarg1);\n", upcast_method_name);
|
||||
|
||||
String *classname = SwigType_namestr(c_classname);
|
||||
String *baseclassname = SwigType_namestr(c_baseclassname);
|
||||
if (smart) {
|
||||
SwigType *bsmart = Copy(smart);
|
||||
SwigType *rclassname = SwigType_typedef_resolve_all(c_classname);
|
||||
SwigType *rbaseclass = SwigType_typedef_resolve_all(c_baseclass);
|
||||
Replaceall(bsmart, rclassname, rbaseclass);
|
||||
Delete(rclassname);
|
||||
Delete(rbaseclass);
|
||||
String *smartnamestr = SwigType_namestr(smart);
|
||||
String *bsmartnamestr = SwigType_namestr(bsmart);
|
||||
String *bsmartnamestr = SwigType_namestr(smart);
|
||||
|
||||
// TODO: SwigType_typedef_resolve_all on a String instead of SwigType is incorrect for templates
|
||||
SwigType *rclassname = SwigType_typedef_resolve_all(classname);
|
||||
SwigType *rbaseclassname = SwigType_typedef_resolve_all(baseclassname);
|
||||
Replaceall(bsmartnamestr, rclassname, rbaseclassname);
|
||||
|
||||
Printv(upcasts_code,
|
||||
"SWIGEXPORT jlong JNICALL ", wname, "(JNIEnv *jenv, jclass jcls, jlong jarg1) {\n",
|
||||
" jlong baseptr = 0;\n"
|
||||
|
|
@ -1847,19 +1919,24 @@ public:
|
|||
" *(", bsmartnamestr, " **)&baseptr = argp1 ? new ", bsmartnamestr, "(*argp1) : 0;\n"
|
||||
" return baseptr;\n"
|
||||
"}\n", "\n", NIL);
|
||||
|
||||
Delete(rbaseclassname);
|
||||
Delete(rclassname);
|
||||
Delete(bsmartnamestr);
|
||||
Delete(smartnamestr);
|
||||
Delete(bsmart);
|
||||
} else {
|
||||
Printv(upcasts_code,
|
||||
"SWIGEXPORT jlong JNICALL ", wname, "(JNIEnv *jenv, jclass jcls, jlong jarg1) {\n",
|
||||
" jlong baseptr = 0;\n"
|
||||
" (void)jenv;\n"
|
||||
" (void)jcls;\n"
|
||||
" *(", c_baseclass, " **)&baseptr = *(", c_classname, " **)&jarg1;\n"
|
||||
" *(", baseclassname, " **)&baseptr = *(", classname, " **)&jarg1;\n"
|
||||
" return baseptr;\n"
|
||||
"}\n", "\n", NIL);
|
||||
}
|
||||
|
||||
Delete(baseclassname);
|
||||
Delete(classname);
|
||||
Delete(wname);
|
||||
Delete(jniname);
|
||||
}
|
||||
|
|
@ -1869,10 +1946,9 @@ public:
|
|||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
void emitProxyClassDefAndCPPCasts(Node *n) {
|
||||
String *c_classname = SwigType_namestr(Getattr(n, "name"));
|
||||
String *c_baseclass = NULL;
|
||||
SwigType *c_classname = Getattr(n, "name");
|
||||
SwigType *c_baseclassname = NULL;
|
||||
String *baseclass = NULL;
|
||||
String *c_baseclassname = NULL;
|
||||
String *interface_list = NewStringEmpty();
|
||||
String *interface_upcasts = NewStringEmpty();
|
||||
SwigType *typemap_lookup_type = Getattr(n, "classtypeobj");
|
||||
|
|
@ -1894,12 +1970,13 @@ public:
|
|||
Iterator base = First(baselist);
|
||||
while (base.item) {
|
||||
if (!(GetFlag(base.item, "feature:ignore") || Getattr(base.item, "feature:interface"))) {
|
||||
String *baseclassname = Getattr(base.item, "name");
|
||||
SwigType *baseclassname = Getattr(base.item, "name");
|
||||
if (!c_baseclassname) {
|
||||
c_baseclassname = baseclassname;
|
||||
baseclass = Copy(getProxyName(baseclassname));
|
||||
if (baseclass)
|
||||
c_baseclass = SwigType_namestr(baseclassname);
|
||||
String *name = getProxyName(baseclassname);
|
||||
if (name) {
|
||||
c_baseclassname = baseclassname;
|
||||
baseclass = name;
|
||||
}
|
||||
} else {
|
||||
/* Warn about multiple inheritance for additional base class(es) */
|
||||
String *proxyclassname = Getattr(n, "classtypeobj");
|
||||
|
|
@ -1916,7 +1993,7 @@ public:
|
|||
if (interface_bases)
|
||||
addInterfaceNameAndUpcasts(smart, interface_list, interface_upcasts, interface_bases, c_classname);
|
||||
|
||||
bool derived = baseclass && getProxyName(c_baseclassname);
|
||||
bool derived = baseclass != 0;
|
||||
if (derived && purebase_notderived)
|
||||
pure_baseclass = empty_string;
|
||||
const String *wanted_base = baseclass ? baseclass : pure_baseclass;
|
||||
|
|
@ -1924,7 +2001,6 @@ public:
|
|||
if (purebase_replace) {
|
||||
wanted_base = pure_baseclass;
|
||||
derived = false;
|
||||
Delete(baseclass);
|
||||
baseclass = NULL;
|
||||
if (purebase_notderived)
|
||||
Swig_error(Getfile(n), Getline(n), "The javabase typemap for proxy %s must contain just one of the 'replace' or 'notderived' attributes.\n", typemap_lookup_type);
|
||||
|
|
@ -1936,13 +2012,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
|
||||
|
|
@ -1956,16 +2043,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) {
|
||||
|
|
@ -1974,6 +2064,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) {
|
||||
|
|
@ -1987,8 +2079,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);
|
||||
|
|
@ -2024,12 +2123,11 @@ public:
|
|||
|
||||
if (derived) {
|
||||
String *upcast_method_name = Swig_name_member(getNSpace(), getClassPrefix(), smart != 0 ? "SWIGSmartPtrUpcast" : "SWIGUpcast");
|
||||
upcastsCode(smart, upcast_method_name, c_classname, c_baseclass);
|
||||
upcastsCode(smart, upcast_method_name, c_classname, c_baseclassname);
|
||||
Delete(upcast_method_name);
|
||||
}
|
||||
|
||||
Delete(smart);
|
||||
Delete(baseclass);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
|
|
@ -2047,7 +2145,8 @@ public:
|
|||
}
|
||||
|
||||
Printv(f_interface, typemapLookup(n, "javaimports", Getattr(n, "classtypeobj"), WARN_NONE), "\n", NIL);
|
||||
Printf(f_interface, "public interface %s", interface_name);
|
||||
Printv(f_interface, typemapLookup(n, "javainterfacemodifiers", Getattr(n, "classtypeobj"), WARN_JAVA_TYPEMAP_INTERFACEMODIFIERS_UNDEF), NIL);
|
||||
Printf(f_interface, " %s", interface_name);
|
||||
if (List *baselist = Getattr(n, "bases")) {
|
||||
String *bases = 0;
|
||||
for (Iterator base = First(baselist); base.item; base = Next(base)) {
|
||||
|
|
@ -2417,6 +2516,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);
|
||||
|
|
@ -2424,7 +2532,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);
|
||||
|
||||
|
|
@ -2544,8 +2652,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))) {
|
||||
|
|
@ -2603,8 +2709,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);
|
||||
|
|
@ -2649,6 +2760,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);
|
||||
|
||||
|
|
@ -2757,7 +2877,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) {
|
||||
|
|
@ -2827,6 +2948,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;
|
||||
}
|
||||
|
|
@ -2910,6 +3034,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);
|
||||
|
|
@ -3062,7 +3195,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);
|
||||
|
|
@ -3760,15 +3893,16 @@ 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 = static_cast<%s *>(obj->operator->());\n", dirClassName, dirClassName);
|
||||
}
|
||||
else {
|
||||
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 = static_cast<%s *>(obj);\n", dirClassName, dirClassName);
|
||||
Printf(code_wrap->code, " %s *director = dynamic_cast<%s *>(obj);\n", dirClassName, dirClassName);
|
||||
}
|
||||
|
||||
Printf(code_wrap->code, " (void)jcls;\n");
|
||||
Printf(code_wrap->code, " director->swig_java_change_ownership(jenv, jself, jtake_or_release ? true : false);\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");
|
||||
Printf(code_wrap->code, " }\n");
|
||||
Printf(code_wrap->code, "}\n");
|
||||
|
||||
Wrapper_print(code_wrap, f_wrappers);
|
||||
|
|
@ -3945,15 +4079,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);
|
||||
|
|
@ -4044,7 +4180,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);
|
||||
|
||||
|
|
@ -4243,11 +4379,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);
|
||||
|
||||
|
|
@ -4461,8 +4597,8 @@ 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, "if ($error) {");
|
||||
Printf(directorexcept, "$directorthrowshandlers\n");
|
||||
Printf(directorexcept, " Swig::DirectorException::raise(jenv, $error);\n");
|
||||
Printf(directorexcept, "}\n");
|
||||
} else {
|
||||
|
|
@ -4562,7 +4698,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"));
|
||||
|
||||
|
|
@ -4576,7 +4712,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);
|
||||
}
|
||||
|
|
@ -4652,8 +4788,8 @@ public:
|
|||
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);
|
||||
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);
|
||||
|
|
@ -4700,34 +4836,27 @@ public:
|
|||
// .'s to delimit namespaces, so we need to replace those with /'s
|
||||
Replace(internal_classname, NSPACE_SEPARATOR, "/", DOH_REPLACE_ANY);
|
||||
|
||||
Wrapper_add_localv(w, "baseclass", "static jclass baseclass", "= 0", NIL);
|
||||
Printf(w->def, "void %s::swig_connect_director(JNIEnv *jenv, jobject jself, jclass jcls, bool swig_mem_own, bool weak_global) {", director_classname);
|
||||
|
||||
Printf(w->def, "static jclass baseclass = swig_new_global_ref(jenv, \"%s\");\n", internal_classname);
|
||||
Printf(w->def, "if (!baseclass) return;\n");
|
||||
|
||||
if (first_class_dmethod != curr_class_dmethod) {
|
||||
Printf(w->def, "static struct {\n");
|
||||
Printf(w->def, "const char *mname;\n");
|
||||
Printf(w->def, "const char *mdesc;\n");
|
||||
Printf(w->def, "jmethodID base_methid;\n");
|
||||
Printf(w->def, "} methods[] = {\n");
|
||||
Printf(w->def, "static SwigDirectorMethod methods[] = {\n");
|
||||
|
||||
for (int i = first_class_dmethod; i < curr_class_dmethod; ++i) {
|
||||
UpcallData *udata = Getitem(dmethods_seq, i);
|
||||
|
||||
Printf(w->def, "{ \"%s\", \"%s\", NULL }", Getattr(udata, "method"), Getattr(udata, "fdesc"));
|
||||
Printf(w->def, "SwigDirectorMethod(jenv, baseclass, \"%s\", \"%s\")", Getattr(udata, "method"), Getattr(udata, "fdesc"));
|
||||
if (i != curr_class_dmethod - 1)
|
||||
Putc(',', w->def);
|
||||
Putc('\n', w->def);
|
||||
}
|
||||
|
||||
Printf(w->def, "};\n");
|
||||
Printf(w->def, "};");
|
||||
}
|
||||
|
||||
Printf(w->code, "if (swig_set_self(jenv, jself, swig_mem_own, weak_global)) {\n");
|
||||
Printf(w->code, "if (!baseclass) {\n");
|
||||
Printf(w->code, "baseclass = jenv->FindClass(\"%s\");\n", internal_classname);
|
||||
Printf(w->code, "if (!baseclass) return;\n");
|
||||
Printf(w->code, "baseclass = (jclass) jenv->NewGlobalRef(baseclass);\n");
|
||||
Printf(w->code, "}\n");
|
||||
|
||||
int n_methods = curr_class_dmethod - first_class_dmethod;
|
||||
|
||||
|
|
@ -4742,12 +4871,8 @@ public:
|
|||
|
||||
/* Emit the code to look up the class's methods, initialize the override array */
|
||||
|
||||
Printf(w->code, "bool derived = (jenv->IsSameObject(baseclass, jcls) ? false : true);\n");
|
||||
Printf(w->code, "for (int i = 0; i < %d; ++i) {\n", n_methods);
|
||||
Printf(w->code, " if (!methods[i].base_methid) {\n");
|
||||
Printf(w->code, " methods[i].base_methid = jenv->GetMethodID(baseclass, methods[i].mname, methods[i].mdesc);\n");
|
||||
Printf(w->code, " if (!methods[i].base_methid) return;\n");
|
||||
Printf(w->code, " }\n");
|
||||
Printf(w->code, " bool derived = (jenv->IsSameObject(baseclass, jcls) ? false : true);\n");
|
||||
Printf(w->code, " for (int i = 0; i < %d; ++i) {\n", n_methods);
|
||||
// Generally, derived classes have a mix of overridden and
|
||||
// non-overridden methods and it is worth making a GetMethodID
|
||||
// check during initialization to determine if each method is
|
||||
|
|
@ -4767,8 +4892,8 @@ public:
|
|||
} else {
|
||||
Printf(w->code, " swig_override[i] = false;\n");
|
||||
Printf(w->code, " if (derived) {\n");
|
||||
Printf(w->code, " jmethodID methid = jenv->GetMethodID(jcls, methods[i].mname, methods[i].mdesc);\n");
|
||||
Printf(w->code, " swig_override[i] = (methid != methods[i].base_methid);\n");
|
||||
Printf(w->code, " jmethodID methid = jenv->GetMethodID(jcls, methods[i].name, methods[i].desc);\n");
|
||||
Printf(w->code, " swig_override[i] = methods[i].methid && (methid != methods[i].methid);\n");
|
||||
Printf(w->code, " jenv->ExceptionClear();\n");
|
||||
Printf(w->code, " }\n");
|
||||
}
|
||||
|
|
@ -4856,6 +4981,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"
|
||||
|
|
@ -196,6 +197,11 @@ public:
|
|||
*/
|
||||
virtual int emitWrapperFunction(Node *n);
|
||||
|
||||
/**
|
||||
* Invoked by nativeWrapper callback
|
||||
*/
|
||||
virtual int emitNativeFunction(Node *n);
|
||||
|
||||
/**
|
||||
* Invoked from constantWrapper after call to Language::constantWrapper.
|
||||
**/
|
||||
|
|
@ -262,7 +268,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;
|
||||
|
||||
|
|
@ -310,6 +316,7 @@ public:
|
|||
virtual int classHandler(Node *n);
|
||||
virtual int functionWrapper(Node *n);
|
||||
virtual int constantWrapper(Node *n);
|
||||
virtual int nativeWrapper(Node *n);
|
||||
virtual void main(int argc, char *argv[]);
|
||||
virtual int top(Node *n);
|
||||
|
||||
|
|
@ -440,6 +447,18 @@ int JAVASCRIPT::constantWrapper(Node *n) {
|
|||
return SWIG_OK;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* nativeWrapper()
|
||||
*
|
||||
* Function wrapper for generating placeholders for native functions
|
||||
* --------------------------------------------------------------------- */
|
||||
|
||||
int JAVASCRIPT::nativeWrapper(Node *n) {
|
||||
emitter->emitNativeFunction(n);
|
||||
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* classHandler()
|
||||
*
|
||||
|
|
@ -552,7 +571,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 +683,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;
|
||||
|
|
@ -767,6 +786,14 @@ int JSEmitter::emitWrapperFunction(Node *n) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
int JSEmitter::emitNativeFunction(Node *n) {
|
||||
String *wrapname = Getattr(n, "wrap:name");
|
||||
enterFunction(n);
|
||||
state.function(WRAPPER_NAME, wrapname);
|
||||
exitFunction(n);
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
int JSEmitter::enterClass(Node *n) {
|
||||
state.clazz(RESET);
|
||||
state.clazz(NAME, Getattr(n, "sym:name"));
|
||||
|
|
@ -993,7 +1020,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 +1151,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?
|
||||
|
|
@ -1428,19 +1455,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;
|
||||
|
|
@ -1467,7 +1495,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:
|
||||
|
|
@ -1547,7 +1575,8 @@ void JSCEmitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, Ma
|
|||
Printf(arg, "argv[%d]", i);
|
||||
break;
|
||||
default:
|
||||
throw "Illegal state.";
|
||||
Printf(stderr, "Illegal MarshallingMode.");
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
}
|
||||
tm = emitInputTypemap(n, p, wrapper, arg);
|
||||
Delete(arg);
|
||||
|
|
@ -1773,8 +1802,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;
|
||||
|
|
@ -1786,8 +1815,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");
|
||||
|
||||
|
|
@ -2037,7 +2065,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))
|
||||
|
|
@ -2185,7 +2213,8 @@ void V8Emitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, Mar
|
|||
Printf(arg, "args[%d]", i);
|
||||
break;
|
||||
default:
|
||||
throw "Illegal state.";
|
||||
Printf(stderr, "Illegal MarshallingMode.");
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
tm = emitInputTypemap(n, p, wrapper, arg);
|
||||
|
|
@ -2206,7 +2235,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;
|
||||
|
|
@ -2427,7 +2456,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
|
||||
|
|
|
|||
|
|
@ -307,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),
|
||||
|
|
@ -336,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;
|
||||
|
|
@ -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));
|
||||
|
|
@ -1273,6 +1272,9 @@ int Language::memberfunctionHandler(Node *n) {
|
|||
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);
|
||||
|
||||
|
|
@ -1333,6 +1335,9 @@ int Language::staticmemberfunctionHandler(Node *n) {
|
|||
|
||||
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);
|
||||
|
|
@ -1889,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) {
|
||||
|
|
@ -2104,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");
|
||||
|
|
@ -2151,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);
|
||||
|
|
@ -2193,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)) {
|
||||
|
|
@ -3264,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);
|
||||
|
|
@ -3296,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;
|
||||
|
|
@ -3323,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 {
|
||||
|
|
@ -3349,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);
|
||||
|
|
@ -3393,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;
|
||||
|
|
@ -3513,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()) {
|
||||
|
|
@ -3589,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) {
|
||||
|
|
@ -3597,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
|
||||
|
|
@ -3773,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;
|
||||
|
|
@ -1002,6 +1002,7 @@ public:
|
|||
// REPORT("variableWrapper", n);
|
||||
String *lua_name = Getattr(n, "lua:name");
|
||||
assert(lua_name);
|
||||
(void)lua_name;
|
||||
current[VARIABLE] = true;
|
||||
// let SWIG generate the wrappers
|
||||
int result = Language::variableWrapper(n);
|
||||
|
|
@ -1359,7 +1360,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 +1462,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);
|
||||
|
|
@ -2110,7 +2111,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 +2194,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();
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include "swigwarn.h"
|
||||
#include "cparse.h"
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h> // for INT_MAX
|
||||
|
||||
// Global variables
|
||||
|
|
@ -38,14 +39,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 +66,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 PHP5 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 +98,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 +131,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 +156,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 +460,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 +879,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 +891,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 +926,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 +957,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 +970,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 +1066,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 +1075,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");
|
||||
|
|
@ -1125,9 +1141,9 @@ int SWIG_main(int argc, char *argv[], Language *l) {
|
|||
} else
|
||||
f_dependencies_file = stdout;
|
||||
if (dependencies_target) {
|
||||
Printf(f_dependencies_file, "%s: ", dependencies_target);
|
||||
Printf(f_dependencies_file, "%s: ", Swig_filename_escape_space(dependencies_target));
|
||||
} else {
|
||||
Printf(f_dependencies_file, "%s: ", outfile);
|
||||
Printf(f_dependencies_file, "%s: ", Swig_filename_escape_space(outfile));
|
||||
}
|
||||
List *files = Preprocessor_depend();
|
||||
List *phony_targets = NewList();
|
||||
|
|
@ -1138,7 +1154,7 @@ int SWIG_main(int argc, char *argv[], Language *l) {
|
|||
use_file = 0;
|
||||
}
|
||||
if (use_file) {
|
||||
Printf(f_dependencies_file, "\\\n %s ", Getitem(files, i));
|
||||
Printf(f_dependencies_file, "\\\n %s ", Swig_filename_escape_space(Getitem(files, i)));
|
||||
if (depend_phony)
|
||||
Append(phony_targets, Getitem(files, i));
|
||||
}
|
||||
|
|
@ -1146,7 +1162,7 @@ int SWIG_main(int argc, char *argv[], Language *l) {
|
|||
Printf(f_dependencies_file, "\n");
|
||||
if (depend_phony) {
|
||||
for (int i = 0; i < Len(phony_targets); i++) {
|
||||
Printf(f_dependencies_file, "\n%s:\n", Getitem(phony_targets, i));
|
||||
Printf(f_dependencies_file, "\n%s:\n", Swig_filename_escape_space(Getitem(phony_targets, i)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1300,6 +1316,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) {
|
||||
|
|
@ -1354,13 +1377,15 @@ int SWIG_main(int argc, char *argv[], Language *l) {
|
|||
while (freeze) {
|
||||
}
|
||||
|
||||
if ((werror) && (Swig_warn_count())) {
|
||||
return Swig_warn_count();
|
||||
}
|
||||
|
||||
delete lang;
|
||||
|
||||
return Swig_error_count();
|
||||
int error_count = werror ? Swig_warn_count() : 0;
|
||||
error_count += Swig_error_count();
|
||||
|
||||
if (error_count != 0)
|
||||
SWIG_exit(error_count);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
|
|
@ -1372,5 +1397,20 @@ int SWIG_main(int argc, char *argv[], Language *l) {
|
|||
void SWIG_exit(int exit_code) {
|
||||
while (freeze) {
|
||||
}
|
||||
|
||||
if (exit_code > 0) {
|
||||
CloseAllOpenFiles();
|
||||
|
||||
/* Remove all generated files */
|
||||
if (all_output_files) {
|
||||
for (int i = 0; i < Len(all_output_files); i++) {
|
||||
String *filename = Getitem(all_output_files, i);
|
||||
int removed = remove(Char(filename));
|
||||
if (removed == -1)
|
||||
fprintf(stderr, "On exit, could not delete file %s: %s\n", Char(filename), strerror(errno));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exit(exit_code);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
@ -693,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);
|
||||
|
||||
|
|
@ -711,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 */
|
||||
|
|
@ -725,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);
|
||||
|
||||
|
|
@ -735,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);
|
||||
|
|
@ -761,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.
|
||||
|
|
@ -780,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) {
|
||||
|
|
@ -802,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 */
|
||||
|
|
@ -818,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");
|
||||
}
|
||||
|
|
@ -842,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);
|
||||
|
|
@ -868,9 +905,6 @@ public:
|
|||
|
||||
Delete(var_name);
|
||||
Delete(proc_name);
|
||||
Delete(argnum);
|
||||
Delete(arg);
|
||||
Delete(tm2);
|
||||
DelWrapper(f);
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
|
@ -898,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;
|
||||
|
|
@ -913,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;
|
||||
|
|
@ -1104,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;
|
||||
|
|
@ -1117,7 +1128,6 @@ public:
|
|||
bool sizeof_feature = generate_sizeof && isSimpleType(name);
|
||||
|
||||
|
||||
classname = mangled_sym_name;
|
||||
classmode = true;
|
||||
int rv = Language::classHandler(n);
|
||||
classmode = false;
|
||||
|
|
@ -1125,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");
|
||||
|
|
@ -1152,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);
|
||||
|
|
@ -1165,7 +1175,7 @@ public:
|
|||
|
||||
Multiwrite(this_class_def);
|
||||
|
||||
Setattr(n, "ocaml:ctor", classname);
|
||||
Setattr(n, "ocaml:ctor", mangled_name);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
|
@ -1404,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);
|
||||
|
|
@ -1416,15 +1425,47 @@ 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).
|
||||
|
|
@ -1447,23 +1488,25 @@ public:
|
|||
|
||||
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;
|
||||
|
|
@ -1573,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 const 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) {
|
||||
|
|
@ -1592,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).
|
||||
*/
|
||||
|
|
@ -1651,6 +1696,8 @@ public:
|
|||
Printf(w->code, "CAMLreturn_type(*c_result);\n");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Printf(w->code, "CAMLreturn0;\n");
|
||||
}
|
||||
|
||||
Printf(w->code, "}\n");
|
||||
|
|
@ -1716,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);
|
||||
|
|
@ -1727,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);
|
||||
}
|
||||
|
|
@ -1817,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);
|
||||
|
|
@ -569,6 +567,10 @@ public:
|
|||
Wrapper *f = NewWrapper();
|
||||
Octave_begin_function(n, f->def, iname, overname, !overloaded);
|
||||
|
||||
// Start default try block to execute
|
||||
// cleanup code if exception is thrown
|
||||
Printf(f->code, "try {\n");
|
||||
|
||||
emit_parameter_variables(l, f);
|
||||
emit_attach_parmmaps(l, f);
|
||||
Setattr(n, "wrap:parms", l);
|
||||
|
|
@ -756,9 +758,20 @@ public:
|
|||
}
|
||||
|
||||
Printf(f->code, "return _out;\n");
|
||||
Printf(f->code, "fail:\n"); // we should free locals etc if this happens
|
||||
|
||||
// Execute cleanup code if branched to fail: label
|
||||
Printf(f->code, "fail:\n");
|
||||
Printv(f->code, cleanup, NIL);
|
||||
Printf(f->code, "return octave_value_list();\n");
|
||||
|
||||
// Execute cleanup code if exception was thrown
|
||||
Printf(f->code, "}\n");
|
||||
Printf(f->code, "catch(...) {\n");
|
||||
Printv(f->code, cleanup, NIL);
|
||||
Printf(f->code, "throw;\n");
|
||||
Printf(f->code, "}\n");
|
||||
|
||||
// End wrapper function
|
||||
Printf(f->code, "}\n");
|
||||
|
||||
/* Substitute the cleanup code */
|
||||
|
|
@ -832,7 +845,7 @@ public:
|
|||
String *setwname = Swig_name_wrapper(setname);
|
||||
|
||||
Octave_begin_function(n, setf->def, setname, setwname, true);
|
||||
Printf(setf->def, "if (!SWIG_check_num_args(\"%s_set\",args.length(),1,1,0)) return octave_value_list();", iname);
|
||||
Printf(setf->code, "if (!SWIG_check_num_args(\"%s_set\",args.length(),1,1,0)) return octave_value_list();", iname);
|
||||
if (is_assignable(n)) {
|
||||
Setattr(n, "wrap:name", setname);
|
||||
if ((tm = Swig_typemap_lookup("varin", n, name, 0))) {
|
||||
|
|
@ -847,8 +860,9 @@ public:
|
|||
} else {
|
||||
Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(t, 0));
|
||||
}
|
||||
Append(setf->code, "return octave_value_list();\n");
|
||||
Append(setf->code, "fail:\n");
|
||||
Printf(setf->code, "return octave_value_list();\n");
|
||||
Append(setf->code, "return octave_value_list();\n");
|
||||
} else {
|
||||
Printf(setf->code, "return octave_set_immutable(args,nargout);");
|
||||
}
|
||||
|
|
@ -868,10 +882,10 @@ public:
|
|||
} else {
|
||||
Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(t, 0));
|
||||
}
|
||||
Append(getf->code, " return obj;\n");
|
||||
Append(getf->code, "return obj;\n");
|
||||
if (addfail) {
|
||||
Append(getf->code, "fail:\n");
|
||||
Append(getf->code, " return octave_value_list();\n");
|
||||
Append(getf->code, "return octave_value_list();\n");
|
||||
}
|
||||
Append(getf->code, "}\n");
|
||||
Wrapper_print(getf, f_wrappers);
|
||||
|
|
@ -1234,7 +1248,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 +1260,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,13 +1324,13 @@ 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);
|
||||
|
||||
|
|
@ -1393,7 +1407,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,12 +2083,12 @@ 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);
|
||||
|
||||
|
|
@ -2129,27 +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 (!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);
|
||||
}
|
||||
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 {
|
||||
String *cres = SwigType_lstr(returntype, "c_result");
|
||||
Printf(w->code, "%s;\n", cres);
|
||||
Delete(cres);
|
||||
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) {
|
||||
|
|
@ -2172,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");
|
||||
|
|
@ -2346,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).
|
||||
*
|
||||
*/
|
||||
|
|
@ -2504,8 +2506,8 @@ public:
|
|||
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);
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* FIXME: PHP5 OO wrapping TODO list:
|
||||
/* FIXME: PHP OO wrapping TODO list:
|
||||
*
|
||||
* Medium term:
|
||||
*
|
||||
|
|
@ -211,7 +211,7 @@ static void SwigPHP_emit_resource_registrations() {
|
|||
|
||||
ki = First(zend_types);
|
||||
if (ki.key)
|
||||
Printf(s_oinit, "\n/* Register resource destructors for pointer types */\n");
|
||||
Printf(s_oinit, "\n /* Register resource destructors for pointer types */\n");
|
||||
while (ki.key) {
|
||||
DOH *key = ki.key;
|
||||
Node *class_node = ki.item;
|
||||
|
|
@ -249,11 +249,11 @@ static void SwigPHP_emit_resource_registrations() {
|
|||
Printf(s_vdecl, "static int le_swig_%s=0; /* handle for %s */\n", key, human_name);
|
||||
|
||||
// register with php
|
||||
Printf(s_oinit, "le_swig_%s=zend_register_list_destructors_ex"
|
||||
Printf(s_oinit, " le_swig_%s=zend_register_list_destructors_ex"
|
||||
"(%s, NULL, SWIGTYPE%s->name, module_number);\n", key, rsrc_dtor_name, key);
|
||||
|
||||
// store php type in class struct
|
||||
Printf(s_oinit, "SWIG_TypeClientData(SWIGTYPE%s,&le_swig_%s);\n", key, key);
|
||||
Printf(s_oinit, " SWIG_TypeClientData(SWIGTYPE%s,&le_swig_%s);\n", key, key);
|
||||
|
||||
Delete(rsrc_dtor_name);
|
||||
|
||||
|
|
@ -341,8 +341,8 @@ public:
|
|||
/* subsections of the init section */
|
||||
s_vinit = NewStringEmpty();
|
||||
s_vdecl = NewString("/* vdecl subsection */\n");
|
||||
s_cinit = NewString("/* cinit subsection */\n");
|
||||
s_oinit = NewString("/* oinit subsection */\n");
|
||||
s_cinit = NewString(" /* cinit subsection */\n");
|
||||
s_oinit = NewString(" /* oinit subsection */\n");
|
||||
pragma_phpinfo = NewStringEmpty();
|
||||
s_phpclasses = NewString("/* PHP Proxy Classes */\n");
|
||||
f_directors_h = NewStringEmpty();
|
||||
|
|
@ -433,7 +433,7 @@ public:
|
|||
|
||||
/* Initialize the rest of the module */
|
||||
|
||||
Printf(s_oinit, "ZEND_INIT_MODULE_GLOBALS(%s, %s_init_globals, NULL);\n", module, module);
|
||||
Printf(s_oinit, " ZEND_INIT_MODULE_GLOBALS(%s, %s_init_globals, NULL);\n", module, module);
|
||||
|
||||
/* start the header section */
|
||||
Printf(s_header, "ZEND_BEGIN_MODULE_GLOBALS(%s)\n", module);
|
||||
|
|
@ -441,8 +441,8 @@ public:
|
|||
Printf(s_header, "int error_code;\n");
|
||||
Printf(s_header, "ZEND_END_MODULE_GLOBALS(%s)\n", module);
|
||||
Printf(s_header, "ZEND_DECLARE_MODULE_GLOBALS(%s)\n", module);
|
||||
Printf(s_header, "#define SWIG_ErrorMsg() (%s_globals.error_msg)\n", module);
|
||||
Printf(s_header, "#define SWIG_ErrorCode() (%s_globals.error_code)\n", module);
|
||||
Printf(s_header, "#define SWIG_ErrorMsg() ZEND_MODULE_GLOBALS_ACCESSOR(%s, error_msg)\n", module);
|
||||
Printf(s_header, "#define SWIG_ErrorCode() ZEND_MODULE_GLOBALS_ACCESSOR(%s, error_code)\n", module);
|
||||
|
||||
/* The following can't go in Lib/php/phprun.swg as it uses SWIG_ErrorMsg(), etc
|
||||
* which has to be dynamically generated as it depends on the module name.
|
||||
|
|
@ -551,6 +551,20 @@ public:
|
|||
s_arginfo = NewString("/* arginfo subsection */\n");
|
||||
arginfo_used = NewHash();
|
||||
|
||||
// Add arginfo we'll definitely need for *_alter_newobject and *_get_newobject.
|
||||
SetFlag(arginfo_used, "1");
|
||||
Append(s_arginfo,
|
||||
"ZEND_BEGIN_ARG_INFO_EX(swig_arginfo_1, 0, 0, 1)\n"
|
||||
" ZEND_ARG_INFO(0,arg1)\n"
|
||||
"ZEND_END_ARG_INFO()\n");
|
||||
|
||||
SetFlag(arginfo_used, "2");
|
||||
Append(s_arginfo,
|
||||
"ZEND_BEGIN_ARG_INFO_EX(swig_arginfo_2, 0, 0, 2)\n"
|
||||
" ZEND_ARG_INFO(0,arg1)\n"
|
||||
" ZEND_ARG_INFO(0,arg2)\n"
|
||||
"ZEND_END_ARG_INFO()\n");
|
||||
|
||||
/* start the function entry section */
|
||||
s_entry = NewString("/* entry subsection */\n");
|
||||
|
||||
|
|
@ -613,7 +627,7 @@ public:
|
|||
Printf(s_init, "extern \"C\" {\n");
|
||||
Printf(s_init, "#endif\n");
|
||||
// We want to write "SWIGEXPORT ZEND_GET_MODULE(%s)" but ZEND_GET_MODULE
|
||||
// in PHP5 has "extern "C" { ... }" around it so we can't do that.
|
||||
// in PHP7 has "extern "C" { ... }" around it so we can't do that.
|
||||
Printf(s_init, "SWIGEXPORT zend_module_entry *get_module(void) { return &%s_module_entry; }\n", module);
|
||||
Printf(s_init, "#ifdef __cplusplus\n");
|
||||
Printf(s_init, "}\n");
|
||||
|
|
@ -632,17 +646,17 @@ public:
|
|||
|
||||
// Printv(s_init,s_resourcetypes,NIL);
|
||||
/* We need this after all classes written out by ::top */
|
||||
Printf(s_oinit, "CG(active_class_entry) = NULL;\n");
|
||||
Printf(s_oinit, "/* end oinit subsection */\n");
|
||||
Printf(s_oinit, " CG(active_class_entry) = NULL;\n");
|
||||
Printf(s_oinit, " /* end oinit subsection */\n");
|
||||
Printf(s_init, "%s\n", s_oinit);
|
||||
|
||||
/* Constants generated during top call */
|
||||
Printf(s_cinit, "/* end cinit subsection */\n");
|
||||
Printf(s_cinit, " /* end cinit subsection */\n");
|
||||
Printf(s_init, "%s\n", s_cinit);
|
||||
Clear(s_cinit);
|
||||
Delete(s_cinit);
|
||||
|
||||
Printf(s_init, " return SUCCESS;\n");
|
||||
Printf(s_init, " return SUCCESS;\n");
|
||||
Printf(s_init, "}\n\n");
|
||||
|
||||
// Now do REQUEST init which holds any user specified %rinit, and also vinit
|
||||
|
|
@ -660,15 +674,15 @@ public:
|
|||
if (Len(s_vinit) > 0) {
|
||||
/* finish our init section which will have been used by class wrappers */
|
||||
Printv(s_init,
|
||||
"/* vinit subsection */\n",
|
||||
" /* vinit subsection */\n",
|
||||
s_vinit, "\n"
|
||||
"/* end vinit subsection */\n",
|
||||
" /* end vinit subsection */\n",
|
||||
NIL);
|
||||
Clear(s_vinit);
|
||||
}
|
||||
Delete(s_vinit);
|
||||
|
||||
Printf(s_init, " return SUCCESS;\n");
|
||||
Printf(s_init, " return SUCCESS;\n");
|
||||
Printf(s_init, "}\n\n");
|
||||
}
|
||||
|
||||
|
|
@ -681,7 +695,7 @@ public:
|
|||
"/* shutdown section */\n"
|
||||
"{\n",
|
||||
s_shutdown,
|
||||
" return SUCCESS;\n"
|
||||
" return SUCCESS;\n"
|
||||
"}\n\n", NIL);
|
||||
}
|
||||
|
||||
|
|
@ -736,8 +750,8 @@ public:
|
|||
}
|
||||
Printv(f_begin, s_vdecl, s_wrappers, NIL);
|
||||
Printv(f_begin, s_arginfo, "\n\n", all_cs_entry, "\n\n", s_entry,
|
||||
" SWIG_ZEND_NAMED_FE(swig_", module, "_alter_newobject,_wrap_swig_", module, "_alter_newobject,NULL)\n"
|
||||
" SWIG_ZEND_NAMED_FE(swig_", module, "_get_newobject,_wrap_swig_", module, "_get_newobject,NULL)\n"
|
||||
" SWIG_ZEND_NAMED_FE(swig_", module, "_alter_newobject,_wrap_swig_", module, "_alter_newobject,swig_arginfo_2)\n"
|
||||
" SWIG_ZEND_NAMED_FE(swig_", module, "_get_newobject,_wrap_swig_", module, "_get_newobject,swig_arginfo_1)\n"
|
||||
" ZEND_FE_END\n};\n\n", NIL);
|
||||
Printv(f_begin, s_init, NIL);
|
||||
Delete(s_header);
|
||||
|
|
@ -759,7 +773,7 @@ public:
|
|||
Delete(s_fakeoowrappers);
|
||||
s_fakeoowrappers = NULL;
|
||||
}
|
||||
Printf(f_phpcode, "%s\n?>\n", s_phpclasses);
|
||||
Printf(f_phpcode, "%s\n", s_phpclasses);
|
||||
Delete(f_phpcode);
|
||||
|
||||
return SWIG_OK;
|
||||
|
|
@ -778,17 +792,18 @@ public:
|
|||
}
|
||||
// We want to only emit each different arginfo once, as that reduces the
|
||||
// size of both the generated source code and the compiled extension
|
||||
// module. To do this, we name the arginfo to encode the number of
|
||||
// parameters and which (if any) are passed by reference by using a
|
||||
// sequence of 0s (for non-reference) and 1s (for by references).
|
||||
// module. The parameters at this level are just named arg1, arg2, etc
|
||||
// so we generate an arginfo name with the number of parameters and a
|
||||
// bitmap value saying which (if any) are passed by reference.
|
||||
bool constructor = false;
|
||||
if (Cmp(fname,"__construct") == 0) {
|
||||
constructor = true;
|
||||
}
|
||||
|
||||
ParmList *l = Getattr(n, "parms");
|
||||
int Iterator = 0;
|
||||
String * arginfo_code = NewStringEmpty();
|
||||
unsigned long bitmap = 0, bit = 1;
|
||||
int n_params = 0;
|
||||
bool overflowed = false;
|
||||
for (Parm *p = l; p; p = Getattr(p, "tmap:in:next")) {
|
||||
/* Ignored parameters */
|
||||
if ((overload || (!constructor && class_name)) && (Iterator == 0)) {
|
||||
|
|
@ -798,16 +813,34 @@ public:
|
|||
if (checkAttribute(p, "tmap:in:numinputs", "0")) {
|
||||
continue;
|
||||
}
|
||||
Append(arginfo_code, GetFlag(p, "tmap:in:byref") ? "1" : "0");
|
||||
++n_params;
|
||||
if (GetFlag(p, "tmap:in:byref")) {
|
||||
bitmap |= bit;
|
||||
if (bit == 0) overflowed = true;
|
||||
}
|
||||
bit <<= 1;
|
||||
}
|
||||
String * arginfo_code;
|
||||
if (overflowed) {
|
||||
// We overflowed the bitmap so just generate a unique name - this only
|
||||
// happens for a function with more parameters than bits in a long
|
||||
// where a high numbered parameter is passed by reference, so should be
|
||||
// rare in practice.
|
||||
static int overflowed_counter = 0;
|
||||
arginfo_code = NewStringf("z%d", ++overflowed_counter);
|
||||
} else if (bitmap == 0) {
|
||||
// No parameters passed by reference.
|
||||
arginfo_code = NewStringf("%d", n_params);
|
||||
} else {
|
||||
arginfo_code = NewStringf("%d_%lx", n_params, bitmap);
|
||||
}
|
||||
|
||||
int numberOfParams = Len(arginfo_code);
|
||||
if (!GetFlag(arginfo_used, arginfo_code)) {
|
||||
// Not had this one before, so emit it.
|
||||
// Not had this one before so emit it.
|
||||
SetFlag(arginfo_used, arginfo_code);
|
||||
Printf(s_arginfo, "ZEND_BEGIN_ARG_INFO_EX(swig_arginfo_%s, 0, 0, %d)\n", arginfo_code, numberOfParams);
|
||||
for (const char * p = Char(arginfo_code); *p; ++p) {
|
||||
Printf(s_arginfo, " ZEND_ARG_PASS_INFO(%c)\n", *p);
|
||||
Printf(s_arginfo, "ZEND_BEGIN_ARG_INFO_EX(swig_arginfo_%s, 0, 0, %d)\n", arginfo_code, n_params);
|
||||
for (Parm *p = l; p; p = Getattr(p, "tmap:in:next")) {
|
||||
Printf(s_arginfo, " ZEND_ARG_INFO(%d,%s)\n", GetFlag(p, "tmap:in:byref"), Getattr(p, "lname"));
|
||||
}
|
||||
Printf(s_arginfo, "ZEND_END_ARG_INFO()\n");
|
||||
}
|
||||
|
|
@ -1120,36 +1153,9 @@ public:
|
|||
baseClassExtend = NULL;
|
||||
}
|
||||
Wrapper *f = NewWrapper();
|
||||
// Need arg info set for __get magic function with one variable.
|
||||
String * arginfo_code = NewString("0");
|
||||
if (!GetFlag(arginfo_used, arginfo_code)) {
|
||||
// Not had this one before, so emit it.
|
||||
SetFlag(arginfo_used, arginfo_code);
|
||||
Printf(s_arginfo, "ZEND_BEGIN_ARG_INFO_EX(swig_arginfo_%s, 0, 0, 1)\n", arginfo_code);
|
||||
for (const char * p = Char(arginfo_code); *p; ++p) {
|
||||
Printf(s_arginfo, " ZEND_ARG_PASS_INFO(%c)\n", *p);
|
||||
}
|
||||
Printf(s_arginfo, "ZEND_END_ARG_INFO()\n");
|
||||
}
|
||||
|
||||
arginfo_code = NULL;
|
||||
|
||||
// Need arg info set for __set and __isset magic function with two variable.
|
||||
arginfo_code = NewString("00");
|
||||
if (!GetFlag(arginfo_used, arginfo_code)) {
|
||||
// Not had this one before, so emit it.
|
||||
SetFlag(arginfo_used, arginfo_code);
|
||||
Printf(s_arginfo, "ZEND_BEGIN_ARG_INFO_EX(swig_arginfo_%s, 0, 0, 2)\n", arginfo_code);
|
||||
for (const char * p = Char(arginfo_code); *p; ++p) {
|
||||
Printf(s_arginfo, " ZEND_ARG_PASS_INFO(%c)\n", *p);
|
||||
}
|
||||
Printf(s_arginfo, "ZEND_END_ARG_INFO()\n");
|
||||
}
|
||||
|
||||
arginfo_code = NULL;
|
||||
|
||||
Printf(f_h, "PHP_METHOD(%s,__set);\n", class_name);
|
||||
Printf(all_cs_entry, " PHP_ME(%s,__set,swig_arginfo_00,ZEND_ACC_PUBLIC)\n", class_name);
|
||||
Printf(all_cs_entry, " PHP_ME(%s,__set,swig_arginfo_2,ZEND_ACC_PUBLIC)\n", class_name);
|
||||
Printf(f->code, "PHP_METHOD(%s,__set) {\n",class_name);
|
||||
|
||||
Printf(f->code, " swig_object_wrapper *arg = (swig_object_wrapper *)SWIG_Z_FETCH_OBJ_P(getThis());\n");
|
||||
|
|
@ -1184,7 +1190,7 @@ public:
|
|||
|
||||
|
||||
Printf(f_h, "PHP_METHOD(%s,__get);\n", class_name);
|
||||
Printf(all_cs_entry, " PHP_ME(%s,__get,swig_arginfo_0,ZEND_ACC_PUBLIC)\n", class_name);
|
||||
Printf(all_cs_entry, " PHP_ME(%s,__get,swig_arginfo_1,ZEND_ACC_PUBLIC)\n", class_name);
|
||||
Printf(f->code, "PHP_METHOD(%s,__get) {\n",class_name);
|
||||
|
||||
Printf(f->code, " swig_object_wrapper *arg = (swig_object_wrapper *)SWIG_Z_FETCH_OBJ_P(getThis());\n", class_name);
|
||||
|
|
@ -1218,7 +1224,7 @@ public:
|
|||
|
||||
|
||||
Printf(f_h, "PHP_METHOD(%s,__isset);\n", class_name);
|
||||
Printf(all_cs_entry, " PHP_ME(%s,__isset,swig_arginfo_0,ZEND_ACC_PUBLIC)\n", class_name);
|
||||
Printf(all_cs_entry, " PHP_ME(%s,__isset,swig_arginfo_1,ZEND_ACC_PUBLIC)\n", class_name);
|
||||
Printf(f->code, "PHP_METHOD(%s,__isset) {\n",class_name);
|
||||
|
||||
Printf(f->code, " swig_object_wrapper *arg = (swig_object_wrapper *)SWIG_Z_FETCH_OBJ_P(getThis());\n", class_name);
|
||||
|
|
@ -1643,7 +1649,7 @@ public:
|
|||
/* Insert argument output code */
|
||||
bool hasargout = false;
|
||||
for (i = 0, p = l; p; i++) {
|
||||
if ((tm = Getattr(p, "tmap:argout"))) {
|
||||
if ((tm = Getattr(p, "tmap:argout")) && Len(tm)) {
|
||||
hasargout = true;
|
||||
Replaceall(tm, "$source", Getattr(p, "lname"));
|
||||
// Replaceall(tm,"$input",Getattr(p,"lname"));
|
||||
|
|
@ -1803,11 +1809,11 @@ public:
|
|||
if (constructor) {
|
||||
class_has_ctor = true;
|
||||
// Skip the Foo:: prefix.
|
||||
char *ptr = strrchr(GetChar(Swig_methodclass(n), "sym:name"), ':');
|
||||
char *ptr = strrchr(GetChar(current_class, "sym:name"), ':');
|
||||
if (ptr) {
|
||||
ptr++;
|
||||
} else {
|
||||
ptr = GetChar(Swig_methodclass(n), "sym:name");
|
||||
ptr = GetChar(current_class, "sym:name");
|
||||
}
|
||||
if (strcmp(ptr, GetChar(n, "constructorHandler:sym:name")) == 0) {
|
||||
methodname = "__construct";
|
||||
|
|
@ -1930,7 +1936,7 @@ public:
|
|||
/* FIXME: How should this be handled? The rest of SWIG just seems
|
||||
* to not bother checking for malloc failing! */
|
||||
fprintf(stderr, "Malloc failed!\n");
|
||||
exit(1);
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
}
|
||||
for (i = 0; i < max_num_of_arguments; ++i) {
|
||||
arg_names[i] = NULL;
|
||||
|
|
@ -1942,7 +1948,7 @@ public:
|
|||
/* FIXME: How should this be handled? The rest of SWIG just seems
|
||||
* to not bother checking for malloc failing! */
|
||||
fprintf(stderr, "Malloc failed!\n");
|
||||
exit(1);
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
}
|
||||
for (i = 0; i < max_num_of_arguments; ++i) {
|
||||
arg_values[i] = NULL;
|
||||
|
|
@ -2169,14 +2175,6 @@ public:
|
|||
/* We need $this to refer to the current class, so can't allow it
|
||||
* to be used as a parameter. */
|
||||
Setattr(seen, "this", seen);
|
||||
/* We use $r to store the return value, so disallow that as a parameter
|
||||
* name in case the user uses the "call-time pass-by-reference" feature
|
||||
* (it's deprecated and off by default in PHP5, but we want to be
|
||||
* maximally portable). Similarly we use $c for the classname or new
|
||||
* stdClass object.
|
||||
*/
|
||||
Setattr(seen, "r", seen);
|
||||
Setattr(seen, "c", seen);
|
||||
|
||||
for (int argno = 0; argno < max_num_of_arguments; ++argno) {
|
||||
String *&pname = arg_names[argno];
|
||||
|
|
@ -2224,7 +2222,7 @@ public:
|
|||
Replaceall(value, "$", "\\$");
|
||||
}
|
||||
Printf(args, "$%s=%s", arg_names[i], value);
|
||||
} else if (constructor && i >= 1 && i < min_num_of_arguments) {
|
||||
} else if (constructor && strcmp(methodname, "__construct") == 0 && i >= 1 && i < min_num_of_arguments) {
|
||||
// We need to be able to call __construct($resource).
|
||||
Printf(args, "$%s=null", arg_names[i]);
|
||||
} else {
|
||||
|
|
@ -2281,13 +2279,15 @@ public:
|
|||
Printf(prepare, "case %d: ", ++last_handled_i);
|
||||
}
|
||||
if (non_void_return) {
|
||||
if ((!directorsEnabled() || !Swig_directorclass(n)) && !newobject) {
|
||||
if (!constructor) {
|
||||
Append(prepare, "$r=");
|
||||
} else if (wrapperType == staticmemberfn || wrapperType == staticmembervar) {
|
||||
Append(prepare, "$r=");
|
||||
} else {
|
||||
Printf(prepare, "$this->%s=", SWIG_PTR);
|
||||
}
|
||||
}
|
||||
if (!directorsEnabled() || !Swig_directorclass(n) || !newobject) {
|
||||
if (!directorsEnabled() || !Swig_directorclass(n) || !constructor) {
|
||||
Printf(prepare, "%s(%s); break;\n", iname, invoke_args);
|
||||
} else if (!i) {
|
||||
Printf(prepare, "%s($_this%s); break;\n", iname, invoke_args);
|
||||
|
|
@ -2303,14 +2303,16 @@ public:
|
|||
if (had_a_case)
|
||||
Printf(prepare, "default: ");
|
||||
if (non_void_return) {
|
||||
if ((!directorsEnabled() || !Swig_directorclass(n)) && !newobject) {
|
||||
if (!constructor) {
|
||||
Append(prepare, "$r=");
|
||||
} else if (wrapperType == staticmemberfn || wrapperType == staticmembervar) {
|
||||
Append(prepare, "$r=");
|
||||
} else {
|
||||
Printf(prepare, "$this->%s=", SWIG_PTR);
|
||||
}
|
||||
}
|
||||
|
||||
if (!directorsEnabled() || !Swig_directorclass(n) || !newobject) {
|
||||
if (!directorsEnabled() || !Swig_directorclass(n) || !constructor) {
|
||||
Printf(prepare, "%s(%s);\n", iname, invoke_args);
|
||||
} else {
|
||||
Printf(prepare, "%s($_this, %s);\n", iname, invoke_args);
|
||||
|
|
@ -2378,20 +2380,33 @@ public:
|
|||
}
|
||||
|
||||
if (constructor) {
|
||||
const char * arg0;
|
||||
// Discriminate between the PHP constructor and a C++ constructor
|
||||
// renamed to become a factory function in PHP.
|
||||
bool php_constructor = (strcmp(methodname, "__construct") == 0);
|
||||
const char * arg0 = NULL;
|
||||
if (max_num_of_arguments > 0) {
|
||||
arg0 = Char(arg_names[0]);
|
||||
} else {
|
||||
} else if (php_constructor) {
|
||||
// The PHP constructor needs to be able to wrap a resource, but a
|
||||
// renamed constructor doesn't.
|
||||
arg0 = "res";
|
||||
Delete(args);
|
||||
args = NewString("$res=null");
|
||||
}
|
||||
String *mangled_type = SwigType_manglestr(Getattr(n, "type"));
|
||||
if (!php_constructor) {
|
||||
// A renamed constructor should be a static method.
|
||||
Append(acc, "static ");
|
||||
}
|
||||
Printf(output, "\t%sfunction %s(%s) {\n", acc, methodname, args);
|
||||
Printf(output, "\t\tif (is_resource($%s) && get_resource_type($%s) === '%s') {\n", arg0, arg0, mangled_type);
|
||||
Printf(output, "\t\t\t$this->%s=$%s;\n", SWIG_PTR, arg0);
|
||||
Printf(output, "\t\t\treturn;\n");
|
||||
Printf(output, "\t\t}\n");
|
||||
if (php_constructor) {
|
||||
// The PHP constructor needs to be able to wrap a resource, but a
|
||||
// renamed constructor doesn't.
|
||||
Printf(output, "\t\tif (is_resource($%s) && get_resource_type($%s) === '%s') {\n", arg0, arg0, mangled_type);
|
||||
Printf(output, "\t\t\t$this->%s=$%s;\n", SWIG_PTR, arg0);
|
||||
Printf(output, "\t\t\treturn;\n");
|
||||
Printf(output, "\t\t}\n");
|
||||
}
|
||||
} else {
|
||||
Printf(output, "\t%sfunction %s(%s) {\n", acc, methodname, args);
|
||||
}
|
||||
|
|
@ -2420,7 +2435,7 @@ public:
|
|||
Printf(output, "\tstatic function %s(%s) {\n", methodname, args);
|
||||
}
|
||||
|
||||
if (!newobject)
|
||||
if (!constructor)
|
||||
Printf(output, "%s", prepare);
|
||||
if (constructor) {
|
||||
if (!directorsEnabled() || !Swig_directorclass(n)) {
|
||||
|
|
@ -2714,7 +2729,7 @@ done:
|
|||
String *type = Getattr(n, "name");
|
||||
String *value = Getattr(n, "value");
|
||||
|
||||
if (Strcmp(lang, "php") == 0 || Strcmp(lang, "php4") == 0) {
|
||||
if (Strcmp(lang, "php") == 0) {
|
||||
if (Strcmp(type, "code") == 0) {
|
||||
if (value) {
|
||||
Printf(pragma_code, "%s\n", value);
|
||||
|
|
@ -2990,7 +3005,6 @@ done:
|
|||
}
|
||||
Printf(s_phpclasses, "\t}\n");
|
||||
|
||||
/* Create __isset for PHP 5.1 and later; PHP 5.0 will just ignore it. */
|
||||
/* __isset() should return true for read-only properties, so check for
|
||||
* *_get() not *_set(). */
|
||||
Printf(s_phpclasses, "\n\tfunction __isset($var) {\n");
|
||||
|
|
@ -3277,7 +3291,7 @@ done:
|
|||
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);
|
||||
Append(w->def, "}");
|
||||
|
|
@ -3289,7 +3303,7 @@ done:
|
|||
|
||||
/* 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);
|
||||
}
|
||||
|
|
@ -3333,12 +3347,12 @@ done:
|
|||
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);
|
||||
|
||||
|
|
@ -3417,7 +3431,7 @@ done:
|
|||
|
||||
/* 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);
|
||||
|
||||
Parm *p;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
1642
Source/Modules/r.cxx
1642
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);
|
||||
|
|
@ -2201,6 +2191,12 @@ public:
|
|||
String *tm;
|
||||
String *getfname, *setfname;
|
||||
Wrapper *getf, *setf;
|
||||
const int assignable = is_assignable(n);
|
||||
|
||||
// Determine whether virtual global variables shall be used
|
||||
// which have different getter and setter signatures,
|
||||
// see https://docs.ruby-lang.org/en/2.6.0/extension_rdoc.html#label-Global+Variables+Shared+Between+C+and+Ruby
|
||||
const bool use_virtual_var = (current == NO_CPP && useGlobalModule);
|
||||
|
||||
getf = NewWrapper();
|
||||
setf = NewWrapper();
|
||||
|
|
@ -2211,7 +2207,7 @@ public:
|
|||
getfname = Swig_name_wrapper(getname);
|
||||
Setattr(n, "wrap:name", getfname);
|
||||
Printv(getf->def, "SWIGINTERN VALUE\n", getfname, "(", NIL);
|
||||
Printf(getf->def, "VALUE self");
|
||||
Printf(getf->def, (use_virtual_var) ? "ID id, VALUE *data" : "VALUE self");
|
||||
Printf(getf->def, ") {");
|
||||
Wrapper_add_local(getf, "_val", "VALUE _val");
|
||||
|
||||
|
|
@ -2234,8 +2230,8 @@ public:
|
|||
|
||||
Wrapper_print(getf, f_wrappers);
|
||||
|
||||
if (!is_assignable(n)) {
|
||||
setfname = NewString("NULL");
|
||||
if (!assignable) {
|
||||
setfname = NewString("(rb_gvar_setter_t *)NULL");
|
||||
} else {
|
||||
/* create setter */
|
||||
String* docs = docstring(n, AUTODOC_SETTER);
|
||||
|
|
@ -2245,8 +2241,12 @@ public:
|
|||
String *setname = Swig_name_set(NSPACE_TODO, iname);
|
||||
setfname = Swig_name_wrapper(setname);
|
||||
Setattr(n, "wrap:name", setfname);
|
||||
Printv(setf->def, "SWIGINTERN VALUE\n", setfname, "(VALUE self, ", NIL);
|
||||
Printf(setf->def, "VALUE _val) {");
|
||||
Printf(setf->def, "SWIGINTERN ");
|
||||
if (use_virtual_var) {
|
||||
Printv(setf->def, "void\n", setfname, "(VALUE _val, ID id, VALUE *data) {", NIL);
|
||||
} else {
|
||||
Printv(setf->def, "VALUE\n", setfname, "(VALUE self, VALUE _val) {", NIL);
|
||||
}
|
||||
tm = Swig_typemap_lookup("varin", n, name, 0);
|
||||
if (tm) {
|
||||
Replaceall(tm, "$input", "_val");
|
||||
|
|
@ -2257,28 +2257,31 @@ public:
|
|||
} else {
|
||||
Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s\n", SwigType_str(t, 0));
|
||||
}
|
||||
Printv(setf->code, tab4, "return _val;\n", NIL);
|
||||
Printf(setf->code, "fail:\n");
|
||||
Printv(setf->code, tab4, "return Qnil;\n", NIL);
|
||||
if (use_virtual_var) {
|
||||
Printf(setf->code, "fail:\n");
|
||||
Printv(setf->code, tab4, "return;\n", NIL);
|
||||
} else {
|
||||
Printv(setf->code, tab4, "return _val;\n", NIL);
|
||||
Printf(setf->code, "fail:\n");
|
||||
Printv(setf->code, tab4, "return Qnil;\n", NIL);
|
||||
}
|
||||
Printf(setf->code, "}\n");
|
||||
Wrapper_print(setf, f_wrappers);
|
||||
Delete(setname);
|
||||
}
|
||||
|
||||
/* define accessor method */
|
||||
if (CPlusPlus) {
|
||||
Insert(getfname, 0, "VALUEFUNC(");
|
||||
Append(getfname, ")");
|
||||
Insert(setfname, 0, "VALUEFUNC(");
|
||||
Append(setfname, ")");
|
||||
}
|
||||
/* define accessor methods */
|
||||
Insert(getfname, 0, "VALUEFUNC(");
|
||||
Append(getfname, ")");
|
||||
Insert(setfname, 0, (use_virtual_var) ? "SWIG_RUBY_VOID_ANYARGS_FUNC(" : "VALUEFUNC(");
|
||||
Append(setfname, ")");
|
||||
|
||||
String *s = NewString("");
|
||||
switch (current) {
|
||||
case STATIC_VAR:
|
||||
/* C++ class variable */
|
||||
Printv(s, tab4, "rb_define_singleton_method(", klass->vname, ", \"", klass->strip(iname), "\", ", getfname, ", 0);\n", NIL);
|
||||
if (!GetFlag(n, "feature:immutable")) {
|
||||
if (assignable) {
|
||||
Printv(s, tab4, "rb_define_singleton_method(", klass->vname, ", \"", klass->strip(iname), "=\", ", setfname, ", 1);\n", NIL);
|
||||
}
|
||||
Printv(klass->init, s, NIL);
|
||||
|
|
@ -2289,14 +2292,11 @@ public:
|
|||
assert(current == NO_CPP);
|
||||
if (!useGlobalModule) {
|
||||
Printv(s, tab4, "rb_define_singleton_method(", modvar, ", \"", iname, "\", ", getfname, ", 0);\n", NIL);
|
||||
if (!GetFlag(n, "feature:immutable")) {
|
||||
if (assignable) {
|
||||
Printv(s, tab4, "rb_define_singleton_method(", modvar, ", \"", iname, "=\", ", setfname, ", 1);\n", NIL);
|
||||
}
|
||||
} else {
|
||||
Printv(s, tab4, "rb_define_global_method(\"", iname, "\", ", getfname, ", 0);\n", NIL);
|
||||
if (!GetFlag(n, "feature:immutable")) {
|
||||
Printv(s, tab4, "rb_define_global_method(\"", iname, "=\", ", setfname, ", 1);\n", NIL);
|
||||
}
|
||||
Printv(s, tab4, "rb_define_virtual_variable(\"$", iname, "\", ", getfname, ", ", setfname, ");\n", NIL);
|
||||
}
|
||||
Printv(f_init, s, NIL);
|
||||
Delete(s);
|
||||
|
|
@ -2925,7 +2925,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);
|
||||
|
|
@ -2936,7 +2936,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);
|
||||
}
|
||||
|
|
@ -3046,7 +3046,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");
|
||||
}
|
||||
|
|
@ -3102,12 +3102,12 @@ 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);
|
||||
|
||||
|
|
@ -3188,7 +3188,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];
|
||||
|
|
|
|||
|
|
@ -496,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 */
|
||||
|
|
|
|||
|
|
@ -26,79 +26,62 @@
|
|||
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_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_php5(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_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"},
|
||||
{"-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_php5, 0},
|
||||
{"-php4", swig_php4, 0},
|
||||
{"-php5", swig_php5, "PHP5"},
|
||||
{"-php7", swig_php, "PHP7"},
|
||||
{"-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},
|
||||
{"-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 +89,6 @@ static swig_module modules[] = {
|
|||
#include <SIOUX.h>
|
||||
#endif
|
||||
|
||||
#ifndef SWIG_LANG
|
||||
#define SWIG_LANG "-python"
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
// main()
|
||||
//
|
||||
|
|
@ -119,13 +98,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 +127,140 @@ 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"))) {
|
||||
int ci;
|
||||
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 ((ci = fgetc(f)) != EOF) {
|
||||
const char c = static_cast<char>(ci);
|
||||
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 +268,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,10 +354,23 @@ 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} */
|
||||
void SWIG_config_file(const_String_or_char_ptr );
|
||||
const String *SWIG_output_directory();
|
||||
void SWIG_config_cppext(const char *ext);
|
||||
|
|
@ -368,15 +382,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 +399,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);
|
||||
|
|
|
|||
|
|
@ -267,6 +267,8 @@ class TypePass:private Dispatcher {
|
|||
and smart pointer to base class, so that smart pointer upcasts
|
||||
are automatically generated. */
|
||||
SwigType *bsmart = Copy(smart);
|
||||
|
||||
// TODO: SwigType_typedef_resolve_all on a String instead of SwigType is incorrect for templates
|
||||
SwigType *rclsname = SwigType_typedef_resolve_all(clsname);
|
||||
SwigType *rbname = SwigType_typedef_resolve_all(bname);
|
||||
int replace_count = Replaceall(bsmart, rclsname, rbname);
|
||||
|
|
@ -276,6 +278,12 @@ class TypePass:private Dispatcher {
|
|||
String *firstname = Getattr(first, "name");
|
||||
Replaceall(bsmart, firstname, rbname);
|
||||
}
|
||||
// The code above currently creates a smartptr of the base class by substitution, replacing Derived
|
||||
// with Base resulting in something like: 'smartptr< Derived >' from 'smartptr< Base >'. Instead
|
||||
// the feature:smartptr should be used as it also contains 'smartptr< Base >' as specified by the user.
|
||||
// A similar fix should also be done in upcastsCode in java.cxx, csharp.cxx and writeClassUpcast in d.cxx.
|
||||
// Printf(stdout, "smartcomparison %s <=> %s\n", SwigType_namestr(bsmart), Getattr(bclass, "feature:smartptr"));
|
||||
|
||||
Delete(rclsname);
|
||||
Delete(rbname);
|
||||
String *smartnamestr = SwigType_namestr(smart);
|
||||
|
|
@ -961,7 +969,7 @@ class TypePass:private Dispatcher {
|
|||
if (Getattr(c, "sym:overloaded") != checkoverloaded) {
|
||||
Printf(stdout, "sym:overloaded error c:%p checkoverloaded:%p\n", c, checkoverloaded);
|
||||
Swig_print_node(c);
|
||||
exit (1);
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
String *decl = Strcmp(nodeType(c), "using") == 0 ? NewString("------") : Getattr(c, "decl");
|
||||
|
|
@ -969,7 +977,7 @@ class TypePass:private Dispatcher {
|
|||
if (!Getattr(c, "sym:overloaded")) {
|
||||
Printf(stdout, "sym:overloaded error.....%p\n", c);
|
||||
Swig_print_node(c);
|
||||
exit (1);
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
}
|
||||
c = Getattr(c, "sym:nextSibling");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -610,6 +623,7 @@ static List *find_args(String *s, int ismacro, String *macro_name) {
|
|||
} 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 == '*') {
|
||||
|
|
@ -621,6 +635,16 @@ static List *find_args(String *s, int ismacro, String *macro_name) {
|
|||
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 = '/';
|
||||
|
|
@ -640,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);
|
||||
|
|
@ -817,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);
|
||||
|
|
@ -830,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);
|
||||
}
|
||||
|
|
@ -922,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1156,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;
|
||||
}
|
||||
|
|
@ -1448,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') {
|
||||
|
|
@ -1467,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);
|
||||
|
|
@ -1787,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;
|
||||
|
|
|
|||
|
|
@ -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,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;
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
* sure there are no unmarked options.
|
||||
*
|
||||
* TODO:
|
||||
* - This module needs to be modified so that it doesn't call exit().
|
||||
* Should have cleaner error handling in general.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
|
|
@ -88,11 +87,11 @@ void Swig_check_options(int check_input) {
|
|||
}
|
||||
if (error) {
|
||||
Printf(stderr, "Use 'swig -help' for available options.\n");
|
||||
exit(1);
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
}
|
||||
if (check_input && marked[numargs - 1]) {
|
||||
Printf(stderr, "Must specify an input file. Use -help for available options.\n");
|
||||
exit(1);
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -105,5 +104,5 @@ void Swig_check_options(int check_input) {
|
|||
void Swig_arg_error(void) {
|
||||
Printf(stderr, "SWIG : Unable to parse command line options.\n");
|
||||
Printf(stderr, "Use 'swig -help' for available options.\n");
|
||||
exit(1);
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -249,6 +249,19 @@ String *Swig_filename_escape(String *filename) {
|
|||
return adjusted_filename;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_filename_escape()
|
||||
*
|
||||
* Escapes spaces in filename - for Makefiles
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
String *Swig_filename_escape_space(String *filename) {
|
||||
String *adjusted_filename = Copy(filename);
|
||||
Swig_filename_correct(adjusted_filename);
|
||||
Replaceall(adjusted_filename, " ", "\\ ");
|
||||
return adjusted_filename;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_filename_unescape()
|
||||
*
|
||||
|
|
@ -523,7 +536,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
|
||||
|
|
@ -1177,7 +1190,7 @@ String *Swig_string_command(String *s) {
|
|||
pclose(fp);
|
||||
} else {
|
||||
Swig_error("SWIG", Getline(s), "Command encoder fails attempting '%s'.\n", s);
|
||||
exit(1);
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1327,7 +1340,8 @@ static int split_regex_pattern_subst(String *s, String **pattern, String **subst
|
|||
|
||||
err_out:
|
||||
Swig_error("SWIG", Getline(s), "Invalid regex substitution: '%s'.\n", s);
|
||||
exit(1);
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This function copies len characters from src to dst, possibly applying case conversions to them: if convertCase is 1, to upper case and if it is -1, to lower
|
||||
|
|
@ -1449,7 +1463,7 @@ String *Swig_string_regex(String *s) {
|
|||
if (!compiled_pat) {
|
||||
Swig_error("SWIG", Getline(s), "PCRE compilation failed: '%s' in '%s':%i.\n",
|
||||
pcre_error, Char(pattern), pcre_errorpos);
|
||||
exit(1);
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
}
|
||||
rc = pcre_exec(compiled_pat, NULL, input, (int)strlen(input), 0, 0, captures, 30);
|
||||
if (rc >= 0) {
|
||||
|
|
@ -1457,7 +1471,7 @@ String *Swig_string_regex(String *s) {
|
|||
} else if (rc != PCRE_ERROR_NOMATCH) {
|
||||
Swig_error("SWIG", Getline(s), "PCRE execution failed: error %d while matching \"%s\" using \"%s\".\n",
|
||||
rc, Char(pattern), input);
|
||||
exit(1);
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1475,7 +1489,8 @@ String *Swig_pcre_version(void) {
|
|||
|
||||
String *Swig_string_regex(String *s) {
|
||||
Swig_error("SWIG", Getline(s), "PCRE regex support not enabled in this SWIG build.\n");
|
||||
exit(1);
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
String *Swig_pcre_version(void) {
|
||||
|
|
@ -1484,6 +1499,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()
|
||||
*
|
||||
|
|
|
|||
|
|
@ -439,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);
|
||||
|
|
@ -579,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);
|
||||
|
|
@ -1055,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 {
|
||||
|
|
@ -1105,7 +1105,7 @@ static int name_regexmatch_value(Node *n, String *pattern, String *s) {
|
|||
Swig_error("SWIG", Getline(n),
|
||||
"Invalid regex \"%s\": compilation failed at %d: %s\n",
|
||||
Char(pattern), errpos, err);
|
||||
exit(1);
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
rc = pcre_exec(compiled_pat, NULL, Char(s), Len(s), 0, 0, NULL, 0);
|
||||
|
|
@ -1118,7 +1118,7 @@ static int name_regexmatch_value(Node *n, String *pattern, String *s) {
|
|||
Swig_error("SWIG", Getline(n),
|
||||
"Matching \"%s\" against regex \"%s\" failed: %d\n",
|
||||
Char(s), Char(pattern), rc);
|
||||
exit(1);
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
|
@ -1131,7 +1131,8 @@ static int name_regexmatch_value(Node *n, String *pattern, String *s) {
|
|||
(void)s;
|
||||
Swig_error("SWIG", Getline(n),
|
||||
"PCRE regex matching is not available in this SWIG build.\n");
|
||||
exit(1);
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* HAVE_PCRE/!HAVE_PCRE */
|
||||
|
|
@ -1377,12 +1378,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) {
|
||||
|
|
@ -1431,8 +1435,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);
|
||||
|
|
@ -1480,7 +1484,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 */
|
||||
|
|
@ -1504,13 +1508,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);
|
||||
}
|
||||
|
|
@ -1650,12 +1660,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;
|
||||
}
|
||||
|
|
@ -1681,6 +1692,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"
|
||||
*
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
|
@ -1690,11 +1702,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,14 @@ 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;
|
||||
|
|
@ -830,7 +833,7 @@ static int look(Scanner *s) {
|
|||
return SWIG_TOKEN_MODEQUAL;
|
||||
} else if (c == '}') {
|
||||
Swig_error(cparse_file, cparse_line, "Syntax error. Extraneous '%%}'\n");
|
||||
exit(1);
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
} else {
|
||||
retract(s, 1);
|
||||
return SWIG_TOKEN_PERCENT;
|
||||
|
|
@ -935,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 {
|
||||
|
|
@ -958,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;
|
||||
}
|
||||
|
|
@ -966,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 */
|
||||
}
|
||||
|
|
@ -1118,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:
|
||||
|
|
@ -1147,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')) {
|
||||
|
|
@ -1166,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')) {
|
||||
|
|
@ -1181,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')) {
|
||||
|
|
@ -1190,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,7 +44,7 @@
|
|||
* '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)
|
||||
* '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.
|
||||
|
|
@ -64,11 +64,19 @@
|
|||
*
|
||||
* More examples:
|
||||
*
|
||||
* String Encoding C++ Example
|
||||
* --------------- -----------
|
||||
* p.f(bool).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)
|
||||
* 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
|
||||
|
|
@ -126,7 +134,7 @@ SwigType *NewSwigType(int t) {
|
|||
return NewString("double");
|
||||
break;
|
||||
case T_COMPLEX:
|
||||
return NewString("complex");
|
||||
return NewString("_Complex");
|
||||
break;
|
||||
case T_CHAR:
|
||||
return NewString("char");
|
||||
|
|
@ -536,10 +544,9 @@ String *SwigType_str(const SwigType *s, const_String_or_char_ptr id) {
|
|||
String *element = 0;
|
||||
String *nextelement;
|
||||
String *forwardelement;
|
||||
String *member_const_function_element = 0;
|
||||
SwigType *member_function_qualifiers = 0;
|
||||
List *elements;
|
||||
int nelements, i;
|
||||
int member_const_function = 0;
|
||||
|
||||
if (id) {
|
||||
/* stringify the id expanding templates, for example when the id is a fully qualified templated class name */
|
||||
|
|
@ -570,14 +577,12 @@ String *SwigType_str(const SwigType *s, const_String_or_char_ptr id) {
|
|||
forwardelement = 0;
|
||||
}
|
||||
if (SwigType_isqualifier(element)) {
|
||||
if (!member_const_function) {
|
||||
if (!member_function_qualifiers) {
|
||||
DOH *q = 0;
|
||||
q = SwigType_parm(element);
|
||||
Insert(result, 0, " ");
|
||||
Insert(result, 0, q);
|
||||
Delete(q);
|
||||
} else {
|
||||
member_const_function = 0;
|
||||
}
|
||||
} else if (SwigType_ispointer(element)) {
|
||||
Insert(result, 0, "*");
|
||||
|
|
@ -594,20 +599,28 @@ String *SwigType_str(const SwigType *s, const_String_or_char_ptr id) {
|
|||
Insert(result, 0, "(");
|
||||
Append(result, ")");
|
||||
}
|
||||
if (SwigType_isqualifier(nextelement)) {
|
||||
member_const_function_element = nextelement;
|
||||
member_const_function = 1;
|
||||
{
|
||||
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, ")");
|
||||
}
|
||||
|
|
@ -631,12 +644,13 @@ String *SwigType_str(const SwigType *s, const_String_or_char_ptr id) {
|
|||
Append(result, ",");
|
||||
}
|
||||
Append(result, ")");
|
||||
if (member_const_function_element) {
|
||||
String *p = SwigType_str(member_const_function_element, 0);
|
||||
if (member_function_qualifiers) {
|
||||
String *p = SwigType_str(member_function_qualifiers, 0);
|
||||
Append(result, " ");
|
||||
Append(result, p);
|
||||
Delete(p);
|
||||
member_const_function_element = 0;
|
||||
Delete(member_function_qualifiers);
|
||||
member_function_qualifiers = 0;
|
||||
}
|
||||
Delete(parms);
|
||||
} else {
|
||||
|
|
@ -670,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);
|
||||
|
|
@ -696,6 +711,7 @@ SwigType *SwigType_ltype(const SwigType *s) {
|
|||
tc = td;
|
||||
}
|
||||
}
|
||||
|
||||
elements = SwigType_split(tc);
|
||||
nelements = Len(elements);
|
||||
|
||||
|
|
@ -705,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) {
|
||||
|
|
@ -752,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.
|
||||
|
|
@ -788,7 +824,7 @@ String *SwigType_rcaststr(const SwigType *s, const_String_or_char_ptr name) {
|
|||
String *element = 0;
|
||||
String *nextelement;
|
||||
String *forwardelement;
|
||||
String *member_const_function_element = 0;
|
||||
String *member_function_qualifiers = 0;
|
||||
SwigType *td, *tc = 0;
|
||||
const SwigType *rs;
|
||||
List *elements;
|
||||
|
|
@ -797,7 +833,6 @@ String *SwigType_rcaststr(const SwigType *s, const_String_or_char_ptr name) {
|
|||
int firstarray = 1;
|
||||
int isreference = 0;
|
||||
int isfunction = 0;
|
||||
int member_const_function = 0;
|
||||
|
||||
result = NewStringEmpty();
|
||||
|
||||
|
|
@ -846,15 +881,13 @@ String *SwigType_rcaststr(const SwigType *s, const_String_or_char_ptr name) {
|
|||
forwardelement = 0;
|
||||
}
|
||||
if (SwigType_isqualifier(element)) {
|
||||
if (!member_const_function) {
|
||||
if (!member_function_qualifiers) {
|
||||
DOH *q = 0;
|
||||
q = SwigType_parm(element);
|
||||
Insert(result, 0, " ");
|
||||
Insert(result, 0, q);
|
||||
Delete(q);
|
||||
clear = 0;
|
||||
} else {
|
||||
member_const_function = 0;
|
||||
}
|
||||
} else if (SwigType_ispointer(element)) {
|
||||
Insert(result, 0, "*");
|
||||
|
|
@ -868,32 +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, ")");
|
||||
}
|
||||
if (SwigType_isqualifier(nextelement)) {
|
||||
member_const_function_element = nextelement;
|
||||
member_const_function = 1;
|
||||
{
|
||||
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;
|
||||
|
|
@ -923,12 +966,13 @@ String *SwigType_rcaststr(const SwigType *s, const_String_or_char_ptr name) {
|
|||
}
|
||||
Append(result, ")");
|
||||
Delete(parms);
|
||||
if (member_const_function_element) {
|
||||
String *p = SwigType_str(member_const_function_element, 0);
|
||||
if (member_function_qualifiers) {
|
||||
String *p = SwigType_str(member_function_qualifiers, 0);
|
||||
Append(result, " ");
|
||||
Append(result, p);
|
||||
Delete(p);
|
||||
member_const_function_element = 0;
|
||||
Delete(member_function_qualifiers);
|
||||
member_function_qualifiers = 0;
|
||||
clear = 0;
|
||||
}
|
||||
isfunction = 1;
|
||||
|
|
@ -1247,11 +1291,29 @@ void SwigType_typename_replace(SwigType *t, String *pat, String *rep) {
|
|||
Replace(e, pat, rep, DOH_REPLACE_ANY);
|
||||
} else if (SwigType_istemplate(e)) {
|
||||
/* Replaces a type of the form 'pat<args>' with 'rep' */
|
||||
if (Equal(e, pat)) {
|
||||
String *repbase = SwigType_templateprefix(rep);
|
||||
Replace(e, pat, repbase, DOH_REPLACE_ID | DOH_REPLACE_FIRST);
|
||||
Delete(repbase);
|
||||
{
|
||||
/* To match "e=TemplateTemplateT<(float)>"
|
||||
* with "pat=TemplateTemplateT"
|
||||
* we need to compare only the first part of the string e.
|
||||
*/
|
||||
int len = Len(pat);
|
||||
|
||||
/* Len(e) > len, not >= (because we expect at least a
|
||||
* character '<' following the template typename)
|
||||
*/
|
||||
if (Len(e) > len) {
|
||||
String *firstPartOfType = NewStringWithSize(e, len);
|
||||
const char* e_as_char = Char(e);
|
||||
|
||||
if (Equal(firstPartOfType, pat) && e_as_char[len] == '<') {
|
||||
String *repbase = SwigType_templateprefix(rep);
|
||||
Replace(e, pat, repbase, DOH_REPLACE_ID | DOH_REPLACE_FIRST);
|
||||
Delete(repbase);
|
||||
}
|
||||
Delete(firstPartOfType);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
String *tsuffix;
|
||||
List *tparms = SwigType_parmlist(e);
|
||||
|
|
@ -1266,6 +1328,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);
|
||||
|
|
@ -1274,13 +1337,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);
|
||||
|
|
@ -314,6 +315,7 @@ extern int ParmList_is_compactdefargs(ParmList *p);
|
|||
extern String *Swig_new_subdirectory(String *basedirectory, String *subdirectory);
|
||||
extern void Swig_filename_correct(String *filename);
|
||||
extern String *Swig_filename_escape(String *filename);
|
||||
extern String *Swig_filename_escape_space(String *filename);
|
||||
extern void Swig_filename_unescape(String *filename);
|
||||
extern int Swig_storage_isextern(Node *n);
|
||||
extern int Swig_storage_isexternc(Node *n);
|
||||
|
|
@ -334,7 +336,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;
|
||||
|
||||
|
|
@ -435,6 +439,7 @@ extern int ParmList_is_compactdefargs(ParmList *p);
|
|||
extern void Language_replace_special_variables(String *method, String *tm, Parm *parm);
|
||||
extern void Swig_print(DOH *object, int count);
|
||||
extern void Swig_print_with_location(DOH *object, int count);
|
||||
extern void SWIG_exit(int exit_code);
|
||||
|
||||
|
||||
/* -- template init -- */
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
@ -690,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;
|
||||
|
|
@ -756,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 */
|
||||
|
|
@ -777,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"))
|
||||
|
|
@ -857,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");
|
||||
|
|
@ -1010,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);
|
||||
|
|
|
|||
|
|
@ -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 = "";
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
@ -403,6 +404,7 @@ SwigType *SwigType_del_reference(SwigType *t) {
|
|||
char *c = Char(t);
|
||||
int check = strncmp(c, "r.", 2);
|
||||
assert(check == 0);
|
||||
(void)check;
|
||||
Delslice(t, 0, 2);
|
||||
return t;
|
||||
}
|
||||
|
|
@ -438,6 +440,7 @@ SwigType *SwigType_del_rvalue_reference(SwigType *t) {
|
|||
char *c = Char(t);
|
||||
int check = strncmp(c, "z.", 2);
|
||||
assert(check == 0);
|
||||
(void)check;
|
||||
Delslice(t, 0, 2);
|
||||
return t;
|
||||
}
|
||||
|
|
@ -528,6 +531,7 @@ SwigType *SwigType_del_qualifier(SwigType *t) {
|
|||
char *c = Char(t);
|
||||
int check = strncmp(c, "q(", 2);
|
||||
assert(check == 0);
|
||||
(void)check;
|
||||
Delslice(t, 0, element_size(c));
|
||||
return t;
|
||||
}
|
||||
|
|
@ -596,6 +600,7 @@ SwigType *SwigType_del_memberpointer(SwigType *t) {
|
|||
char *c = Char(t);
|
||||
int check = strncmp(c, "m(", 2);
|
||||
assert(check == 0);
|
||||
(void)check;
|
||||
Delslice(t, 0, element_size(c));
|
||||
return t;
|
||||
}
|
||||
|
|
@ -640,6 +645,7 @@ SwigType *SwigType_del_array(SwigType *t) {
|
|||
char *c = Char(t);
|
||||
int check = strncmp(c, "a(", 2);
|
||||
assert(check == 0);
|
||||
(void)check;
|
||||
Delslice(t, 0, element_size(c));
|
||||
return t;
|
||||
}
|
||||
|
|
@ -771,7 +777,6 @@ SwigType *SwigType_array_type(const SwigType *ty) {
|
|||
* Functions
|
||||
*
|
||||
* SwigType_add_function()
|
||||
* SwigType_del_function()
|
||||
* SwigType_isfunction()
|
||||
* SwigType_pop_function()
|
||||
*
|
||||
|
|
@ -795,14 +800,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 +841,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++;
|
||||
|
|
|
|||
|
|
@ -570,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)) {
|
||||
|
|
@ -839,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;
|
||||
|
|
@ -1455,11 +1453,11 @@ int SwigType_type(const SwigType *t) {
|
|||
return T_DOUBLE;
|
||||
if (strcmp(c, "long double") == 0)
|
||||
return T_LONGDOUBLE;
|
||||
if (!cparse_cplusplus && (strcmp(c, "float complex") == 0))
|
||||
if (!cparse_cplusplus && (strcmp(c, "float _Complex") == 0))
|
||||
return T_FLTCPLX;
|
||||
if (!cparse_cplusplus && (strcmp(c, "double complex") == 0))
|
||||
if (!cparse_cplusplus && (strcmp(c, "double _Complex") == 0))
|
||||
return T_DBLCPLX;
|
||||
if (!cparse_cplusplus && (strcmp(c, "complex") == 0))
|
||||
if (!cparse_cplusplus && (strcmp(c, "_Complex") == 0))
|
||||
return T_COMPLEX;
|
||||
if (strcmp(c, "void") == 0)
|
||||
return T_VOID;
|
||||
|
|
@ -1542,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