fixes and docs in %rename

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@8160 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Marcelo Matus 2006-01-01 11:01:12 +00:00
commit dfd35441ec
7 changed files with 586 additions and 319 deletions

View file

@ -15,42 +15,133 @@ Version 1.3.28 (unreleased).
Now, since the format is processed via swig Printf, you Now, since the format is processed via swig Printf, you
can use encoder as follows: can use encoder as follows:
%rename("%(title)s") import; -> Import %rename("%(title)s") import; -> Import
%rename("%(upper)s") import; -> IMPORT %rename("%(upper)s") import; -> IMPORT
%rename("%(lower)s") Import; -> import %rename("%(lower)s") Import; -> import
%rename("%(ctitle)s") camel_case; -> CamelCase
This will allow us to add more encoders, as the next
expected 'regexp'.
- In the meantime, add the 'command' encoder, you can use it as follows
%rename(%(command:sed -e 's/\([a-z]\)/\U\\1/' <<< %s)s) import; -> Import
where swig executes the command defined as %(command:<command here>)s.
Note that swig pass the name and the prefix as parameters
that can capture via '%s'. Another example
#define awk_cmd "%(command:awk '{if (NF==2) {print $2_$1} else {print _$1}}' <<< %s %s)s"
%rename(awk_cmd) ns1::import; -> ns1_import; This will allow us to add more encoders, as the
%rename(awk_cmd) import; -> _import expected one for regular expressions.
Just remember, first parameter is the name, the second is
the prefix. If you don't need the prefix, just put one '%s'
argument in your command.
Note that the 'command' encoder requires popen in your platform. - Add the above 'ctitle' encoder, which does the camel case:
- The rename directive has its first option 'match', to camel_case -> CamelCase
match the node type, for example:
- Also, while we get the regexp support, add the 'command' encoder,
you can use it as follows
%rename(%(title)s,match="enumitem") *; %rename("%(command:sed -e 's/\([a-z]\)/\U\\1/' <<< )s") import;
then swig will popen the command
"sed -e 's/\([a-z]\)/\U\\1/' <<< import"
see below for anonymous renames for better examples.
- The rename directive now also allows:
- simple match: only apply the rename if a type match
happen, for example
%rename(%(title)s,match="enumitem") hello;
enum Hello { enum Hello {
hi, hello -> Hi, Hello hi, hello -> hi, Hello
};
int hello() -> hello;
- extended match: only apply the rename if the 'extended attribute' match
occurred, for example:
// same as simple match
%rename(%(title)s,match$nodeType="enumitem") hello;
enum Hello {
hi, hello -> hi, Hello
};
Note that the symbol '$' is used to define the attribute name in
a 'recursive' way, for example:
// match only hello in 'enum Hello'
%rename(%(title)s,match$parentNode$type="enum Hello") hello;
enum Hello {
hi, hello -> hi, Hello // match
};
enum Hi {
hi, hello -> hi, hello // no match
};
here, for Hello::hi, the "parentNode" is "Hello", and its "type"
is "enum Hello".
- Anonymous renames: you can use 'anonymous' rename directives, for example:
// rename all the enum items in Hello
%rename(%(title)s,match$parentNode$type="enum Hello") "";
enum Hello {
hi, hello -> Hi, Hello // match both
};
enum Hi {
hi, hello -> hi, hello // no match
}; };
// rename all the enum items
%rename(%(title)s,match$nodeType="enumitem") "";
// rename all the items in given command (sloooow, but...)
%rename(%(command:<my external cmd>)s) "";
Anonymous renames with commands can be very powerful, since you
can 'outsource' all the renaming mechanism (or part of it) to an
external program:
// Uppercase all (and only) the names that start with 'i'
%rename("%(command:awk '/^i/{print toupper($1)}' <<<)s") "";
int imported() -> IMPORTED;
int hello() -> hello
Note that if the 'command' encoder returns an empty string, swig
understand that no rename is necessary.
Also note that %rename 'passes' the matched name. For example, in
this case
namespace ns1 {
int foo();
}
namespace ns2 {
int bar();
}
the external program only receives "foo" and "bar". If needed,
however, you can request the 'fullname'
%rename("%(command:awk 'awk '/ns1::/{l=split($1,a,"::"); print toupper(a[l])}'' <<<)s",fullname=1) "";
ns1::foo -> FOO
ns2::bar -> bar
- Mixing encoders and matching: of course, you can do mix commands
and match fields, for example:
%rename("%(<my encoder for fncs>)",match="cdecl") "";
%rename("%(<my encoder for enums>)",match="enumitem") "";
%rename("%(<my encoder for enums inside a class>)",match="enumitem",
match$parentNode$parentNode$nodeType="class") "";
Use "swig -dump_tree" to see the attributes names you can use to
match an specific case.
12/30/2005: mmatus 12/30/2005: mmatus
- Add initial support for gcj and Java -> <target language> mechanism. - Add initial support for gcj and Java -> <target language> mechanism.

View file

@ -1,18 +1,18 @@
%module rename_camel %module rename_camel
%define CamelCase "%(command:sed -e 's/\([a-z]\)/\U\\1/' -e 's/\(_\)\([a-z]\)/\U\\2/g' <<< %s)s" %enddef %define SedCmd "%(command:sed -e 's/\([a-z]\)/\U\\1/' -e 's/\(_\)\([a-z]\)/\U\\2/g' <<<)s" %enddef
%rename(CamelCase1) camel_case_1;
%rename(SedCmd) camel_case_2;
%rename("%(ctitle)s") camel_case_3;
%rename("CamelCase1") camel_case_1; %rename("%(title)s",match$parentNode$type="enum HelloEnum") "";
%rename("_%s") camel_case_2; %rename("%(ctitle)s",match$parentNode$type="enum ChaoEnum") "";
%rename("%(mangle)s") camel_case_3;
%rename("%(title)s") camel_case_4;
%rename(CamelCase) camel_case;
%rename(CamelCase) also_works_here;
%rename("%(title)s",match="enumitem") "*"; #define awk_cmd "%(command:awk '/^i/{print toupper($1)}' <<<)s"
%rename(awk_cmd) "";
%inline %inline
{ {
@ -24,8 +24,15 @@
int also_works_here(int); int also_works_here(int);
enum HelloEnum { enum HelloEnum {
hi, hello hello, hi_there
}; };
enum ChaoEnum {
bye, see_you
};
int import(int);
int foo(int);
} }

View file

@ -1,4 +1,7 @@
%{ %{
#if 0
} /* cc-mode */
#endif
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
* parser.y * parser.y
* *
@ -42,7 +45,7 @@ static Hash *extendhash = 0; /* Hash table of added methods */
static Hash *classes = 0; /* Hash table of classes */ static Hash *classes = 0; /* Hash table of classes */
static Symtab *prev_symtab = 0; static Symtab *prev_symtab = 0;
static Node *current_class = 0; static Node *current_class = 0;
String *ModuleName = 0; String *ModuleName = 0;
static Node *module_node = 0; static Node *module_node = 0;
static String *Classprefix = 0; static String *Classprefix = 0;
static String *Namespaceprefix = 0; static String *Namespaceprefix = 0;
@ -205,23 +208,37 @@ static Hash *rename_hash = 0;
static Hash *namewarn_hash = 0; static Hash *namewarn_hash = 0;
static Hash *features_hash = 0; static Hash *features_hash = 0;
static List *rename_list = 0;
static List *namewarn_list = 0;
static String *resolve_node_scope(String *cname); static String *resolve_node_scope(String *cname);
Hash *Swig_cparse_namewarn() { Hash *Swig_cparse_namewarn_hash() {
if (!namewarn_hash) namewarn_hash = NewHash(); if (!namewarn_hash) namewarn_hash = NewHash();
return namewarn_hash; return namewarn_hash;
} }
Hash *Swig_cparse_rename_hash() {
if (!rename_hash) rename_hash = NewHash();
return rename_hash;
}
Hash *Swig_cparse_features() { Hash *Swig_cparse_features() {
if (!features_hash) features_hash = NewHash(); if (!features_hash) features_hash = NewHash();
return features_hash; return features_hash;
} }
Hash *Swig_cparse_rename() { List *Swig_cparse_namewarn_list() {
if (!rename_hash) rename_hash = NewHash(); if (!namewarn_list) namewarn_list = NewList();
return rename_hash; return namewarn_list;
} }
List *Swig_cparse_rename_list() {
if (!rename_list) rename_list = NewList();
return rename_list;
}
static String *feature_identifier_fix(String *s) { static String *feature_identifier_fix(String *s) {
if (SwigType_istemplate(s)) { if (SwigType_istemplate(s)) {
String *tp, *ts, *ta, *tq; String *tp, *ts, *ta, *tq;
@ -240,44 +257,86 @@ static String *feature_identifier_fix(String *s) {
} }
} }
static void single_rename_add(const char *name, SwigType *decl, Hash *newname) { static void
String *nname; Swig_cparse_add_name_object(Hash *name_hash, List *name_list,
if (Namespaceprefix) { String *prefix, const char *name, SwigType *decl, Hash *nameobj) {
nname = NewStringf("%s::%s",Namespaceprefix, name); String *nname = 0;
} else {
nname = NewString(name); if (name && Len(name)) {
String *target_fmt = Getattr(nameobj,"target_fmt");
nname = prefix ? NewStringf("%s::%s",prefix, name) : NewString(name);
if (target_fmt) {
String *tmp = NewStringf(Getattr(nameobj,"target_fmt"), nname);
Delete(nname);
nname = tmp;
}
}
if (!nname || !Len(nname) || Getattr(nameobj,"source_fmt")) {
if (decl) Setattr(nameobj,"decl", decl);
if (nname && Len(nname)) Setattr(nameobj,"target_name", nname);
Append(name_list, nameobj);
} else {
Swig_name_object_set(name_hash,nname,decl,nameobj);
} }
Swig_name_object_set(Swig_cparse_rename(),nname,decl,newname);
Delete(nname); Delete(nname);
} }
static void single_rename_add(const char *name, SwigType *decl, Hash *newname) {
Swig_cparse_add_name_object(Swig_cparse_rename_hash(), Swig_cparse_rename_list(),
Namespaceprefix, name, decl, newname);
}
static void Swig_name_object_attach_keys(const char *keys[], Hash *nameobj)
{
Node *kw = nextSibling(nameobj);
while (kw) {
Node *next = nextSibling(kw);
String *kname = Getattr(kw,"name");
char *ckey = kname ? Char(kname) : 0;
if (ckey) {
const char **rkey;
for (rkey = keys; *rkey != 0; ++rkey) {
if (strcmp(ckey,*rkey) == 0) {
Setattr(nameobj, *rkey, Getattr(kw,"value"));
deleteNode(kw);
}
}
}
kw = next;
}
}
/* Add a new rename. Works much like new_feature including default argument handling. */ /* Add a new rename. Works much like new_feature including default argument handling. */
static void rename_add(const char *name, SwigType *decl, Hash *kwargs, ParmList *declaratorparms) { static void rename_add(const char *name, SwigType *decl, Hash *newname, ParmList *declaratorparms) {
ParmList *declparms = declaratorparms; ParmList *declparms = declaratorparms;
String *newname = kwargs; const char *rename_keys[] = {"fullname", "source_fmt", "target_fmt", 0};
Swig_name_object_attach_keys(rename_keys, newname);
/* Add the name */ /* Add the name */
single_rename_add(name, decl, newname); single_rename_add(name, decl, newname);
/* Add extra names if there are default parameters in the parameter list */ /* Add extra names if there are default parameters in the parameter list */
if (decl) { if (decl) {
int constqualifier = SwigType_isconst(decl); int constqualifier = SwigType_isconst(decl);
while (declparms) { while (declparms) {
if (ParmList_has_defaultargs(declparms)) { if (ParmList_has_defaultargs(declparms)) {
/* Create a parameter list for the new rename by copying all /* Create a parameter list for the new rename by copying all
but the last (defaulted) parameter */ but the last (defaulted) parameter */
ParmList* newparms = ParmList_copy_all_except_last_parm(declparms); ParmList* newparms = ParmList_copy_all_except_last_parm(declparms);
/* Create new declaration - with the last parameter removed */ /* Create new declaration - with the last parameter removed */
SwigType *newdecl = Copy(decl); SwigType *newdecl = Copy(decl);
Delete(SwigType_pop_function(newdecl)); /* remove the old parameter list from newdecl */ Delete(SwigType_pop_function(newdecl)); /* remove the old parameter list from newdecl */
SwigType_add_function(newdecl,newparms); SwigType_add_function(newdecl,newparms);
if (constqualifier) if (constqualifier)
SwigType_add_qualifier(newdecl,"const"); SwigType_add_qualifier(newdecl,"const");
single_rename_add(name, newdecl, newname); single_rename_add(name, newdecl, newname);
declparms = newparms; declparms = newparms;
Delete(newdecl); Delete(newdecl);
@ -288,22 +347,17 @@ static void rename_add(const char *name, SwigType *decl, Hash *kwargs, ParmList
} }
} }
static void namewarn_add(const char *name, SwigType *decl, Hash *warning) { static void namewarn_add(const char *name, SwigType *decl, Hash *namewrn) {
String *nname; const char *namewrn_keys[] = {"rename", "error", "fullname", "source_fmt", "target_fmt", 0};
if (Namespaceprefix) { Swig_name_object_attach_keys(namewrn_keys, namewrn);
nname = NewStringf("%s::%s",Namespaceprefix, name); Swig_cparse_add_name_object(Swig_cparse_namewarn_hash(), Swig_cparse_namewarn_list(),
} else { Namespaceprefix, name, decl, namewrn);
nname = NewString(name);
}
Swig_name_object_set(Swig_cparse_namewarn(),nname,decl,warning);
Delete(nname);
} }
static void rename_inherit(String *base, String *derived) { static void rename_inherit(String *base, String *derived) {
/* Printf(stdout,"base = '%s', derived = '%s'\n", base, derived); */ /* Printf(stdout,"base = '%s', derived = '%s'\n", base, derived); */
Swig_name_object_inherit(Swig_cparse_rename(),base,derived); Swig_name_object_inherit(Swig_cparse_rename_hash(),base,derived);
Swig_name_object_inherit(Swig_cparse_namewarn(),base,derived); Swig_name_object_inherit(Swig_cparse_namewarn_hash(),base,derived);
Swig_name_object_inherit(features_hash,base,derived); Swig_name_object_inherit(features_hash,base,derived);
} }
@ -311,12 +365,93 @@ static void rename_inherit(String *base, String *derived) {
/* This is a bit of a mess. Need to clean up */ /* This is a bit of a mess. Need to clean up */
static String *add_oldname = 0; static String *add_oldname = 0;
DOH *Swig_node_getattr(Node *n, const char *cattr)
{
const char *rattr = strstr(cattr,"$");
if (rattr) {
String *nattr = NewStringWithSize(cattr, rattr-cattr);
Node *rn = Getattr(n,nattr);
if (rn) {
DOH *res = Swig_node_getattr(rn, rattr + 1);
Delete(nattr);
return res;
} else {
return 0;
}
} else {
return Getattr(n,cattr);
}
}
int Swig_cparse_match(Hash *rn, Node *n) {
int match = 1;
Node *kw = nextSibling(rn);
while (match && kw) {
String *key = Getattr(kw,"name");
char *ckey = key ? Char(key) : 0;
if (ckey && (strncmp(ckey,"match",5) == 0)) {
match = 0;
if (n) {
const char *csep = strstr(ckey,"$");
const char *cattr = csep ? csep + 1 : "nodeType";
String *nval = Swig_node_getattr(n,cattr);
String *kwval = Getattr(kw,"value");
if (nval && Equal(nval, kwval)) {
match = 1;
}
}
}
kw = nextSibling(kw);
}
return match;
}
Hash *Swig_cparse_name_object(List *namelist, Node *n, String *prefix, String *name, String *decl) {
Hash *res = 0;
if (namelist) {
int len = Len(namelist);
int i;
int match = 0;
for (i = 0; !match && (i < len); i++) {
Hash *rn = Getitem(namelist,i);
String *rdecl = Getattr(rn,"decl");
if (rdecl && (!decl || !Equal(rdecl,decl))) {
continue;
} else {
String *tname = Getattr(rn,"target_name");
String *sfmt = Getattr(rn,"source_fmt");
String *sname = 0;
int fullname = GetFlag(namelist,"fullname");
if (sfmt) {
if (fullname && prefix) {
sname = NewStringf(sfmt, prefix, name);
} else {
sname = NewStringf(sfmt, name);
}
} else {
if (fullname && prefix) {
sname = NewStringf("%s::%s", prefix, name);
} else {
sname = NewString(name);
}
}
match = (!tname || Equal(sname,tname)) && Swig_cparse_match(rn, n);
Delete(sname);
}
if (match) {
res = rn;
break;
}
}
}
return res;
}
/* Return the node name when it requires to emit a name warning */ /* Return the node name when it requires to emit a name warning */
String *Swig_cparse_name_warning(Node *n, String *prefix, String *name,SwigType *decl) { Hash *Swig_cparse_warning_object(Node *n, String *prefix, String *name,SwigType *decl) {
if (n) { if (n) {
/* Return in the obvious cases */ /* Return in the obvious cases */
if (!Swig_cparse_namewarn() || !name || !need_name_warning(n)) { if (!Swig_cparse_namewarn_hash() || !name || !need_name_warning(n)) {
return 0; return 0;
} else { } else {
String *access = Getattr(n,"access"); String *access = Getattr(n,"access");
@ -328,101 +463,97 @@ String *Swig_cparse_name_warning(Node *n, String *prefix, String *name,SwigType
} }
if (name) { if (name) {
/* Check to see if the name is in the hash */ /* Check to see if the name is in the hash */
Hash *res = Swig_name_object_get(Swig_cparse_namewarn(),prefix,name,decl); Hash *wrn = Swig_name_object_get(Swig_cparse_namewarn_hash(),prefix,name,decl);
return res ? Getattr(res,"name"): 0; if (!wrn || !Swig_cparse_match(wrn, n)) {
wrn = Swig_cparse_name_object(Swig_cparse_namewarn_list(), n, prefix, name, decl);
}
if (wrn && Getattr(wrn,"error")) {
if (n) {
Swig_error(Getfile(n), Getline(n), "%s\n", Getattr(wrn,"name"));
} else {
Swig_error(cparse_file, cparse_line,"%s\n", Getattr(wrn,"name"));
}
}
return wrn;
} else { } else {
return 0; return 0;
} }
} }
String *Swig_cparse_name_warning(Node *n, String *prefix, String *name,SwigType *decl) {
Hash *wrn = Swig_cparse_warning_object(n, prefix, name,decl);
return (name && wrn) ? Getattr(wrn,"name") : 0;
}
/* Create a name applying rename/namewarn if needed */ /* Create a name applying rename/namewarn if needed */
String *Swig_cparse_symbol_name(Node *n, String *prefix, String *name, SwigType *decl, String *oldname) { String *apply_rename(String *newname, int fullname, String *prefix, String *name)
String *rn = 0; {
Hash *wrn; String *result = 0;
int destructor = name && (*(Char(name)) == '~'); if (newname) {
int need_wrn = 1; if (Strcmp(newname,"$ignore") == 0) {
if (n) { result = Copy(newname);
/* Return in the obvious cases */
if (!Swig_cparse_namewarn() || !name || !need_name_warning(n)) {
need_wrn = 0;
} else { } else {
String *access = Getattr(n,"access"); int destructor = name && (*(Char(name)) == '~');
int is_public = !access || (Strcmp(access,"public") == 0); String *fmt = newname;
if (!is_public && !need_protected(n,dirprot_mode)) { String *tmp = 0;
need_wrn = 0; if (destructor && (*(Char(newname)) != '~')) {
fmt = tmp = NewStringf("~%s", newname);
} }
if (fullname && prefix) {
result = NewStringf(fmt,prefix,name);
} else {
result = NewStringf(fmt,name);
}
if (tmp) Delete(tmp);
} }
} }
wrn = need_wrn ? Swig_name_object_get(Swig_cparse_namewarn(),prefix,name,decl) : 0; return result;
}
String *
Swig_cparse_symbol_name(Node *n, String *prefix, String *name, SwigType *decl, String *oldname) {
String *nname = 0;
String *result = 0;
Hash *wrn = 0;
Hash *rn = Swig_name_object_get(Swig_cparse_rename_hash(), prefix, name, decl);
if (!rn || !Swig_cparse_match(rn,n)) {
rn = Swig_cparse_name_object(Swig_cparse_rename_list(), n, prefix, name, decl);
}
if (rn) {
String *newname = Getattr(rn,"name");
int fullname = GetFlag(rn,"fullname");
result = apply_rename(newname, fullname, prefix, name);
}
nname = result ? result : name;
wrn = Swig_cparse_warning_object(n, prefix, nname, decl);
if (wrn) { if (wrn) {
String *fmt = 0; String *rename = Getattr(wrn,"rename");
Hash *kw = nextSibling(wrn); if (rename) {
while (kw) { String *msg = Getattr(wrn,"name");
String *kname = Getattr(kw,"name"); int fullname = GetFlag(wrn,"fullname");
if (kname && (Cmp(kname,"rename") == 0)) { if (result) Delete(result);
fmt = Getattr(kw,"value"); result = apply_rename(rename, fullname, prefix, name);
break; if ((msg) && (Len(msg))) {
}
kw = nextSibling(kw);
}
if (fmt) {
char *cprefix = prefix ? Char(prefix) : "";
if ((wrn) && (Len(wrn))) {
if (n) { if (n) {
SWIG_WARN_NODE_BEGIN(n); SWIG_WARN_NODE_BEGIN(n);
Swig_warning(0,Getfile(n),Getline(n), "%s\n", Getattr(wrn,"name")); Swig_warning(0,Getfile(n), Getline(n), "%s\n", msg);
SWIG_WARN_NODE_END(n); SWIG_WARN_NODE_END(n);
} else { } else {
Swig_warning(0,Getfile(name),Getline(name), "%s\n", Getattr(wrn,"name")); Swig_warning(0,Getfile(name),Getline(name), "%s\n", msg);
} }
} }
return NewStringf(fmt,name,cprefix);
} }
} }
rn = Swig_name_object_get(Swig_cparse_rename(), prefix, name, decl); if (!result || !Len(result)) {
if (!rn) { if (result) Delete(result);
return oldname ? Copy(oldname): Copy(name); result = oldname ? Copy(oldname): Copy(name);
} else {
String *type = 0;
String *newname = Getattr(rn,"name");
Hash *kw = nextSibling(rn);
while (kw) {
String *kname = Getattr(kw,"name");
if (kname && (Cmp(kname,"match") == 0)) {
type = Getattr(kw,"value");
break;
}
kw = nextSibling(kw);
}
if (type){
int match = 0;
if (n) {
String *ntype = Getattr(n,"nodeType");
if (ntype && Equal(ntype,type)) {
match = 1;
}
}
if (!match) {
return oldname ? Copy(oldname): Copy(name);
}
}
if (Strcmp(newname,"$ignore") == 0) {
return Copy(newname);
} else {
char *cprefix = prefix ? Char(prefix) : "";
if (destructor && (*(Char(newname)) != '~')) {
String *fmt = NewStringf("~%s", newname);
String *res = NewStringf(fmt,name,cprefix);
Delete(fmt);
return res;
} else {
String *res = NewStringf(newname,name,cprefix);
return res;
}
}
} }
} return result;
}
static String *make_name(Node *n, String *name,SwigType *decl) { static String *make_name(Node *n, String *name,SwigType *decl) {
String *origname = name; String *origname = name;
@ -454,11 +585,11 @@ static String *make_unnamed() {
/* Return if the node is a friend declaration */ /* Return if the node is a friend declaration */
static int is_friend(Node *n) { static int is_friend(Node *n) {
return Cmp(Getattr(n,"storage"),"friend") == 0; return Cmp(Getattr(n,"storage"),"friend") == 0;
} }
static int is_operator(String *name) { static int is_operator(String *name) {
return Strncmp(name,"operator ", 9) == 0; return Strncmp(name,"operator ", 9) == 0;
} }
@ -506,7 +637,7 @@ static void add_symbols(Node *n) {
class scope if provided, as in class scope if provided, as in
struct Foo { struct Foo {
int Foo::method(int a); int Foo::method(int a);
}; };
*/ */
@ -838,120 +969,121 @@ static void append_previous_extension(Node *cls, Node *am) {
/* Check for unused %extend. Special case, don't report unused /* Check for unused %extend. Special case, don't report unused
extensions for templates */ extensions for templates */
static void check_extensions() { static void check_extensions() {
Iterator ki; Iterator ki;
if (!extendhash) return; if (!extendhash) return;
for (ki = First(extendhash); ki.key; ki = Next(ki)) { for (ki = First(extendhash); ki.key; ki = Next(ki)) {
if (!Strstr(ki.key,"<")) { if (!Strstr(ki.key,"<")) {
SWIG_WARN_NODE_BEGIN(ki.item); SWIG_WARN_NODE_BEGIN(ki.item);
Swig_warning(WARN_PARSE_EXTEND_UNDEF,Getfile(ki.item), Getline(ki.item), "%%extend defined for an undeclared class %s.\n", ki.key); Swig_warning(WARN_PARSE_EXTEND_UNDEF,Getfile(ki.item), Getline(ki.item), "%%extend defined for an undeclared class %s.\n", ki.key);
SWIG_WARN_NODE_END(ki.item); SWIG_WARN_NODE_END(ki.item);
} }
} }
} }
/* Check a set of declarations to see if any are pure-abstract */ /* Check a set of declarations to see if any are pure-abstract */
static List *pure_abstract(Node *n) { static List *pure_abstract(Node *n) {
List *abs = 0; List *abs = 0;
while (n) { while (n) {
if (Cmp(nodeType(n),"cdecl") == 0) { if (Cmp(nodeType(n),"cdecl") == 0) {
String *decl = Getattr(n,"decl"); String *decl = Getattr(n,"decl");
if (SwigType_isfunction(decl)) { if (SwigType_isfunction(decl)) {
String *init = Getattr(n,"value"); String *init = Getattr(n,"value");
if (Cmp(init,"0") == 0) { if (Cmp(init,"0") == 0) {
if (!abs) { if (!abs) {
abs = NewList(); abs = NewList();
} }
Append(abs,n); Append(abs,n);
Setattr(n,"abstract","1"); Setattr(n,"abstract","1");
} }
} }
} else if (Cmp(nodeType(n),"destructor") == 0) { } else if (Cmp(nodeType(n),"destructor") == 0) {
if (Cmp(Getattr(n,"value"),"0") == 0) { if (Cmp(Getattr(n,"value"),"0") == 0) {
if (!abs) { if (!abs) {
abs = NewList(); abs = NewList();
} }
Append(abs,n); Append(abs,n);
Setattr(n,"abstract","1"); Setattr(n,"abstract","1");
} }
} }
n = nextSibling(n); n = nextSibling(n);
} }
return abs; return abs;
} }
/* Make a classname */ /* Make a classname */
static String *make_class_name(String *name) { static String *make_class_name(String *name) {
String *nname = 0; String *nname = 0;
if (Namespaceprefix) { if (Namespaceprefix) {
nname= NewStringf("%s::%s", Namespaceprefix, name); nname= NewStringf("%s::%s", Namespaceprefix, name);
} else { } else {
nname = NewString(name); nname = NewString(name);
} }
if (SwigType_istemplate(nname)) { if (SwigType_istemplate(nname)) {
String *prefix, *args, *qargs; String *prefix, *args, *qargs;
prefix = SwigType_templateprefix(nname); prefix = SwigType_templateprefix(nname);
args = SwigType_templateargs(nname); args = SwigType_templateargs(nname);
qargs = Swig_symbol_type_qualify(args,0); qargs = Swig_symbol_type_qualify(args,0);
Append(prefix,qargs); Append(prefix,qargs);
Delete(nname); Delete(nname);
Delete(args); Delete(args);
Delete(qargs); Delete(qargs);
nname = prefix; nname = prefix;
} }
return nname; return nname;
} }
static List *make_inherit_list(String *clsname, List *names) { static List *make_inherit_list(String *clsname, List *names) {
int i; int i, ilen;
String *derived; String *derived;
List *bases = NewList(); List *bases = NewList();
if (Namespaceprefix) derived = NewStringf("%s::%s", Namespaceprefix,clsname); if (Namespaceprefix) derived = NewStringf("%s::%s", Namespaceprefix,clsname);
else derived = NewString(clsname); else derived = NewString(clsname);
for (i = 0; i < Len(names); i++) { ilen = Len(names);
Node *s; for (i = 0; i < ilen; i++) {
String *base; Node *s;
String *n = Getitem(names,i); String *base;
/* Try to figure out where this symbol is */ String *n = Getitem(names,i);
s = Swig_symbol_clookup(n,0); /* Try to figure out where this symbol is */
if (s) { s = Swig_symbol_clookup(n,0);
while (s && (Strcmp(nodeType(s),"class") != 0)) { if (s) {
/* Not a class. Could be a typedef though. */ while (s && (Strcmp(nodeType(s),"class") != 0)) {
String *storage = Getattr(s,"storage"); /* Not a class. Could be a typedef though. */
if (storage && (Strcmp(storage,"typedef") == 0)) { String *storage = Getattr(s,"storage");
String *nn = Getattr(s,"type"); if (storage && (Strcmp(storage,"typedef") == 0)) {
s = Swig_symbol_clookup(nn,Getattr(s,"sym:symtab")); String *nn = Getattr(s,"type");
} else { s = Swig_symbol_clookup(nn,Getattr(s,"sym:symtab"));
break; } else {
} break;
} }
if (s && ((Strcmp(nodeType(s),"class") == 0) || (Strcmp(nodeType(s),"template") == 0))) { }
String *q = Swig_symbol_qualified(s); if (s && ((Strcmp(nodeType(s),"class") == 0) || (Strcmp(nodeType(s),"template") == 0))) {
Append(bases,s); String *q = Swig_symbol_qualified(s);
if (q) { Append(bases,s);
base = NewStringf("%s::%s", q, Getattr(s,"name")); if (q) {
Delete(q); base = NewStringf("%s::%s", q, Getattr(s,"name"));
} else { Delete(q);
base = NewString(Getattr(s,"name")); } else {
} base = NewString(Getattr(s,"name"));
} else { }
base = NewString(n); } else {
} base = NewString(n);
} else { }
base = NewString(n); } else {
} base = NewString(n);
if (base) { }
rename_inherit(base,derived); if (base) {
Delete(base); rename_inherit(base,derived);
} Delete(base);
} }
return bases; }
} return bases;
}
/* If the class name is qualified. We need to create or lookup namespace entries */ /* If the class name is qualified. We need to create or lookup namespace entries */
@ -1165,12 +1297,12 @@ static Node *dump_nested(const char *parent) {
/* Insert a forward class declaration */ /* Insert a forward class declaration */
/* Disabled: [ 597599 ] union in class: incorrect scope /* Disabled: [ 597599 ] union in class: incorrect scope
retx = new_node("classforward"); retx = new_node("classforward");
Setattr(retx,"kind",n->kind); Setattr(retx,"kind",n->kind);
Setattr(retx,"name",Copy(n->type)); Setattr(retx,"name",Copy(n->type));
Setattr(retx,"sym:name", make_name(n->type,0)); Setattr(retx,"sym:name", make_name(n->type,0));
set_nextSibling(retx,ret); set_nextSibling(retx,ret);
ret = retx; ret = retx;
*/ */
/* Make all SWIG created typedef structs/unions/classes unnamed else /* Make all SWIG created typedef structs/unions/classes unnamed else
@ -1181,24 +1313,24 @@ static Node *dump_nested(const char *parent) {
int i; int i;
for (i=0; i<3; i++) { for (i=0; i<3; i++) {
char* code_ptr = Char(n->code); char* code_ptr = Char(n->code);
while (code_ptr) { while (code_ptr) {
/* Replace struct name (as in 'struct name {' ) with whitespace /* Replace struct name (as in 'struct name {' ) with whitespace
name will be between struct and { */ name will be between struct and { */
code_ptr = strstr(code_ptr, types_array[i]); code_ptr = strstr(code_ptr, types_array[i]);
if (code_ptr) { if (code_ptr) {
char *open_bracket_pos; char *open_bracket_pos;
code_ptr += strlen(types_array[i]); code_ptr += strlen(types_array[i]);
open_bracket_pos = strstr(code_ptr, "{"); open_bracket_pos = strstr(code_ptr, "{");
if (open_bracket_pos) { if (open_bracket_pos) {
/* Make sure we don't have something like struct A a; */ /* Make sure we don't have something like struct A a; */
char* semi_colon_pos = strstr(code_ptr, ";"); char* semi_colon_pos = strstr(code_ptr, ";");
if (!(semi_colon_pos && (semi_colon_pos < open_bracket_pos))) if (!(semi_colon_pos && (semi_colon_pos < open_bracket_pos)))
while (code_ptr < open_bracket_pos) while (code_ptr < open_bracket_pos)
*code_ptr++ = ' '; *code_ptr++ = ' ';
} }
} }
} }
} }
} }
@ -1261,33 +1393,33 @@ static void single_new_feature(const char *featurename, String *val, Hash *featu
fixname = NewStringEmpty(); fixname = NewStringEmpty();
} }
if (Namespaceprefix) { if (Namespaceprefix) {
name = NewStringf("%s::%s",Namespaceprefix, fixname); name = NewStringf("%s::%s",Namespaceprefix, fixname);
} else { } else {
name = fixname; name = fixname;
} }
if (declaratorparms) Setmeta(val,"parms",declaratorparms); if (declaratorparms) Setmeta(val,"parms",declaratorparms);
if (!Len(t)) t = 0; if (!Len(t)) t = 0;
if (t) { if (t) {
if (qualifier) SwigType_push(t,qualifier); if (qualifier) SwigType_push(t,qualifier);
if (SwigType_isfunction(t)) { if (SwigType_isfunction(t)) {
SwigType *decl = SwigType_pop_function(t); SwigType *decl = SwigType_pop_function(t);
if (SwigType_ispointer(t)) { if (SwigType_ispointer(t)) {
String *nname = NewStringf("*%s",name); String *nname = NewStringf("*%s",name);
Swig_feature_set(features_hash, nname, decl, fname, val, featureattribs); Swig_feature_set(features_hash, nname, decl, fname, val, featureattribs);
Delete(nname); Delete(nname);
} else { } else {
Swig_feature_set(features_hash, name, decl, fname, val, featureattribs); Swig_feature_set(features_hash, name, decl, fname, val, featureattribs);
} }
Delete(decl); Delete(decl);
} else if (SwigType_ispointer(t)) { } else if (SwigType_ispointer(t)) {
String *nname = NewStringf("*%s",name); String *nname = NewStringf("*%s",name);
Swig_feature_set(features_hash,nname,0,fname,val, featureattribs); Swig_feature_set(features_hash,nname,0,fname,val, featureattribs);
Delete(nname); Delete(nname);
} }
} else { } else {
/* Global feature, that is, feature not associated with any particular symbol */ /* Global feature, that is, feature not associated with any particular symbol */
Swig_feature_set(features_hash,name,0,fname,val, featureattribs); Swig_feature_set(features_hash,name,0,fname,val, featureattribs);
} }
Delete(fname); Delete(fname);
Delete(name); Delete(name);
@ -1368,7 +1500,7 @@ static void default_arguments(Node *n) {
} }
/* Do not add in functions if kwargs is being used or if user wants old default argument wrapping /* Do not add in functions if kwargs is being used or if user wants old default argument wrapping
(one wrapped method per function irrespective of number of default arguments) */ (one wrapped method per function irrespective of number of default arguments) */
if (compact_default_args if (compact_default_args
|| is_cfunction(function) || is_cfunction(function)
|| GetFlag(function,"feature:compactdefaultargs") || GetFlag(function,"feature:compactdefaultargs")
@ -1468,6 +1600,9 @@ static void default_arguments(Node *n) {
} }
} }
#if 0
{ /* cc-mode */
#endif
%} %}
%union { %union {
@ -3058,8 +3193,7 @@ c_enum_decl : storage_class ENUM ename LBRACE enumlist RBRACE SEMI {
appendChild($$,$5); appendChild($$,$5);
add_symbols($$); /* Add to tag space */ add_symbols($$); /* Add to tag space */
add_symbols($5); /* Add enum values to id space */ add_symbols($5); /* Add enum values to id space */
} }
| storage_class ENUM ename LBRACE enumlist RBRACE declarator c_decl_tail { | storage_class ENUM ename LBRACE enumlist RBRACE declarator c_decl_tail {
Node *n; Node *n;
SwigType *ty = 0; SwigType *ty = 0;
@ -3132,7 +3266,6 @@ c_enum_decl : storage_class ENUM ename LBRACE enumlist RBRACE SEMI {
add_symbols($$); /* Add enum to tag space */ add_symbols($$); /* Add enum to tag space */
set_nextSibling($$,n); set_nextSibling($$,n);
Delete(n); Delete(n);
add_symbols($5); /* Add enum values to id space */ add_symbols($5); /* Add enum values to id space */
add_symbols(n); add_symbols(n);
Delete(unnamed); Delete(unnamed);
@ -3696,14 +3829,15 @@ cpp_template_decl : TEMPLATE LESSTHAN template_parms GREATERTHAN { template_para
String *ffname = 0; String *ffname = 0;
char tmp[32]; char tmp[32];
int i; int i, ilen;
while (p) { while (p) {
String *n = Getattr(p,"name"); String *n = Getattr(p,"name");
if (!n) { if (!n) {
p = nextSibling(p); p = nextSibling(p);
continue; continue;
} }
for (i = 0; i < Len(tlist); i++) { ilen = Len(tlist);
for (i = 0; i < ilen; i++) {
if (Strstr(Getitem(tlist,i),n)) { if (Strstr(Getitem(tlist,i),n)) {
sprintf(tmp,"$%d",i+1); sprintf(tmp,"$%d",i+1);
Replaceid(fname,n,tmp); Replaceid(fname,n,tmp);

View file

@ -58,7 +58,8 @@ static DOH *encode(char *name, DOH *s) {
char *cfmt = strstr(name,":"); char *cfmt = strstr(name,":");
DOH *tmp = 0; DOH *tmp = 0;
if (cfmt) { if (cfmt) {
tmp = NewStringf(cfmt + 1, s); tmp = NewString(cfmt + 1);
Append(tmp,s);
Setfile(tmp,Getfile((DOH *)s)); Setfile(tmp,Getfile((DOH *)s));
Setline(tmp,Getline((DOH *)s)); Setline(tmp,Getline((DOH *)s));
*cfmt = '\0'; *cfmt = '\0';

View file

@ -696,11 +696,12 @@ expand_macro(String *name, List *args)
ns = NewStringEmpty(); ns = NewStringEmpty();
StringAppend(ns,name); StringAppend(ns,name);
if (args) { if (args) {
if (Len(args)) int lenargs = Len(args);
if (lenargs)
StringPutc('(',ns); StringPutc('(',ns);
for (i = 0; i < Len(args); i++) { for (i = 0; i < lenargs; i++) {
StringAppend(ns,Getitem(args,i)); StringAppend(ns,Getitem(args,i));
if (i < (Len(args) -1)) StringPutc(',',ns); if (i < (lenargs -1)) StringPutc(',',ns);
} }
if (i) if (i)
StringPutc(')',ns); StringPutc(')',ns);
@ -970,6 +971,7 @@ Preprocessor_replace(DOH *s)
StringUngetc(c,s); StringUngetc(c,s);
/* See if this is the special "defined" macro */ /* See if this is the special "defined" macro */
if (StringEqual(k_defined,id)) { if (StringEqual(k_defined,id)) {
int lenargs = 0;
DOH *args = 0; DOH *args = 0;
/* See whether or not a paranthesis has been used */ /* See whether or not a paranthesis has been used */
skip_whitespace(s,0); skip_whitespace(s,0);
@ -993,19 +995,20 @@ Preprocessor_replace(DOH *s)
} else { } else {
Seek(s,-1,SEEK_CUR); Seek(s,-1,SEEK_CUR);
} }
if ((!args) || (!Len(args))) { lenargs = Len(args);
if ((!args) || (!lenargs)) {
/* This is not a defined() macro. */ /* This is not a defined() macro. */
StringAppend(ns,id); StringAppend(ns,id);
state = 0; state = 0;
break; break;
} }
for (i = 0; i < Len(args); i++) { for (i = 0; i < lenargs; i++) {
DOH *o = Getitem(args,i); DOH *o = Getitem(args,i);
if (!HashGetAttr(symbols,o)) { if (!HashGetAttr(symbols,o)) {
break; break;
} }
} }
if (i < Len(args)) StringPutc('0',ns); if (i < lenargs) StringPutc('0',ns);
else StringPutc('1',ns); else StringPutc('1',ns);
Delete(args); Delete(args);
state = 0; state = 0;

View file

@ -141,7 +141,7 @@ Swig_search_path_any(int syspath) {
String *filename; String *filename;
String *dirname; String *dirname;
List *slist, *llist; List *slist, *llist;
int i; int i, ilen;
llist = 0; llist = 0;
slist = NewList(); slist = NewList();
@ -160,8 +160,8 @@ Swig_search_path_any(int syspath) {
} else { } else {
Append(slist,filename); Append(slist,filename);
} }
ilen = Len(directories);
for (i = 0; i < Len(directories); i++) { for (i = 0; i < ilen; i++) {
dirname = Getitem(directories,i); dirname = Getitem(directories,i);
filename = NewStringEmpty(); filename = NewStringEmpty();
assert(filename); assert(filename);
@ -174,7 +174,8 @@ Swig_search_path_any(int syspath) {
Delete(filename); Delete(filename);
} }
if (syspath) { if (syspath) {
for (i = 0; i < Len(llist); i++) { int ilen = Len(llist);
for (i = 0; i < ilen; i++) {
Append(slist,Getitem(llist,i)); Append(slist,Getitem(llist,i));
} }
Delete(llist); Delete(llist);
@ -202,7 +203,7 @@ Swig_open_any(const String_or_char *name, int sysfile) {
String *filename; String *filename;
List *spath = 0; List *spath = 0;
char *cname; char *cname;
int i; int i, ilen;
if (!directories) directories = NewList(); if (!directories) directories = NewList();
assert(directories); assert(directories);
@ -213,7 +214,8 @@ Swig_open_any(const String_or_char *name, int sysfile) {
f = fopen(Char(filename),"r"); f = fopen(Char(filename),"r");
if (!f) { if (!f) {
spath = Swig_search_path_any(sysfile); spath = Swig_search_path_any(sysfile);
for (i = 0; i < Len(spath); i++) { ilen = Len(spath);
for (i = 0; i < ilen; i++) {
Clear(filename); Clear(filename);
Printf(filename,"%s%s", Getitem(spath,i), cname); Printf(filename,"%s%s", Getitem(spath,i), cname);
f = fopen(Char(filename),"r"); f = fopen(Char(filename),"r");
@ -349,13 +351,14 @@ char *
Swig_file_suffix(const String_or_char *filename) { Swig_file_suffix(const String_or_char *filename) {
char *d; char *d;
char *c = Char(filename); char *c = Char(filename);
int len = Len(filename);
if (strlen(c)) { if (strlen(c)) {
d = c + Len(filename) - 1; d = c + len - 1;
while (d != c) { while (d != c) {
if (*d == '.') return d; if (*d == '.') return d;
d--; d--;
} }
return c+Len(filename); return c+len;
} }
return c; return c;
} }

View file

@ -151,6 +151,33 @@ String *Swig_string_title(String *s) {
return ns; return ns;
} }
/* -----------------------------------------------------------------------------
* Swig_string_ctitle()
*
* Takes a string object and returns a copy that is lowercase with thefirst letter
* capitalized and the one following '_', which are removed.
*
* camel_case -> CamelCase
* ----------------------------------------------------------------------------- */
String *Swig_string_ctitle(String *s) {
String *ns;
int first = 1;
int c;
ns = NewStringEmpty();
Seek(s,0,SEEK_SET);
while ((c = Getc(s)) != EOF) {
if (c == '_') {
first = 1;
continue;
}
Putc(first ? toupper(c) : tolower(c),ns);
first = 0;
}
return ns;
}
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
* Swig_string_typecode() * Swig_string_typecode()
* *
@ -642,11 +669,11 @@ String *Swig_string_command(String *s) {
} }
pclose(fp); pclose(fp);
} }
if (!fp || (errno) || (StringLen(res) == 0)) { if (!fp || (errno)) {
Swig_error("SWIG",Getline(s), "Command encoder fails attempting '%s'.\n", s); Swig_error("SWIG",Getline(s), "Command encoder fails attempting '%s'.\n", s);
exit(1); exit(1);
} }
} }
return res; return res;
} }
#endif #endif
@ -665,6 +692,7 @@ Swig_init() {
DohEncoding("upper", Swig_string_upper); DohEncoding("upper", Swig_string_upper);
DohEncoding("lower", Swig_string_lower); DohEncoding("lower", Swig_string_lower);
DohEncoding("title", Swig_string_title); DohEncoding("title", Swig_string_title);
DohEncoding("ctitle", Swig_string_ctitle);
DohEncoding("typecode",Swig_string_typecode); DohEncoding("typecode",Swig_string_typecode);
DohEncoding("mangle",Swig_string_emangle); DohEncoding("mangle",Swig_string_emangle);
#if defined(HAVE_POPEN) #if defined(HAVE_POPEN)