Line data Source code
1 : /* src/interfaces/ecpg/preproc/type.c */
2 :
3 : #include "postgres_fe.h"
4 :
5 : #include "preproc_extern.h"
6 :
7 : #define indicator_set ind_type != NULL && ind_type->type != ECPGt_NO_INDICATOR
8 :
9 : static struct ECPGstruct_member struct_no_indicator = {"no_indicator", &ecpg_no_indicator, NULL};
10 :
11 : /* duplicate memberlist */
12 : struct ECPGstruct_member *
13 142 : ECPGstruct_member_dup(struct ECPGstruct_member *rm)
14 : {
15 142 : struct ECPGstruct_member *new = NULL;
16 :
17 452 : while (rm)
18 : {
19 : struct ECPGtype *type;
20 :
21 310 : switch (rm->type->type)
22 : {
23 8 : case ECPGt_struct:
24 : case ECPGt_union:
25 8 : type = ECPGmake_struct_type(rm->type->u.members, rm->type->type, rm->type->type_name, rm->type->struct_sizeof);
26 8 : break;
27 0 : case ECPGt_array:
28 :
29 : /*
30 : * if this array does contain a struct again, we have to
31 : * create the struct too
32 : */
33 0 : if (rm->type->u.element->type == ECPGt_struct || rm->type->u.element->type == ECPGt_union)
34 0 : type = ECPGmake_struct_type(rm->type->u.element->u.members, rm->type->u.element->type, rm->type->u.element->type_name, rm->type->u.element->struct_sizeof);
35 : else
36 0 : type = ECPGmake_array_type(ECPGmake_simple_type(rm->type->u.element->type, rm->type->u.element->size, rm->type->u.element->counter), rm->type->size);
37 0 : break;
38 302 : default:
39 302 : type = ECPGmake_simple_type(rm->type->type, rm->type->size, rm->type->counter);
40 302 : break;
41 : }
42 :
43 310 : ECPGmake_struct_member(rm->name, type, &new);
44 :
45 310 : rm = rm->next;
46 : }
47 :
48 142 : return new;
49 : }
50 :
51 : /* The NAME argument is copied. The type argument is preserved as a pointer. */
52 : void
53 418 : ECPGmake_struct_member(const char *name, struct ECPGtype *type, struct ECPGstruct_member **start)
54 : {
55 : struct ECPGstruct_member *ptr,
56 : *ne =
57 418 : (struct ECPGstruct_member *) mm_alloc(sizeof(struct ECPGstruct_member));
58 :
59 418 : ne->name = mm_strdup(name);
60 418 : ne->type = type;
61 418 : ne->next = NULL;
62 :
63 590 : for (ptr = *start; ptr && ptr->next; ptr = ptr->next);
64 :
65 418 : if (ptr)
66 254 : ptr->next = ne;
67 : else
68 164 : *start = ne;
69 418 : }
70 :
71 : struct ECPGtype *
72 1530 : ECPGmake_simple_type(enum ECPGttype type, const char *size, int counter)
73 : {
74 1530 : struct ECPGtype *ne = (struct ECPGtype *) mm_alloc(sizeof(struct ECPGtype));
75 :
76 1530 : ne->type = type;
77 1530 : ne->type_name = NULL;
78 1530 : ne->size = mm_strdup(size);
79 1530 : ne->u.element = NULL;
80 1530 : ne->struct_sizeof = NULL;
81 1530 : ne->counter = counter; /* only needed for varchar and bytea */
82 :
83 1530 : return ne;
84 : }
85 :
86 : struct ECPGtype *
87 144 : ECPGmake_array_type(struct ECPGtype *type, const char *size)
88 : {
89 144 : struct ECPGtype *ne = ECPGmake_simple_type(ECPGt_array, size, 0);
90 :
91 144 : ne->u.element = type;
92 :
93 144 : return ne;
94 : }
95 :
96 : struct ECPGtype *
97 66 : ECPGmake_struct_type(struct ECPGstruct_member *rm, enum ECPGttype type, char *type_name, char *struct_sizeof)
98 : {
99 66 : struct ECPGtype *ne = ECPGmake_simple_type(type, "1", 0);
100 :
101 66 : ne->type_name = mm_strdup(type_name);
102 66 : ne->u.members = ECPGstruct_member_dup(rm);
103 66 : ne->struct_sizeof = struct_sizeof;
104 :
105 66 : return ne;
106 : }
107 :
108 : static const char *
109 1212 : get_type(enum ECPGttype type)
110 : {
111 1212 : switch (type)
112 : {
113 390 : case ECPGt_char:
114 390 : return "ECPGt_char";
115 : break;
116 0 : case ECPGt_unsigned_char:
117 0 : return "ECPGt_unsigned_char";
118 : break;
119 64 : case ECPGt_short:
120 64 : return "ECPGt_short";
121 : break;
122 0 : case ECPGt_unsigned_short:
123 0 : return "ECPGt_unsigned_short";
124 : break;
125 424 : case ECPGt_int:
126 424 : return "ECPGt_int";
127 : break;
128 0 : case ECPGt_unsigned_int:
129 0 : return "ECPGt_unsigned_int";
130 : break;
131 24 : case ECPGt_long:
132 24 : return "ECPGt_long";
133 : break;
134 0 : case ECPGt_unsigned_long:
135 0 : return "ECPGt_unsigned_long";
136 : break;
137 0 : case ECPGt_long_long:
138 0 : return "ECPGt_long_long";
139 : break;
140 0 : case ECPGt_unsigned_long_long:
141 0 : return "ECPGt_unsigned_long_long";
142 : break;
143 12 : case ECPGt_float:
144 12 : return "ECPGt_float";
145 : break;
146 32 : case ECPGt_double:
147 32 : return "ECPGt_double";
148 : break;
149 26 : case ECPGt_bool:
150 26 : return "ECPGt_bool";
151 : break;
152 40 : case ECPGt_varchar:
153 40 : return "ECPGt_varchar";
154 42 : case ECPGt_bytea:
155 42 : return "ECPGt_bytea";
156 0 : case ECPGt_NO_INDICATOR: /* no indicator */
157 0 : return "ECPGt_NO_INDICATOR";
158 : break;
159 40 : case ECPGt_char_variable: /* string that should not be quoted */
160 40 : return "ECPGt_char_variable";
161 : break;
162 32 : case ECPGt_const: /* constant string quoted */
163 32 : return "ECPGt_const";
164 : break;
165 12 : case ECPGt_decimal:
166 12 : return "ECPGt_decimal";
167 : break;
168 18 : case ECPGt_numeric:
169 18 : return "ECPGt_numeric";
170 : break;
171 8 : case ECPGt_interval:
172 8 : return "ECPGt_interval";
173 : break;
174 0 : case ECPGt_descriptor:
175 0 : return "ECPGt_descriptor";
176 : break;
177 0 : case ECPGt_sqlda:
178 0 : return "ECPGt_sqlda";
179 : break;
180 20 : case ECPGt_date:
181 20 : return "ECPGt_date";
182 : break;
183 26 : case ECPGt_timestamp:
184 26 : return "ECPGt_timestamp";
185 : break;
186 2 : case ECPGt_string:
187 2 : return "ECPGt_string";
188 : break;
189 0 : default:
190 0 : mmerror(PARSE_ERROR, ET_ERROR, "unrecognized variable type code %d", type);
191 : }
192 :
193 0 : return NULL;
194 : }
195 :
196 : /* Dump a type.
197 : The type is dumped as:
198 : type-tag <comma> - enum ECPGttype
199 : reference-to-variable <comma> - char *
200 : size <comma> - long size of this field (if varchar)
201 : arrsize <comma> - long number of elements in the arr
202 : offset <comma> - offset to the next element
203 : Where:
204 : type-tag is one of the simple types or varchar.
205 : reference-to-variable can be a reference to a struct element.
206 : arrsize is the size of the array in case of array fetches. Otherwise 0.
207 : size is the maxsize in case it is a varchar. Otherwise it is the size of
208 : the variable (required to do array fetches of structs).
209 : */
210 : static void ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype type,
211 : char *varcharsize,
212 : char *arrsize, const char *size, const char *prefix, int counter);
213 : static void ECPGdump_a_struct(FILE *o, const char *name, const char *ind_name, char *arrsize,
214 : struct ECPGtype *type, struct ECPGtype *ind_type, const char *prefix, const char *ind_prefix);
215 :
216 : void
217 1234 : ECPGdump_a_type(FILE *o, const char *name, struct ECPGtype *type, const int brace_level,
218 : const char *ind_name, struct ECPGtype *ind_type, const int ind_brace_level,
219 : const char *prefix, const char *ind_prefix,
220 : char *arr_str_size, const char *struct_sizeof,
221 : const char *ind_struct_sizeof)
222 : {
223 : struct variable *var;
224 :
225 1234 : if (type->type != ECPGt_descriptor && type->type != ECPGt_sqlda &&
226 1140 : type->type != ECPGt_char_variable && type->type != ECPGt_const &&
227 : brace_level >= 0)
228 : {
229 : char *str;
230 :
231 996 : str = mm_strdup(name);
232 996 : var = find_variable(str);
233 996 : free(str);
234 :
235 996 : if ((var->type->type != type->type) ||
236 996 : (var->type->type_name && !type->type_name) ||
237 996 : (!var->type->type_name && type->type_name) ||
238 996 : (var->type->type_name && type->type_name && strcmp(var->type->type_name, type->type_name) != 0))
239 0 : mmerror(PARSE_ERROR, ET_ERROR, "variable \"%s\" is hidden by a local variable of a different type", name);
240 996 : else if (var->brace_level != brace_level)
241 0 : mmerror(PARSE_ERROR, ET_WARNING, "variable \"%s\" is hidden by a local variable", name);
242 :
243 996 : if (ind_name && ind_type && ind_type->type != ECPGt_NO_INDICATOR && ind_brace_level >= 0)
244 : {
245 64 : str = mm_strdup(ind_name);
246 64 : var = find_variable(str);
247 64 : free(str);
248 :
249 64 : if ((var->type->type != ind_type->type) ||
250 64 : (var->type->type_name && !ind_type->type_name) ||
251 64 : (!var->type->type_name && ind_type->type_name) ||
252 64 : (var->type->type_name && ind_type->type_name && strcmp(var->type->type_name, ind_type->type_name) != 0))
253 0 : mmerror(PARSE_ERROR, ET_ERROR, "indicator variable \"%s\" is hidden by a local variable of a different type", ind_name);
254 64 : else if (var->brace_level != ind_brace_level)
255 0 : mmerror(PARSE_ERROR, ET_WARNING, "indicator variable \"%s\" is hidden by a local variable", ind_name);
256 : }
257 : }
258 :
259 1234 : switch (type->type)
260 : {
261 166 : case ECPGt_array:
262 166 : if (indicator_set && ind_type->type != ECPGt_array)
263 0 : mmfatal(INDICATOR_NOT_ARRAY, "indicator for array/pointer has to be array/pointer");
264 166 : switch (type->u.element->type)
265 : {
266 0 : case ECPGt_array:
267 0 : mmerror(PARSE_ERROR, ET_ERROR, "nested arrays are not supported (except strings)"); /* array of array */
268 0 : break;
269 16 : case ECPGt_struct:
270 : case ECPGt_union:
271 32 : ECPGdump_a_struct(o, name,
272 : ind_name,
273 : type->size,
274 : type->u.element,
275 16 : (ind_type == NULL) ? NULL : ((ind_type->type == ECPGt_NO_INDICATOR) ? ind_type : ind_type->u.element),
276 : prefix, ind_prefix);
277 16 : break;
278 150 : default:
279 150 : if (!IS_SIMPLE_TYPE(type->u.element->type))
280 0 : base_yyerror("internal error: unknown datatype, please report this to <" PACKAGE_BUGREPORT ">");
281 :
282 150 : ECPGdump_a_simple(o, name,
283 150 : type->u.element->type,
284 150 : type->u.element->size, type->size, struct_sizeof ? struct_sizeof : NULL,
285 150 : prefix, type->u.element->counter);
286 :
287 150 : if (ind_type != NULL)
288 : {
289 110 : if (ind_type->type == ECPGt_NO_INDICATOR)
290 : {
291 106 : char *str_neg_one = mm_strdup("-1");
292 :
293 106 : ECPGdump_a_simple(o, ind_name, ind_type->type, ind_type->size, str_neg_one, NULL, ind_prefix, 0);
294 106 : free(str_neg_one);
295 : }
296 : else
297 : {
298 4 : ECPGdump_a_simple(o, ind_name, ind_type->u.element->type,
299 4 : ind_type->u.element->size, ind_type->size, NULL, ind_prefix, 0);
300 : }
301 : }
302 : }
303 166 : break;
304 12 : case ECPGt_struct:
305 : {
306 12 : char *str_one = mm_strdup("1");
307 :
308 12 : if (indicator_set && ind_type->type != ECPGt_struct)
309 0 : mmfatal(INDICATOR_NOT_STRUCT, "indicator for struct has to be a struct");
310 :
311 12 : ECPGdump_a_struct(o, name, ind_name, str_one, type, ind_type, prefix, ind_prefix);
312 12 : free(str_one);
313 : }
314 12 : break;
315 0 : case ECPGt_union: /* cannot dump a complete union */
316 0 : base_yyerror("type of union has to be specified");
317 0 : break;
318 40 : case ECPGt_char_variable:
319 : {
320 : /*
321 : * Allocate for each, as there are code-paths where the values
322 : * get stomped on.
323 : */
324 40 : char *str_varchar_one = mm_strdup("1");
325 40 : char *str_arr_one = mm_strdup("1");
326 40 : char *str_neg_one = mm_strdup("-1");
327 :
328 40 : if (indicator_set && (ind_type->type == ECPGt_struct || ind_type->type == ECPGt_array))
329 0 : mmfatal(INDICATOR_NOT_SIMPLE, "indicator for simple data type has to be simple");
330 :
331 40 : ECPGdump_a_simple(o, name, type->type, str_varchar_one, (arr_str_size && strcmp(arr_str_size, "0") != 0) ? arr_str_size : str_arr_one, struct_sizeof, prefix, 0);
332 40 : if (ind_type != NULL)
333 40 : ECPGdump_a_simple(o, ind_name, ind_type->type, ind_type->size, (arr_str_size && strcmp(arr_str_size, "0") != 0) ? arr_str_size : str_neg_one, ind_struct_sizeof, ind_prefix, 0);
334 :
335 40 : free(str_varchar_one);
336 40 : free(str_arr_one);
337 40 : free(str_neg_one);
338 : }
339 40 : break;
340 44 : case ECPGt_descriptor:
341 : {
342 : /*
343 : * Allocate for each, as there are code-paths where the values
344 : * get stomped on.
345 : */
346 44 : char *str_neg_one = mm_strdup("-1");
347 44 : char *ind_type_neg_one = mm_strdup("-1");
348 :
349 44 : if (indicator_set && (ind_type->type == ECPGt_struct || ind_type->type == ECPGt_array))
350 0 : mmfatal(INDICATOR_NOT_SIMPLE, "indicator for simple data type has to be simple");
351 :
352 44 : ECPGdump_a_simple(o, name, type->type, NULL, str_neg_one, NULL, prefix, 0);
353 44 : if (ind_type != NULL)
354 44 : ECPGdump_a_simple(o, ind_name, ind_type->type, ind_type->size, ind_type_neg_one, NULL, ind_prefix, 0);
355 :
356 44 : free(str_neg_one);
357 44 : free(ind_type_neg_one);
358 : }
359 44 : break;
360 972 : default:
361 : {
362 : /*
363 : * Allocate for each, as there are code-paths where the values
364 : * get stomped on.
365 : */
366 972 : char *str_neg_one = mm_strdup("-1");
367 972 : char *ind_type_neg_one = mm_strdup("-1");
368 :
369 972 : if (indicator_set && (ind_type->type == ECPGt_struct || ind_type->type == ECPGt_array))
370 0 : mmfatal(INDICATOR_NOT_SIMPLE, "indicator for simple data type has to be simple");
371 :
372 972 : ECPGdump_a_simple(o, name, type->type, type->size, (arr_str_size && strcmp(arr_str_size, "0") != 0) ? arr_str_size : str_neg_one, struct_sizeof, prefix, type->counter);
373 972 : if (ind_type != NULL)
374 880 : ECPGdump_a_simple(o, ind_name, ind_type->type, ind_type->size, (arr_str_size && strcmp(arr_str_size, "0") != 0) ? arr_str_size : ind_type_neg_one, ind_struct_sizeof, ind_prefix, 0);
375 :
376 972 : free(str_neg_one);
377 972 : free(ind_type_neg_one);
378 : }
379 972 : break;
380 : }
381 1234 : }
382 :
383 :
384 : /* If size is NULL, then the offset is 0, if not use size as a
385 : string, it represents the offset needed if we are in an array of structs. */
386 : static void
387 2280 : ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype type,
388 : char *varcharsize,
389 : char *arrsize,
390 : const char *size,
391 : const char *prefix,
392 : int counter)
393 : {
394 2280 : if (type == ECPGt_NO_INDICATOR)
395 974 : fprintf(o, "\n\tECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ");
396 1306 : else if (type == ECPGt_descriptor)
397 : /* remember that name here already contains quotes (if needed) */
398 44 : fprintf(o, "\n\tECPGt_descriptor, %s, 1L, 1L, 1L, ", name);
399 1262 : else if (type == ECPGt_sqlda)
400 50 : fprintf(o, "\n\tECPGt_sqlda, &%s, 0L, 0L, 0L, ", name);
401 : else
402 : {
403 1212 : char *variable = (char *) mm_alloc(strlen(name) + ((prefix == NULL) ? 0 : strlen(prefix)) + 4);
404 1212 : char *offset = (char *) mm_alloc(strlen(name) + strlen("sizeof(struct varchar_)") + 1 + strlen(varcharsize) + sizeof(int) * CHAR_BIT * 10 / 3);
405 : char *struct_name;
406 :
407 1212 : switch (type)
408 : {
409 : /*
410 : * we have to use the & operator except for arrays and
411 : * pointers
412 : */
413 :
414 82 : case ECPGt_varchar:
415 : case ECPGt_bytea:
416 :
417 : /*
418 : * we have to use the pointer except for arrays with given
419 : * bounds
420 : */
421 82 : if (((atoi(arrsize) > 0) ||
422 82 : (atoi(arrsize) == 0 && strcmp(arrsize, "0") != 0)) &&
423 : size == NULL)
424 4 : sprintf(variable, "(%s%s)", prefix ? prefix : "", name);
425 : else
426 78 : sprintf(variable, "&(%s%s)", prefix ? prefix : "", name);
427 :
428 : /*
429 : * If we created a varchar structure automatically, counter is
430 : * greater than 0.
431 : */
432 82 : if (type == ECPGt_varchar)
433 40 : struct_name = "struct varchar";
434 : else
435 42 : struct_name = "struct bytea";
436 :
437 82 : if (counter)
438 80 : sprintf(offset, "sizeof(%s_%d)", struct_name, counter);
439 : else
440 2 : sprintf(offset, "sizeof(%s)", struct_name);
441 82 : break;
442 432 : case ECPGt_char:
443 : case ECPGt_unsigned_char:
444 : case ECPGt_char_variable:
445 : case ECPGt_string:
446 : {
447 432 : char *sizeof_name = "char";
448 :
449 : /*
450 : * we have to use the pointer except for arrays with given
451 : * bounds, ecpglib will distinguish between * and []
452 : */
453 432 : if ((atoi(varcharsize) > 1 ||
454 170 : (atoi(arrsize) > 0) ||
455 118 : (atoi(varcharsize) == 0 && strcmp(varcharsize, "0") != 0) ||
456 102 : (atoi(arrsize) == 0 && strcmp(arrsize, "0") != 0))
457 330 : && size == NULL)
458 : {
459 316 : sprintf(variable, "(%s%s)", prefix ? prefix : "", name);
460 316 : if ((type == ECPGt_char || type == ECPGt_unsigned_char) &&
461 274 : strcmp(varcharsize, "0") == 0)
462 : {
463 : /*
464 : * If this is an array of char *, the offset would
465 : * be sizeof(char *) and not sizeof(char).
466 : */
467 0 : sizeof_name = "char *";
468 : }
469 : }
470 : else
471 116 : sprintf(variable, "&(%s%s)", prefix ? prefix : "", name);
472 :
473 432 : sprintf(offset, "(%s)*sizeof(%s)", strcmp(varcharsize, "0") == 0 ? "1" : varcharsize, sizeof_name);
474 432 : break;
475 : }
476 18 : case ECPGt_numeric:
477 :
478 : /*
479 : * we have to use a pointer here
480 : */
481 18 : sprintf(variable, "&(%s%s)", prefix ? prefix : "", name);
482 18 : sprintf(offset, "sizeof(numeric)");
483 18 : break;
484 8 : case ECPGt_interval:
485 :
486 : /*
487 : * we have to use a pointer here
488 : */
489 8 : sprintf(variable, "&(%s%s)", prefix ? prefix : "", name);
490 8 : sprintf(offset, "sizeof(interval)");
491 8 : break;
492 20 : case ECPGt_date:
493 :
494 : /*
495 : * we have to use a pointer and translate the variable type
496 : */
497 20 : sprintf(variable, "&(%s%s)", prefix ? prefix : "", name);
498 20 : sprintf(offset, "sizeof(date)");
499 20 : break;
500 26 : case ECPGt_timestamp:
501 :
502 : /*
503 : * we have to use a pointer and translate the variable type
504 : */
505 26 : sprintf(variable, "&(%s%s)", prefix ? prefix : "", name);
506 26 : sprintf(offset, "sizeof(timestamp)");
507 26 : break;
508 32 : case ECPGt_const:
509 :
510 : /*
511 : * just dump the const as string
512 : */
513 32 : sprintf(variable, "\"%s\"", name);
514 32 : sprintf(offset, "strlen(\"%s\")", name);
515 32 : break;
516 594 : default:
517 :
518 : /*
519 : * we have to use the pointer except for arrays with given
520 : * bounds
521 : */
522 594 : if (((atoi(arrsize) > 0) ||
523 594 : (atoi(arrsize) == 0 && strcmp(arrsize, "0") != 0)) &&
524 : size == NULL)
525 36 : sprintf(variable, "(%s%s)", prefix ? prefix : "", name);
526 : else
527 558 : sprintf(variable, "&(%s%s)", prefix ? prefix : "", name);
528 :
529 594 : sprintf(offset, "sizeof(%s)", ecpg_type_name(type));
530 594 : break;
531 : }
532 :
533 : /*
534 : * Array size would be -1 for addresses of members within structure,
535 : * when pointer to structure is being dumped.
536 : */
537 1212 : if (atoi(arrsize) < 0 && !size)
538 890 : strcpy(arrsize, "1");
539 :
540 : /*
541 : * If size i.e. the size of structure of which this variable is part
542 : * of, that gives the offset to the next element, if required
543 : */
544 1212 : if (size == NULL || strlen(size) == 0)
545 1090 : fprintf(o, "\n\t%s,%s,(long)%s,(long)%s,%s, ", get_type(type), variable, varcharsize, arrsize, offset);
546 : else
547 122 : fprintf(o, "\n\t%s,%s,(long)%s,(long)%s,%s, ", get_type(type), variable, varcharsize, arrsize, size);
548 :
549 1212 : free(variable);
550 1212 : free(offset);
551 : }
552 2280 : }
553 :
554 :
555 : /* Penetrate a struct and dump the contents. */
556 : static void
557 28 : ECPGdump_a_struct(FILE *o, const char *name, const char *ind_name, char *arrsize, struct ECPGtype *type, struct ECPGtype *ind_type, const char *prefix, const char *ind_prefix)
558 : {
559 : /*
560 : * If offset is NULL, then this is the first recursive level. If not then
561 : * we are in a struct and the offset is used as offset.
562 : */
563 : struct ECPGstruct_member *p,
564 28 : *ind_p = NULL;
565 28 : char *pbuf = (char *) mm_alloc(strlen(name) + ((prefix == NULL) ? 0 : strlen(prefix)) + 3);
566 28 : char *ind_pbuf = (char *) mm_alloc(strlen(ind_name) + ((ind_prefix == NULL) ? 0 : strlen(ind_prefix)) + 3);
567 :
568 28 : if (atoi(arrsize) == 1)
569 12 : sprintf(pbuf, "%s%s.", prefix ? prefix : "", name);
570 : else
571 16 : sprintf(pbuf, "%s%s->", prefix ? prefix : "", name);
572 :
573 28 : prefix = pbuf;
574 :
575 28 : if (ind_type == &ecpg_no_indicator)
576 4 : ind_p = &struct_no_indicator;
577 24 : else if (ind_type != NULL)
578 : {
579 24 : if (atoi(arrsize) == 1)
580 8 : sprintf(ind_pbuf, "%s%s.", ind_prefix ? ind_prefix : "", ind_name);
581 : else
582 16 : sprintf(ind_pbuf, "%s%s->", ind_prefix ? ind_prefix : "", ind_name);
583 :
584 24 : ind_prefix = ind_pbuf;
585 24 : ind_p = ind_type->u.members;
586 : }
587 :
588 100 : for (p = type->u.members; p; p = p->next)
589 : {
590 144 : ECPGdump_a_type(o, p->name, p->type, -1,
591 : (ind_p != NULL) ? ind_p->name : NULL,
592 : (ind_p != NULL) ? ind_p->type : NULL,
593 : -1,
594 72 : prefix, ind_prefix, arrsize, type->struct_sizeof,
595 : (ind_p != NULL) ? ind_type->struct_sizeof : NULL);
596 72 : if (ind_p != NULL && ind_p != &struct_no_indicator)
597 : {
598 60 : ind_p = ind_p->next;
599 60 : if (ind_p == NULL && p->next != NULL)
600 : {
601 0 : mmerror(PARSE_ERROR, ET_WARNING, "indicator struct \"%s\" has too few members", ind_name);
602 0 : ind_p = &struct_no_indicator;
603 : }
604 : }
605 : }
606 :
607 28 : if (ind_type != NULL && ind_p != NULL && ind_p != &struct_no_indicator)
608 : {
609 0 : mmerror(PARSE_ERROR, ET_WARNING, "indicator struct \"%s\" has too many members", ind_name);
610 : }
611 :
612 28 : free(pbuf);
613 28 : free(ind_pbuf);
614 28 : }
615 :
616 : void
617 96 : ECPGfree_struct_member(struct ECPGstruct_member *rm)
618 : {
619 224 : while (rm)
620 : {
621 128 : struct ECPGstruct_member *p = rm;
622 :
623 128 : rm = rm->next;
624 128 : free(p->name);
625 128 : free(p->type);
626 128 : free(p);
627 : }
628 96 : }
629 :
630 : void
631 788 : ECPGfree_type(struct ECPGtype *type)
632 : {
633 788 : if (!IS_SIMPLE_TYPE(type->type))
634 : {
635 160 : switch (type->type)
636 : {
637 136 : case ECPGt_array:
638 136 : switch (type->u.element->type)
639 : {
640 0 : case ECPGt_array:
641 0 : base_yyerror("internal error: found multidimensional array\n");
642 0 : break;
643 26 : case ECPGt_struct:
644 : case ECPGt_union:
645 : /* Array of structs. */
646 26 : ECPGfree_struct_member(type->u.element->u.members);
647 26 : free(type->u.element);
648 26 : break;
649 110 : default:
650 110 : if (!IS_SIMPLE_TYPE(type->u.element->type))
651 0 : base_yyerror("internal error: unknown datatype, please report this to <" PACKAGE_BUGREPORT ">");
652 :
653 110 : free(type->u.element);
654 : }
655 136 : break;
656 24 : case ECPGt_struct:
657 : case ECPGt_union:
658 24 : ECPGfree_struct_member(type->u.members);
659 24 : break;
660 0 : default:
661 0 : mmerror(PARSE_ERROR, ET_ERROR, "unrecognized variable type code %d", type->type);
662 0 : break;
663 : }
664 628 : }
665 788 : free(type);
666 788 : }
667 :
668 : const char *
669 132 : get_dtype(enum ECPGdtype type)
670 : {
671 132 : switch (type)
672 : {
673 0 : case ECPGd_count:
674 0 : return "ECPGd_count";
675 : break;
676 62 : case ECPGd_data:
677 62 : return "ECPGd_data";
678 : break;
679 4 : case ECPGd_di_code:
680 4 : return "ECPGd_di_code";
681 : break;
682 0 : case ECPGd_di_precision:
683 0 : return "ECPGd_di_precision";
684 : break;
685 34 : case ECPGd_indicator:
686 34 : return "ECPGd_indicator";
687 : break;
688 0 : case ECPGd_key_member:
689 0 : return "ECPGd_key_member";
690 : break;
691 4 : case ECPGd_length:
692 4 : return "ECPGd_length";
693 : break;
694 18 : case ECPGd_name:
695 18 : return "ECPGd_name";
696 : break;
697 0 : case ECPGd_nullable:
698 0 : return "ECPGd_nullable";
699 : break;
700 2 : case ECPGd_octet:
701 2 : return "ECPGd_octet";
702 : break;
703 2 : case ECPGd_precision:
704 2 : return "ECPGd_precision";
705 : break;
706 0 : case ECPGd_ret_length:
707 0 : return "ECPGd_ret_length";
708 2 : case ECPGd_ret_octet:
709 2 : return "ECPGd_ret_octet";
710 : break;
711 2 : case ECPGd_scale:
712 2 : return "ECPGd_scale";
713 : break;
714 2 : case ECPGd_type:
715 2 : return "ECPGd_type";
716 : break;
717 0 : case ECPGd_cardinality:
718 0 : return "ECPGd_cardinality";
719 0 : default:
720 0 : mmerror(PARSE_ERROR, ET_ERROR, "unrecognized descriptor item code %d", type);
721 : }
722 :
723 0 : return NULL;
724 : }
|