Age Owner TLA Line data Source code
1 : /* src/interfaces/ecpg/preproc/variable.c */
2 :
3 : #include "postgres_fe.h"
4 :
5 : #include "preproc_extern.h"
6 :
7 : static struct variable *allvariables = NULL;
8 :
9 : struct variable *
2118 tgl 10 CBC 479 : new_variable(const char *name, struct ECPGtype *type, int brace_level)
11 : {
8397 bruce 12 479 : struct variable *p = (struct variable *) mm_alloc(sizeof(struct variable));
13 :
14 479 : p->name = mm_strdup(name);
15 479 : p->type = type;
7756 meskes 16 479 : p->brace_level = brace_level;
17 :
8397 bruce 18 479 : p->next = allvariables;
19 479 : allvariables = p;
20 :
2061 peter_e 21 479 : return p;
22 : }
23 :
24 : static struct variable *
2118 tgl 25 29 : find_struct_member(char *name, char *str, struct ECPGstruct_member *members, int brace_level)
26 : {
7255 meskes 27 29 : char *next = strpbrk(++str, ".-["),
28 : *end,
7188 bruce 29 29 : c = '\0';
30 :
8397 31 29 : if (next != NULL)
32 : {
8397 bruce 33 UBC 0 : c = *next;
34 0 : *next = '\0';
35 : }
36 :
8397 bruce 37 CBC 56 : for (; members; members = members->next)
38 : {
39 56 : if (strcmp(members->name, str) == 0)
40 : {
7255 meskes 41 29 : if (next == NULL)
42 : {
43 : /* found the end */
7777 44 29 : switch (members->type->type)
45 : {
8397 bruce 46 UBC 0 : case ECPGt_array:
2061 peter_e 47 0 : return new_variable(name, ECPGmake_array_type(ECPGmake_simple_type(members->type->u.element->type, members->type->u.element->size, members->type->u.element->counter), members->type->size), brace_level);
8397 bruce 48 0 : case ECPGt_struct:
49 : case ECPGt_union:
2061 peter_e 50 0 : return new_variable(name, ECPGmake_struct_type(members->type->u.members, members->type->type, members->type->type_name, members->type->struct_sizeof), brace_level);
8397 bruce 51 CBC 29 : default:
2061 peter_e 52 29 : return new_variable(name, ECPGmake_simple_type(members->type->type, members->type->size, members->type->counter), brace_level);
53 : }
54 : }
55 : else
56 : {
8397 bruce 57 UBC 0 : *next = c;
7255 meskes 58 0 : if (c == '[')
59 : {
60 : int count;
61 :
62 : /*
63 : * We don't care about what's inside the array braces so
64 : * just eat up the character
65 : */
7188 bruce 66 0 : for (count = 1, end = next + 1; count; end++)
67 : {
68 0 : switch (*end)
69 : {
70 0 : case '[':
71 0 : count++;
72 0 : break;
73 0 : case ']':
74 0 : count--;
75 0 : break;
76 0 : default:
77 0 : break;
78 : }
79 : }
80 : }
81 : else
82 0 : end = next;
83 :
7255 meskes 84 0 : switch (*end)
85 : {
6385 bruce 86 0 : case '\0': /* found the end, but this time it has to be
87 : * an array element */
7188 88 0 : if (members->type->type != ECPGt_array)
3435 peter_e 89 0 : mmfatal(PARSE_ERROR, "incorrectly formed variable \"%s\"", name);
90 :
7188 bruce 91 0 : switch (members->type->u.element->type)
92 : {
93 0 : case ECPGt_array:
2061 peter_e 94 0 : return new_variable(name, ECPGmake_array_type(ECPGmake_simple_type(members->type->u.element->u.element->type, members->type->u.element->u.element->size, members->type->u.element->u.element->counter), members->type->u.element->size), brace_level);
7188 bruce 95 0 : case ECPGt_struct:
96 : case ECPGt_union:
2061 peter_e 97 0 : return new_variable(name, ECPGmake_struct_type(members->type->u.element->u.members, members->type->u.element->type, members->type->u.element->type_name, members->type->u.element->struct_sizeof), brace_level);
7188 bruce 98 0 : default:
2061 peter_e 99 0 : return new_variable(name, ECPGmake_simple_type(members->type->u.element->type, members->type->u.element->size, members->type->u.element->counter), brace_level);
100 : }
101 : break;
7188 bruce 102 0 : case '-':
3783 meskes 103 0 : if (members->type->type == ECPGt_array)
2061 peter_e 104 0 : return find_struct_member(name, ++end, members->type->u.element->u.members, brace_level);
105 : else
106 0 : return find_struct_member(name, ++end, members->type->u.members, brace_level);
107 : break;
108 : break;
7188 bruce 109 0 : case '.':
7011 meskes 110 0 : if (members->type->type == ECPGt_array)
2061 peter_e 111 0 : return find_struct_member(name, end, members->type->u.element->u.members, brace_level);
112 : else
113 0 : return find_struct_member(name, end, members->type->u.members, brace_level);
114 : break;
7188 bruce 115 0 : default:
3435 peter_e 116 0 : mmfatal(PARSE_ERROR, "incorrectly formed variable \"%s\"", name);
117 : break;
118 : }
119 : }
120 : }
121 : }
122 :
2061 123 0 : return NULL;
124 : }
125 :
126 : static struct variable *
7255 meskes 127 CBC 29 : find_struct(char *name, char *next, char *end)
128 : {
129 : struct variable *p;
8397 bruce 130 29 : char c = *next;
131 :
132 : /* first get the mother structure entry */
133 29 : *next = '\0';
134 29 : p = find_variable(name);
135 :
136 29 : if (c == '-')
137 : {
7777 meskes 138 UBC 0 : if (p->type->type != ECPGt_array)
3435 peter_e 139 0 : mmfatal(PARSE_ERROR, "variable \"%s\" is not a pointer", name);
140 :
7777 meskes 141 0 : if (p->type->u.element->type != ECPGt_struct && p->type->u.element->type != ECPGt_union)
3435 peter_e 142 0 : mmfatal(PARSE_ERROR, "variable \"%s\" is not a pointer to a structure or a union", name);
143 :
144 : /* restore the name, we will need it later */
8397 bruce 145 0 : *next = c;
146 :
7242 meskes 147 0 : return find_struct_member(name, ++end, p->type->u.element->u.members, p->brace_level);
148 : }
149 : else
150 : {
7255 meskes 151 CBC 29 : if (next == end)
152 : {
153 29 : if (p->type->type != ECPGt_struct && p->type->type != ECPGt_union)
3435 peter_e 154 UBC 0 : mmfatal(PARSE_ERROR, "variable \"%s\" is neither a structure nor a union", name);
155 :
156 : /* restore the name, we will need it later */
7255 meskes 157 CBC 29 : *next = c;
158 :
159 29 : return find_struct_member(name, end, p->type->u.members, p->brace_level);
160 : }
161 : else
162 : {
7255 meskes 163 UBC 0 : if (p->type->type != ECPGt_array)
3435 peter_e 164 0 : mmfatal(PARSE_ERROR, "variable \"%s\" is not an array", name);
165 :
7255 meskes 166 0 : if (p->type->u.element->type != ECPGt_struct && p->type->u.element->type != ECPGt_union)
3435 peter_e 167 0 : mmfatal(PARSE_ERROR, "variable \"%s\" is not a pointer to a structure or a union", name);
168 :
169 : /* restore the name, we will need it later */
7255 meskes 170 0 : *next = c;
171 :
172 0 : return find_struct_member(name, end, p->type->u.element->u.members, p->brace_level);
173 : }
174 : }
175 : }
176 :
177 : static struct variable *
8397 bruce 178 CBC 1316 : find_simple(char *name)
179 : {
180 : struct variable *p;
181 :
182 10572 : for (p = allvariables; p; p = p->next)
183 : {
184 10572 : if (strcmp(p->name, name) == 0)
185 1316 : return p;
186 : }
187 :
2061 peter_e 188 UBC 0 : return NULL;
189 : }
190 :
191 : /* Note that this function will end the program in case of an unknown */
192 : /* variable */
193 : struct variable *
8397 bruce 194 CBC 1345 : find_variable(char *name)
195 : {
196 : char *next,
197 : *end;
198 : struct variable *p;
199 : int count;
200 :
7255 meskes 201 1345 : next = strpbrk(name, ".[-");
202 1345 : if (next)
203 : {
204 129 : if (*next == '[')
205 : {
206 : /*
207 : * We don't care about what's inside the array braces so just eat
208 : * up the characters
209 : */
7188 bruce 210 300 : for (count = 1, end = next + 1; count; end++)
211 : {
212 200 : switch (*end)
213 : {
7188 bruce 214 UBC 0 : case '[':
215 0 : count++;
216 0 : break;
7188 bruce 217 CBC 100 : case ']':
218 100 : count--;
219 100 : break;
220 100 : default:
221 100 : break;
222 : }
223 : }
224 100 : if (*end == '.')
7188 bruce 225 UBC 0 : p = find_struct(name, next, end);
226 : else
227 : {
7188 bruce 228 CBC 100 : char c = *next;
229 :
7255 meskes 230 100 : *next = '\0';
231 100 : p = find_simple(name);
6975 232 100 : if (p == NULL)
3435 peter_e 233 UBC 0 : mmfatal(PARSE_ERROR, "variable \"%s\" is not declared", name);
234 :
7255 meskes 235 CBC 100 : *next = c;
236 100 : switch (p->type->u.element->type)
237 : {
7255 meskes 238 UBC 0 : case ECPGt_array:
2061 peter_e 239 0 : return new_variable(name, ECPGmake_array_type(ECPGmake_simple_type(p->type->u.element->u.element->type, p->type->u.element->u.element->size, p->type->u.element->u.element->counter), p->type->u.element->size), p->brace_level);
7255 meskes 240 CBC 3 : case ECPGt_struct:
241 : case ECPGt_union:
2061 peter_e 242 3 : return new_variable(name, ECPGmake_struct_type(p->type->u.element->u.members, p->type->u.element->type, p->type->u.element->type_name, p->type->u.element->struct_sizeof), p->brace_level);
7255 meskes 243 97 : default:
2061 peter_e 244 97 : return new_variable(name, ECPGmake_simple_type(p->type->u.element->type, p->type->u.element->size, p->type->u.element->counter), p->brace_level);
245 : }
246 : }
247 : }
248 : else
7188 bruce 249 29 : p = find_struct(name, next, next);
250 : }
251 : else
252 1216 : p = find_simple(name);
253 :
8397 254 1245 : if (p == NULL)
3435 peter_e 255 UBC 0 : mmfatal(PARSE_ERROR, "variable \"%s\" is not declared", name);
256 :
2061 peter_e 257 CBC 1245 : return p;
258 : }
259 :
260 : void
6860 meskes 261 326 : remove_typedefs(int brace_level)
262 : {
263 : struct typedefs *p,
264 : *prev;
265 :
266 479 : for (p = prev = types; p;)
267 : {
268 153 : if (p->brace_level >= brace_level)
269 : {
270 : /* remove it */
271 13 : if (p == types)
272 13 : prev = types = p->next;
273 : else
6860 meskes 274 UBC 0 : prev->next = p->next;
275 :
6797 bruce 276 CBC 13 : if (p->type->type_enum == ECPGt_struct || p->type->type_enum == ECPGt_union)
6860 meskes 277 12 : free(p->struct_member_list);
278 13 : free(p->type);
279 13 : free(p->name);
280 13 : free(p);
281 13 : if (prev == types)
282 13 : p = types;
283 : else
6860 meskes 284 UBC 0 : p = prev ? prev->next : NULL;
285 : }
286 : else
287 : {
6860 meskes 288 CBC 140 : prev = p;
289 140 : p = prev->next;
290 : }
291 : }
292 326 : }
293 :
294 : void
8452 295 326 : remove_variables(int brace_level)
296 : {
297 : struct variable *p,
298 : *prev;
299 :
6860 300 1547 : for (p = prev = allvariables; p;)
301 : {
8397 bruce 302 1221 : if (p->brace_level >= brace_level)
303 : {
304 : /* is it still referenced by a cursor? */
305 : struct cursor *ptr;
306 :
7188 307 748 : for (ptr = cur; ptr != NULL; ptr = ptr->next)
308 : {
309 : struct arguments *varptr,
310 : *prevvar;
311 :
7242 meskes 312 610 : for (varptr = prevvar = ptr->argsinsert; varptr != NULL; varptr = varptr->next)
313 : {
314 253 : if (p == varptr->variable)
315 : {
316 : /* remove from list */
317 10 : if (varptr == ptr->argsinsert)
318 7 : ptr->argsinsert = varptr->next;
319 : else
320 3 : prevvar->next = varptr->next;
321 : }
322 : }
7053 323 362 : for (varptr = prevvar = ptr->argsresult; varptr != NULL; varptr = varptr->next)
324 : {
7242 325 5 : if (p == varptr->variable)
326 : {
327 : /* remove from list */
328 3 : if (varptr == ptr->argsresult)
329 3 : ptr->argsresult = varptr->next;
330 : else
7242 meskes 331 UBC 0 : prevvar->next = varptr->next;
332 : }
333 : }
334 : }
335 :
336 : /* remove it */
8397 bruce 337 CBC 391 : if (p == allvariables)
338 230 : prev = allvariables = p->next;
339 : else
340 161 : prev->next = p->next;
341 :
342 391 : ECPGfree_type(p->type);
343 391 : free(p->name);
344 391 : free(p);
6860 meskes 345 391 : if (prev == allvariables)
346 258 : p = allvariables;
347 : else
348 133 : p = prev ? prev->next : NULL;
349 : }
350 : else
351 : {
8397 bruce 352 830 : prev = p;
6860 meskes 353 830 : p = prev->next;
354 : }
355 : }
8452 356 326 : }
357 :
358 :
359 : /*
360 : * Here are the variables that need to be handled on every request.
361 : * These are of two kinds: input and output.
362 : * I will make two lists for them.
363 : */
364 :
365 : struct arguments *argsinsert = NULL;
366 : struct arguments *argsresult = NULL;
367 :
368 : void
369 1917 : reset_variables(void)
370 : {
8397 bruce 371 1917 : argsinsert = NULL;
372 1917 : argsresult = NULL;
8452 meskes 373 1917 : }
374 :
375 : /* Insert a new variable into our request list.
376 : * Note: The list is dumped from the end,
377 : * so we have to add new entries at the beginning */
378 : void
2118 tgl 379 480 : add_variable_to_head(struct arguments **list, struct variable *var, struct variable *ind)
380 : {
8397 bruce 381 480 : struct arguments *p = (struct arguments *) mm_alloc(sizeof(struct arguments));
382 :
383 480 : p->variable = var;
384 480 : p->indicator = ind;
385 480 : p->next = *list;
386 480 : *list = p;
8452 meskes 387 480 : }
388 :
389 : /* Append a new variable to our request list. */
390 : void
2118 tgl 391 93 : add_variable_to_tail(struct arguments **list, struct variable *var, struct variable *ind)
392 : {
393 : struct arguments *p,
8397 bruce 394 93 : *new = (struct arguments *) mm_alloc(sizeof(struct arguments));
395 :
396 100 : for (p = *list; p && p->next; p = p->next);
397 :
398 93 : new->variable = var;
399 93 : new->indicator = ind;
400 93 : new->next = NULL;
401 :
402 93 : if (p)
403 26 : p->next = new;
404 : else
405 67 : *list = new;
8431 meskes 406 93 : }
407 :
408 : void
2118 tgl 409 17 : remove_variable_from_list(struct arguments **list, struct variable *var)
410 : {
411 : struct arguments *p,
4790 bruce 412 17 : *prev = NULL;
413 17 : bool found = false;
414 :
4882 meskes 415 17 : for (p = *list; p; p = p->next)
416 : {
417 17 : if (p->variable == var)
418 : {
419 17 : found = true;
420 17 : break;
421 : }
4882 meskes 422 UBC 0 : prev = p;
423 : }
4882 meskes 424 CBC 17 : if (found)
425 : {
426 17 : if (prev)
4882 meskes 427 UBC 0 : prev->next = p->next;
428 : else
4882 meskes 429 CBC 17 : *list = p->next;
430 : }
431 17 : }
432 :
433 : /* Dump out a list of all the variable on this list.
434 : This is a recursive function that works from the end of the list and
435 : deletes the list as we go on.
436 : */
437 : void
2118 tgl 438 1561 : dump_variables(struct arguments *list, int mode)
439 : {
440 : char *str_zero;
441 :
8397 bruce 442 1561 : if (list == NULL)
443 1071 : return;
444 :
2858 meskes 445 490 : str_zero = mm_strdup("0");
446 :
447 : /*
448 : * The list is build up from the beginning so lets first dump the end of
449 : * the list:
450 : */
451 :
8397 bruce 452 490 : dump_variables(list->next, mode);
453 :
454 : /* Then the current element and its indicator */
2310 tgl 455 490 : ECPGdump_a_type(base_yyout, list->variable->name, list->variable->type, list->variable->brace_level,
4756 meskes 456 490 : list->indicator->name, list->indicator->type, list->indicator->brace_level,
457 : NULL, NULL, str_zero, NULL, NULL);
458 :
459 : /* Then release the list element. */
8397 bruce 460 490 : if (mode != 0)
461 490 : free(list);
462 :
3326 sfrost 463 490 : free(str_zero);
464 : }
465 :
466 : void
2118 tgl 467 67 : check_indicator(struct ECPGtype *var)
468 : {
469 : /* make sure this is a valid indicator variable */
7777 meskes 470 67 : switch (var->type)
471 : {
472 : struct ECPGstruct_member *p;
473 :
8452 474 45 : case ECPGt_short:
475 : case ECPGt_int:
476 : case ECPGt_long:
477 : case ECPGt_long_long:
478 : case ECPGt_unsigned_short:
479 : case ECPGt_unsigned_int:
480 : case ECPGt_unsigned_long:
481 : case ECPGt_unsigned_long_long:
482 45 : break;
483 :
484 11 : case ECPGt_struct:
485 : case ECPGt_union:
486 36 : for (p = var->u.members; p; p = p->next)
7777 487 25 : check_indicator(p->type);
8452 488 11 : break;
489 :
490 11 : case ECPGt_array:
491 11 : check_indicator(var->u.element);
492 11 : break;
8397 bruce 493 UBC 0 : default:
5189 peter_e 494 0 : mmerror(PARSE_ERROR, ET_ERROR, "indicator variable must have an integer type");
8452 meskes 495 0 : break;
496 : }
8452 meskes 497 CBC 67 : }
498 :
499 : struct typedefs *
271 tgl 500 GNC 5392 : get_typedef(const char *name, bool noerror)
501 : {
502 : struct typedefs *this;
503 :
504 8789 : for (this = types; this != NULL; this = this->next)
505 : {
506 3427 : if (strcmp(this->name, name) == 0)
507 30 : return this;
508 : }
509 :
510 5362 : if (!noerror)
3435 peter_e 511 LBC 0 : mmfatal(PARSE_ERROR, "unrecognized data type name \"%s\"", name);
8452 meskes 512 ECB :
271 tgl 513 GNC 5362 : return NULL;
514 : }
8452 meskes 515 ECB :
8452 meskes 516 EUB : void
6911 meskes 517 GIC 371 : adjust_array(enum ECPGttype type_enum, char **dimension, char **length, char *type_dimension, char *type_index, int pointer_len, bool type_definition)
8452 meskes 518 ECB : {
7270 meskes 519 GIC 371 : if (atoi(type_index) >= 0)
520 : {
521 6 : if (atoi(*length) >= 0)
3435 peter_e 522 LBC 0 : mmfatal(PARSE_ERROR, "multidimensional arrays are not supported");
523 :
8452 meskes 524 CBC 6 : *length = type_index;
525 : }
8397 bruce 526 ECB :
7270 meskes 527 GBC 371 : if (atoi(type_dimension) >= 0)
528 : {
7270 meskes 529 CBC 1 : if (atoi(*dimension) >= 0 && atoi(*length) >= 0)
3435 peter_e 530 UIC 0 : mmfatal(PARSE_ERROR, "multidimensional arrays are not supported");
531 :
7270 meskes 532 CBC 1 : if (atoi(*dimension) >= 0)
8452 meskes 533 UIC 0 : *length = *dimension;
8452 meskes 534 ECB :
8452 meskes 535 GBC 1 : *dimension = type_dimension;
536 : }
7522 bruce 537 ECB :
7522 bruce 538 GBC 371 : if (pointer_len > 2)
3435 peter_e 539 UIC 0 : mmfatal(PARSE_ERROR, ngettext("multilevel pointers (more than 2 levels) are not supported; found %d level",
3260 bruce 540 ECB : "multilevel pointers (more than 2 levels) are not supported; found %d levels", pointer_len),
541 : pointer_len);
542 :
4993 meskes 543 CBC 371 : if (pointer_len > 1 && type_enum != ECPGt_char && type_enum != ECPGt_unsigned_char && type_enum != ECPGt_string)
3435 peter_e 544 UBC 0 : mmfatal(PARSE_ERROR, "pointer to pointer is not supported for this data type");
545 :
7270 meskes 546 GIC 371 : if (pointer_len > 1 && (atoi(*length) >= 0 || atoi(*dimension) >= 0))
3435 peter_e 547 UIC 0 : mmfatal(PARSE_ERROR, "multidimensional arrays are not supported");
8452 meskes 548 ECB :
7270 meskes 549 GBC 371 : if (atoi(*length) >= 0 && atoi(*dimension) >= 0 && pointer_len)
3435 peter_e 550 UIC 0 : mmfatal(PARSE_ERROR, "multidimensional arrays are not supported");
8452 meskes 551 ECB :
8452 meskes 552 GBC 371 : switch (type_enum)
553 : {
8397 bruce 554 CBC 34 : case ECPGt_struct:
8397 bruce 555 EUB : case ECPGt_union:
556 : /* pointer has to get dimension 0 */
7814 meskes 557 CBC 34 : if (pointer_len)
558 : {
8397 bruce 559 9 : *length = *dimension;
4473 meskes 560 GIC 9 : *dimension = mm_strdup("0");
561 : }
8397 bruce 562 ECB :
7270 meskes 563 GIC 34 : if (atoi(*length) >= 0)
3435 peter_e 564 LBC 0 : mmfatal(PARSE_ERROR, "multidimensional arrays for structures are not supported");
8397 bruce 565 ECB :
8397 bruce 566 GIC 34 : break;
567 23 : case ECPGt_varchar:
1511 meskes 568 ECB : case ECPGt_bytea:
8397 bruce 569 EUB : /* pointer has to get dimension 0 */
7814 meskes 570 GIC 23 : if (pointer_len)
4473 meskes 571 LBC 0 : *dimension = mm_strdup("0");
8397 bruce 572 ECB :
573 : /* one index is the string length */
7270 meskes 574 GIC 23 : if (atoi(*length) < 0)
8397 bruce 575 ECB : {
8397 bruce 576 GBC 15 : *length = *dimension;
4473 meskes 577 GIC 15 : *dimension = mm_strdup("-1");
578 : }
8397 bruce 579 ECB :
8397 bruce 580 GIC 23 : break;
8397 bruce 581 CBC 118 : case ECPGt_char:
8397 bruce 582 ECB : case ECPGt_unsigned_char:
583 : case ECPGt_string:
584 : /* char ** */
7522 bruce 585 CBC 118 : if (pointer_len == 2)
7814 meskes 586 ECB : {
4473 meskes 587 GIC 8 : *length = *dimension = mm_strdup("0");
7814 588 8 : break;
589 : }
7522 bruce 590 ECB :
591 : /* pointer has to get length 0 */
7522 bruce 592 CBC 110 : if (pointer_len == 1)
4473 meskes 593 36 : *length = mm_strdup("0");
594 :
595 : /* one index is the string length */
7270 meskes 596 GIC 110 : if (atoi(*length) < 0)
8397 bruce 597 ECB : {
7188 598 : /*
599 : * make sure we return length = -1 for arrays without given
600 : * bounds
601 : */
6911 meskes 602 GIC 64 : if (atoi(*dimension) < 0 && !type_definition)
603 :
604 : /*
605 : * do not change this for typedefs since it will be
606 : * changed later on when the variable is defined
6911 meskes 607 ECB : */
4473 meskes 608 GIC 5 : *length = mm_strdup("1");
6698 609 59 : else if (strcmp(*dimension, "0") == 0)
4473 610 2 : *length = mm_strdup("-1");
611 : else
7216 612 57 : *length = *dimension;
7188 bruce 613 ECB :
4473 meskes 614 CBC 64 : *dimension = mm_strdup("-1");
8397 bruce 615 ECB : }
8397 bruce 616 GIC 110 : break;
8397 bruce 617 CBC 196 : default:
618 : /* a pointer has dimension = 0 */
7814 meskes 619 196 : if (pointer_len)
620 : {
8397 bruce 621 19 : *length = *dimension;
4473 meskes 622 19 : *dimension = mm_strdup("0");
623 : }
8397 bruce 624 ECB :
7270 meskes 625 GIC 196 : if (atoi(*length) >= 0)
3435 peter_e 626 LBC 0 : mmfatal(PARSE_ERROR, "multidimensional arrays for simple data types are not supported");
8397 bruce 627 ECB :
8397 bruce 628 GIC 196 : break;
629 : }
8452 meskes 630 CBC 371 : }
|