git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@4435 626c5289-ae23-0410-ae9c-e8d60b6d4f22
660 lines
16 KiB
C
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);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|