swig/SWIG/Source/Swig/naming.c
Mark Rose bd40a83f1c polymorphism patch merge
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@4435 626c5289-ae23-0410-ae9c-e8d60b6d4f22
2003-03-06 19:21:58 +00:00

660 lines
16 KiB
C

/* -----------------------------------------------------------------------------
* naming.c
*
* Functions for generating various kinds of names during code generation
*
* Author(s) : David Beazley (beazley@cs.uchicago.edu)
*
* Copyright (C) 1999-2000. The University of Chicago
* See the file LICENSE for information on usage and redistribution.
* ----------------------------------------------------------------------------- */
char cvsroot_naming_c[] = "$Header$";
#include "swig.h"
#include <ctype.h>
/* Hash table containing naming data */
static Hash *naming_hash = 0;
/* -----------------------------------------------------------------------------
* Swig_name_register()
*
* Register a new naming format.
* ----------------------------------------------------------------------------- */
void
Swig_name_register(const String_or_char *method, const String_or_char *format) {
if (!naming_hash) naming_hash = NewHash();
Setattr(naming_hash,method,format);
}
void
Swig_name_unregister(const String_or_char *method) {
if (naming_hash) {
Delattr(naming_hash,method);
}
}
static int name_mangle(String *r) {
char *c;
int special;
special = 0;
Replaceall(r,"::","_");
c = Char(r);
while (*c) {
if (!isalnum(*c) && (*c != '_')) {
special = 1;
switch(*c) {
case '+':
*c = 'a';
break;
case '-':
*c = 's';
break;
case '*':
*c = 'm';
break;
case '/':
*c = 'd';
break;
case '<':
*c = 'l';
break;
case '>':
*c = 'g';
break;
case '=':
*c = 'e';
break;
case ',':
*c = 'c';
break;
case '(':
*c = 'p';
break;
case ')':
*c = 'P';
break;
case '[':
*c = 'b';
break;
case ']':
*c = 'B';
break;
case '^':
*c = 'x';
break;
case '&':
*c = 'A';
break;
case '|':
*c = 'o';
break;
case '~':
*c = 'n';
break;
case '!':
*c = 'N';
break;
case '%':
*c = 'M';
break;
case '.':
*c = 'f';
break;
case '?':
*c = 'q';
break;
default:
*c = '_';
break;
}
}
c++;
}
if (special) Append(r,"___");
return special;
}
/* -----------------------------------------------------------------------------
* Swig_name_mangle()
*
* Converts all of the non-identifier characters of a string to underscores.
* ----------------------------------------------------------------------------- */
String *
Swig_name_mangle(const String_or_char *s) {
String *r = NewString(s);
name_mangle(r);
return r;
}
/* -----------------------------------------------------------------------------
* Swig_name_wrapper()
*
* Returns the name of a wrapper function.
* ----------------------------------------------------------------------------- */
String *
Swig_name_wrapper(const String_or_char *fname) {
String *r;
String *f;
r = NewString("");
if (!naming_hash) naming_hash = NewHash();
f = Getattr(naming_hash,"wrapper");
if (!f) {
Append(r,"_wrap_%f");
} else {
Append(r,f);
}
Replace(r,"%f",fname, DOH_REPLACE_ANY);
name_mangle(r);
return r;
}
/* -----------------------------------------------------------------------------
* Swig_name_member()
*
* Returns the name of a class method.
* ----------------------------------------------------------------------------- */
String *
Swig_name_member(const String_or_char *classname, const String_or_char *mname) {
String *r;
String *f;
String *rclassname;
char *cname;
rclassname = SwigType_namestr(classname);
r = NewString("");
if (!naming_hash) naming_hash = NewHash();
f = Getattr(naming_hash,"member");
if (!f) {
Append(r,"%c_%m");
} else {
Append(r,f);
}
cname = Char(rclassname);
if ((strncmp(cname,"struct ", 7) == 0) ||
((strncmp(cname,"class ", 6) == 0)) ||
((strncmp(cname,"union ", 6) == 0))) {
cname = strchr(cname, ' ')+1;
}
Replace(r,"%c",cname, DOH_REPLACE_ANY);
Replace(r,"%m",mname, DOH_REPLACE_ANY);
/* name_mangle(r);*/
Delete(rclassname);
return r;
}
/* -----------------------------------------------------------------------------
* Swig_name_get()
*
* Returns the name of the accessor function used to get a variable.
* ----------------------------------------------------------------------------- */
String *
Swig_name_get(const String_or_char *vname) {
String *r;
String *f;
r = NewString("");
if (!naming_hash) naming_hash = NewHash();
f = Getattr(naming_hash,"get");
if (!f) {
Append(r,"%v_get");
} else {
Append(r,f);
}
Replace(r,"%v",vname, DOH_REPLACE_ANY);
Replace(r,"::","_", DOH_REPLACE_ANY);
return r;
}
/* -----------------------------------------------------------------------------
* Swig_name_set()
*
* Returns the name of the accessor function used to set a variable.
* ----------------------------------------------------------------------------- */
String *
Swig_name_set(const String_or_char *vname) {
String *r;
String *f;
r = NewString("");
if (!naming_hash) naming_hash = NewHash();
f = Getattr(naming_hash,"set");
if (!f) {
Append(r,"%v_set");
} else {
Append(r,f);
}
Replace(r,"%v",vname, DOH_REPLACE_ANY);
Replace(r,"::","_", DOH_REPLACE_ANY);
return r;
}
/* -----------------------------------------------------------------------------
* Swig_name_construct()
*
* Returns the name of the accessor function used to create an object.
* ----------------------------------------------------------------------------- */
String *
Swig_name_construct(const String_or_char *classname) {
String *r;
String *f;
String *rclassname;
char *cname;
rclassname = SwigType_namestr(classname);
r = NewString("");
if (!naming_hash) naming_hash = NewHash();
f = Getattr(naming_hash,"construct");
if (!f) {
Append(r,"new_%c");
} else {
Append(r,f);
}
cname = Char(rclassname);
if ((strncmp(cname,"struct ", 7) == 0) ||
((strncmp(cname,"class ", 6) == 0)) ||
((strncmp(cname,"union ", 6) == 0))) {
cname = strchr(cname, ' ')+1;
}
Replace(r,"%c",cname, DOH_REPLACE_ANY);
Delete(rclassname);
return r;
}
/* -----------------------------------------------------------------------------
* Swig_name_copyconstructor()
*
* Returns the name of the accessor function used to copy an object.
* ----------------------------------------------------------------------------- */
String *
Swig_name_copyconstructor(const String_or_char *classname) {
String *r;
String *f;
String *rclassname;
char *cname;
rclassname = SwigType_namestr(classname);
r = NewString("");
if (!naming_hash) naming_hash = NewHash();
f = Getattr(naming_hash,"construct");
if (!f) {
Append(r,"copy_%c");
} else {
Append(r,f);
}
cname = Char(rclassname);
if ((strncmp(cname,"struct ", 7) == 0) ||
((strncmp(cname,"class ", 6) == 0)) ||
((strncmp(cname,"union ", 6) == 0))) {
cname = strchr(cname, ' ')+1;
}
Replace(r,"%c",cname, DOH_REPLACE_ANY);
Delete(rclassname);
return r;
}
/* -----------------------------------------------------------------------------
* Swig_name_destroy()
*
* Returns the name of the accessor function used to destroy an object.
* ----------------------------------------------------------------------------- */
String *Swig_name_destroy(const String_or_char *classname) {
String *r;
String *f;
String *rclassname;
char *cname;
rclassname = SwigType_namestr(classname);
r = NewString("");
if (!naming_hash) naming_hash = NewHash();
f = Getattr(naming_hash,"destroy");
if (!f) {
Append(r,"delete_%c");
} else {
Append(r,f);
}
cname = Char(rclassname);
if ((strncmp(cname,"struct ", 7) == 0) ||
((strncmp(cname,"class ", 6) == 0)) ||
((strncmp(cname,"union ", 6) == 0))) {
cname = strchr(cname, ' ')+1;
}
Replace(r,"%c",cname, DOH_REPLACE_ANY);
Delete(rclassname);
return r;
}
/* -----------------------------------------------------------------------------
* Swig_name_disown()
*
* Returns the name of the accessor function used to disown an object.
* ----------------------------------------------------------------------------- */
String *Swig_name_disown(const String_or_char *classname) {
String *r;
String *f;
String *rclassname;
char *cname;
rclassname = SwigType_namestr(classname);
r = NewString("");
if (!naming_hash) naming_hash = NewHash();
f = Getattr(naming_hash,"disown");
if (!f) {
Append(r,"disown_%c");
} else {
Append(r,f);
}
cname = Char(rclassname);
if ((strncmp(cname,"struct ", 7) == 0) ||
((strncmp(cname,"class ", 6) == 0)) ||
((strncmp(cname,"union ", 6) == 0))) {
cname = strchr(cname, ' ')+1;
}
Replace(r,"%c",cname, DOH_REPLACE_ANY);
Delete(rclassname);
return r;
}
/* -----------------------------------------------------------------------------
* Swig_name_object_set()
*
* Sets an object associated with a name and optional declarators.
* ----------------------------------------------------------------------------- */
void
Swig_name_object_set(Hash *namehash, String *name, SwigType *decl, DOH *object) {
DOH *n;
/* Printf(stdout,"name: '%s', '%s'\n", name, decl);*/
n = Getattr(namehash,name);
if (!n) {
n = NewHash();
Setattr(namehash,name,n);
}
/* Add an object based on the declarator value */
if (!decl) {
Setattr(n,NewString("*"),object);
} else {
Setattr(n,Copy(decl),object);
}
}
/* -----------------------------------------------------------------------------
* Swig_name_object_get()
*
* Return an object associated with an optional class prefix, name, and
* declarator. This function operates according to name matching rules
* described for the %rename directive in the SWIG manual.
* ----------------------------------------------------------------------------- */
static DOH *get_object(Hash *n, String *decl) {
DOH *rn = 0;
if (!n) return 0;
if (decl) {
rn = Getattr(n,decl);
} else {
rn = Getattr(n,"*");
}
return rn;
}
DOH *
Swig_name_object_get(Hash *namehash, String *prefix, String *name, SwigType *decl) {
String *tname;
DOH *rn = 0;
Hash *n;
char *ncdecl = 0;
if (!namehash) return 0;
/* DB: This removed to more tightly control feature/name matching */
/* if ((decl) && (SwigType_isqualifier(decl))) {
ncdecl = strchr(Char(decl),'.');
ncdecl++;
}
*/
/* Perform a class-based lookup (if class prefix supplied) */
if (prefix) {
if (Len(prefix)) {
tname = NewStringf("%s::%s",prefix,name);
n = Getattr(namehash,tname);
rn = get_object(n,decl);
if ((!rn) && ncdecl) rn = get_object(n,ncdecl);
if (!rn) rn = get_object(n,0);
Delete(tname);
}
/* A wildcard-based class lookup */
if (!rn) {
tname = NewStringf("*::%s",name);
n = Getattr(namehash,tname);
rn = get_object(n,decl);
if ((!rn) && ncdecl) rn = get_object(n,ncdecl);
if (!rn) rn = get_object(n,0);
Delete(tname);
}
} else {
/* Lookup in the global namespace only */
tname = NewStringf("::%s",name);
n = Getattr(namehash,tname);
rn = get_object(n,decl);
if ((!rn) && ncdecl) rn = get_object(n,ncdecl);
if (!rn) rn = get_object(n,0);
Delete(tname);
}
/* Catch-all */
if (!rn) {
n = Getattr(namehash,name);
rn = get_object(n,decl);
if ((!rn) && ncdecl) rn = get_object(n,ncdecl);
if (!rn) rn = get_object(n,0);
}
return rn;
}
/* -----------------------------------------------------------------------------
* Swig_name_object_inherit()
*
* Implements name-based inheritance scheme.
* ----------------------------------------------------------------------------- */
void
Swig_name_object_inherit(Hash *namehash, String *base, String *derived) {
String *key;
String *bprefix;
String *dprefix;
char *cbprefix;
int plen;
if (!namehash) return;
bprefix = NewStringf("%s::",base);
dprefix = NewStringf("%s::",derived);
cbprefix = Char(bprefix);
plen = strlen(cbprefix);
for (key = Firstkey(namehash); key; key = Nextkey(namehash)) {
char *k = Char(key);
if (strncmp(k,cbprefix,plen) == 0) {
Hash *n, *newh;
String *nkey, *okey;
nkey = NewStringf("%s%s",dprefix,k+plen);
n = Getattr(namehash,key);
newh = Getattr(namehash,nkey);
if (!newh) {
newh = NewHash();
Setattr(namehash,nkey,newh);
}
for (okey = Firstkey(n); okey; okey = Nextkey(n)) {
String *ovalue = Getattr(n,okey);
if (!Getattr(newh,okey)) {
Setattr(newh,okey,Copy(ovalue));
}
}
}
}
}
/* -----------------------------------------------------------------------------
* Swig_features_get()
*
* Given a node, this function merges features.
* ----------------------------------------------------------------------------- */
static void merge_features(Hash *features, Node *n) {
String *key;
if (!features) return;
for (key = Firstkey(features); key; key = Nextkey(features)) {
if (Getattr(n,key)) {
continue;
}
Setattr(n,key,Copy(Getattr(features,key)));
}
}
void
Swig_features_get(Hash *features, String *prefix, String *name, SwigType *decl, Node *node) {
String *tname;
DOH *rn = 0;
Hash *n;
char *ncdecl = 0;
if (!features) return;
if ((decl) && (SwigType_isqualifier(decl))) {
ncdecl = strchr(Char(decl),'.');
ncdecl++;
}
if (name) {
/* Perform a class-based lookup (if class prefix supplied) */
if (prefix) {
if (Len(prefix)) {
tname = NewStringf("%s::%s",prefix,name);
n = Getattr(features,tname);
rn = get_object(n,decl);
merge_features(rn,node);
if (ncdecl) {
rn = get_object(n,ncdecl);
merge_features(rn,node);
}
rn = get_object(n,0);
merge_features(rn,node);
Delete(tname);
}
/* A wildcard-based class lookup */
tname = NewStringf("*::%s",name);
n = Getattr(features,tname);
rn = get_object(n,decl);
merge_features(rn,node);
if (ncdecl) {
rn = get_object(n,ncdecl);
merge_features(rn,node);
}
rn = get_object(n,0);
merge_features(rn,node);
Delete(tname);
/* A class-generic feature */
if (Len(prefix)) {
tname = NewStringf("%s::",prefix);
n = Getattr(features,tname);
rn = get_object(n,0);
merge_features(rn,node);
Delete(tname);
}
} else {
/* Lookup in the global namespace only */
tname = NewStringf("::%s",name);
n = Getattr(features,tname);
rn = get_object(n,decl);
merge_features(rn,node);
if (ncdecl) {
rn = get_object(n,ncdecl);
merge_features(rn,node);
}
rn = get_object(n,0);
merge_features(rn,node);
Delete(tname);
}
/* Catch-all */
n = Getattr(features,name);
rn = get_object(n,decl);
merge_features(rn,node);
if (ncdecl) {
rn = get_object(n,ncdecl);
merge_features(rn,node);
}
rn = get_object(n,0);
merge_features(rn,node);
}
/* Global features */
n = Getattr(features,"");
rn = get_object(n,0);
merge_features(rn,node);
}
/* -----------------------------------------------------------------------------
* Swig_feature_set()
*
* Sets a feature name and value.
* ----------------------------------------------------------------------------- */
void
Swig_feature_set(Hash *features, String *name, SwigType *decl, String *featurename, DOH *value) {
Hash *n;
Hash *fhash;
/* Printf(stdout,"feature: %s %s %s %s\n", name, decl, featurename, value);*/
n = Getattr(features,name);
if (!n) {
n = NewHash();
Setattr(features,name,n);
}
if (!decl) {
fhash = Getattr(n,"*");
if (!fhash) {
fhash = NewHash();
Setattr(n,"*",fhash);
}
} else {
fhash = Getattr(n,decl);
if (!fhash) {
fhash = NewHash();
Setattr(n,Copy(decl),fhash);
}
}
if (value) {
Setattr(fhash,featurename,value);
} else {
Delattr(fhash,featurename);
}
}