Salome HOME
Merge from BR_PORTING_VTK6 01/03/2013
[modules/paravis.git] / src / ParaView / vtkParseExtras.c
1 /*=========================================================================
2
3   Program:   Visualization Toolkit
4   Module:    vtkParseExtras.c
5
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9
10      This software is distributed WITHOUT ANY WARRANTY; without even
11      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12      PURPOSE.  See the above copyright notice for more information.
13
14 =========================================================================*/
15 /*-------------------------------------------------------------------------
16   Copyright (c) 2011 David Gobbi.
17
18   Contributed to the VisualizationToolkit by the author in May 2011
19   under the terms of the Visualization Toolkit 2008 copyright.
20 -------------------------------------------------------------------------*/
21
22 #include "vtkParseExtras.h"
23 #include "vtkParseString.h"
24 #include "vtkType.h"
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <ctype.h>
29 #include <assert.h>
30
31 /* skip over an identifier */
32 static size_t vtkparse_id_len(const char *text)
33 {
34   size_t i = 0;
35   char c = text[0];
36
37   if ((c >= 'a' && c <= 'z') ||
38       (c >= 'A' && c <= 'Z') ||
39        c == '_')
40     {
41     do
42       {
43       c = text[++i];
44       }
45     while ((c >= 'a' && c <= 'z') ||
46            (c >= 'A' && c <= 'Z') ||
47            (c >= '0' && c <= '9') ||
48            c == '_');
49     }
50
51   return i;
52 }
53
54 /* skip over numbers, int or float, including suffixes */
55 static size_t vtkparse_number_len(const char *text)
56 {
57   size_t i = 0;
58   char c = text[0];
59
60   if (c == '.')
61     {
62     c = text[1];
63     }
64
65   if (c >= '0' && c <= '9')
66     {
67     do
68       {
69       do
70         {
71         c = text[++i];
72         }
73       while ((c >= '0' && c <= '9') ||
74              (c >= 'a' && c <= 'z') ||
75              (c >= 'A' && c <= 'Z') ||
76              c == '_' || c == '.');
77       }
78     while ((c == '-' || c == '+') &&
79            (text[i-1] == 'e' || text[i-1] == 'E'));
80     }
81
82   return i;
83 }
84
85 /* skip over string and char literals. */
86 static size_t vtkparse_quote_len(const char *text)
87 {
88   size_t i = 0;
89   const char qc = text[0];
90   char c = text[0];
91
92   if (c == '\'' || c == '\"')
93     {
94     do
95       {
96       do
97         {
98         c = text[++i];
99         }
100       while (c != qc && c != '\n' && c != '\0');
101       }
102     while (c == qc && text[i-1] == '\\');
103
104     if (c == qc)
105       {
106       ++i;
107       }
108     }
109
110   return i;
111 }
112
113 /* skip over an expression in brackets */
114 static size_t vtkparse_bracket_len(const char *text)
115 {
116   size_t i = 0;
117   size_t j = 1;
118   char bc = text[0];
119   char tc = 0;
120   char semi = ';';
121   char c;
122
123   if (bc == '(') { tc = ')'; }
124   else if (bc == '[') { tc = ']'; }
125   else if (bc == '{') { tc = '}'; semi = '\0'; }
126   else if (bc == '<') { tc = '>'; }
127   else { return 0; }
128
129   do
130     {
131     i += j;
132     j = 1;
133     c = text[i];
134     if (c == '\'' || c == '\"')
135       {
136       j = vtkparse_quote_len(&text[i]);
137       }
138     else if (c == bc || c == '(' || c == '[' || c == '{')
139       {
140       j = vtkparse_bracket_len(&text[i]);
141       }
142     }
143   while (c != tc && c != ')' && c != ']' && c != '}' &&
144          c != '\0' && c != '\n' && c != semi && j != 0);
145
146   if (c == tc)
147     {
148     i++;
149     }
150
151   return i;
152 }
153
154 /* skip over a name that is neither scoped or templated, return the
155  * total number of characters in the name */
156 size_t vtkParse_IdentifierLength(const char *text)
157 {
158   return vtkparse_id_len(text);
159 }
160
161 /* skip over a name that might be templated, return the
162  * total number of characters in the name */
163 size_t vtkParse_UnscopedNameLength(const char *text)
164 {
165   size_t i = 0;
166
167   i += vtkparse_id_len(text);
168   if (text[i] == '<')
169     {
170     i += vtkparse_bracket_len(&text[i]);
171     if (text[i-1] != '>')
172       {
173       fprintf(stderr, "Bad template args %*.*s\n", (int)i, (int)i, text);
174       assert(text[i-1] == '>');
175       return 0;
176       }
177     }
178
179   return i;
180 }
181
182 /* skip over a name that might be scoped or templated, return the
183  * total number of characters in the name */
184 size_t vtkParse_NameLength(const char *text)
185 {
186   size_t i = 0;
187   do
188     {
189     if (text[i] == ':' && text[i+1] == ':') { i += 2; }
190     i += vtkParse_UnscopedNameLength(&text[i]);
191     }
192   while (text[i] == ':' && text[i+1] == ':');
193   return i;
194 }
195
196 /* Search and replace, return the initial string if no replacements
197  * occurred, otherwise return a new string. */
198 static const char *vtkparse_string_replace(
199   StringCache *cache, const char *str1,
200   int n, const char *name[], const char *val[])
201 {
202   const char *cp = str1;
203   char result_store[1024];
204   size_t resultMaxLen = 1024;
205   char *result, *tmp;
206   int k;
207   size_t i, j, l, m;
208   size_t lastPos, nameBegin, nameEnd;
209   int replaced = 0;
210   int any_replaced = 0;
211
212   result = result_store;
213
214   if (n == 0)
215     {
216     return str1;
217     }
218
219   i = 0;
220   j = 0;
221   result[j] = '\0';
222
223   while (cp[i] != '\0')
224     {
225     lastPos = i;
226
227     /* skip all chars that aren't part of a name */
228     while ((cp[i] < 'a' || cp[i] > 'z') &&
229            (cp[i] < 'A' || cp[i] > 'Z') &&
230            cp[i] != '_' && cp[i] != '\0')
231       {
232       if (cp[i] == '\'' || cp[i] == '\"')
233         {
234         i += vtkparse_quote_len(&cp[i]);
235         }
236       else if (cp[i] >= '0' && cp[i] <= '9')
237         {
238         i += vtkparse_number_len(&cp[i]);
239         }
240       else
241         {
242         i++;
243         }
244       }
245     nameBegin = i;
246
247     /* skip all chars that are part of a name */
248     i += vtkparse_id_len(&cp[i]);
249     nameEnd = i;
250
251     /* search through the list of names to replace */
252     replaced = 0;
253     m = nameEnd - nameBegin;
254     for (k = 0; k < n; k++)
255       {
256       l = strlen(name[k]);
257       if (l > 0 && l == m && strncmp(&cp[nameBegin], name[k], l) == 0)
258         {
259         m = strlen(val[k]);
260         replaced = 1;
261         any_replaced = 1;
262         break;
263         }
264       }
265
266     /* expand the storage space if needed */
267     if (j + m + (nameBegin - lastPos) + 1 >= resultMaxLen)
268       {
269       resultMaxLen *= 2;
270       tmp = (char *)malloc(resultMaxLen);
271       strcpy(tmp, result);
272       if (result != result_store)
273          {
274          free(result);
275          }
276        result = tmp;
277        }
278
279     /* copy the old bits */
280     if (nameBegin > lastPos)
281       {
282       strncpy(&result[j], &cp[lastPos], nameBegin - lastPos);
283       j += (nameBegin - lastPos);
284       }
285
286     /* do the replacement */
287     if (replaced)
288       {
289       strncpy(&result[j], val[k], m);
290       j += m;
291       /* guard against creating double ">>" */
292       if (val[k][m-1] == '>' && cp[nameEnd] == '>')
293         {
294         result[j++] = ' ';
295         }
296       }
297     else if (nameEnd > nameBegin)
298       {
299       strncpy(&result[j], &cp[nameBegin], nameEnd - nameBegin);
300       j += (nameEnd - nameBegin);
301       }
302
303     result[j] = '\0';
304     }
305
306   if (cache)
307     {
308     if (any_replaced)
309       {
310       /* use the efficient CacheString method */
311       cp = vtkParse_CacheString(cache, result, j);
312       if (result != result_store)
313         {
314         free(result);
315         }
316       }
317     }
318   else
319     {
320     if (any_replaced)
321       {
322       /* return a string that was allocated with malloc */
323       if (result == result_store)
324         {
325         tmp = (char *)malloc(strlen(result) + 1);
326         strcpy(tmp, result);
327         result = tmp;
328         }
329       cp = result;
330       }
331     }
332
333   return cp;
334 }
335
336 /* Wherever one of the specified names exists inside a Value or inside
337  * a Dimension size, replace it with the corresponding val string. */
338 void vtkParse_ExpandValues(
339   ValueInfo *valinfo, StringCache *cache,
340   int n, const char *name[], const char *val[])
341 {
342   int j, m, dim, count;
343   const char *cp;
344
345   if (valinfo->Value)
346     {
347     valinfo->Value = vtkparse_string_replace(
348       cache, valinfo->Value, n, name, val);
349     }
350
351   m = valinfo->NumberOfDimensions;
352   if (m)
353     {
354     count = 1;
355     for (j = 0; j < m; j++)
356       {
357       cp = valinfo->Dimensions[j];
358       if (cp)
359         {
360         cp = vtkparse_string_replace(cache, cp, n, name, val);
361         valinfo->Dimensions[j] = cp;
362
363         /* check whether dimension has become an integer literal */
364         if (cp[0] == '0' && (cp[1] == 'x' || cp[1] == 'X')) { cp += 2; }
365         while (*cp >= '0' && *cp <= '9') { cp++; }
366         while (*cp == 'u' || *cp == 'l' || *cp == 'U' || *cp == 'L') { cp++; }
367         dim = 0;
368         if (*cp == '\0')
369           {
370           dim = (int)strtol(valinfo->Dimensions[j], NULL, 0);
371           }
372         count *= dim;
373         }
374       }
375
376     /* update count if all values are integer literals */
377     if (count)
378       {
379       valinfo->Count = count;
380       }
381     }
382 }
383
384 /* Expand a typedef within a type declaration. */
385 void vtkParse_ExpandTypedef(
386   ValueInfo *valinfo, ValueInfo *typedefinfo)
387 {
388   const char *classname;
389   unsigned int baseType;
390   unsigned int pointers;
391   unsigned int refbit;
392   unsigned int qualifiers;
393   unsigned int tmp1, tmp2;
394   int i;
395
396   classname = typedefinfo->Class;
397   baseType = (typedefinfo->Type & VTK_PARSE_BASE_TYPE);
398   pointers = (typedefinfo->Type & VTK_PARSE_POINTER_MASK);
399   refbit = (valinfo->Type & VTK_PARSE_REF);
400   qualifiers = (typedefinfo->Type & VTK_PARSE_CONST);
401
402   /* handle const */
403   if ((valinfo->Type & VTK_PARSE_CONST) != 0)
404     {
405     if ((pointers & VTK_PARSE_POINTER_LOWMASK) != 0)
406       {
407       if ((pointers & VTK_PARSE_POINTER_LOWMASK) != VTK_PARSE_ARRAY)
408         {
409         /* const turns into const pointer */
410         pointers = (pointers & ~VTK_PARSE_POINTER_LOWMASK);
411         pointers = (pointers | VTK_PARSE_CONST_POINTER);
412         }
413       }
414     else
415       {
416       /* const remains as const value */
417       qualifiers = (qualifiers | VTK_PARSE_CONST);
418       }
419     }
420
421   /* make a reversed copy of the pointer bitfield */
422   tmp1 = (valinfo->Type & VTK_PARSE_POINTER_MASK);
423   tmp2 = 0;
424   while (tmp1)
425     {
426     tmp2 = ((tmp2 << 2) | (tmp1 & VTK_PARSE_POINTER_LOWMASK));
427     tmp1 = ((tmp1 >> 2) & VTK_PARSE_POINTER_MASK);
428     }
429
430   /* turn pointers into zero-element arrays where necessary */
431   if ((pointers & VTK_PARSE_POINTER_LOWMASK) == VTK_PARSE_ARRAY)
432     {
433     tmp2 = ((tmp2 >> 2) & VTK_PARSE_POINTER_MASK);
434     while (tmp2)
435       {
436       vtkParse_AddStringToArray(
437         &valinfo->Dimensions, &valinfo->NumberOfDimensions, "");
438       tmp2 = ((tmp2 >> 2) & VTK_PARSE_POINTER_MASK);
439       }
440     }
441   else
442     {
443     /* combine the pointers */
444     while (tmp2)
445       {
446       pointers = ((pointers << 2) | (tmp2 & VTK_PARSE_POINTER_LOWMASK));
447       tmp2 = ((tmp2 >> 2) & VTK_PARSE_POINTER_MASK);
448       }
449     }
450
451   /* combine the arrays */
452   for (i = 0; i < typedefinfo->NumberOfDimensions; i++)
453     {
454     vtkParse_AddStringToArray(
455       &valinfo->Dimensions, &valinfo->NumberOfDimensions,
456       typedefinfo->Dimensions[i]);
457     }
458   if (valinfo->NumberOfDimensions > 1)
459     {
460     pointers = ((pointers & ~VTK_PARSE_POINTER_LOWMASK) | VTK_PARSE_ARRAY);
461     }
462
463   /* put everything together */
464   valinfo->Type = (baseType | pointers | refbit | qualifiers);
465   valinfo->Class = classname;
466   valinfo->Function = typedefinfo->Function;
467   valinfo->Count *= typedefinfo->Count;
468 }
469
470 /* Expand any unrecognized types within a variable, parameter, or typedef
471  * that match any of the supplied typedefs. The expansion is done in-place. */
472 void vtkParse_ExpandTypedefs(
473   ValueInfo *val, StringCache *cache,
474   int n, const char *names[], const char *values[],
475   ValueInfo *typedefinfo[])
476 {
477   int i;
478
479   if (((val->Type & VTK_PARSE_BASE_TYPE) == VTK_PARSE_OBJECT ||
480        (val->Type & VTK_PARSE_BASE_TYPE) == VTK_PARSE_UNKNOWN) &&
481       val->Class != 0)
482    {
483    for (i = 0; i < n; i++)
484      {
485      if (typedefinfo[i] && strcmp(val->Class, typedefinfo[i]->Name) == 0)
486        {
487        vtkParse_ExpandTypedef(val, typedefinfo[i]);
488        break;
489        }
490      }
491    if (i == n)
492      {
493      /* in case type appears as a template arg of another type */
494      val->Class = vtkparse_string_replace(
495        cache, val->Class, n, names, values);
496      }
497    }
498 }
499
500 /* Helper struct for VTK-specific types */
501 struct vtk_type_struct
502 {
503   size_t len;
504   const char *name;
505   unsigned int type;
506 };
507
508 /* Simple utility for mapping VTK types to VTK_PARSE types */
509 unsigned int vtkParse_MapType(int vtktype)
510 {
511   static unsigned int typemap[] =
512   {
513     VTK_PARSE_VOID,               /* VTK_VOID                0 */
514     0,                            /* VTK_BIT                 1 */
515     VTK_PARSE_CHAR,               /* VTK_CHAR                2 */
516     VTK_PARSE_UNSIGNED_CHAR,      /* VTK_UNSIGNED_CHAR       3 */
517     VTK_PARSE_SHORT,              /* VTK_SHORT               4 */
518     VTK_PARSE_UNSIGNED_SHORT,     /* VTK_UNSIGNED_SHORT      5 */
519     VTK_PARSE_INT,                /* VTK_INT                 6 */
520     VTK_PARSE_UNSIGNED_INT,       /* VTK_UNSIGNED_INT        7 */
521     VTK_PARSE_LONG,               /* VTK_LONG                8 */
522     VTK_PARSE_UNSIGNED_LONG,      /* VTK_UNSIGNED_LONG       9 */
523     VTK_PARSE_FLOAT,              /* VTK_FLOAT              10 */
524     VTK_PARSE_DOUBLE,             /* VTK_DOUBLE             11 */
525     VTK_PARSE_ID_TYPE,            /* VTK_ID_TYPE            12 */
526     VTK_PARSE_STRING,             /* VTK_STRING             13 */
527     0,                            /* VTK_OPAQUE             14 */
528     VTK_PARSE_SIGNED_CHAR,        /* VTK_SIGNED_CHAR        15 */
529     VTK_PARSE_LONG_LONG,          /* VTK_LONG_LONG          16 */
530     VTK_PARSE_UNSIGNED_LONG_LONG, /* VTK_UNSIGNED_LONG_LONG 17 */
531     VTK_PARSE___INT64,            /* VTK___INT64            18 */
532     VTK_PARSE_UNSIGNED___INT64,   /* VTK_UNSIGNED___INT64   19 */
533     0,                            /* VTK_VARIANT            20 */
534     0,                            /* VTK_OBJECT             21 */
535     VTK_PARSE_UNICODE_STRING      /* VTK_UNICODE_STRING     22 */
536     };
537
538   if (vtktype > 0 && vtktype <= VTK_UNICODE_STRING)
539     {
540     return typemap[vtktype];
541     }
542   return 0;
543 }
544
545 /* Get a type from a type name, and return the number of characters used.
546  * If the "classname" argument is not NULL, then it is used to return
547  * the short name for the type, e.g. "long int" becomes "long", while
548  * typedef names and class names are returned unchanged.  If "const"
549  * appears in the type name, then the const bit flag is set for the
550  * type, but "const" will not appear in the returned classname. */
551 size_t vtkParse_BasicTypeFromString(
552   const char *text, unsigned int *type_ptr,
553   const char **classname_ptr, size_t *len_ptr)
554 {
555   /* The various typedefs and types specific to VTK */
556   static struct vtk_type_struct vtktypes[] = {
557     { 9,  "vtkIdType", VTK_ID_TYPE },
558     { 12, "vtkStdString", VTK_STRING },
559     { 16, "vtkUnicodeString", VTK_UNICODE_STRING },
560     { 11, "vtkTypeInt8", VTK_TYPE_INT8 },
561     { 12, "vtkTypeUInt8", VTK_TYPE_UINT8 },
562     { 12, "vtkTypeInt16", VTK_TYPE_INT16 },
563     { 13, "vtkTypeUInt16", VTK_TYPE_UINT16 },
564     { 12, "vtkTypeInt32", VTK_TYPE_INT32 },
565     { 13, "vtkTypeUInt32", VTK_TYPE_UINT32 },
566     { 12, "vtkTypeInt64", VTK_TYPE_INT64 },
567     { 13, "vtkTypeUInt64", VTK_TYPE_UINT64 },
568     { 14, "vtkTypeFloat32", VTK_TYPE_FLOAT32 },
569     { 14, "vtkTypeFloat64", VTK_TYPE_FLOAT64 },
570     { 0, 0, 0 } };
571
572   /* Other typedefs and types */
573   static struct vtk_type_struct stdtypes[] = {
574     { 6,  "size_t", VTK_PARSE_SIZE_T },
575     { 7,  "ssize_t", VTK_PARSE_SSIZE_T },
576     { 7,  "ostream", VTK_PARSE_OSTREAM },
577     { 7,  "istream", VTK_PARSE_ISTREAM },
578     { 8,  "string", VTK_PARSE_STRING },
579     { 0, 0, 0 } };
580
581   const char *cp = text;
582   const char *tmpcp;
583   size_t k, n, m;
584   int i;
585   unsigned int const_bits = 0;
586   unsigned int static_bits = 0;
587   unsigned int unsigned_bits = 0;
588   unsigned int base_bits = 0;
589   const char *classname = NULL;
590   size_t len = 0;
591
592   while (*cp == ' ' || *cp == '\t') { cp++; }
593
594   while ((*cp >= 'a' && *cp <= 'z') ||
595          (*cp >= 'A' && *cp <= 'Z') ||
596          (*cp == '_') || (cp[0] == ':' && cp[1] == ':'))
597     {
598     /* skip all chars that are part of a name */
599     n = vtkParse_NameLength(cp);
600
601     if ((n == 6 && strncmp("static", cp, n) == 0) ||
602         (n == 4 && strncmp("auto", cp, n) == 0) ||
603         (n == 8 && strncmp("register", cp, n) == 0) ||
604         (n == 8 && strncmp("volatile", cp, n) == 0))
605       {
606       if (strncmp("static", cp, n) == 0)
607         {
608         static_bits = VTK_PARSE_STATIC;
609         }
610       }
611     else if (n == 5 && strncmp(cp, "const", n) == 0)
612       {
613       const_bits |= VTK_PARSE_CONST;
614       }
615     else if (n == 8 && strncmp(cp, "unsigned", n) == 0)
616       {
617       unsigned_bits |= VTK_PARSE_UNSIGNED;
618       if (base_bits == 0)
619         {
620         classname = "int";
621         base_bits = VTK_PARSE_INT;
622         }
623       }
624     else if (n == 6 && strncmp(cp, "signed", n) == 0)
625       {
626       if (base_bits == VTK_PARSE_CHAR)
627         {
628         classname = "signed char";
629         base_bits = VTK_PARSE_SIGNED_CHAR;
630         }
631       else
632         {
633         classname = "int";
634         base_bits = VTK_PARSE_INT;
635         }
636       }
637     else if (n == 3 && strncmp(cp, "int", n) == 0)
638       {
639       if (base_bits == 0)
640         {
641         classname = "int";
642         base_bits = VTK_PARSE_INT;
643         }
644       }
645     else if (n == 4 && strncmp(cp, "long", n) == 0)
646       {
647       if (base_bits == VTK_PARSE_DOUBLE)
648         {
649         classname = "long double";
650         base_bits = VTK_PARSE_LONG_DOUBLE;
651         }
652       else if (base_bits == VTK_PARSE_LONG)
653         {
654         classname = "long long";
655         base_bits = VTK_PARSE_LONG_LONG;
656         }
657       else
658         {
659         classname = "long";
660         base_bits = VTK_PARSE_LONG;
661         }
662       }
663     else if (n == 5 && strncmp(cp, "short", n) == 0)
664       {
665       classname = "short";
666       base_bits = VTK_PARSE_SHORT;
667       }
668     else if (n == 4 && strncmp(cp, "char", n) == 0)
669       {
670       if (base_bits == VTK_PARSE_INT && unsigned_bits != VTK_PARSE_UNSIGNED)
671         {
672         classname = "signed char";
673         base_bits = VTK_PARSE_SIGNED_CHAR;
674         }
675       else
676         {
677         classname = "char";
678         base_bits = VTK_PARSE_CHAR;
679         }
680       }
681     else if (n == 5 && strncmp(cp, "float", n) == 0)
682       {
683       classname = "float";
684       base_bits = VTK_PARSE_FLOAT;
685       }
686     else if (n == 6 && strncmp(cp, "double", n) == 0)
687       {
688       if (base_bits == VTK_PARSE_LONG)
689         {
690         classname = "long double";
691         base_bits = VTK_PARSE_LONG_DOUBLE;
692         }
693       else
694         {
695         classname = "double";
696         base_bits = VTK_PARSE_DOUBLE;
697         }
698       }
699     else if (n == 4 && strncmp(cp, "bool", n) == 0)
700       {
701       classname = "bool";
702       base_bits = VTK_PARSE_BOOL;
703       }
704     else if (n == 4 && strncmp(cp, "void", n) == 0)
705       {
706       classname = "void";
707       base_bits = VTK_PARSE_VOID;
708       }
709     else if (n == 7 && strncmp(cp, "__int64", n) == 0)
710       {
711       classname = "__int64";
712       base_bits = VTK_PARSE___INT64;
713       }
714     else
715       {
716       /* if type already found, break */
717       if (base_bits != 0)
718         {
719         break;
720         }
721
722       /* check vtk typedefs */
723       if (strncmp(cp, "vtk", 3) == 0)
724         {
725         for (i = 0; vtktypes[i].len != 0; i++)
726           {
727           if (n == vtktypes[i].len && strncmp(cp, vtktypes[i].name, n) == 0)
728             {
729             classname = vtktypes[i].name;
730             base_bits = vtkParse_MapType((int)vtktypes[i].type);
731             }
732           }
733         }
734
735       /* check standard typedefs */
736       if (base_bits == 0)
737         {
738         m = 0;
739         if (strncmp(cp, "::", 2) == 0) { m = 2; }
740         else if (strncmp(cp, "std::", 5) == 0) { m = 5; }
741         else if (strncmp(cp, "vtkstd::", 8) == 0) { m = 8; }
742
743         /* advance past the namespace */
744         tmpcp = cp + m;
745
746         for (i = 0; stdtypes[i].len != 0; i++)
747           {
748           if (n == stdtypes[i].len && strncmp(tmpcp, stdtypes[i].name, n) == 0)
749             {
750             classname = stdtypes[i].name;
751             base_bits = stdtypes[i].type;
752             }
753           }
754
755         /* include the namespace if present */
756         if (base_bits != 0 && m > 0)
757           {
758           classname = cp;
759           len = n;
760           }
761         }
762
763       /* anything else is assumed to be a class, enum, or who knows */
764       if (base_bits == 0)
765         {
766         base_bits = VTK_PARSE_UNKNOWN;
767         classname = cp;
768         len = n;
769
770         /* VTK classes all start with vtk */
771         if (strncmp(classname, "vtk", 3) == 0)
772           {
773           base_bits = VTK_PARSE_OBJECT;
774           /* make sure the "vtk" isn't just part of the namespace */
775           for (k = 0; k < n; k++)
776             {
777             if (cp[k] == ':')
778               {
779               base_bits = VTK_PARSE_UNKNOWN;
780               break;
781               }
782             }
783           }
784         /* Qt objects and enums */
785         else if (classname[0] == 'Q' &&
786                  ((classname[1] >= 'A' && classname[2] <= 'Z') ||
787                   strncmp(classname, "Qt::", 4) == 0))
788           {
789           base_bits = VTK_PARSE_QOBJECT;
790           }
791         }
792       }
793
794     cp += n;
795     while (*cp == ' ' || *cp == '\t') { cp++; }
796     }
797
798   if ((unsigned_bits & VTK_PARSE_UNSIGNED) != 0)
799     {
800     switch (base_bits)
801       {
802       case VTK_PARSE_CHAR:
803         classname = "unsigned char";
804         break;
805       case VTK_PARSE_SHORT:
806         classname = "unsigned short";
807         break;
808       case VTK_PARSE_INT:
809         classname = "unsigned int";
810         break;
811       case VTK_PARSE_LONG:
812         classname = "unsigned long";
813         break;
814       case VTK_PARSE_LONG_LONG:
815         classname = "unsigned long long";
816         break;
817       case VTK_PARSE___INT64:
818         classname = "unsigned __int64";
819         break;
820       }
821     }
822
823   *type_ptr = (static_bits | const_bits | unsigned_bits | base_bits);
824
825   if (classname_ptr)
826     {
827     *classname_ptr = classname;
828     if (len == 0)
829       {
830       len = strlen(classname);
831       }
832     *len_ptr = len;
833     }
834
835   return (size_t)(cp - text);
836 }
837
838 /* Parse a type description in "text" and generate a typedef named "name" */
839 size_t vtkParse_ValueInfoFromString(
840   ValueInfo *data, StringCache *cache, const char *text)
841 {
842   const char *cp = text;
843   size_t n;
844   int m, count;
845   unsigned int base_bits = 0;
846   unsigned int pointer_bits = 0;
847   unsigned int ref_bits = 0;
848   const char *classname = NULL;
849
850   /* get the basic type with qualifiers */
851   cp += vtkParse_BasicTypeFromString(cp, &base_bits, &classname, &n);
852
853   data->Class = vtkParse_CacheString(cache, classname, n);
854
855   if ((base_bits & VTK_PARSE_STATIC) != 0)
856     {
857     data->IsStatic = 1;
858     }
859
860   /* look for pointers (and const pointers) */
861   while (*cp == '*')
862     {
863     cp++;
864     pointer_bits = (pointer_bits << 2);
865     while (*cp == ' ' || *cp == '\t') { cp++; }
866     if (strncmp(cp, "const", 5) == 0 &&
867         (cp[5] < 'a' || cp[5] > 'z') &&
868         (cp[5] < 'A' || cp[5] > 'Z') &&
869         (cp[5] < '0' || cp[5] > '9') &&
870         cp[5] != '_')
871       {
872       cp += 5;
873       while (*cp == ' ' || *cp == '\t') { cp++; }
874       pointer_bits = (pointer_bits | VTK_PARSE_CONST_POINTER);
875       }
876     else
877       {
878       pointer_bits = (pointer_bits | VTK_PARSE_POINTER);
879       }
880     pointer_bits = (pointer_bits & VTK_PARSE_POINTER_MASK);
881     }
882
883   /* look for ref */
884   if (*cp == '&')
885     {
886     cp++;
887     while (*cp == ' ' || *cp == '\t') { cp++; }
888     ref_bits = VTK_PARSE_REF;
889     }
890
891   /* look for the variable name */
892   if ((*cp >= 'a' && *cp <= 'z') ||
893       (*cp >= 'A' && *cp <= 'Z') ||
894       (*cp == '_'))
895     {
896     /* skip all chars that are part of a name */
897     n = vtkparse_id_len(cp);
898     data->Name = vtkParse_CacheString(cache, cp, n);
899     cp += n;
900     while (*cp == ' ' || *cp == '\t') { cp++; }
901     }
902
903   /* look for array brackets */
904   if (*cp == '[')
905     {
906     count = 1;
907     }
908
909   while (*cp == '[')
910     {
911     n = vtkparse_bracket_len(cp);
912     if (n > 1)
913       {
914       cp++;
915       n -= 2;
916       }
917     while (*cp == ' ' || *cp == '\t') { cp++; n--; }
918     while (n > 0 && (cp[n-1] == ' ' || cp[n-1] == '\t')) { n--; }
919     vtkParse_AddStringToArray(
920       &data->Dimensions,
921       &data->NumberOfDimensions,
922       vtkParse_CacheString(cache, cp, n));
923     m = 0;
924     if (*cp >= '0' && *cp <= '9' && vtkparse_number_len(cp) == n)
925       {
926       m = (int)strtol(cp, NULL, 0);
927       }
928     count *= m;
929
930     cp += n;
931     while (*cp == ' ' || *cp == '\t') { cp++; }
932     if (*cp == ']') { cp++; }
933     while (*cp == ' ' || *cp == '\t') { cp++; }
934     }
935
936   /* add pointer indirection to correspond to first array dimension */
937   if (data->NumberOfDimensions > 1)
938     {
939     pointer_bits = ((pointer_bits << 2) | VTK_PARSE_ARRAY);
940     }
941   else if (data->NumberOfDimensions == 1)
942     {
943     pointer_bits = ((pointer_bits << 2) | VTK_PARSE_POINTER);
944     }
945   pointer_bits = (pointer_bits & VTK_PARSE_POINTER_MASK);
946
947   /* (Add code here to look for "=" followed by a value ) */
948
949   data->Type = (pointer_bits | ref_bits | base_bits);
950
951   return (cp - text);
952 }
953
954 /* Generate a C++ declaration string from a ValueInfo struct */
955 const char *vtkParse_ValueInfoToString(
956   ValueInfo *data, int *needs_free)
957 {
958   unsigned int pointer_bits = (data->Type & VTK_PARSE_POINTER_MASK);
959   unsigned int ref_bits = (data->Type & VTK_PARSE_REF);
960   unsigned int qualifier_bits = (data->Type & VTK_PARSE_CONST);
961   unsigned int reverse_bits = 0;
962   unsigned int pointer_type = 0;
963   const char *classname = data->Class;
964   const char *name = data->Name;
965   char *text = NULL;
966   size_t i = 0;
967   size_t l;
968   int j = 0;
969
970   if (pointer_bits == 0 && ref_bits == 0 && qualifier_bits == 0 &&
971       name == NULL)
972     {
973     if (needs_free)
974       {
975       *needs_free = 0;
976       }
977     return classname;
978     }
979
980   /* compute the length of string to allocate */
981   l = 6; /* for const */
982   l += 4*7; /* for pointers */
983   l += 1; /* for ref */
984   l += strlen(classname) + 1; /* for type */
985   for (j = 0; j < data->NumberOfDimensions; j++)
986     {
987     l += 2 + strlen(data->Dimensions[j]);
988     }
989   l++; /* for NULL */
990   l += 4; /* for safety */
991
992   text = (char *)malloc(l);
993
994   if ((qualifier_bits & VTK_PARSE_CONST) != 0)
995     {
996     strcpy(&text[i], "const ");
997     i += 6;
998     }
999
1000   strcpy(&text[i], classname);
1001   i += strlen(classname);
1002   text[i++] = ' ';
1003
1004   while (pointer_bits != 0)
1005     {
1006     reverse_bits <<= 2;
1007     reverse_bits |= (pointer_bits & VTK_PARSE_POINTER_LOWMASK);
1008     pointer_bits = ((pointer_bits >> 2) & VTK_PARSE_POINTER_MASK);
1009     }
1010
1011   while (reverse_bits != 0)
1012     {
1013     pointer_type = (reverse_bits & VTK_PARSE_POINTER_LOWMASK);
1014     if (pointer_type == VTK_PARSE_ARRAY ||
1015         (reverse_bits == VTK_PARSE_POINTER &&
1016          data->NumberOfDimensions > 0))
1017       {
1018       break;
1019       }
1020     else if (pointer_type == VTK_PARSE_POINTER)
1021       {
1022       text[i++] = '*';
1023       }
1024     else if (pointer_type == VTK_PARSE_CONST_POINTER)
1025       {
1026       strcpy(&text[i], "*const ");
1027       i += 7;
1028       }
1029
1030     reverse_bits = ((reverse_bits >> 2) & VTK_PARSE_POINTER_MASK);
1031     }
1032
1033   if (ref_bits)
1034     {
1035     text[i++] = '&';
1036     }
1037
1038   if (name)
1039     {
1040     strcpy(&text[i], name);
1041     i += strlen(name);
1042     }
1043
1044   for (j = 0; j < data->NumberOfDimensions; j++)
1045     {
1046     text[i++] = '[';
1047     if (data->Dimensions[j])
1048       {
1049       strcpy(&text[i], data->Dimensions[j]);
1050       i += strlen(data->Dimensions[j]);
1051       }
1052     text[i++] = ']';
1053     }
1054
1055   text[i] = '\0';
1056
1057   /* make sure enough space was allocated */
1058   assert(i < l);
1059
1060   if (needs_free)
1061     {
1062     *needs_free = 1;
1063     }
1064
1065   return text;
1066 }
1067
1068 /* Search and replace, return the initial string if no replacements
1069  * occurred, otherwise return a new string allocated with malloc. */
1070 const char *vtkParse_StringReplace(
1071   const char *str1, int n, const char *name[], const char *val[])
1072 {
1073   return vtkparse_string_replace(NULL, str1, n, name, val);
1074 }
1075
1076 /* substitute generic types and values with actual types and values */
1077 static void func_substitution(
1078   FunctionInfo *data, StringCache *cache,
1079   int m, const char *arg_names[],
1080   const char *arg_values[], ValueInfo *arg_types[]);
1081
1082 static void value_substitution(
1083   ValueInfo *data, StringCache *cache,
1084   int m, const char *arg_names[],
1085   const char *arg_values[], ValueInfo *arg_types[])
1086 {
1087   vtkParse_ExpandTypedefs(data, cache, m, arg_names, arg_values, arg_types);
1088   vtkParse_ExpandValues(data, cache, m, arg_names, arg_values);
1089
1090   if (data->Function)
1091     {
1092     func_substitution(
1093       data->Function, cache, m, arg_names, arg_values, arg_types);
1094     }
1095 }
1096
1097 static void func_substitution(
1098   FunctionInfo *data, StringCache *cache,
1099   int m, const char *arg_names[],
1100   const char *arg_values[], ValueInfo *arg_types[])
1101 {
1102   int i, n;
1103
1104   n = data->NumberOfParameters;
1105   for (i = 0; i < n; i++)
1106     {
1107     value_substitution(
1108       data->Parameters[i], cache, m, arg_names, arg_values, arg_types);
1109     }
1110
1111   if (data->ReturnValue)
1112     {
1113     value_substitution(
1114       data->ReturnValue, cache, m, arg_names, arg_values, arg_types);
1115     }
1116
1117   if (data->Signature)
1118     {
1119     data->Signature =
1120       vtkparse_string_replace(
1121         cache, data->Signature, m, arg_names, arg_values);
1122     }
1123
1124   /* legacy information for old wrappers */
1125 #ifndef VTK_PARSE_LEGACY_REMOVE
1126   n = data->NumberOfArguments;
1127   for (i = 0; i < n; i++)
1128     {
1129     data->ArgTypes[i] = data->Parameters[i]->Type;
1130     data->ArgClasses[i] = data->Parameters[i]->Class;
1131     if (data->Parameters[i]->NumberOfDimensions == 1 &&
1132         data->Parameters[i]->Count > 0)
1133       {
1134       data->ArgCounts[i] = data->Parameters[i]->Count;
1135       }
1136     }
1137
1138   if (data->ReturnValue)
1139     {
1140     data->ReturnType = data->ReturnValue->Type;
1141     data->ReturnClass = data->ReturnValue->Class;
1142     if (data->ReturnValue->NumberOfDimensions == 1 &&
1143         data->ReturnValue->Count > 0)
1144       {
1145       data->HintSize = data->ReturnValue->Count;
1146       data->HaveHint = 1;
1147       }
1148     }
1149 #endif /* VTK_PARSE_LEGACY_REMOVE */
1150 }
1151
1152 static void class_substitution(
1153   ClassInfo *data, StringCache *cache,
1154   int m, const char *arg_names[],
1155   const char *arg_values[], ValueInfo *arg_types[])
1156 {
1157   int i, n;
1158
1159   /* superclasses may be templated */
1160   n = data->NumberOfSuperClasses;
1161   for (i = 0; i < n; i++)
1162     {
1163     data->SuperClasses[i] = vtkparse_string_replace(
1164       cache, data->SuperClasses[i], m, arg_names, arg_values);
1165     }
1166
1167   n = data->NumberOfClasses;
1168   for (i = 0; i < n; i++)
1169     {
1170     class_substitution(
1171       data->Classes[i], cache, m, arg_names, arg_values, arg_types);
1172     }
1173
1174   n = data->NumberOfFunctions;
1175   for (i = 0; i < n; i++)
1176     {
1177     func_substitution(
1178       data->Functions[i], cache, m, arg_names, arg_values, arg_types);
1179     }
1180
1181   n = data->NumberOfConstants;
1182   for (i = 0; i < n; i++)
1183     {
1184     value_substitution(
1185       data->Constants[i], cache, m, arg_names, arg_values, arg_types);
1186     }
1187
1188   n = data->NumberOfVariables;
1189   for (i = 0; i < n; i++)
1190     {
1191     value_substitution(
1192       data->Variables[i], cache, m, arg_names, arg_values, arg_types);
1193     }
1194
1195   n = data->NumberOfTypedefs;
1196   for (i = 0; i < n; i++)
1197     {
1198     value_substitution(
1199       data->Typedefs[i], cache, m, arg_names, arg_values, arg_types);
1200     }
1201 }
1202
1203 /* Extract template args from a comma-separated list enclosed
1204  * in angle brackets.  Returns zero if no angle brackets found. */
1205 size_t vtkParse_DecomposeTemplatedType(
1206   const char *text, const char **classname,
1207   int nargs, const char ***argp, const char *defaults[])
1208 {
1209   size_t i, j, k, n;
1210   const char *arg;
1211   char *new_text;
1212   const char **template_args = NULL;
1213   int template_arg_count = 0;
1214
1215   n = vtkParse_NameLength(text);
1216
1217   /* is the class templated? */
1218   for (i = 0; i < n; i++)
1219     {
1220     if (text[i] == '<')
1221       {
1222       break;
1223       }
1224     }
1225
1226   if (classname)
1227     {
1228     new_text = (char *)malloc(i + 1);
1229     strncpy(new_text, text, i);
1230     new_text[i] = '\0';
1231     *classname = new_text;
1232     }
1233
1234   if (text[i] == '<')
1235     {
1236     i++;
1237     /* extract the template arguments */
1238     for (;;)
1239       {
1240       while (text[i] == ' ' || text[i] == '\t') { i++; }
1241       j = i;
1242       while (text[j] != ',' && text[j] != '>' &&
1243              text[j] != '\n' && text[j] != '\0')
1244         {
1245         if (text[j] == '<' || text[j] == '(' ||
1246             text[j] == '[' || text[j] == '{')
1247           {
1248           j += vtkparse_bracket_len(&text[j]);
1249           }
1250         else if (text[j] == '\'' || text[j] == '\"')
1251           {
1252           j += vtkparse_quote_len(&text[j]);
1253           }
1254         else
1255           {
1256           j++;
1257           }
1258         }
1259
1260       k = j;
1261       while (text[k-1] == ' ' || text[k-1] == '\t') { --k; }
1262
1263       new_text = (char *)malloc(k-i + 1);
1264       strncpy(new_text, &text[i], k-i);
1265       new_text[k-i] = '\0';
1266       vtkParse_AddStringToArray(&template_args, &template_arg_count,
1267                                 new_text);
1268
1269       assert(template_arg_count <= nargs);
1270
1271       i = j + 1;
1272
1273       if (text[j] != ',')
1274         {
1275         break;
1276         }
1277       }
1278     }
1279
1280   while (template_arg_count < nargs)
1281     {
1282     assert(defaults != NULL);
1283     arg = defaults[template_arg_count];
1284     assert(arg != NULL);
1285     new_text = (char *)malloc(strlen(arg + 1));
1286     strcpy(new_text, arg);
1287     vtkParse_AddStringToArray(&template_args, &template_arg_count, new_text);
1288     }
1289
1290   *argp = template_args;
1291
1292   return i;
1293 }
1294
1295 /* Free the list of strings returned by ExtractTemplateArgs.  */
1296 void vtkParse_FreeTemplateDecomposition(
1297   const char *name, int n, const char **args)
1298 {
1299   int i;
1300
1301   if (name)
1302     {
1303     free((char *)name);
1304     }
1305
1306   if (n > 0)
1307     {
1308     for (i = 0; i < n; i++)
1309       {
1310       free((char *)args[i]);
1311       }
1312
1313     free((char **)args);
1314     }
1315 }
1316
1317 /* Instantiate a class template by substituting the provided arguments. */
1318 void vtkParse_InstantiateClassTemplate(
1319   ClassInfo *data, StringCache *cache, int n, const char *args[])
1320 {
1321   TemplateInfo *t = data->Template;
1322   const char **new_args = NULL;
1323   const char **arg_names = NULL;
1324   ValueInfo **arg_types = NULL;
1325   int i, m;
1326   char *new_name;
1327   size_t k;
1328
1329   if (t == NULL)
1330     {
1331     fprintf(stderr, "vtkParse_InstantiateClassTemplate: "
1332             "this class is not templated.\n");
1333     return;
1334     }
1335
1336   m = t->NumberOfParameters;
1337   if (n > m)
1338     {
1339     fprintf(stderr, "vtkParse_InstantiateClassTemplate: "
1340             "too many template args.\n");
1341     return;
1342     }
1343
1344   for (i = n; i < m; i++)
1345     {
1346     if (t->Parameters[i]->Value == NULL ||
1347         t->Parameters[i]->Value[0] == '\0')
1348       {
1349       fprintf(stderr, "vtkParse_InstantiateClassTemplate: "
1350               "too few template args.\n");
1351       return;
1352       }
1353     }
1354
1355   new_args = (const char **)malloc(m*sizeof(char **));
1356   for (i = 0; i < n; i++)
1357     {
1358     new_args[i] = args[i];
1359     }
1360   for (i = n; i < m; i++)
1361     {
1362     new_args[i] = t->Parameters[i]->Value;
1363     }
1364   args = new_args;
1365
1366   arg_names = (const char **)malloc(m*sizeof(char **));
1367   arg_types = (ValueInfo **)malloc(m*sizeof(ValueInfo *));
1368   for (i = 0; i < m; i++)
1369     {
1370     arg_names[i] = t->Parameters[i]->Name;
1371     arg_types[i] = NULL;
1372     if (t->Parameters[i]->Type == 0)
1373       {
1374       arg_types[i] = (ValueInfo *)malloc(sizeof(ValueInfo));
1375       vtkParse_InitValue(arg_types[i]);
1376       vtkParse_ValueInfoFromString(arg_types[i], cache, args[i]);
1377       arg_types[i]->ItemType = VTK_TYPEDEF_INFO;
1378       arg_types[i]->Name = arg_names[i];
1379       }
1380     }
1381
1382   /* no longer a template (has been instantiated) */
1383   if (data->Template)
1384     {
1385     vtkParse_FreeTemplate(data->Template);
1386     }
1387   data->Template = NULL;
1388
1389   /* append template args to class name */
1390   k = strlen(data->Name) + 2;
1391   for (i = 0; i < m; i++)
1392     {
1393     k += strlen(args[i]) + 2;
1394     }
1395   new_name = (char *)malloc(k);
1396   strcpy(new_name, data->Name);
1397   k = strlen(new_name);
1398   new_name[k++] = '<';
1399   for (i = 0; i < m; i++)
1400     {
1401     strcpy(&new_name[k], args[i]);
1402     k += strlen(args[i]);
1403     if (i+1 < m)
1404       {
1405       new_name[k++] = ',';
1406       new_name[k++] = ' ';
1407       }
1408     }
1409   if (new_name[k-1] == '>')
1410     {
1411     new_name[k++] = ' ';
1412     }
1413   new_name[k++] = '>';
1414   new_name[k] = '\0';
1415
1416   data->Name = vtkParse_CacheString(cache, new_name, k);
1417   free(new_name);
1418
1419   /* do the template arg substitution */
1420   class_substitution(data, cache, m, arg_names, args, arg_types);
1421
1422   /* free all allocated arrays */
1423   free((char **)new_args);
1424   free((char **)arg_names);
1425
1426   for (i = 0; i < m; i++)
1427     {
1428     if (arg_types[i])
1429       {
1430       vtkParse_FreeValue(arg_types[i]);
1431       }
1432     }
1433   free(arg_types);
1434 }
1435
1436 /* Get a zero-terminated array of the types in vtkTemplateMacro. */
1437 const char **vtkParse_GetTemplateMacroTypes()
1438 {
1439   static const char *types[] = {
1440     "char", "signed char", "unsigned char", "short", "unsigned short",
1441     "int", "unsigned int", "long", "unsigned long",
1442 #ifdef VTK_TYPE_USE_LONG_LONG
1443     "long long", "unsigned long long",
1444 #endif
1445 #ifdef VTK_TYPE_USE___INT64
1446     "__int64", "unsigned __int64",
1447 #endif
1448     "float", "double", NULL };
1449
1450   return types;
1451 }
1452
1453 /* Get a zero-terminated array of the types in vtkArray. */
1454 const char **vtkParse_GetArrayTypes()
1455 {
1456   static const char *types[] = {
1457     "char", "signed char", "unsigned char", "short", "unsigned short",
1458     "int", "unsigned int", "long", "unsigned long",
1459 #ifdef VTK_TYPE_USE_LONG_LONG
1460     "long long", "unsigned long long",
1461 #endif
1462 #ifdef VTK_TYPE_USE___INT64
1463     "__int64", "unsigned __int64",
1464 #endif
1465     "float", "double",
1466     "vtkStdString", "vtkUnicodeString", "vtkVariant", NULL };
1467
1468   return types;
1469 }