/* ----------------------------------------------------------------------------- * 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 /* 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); } }