1 /*=========================================================================
3 Program: Visualization Toolkit
4 Module: vtkParseExtras.c
6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
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.
14 =========================================================================*/
15 /*-------------------------------------------------------------------------
16 Copyright (c) 2011 David Gobbi.
18 Contributed to the VisualizationToolkit by the author in May 2011
19 under the terms of the Visualization Toolkit 2008 copyright.
20 -------------------------------------------------------------------------*/
22 #include "vtkParseExtras.h"
23 #include "vtkParseString.h"
31 /* skip over an identifier */
32 static size_t vtkparse_id_len(const char *text)
37 if ((c >= 'a' && c <= 'z') ||
38 (c >= 'A' && c <= 'Z') ||
45 while ((c >= 'a' && c <= 'z') ||
46 (c >= 'A' && c <= 'Z') ||
47 (c >= '0' && c <= '9') ||
54 /* skip over numbers, int or float, including suffixes */
55 static size_t vtkparse_number_len(const char *text)
65 if (c >= '0' && c <= '9')
73 while ((c >= '0' && c <= '9') ||
74 (c >= 'a' && c <= 'z') ||
75 (c >= 'A' && c <= 'Z') ||
76 c == '_' || c == '.');
78 while ((c == '-' || c == '+') &&
79 (text[i-1] == 'e' || text[i-1] == 'E'));
85 /* skip over string and char literals. */
86 static size_t vtkparse_quote_len(const char *text)
89 const char qc = text[0];
92 if (c == '\'' || c == '\"')
100 while (c != qc && c != '\n' && c != '\0');
102 while (c == qc && text[i-1] == '\\');
113 /* skip over an expression in brackets */
114 static size_t vtkparse_bracket_len(const char *text)
123 if (bc == '(') { tc = ')'; }
124 else if (bc == '[') { tc = ']'; }
125 else if (bc == '{') { tc = '}'; semi = '\0'; }
126 else if (bc == '<') { tc = '>'; }
134 if (c == '\'' || c == '\"')
136 j = vtkparse_quote_len(&text[i]);
138 else if (c == bc || c == '(' || c == '[' || c == '{')
140 j = vtkparse_bracket_len(&text[i]);
143 while (c != tc && c != ')' && c != ']' && c != '}' &&
144 c != '\0' && c != '\n' && c != semi && j != 0);
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)
158 return vtkparse_id_len(text);
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)
167 i += vtkparse_id_len(text);
170 i += vtkparse_bracket_len(&text[i]);
171 if (text[i-1] != '>')
173 fprintf(stderr, "Bad template args %*.*s\n", (int)i, (int)i, text);
174 assert(text[i-1] == '>');
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)
189 if (text[i] == ':' && text[i+1] == ':') { i += 2; }
190 i += vtkParse_UnscopedNameLength(&text[i]);
192 while (text[i] == ':' && text[i+1] == ':');
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[])
202 const char *cp = str1;
203 char result_store[1024];
204 size_t resultMaxLen = 1024;
208 size_t lastPos, nameBegin, nameEnd;
210 int any_replaced = 0;
212 result = result_store;
223 while (cp[i] != '\0')
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')
232 if (cp[i] == '\'' || cp[i] == '\"')
234 i += vtkparse_quote_len(&cp[i]);
236 else if (cp[i] >= '0' && cp[i] <= '9')
238 i += vtkparse_number_len(&cp[i]);
247 /* skip all chars that are part of a name */
248 i += vtkparse_id_len(&cp[i]);
251 /* search through the list of names to replace */
253 m = nameEnd - nameBegin;
254 for (k = 0; k < n; k++)
257 if (l > 0 && l == m && strncmp(&cp[nameBegin], name[k], l) == 0)
266 /* expand the storage space if needed */
267 if (j + m + (nameBegin - lastPos) + 1 >= resultMaxLen)
270 tmp = (char *)malloc(resultMaxLen);
272 if (result != result_store)
279 /* copy the old bits */
280 if (nameBegin > lastPos)
282 strncpy(&result[j], &cp[lastPos], nameBegin - lastPos);
283 j += (nameBegin - lastPos);
286 /* do the replacement */
289 strncpy(&result[j], val[k], m);
291 /* guard against creating double ">>" */
292 if (val[k][m-1] == '>' && cp[nameEnd] == '>')
297 else if (nameEnd > nameBegin)
299 strncpy(&result[j], &cp[nameBegin], nameEnd - nameBegin);
300 j += (nameEnd - nameBegin);
310 /* use the efficient CacheString method */
311 cp = vtkParse_CacheString(cache, result, j);
312 if (result != result_store)
322 /* return a string that was allocated with malloc */
323 if (result == result_store)
325 tmp = (char *)malloc(strlen(result) + 1);
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[])
342 int j, m, dim, count;
347 valinfo->Value = vtkparse_string_replace(
348 cache, valinfo->Value, n, name, val);
351 m = valinfo->NumberOfDimensions;
355 for (j = 0; j < m; j++)
357 cp = valinfo->Dimensions[j];
360 cp = vtkparse_string_replace(cache, cp, n, name, val);
361 valinfo->Dimensions[j] = cp;
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++; }
370 dim = (int)strtol(valinfo->Dimensions[j], NULL, 0);
376 /* update count if all values are integer literals */
379 valinfo->Count = count;
384 /* Expand a typedef within a type declaration. */
385 void vtkParse_ExpandTypedef(
386 ValueInfo *valinfo, ValueInfo *typedefinfo)
388 const char *classname;
389 unsigned int baseType;
390 unsigned int pointers;
392 unsigned int qualifiers;
393 unsigned int tmp1, tmp2;
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);
403 if ((valinfo->Type & VTK_PARSE_CONST) != 0)
405 if ((pointers & VTK_PARSE_POINTER_LOWMASK) != 0)
407 if ((pointers & VTK_PARSE_POINTER_LOWMASK) != VTK_PARSE_ARRAY)
409 /* const turns into const pointer */
410 pointers = (pointers & ~VTK_PARSE_POINTER_LOWMASK);
411 pointers = (pointers | VTK_PARSE_CONST_POINTER);
416 /* const remains as const value */
417 qualifiers = (qualifiers | VTK_PARSE_CONST);
421 /* make a reversed copy of the pointer bitfield */
422 tmp1 = (valinfo->Type & VTK_PARSE_POINTER_MASK);
426 tmp2 = ((tmp2 << 2) | (tmp1 & VTK_PARSE_POINTER_LOWMASK));
427 tmp1 = ((tmp1 >> 2) & VTK_PARSE_POINTER_MASK);
430 /* turn pointers into zero-element arrays where necessary */
431 if ((pointers & VTK_PARSE_POINTER_LOWMASK) == VTK_PARSE_ARRAY)
433 tmp2 = ((tmp2 >> 2) & VTK_PARSE_POINTER_MASK);
436 vtkParse_AddStringToArray(
437 &valinfo->Dimensions, &valinfo->NumberOfDimensions, "");
438 tmp2 = ((tmp2 >> 2) & VTK_PARSE_POINTER_MASK);
443 /* combine the pointers */
446 pointers = ((pointers << 2) | (tmp2 & VTK_PARSE_POINTER_LOWMASK));
447 tmp2 = ((tmp2 >> 2) & VTK_PARSE_POINTER_MASK);
451 /* combine the arrays */
452 for (i = 0; i < typedefinfo->NumberOfDimensions; i++)
454 vtkParse_AddStringToArray(
455 &valinfo->Dimensions, &valinfo->NumberOfDimensions,
456 typedefinfo->Dimensions[i]);
458 if (valinfo->NumberOfDimensions > 1)
460 pointers = ((pointers & ~VTK_PARSE_POINTER_LOWMASK) | VTK_PARSE_ARRAY);
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;
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[])
479 if (((val->Type & VTK_PARSE_BASE_TYPE) == VTK_PARSE_OBJECT ||
480 (val->Type & VTK_PARSE_BASE_TYPE) == VTK_PARSE_UNKNOWN) &&
483 for (i = 0; i < n; i++)
485 if (typedefinfo[i] && strcmp(val->Class, typedefinfo[i]->Name) == 0)
487 vtkParse_ExpandTypedef(val, typedefinfo[i]);
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);
500 /* Helper struct for VTK-specific types */
501 struct vtk_type_struct
508 /* Simple utility for mapping VTK types to VTK_PARSE types */
509 unsigned int vtkParse_MapType(int vtktype)
511 static unsigned int typemap[] =
513 VTK_PARSE_VOID, /* VTK_VOID 0 */
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 */
538 if (vtktype > 0 && vtktype <= VTK_UNICODE_STRING)
540 return typemap[vtktype];
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)
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 },
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 },
581 const char *cp = text;
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;
592 while (*cp == ' ' || *cp == '\t') { cp++; }
594 while ((*cp >= 'a' && *cp <= 'z') ||
595 (*cp >= 'A' && *cp <= 'Z') ||
596 (*cp == '_') || (cp[0] == ':' && cp[1] == ':'))
598 /* skip all chars that are part of a name */
599 n = vtkParse_NameLength(cp);
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))
606 if (strncmp("static", cp, n) == 0)
608 static_bits = VTK_PARSE_STATIC;
611 else if (n == 5 && strncmp(cp, "const", n) == 0)
613 const_bits |= VTK_PARSE_CONST;
615 else if (n == 8 && strncmp(cp, "unsigned", n) == 0)
617 unsigned_bits |= VTK_PARSE_UNSIGNED;
621 base_bits = VTK_PARSE_INT;
624 else if (n == 6 && strncmp(cp, "signed", n) == 0)
626 if (base_bits == VTK_PARSE_CHAR)
628 classname = "signed char";
629 base_bits = VTK_PARSE_SIGNED_CHAR;
634 base_bits = VTK_PARSE_INT;
637 else if (n == 3 && strncmp(cp, "int", n) == 0)
642 base_bits = VTK_PARSE_INT;
645 else if (n == 4 && strncmp(cp, "long", n) == 0)
647 if (base_bits == VTK_PARSE_DOUBLE)
649 classname = "long double";
650 base_bits = VTK_PARSE_LONG_DOUBLE;
652 else if (base_bits == VTK_PARSE_LONG)
654 classname = "long long";
655 base_bits = VTK_PARSE_LONG_LONG;
660 base_bits = VTK_PARSE_LONG;
663 else if (n == 5 && strncmp(cp, "short", n) == 0)
666 base_bits = VTK_PARSE_SHORT;
668 else if (n == 4 && strncmp(cp, "char", n) == 0)
670 if (base_bits == VTK_PARSE_INT && unsigned_bits != VTK_PARSE_UNSIGNED)
672 classname = "signed char";
673 base_bits = VTK_PARSE_SIGNED_CHAR;
678 base_bits = VTK_PARSE_CHAR;
681 else if (n == 5 && strncmp(cp, "float", n) == 0)
684 base_bits = VTK_PARSE_FLOAT;
686 else if (n == 6 && strncmp(cp, "double", n) == 0)
688 if (base_bits == VTK_PARSE_LONG)
690 classname = "long double";
691 base_bits = VTK_PARSE_LONG_DOUBLE;
695 classname = "double";
696 base_bits = VTK_PARSE_DOUBLE;
699 else if (n == 4 && strncmp(cp, "bool", n) == 0)
702 base_bits = VTK_PARSE_BOOL;
704 else if (n == 4 && strncmp(cp, "void", n) == 0)
707 base_bits = VTK_PARSE_VOID;
709 else if (n == 7 && strncmp(cp, "__int64", n) == 0)
711 classname = "__int64";
712 base_bits = VTK_PARSE___INT64;
716 /* if type already found, break */
722 /* check vtk typedefs */
723 if (strncmp(cp, "vtk", 3) == 0)
725 for (i = 0; vtktypes[i].len != 0; i++)
727 if (n == vtktypes[i].len && strncmp(cp, vtktypes[i].name, n) == 0)
729 classname = vtktypes[i].name;
730 base_bits = vtkParse_MapType((int)vtktypes[i].type);
735 /* check standard typedefs */
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; }
743 /* advance past the namespace */
746 for (i = 0; stdtypes[i].len != 0; i++)
748 if (n == stdtypes[i].len && strncmp(tmpcp, stdtypes[i].name, n) == 0)
750 classname = stdtypes[i].name;
751 base_bits = stdtypes[i].type;
755 /* include the namespace if present */
756 if (base_bits != 0 && m > 0)
763 /* anything else is assumed to be a class, enum, or who knows */
766 base_bits = VTK_PARSE_UNKNOWN;
770 /* VTK classes all start with vtk */
771 if (strncmp(classname, "vtk", 3) == 0)
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++)
779 base_bits = VTK_PARSE_UNKNOWN;
784 /* Qt objects and enums */
785 else if (classname[0] == 'Q' &&
786 ((classname[1] >= 'A' && classname[2] <= 'Z') ||
787 strncmp(classname, "Qt::", 4) == 0))
789 base_bits = VTK_PARSE_QOBJECT;
795 while (*cp == ' ' || *cp == '\t') { cp++; }
798 if ((unsigned_bits & VTK_PARSE_UNSIGNED) != 0)
803 classname = "unsigned char";
805 case VTK_PARSE_SHORT:
806 classname = "unsigned short";
809 classname = "unsigned int";
812 classname = "unsigned long";
814 case VTK_PARSE_LONG_LONG:
815 classname = "unsigned long long";
817 case VTK_PARSE___INT64:
818 classname = "unsigned __int64";
823 *type_ptr = (static_bits | const_bits | unsigned_bits | base_bits);
827 *classname_ptr = classname;
830 len = strlen(classname);
835 return (size_t)(cp - text);
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)
842 const char *cp = text;
845 unsigned int base_bits = 0;
846 unsigned int pointer_bits = 0;
847 unsigned int ref_bits = 0;
848 const char *classname = NULL;
850 /* get the basic type with qualifiers */
851 cp += vtkParse_BasicTypeFromString(cp, &base_bits, &classname, &n);
853 data->Class = vtkParse_CacheString(cache, classname, n);
855 if ((base_bits & VTK_PARSE_STATIC) != 0)
860 /* look for pointers (and const pointers) */
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') &&
873 while (*cp == ' ' || *cp == '\t') { cp++; }
874 pointer_bits = (pointer_bits | VTK_PARSE_CONST_POINTER);
878 pointer_bits = (pointer_bits | VTK_PARSE_POINTER);
880 pointer_bits = (pointer_bits & VTK_PARSE_POINTER_MASK);
887 while (*cp == ' ' || *cp == '\t') { cp++; }
888 ref_bits = VTK_PARSE_REF;
891 /* look for the variable name */
892 if ((*cp >= 'a' && *cp <= 'z') ||
893 (*cp >= 'A' && *cp <= 'Z') ||
896 /* skip all chars that are part of a name */
897 n = vtkparse_id_len(cp);
898 data->Name = vtkParse_CacheString(cache, cp, n);
900 while (*cp == ' ' || *cp == '\t') { cp++; }
903 /* look for array brackets */
911 n = vtkparse_bracket_len(cp);
917 while (*cp == ' ' || *cp == '\t') { cp++; n--; }
918 while (n > 0 && (cp[n-1] == ' ' || cp[n-1] == '\t')) { n--; }
919 vtkParse_AddStringToArray(
921 &data->NumberOfDimensions,
922 vtkParse_CacheString(cache, cp, n));
924 if (*cp >= '0' && *cp <= '9' && vtkparse_number_len(cp) == n)
926 m = (int)strtol(cp, NULL, 0);
931 while (*cp == ' ' || *cp == '\t') { cp++; }
932 if (*cp == ']') { cp++; }
933 while (*cp == ' ' || *cp == '\t') { cp++; }
936 /* add pointer indirection to correspond to first array dimension */
937 if (data->NumberOfDimensions > 1)
939 pointer_bits = ((pointer_bits << 2) | VTK_PARSE_ARRAY);
941 else if (data->NumberOfDimensions == 1)
943 pointer_bits = ((pointer_bits << 2) | VTK_PARSE_POINTER);
945 pointer_bits = (pointer_bits & VTK_PARSE_POINTER_MASK);
947 /* (Add code here to look for "=" followed by a value ) */
949 data->Type = (pointer_bits | ref_bits | base_bits);
954 /* Generate a C++ declaration string from a ValueInfo struct */
955 const char *vtkParse_ValueInfoToString(
956 ValueInfo *data, int *needs_free)
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;
970 if (pointer_bits == 0 && ref_bits == 0 && qualifier_bits == 0 &&
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++)
987 l += 2 + strlen(data->Dimensions[j]);
990 l += 4; /* for safety */
992 text = (char *)malloc(l);
994 if ((qualifier_bits & VTK_PARSE_CONST) != 0)
996 strcpy(&text[i], "const ");
1000 strcpy(&text[i], classname);
1001 i += strlen(classname);
1004 while (pointer_bits != 0)
1007 reverse_bits |= (pointer_bits & VTK_PARSE_POINTER_LOWMASK);
1008 pointer_bits = ((pointer_bits >> 2) & VTK_PARSE_POINTER_MASK);
1011 while (reverse_bits != 0)
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))
1020 else if (pointer_type == VTK_PARSE_POINTER)
1024 else if (pointer_type == VTK_PARSE_CONST_POINTER)
1026 strcpy(&text[i], "*const ");
1030 reverse_bits = ((reverse_bits >> 2) & VTK_PARSE_POINTER_MASK);
1040 strcpy(&text[i], name);
1044 for (j = 0; j < data->NumberOfDimensions; j++)
1047 if (data->Dimensions[j])
1049 strcpy(&text[i], data->Dimensions[j]);
1050 i += strlen(data->Dimensions[j]);
1057 /* make sure enough space was allocated */
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[])
1073 return vtkparse_string_replace(NULL, str1, n, name, val);
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[]);
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[])
1087 vtkParse_ExpandTypedefs(data, cache, m, arg_names, arg_values, arg_types);
1088 vtkParse_ExpandValues(data, cache, m, arg_names, arg_values);
1093 data->Function, cache, m, arg_names, arg_values, arg_types);
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[])
1104 n = data->NumberOfParameters;
1105 for (i = 0; i < n; i++)
1108 data->Parameters[i], cache, m, arg_names, arg_values, arg_types);
1111 if (data->ReturnValue)
1114 data->ReturnValue, cache, m, arg_names, arg_values, arg_types);
1117 if (data->Signature)
1120 vtkparse_string_replace(
1121 cache, data->Signature, m, arg_names, arg_values);
1124 /* legacy information for old wrappers */
1125 #ifndef VTK_PARSE_LEGACY_REMOVE
1126 n = data->NumberOfArguments;
1127 for (i = 0; i < n; i++)
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)
1134 data->ArgCounts[i] = data->Parameters[i]->Count;
1138 if (data->ReturnValue)
1140 data->ReturnType = data->ReturnValue->Type;
1141 data->ReturnClass = data->ReturnValue->Class;
1142 if (data->ReturnValue->NumberOfDimensions == 1 &&
1143 data->ReturnValue->Count > 0)
1145 data->HintSize = data->ReturnValue->Count;
1149 #endif /* VTK_PARSE_LEGACY_REMOVE */
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[])
1159 /* superclasses may be templated */
1160 n = data->NumberOfSuperClasses;
1161 for (i = 0; i < n; i++)
1163 data->SuperClasses[i] = vtkparse_string_replace(
1164 cache, data->SuperClasses[i], m, arg_names, arg_values);
1167 n = data->NumberOfClasses;
1168 for (i = 0; i < n; i++)
1171 data->Classes[i], cache, m, arg_names, arg_values, arg_types);
1174 n = data->NumberOfFunctions;
1175 for (i = 0; i < n; i++)
1178 data->Functions[i], cache, m, arg_names, arg_values, arg_types);
1181 n = data->NumberOfConstants;
1182 for (i = 0; i < n; i++)
1185 data->Constants[i], cache, m, arg_names, arg_values, arg_types);
1188 n = data->NumberOfVariables;
1189 for (i = 0; i < n; i++)
1192 data->Variables[i], cache, m, arg_names, arg_values, arg_types);
1195 n = data->NumberOfTypedefs;
1196 for (i = 0; i < n; i++)
1199 data->Typedefs[i], cache, m, arg_names, arg_values, arg_types);
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[])
1212 const char **template_args = NULL;
1213 int template_arg_count = 0;
1215 n = vtkParse_NameLength(text);
1217 /* is the class templated? */
1218 for (i = 0; i < n; i++)
1228 new_text = (char *)malloc(i + 1);
1229 strncpy(new_text, text, i);
1231 *classname = new_text;
1237 /* extract the template arguments */
1240 while (text[i] == ' ' || text[i] == '\t') { i++; }
1242 while (text[j] != ',' && text[j] != '>' &&
1243 text[j] != '\n' && text[j] != '\0')
1245 if (text[j] == '<' || text[j] == '(' ||
1246 text[j] == '[' || text[j] == '{')
1248 j += vtkparse_bracket_len(&text[j]);
1250 else if (text[j] == '\'' || text[j] == '\"')
1252 j += vtkparse_quote_len(&text[j]);
1261 while (text[k-1] == ' ' || text[k-1] == '\t') { --k; }
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,
1269 assert(template_arg_count <= nargs);
1280 while (template_arg_count < nargs)
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);
1290 *argp = template_args;
1295 /* Free the list of strings returned by ExtractTemplateArgs. */
1296 void vtkParse_FreeTemplateDecomposition(
1297 const char *name, int n, const char **args)
1308 for (i = 0; i < n; i++)
1310 free((char *)args[i]);
1313 free((char **)args);
1317 /* Instantiate a class template by substituting the provided arguments. */
1318 void vtkParse_InstantiateClassTemplate(
1319 ClassInfo *data, StringCache *cache, int n, const char *args[])
1321 TemplateInfo *t = data->Template;
1322 const char **new_args = NULL;
1323 const char **arg_names = NULL;
1324 ValueInfo **arg_types = NULL;
1331 fprintf(stderr, "vtkParse_InstantiateClassTemplate: "
1332 "this class is not templated.\n");
1336 m = t->NumberOfParameters;
1339 fprintf(stderr, "vtkParse_InstantiateClassTemplate: "
1340 "too many template args.\n");
1344 for (i = n; i < m; i++)
1346 if (t->Parameters[i]->Value == NULL ||
1347 t->Parameters[i]->Value[0] == '\0')
1349 fprintf(stderr, "vtkParse_InstantiateClassTemplate: "
1350 "too few template args.\n");
1355 new_args = (const char **)malloc(m*sizeof(char **));
1356 for (i = 0; i < n; i++)
1358 new_args[i] = args[i];
1360 for (i = n; i < m; i++)
1362 new_args[i] = t->Parameters[i]->Value;
1366 arg_names = (const char **)malloc(m*sizeof(char **));
1367 arg_types = (ValueInfo **)malloc(m*sizeof(ValueInfo *));
1368 for (i = 0; i < m; i++)
1370 arg_names[i] = t->Parameters[i]->Name;
1371 arg_types[i] = NULL;
1372 if (t->Parameters[i]->Type == 0)
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];
1382 /* no longer a template (has been instantiated) */
1385 vtkParse_FreeTemplate(data->Template);
1387 data->Template = NULL;
1389 /* append template args to class name */
1390 k = strlen(data->Name) + 2;
1391 for (i = 0; i < m; i++)
1393 k += strlen(args[i]) + 2;
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++)
1401 strcpy(&new_name[k], args[i]);
1402 k += strlen(args[i]);
1405 new_name[k++] = ',';
1406 new_name[k++] = ' ';
1409 if (new_name[k-1] == '>')
1411 new_name[k++] = ' ';
1413 new_name[k++] = '>';
1416 data->Name = vtkParse_CacheString(cache, new_name, k);
1419 /* do the template arg substitution */
1420 class_substitution(data, cache, m, arg_names, args, arg_types);
1422 /* free all allocated arrays */
1423 free((char **)new_args);
1424 free((char **)arg_names);
1426 for (i = 0; i < m; i++)
1430 vtkParse_FreeValue(arg_types[i]);
1436 /* Get a zero-terminated array of the types in vtkTemplateMacro. */
1437 const char **vtkParse_GetTemplateMacroTypes()
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",
1445 #ifdef VTK_TYPE_USE___INT64
1446 "__int64", "unsigned __int64",
1448 "float", "double", NULL };
1453 /* Get a zero-terminated array of the types in vtkArray. */
1454 const char **vtkParse_GetArrayTypes()
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",
1462 #ifdef VTK_TYPE_USE___INT64
1463 "__int64", "unsigned __int64",
1466 "vtkStdString", "vtkUnicodeString", "vtkVariant", NULL };