Back to index

salome-paravis  6.5.0
vtkParseExtras.c
Go to the documentation of this file.
00001 /*=========================================================================
00002 
00003   Program:   Visualization Toolkit
00004   Module:    vtkParseExtras.c
00005 
00006   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
00007   All rights reserved.
00008   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
00009 
00010      This software is distributed WITHOUT ANY WARRANTY; without even
00011      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
00012      PURPOSE.  See the above copyright notice for more information.
00013 
00014 =========================================================================*/
00015 /*-------------------------------------------------------------------------
00016   Copyright (c) 2011 David Gobbi.
00017 
00018   Contributed to the VisualizationToolkit by the author in May 2011
00019   under the terms of the Visualization Toolkit 2008 copyright.
00020 -------------------------------------------------------------------------*/
00021 
00022 #include <stdio.h>
00023 #include <stdlib.h>
00024 #include <string.h>
00025 #include <ctype.h>
00026 #include <assert.h>
00027 #include "vtkParse.h"
00028 #include "vtkParseInternal.h"
00029 #include "vtkParseExtras.h"
00030 #include "vtkType.h"
00031 
00032 /* skip over an identifier */
00033 static size_t vtkparse_id_len(const char *text)
00034 {
00035   size_t i = 0;
00036   char c = text[0];
00037 
00038   if ((c >= 'a' && c <= 'z') ||
00039       (c >= 'A' && c <= 'Z') ||
00040        c == '_')
00041     {
00042     do
00043       {
00044       c = text[++i];
00045       }
00046     while ((c >= 'a' && c <= 'z') ||
00047            (c >= 'A' && c <= 'Z') ||
00048            (c >= '0' && c <= '9') ||
00049            c == '_');
00050     }
00051 
00052   return i;
00053 }
00054 
00055 /* skip over numbers, int or float, including suffixes */
00056 static size_t vtkparse_number_len(const char *text)
00057 {
00058   size_t i = 0;
00059   char c = text[0];
00060 
00061   if (c == '.')
00062     {
00063     c = text[1];
00064     }
00065 
00066   if (c >= '0' && c <= '9')
00067     {
00068     do
00069       {
00070       do
00071         {
00072         c = text[++i];
00073         }
00074       while ((c >= '0' && c <= '9') ||
00075              (c >= 'a' && c <= 'z') ||
00076              (c >= 'A' && c <= 'Z') ||
00077              c == '_' || c == '.');
00078       }
00079     while ((c == '-' || c == '+') &&
00080            (text[i-1] == 'e' || text[i-1] == 'E'));
00081     }
00082 
00083   return i;
00084 }
00085 
00086 /* skip over string and char literals. */
00087 static size_t vtkparse_quote_len(const char *text)
00088 {
00089   size_t i = 0;
00090   const char qc = text[0];
00091   char c = text[0];
00092 
00093   if (c == '\'' || c == '\"')
00094     {
00095     do
00096       {
00097       do
00098         {
00099         c = text[++i];
00100         }
00101       while (c != qc && c != '\n' && c != '\0');
00102       }
00103     while (c == qc && text[i-1] == '\\');
00104 
00105     if (c == qc)
00106       {
00107       ++i;
00108       }
00109     }
00110 
00111   return i;
00112 }
00113 
00114 /* skip over an expression in brackets */
00115 size_t vtkparse_bracket_len(const char *text)
00116 {
00117   size_t i = 0;
00118   size_t j = 1;
00119   char bc = text[0];
00120   char tc = 0;
00121   char semi = ';';
00122   char c;
00123 
00124   if (bc == '(') { tc = ')'; }
00125   else if (bc == '[') { tc = ']'; }
00126   else if (bc == '{') { tc = '}'; semi = '\0'; }
00127   else if (bc == '<') { tc = '>'; }
00128   else { return 0; }
00129 
00130   do
00131     {
00132     i += j;
00133     j = 1;
00134     c = text[i];
00135     if (c == '\'' || c == '\"')
00136       {
00137       j = vtkparse_quote_len(&text[i]);
00138       }
00139     else if (c == bc || c == '(' || c == '[' || c == '{')
00140       {
00141       j = vtkparse_bracket_len(&text[i]);
00142       }
00143     }
00144   while (c != tc && c != ')' && c != ']' && c != '}' &&
00145          c != '\0' && c != '\n' && c != semi && j != 0);
00146 
00147   if (c == tc)
00148     {
00149     i++;
00150     }
00151 
00152   return i;
00153 }
00154 
00155 /* skip over a name that is neither scoped or templated, return the
00156  * total number of characters in the name */
00157 size_t vtkParse_IdentifierLength(const char *text)
00158 {
00159   return vtkparse_id_len(text);
00160 }
00161 
00162 /* skip over a name that might be templated, return the
00163  * total number of characters in the name */
00164 size_t vtkParse_UnscopedNameLength(const char *text)
00165 {
00166   size_t i = 0;
00167 
00168   i += vtkparse_id_len(text);
00169   if (text[i] == '<')
00170     {
00171     i += vtkparse_bracket_len(&text[i]);
00172     if (text[i-1] != '>')
00173       {
00174       fprintf(stderr, "Bad template args %*.*s\n", (int)i, (int)i, text);
00175       return 0;
00176       }
00177     }
00178 
00179   return i;
00180 }
00181 
00182 /* skip over a name that might be scoped or templated, return the
00183  * total number of characters in the name */
00184 size_t vtkParse_NameLength(const char *text)
00185 {
00186   size_t i = 0;
00187   do
00188     {
00189     if (text[i] == ':' && text[i+1] == ':') { i += 2; }
00190     i += vtkParse_UnscopedNameLength(&text[i]);
00191     }
00192   while (text[i] == ':' && text[i+1] == ':');
00193   return i;
00194 }
00195 
00196 /* Search and replace, return the initial string if no replacements
00197  * occurred, otherwise return a new string. */
00198 static const char *vtkparse_string_replace(
00199   const char *str1, int n, const char *name[], const char *val[],
00200   int useDuplicateString)
00201 {
00202   const char *cp = str1;
00203   char result_store[1024];
00204   size_t resultMaxLen = 1024;
00205   char *result, *tmp;
00206   int k;
00207   size_t i, j, l, m;
00208   size_t lastPos, nameBegin, nameEnd;
00209   int replaced = 0;
00210   int any_replaced = 0;
00211 
00212   result = result_store;
00213 
00214   if (n == 0)
00215     {
00216     return str1;
00217     }
00218 
00219   i = 0;
00220   j = 0;
00221   result[j] = '\0';
00222 
00223   while (cp[i] != '\0')
00224     {
00225     lastPos = i;
00226 
00227     /* skip all chars that aren't part of a name */
00228     while ((cp[i] < 'a' || cp[i] > 'z') &&
00229            (cp[i] < 'A' || cp[i] > 'Z') &&
00230            cp[i] != '_' && cp[i] != '\0')
00231       {
00232       if (cp[i] == '\'' || cp[i] == '\"')
00233         {
00234         i += vtkparse_quote_len(&cp[i]);
00235         }
00236       else if (cp[i] >= '0' && cp[i] <= '9')
00237         {
00238         i += vtkparse_number_len(&cp[i]);
00239         }
00240       else
00241         {
00242         i++;
00243         }
00244       }
00245     nameBegin = i;
00246 
00247     /* skip all chars that are part of a name */
00248     i += vtkparse_id_len(&cp[i]);
00249     nameEnd = i;
00250 
00251     /* search through the list of names to replace */
00252     replaced = 0;
00253     m = nameEnd - nameBegin;
00254     for (k = 0; k < n; k++)
00255       {
00256       l = strlen(name[k]);
00257       if (l > 0 && l == m && strncmp(&cp[nameBegin], name[k], l) == 0)
00258         {
00259         m = strlen(val[k]);
00260         replaced = 1;
00261         any_replaced = 1;
00262         break;
00263         }
00264       }
00265 
00266     /* expand the storage space if needed */
00267     if (j + m + (nameBegin - lastPos) + 1 >= resultMaxLen)
00268       {
00269       resultMaxLen *= 2;
00270       tmp = (char *)malloc(resultMaxLen);
00271       strcpy(tmp, result);
00272       if (result != result_store)
00273          {
00274          free(result);
00275          }
00276        result = tmp;
00277        }
00278 
00279     /* copy the old bits */
00280     if (nameBegin > lastPos)
00281       {
00282       strncpy(&result[j], &cp[lastPos], nameBegin - lastPos);
00283       j += (nameBegin - lastPos);
00284       }
00285 
00286     /* do the replacement */
00287     if (replaced)
00288       {
00289       strncpy(&result[j], val[k], m);
00290       j += m;
00291       /* guard against creating double ">>" */
00292       if (val[k][m-1] == '>' && cp[nameEnd] == '>')
00293         {
00294         result[j++] = ' ';
00295         }
00296       }
00297     else if (nameEnd > nameBegin)
00298       {
00299       strncpy(&result[j], &cp[nameBegin], nameEnd - nameBegin);
00300       j += (nameEnd - nameBegin);
00301       }
00302 
00303     result[j] = '\0';
00304     }
00305 
00306   if (useDuplicateString)
00307     {
00308     if (any_replaced)
00309       {
00310       /* use the efficient but leaky DuplicateString method */
00311       cp = vtkParse_DuplicateString(result, j);
00312       if (result != result_store)
00313         {
00314         free(result);
00315         }
00316       }
00317     }
00318   else
00319     {
00320     if (any_replaced)
00321       {
00322       /* return a string that was allocated with malloc */
00323       if (result == result_store)
00324         {
00325         tmp = (char *)malloc(strlen(result) + 1);
00326         strcpy(tmp, result);
00327         result = tmp;
00328         }
00329       cp = result;
00330       }
00331     }
00332 
00333   return cp;
00334 }
00335 
00336 /* Wherever one of the specified names exists inside a Value or inside
00337  * a Dimension size, replace it with the corresponding val string. */
00338 void vtkParse_ExpandValues(
00339   ValueInfo *valinfo, int n, const char *name[], const char *val[])
00340 {
00341   int j, m, dim, count;
00342   const char *cp;
00343 
00344   if (valinfo->Value)
00345     {
00346     valinfo->Value = vtkparse_string_replace(valinfo->Value, n, name, val, 1);
00347     }
00348 
00349   m = valinfo->NumberOfDimensions;
00350   if (m)
00351     {
00352     count = 1;
00353     for (j = 0; j < m; j++)
00354       {
00355       cp = valinfo->Dimensions[j];
00356       if (cp)
00357         {
00358         cp = vtkparse_string_replace(cp, n, name, val, 1);
00359         valinfo->Dimensions[j] = cp;
00360 
00361         /* check whether dimension has become an integer literal */
00362         if (cp[0] == '0' && (cp[1] == 'x' || cp[1] == 'X')) { cp += 2; }
00363         while (*cp >= '0' && *cp <= '9') { cp++; }
00364         while (*cp == 'u' || *cp == 'l' || *cp == 'U' || *cp == 'L') { cp++; }
00365         dim = 0;
00366         if (*cp == '\0')
00367           {
00368           dim = (int)strtol(valinfo->Dimensions[j], NULL, 0);
00369           }
00370         count *= dim;
00371         }
00372       }
00373 
00374     /* update count if all values are integer literals */
00375     if (count)
00376       {
00377       valinfo->Count = count;
00378       }
00379     }
00380 }
00381 
00382 /* Expand a typedef within a type declaration. */
00383 void vtkParse_ExpandTypedef(ValueInfo *valinfo, ValueInfo *typedefinfo)
00384 {
00385   const char *classname;
00386   unsigned int baseType;
00387   unsigned int pointers;
00388   unsigned int refbit;
00389   unsigned int qualifiers;
00390   unsigned int tmp1, tmp2;
00391   int i;
00392 
00393   classname = typedefinfo->Class;
00394   baseType = (typedefinfo->Type & VTK_PARSE_BASE_TYPE);
00395   pointers = (typedefinfo->Type & VTK_PARSE_POINTER_MASK);
00396   refbit = (valinfo->Type & VTK_PARSE_REF);
00397   qualifiers = (typedefinfo->Type & VTK_PARSE_CONST);
00398 
00399   /* handle const */
00400   if ((valinfo->Type & VTK_PARSE_CONST) != 0)
00401     {
00402     if ((pointers & VTK_PARSE_POINTER_LOWMASK) != 0)
00403       {
00404       if ((pointers & VTK_PARSE_POINTER_LOWMASK) != VTK_PARSE_ARRAY)
00405         {
00406         /* const turns into const pointer */
00407         pointers = (pointers & ~VTK_PARSE_POINTER_LOWMASK);
00408         pointers = (pointers | VTK_PARSE_CONST_POINTER);
00409         }
00410       }
00411     else
00412       {
00413       /* const remains as const value */
00414       qualifiers = (qualifiers | VTK_PARSE_CONST);
00415       }
00416     }
00417 
00418   /* make a reversed copy of the pointer bitfield */
00419   tmp1 = (valinfo->Type & VTK_PARSE_POINTER_MASK);
00420   tmp2 = 0;
00421   while (tmp1)
00422     {
00423     tmp2 = ((tmp2 << 2) | (tmp1 & VTK_PARSE_POINTER_LOWMASK));
00424     tmp1 = ((tmp1 >> 2) & VTK_PARSE_POINTER_MASK);
00425     }
00426 
00427   /* turn pointers into zero-element arrays where necessary */
00428   if ((pointers & VTK_PARSE_POINTER_LOWMASK) == VTK_PARSE_ARRAY)
00429     {
00430     tmp2 = ((tmp2 >> 2) & VTK_PARSE_POINTER_MASK);
00431     while (tmp2)
00432       {
00433       vtkParse_AddStringToArray(
00434         &valinfo->Dimensions, &valinfo->NumberOfDimensions, "");
00435       tmp2 = ((tmp2 >> 2) & VTK_PARSE_POINTER_MASK);
00436       }
00437     }
00438   else
00439     {
00440     /* combine the pointers */
00441     while (tmp2)
00442       {
00443       pointers = ((pointers << 2) | (tmp2 & VTK_PARSE_POINTER_LOWMASK));
00444       tmp2 = ((tmp2 >> 2) & VTK_PARSE_POINTER_MASK);
00445       }
00446     }
00447 
00448   /* combine the arrays */
00449   for (i = 0; i < typedefinfo->NumberOfDimensions; i++)
00450     {
00451     vtkParse_AddStringToArray(
00452       &valinfo->Dimensions, &valinfo->NumberOfDimensions,
00453       typedefinfo->Dimensions[i]);
00454     }
00455   if (valinfo->NumberOfDimensions > 1)
00456     {
00457     pointers = ((pointers & ~VTK_PARSE_POINTER_LOWMASK) | VTK_PARSE_ARRAY);
00458     }
00459 
00460   /* put everything together */
00461   valinfo->Type = (baseType | pointers | refbit | qualifiers);
00462   valinfo->Class = classname;
00463   valinfo->Function = typedefinfo->Function;
00464   valinfo->Count *= typedefinfo->Count;
00465 }
00466 
00467 /* Expand any unrecognized types within a variable, parameter, or typedef
00468  * that match any of the supplied typedefs. The expansion is done in-place. */
00469 void vtkParse_ExpandTypedefs(
00470   ValueInfo *val, int n, const char *names[], const char *values[],
00471   ValueInfo *typedefinfo[])
00472 {
00473   int i;
00474 
00475   if (((val->Type & VTK_PARSE_BASE_TYPE) == VTK_PARSE_OBJECT ||
00476        (val->Type & VTK_PARSE_BASE_TYPE) == VTK_PARSE_UNKNOWN) &&
00477       val->Class != 0)
00478    {
00479    for (i = 0; i < n; i++)
00480      {
00481      if (typedefinfo[i] && strcmp(val->Class, typedefinfo[i]->Name) == 0)
00482        {
00483        vtkParse_ExpandTypedef(val, typedefinfo[i]);
00484        break;
00485        }
00486      }
00487    if (i == n)
00488      {
00489      /* in case type appears as a template arg of another type */
00490      val->Class = vtkparse_string_replace(val->Class, n, names, values, 1);
00491      }
00492    }
00493 }
00494 
00495 /* Helper struct for VTK-specific types */
00496 struct vtk_type_struct
00497 {
00498   size_t len;
00499   const char *name;
00500   int type;
00501 };
00502 
00503 /* Get a type from a type name, and return the number of characters used.
00504  * If the "classname" argument is not NULL, then it is used to return
00505  * the short name for the type, e.g. "long int" becomes "long", while
00506  * typedef names and class names are returned unchanged.  If "const"
00507  * appears in the type name, then the const bit flag is set for the
00508  * type, but "const" will not appear in the returned classname. */
00509 size_t vtkParse_BasicTypeFromString(
00510   const char *text, unsigned int *type_ptr,
00511   const char **classname_ptr, size_t *len_ptr)
00512 {
00513   /* The various typedefs and types specific to VTK */
00514   static struct vtk_type_struct vtktypes[] = {
00515     { 9,  "vtkIdType", VTK_ID_TYPE },
00516     { 12, "vtkStdString", VTK_STRING },
00517     { 16, "vtkUnicodeString", VTK_UNICODE_STRING },
00518     { 11, "vtkTypeInt8", VTK_TYPE_INT8 },
00519     { 12, "vtkTypeUInt8", VTK_TYPE_UINT8 },
00520     { 12, "vtkTypeInt16", VTK_TYPE_INT16 },
00521     { 13, "vtkTypeUInt16", VTK_TYPE_UINT16 },
00522     { 12, "vtkTypeInt32", VTK_TYPE_INT32 },
00523     { 13, "vtkTypeUInt32", VTK_TYPE_UINT32 },
00524     { 12, "vtkTypeInt64", VTK_TYPE_INT64 },
00525     { 13, "vtkTypeUInt64", VTK_TYPE_UINT64 },
00526     { 14, "vtkTypeFloat32", VTK_TYPE_FLOAT32 },
00527     { 14, "vtkTypeFloat64", VTK_TYPE_FLOAT64 },
00528     { 0, 0, 0 } };
00529 
00530   /* Other typedefs and types */
00531   static struct vtk_type_struct stdtypes[] = {
00532     { 6,  "size_t", VTK_PARSE_SIZE_T },
00533     { 7,  "ssize_t", VTK_PARSE_SSIZE_T },
00534     { 7,  "ostream", VTK_PARSE_OSTREAM },
00535     { 7,  "istream", VTK_PARSE_ISTREAM },
00536     { 8,  "string", VTK_PARSE_STRING },
00537     { 0, 0, 0 } };
00538 
00539   const char *cp = text;
00540   const char *tmpcp;
00541   size_t k, n, m;
00542   int i;
00543   unsigned int const_bits = 0;
00544   unsigned int static_bits = 0;
00545   unsigned int unsigned_bits = 0;
00546   unsigned int base_bits = 0;
00547   const char *classname = NULL;
00548   size_t len = 0;
00549 
00550   while (*cp == ' ' || *cp == '\t') { cp++; }
00551 
00552   while ((*cp >= 'a' && *cp <= 'z') ||
00553          (*cp >= 'A' && *cp <= 'Z') ||
00554          (*cp == '_') || (cp[0] == ':' && cp[1] == ':'))
00555     {
00556     /* skip all chars that are part of a name */
00557     n = vtkParse_NameLength(cp);
00558 
00559     if ((n == 6 && strncmp("static", cp, n) == 0) ||
00560         (n == 4 && strncmp("auto", cp, n) == 0) ||
00561         (n == 8 && strncmp("register", cp, n) == 0) ||
00562         (n == 8 && strncmp("volatile", cp, n) == 0))
00563       {
00564       if (strncmp("static", cp, n) == 0)
00565         {
00566         static_bits = VTK_PARSE_STATIC;
00567         }
00568       }
00569     else if (n == 5 && strncmp(cp, "const", n) == 0)
00570       {
00571       const_bits |= VTK_PARSE_CONST;
00572       }
00573     else if (n == 8 && strncmp(cp, "unsigned", n) == 0)
00574       {
00575       unsigned_bits |= VTK_PARSE_UNSIGNED;
00576       if (base_bits == 0)
00577         {
00578         classname = "int";
00579         base_bits = VTK_PARSE_INT;
00580         }
00581       }
00582     else if (n == 6 && strncmp(cp, "signed", n) == 0)
00583       {
00584       if (base_bits == VTK_PARSE_CHAR)
00585         {
00586         classname = "signed char";
00587         base_bits = VTK_PARSE_SIGNED_CHAR;
00588         }
00589       else
00590         {
00591         classname = "int";
00592         base_bits = VTK_PARSE_INT;
00593         }
00594       }
00595     else if (n == 3 && strncmp(cp, "int", n) == 0)
00596       {
00597       if (base_bits == 0)
00598         {
00599         classname = "int";
00600         base_bits = VTK_PARSE_INT;
00601         }
00602       }
00603     else if (n == 4 && strncmp(cp, "long", n) == 0)
00604       {
00605       if (base_bits == VTK_PARSE_LONG)
00606         {
00607         classname = "long long";
00608         base_bits = VTK_PARSE_LONG_LONG;
00609         }
00610       else
00611         {
00612         classname = "long";
00613         base_bits = VTK_PARSE_LONG;
00614         }
00615       }
00616     else if (n == 5 && strncmp(cp, "short", n) == 0)
00617       {
00618       classname = "short";
00619       base_bits = VTK_PARSE_SHORT;
00620       }
00621     else if (n == 4 && strncmp(cp, "char", n) == 0)
00622       {
00623       if (base_bits == VTK_PARSE_INT && unsigned_bits != VTK_PARSE_UNSIGNED)
00624         {
00625         classname = "signed char";
00626         base_bits = VTK_PARSE_SIGNED_CHAR;
00627         }
00628       else
00629         {
00630         classname = "char";
00631         base_bits = VTK_PARSE_CHAR;
00632         }
00633       }
00634     else if (n == 5 && strncmp(cp, "float", n) == 0)
00635       {
00636       classname = "float";
00637       base_bits = VTK_PARSE_FLOAT;
00638       }
00639     else if (n == 6 && strncmp(cp, "double", n) == 0)
00640       {
00641       classname = "double";
00642       base_bits = VTK_PARSE_DOUBLE;
00643       }
00644     else if (n == 4 && strncmp(cp, "bool", n) == 0)
00645       {
00646       classname = "bool";
00647       base_bits = VTK_PARSE_BOOL;
00648       }
00649     else if (n == 4 && strncmp(cp, "void", n) == 0)
00650       {
00651       classname = "void";
00652       base_bits = VTK_PARSE_VOID;
00653       }
00654     else if (n == 7 && strncmp(cp, "__int64", n) == 0)
00655       {
00656       classname = "__int64";
00657       base_bits = VTK_PARSE___INT64;
00658       }
00659     else
00660       {
00661       /* if type already found, break */
00662       if (base_bits != 0)
00663         {
00664         break;
00665         }
00666 
00667       /* check vtk typedefs */
00668       if (strncmp(cp, "vtk", 3) == 0)
00669         {
00670         for (i = 0; vtktypes[i].len != 0; i++)
00671           {
00672           if (n == vtktypes[i].len && strncmp(cp, vtktypes[i].name, n) == 0)
00673             {
00674             classname = vtktypes[i].name;
00675             base_bits = vtkParse_MapType((int)vtktypes[i].type);
00676             }
00677           }
00678         }
00679 
00680       /* check standard typedefs */
00681       if (base_bits == 0)
00682         {
00683         m = 0;
00684         if (strncmp(cp, "::", 2) == 0) { m = 2; }
00685         else if (strncmp(cp, "std::", 5) == 0) { m = 5; }
00686 #ifndef VTK_LEGACY_REMOVE
00687         else if (strncmp(cp, "vtkstd::", 8) == 0) { m = 8; }
00688 #endif
00689 
00690         /* advance past the namespace */
00691         tmpcp = cp + m;
00692 
00693         for (i = 0; stdtypes[i].len != 0; i++)
00694           {
00695           if (n == stdtypes[i].len && strncmp(tmpcp, stdtypes[i].name, n) == 0)
00696             {
00697             classname = stdtypes[i].name;
00698             base_bits = stdtypes[i].type;
00699             }
00700           }
00701 
00702         /* include the namespace if present */
00703         if (base_bits != 0 && m > 0)
00704           {
00705           classname = cp;
00706           len = n;
00707           }
00708         }
00709 
00710       /* anything else is assumed to be a class, enum, or who knows */
00711       if (base_bits == 0)
00712         {
00713         base_bits = VTK_PARSE_UNKNOWN;
00714         classname = cp;
00715         len = n;
00716 
00717         /* VTK classes all start with vtk */
00718         if (strncmp(classname, "vtk", 3) == 0)
00719           {
00720           base_bits = VTK_PARSE_OBJECT;
00721           /* make sure the "vtk" isn't just part of the namespace */
00722           for (k = 0; k < n; k++)
00723             {
00724             if (cp[k] == ':')
00725               {
00726               base_bits = VTK_PARSE_UNKNOWN;
00727               break;
00728               }
00729             }
00730           }
00731         /* Qt objects and enums */
00732         else if (classname[0] == 'Q' &&
00733                  ((classname[1] >= 'A' && classname[2] <= 'Z') ||
00734                   strncmp(classname, "Qt::", 4) == 0))
00735           {
00736           base_bits = VTK_PARSE_QOBJECT;
00737           }
00738         }
00739       }
00740 
00741     cp += n;
00742     while (*cp == ' ' || *cp == '\t') { cp++; }
00743     }
00744 
00745   if ((unsigned_bits & VTK_PARSE_UNSIGNED) != 0)
00746     {
00747     switch (base_bits)
00748       {
00749       case VTK_PARSE_CHAR:
00750         classname = "unsigned char";
00751         break;
00752       case VTK_PARSE_SHORT:
00753         classname = "unsigned short";
00754         break;
00755       case VTK_PARSE_INT:
00756         classname = "unsigned int";
00757         break;
00758       case VTK_PARSE_LONG:
00759         classname = "unsigned long";
00760         break;
00761       case VTK_PARSE_LONG_LONG:
00762         classname = "unsigned long long";
00763         break;
00764       case VTK_PARSE___INT64:
00765         classname = "unsigned __int64";
00766         break;
00767       }
00768     }
00769 
00770   *type_ptr = (static_bits | const_bits | unsigned_bits | base_bits);
00771 
00772   if (classname_ptr)
00773     {
00774     *classname_ptr = classname;
00775     if (len == 0)
00776       {
00777       len = strlen(classname);
00778       }
00779     *len_ptr = len;
00780     }
00781 
00782   return (size_t)(cp - text);
00783 }
00784 
00785 /* Parse a type description in "text" and generate a typedef named "name" */
00786 void vtkParse_ValueInfoFromString(ValueInfo *data, const char *text)
00787 {
00788   const char *cp = text;
00789   size_t n;
00790   int m, count;
00791   unsigned int base_bits = 0;
00792   unsigned int pointer_bits = 0;
00793   unsigned int ref_bits = 0;
00794   const char *classname = NULL;
00795 
00796   /* get the basic type with qualifiers */
00797   cp += vtkParse_BasicTypeFromString(cp, &base_bits, &classname, &n);
00798 
00799   data->Class = vtkParse_DuplicateString(classname, n);
00800 
00801   if ((base_bits & VTK_PARSE_STATIC) != 0)
00802     {
00803     data->IsStatic = 1;
00804     }
00805 
00806   /* look for pointers (and const pointers) */
00807   while (*cp == '*')
00808     {
00809     cp++;
00810     pointer_bits = (pointer_bits << 2);
00811     while (*cp == ' ' || *cp == '\t') { cp++; }
00812     if (strncmp(cp, "const", 5) == 0 &&
00813         (cp[5] < 'a' || cp[5] > 'z') &&
00814         (cp[5] < 'A' || cp[5] > 'Z') &&
00815         (cp[5] < '0' || cp[5] > '9') &&
00816         cp[5] != '_')
00817       {
00818       cp += 5;
00819       while (*cp == ' ' || *cp == '\t') { cp++; }
00820       pointer_bits = (pointer_bits | VTK_PARSE_CONST_POINTER);
00821       }
00822     else
00823       {
00824       pointer_bits = (pointer_bits | VTK_PARSE_POINTER);
00825       }
00826     pointer_bits = (pointer_bits & VTK_PARSE_POINTER_MASK);
00827     }
00828 
00829   /* look for ref */
00830   if (*cp == '&')
00831     {
00832     cp++;
00833     while (*cp == ' ' || *cp == '\t') { cp++; }
00834     ref_bits = VTK_PARSE_REF;
00835     }
00836 
00837   /* look for the variable name */
00838   if ((*cp >= 'a' && *cp <= 'z') ||
00839       (*cp >= 'A' && *cp <= 'Z') ||
00840       (*cp == '_'))
00841     {
00842     /* skip all chars that are part of a name */
00843     n = vtkparse_id_len(cp);
00844     data->Name = vtkParse_DuplicateString(cp, n);
00845     cp += n;
00846     while (*cp == ' ' || *cp == '\t') { cp++; }
00847     }
00848 
00849   /* look for array brackets */
00850   if (*cp == '[')
00851     {
00852     count = 1;
00853     }
00854 
00855   while (*cp == '[')
00856     {
00857     n = vtkparse_bracket_len(cp);
00858     if (n > 0)
00859       {
00860       cp++;
00861       n--;
00862       }
00863     while (*cp == ' ' || *cp == '\t') { cp++; n--; }
00864     while (n > 0 && (cp[n-1] == ' ' || cp[n-1] == '\t')) { n--; }
00865     vtkParse_AddStringToArray(&data->Dimensions,
00866                               &data->NumberOfDimensions,
00867                               vtkParse_DuplicateString(cp, n));
00868     m = 0;
00869     if (*cp >= '0' && *cp <= '9' && vtkparse_number_len(cp) == n)
00870       {
00871       m = (int)strtol(cp, NULL, 0);
00872       }
00873     count *= m;
00874 
00875     cp += n;
00876     while (*cp == ' ' || *cp == '\t') { cp++; }
00877     if (cp[n] == ']') { cp++; }
00878     while (*cp == ' ' || *cp == '\t') { cp++; }
00879     }
00880 
00881   /* add pointer indirection to correspond to first array dimension */
00882   if (data->NumberOfDimensions > 1)
00883     {
00884     pointer_bits = ((pointer_bits << 2) | VTK_PARSE_ARRAY);
00885     }
00886   else if (data->NumberOfDimensions == 1)
00887     {
00888     pointer_bits = ((pointer_bits << 2) | VTK_PARSE_POINTER);
00889     }
00890   pointer_bits = (pointer_bits & VTK_PARSE_POINTER_MASK);
00891 
00892   /* (Add code here to look for "=" followed by a value ) */
00893 
00894   data->Type = (pointer_bits | ref_bits | base_bits);
00895 }
00896 
00897 
00898 
00899 /* substitute generic types and values with actual types and values */
00900 static void func_substitution(
00901   FunctionInfo *data, int m, const char *arg_names[],
00902   const char *arg_values[], ValueInfo *arg_types[]);
00903 
00904 static void value_substitution(
00905   ValueInfo *data, int m, const char *arg_names[],
00906   const char *arg_values[], ValueInfo *arg_types[])
00907 {
00908   vtkParse_ExpandTypedefs(data, m, arg_names, arg_values, arg_types);
00909   vtkParse_ExpandValues(data, m, arg_names, arg_values);
00910 
00911   if (data->Function)
00912     {
00913     func_substitution(data->Function, m, arg_names, arg_values, arg_types);
00914     }
00915 }
00916 
00917 static void func_substitution(
00918   FunctionInfo *data, int m, const char *arg_names[],
00919   const char *arg_values[], ValueInfo *arg_types[])
00920 {
00921   int i, n;
00922 
00923   n = data->NumberOfArguments;
00924   for (i = 0; i < n; i++)
00925     {
00926     value_substitution(data->Arguments[i], m, arg_names, arg_values, arg_types);
00927     if (i < MAX_ARGS)
00928       {
00929       data->ArgTypes[i] = data->Arguments[i]->Type;
00930       data->ArgClasses[i] = data->Arguments[i]->Class;
00931       if (data->Arguments[i]->NumberOfDimensions == 1 &&
00932           data->Arguments[i]->Count > 0)
00933         {
00934         data->ArgCounts[i] = data->Arguments[i]->Count;
00935         }
00936       }
00937     }
00938   if (data->ReturnValue)
00939     {
00940     value_substitution(data->ReturnValue, m, arg_names, arg_values, arg_types);
00941     data->ReturnType = data->ReturnValue->Type;
00942     data->ReturnClass = data->ReturnValue->Class;
00943     if (data->ReturnValue->NumberOfDimensions == 1 &&
00944         data->ReturnValue->Count > 0)
00945       {
00946       data->HintSize = data->ReturnValue->Count;
00947       data->HaveHint = 1;
00948       }
00949     }
00950   if (data->Signature)
00951     {
00952     data->Signature =
00953       vtkparse_string_replace(data->Signature, m, arg_names, arg_values, 1);
00954     }
00955 }
00956 
00957 static void class_substitution(
00958   ClassInfo *data, int m, const char *arg_names[],
00959   const char *arg_values[], ValueInfo *arg_types[])
00960 {
00961   int i, n;
00962 
00963   /* superclasses may be templated */
00964   n = data->NumberOfSuperClasses;
00965   for (i = 0; i < n; i++)
00966     {
00967     data->SuperClasses[i] = vtkparse_string_replace(
00968       data->SuperClasses[i], m, arg_names, arg_values, 1);
00969     }
00970 
00971   n = data->NumberOfClasses;
00972   for (i = 0; i < n; i++)
00973     {
00974     class_substitution(data->Classes[i], m, arg_names, arg_values, arg_types);
00975     }
00976 
00977   n = data->NumberOfFunctions;
00978   for (i = 0; i < n; i++)
00979     {
00980     func_substitution(data->Functions[i], m, arg_names, arg_values, arg_types);
00981     }
00982 
00983   n = data->NumberOfConstants;
00984   for (i = 0; i < n; i++)
00985     {
00986     value_substitution(data->Constants[i], m, arg_names, arg_values, arg_types);
00987     }
00988 
00989   n = data->NumberOfVariables;
00990   for (i = 0; i < n; i++)
00991     {
00992     value_substitution(data->Variables[i], m, arg_names, arg_values, arg_types);
00993     }
00994 
00995   n = data->NumberOfTypedefs;
00996   for (i = 0; i < n; i++)
00997     {
00998     value_substitution(data->Typedefs[i], m, arg_names, arg_values, arg_types);
00999     }
01000 }
01001 
01002 
01003 /* Search and replace, return the initial string if no replacements
01004  * occurred, otherwise return a new string allocated with malloc. */
01005 const char *vtkParse_StringReplace(
01006   const char *str1, int n, const char *name[], const char *val[])
01007 {
01008   return vtkparse_string_replace(str1, n, name, val, 0);
01009 }
01010 
01011 /* Extract template args from a comma-separated list enclosed
01012  * in angle brackets.  Returns zero if no angle brackets found. */
01013 size_t vtkParse_DecomposeTemplatedType(
01014   const char *text, const char **classname,
01015   int nargs, const char ***argp, const char *defaults[])
01016 {
01017   size_t i, j, k, n;
01018   const char *arg;
01019   char *new_text;
01020   const char **template_args = NULL;
01021   int template_arg_count = 0;
01022 
01023   n = vtkParse_NameLength(text);
01024 
01025   /* is the class templated? */
01026   for (i = 0; i < n; i++)
01027     {
01028     if (text[i] == '<')
01029       {
01030       break;
01031       }
01032     }
01033 
01034   new_text = (char *)malloc(i + 1);
01035   strncpy(new_text, text, i);
01036   new_text[i] = '\0';
01037   *classname = new_text;
01038 
01039   if (text[i] == '<')
01040     {
01041     i++;
01042     /* extract the template arguments */
01043     for (;;)
01044       {
01045       while (text[i] == ' ' || text[i] == '\t') { i++; }
01046       j = i;
01047       while (text[j] != ',' && text[j] != '>' &&
01048              text[j] != '\n' && text[j] != '\0')
01049         {
01050         if (text[j] == '<' || text[j] == '(' ||
01051             text[j] == '[' || text[j] == '{')
01052           {
01053           j += vtkparse_bracket_len(&text[j]);
01054           }
01055         else if (text[j] == '\'' || text[j] == '\"')
01056           {
01057           j += vtkparse_quote_len(&text[j]);
01058           }
01059         else
01060           {
01061           j++;
01062           }
01063         }
01064 
01065       k = j;
01066       while (text[k-1] == ' ' || text[k-1] == '\t') { --k; }
01067 
01068       new_text = (char *)malloc(k-i + 1);
01069       strncpy(new_text, &text[i], k-i);
01070       new_text[k-i] = '\0';
01071       vtkParse_AddStringToArray(&template_args, &template_arg_count,
01072                                 new_text);
01073 
01074       assert(template_arg_count <= nargs);
01075 
01076       i = j + 1;
01077 
01078       if (text[j] != ',')
01079         {
01080         break;
01081         }
01082       }
01083     }
01084 
01085   while (template_arg_count < nargs)
01086     {
01087     assert(defaults != NULL);
01088     arg = defaults[template_arg_count];
01089     assert(arg != NULL);
01090     new_text = (char *)malloc(strlen(arg + 1));
01091     strcpy(new_text, arg);
01092     vtkParse_AddStringToArray(&template_args, &template_arg_count, new_text);
01093     }
01094 
01095   *argp = template_args;
01096 
01097   return i;
01098 }
01099 
01100 /* Free the list of strings returned by ExtractTemplateArgs.  */
01101 void vtkParse_FreeTemplateDecomposition(
01102   const char *name, int n, const char **args)
01103 {
01104   int i;
01105 
01106   if (name)
01107     {
01108     free((char *)name);
01109     }
01110 
01111   if (n > 0)
01112     {
01113     for (i = 0; i < n; i++)
01114       {
01115       free((char *)args[i]);
01116       }
01117 
01118     free((char **)args);
01119     }
01120 }
01121 
01122 
01123 /* Instantiate a class template by substituting the provided arguments. */
01124 void vtkParse_InstantiateClassTemplate(
01125   ClassInfo *data, int n, const char *args[])
01126 {
01127   TemplateArgs *t = data->Template;
01128   const char **new_args = NULL;
01129   const char **arg_names = NULL;
01130   ValueInfo **arg_types = NULL;
01131   int i, m;
01132   char *new_name;
01133   size_t k;
01134 
01135   if (t == NULL)
01136     {
01137     fprintf(stderr, "vtkParse_InstantiateClassTemplate: "
01138             "this class is not templated.\n");
01139     return;
01140     }
01141 
01142   m = t->NumberOfArguments;
01143   if (n > m)
01144     {
01145     fprintf(stderr, "vtkParse_InstantiateClassTemplate: "
01146             "too many template args.\n");
01147     return;
01148     }
01149 
01150   for (i = n; i < m; i++)
01151     {
01152     if (t->Arguments[i]->Value == NULL ||
01153         t->Arguments[i]->Value[0] == '\0')
01154       {
01155       fprintf(stderr, "vtkParse_InstantiateClassTemplate: "
01156               "too few template args.\n");
01157       return;
01158       }
01159     }
01160 
01161   if (n < m)
01162     {
01163     new_args = (const char **)malloc(m*sizeof(char **));
01164     for (i = 0; i < n; i++)
01165       {
01166       new_args[i] = args[i];
01167       }
01168     for (i = n; i < m; i++)
01169       {
01170       new_args[i] = t->Arguments[i]->Value;
01171       }
01172     args = new_args;
01173     }
01174 
01175   arg_names = (const char **)malloc(m*sizeof(char **));
01176   arg_types = (ValueInfo **)malloc(m*sizeof(ValueInfo *));
01177   for (i = 0; i < m; i++)
01178     {
01179     arg_names[i] = t->Arguments[i]->Name;
01180     arg_types[i] = NULL;
01181     if (t->Arguments[i]->Type == 0)
01182       {
01183       arg_types[i] = (ValueInfo *)malloc(sizeof(ValueInfo));
01184       vtkParse_InitValue(arg_types[i]);
01185       vtkParse_ValueInfoFromString(arg_types[i], args[i]);
01186       arg_types[i]->ItemType = VTK_TYPEDEF_INFO;
01187       arg_types[i]->Name = arg_names[i];
01188       }
01189     }
01190 
01191   /* no longer a template (has been instantiated) */
01192   if (data->Template)
01193     {
01194     vtkParse_FreeTemplateArgs(data->Template);
01195     }
01196   data->Template = NULL;
01197 
01198   /* append template args to class name */
01199   k = strlen(data->Name) + 2;
01200   for (i = 0; i < m; i++)
01201     {
01202     k += strlen(args[i]) + 2;
01203     }
01204   new_name = (char *)malloc(k);
01205   strcpy(new_name, data->Name);
01206   k = strlen(new_name);
01207   new_name[k++] = '<';
01208   for (i = 0; i < m; i++)
01209     {
01210     strcpy(&new_name[k], args[i]);
01211     k += strlen(args[i]);
01212     if (i+1 < m)
01213       {
01214       new_name[k++] = ',';
01215       new_name[k++] = ' ';
01216       }
01217     }
01218   if (new_name[k-1] == '>')
01219     {
01220     new_name[k++] = ' ';
01221     }
01222   new_name[k++] = '>';
01223   new_name[k] = '\0';
01224   data->Name = vtkParse_DuplicateString(new_name, k);
01225   free((char *)new_name);
01226 
01227   /* do the template arg substitution */
01228   class_substitution(data, m, arg_names, args, arg_types);
01229 
01230   /* free all allocated arrays */
01231   if (new_args)
01232     {
01233     free((char **)new_args);
01234     }
01235 
01236   free((char **)arg_names);
01237 
01238   for (i = 0; i < m; i++)
01239     {
01240     if (arg_types[i])
01241       {
01242       vtkParse_FreeValue(arg_types[i]);
01243       }
01244     }
01245   free(arg_types);
01246 }
01247 
01248 /* Generate a mangled name for a type, use gcc ia64 ABI.
01249  * The result is placed in new_name, which must be large enough
01250  * to accept the result.  This function is incomplete, it cannot
01251  * handle function types, or any literals except for integer literals. */
01252 size_t vtkParse_MangledTypeName(const char *name, char *new_name)
01253 {
01254   int scoped = 0;
01255   unsigned int ptype = 0;
01256   size_t j, k, m;
01257   size_t i = 0;
01258   const char *cp;
01259   char basictype;
01260 
01261   m = vtkParse_BasicTypeFromString(name, &ptype, NULL, NULL);
01262 
01263   /* look for pointers */
01264   cp = &name[m];
01265   while (*cp == ' ' || *cp == '\t') { cp++; }
01266   while (*cp == '*')
01267     {
01268     do { cp++; } while (*cp == ' ' || *cp == '\t');
01269     if (*cp == 'c' && strncmp(cp, "const", 5) == 0 &&
01270         ((cp[5] < 'A' || cp[5] > 'Z') &&
01271          (cp[5] < 'a' || cp[5] > 'z') &&
01272          (cp[5] < '0' || cp[5] > '9') &&
01273          cp[5] != '_'))
01274       {
01275       cp += 4;
01276       do { cp++; } while (*cp == ' ' || *cp == '\t');
01277       new_name[i++] = 'K';
01278       }
01279     new_name[i++] = 'P';
01280     }
01281 
01282   /* prepend reference if present */
01283   if (*cp == '&')
01284     {
01285     do { cp++; } while (*cp == ' ' || *cp == '\t');
01286     for (k = i; k > 0; --k)
01287       {
01288       new_name[k] = new_name[k-1];
01289       }
01290     new_name[0] = 'R';
01291     i++;
01292     }
01293 
01294   /* array brackets are not handled */
01295 
01296   /* qualifiers */
01297   if (ptype & VTK_PARSE_CONST)
01298     {
01299     new_name[i++] = 'K';
01300     }
01301 
01302   /* types: the following are unused
01303    *  'w' -> wchar_t
01304    *  'n' -> __int128
01305    *  'o' -> unsigned __int128
01306    *  'e' -> __float80
01307    *  'g' -> __float128
01308    *  'z' -> ... (varargs)
01309    */
01310 
01311   basictype = '\0';
01312   switch (ptype & VTK_PARSE_BASE_TYPE)
01313     {
01314     case VTK_PARSE_VOID:
01315       basictype = 'v';
01316       break;
01317     case VTK_PARSE_BOOL:
01318       basictype = 'b';
01319       break;
01320     case VTK_PARSE_CHAR:
01321       basictype = 'c';
01322       break;
01323     case VTK_PARSE_SIGNED_CHAR:
01324       basictype = 'a';
01325       break;
01326     case VTK_PARSE_UNSIGNED_CHAR:
01327       basictype = 'h';
01328       break;
01329     case VTK_PARSE_SHORT:
01330       basictype = 's';
01331       break;
01332     case VTK_PARSE_UNSIGNED_SHORT:
01333       basictype = 't';
01334       break;
01335     case VTK_PARSE_INT:
01336       basictype = 'i';
01337       break;
01338     case VTK_PARSE_UNSIGNED_INT:
01339       basictype = 'j';
01340       break;
01341     case VTK_PARSE_LONG:
01342       basictype = 'l';
01343       break;
01344     case VTK_PARSE_UNSIGNED_LONG:
01345       basictype = 'm';
01346       break;
01347     case VTK_PARSE_LONG_LONG:
01348     case VTK_PARSE___INT64:
01349       basictype = 'x';
01350       break;
01351     case VTK_PARSE_UNSIGNED_LONG_LONG:
01352     case VTK_PARSE_UNSIGNED___INT64:
01353       basictype = 'y';
01354       break;
01355     case VTK_PARSE_FLOAT:
01356       basictype = 'f';
01357       break;
01358     case VTK_PARSE_DOUBLE:
01359       basictype = 'd';
01360       break;
01361     }
01362 
01363   if (basictype)
01364     {
01365     new_name[i++] = basictype;
01366     new_name[i] = '\0';
01367     return (size_t)(cp - name);
01368     }
01369 
01370   m = 0;
01371   cp = name;
01372   do
01373     {
01374     cp += m;
01375     while (*cp == ' ' || *cp == '\t') { cp++; }
01376     m = vtkParse_UnscopedNameLength(cp);
01377     }
01378   while ((m == 5 && strncmp("const", cp, 5) == 0) ||
01379          (m == 8 && strncmp("volatile", cp, 8) == 0));
01380 
01381   if (cp[m] == ':' && cp[m+1] == ':')
01382     {
01383     if (m == 3 && strncmp(cp, "std::", 5) == 0)
01384       {
01385       cp += 5;
01386       m = vtkParse_UnscopedNameLength(cp);
01387       if (cp[m] == ':' && cp[m+1] == ':')
01388         {
01389         new_name[i++] = 'N';
01390         scoped = 1;
01391         }
01392       /* short form for "std::" */
01393       new_name[i++] = 'S';
01394       new_name[i++] = 't';
01395       }
01396     else
01397       {
01398       new_name[i++] = 'N';
01399       scoped = 1;
01400       }
01401     }
01402 
01403   do
01404     {
01405     if (cp[0] == ':' && cp[1] == ':')
01406       {
01407       cp += 2;
01408       m = vtkParse_UnscopedNameLength(cp);
01409       }
01410 
01411     for (j = 0; j < m; j++)
01412       {
01413       if (cp[j] == '<')
01414         {
01415         break;
01416         }
01417       }
01418 
01419     /* write out identifier length */
01420     if (j >= 100) { new_name[i++] = '0' + (char)(j/100); }
01421     if (j >= 10) { new_name[i++] = '0' + (char)((j%100)/10); }
01422     new_name[i++] = '0' + (char)(j%10);
01423 
01424     /* write out the identifier */
01425     strncpy(&new_name[i], cp, j);
01426     i += j;
01427     cp += j;
01428 
01429     /* handle template args */
01430     if (*cp == '<')
01431       {
01432       new_name[i++] = 'I';
01433       do
01434         {
01435         do { cp++; } while (*cp == ' ' || *cp == '\t');
01436         m = 0;
01437         if ((*cp >= '0' && *cp <= '9') ||
01438             (*cp == '.' && cp[1] >= '0' && cp[1] <= '9') ||
01439             *cp == '\'' || *cp == '\"')
01440           {
01441           m = vtkParse_MangledLiteral(cp, &new_name[i]);
01442           }
01443         else
01444           {
01445           m = vtkParse_MangledTypeName(cp, &new_name[i]);
01446           }
01447         if (m == 0)
01448           {
01449           return 0;
01450           }
01451         cp += m;
01452         i = strlen(new_name);
01453         while (*cp == ' ' || *cp == '\t') { cp++; }
01454         }
01455       while (*cp == ',');
01456       new_name[i++] = 'E';
01457       if (*cp != '>')
01458         {
01459         new_name[i] = '\0';
01460         return 0;
01461         }
01462       cp++;
01463       }
01464     }
01465   while (cp[0] == ':' && cp[1] == ':');
01466 
01467   if (scoped)
01468     {
01469     new_name[i++] = 'E';
01470     }
01471 
01472   new_name[i] = '\0';
01473 
01474   return (size_t)(cp - name);
01475 }
01476 
01477 /* Generate a mangled name for a literal, use gcc ia64 ABI. */
01478 size_t vtkParse_MangledLiteral(const char *name, char *new_name)
01479 {
01480   const char *cp = name;
01481   size_t i = 0;
01482   char *tmp;
01483 
01484   /* only decimal integers are supported for now */
01485   if (*cp >= '0' && *cp <= '9')
01486     {
01487     /* reject octal and hexadecimal */
01488     if (cp[0] == '0' && (cp[1] == 'x' || cp[1] == 'X' ||
01489                          (cp[1] >= '0' && cp[1] <= '9')))
01490       {
01491       new_name[0] = '\0';
01492       return 0;
01493       }
01494 
01495     new_name[i++] = 'L';
01496     tmp = &new_name[i];
01497     new_name[i++] = 'i';
01498     do { new_name[i++] = *cp++; }
01499     while (*cp >= '0' && *cp <= '9');
01500 
01501     /* reject floats */
01502     if (*cp == '.' || *cp == 'f' || *cp == 'e' || *cp == 'E')
01503       {
01504       new_name[0] = '\0';
01505       return 0;
01506       }
01507 
01508     for (;;)
01509       {
01510       if (*cp == 'u' || *cp == 'U')
01511         {
01512         if (*tmp == 'i') { *tmp = 'j'; }
01513         else if (*tmp == 'l') { *tmp = 'm'; }
01514         else if (*tmp == 'x') { *tmp = 'y'; }
01515         cp++;
01516         }
01517       else if (*cp == 'l' || *cp == 'L')
01518         {
01519         if (*tmp == 'i') { *tmp = 'l'; }
01520         else if (*tmp == 'j') { *tmp = 'm'; }
01521         else if (*tmp == 'l') { *tmp = 'x'; }
01522         else if (*tmp == 'm') { *tmp = 'y'; }
01523         cp++;
01524         }
01525       else
01526         {
01527         break;
01528         }
01529       }
01530     new_name[i++] = 'E';
01531     }
01532   new_name[i] = '\0';
01533 
01534   return (size_t)(cp - name);
01535 }
01536 
01537 /* Get a zero-terminated array of the types in vtkTemplateMacro. */
01538 const char **vtkParse_GetTemplateMacroTypes()
01539 {
01540   static const char *types[] = {
01541     "char", "signed char", "unsigned char", "short", "unsigned short",
01542     "int", "unsigned int", "long", "unsigned long",
01543 #ifdef VTK_TYPE_USE_LONG_LONG
01544     "long long", "unsigned long long",
01545 #endif
01546 #ifdef VTK_TYPE_USE___INT64
01547     "__int64", "unsigned __int64",
01548 #endif
01549     "float", "double", NULL };
01550 
01551   return types;
01552 }
01553 
01554 /* Get a zero-terminated array of the types in vtkArray. */
01555 const char **vtkParse_GetArrayTypes()
01556 {
01557   static const char *types[] = {
01558     "char", "signed char", "unsigned char", "short", "unsigned short",
01559     "int", "unsigned int", "long", "unsigned long",
01560 #ifdef VTK_TYPE_USE_LONG_LONG
01561     "long long", "unsigned long long",
01562 #endif
01563 #ifdef VTK_TYPE_USE___INT64
01564     "__int64", "unsigned __int64",
01565 #endif
01566     "float", "double",
01567     "vtkStdString", "vtkUnicodeString", "vtkVariant", NULL };
01568 
01569   return types;
01570 }