import source from 1.3.40
[external/swig.git] / Source / Swig / naming.c
1 /* ----------------------------------------------------------------------------- 
2  * See the LICENSE file for information on copyright, usage and redistribution
3  * of SWIG, and the README file for authors - http://www.swig.org/release.html.
4  *
5  * naming.c
6  *
7  * Functions for generating various kinds of names during code generation.
8  * ----------------------------------------------------------------------------- */
9
10 char cvsroot_naming_c[] = "$Id: naming.c 11454 2009-07-26 21:21:26Z wsfulton $";
11
12 #include "swig.h"
13 #include "cparse.h"
14 #include <ctype.h>
15
16 /* Hash table containing naming data */
17
18 static Hash *naming_hash = 0;
19
20 #if 0
21 #define SWIG_DEBUG
22 #endif
23
24 /* -----------------------------------------------------------------------------
25  * Swig_name_register()
26  *
27  * Register a new naming format.
28  * ----------------------------------------------------------------------------- */
29
30 void Swig_name_register(const_String_or_char_ptr method, const_String_or_char_ptr format) {
31   if (!naming_hash)
32     naming_hash = NewHash();
33   Setattr(naming_hash, method, format);
34 }
35
36 void Swig_name_unregister(const_String_or_char_ptr method) {
37   if (naming_hash) {
38     Delattr(naming_hash, method);
39   }
40 }
41
42 static int name_mangle(String *r) {
43   char *c;
44   int special;
45   special = 0;
46   Replaceall(r, "::", "_");
47   c = Char(r);
48   while (*c) {
49     if (!isalnum((int) *c) && (*c != '_')) {
50       special = 1;
51       switch (*c) {
52       case '+':
53         *c = 'a';
54         break;
55       case '-':
56         *c = 's';
57         break;
58       case '*':
59         *c = 'm';
60         break;
61       case '/':
62         *c = 'd';
63         break;
64       case '<':
65         *c = 'l';
66         break;
67       case '>':
68         *c = 'g';
69         break;
70       case '=':
71         *c = 'e';
72         break;
73       case ',':
74         *c = 'c';
75         break;
76       case '(':
77         *c = 'p';
78         break;
79       case ')':
80         *c = 'P';
81         break;
82       case '[':
83         *c = 'b';
84         break;
85       case ']':
86         *c = 'B';
87         break;
88       case '^':
89         *c = 'x';
90         break;
91       case '&':
92         *c = 'A';
93         break;
94       case '|':
95         *c = 'o';
96         break;
97       case '~':
98         *c = 'n';
99         break;
100       case '!':
101         *c = 'N';
102         break;
103       case '%':
104         *c = 'M';
105         break;
106       case '.':
107         *c = 'f';
108         break;
109       case '?':
110         *c = 'q';
111         break;
112       default:
113         *c = '_';
114         break;
115       }
116     }
117     c++;
118   }
119   if (special)
120     Append(r, "___");
121   return special;
122 }
123
124 /* -----------------------------------------------------------------------------
125  * Swig_name_mangle()
126  *
127  * Converts all of the non-identifier characters of a string to underscores.
128  * ----------------------------------------------------------------------------- */
129
130 String *Swig_name_mangle(const_String_or_char_ptr s) {
131 #if 0
132   String *r = NewString(s);
133   name_mangle(r);
134   return r;
135 #else
136   return Swig_string_mangle(s);
137 #endif
138 }
139
140 /* -----------------------------------------------------------------------------
141  * Swig_name_wrapper()
142  *
143  * Returns the name of a wrapper function.
144  * ----------------------------------------------------------------------------- */
145
146 String *Swig_name_wrapper(const_String_or_char_ptr fname) {
147   String *r;
148   String *f;
149
150   r = NewStringEmpty();
151   if (!naming_hash)
152     naming_hash = NewHash();
153   f = Getattr(naming_hash, "wrapper");
154   if (!f) {
155     Append(r, "_wrap_%f");
156   } else {
157     Append(r, f);
158   }
159   Replace(r, "%f", fname, DOH_REPLACE_ANY);
160   name_mangle(r);
161   return r;
162 }
163
164
165 /* -----------------------------------------------------------------------------
166  * Swig_name_member()
167  *
168  * Returns the name of a class method.
169  * ----------------------------------------------------------------------------- */
170
171 String *Swig_name_member(const_String_or_char_ptr classname, const_String_or_char_ptr mname) {
172   String *r;
173   String *f;
174   String *rclassname;
175   char *cname;
176
177   rclassname = SwigType_namestr(classname);
178   r = NewStringEmpty();
179   if (!naming_hash)
180     naming_hash = NewHash();
181   f = Getattr(naming_hash, "member");
182   if (!f) {
183     Append(r, "%c_%m");
184   } else {
185     Append(r, f);
186   }
187   cname = Char(rclassname);
188   if ((strncmp(cname, "struct ", 7) == 0) || ((strncmp(cname, "class ", 6) == 0)) || ((strncmp(cname, "union ", 6) == 0))) {
189     cname = strchr(cname, ' ') + 1;
190   }
191   Replace(r, "%c", cname, DOH_REPLACE_ANY);
192   Replace(r, "%m", mname, DOH_REPLACE_ANY);
193   /*  name_mangle(r); */
194   Delete(rclassname);
195   return r;
196 }
197
198 /* -----------------------------------------------------------------------------
199  * Swig_name_get()
200  *
201  * Returns the name of the accessor function used to get a variable.
202  * ----------------------------------------------------------------------------- */
203
204 String *Swig_name_get(const_String_or_char_ptr vname) {
205   String *r;
206   String *f;
207
208 #ifdef SWIG_DEBUG
209   Printf(stdout, "Swig_name_get:  '%s'\n", vname);
210 #endif
211
212   r = NewStringEmpty();
213   if (!naming_hash)
214     naming_hash = NewHash();
215   f = Getattr(naming_hash, "get");
216   if (!f) {
217     Append(r, "%v_get");
218   } else {
219     Append(r, f);
220   }
221   Replace(r, "%v", vname, DOH_REPLACE_ANY);
222   /* name_mangle(r); */
223   return r;
224 }
225
226 /* ----------------------------------------------------------------------------- 
227  * Swig_name_set()
228  *
229  * Returns the name of the accessor function used to set a variable.
230  * ----------------------------------------------------------------------------- */
231
232 String *Swig_name_set(const_String_or_char_ptr vname) {
233   String *r;
234   String *f;
235
236   r = NewStringEmpty();
237   if (!naming_hash)
238     naming_hash = NewHash();
239   f = Getattr(naming_hash, "set");
240   if (!f) {
241     Append(r, "%v_set");
242   } else {
243     Append(r, f);
244   }
245   Replace(r, "%v", vname, DOH_REPLACE_ANY);
246   /* name_mangle(r); */
247   return r;
248 }
249
250 /* -----------------------------------------------------------------------------
251  * Swig_name_construct()
252  *
253  * Returns the name of the accessor function used to create an object.
254  * ----------------------------------------------------------------------------- */
255
256 String *Swig_name_construct(const_String_or_char_ptr classname) {
257   String *r;
258   String *f;
259   String *rclassname;
260   char *cname;
261
262   rclassname = SwigType_namestr(classname);
263   r = NewStringEmpty();
264   if (!naming_hash)
265     naming_hash = NewHash();
266   f = Getattr(naming_hash, "construct");
267   if (!f) {
268     Append(r, "new_%c");
269   } else {
270     Append(r, f);
271   }
272
273   cname = Char(rclassname);
274   if ((strncmp(cname, "struct ", 7) == 0) || ((strncmp(cname, "class ", 6) == 0)) || ((strncmp(cname, "union ", 6) == 0))) {
275     cname = strchr(cname, ' ') + 1;
276   }
277   Replace(r, "%c", cname, DOH_REPLACE_ANY);
278   Delete(rclassname);
279   return r;
280 }
281
282
283 /* -----------------------------------------------------------------------------
284  * Swig_name_copyconstructor()
285  *
286  * Returns the name of the accessor function used to copy an object.
287  * ----------------------------------------------------------------------------- */
288
289 String *Swig_name_copyconstructor(const_String_or_char_ptr classname) {
290   String *r;
291   String *f;
292   String *rclassname;
293   char *cname;
294
295   rclassname = SwigType_namestr(classname);
296   r = NewStringEmpty();
297   if (!naming_hash)
298     naming_hash = NewHash();
299   f = Getattr(naming_hash, "copy");
300   if (!f) {
301     Append(r, "copy_%c");
302   } else {
303     Append(r, f);
304   }
305
306   cname = Char(rclassname);
307   if ((strncmp(cname, "struct ", 7) == 0) || ((strncmp(cname, "class ", 6) == 0)) || ((strncmp(cname, "union ", 6) == 0))) {
308     cname = strchr(cname, ' ') + 1;
309   }
310
311   Replace(r, "%c", cname, DOH_REPLACE_ANY);
312   Delete(rclassname);
313   return r;
314 }
315
316 /* -----------------------------------------------------------------------------
317  * Swig_name_destroy()
318  *
319  * Returns the name of the accessor function used to destroy an object.
320  * ----------------------------------------------------------------------------- */
321
322 String *Swig_name_destroy(const_String_or_char_ptr classname) {
323   String *r;
324   String *f;
325   String *rclassname;
326   char *cname;
327   rclassname = SwigType_namestr(classname);
328   r = NewStringEmpty();
329   if (!naming_hash)
330     naming_hash = NewHash();
331   f = Getattr(naming_hash, "destroy");
332   if (!f) {
333     Append(r, "delete_%c");
334   } else {
335     Append(r, f);
336   }
337
338   cname = Char(rclassname);
339   if ((strncmp(cname, "struct ", 7) == 0) || ((strncmp(cname, "class ", 6) == 0)) || ((strncmp(cname, "union ", 6) == 0))) {
340     cname = strchr(cname, ' ') + 1;
341   }
342   Replace(r, "%c", cname, DOH_REPLACE_ANY);
343   Delete(rclassname);
344   return r;
345 }
346
347
348 /* -----------------------------------------------------------------------------
349  * Swig_name_disown()
350  *
351  * Returns the name of the accessor function used to disown an object.
352  * ----------------------------------------------------------------------------- */
353
354 String *Swig_name_disown(const_String_or_char_ptr classname) {
355   String *r;
356   String *f;
357   String *rclassname;
358   char *cname;
359   rclassname = SwigType_namestr(classname);
360   r = NewStringEmpty();
361   if (!naming_hash)
362     naming_hash = NewHash();
363   f = Getattr(naming_hash, "disown");
364   if (!f) {
365     Append(r, "disown_%c");
366   } else {
367     Append(r, f);
368   }
369
370   cname = Char(rclassname);
371   if ((strncmp(cname, "struct ", 7) == 0) || ((strncmp(cname, "class ", 6) == 0)) || ((strncmp(cname, "union ", 6) == 0))) {
372     cname = strchr(cname, ' ') + 1;
373   }
374   Replace(r, "%c", cname, DOH_REPLACE_ANY);
375   Delete(rclassname);
376   return r;
377 }
378
379
380 /* -----------------------------------------------------------------------------
381  * Swig_name_object_set()
382  *
383  * Sets an object associated with a name and optional declarators. 
384  * ----------------------------------------------------------------------------- */
385
386 void Swig_name_object_set(Hash *namehash, String *name, SwigType *decl, DOH *object) {
387   DOH *n;
388
389 #ifdef SWIG_DEBUG
390   Printf(stdout, "Swig_name_object_set:  '%s', '%s'\n", name, decl);
391 #endif
392   n = Getattr(namehash, name);
393   if (!n) {
394     n = NewHash();
395     Setattr(namehash, name, n);
396     Delete(n);
397   }
398   /* Add an object based on the declarator value */
399   if (!decl) {
400     Setattr(n, "start", object);
401   } else {
402     SwigType *cd = Copy(decl);
403     Setattr(n, cd, object);
404     Delete(cd);
405   }
406 }
407
408
409 /* -----------------------------------------------------------------------------
410  * Swig_name_object_get()
411  *
412  * Return an object associated with an optional class prefix, name, and 
413  * declarator.   This function operates according to name matching rules
414  * described for the %rename directive in the SWIG manual.
415  * ----------------------------------------------------------------------------- */
416
417 static DOH *get_object(Hash *n, String *decl) {
418   DOH *rn = 0;
419   if (!n)
420     return 0;
421   if (decl) {
422     rn = Getattr(n, decl);
423   } else {
424     rn = Getattr(n, "start");
425   }
426   return rn;
427 }
428
429 static
430 DOH *name_object_get(Hash *namehash, String *tname, SwigType *decl, SwigType *ncdecl) {
431   DOH *rn = 0;
432   Hash *n = Getattr(namehash, tname);
433   if (n) {
434     rn = get_object(n, decl);
435     if ((!rn) && ncdecl)
436       rn = get_object(n, ncdecl);
437     if (!rn)
438       rn = get_object(n, 0);
439   }
440   return rn;
441 }
442
443 DOH *Swig_name_object_get(Hash *namehash, String *prefix, String *name, SwigType *decl) {
444   String *tname = NewStringEmpty();
445   DOH *rn = 0;
446   char *ncdecl = 0;
447
448   if (!namehash)
449     return 0;
450
451   /* DB: This removed to more tightly control feature/name matching */
452   /*  if ((decl) && (SwigType_isqualifier(decl))) {
453      ncdecl = strchr(Char(decl),'.');
454      ncdecl++;
455      }
456    */
457 #ifdef SWIG_DEBUG
458   Printf(stdout, "Swig_name_object_get:  '%s' '%s', '%s'\n", prefix, name, decl);
459 #endif
460
461
462   /* Perform a class-based lookup (if class prefix supplied) */
463   if (prefix) {
464     if (Len(prefix)) {
465       Printf(tname, "%s::%s", prefix, name);
466       rn = name_object_get(namehash, tname, decl, ncdecl);
467       if (!rn) {
468         String *cls = Swig_scopename_last(prefix);
469         if (!Equal(cls, prefix)) {
470           Clear(tname);
471           Printf(tname, "*::%s::%s", cls, name);
472           rn = name_object_get(namehash, tname, decl, ncdecl);
473         }
474         Delete(cls);
475       }
476       /* A template-based class lookup, check name first */
477       if (!rn && SwigType_istemplate(name)) {
478         String *t_name = SwigType_templateprefix(name);
479         if (!Equal(t_name, name)) {
480           rn = Swig_name_object_get(namehash, prefix, t_name, decl);
481         }
482         Delete(t_name);
483       }
484       /* A template-based class lookup */
485       /*
486       if (!rn && SwigType_istemplate(prefix)) {
487         String *t_prefix = SwigType_templateprefix(prefix);
488         if (Strcmp(t_prefix, prefix) != 0) {
489           String *t_name = SwigType_templateprefix(name);
490           rn = Swig_name_object_get(namehash, t_prefix, t_name, decl);
491           Delete(t_name);
492         }
493         Delete(t_prefix);
494       }
495       */
496     }
497     /* A wildcard-based class lookup */
498     if (!rn) {
499       Clear(tname);
500       Printf(tname, "*::%s", name);
501       rn = name_object_get(namehash, tname, decl, ncdecl);
502     }
503   } else {
504     /* Lookup in the global namespace only */
505     Clear(tname);
506     Printf(tname, "::%s", name);
507     rn = name_object_get(namehash, tname, decl, ncdecl);
508   }
509   /* Catch-all */
510   if (!rn) {
511     rn = name_object_get(namehash, name, decl, ncdecl);
512   }
513   if (!rn && Swig_scopename_check(name)) {
514     String *nprefix = NewStringEmpty();
515     String *nlast = NewStringEmpty();
516     Swig_scopename_split(name, &nprefix, &nlast);
517     rn = name_object_get(namehash, nlast, decl, ncdecl);
518     Delete(nlast);
519     Delete(nprefix);
520   }
521
522   Delete(tname);
523
524 #ifdef SWIG_DEBUG
525   Printf(stdout, "Swig_name_object_get:  found %d\n", rn ? 1 : 0);
526 #endif
527
528   return rn;
529 }
530
531 /* -----------------------------------------------------------------------------
532  * Swig_name_object_inherit()
533  *
534  * Implements name-based inheritance scheme. 
535  * ----------------------------------------------------------------------------- */
536
537 void Swig_name_object_inherit(Hash *namehash, String *base, String *derived) {
538   Iterator ki;
539   String *bprefix;
540   String *dprefix;
541   char *cbprefix;
542   int plen;
543
544   if (!namehash)
545     return;
546
547   bprefix = NewStringf("%s::", base);
548   dprefix = NewStringf("%s::", derived);
549   cbprefix = Char(bprefix);
550   plen = strlen(cbprefix);
551   for (ki = First(namehash); ki.key; ki = Next(ki)) {
552     char *k = Char(ki.key);
553     if (strncmp(k, cbprefix, plen) == 0) {
554       Iterator oi;
555       String *nkey = NewStringf("%s%s", dprefix, k + plen);
556       Hash *n = ki.item;
557       Hash *newh = Getattr(namehash, nkey);
558       if (!newh) {
559         newh = NewHash();
560         Setattr(namehash, nkey, newh);
561         Delete(newh);
562       }
563       for (oi = First(n); oi.key; oi = Next(oi)) {
564         if (!Getattr(newh, oi.key)) {
565           String *ci = Copy(oi.item);
566           Setattr(newh, oi.key, ci);
567           Delete(ci);
568         }
569       }
570       Delete(nkey);
571     }
572   }
573   Delete(bprefix);
574   Delete(dprefix);
575 }
576
577 /* -----------------------------------------------------------------------------
578  * merge_features()
579  *
580  * Given a hash, this function merges the features in the hash into the node.
581  * ----------------------------------------------------------------------------- */
582
583 static void merge_features(Hash *features, Node *n) {
584   Iterator ki;
585
586   if (!features)
587     return;
588   for (ki = First(features); ki.key; ki = Next(ki)) {
589     String *ci = Copy(ki.item);
590     Setattr(n, ki.key, ci);
591     Delete(ci);
592   }
593 }
594
595 /* -----------------------------------------------------------------------------
596  * Swig_features_get()
597  *
598  * Attaches any features in the features hash to the node that matches
599  * the declaration, decl.
600  * ----------------------------------------------------------------------------- */
601
602 static
603 void features_get(Hash *features, const String *tname, SwigType *decl, SwigType *ncdecl, Node *node) {
604   Node *n = Getattr(features, tname);
605 #ifdef SWIG_DEBUG
606   Printf(stdout, "  features_get: %s\n", tname);
607 #endif
608   if (n) {
609     merge_features(get_object(n, 0), node);
610     if (ncdecl)
611       merge_features(get_object(n, ncdecl), node);
612     merge_features(get_object(n, decl), node);
613   }
614 }
615
616 void Swig_features_get(Hash *features, String *prefix, String *name, SwigType *decl, Node *node) {
617   char *ncdecl = 0;
618   String *rdecl = 0;
619   String *rname = 0;
620   if (!features)
621     return;
622
623   /* MM: This removed to more tightly control feature/name matching */
624   /*
625      if ((decl) && (SwigType_isqualifier(decl))) {
626      ncdecl = strchr(Char(decl),'.');
627      ncdecl++;
628      }
629    */
630
631   /* very specific hack for template constructors/destructors */
632   if (name && SwigType_istemplate(name)) {
633     String *nodetype = nodeType(node);
634     if (nodetype && (Equal(nodetype, "constructor") || Equal(nodetype, "destructor"))) {
635       String *nprefix = NewStringEmpty();
636       String *nlast = NewStringEmpty();
637       String *tprefix;
638       Swig_scopename_split(name, &nprefix, &nlast);
639       tprefix = SwigType_templateprefix(nlast);
640       Delete(nlast);
641       if (Len(nprefix)) {
642         Append(nprefix, "::");
643         Append(nprefix, tprefix);
644         Delete(tprefix);
645         rname = nprefix;
646       } else {
647         rname = tprefix;
648         Delete(nprefix);
649       }
650       rdecl = Copy(decl);
651       Replaceall(rdecl, name, rname);
652       decl = rdecl;
653       name = rname;
654     }
655   }
656
657 #ifdef SWIG_DEBUG
658   Printf(stdout, "Swig_features_get: '%s' '%s' '%s'\n", prefix, name, decl);
659 #endif
660
661   /* Global features */
662   features_get(features, "", 0, 0, node);
663   if (name) {
664     String *tname = NewStringEmpty();
665     /* add features for 'root' template */
666     if (SwigType_istemplate(name)) {
667       String *dname = SwigType_templateprefix(name);
668       features_get(features, dname, decl, ncdecl, node);
669       Delete(dname);
670     }
671     /* Catch-all */
672     features_get(features, name, decl, ncdecl, node);
673     /* Perform a class-based lookup (if class prefix supplied) */
674     if (prefix) {
675       /* A class-generic feature */
676       if (Len(prefix)) {
677         Printf(tname, "%s::", prefix);
678         features_get(features, tname, decl, ncdecl, node);
679       }
680       /* A wildcard-based class lookup */
681       Clear(tname);
682       Printf(tname, "*::%s", name);
683       features_get(features, tname, decl, ncdecl, node);
684       /* A specific class lookup */
685       if (Len(prefix)) {
686         /* A template-based class lookup */
687         if (SwigType_istemplate(prefix)) {
688           String *tprefix = SwigType_templateprefix(prefix);
689           Clear(tname);
690           Printf(tname, "%s::%s", tprefix, name);
691           features_get(features, tname, decl, ncdecl, node);
692           Delete(tprefix);
693         }
694         Clear(tname);
695         Printf(tname, "%s::%s", prefix, name);
696         features_get(features, tname, decl, ncdecl, node);
697       }
698     } else {
699       /* Lookup in the global namespace only */
700       Clear(tname);
701       Printf(tname, "::%s", name);
702       features_get(features, tname, decl, ncdecl, node);
703     }
704     Delete(tname);
705   }
706   if (name && SwigType_istemplate(name)) {
707     /* add features for complete template type */
708     String *dname = Swig_symbol_template_deftype(name, 0);
709     if (!Equal(dname, name)) {
710       Swig_features_get(features, prefix, dname, decl, node);
711     }
712     Delete(dname);
713   }
714
715   if (rname)
716     Delete(rname);
717   if (rdecl)
718     Delete(rdecl);
719 }
720
721
722 /* -----------------------------------------------------------------------------
723  * Swig_feature_set()
724  *
725  * Sets a feature name and value. Also sets optional feature attributes as
726  * passed in by featureattribs. Optional feature attributes are given a full name
727  * concatenating the feature name plus ':' plus the attribute name.
728  * ----------------------------------------------------------------------------- */
729
730 void Swig_feature_set(Hash *features, const_String_or_char_ptr name, SwigType *decl, const_String_or_char_ptr featurename, String *value, Hash *featureattribs) {
731   Hash *n;
732   Hash *fhash;
733
734 #ifdef SWIG_DEBUG
735   Printf(stdout, "Swig_feature_set: '%s' '%s' '%s' '%s'\n", name, decl, featurename, value);
736 #endif
737
738   n = Getattr(features, name);
739   if (!n) {
740     n = NewHash();
741     Setattr(features, name, n);
742     Delete(n);
743   }
744   if (!decl) {
745     fhash = Getattr(n, "start");
746     if (!fhash) {
747       fhash = NewHash();
748       Setattr(n, "start", fhash);
749       Delete(fhash);
750     }
751   } else {
752     fhash = Getattr(n, decl);
753     if (!fhash) {
754       String *cdecl_ = Copy(decl);
755       fhash = NewHash();
756       Setattr(n, cdecl_, fhash);
757       Delete(cdecl_);
758       Delete(fhash);
759     }
760   }
761   if (value) {
762     Setattr(fhash, featurename, value);
763   } else {
764     Delattr(fhash, featurename);
765   }
766
767   {
768     /* Add in the optional feature attributes */
769     Hash *attribs = featureattribs;
770     while (attribs) {
771       String *attribname = Getattr(attribs, "name");
772       String *featureattribname = NewStringf("%s:%s", featurename, attribname);
773       if (value) {
774         String *attribvalue = Getattr(attribs, "value");
775         Setattr(fhash, featureattribname, attribvalue);
776       } else {
777         Delattr(fhash, featureattribname);
778       }
779       attribs = nextSibling(attribs);
780       Delete(featureattribname);
781     }
782   }
783
784   if (name && SwigType_istemplate(name)) {
785     String *dname = Swig_symbol_template_deftype(name, 0);
786     if (Strcmp(dname, name)) {
787       Swig_feature_set(features, dname, decl, featurename, value, featureattribs);
788     }
789     Delete(dname);
790   }
791 }
792
793 /* -----------------------------------------------------------------------------
794  * The rename/namewarn engine
795  *
796  * Code below was in parser.y for a while
797  * ----------------------------------------------------------------------------- */
798
799 static Hash *namewarn_hash = 0;
800 Hash *Swig_name_namewarn_hash() {
801   if (!namewarn_hash)
802     namewarn_hash = NewHash();
803   return namewarn_hash;
804 }
805
806 static Hash *rename_hash = 0;
807 Hash *Swig_name_rename_hash() {
808   if (!rename_hash)
809     rename_hash = NewHash();
810   return rename_hash;
811 }
812
813 static List *namewarn_list = 0;
814 List *Swig_name_namewarn_list() {
815   if (!namewarn_list)
816     namewarn_list = NewList();
817   return namewarn_list;
818 }
819
820 static List *rename_list = 0;
821 List *Swig_name_rename_list() {
822   if (!rename_list)
823     rename_list = NewList();
824   return rename_list;
825 }
826
827 /* -----------------------------------------------------------------------------
828  * int Swig_need_name_warning(Node *n)
829  *
830  * Detects if a node needs name warnings 
831  *
832  * ----------------------------------------------------------------------------- */
833
834 int Swig_need_name_warning(Node *n) {
835   int need = 1;
836   /* 
837      we don't use name warnings for:
838      - class forwards, no symbol is generated at the target language.
839      - template declarations, only for real instances using %template(name).
840      - typedefs, they have no effect at the target language.
841    */
842   if (checkAttribute(n, "nodeType", "classforward")) {
843     need = 0;
844   } else if (checkAttribute(n, "storage", "typedef")) {
845     need = 0;
846   } else if (Getattr(n, "hidden")) {
847     need = 0;
848   } else if (Getattr(n, "ignore")) {
849     need = 0;
850   } else if (Getattr(n, "templatetype")) {
851     need = 0;
852   }
853   return need;
854 }
855
856 /* -----------------------------------------------------------------------------
857  * int Swig_need_redefined_warn()
858  *
859  * Detects when a redefined object needs a warning
860  * 
861  * ----------------------------------------------------------------------------- */
862
863 static int nodes_are_equivalent(Node *a, Node *b, int a_inclass) {
864   /* they must have the same type */
865   String *ta = nodeType(a);
866   String *tb = nodeType(b);
867   if (Cmp(ta, tb) != 0)
868     return 0;
869
870   /* cdecl case */
871   if (Cmp(ta, "cdecl") == 0) {
872     /* typedef */
873     String *a_storage = Getattr(a, "storage");
874     String *b_storage = Getattr(b, "storage");
875
876     if ((Cmp(a_storage, "typedef") == 0)
877         || (Cmp(b_storage, "typedef") == 0)) {
878       if (Cmp(a_storage, b_storage) == 0) {
879         String *a_type = (Getattr(a, "type"));
880         String *b_type = (Getattr(b, "type"));
881         if (Cmp(a_type, b_type) == 0)
882           return 1;
883       }
884       return 0;
885     }
886
887     /* static functions */
888     if ((Cmp(a_storage, "static") == 0)
889         || (Cmp(b_storage, "static") == 0)) {
890       if (Cmp(a_storage, b_storage) != 0)
891         return 0;
892     }
893
894     /* friend methods */
895
896     if (!a_inclass || (Cmp(a_storage, "friend") == 0)) {
897       /* check declaration */
898
899       String *a_decl = (Getattr(a, "decl"));
900       String *b_decl = (Getattr(b, "decl"));
901       if (Cmp(a_decl, b_decl) == 0) {
902         /* check return type */
903         String *a_type = (Getattr(a, "type"));
904         String *b_type = (Getattr(b, "type"));
905         if (Cmp(a_type, b_type) == 0) {
906           /* check parameters */
907           Parm *ap = (Getattr(a, "parms"));
908           Parm *bp = (Getattr(b, "parms"));
909           while (ap && bp) {
910             SwigType *at = Getattr(ap, "type");
911             SwigType *bt = Getattr(bp, "type");
912             if (Cmp(at, bt) != 0)
913               return 0;
914             ap = nextSibling(ap);
915             bp = nextSibling(bp);
916           }
917           if (ap || bp) {
918             return 0;
919           } else {
920             Node *a_template = Getattr(a, "template");
921             Node *b_template = Getattr(b, "template");
922             /* Not equivalent if one is a template instantiation (via %template) and the other is a non-templated function */
923             if ((a_template && !b_template) || (!a_template && b_template))
924               return 0;
925           }
926           return 1;
927         }
928       }
929     }
930   } else {
931     /* %constant case */
932     String *a_storage = Getattr(a, "storage");
933     String *b_storage = Getattr(b, "storage");
934     if ((Cmp(a_storage, "%constant") == 0)
935         || (Cmp(b_storage, "%constant") == 0)) {
936       if (Cmp(a_storage, b_storage) == 0) {
937         String *a_type = (Getattr(a, "type"));
938         String *b_type = (Getattr(b, "type"));
939         if ((Cmp(a_type, b_type) == 0)
940             && (Cmp(Getattr(a, "value"), Getattr(b, "value")) == 0))
941           return 1;
942       }
943       return 0;
944     }
945   }
946   return 0;
947 }
948
949 int Swig_need_redefined_warn(Node *a, Node *b, int InClass) {
950   String *a_name = Getattr(a, "name");
951   String *b_name = Getattr(b, "name");
952   String *a_symname = Getattr(a, "sym:name");
953   String *b_symname = Getattr(b, "sym:name");
954   /* always send a warning if a 'rename' is involved */
955   if ((a_symname && !Equal(a_symname, a_name))
956       || (b_symname && !Equal(b_symname, b_name))) {
957     if (!Equal(a_name, b_name)) {
958       return 1;
959     }
960   }
961
962
963   return !nodes_are_equivalent(a, b, InClass);
964 }
965
966
967 /* -----------------------------------------------------------------------------
968  * int Swig_need_protected(Node* n)
969  *
970  * Detects when we need to fully register the protected member.
971  * This is basically any protected members when the allprotected mode is set.
972  * Otherwise we take just the protected virtual methods and non-static methods 
973  * (potentially virtual methods) as well as constructors/destructors.
974  * 
975  * ----------------------------------------------------------------------------- */
976
977 int Swig_need_protected(Node *n) {
978   String *nodetype = nodeType(n);
979   if (checkAttribute(n, "access", "protected")) {
980     if ((Equal(nodetype, "cdecl"))) {
981       if (Swig_director_mode() && Swig_director_protected_mode() && Swig_all_protected_mode()) {
982         return 1;
983       }
984       if (SwigType_isfunction(Getattr(n, "decl"))) {
985         String *storage = Getattr(n, "storage");
986         /* The function is declared virtual, or it has no storage. This eliminates typedef, static etc. */
987         return !storage || Equal(storage, "virtual");
988       }
989     } else if (Equal(nodetype, "constructor") || Equal(nodetype, "destructor")) {
990       return 1;
991     }
992   }
993   return 0;
994 }
995
996 /* -----------------------------------------------------------------------------
997  * void Swig_name_nameobj_add()
998  *
999  * Add nameobj (rename/namewarn)
1000  * 
1001  * ----------------------------------------------------------------------------- */
1002
1003 static List *Swig_make_attrlist(const char *ckey) {
1004   List *list = NewList();
1005   const char *cattr = strchr(ckey, '$');
1006   if (cattr) {
1007     String *nattr;
1008     const char *rattr = strchr(++cattr, '$');
1009     while (rattr) {
1010       nattr = NewStringWithSize(cattr, rattr - cattr);
1011       Append(list, nattr);
1012       Delete(nattr);
1013       cattr = rattr + 1;
1014       rattr = strchr(cattr, '$');
1015     }
1016     nattr = NewString(cattr);
1017     Append(list, nattr);
1018     Delete(nattr);
1019   } else {
1020     Append(list, "nodeType");
1021   }
1022   return list;
1023 }
1024
1025 static void Swig_name_object_attach_keys(const char *keys[], Hash *nameobj) {
1026   Node *kw = nextSibling(nameobj);
1027   List *matchlist = 0;
1028   while (kw) {
1029     Node *next = nextSibling(kw);
1030     String *kname = Getattr(kw, "name");
1031     char *ckey = kname ? Char(kname) : 0;
1032     if (ckey) {
1033       const char **rkey;
1034       int isnotmatch = 0;
1035       int isrxsmatch = 0;
1036       if ((strncmp(ckey, "match", 5) == 0)
1037           || (isnotmatch = (strncmp(ckey, "notmatch", 8) == 0))
1038           || (isrxsmatch = (strncmp(ckey, "rxsmatch", 8) == 0))
1039           || (isnotmatch = isrxsmatch = (strncmp(ckey, "notrxsmatch", 11) == 0))) {
1040         Hash *mi = NewHash();
1041         List *attrlist = Swig_make_attrlist(ckey);
1042         if (!matchlist)
1043           matchlist = NewList();
1044         Setattr(mi, "value", Getattr(kw, "value"));
1045         Setattr(mi, "attrlist", attrlist);
1046 #ifdef SWIG_DEBUG
1047         if (isrxsmatch)
1048           Printf(stdout, "rxsmatch to use: %s %s %s\n", ckey, Getattr(kw, "value"), attrlist);
1049 #endif
1050         if (isnotmatch)
1051           SetFlag(mi, "notmatch");
1052         if (isrxsmatch)
1053           SetFlag(mi, "rxsmatch");
1054         Delete(attrlist);
1055         Append(matchlist, mi);
1056         Delete(mi);
1057         removeNode(kw);
1058       } else {
1059         for (rkey = keys; *rkey != 0; ++rkey) {
1060           if (strcmp(ckey, *rkey) == 0) {
1061             Setattr(nameobj, *rkey, Getattr(kw, "value"));
1062             removeNode(kw);
1063           }
1064         }
1065       }
1066     }
1067     kw = next;
1068   }
1069   if (matchlist) {
1070     Setattr(nameobj, "matchlist", matchlist);
1071     Delete(matchlist);
1072   }
1073 }
1074
1075 void Swig_name_nameobj_add(Hash *name_hash, List *name_list, String *prefix, String *name, SwigType *decl, Hash *nameobj) {
1076   String *nname = 0;
1077   if (name && Len(name)) {
1078     String *target_fmt = Getattr(nameobj, "targetfmt");
1079     nname = prefix ? NewStringf("%s::%s", prefix, name) : NewString(name);
1080     if (target_fmt) {
1081       String *tmp = NewStringf(target_fmt, nname);
1082       Delete(nname);
1083       nname = tmp;
1084     }
1085   }
1086
1087   if (!nname || !Len(nname) || Getattr(nameobj, "fullname") ||  /* any of these options trigger a 'list' nameobj */
1088       Getattr(nameobj, "sourcefmt") || Getattr(nameobj, "matchlist")) {
1089     if (decl)
1090       Setattr(nameobj, "decl", decl);
1091     if (nname && Len(nname))
1092       Setattr(nameobj, "targetname", nname);
1093     /* put the new nameobj at the beginnig of the list, such that the
1094        last inserted rule take precedence */
1095     Insert(name_list, 0, nameobj);
1096   } else {
1097     /* here we add an old 'hash' nameobj, simple and fast */
1098     Swig_name_object_set(name_hash, nname, decl, nameobj);
1099   }
1100   Delete(nname);
1101 }
1102
1103 /* -----------------------------------------------------------------------------
1104  * int Swig_name_match_nameobj()
1105  *
1106  * Apply and check the nameobj's math list to the node
1107  * 
1108  * ----------------------------------------------------------------------------- */
1109
1110 static DOH *Swig_get_lattr(Node *n, List *lattr) {
1111   DOH *res = 0;
1112   int ilen = Len(lattr);
1113   int i;
1114   for (i = 0; n && (i < ilen); ++i) {
1115     String *nattr = Getitem(lattr, i);
1116     res = Getattr(n, nattr);
1117 #ifdef SWIG_DEBUG
1118     if (!res) {
1119       Printf(stdout, "missing %s %s %s\n", nattr, Getattr(n, "name"), Getattr(n, "member"));
1120     } else {
1121       Printf(stdout, "lattr %d %s %s\n", i, nattr, DohIsString(res) ? res : Getattr(res, "name"));
1122     }
1123 #endif
1124     n = res;
1125   }
1126   return res;
1127 }
1128
1129 #if defined(HAVE_RXSPENCER)
1130 #include <sys/types.h>
1131 #include <rxspencer/regex.h>
1132 #define USE_RXSPENCER
1133 #endif
1134
1135 #if defined(USE_RXSPENCER)
1136 int Swig_name_rxsmatch_value(String *mvalue, String *value) {
1137   int match = 0;
1138   char *cvalue = Char(value);
1139   char *cmvalue = Char(mvalue);
1140   regex_t compiled;
1141   int retval = regcomp(&compiled, cmvalue, REG_EXTENDED | REG_NOSUB);
1142   if (retval != 0)
1143     return 0;
1144   retval = regexec(&compiled, cvalue, 0, 0, 0);
1145   match = (retval == REG_NOMATCH) ? 0 : 1;
1146 #ifdef SWIG_DEBUG
1147   Printf(stdout, "rxsmatch_value: %s %s %d\n", cvalue, cmvalue, match);
1148 #endif
1149   regfree(&compiled);
1150   return match;
1151 }
1152 #else
1153 int Swig_name_rxsmatch_value(String *mvalue, String *value) {
1154   (void) mvalue;
1155   (void) value;
1156   return 0;
1157 }
1158 #endif
1159
1160 int Swig_name_match_value(String *mvalue, String *value) {
1161 #if defined(SWIG_USE_SIMPLE_MATCHOR)
1162   int match = 0;
1163   char *cvalue = Char(value);
1164   char *cmvalue = Char(mvalue);
1165   char *sep = strchr(cmvalue, '|');
1166   while (sep && !match) {
1167     match = strncmp(cvalue, cmvalue, sep - cmvalue) == 0;
1168 #ifdef SWIG_DEBUG
1169     Printf(stdout, "match_value: %s %s %d\n", cvalue, cmvalue, match);
1170 #endif
1171     cmvalue = sep + 1;
1172     sep = strchr(cmvalue, '|');
1173   }
1174   if (!match) {
1175     match = strcmp(cvalue, cmvalue) == 0;
1176 #ifdef SWIG_DEBUG
1177     Printf(stdout, "match_value: %s %s %d\n", cvalue, cmvalue, match);
1178 #endif
1179   }
1180   return match;
1181 #else
1182   return Equal(mvalue, value);
1183 #endif
1184 }
1185
1186
1187 int Swig_name_match_nameobj(Hash *rn, Node *n) {
1188   int match = 1;
1189   List *matchlist = Getattr(rn, "matchlist");
1190 #ifdef SWIG_DEBUG
1191   Printf(stdout, "Swig_name_match_nameobj: %s\n", Getattr(n, "name"));
1192 #endif
1193   if (matchlist) {
1194     int ilen = Len(matchlist);
1195     int i;
1196     for (i = 0; match && (i < ilen); ++i) {
1197       Node *mi = Getitem(matchlist, i);
1198       List *lattr = Getattr(mi, "attrlist");
1199       String *nval = Swig_get_lattr(n, lattr);
1200       int notmatch = GetFlag(mi, "notmatch");
1201       int rxsmatch = GetFlag(mi, "rxsmatch");
1202 #ifdef SWIG_DEBUG
1203       Printf(stdout, "mi %d %s re %d not %d \n", i, nval, notmatch, rxsmatch);
1204       if (rxsmatch) {
1205         Printf(stdout, "rxsmatch %s\n", lattr);
1206       }
1207 #endif
1208       match = 0;
1209       if (nval) {
1210         String *kwval = Getattr(mi, "value");
1211         match = rxsmatch ? Swig_name_rxsmatch_value(kwval, nval)
1212             : Swig_name_match_value(kwval, nval);
1213 #ifdef SWIG_DEBUG
1214         Printf(stdout, "val %s %s %d %d \n", nval, kwval, match, ilen);
1215 #endif
1216       }
1217       if (notmatch)
1218         match = !match;
1219     }
1220   }
1221 #ifdef SWIG_DEBUG
1222   Printf(stdout, "Swig_name_match_nameobj: %d\n", match);
1223 #endif
1224   return match;
1225 }
1226
1227 /* -----------------------------------------------------------------------------
1228  * Hash *Swig_name_nameobj_lget()
1229  *
1230  * Get a nameobj (rename/namewarn) from the list of filters
1231  * 
1232  * ----------------------------------------------------------------------------- */
1233
1234 Hash *Swig_name_nameobj_lget(List *namelist, Node *n, String *prefix, String *name, String *decl) {
1235   Hash *res = 0;
1236   if (namelist) {
1237     int len = Len(namelist);
1238     int i;
1239     int match = 0;
1240     for (i = 0; !match && (i < len); i++) {
1241       Hash *rn = Getitem(namelist, i);
1242       String *rdecl = Getattr(rn, "decl");
1243       if (rdecl && (!decl || !Equal(rdecl, decl))) {
1244         continue;
1245       } else if (Swig_name_match_nameobj(rn, n)) {
1246         String *tname = Getattr(rn, "targetname");
1247         if (tname) {
1248           String *sfmt = Getattr(rn, "sourcefmt");
1249           String *sname = 0;
1250           int fullname = GetFlag(rn, "fullname");
1251           int rxstarget = GetFlag(rn, "rxstarget");
1252           if (sfmt) {
1253             if (fullname && prefix) {
1254               String *pname = NewStringf("%s::%s", prefix, name);
1255               sname = NewStringf(sfmt, pname);
1256               Delete(pname);
1257             } else {
1258               sname = NewStringf(sfmt, name);
1259             }
1260           } else {
1261             if (fullname && prefix) {
1262               sname = NewStringf("%s::%s", prefix, name);
1263             } else {
1264               sname = name;
1265               DohIncref(name);
1266             }
1267           }
1268           match = rxstarget ? Swig_name_rxsmatch_value(tname, sname) : Swig_name_match_value(tname, sname);
1269           Delete(sname);
1270         } else {
1271           match = 1;
1272         }
1273       }
1274       if (match) {
1275         res = rn;
1276         break;
1277       }
1278     }
1279   }
1280   return res;
1281 }
1282
1283 /* -----------------------------------------------------------------------------
1284  * Swig_name_namewarn_add
1285  *
1286  * Add a namewarn objects
1287  * 
1288  * ----------------------------------------------------------------------------- */
1289
1290 void Swig_name_namewarn_add(String *prefix, String *name, SwigType *decl, Hash *namewrn) {
1291   const char *namewrn_keys[] = { "rename", "error", "fullname", "sourcefmt", "targetfmt", 0 };
1292   Swig_name_object_attach_keys(namewrn_keys, namewrn);
1293   Swig_name_nameobj_add(Swig_name_namewarn_hash(), Swig_name_namewarn_list(), prefix, name, decl, namewrn);
1294 }
1295
1296 /* -----------------------------------------------------------------------------
1297  * Hash *Swig_name_namewarn_get()
1298  *
1299  * Return the namewarn object, if there is one.
1300  * 
1301  * ----------------------------------------------------------------------------- */
1302
1303 Hash *Swig_name_namewarn_get(Node *n, String *prefix, String *name, SwigType *decl) {
1304   if (!namewarn_hash && !namewarn_list)
1305     return 0;
1306   if (n) {
1307     /* Return in the obvious cases */
1308     if (!name || !Swig_need_name_warning(n)) {
1309       return 0;
1310     } else {
1311       String *access = Getattr(n, "access");
1312       int is_public = !access || Equal(access, "public");
1313       if (!is_public && !Swig_need_protected(n)) {
1314         return 0;
1315       }
1316     }
1317   }
1318   if (name) {
1319     /* Check to see if the name is in the hash */
1320     Hash *wrn = Swig_name_object_get(Swig_name_namewarn_hash(), prefix, name, decl);
1321     if (wrn && !Swig_name_match_nameobj(wrn, n))
1322       wrn = 0;
1323     if (!wrn) {
1324       wrn = Swig_name_nameobj_lget(Swig_name_namewarn_list(), n, prefix, name, decl);
1325     }
1326     if (wrn && Getattr(wrn, "error")) {
1327       if (n) {
1328         Swig_error(Getfile(n), Getline(n), "%s\n", Getattr(wrn, "name"));
1329       } else {
1330         Swig_error(cparse_file, cparse_line, "%s\n", Getattr(wrn, "name"));
1331       }
1332     }
1333     return wrn;
1334   } else {
1335     return 0;
1336   }
1337 }
1338
1339 /* -----------------------------------------------------------------------------
1340  * String *Swig_name_warning()
1341  *
1342  * Return the name warning, if there is one.
1343  * 
1344  * ----------------------------------------------------------------------------- */
1345
1346 String *Swig_name_warning(Node *n, String *prefix, String *name, SwigType *decl) {
1347   Hash *wrn = Swig_name_namewarn_get(n, prefix, name, decl);
1348   return (name && wrn) ? Getattr(wrn, "name") : 0;
1349 }
1350
1351 /* -----------------------------------------------------------------------------
1352  * Swig_name_rename_add()
1353  *
1354  * Manage the rename objects
1355  * 
1356  * ----------------------------------------------------------------------------- */
1357
1358 static void single_rename_add(String *prefix, String *name, SwigType *decl, Hash *newname) {
1359   Swig_name_nameobj_add(Swig_name_rename_hash(), Swig_name_rename_list(), prefix, name, decl, newname);
1360 }
1361
1362 /* Add a new rename. Works much like new_feature including default argument handling. */
1363 void Swig_name_rename_add(String *prefix, String *name, SwigType *decl, Hash *newname, ParmList *declaratorparms) {
1364
1365   ParmList *declparms = declaratorparms;
1366
1367   const char *rename_keys[] = { "fullname", "sourcefmt", "targetfmt", "continue", "rxstarget", 0 };
1368   Swig_name_object_attach_keys(rename_keys, newname);
1369
1370   /* Add the name */
1371   single_rename_add(prefix, name, decl, newname);
1372
1373   /* Add extra names if there are default parameters in the parameter list */
1374   if (decl) {
1375     int constqualifier = SwigType_isconst(decl);
1376     while (declparms) {
1377       if (ParmList_has_defaultargs(declparms)) {
1378
1379         /* Create a parameter list for the new rename by copying all
1380            but the last (defaulted) parameter */
1381         ParmList *newparms = CopyParmListMax(declparms,ParmList_len(declparms)-1);
1382
1383         /* Create new declaration - with the last parameter removed */
1384         SwigType *newdecl = Copy(decl);
1385         Delete(SwigType_pop_function(newdecl)); /* remove the old parameter list from newdecl */
1386         SwigType_add_function(newdecl, newparms);
1387         if (constqualifier)
1388           SwigType_add_qualifier(newdecl, "const");
1389
1390         single_rename_add(prefix, name, newdecl, newname);
1391         declparms = newparms;
1392         Delete(newdecl);
1393       } else {
1394         declparms = 0;
1395       }
1396     }
1397   }
1398 }
1399
1400
1401 /* Create a name applying rename/namewarn if needed */
1402 static String *apply_rename(String *newname, int fullname, String *prefix, String *name) {
1403   String *result = 0;
1404   if (newname && Len(newname)) {
1405     if (Strcmp(newname, "$ignore") == 0) {
1406       result = Copy(newname);
1407     } else {
1408       char *cnewname = Char(newname);
1409       if (cnewname) {
1410         int destructor = name && (*(Char(name)) == '~');
1411         String *fmt = newname;
1412         /* use name as a fmt, but avoid C++ "%" and "%=" operators */
1413         if (Len(newname) > 1 && strchr(cnewname, '%') && !(strcmp(cnewname, "%=") == 0)) {
1414           if (fullname && prefix) {
1415             result = NewStringf(fmt, prefix, name);
1416           } else {
1417             result = NewStringf(fmt, name);
1418           }
1419         } else {
1420           result = Copy(newname);
1421         }
1422         if (destructor && result && (*(Char(result)) != '~')) {
1423           Insert(result, 0, "~");
1424         }
1425       }
1426     }
1427   }
1428
1429   return result;
1430 }
1431
1432 /* -----------------------------------------------------------------------------
1433  * String *Swig_name_make()
1434  *
1435  * Make a name after applying all the rename/namewarn objects
1436  * 
1437  * ----------------------------------------------------------------------------- */
1438
1439 String *Swig_name_make(Node *n, String *prefix, const_String_or_char_ptr cname, SwigType *decl, String *oldname) {
1440   String *nname = 0;
1441   String *result = 0;
1442   String *name = NewString(cname);
1443   Hash *wrn = 0;
1444   String *rdecl = 0;
1445   String *rname = 0;
1446
1447   /* very specific hack for template constructors/destructors */
1448 #ifdef SWIG_DEBUG
1449   Printf(stdout, "Swig_name_make: looking for %s %s %s %s\n", prefix, name, decl, oldname);
1450 #endif
1451
1452   if (name && n && SwigType_istemplate(name)) {
1453     String *nodetype = nodeType(n);
1454     if (nodetype && (Equal(nodetype, "constructor") || Equal(nodetype, "destructor"))) {
1455       String *nprefix = NewStringEmpty();
1456       String *nlast = NewStringEmpty();
1457       String *tprefix;
1458       Swig_scopename_split(name, &nprefix, &nlast);
1459       tprefix = SwigType_templateprefix(nlast);
1460       Delete(nlast);
1461       if (Len(nprefix)) {
1462         Append(nprefix, "::");
1463         Append(nprefix, tprefix);
1464         Delete(tprefix);
1465         rname = nprefix;
1466       } else {
1467         rname = tprefix;
1468         Delete(nprefix);
1469       }
1470       rdecl = Copy(decl);
1471       Replaceall(rdecl, name, rname);
1472 #ifdef SWIG_DEBUG
1473       Printf(stdout, "SWIG_name_make: use new name %s %s : %s %s\n", name, decl, rname, rdecl);
1474 #endif
1475       decl = rdecl;
1476       Delete(name);
1477       name = rname;
1478     }
1479   }
1480
1481
1482   if (rename_hash || rename_list || namewarn_hash || namewarn_list) {
1483     Hash *rn = Swig_name_object_get(Swig_name_rename_hash(), prefix, name, decl);
1484     if (!rn || !Swig_name_match_nameobj(rn, n)) {
1485       rn = Swig_name_nameobj_lget(Swig_name_rename_list(), n, prefix, name, decl);
1486       if (rn) {
1487         String *sfmt = Getattr(rn, "sourcefmt");
1488         int fullname = GetFlag(rn, "fullname");
1489         if (fullname && prefix) {
1490           String *sname = NewStringf("%s::%s", prefix, name);
1491           Delete(name);
1492           name = sname;
1493           prefix = 0;
1494         }
1495         if (sfmt) {
1496           String *sname = NewStringf(sfmt, name);
1497           Delete(name);
1498           name = sname;
1499         }
1500       }
1501     }
1502     if (rn) {
1503       String *newname = Getattr(rn, "name");
1504       int fullname = GetFlag(rn, "fullname");
1505       result = apply_rename(newname, fullname, prefix, name);
1506     }
1507     if (result && !Equal(result, name)) {
1508       /* operators in C++ allow aliases, we look for them */
1509       char *cresult = Char(result);
1510       if (cresult && (strncmp(cresult, "operator ", 9) == 0)) {
1511         String *nresult = Swig_name_make(n, prefix, result, decl, oldname);
1512         if (!Equal(nresult, result)) {
1513           Delete(result);
1514           result = nresult;
1515         } else {
1516           Delete(nresult);
1517         }
1518       }
1519     }
1520     nname = result ? result : name;
1521     wrn = Swig_name_namewarn_get(n, prefix, nname, decl);
1522     if (wrn) {
1523       String *rename = Getattr(wrn, "rename");
1524       if (rename) {
1525         String *msg = Getattr(wrn, "name");
1526         int fullname = GetFlag(wrn, "fullname");
1527         if (result)
1528           Delete(result);
1529         result = apply_rename(rename, fullname, prefix, name);
1530         if ((msg) && (Len(msg))) {
1531           if (!Getmeta(nname, "already_warned")) {
1532             if (n) {
1533               SWIG_WARN_NODE_BEGIN(n);
1534               Swig_warning(0, Getfile(n), Getline(n), "%s\n", msg);
1535               SWIG_WARN_NODE_END(n);
1536             } else {
1537               Swig_warning(0, Getfile(name), Getline(name), "%s\n", msg);
1538             }
1539             Setmeta(nname, "already_warned", "1");
1540           }
1541         }
1542       }
1543     }
1544   }
1545   if (!result || !Len(result)) {
1546     if (result)
1547       Delete(result);
1548     if (oldname) {
1549       result = NewString(oldname);
1550     } else {
1551       result = NewString(cname);
1552     }
1553   }
1554   Delete(name);
1555
1556 #ifdef SWIG_DEBUG
1557   Printf(stdout, "Swig_name_make: result  '%s' '%s'\n", cname, result);
1558 #endif
1559
1560   return result;
1561 }
1562
1563 /* -----------------------------------------------------------------------------
1564  * void Swig_name_inherit()
1565  *
1566  * Inherit namewarn,rename, and feature objects
1567  * 
1568  * ----------------------------------------------------------------------------- */
1569
1570 void Swig_name_inherit(String *base, String *derived) {
1571   /*  Printf(stdout,"base = '%s', derived = '%s'\n", base, derived); */
1572   Swig_name_object_inherit(Swig_name_rename_hash(), base, derived);
1573   Swig_name_object_inherit(Swig_name_namewarn_hash(), base, derived);
1574   Swig_name_object_inherit(Swig_cparse_features(), base, derived);
1575 }
1576
1577 /* -----------------------------------------------------------------------------
1578  * void Swig_name_decl()
1579  *
1580  * Return a stringified version of a C/C++ declaration without the return type.
1581  * The node passed in is expected to be a function. Some example return values:
1582  *   "MyNameSpace::MyTemplate<MyNameSpace::ABC >::~MyTemplate()"
1583  *   "MyNameSpace::ABC::ABC(int,double)"
1584  *   "MyNameSpace::ABC::constmethod(int) const"
1585  * 
1586  * ----------------------------------------------------------------------------- */
1587
1588 String *Swig_name_decl(Node *n) {
1589   String *qname;
1590   String *decl;
1591   String *qualifier = Swig_symbol_qualified(n);
1592   String *name = Swig_scopename_last(Getattr(n, "name"));
1593   if (qualifier)
1594     qualifier = SwigType_namestr(qualifier);
1595
1596   /* Very specific hack for template constructors/destructors */
1597   if (SwigType_istemplate(name)) {
1598     String *nodetype = nodeType(n);
1599     if (nodetype && (Equal(nodetype, "constructor") || Equal(nodetype, "destructor"))) {
1600       String *nprefix = NewStringEmpty();
1601       String *nlast = NewStringEmpty();
1602       String *tprefix;
1603       Swig_scopename_split(name, &nprefix, &nlast);
1604       tprefix = SwigType_templateprefix(nlast);
1605       Delete(nlast);
1606       Delete(name);
1607       name = tprefix;
1608     }
1609   }
1610
1611   qname = NewString("");
1612   if (qualifier && Len(qualifier) > 0)
1613     Printf(qname, "%s::", qualifier);
1614   Printf(qname, "%s", SwigType_str(name, 0));
1615
1616   decl = NewStringf("%s(%s)%s", qname, ParmList_errorstr(Getattr(n, "parms")), SwigType_isconst(Getattr(n, "decl")) ? " const" : "");
1617
1618   Delete(name);
1619   Delete(qualifier);
1620   Delete(qname);
1621
1622   return decl;
1623 }
1624
1625 /* -----------------------------------------------------------------------------
1626  * void Swig_name_fulldecl()
1627  *
1628  * Return a stringified version of a C/C++ declaration including the return type.
1629  * The node passed in is expected to be a function. Some example return values:
1630  *   "MyNameSpace::MyTemplate<MyNameSpace::ABC >::~MyTemplate()"
1631  *   "MyNameSpace::ABC::ABC(int,double)"
1632  *   "int * MyNameSpace::ABC::constmethod(int) const"
1633  * 
1634  * ----------------------------------------------------------------------------- */
1635
1636 String *Swig_name_fulldecl(Node *n) {
1637   String *decl = Swig_name_decl(n);
1638   String *type = Getattr(n, "type");
1639   String *nodetype = nodeType(n);
1640   String *fulldecl;
1641   /* add on the return type */
1642   if (nodetype && (Equal(nodetype, "constructor") || Equal(nodetype, "destructor"))) {
1643     fulldecl = decl;
1644   } else {
1645     String *t = SwigType_str(type, 0);
1646     fulldecl = NewStringf("%s %s", t, decl);
1647     Delete(decl);
1648     Delete(t);
1649   }
1650   return fulldecl;
1651 }
1652