~vcs-imports/mammoth-replicator/trunk

« back to all changes in this revision

Viewing changes to src/interfaces/ecpg/preproc/type.c

  • Committer: alvherre
  • Date: 2005-12-16 21:24:52 UTC
  • Revision ID: svn-v4:db760fc0-0f08-0410-9d63-cc6633f64896:trunk:1
Initial import of the REL8_0_3 sources from the Pgsql CVS repository.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "postgres_fe.h"
 
2
 
 
3
#include "extern.h"
 
4
 
 
5
#define indicator_set ind_type != NULL && ind_type->type != ECPGt_NO_INDICATOR
 
6
 
 
7
struct ECPGstruct_member struct_no_indicator = {"no_indicator", &ecpg_no_indicator, NULL};
 
8
 
 
9
/* malloc + error check */
 
10
void *
 
11
mm_alloc(size_t size)
 
12
{
 
13
        void       *ptr = malloc(size);
 
14
 
 
15
        if (ptr == NULL)
 
16
                mmerror(OUT_OF_MEMORY, ET_FATAL, "Out of memory\n");
 
17
 
 
18
        return ptr;
 
19
}
 
20
 
 
21
/* strdup + error check */
 
22
char *
 
23
mm_strdup(const char *string)
 
24
{
 
25
        char       *new = strdup(string);
 
26
 
 
27
        if (new == NULL)
 
28
                mmerror(OUT_OF_MEMORY, ET_FATAL, "Out of memory\n");
 
29
 
 
30
        return new;
 
31
}
 
32
 
 
33
/* duplicate memberlist */
 
34
struct ECPGstruct_member *
 
35
ECPGstruct_member_dup(struct ECPGstruct_member * rm)
 
36
{
 
37
        struct ECPGstruct_member *new = NULL;
 
38
 
 
39
        while (rm)
 
40
        {
 
41
                struct ECPGtype *type;
 
42
 
 
43
                switch (rm->type->type)
 
44
                {
 
45
                        case ECPGt_struct:
 
46
                        case ECPGt_union:
 
47
                                type = ECPGmake_struct_type(rm->type->u.members, rm->type->type, rm->type->struct_sizeof);
 
48
                                break;
 
49
                        case ECPGt_array:
 
50
 
 
51
                                /*
 
52
                                 * if this array does contain a struct again, we have to
 
53
                                 * create the struct too
 
54
                                 */
 
55
                                if (rm->type->u.element->type == ECPGt_struct)
 
56
                                        type = ECPGmake_struct_type(rm->type->u.element->u.members, rm->type->u.element->type, rm->type->u.element->struct_sizeof);
 
57
                                else
 
58
                                        type = ECPGmake_array_type(ECPGmake_simple_type(rm->type->u.element->type, rm->type->u.element->size), rm->type->size);
 
59
                                break;
 
60
                        default:
 
61
                                type = ECPGmake_simple_type(rm->type->type, rm->type->size);
 
62
                                break;
 
63
                }
 
64
 
 
65
                ECPGmake_struct_member(rm->name, type, &new);
 
66
 
 
67
                rm = rm->next;
 
68
        }
 
69
 
 
70
        return (new);
 
71
}
 
72
 
 
73
/* The NAME argument is copied. The type argument is preserved as a pointer. */
 
74
void
 
75
ECPGmake_struct_member(char *name, struct ECPGtype * type, struct ECPGstruct_member ** start)
 
76
{
 
77
        struct ECPGstruct_member *ptr,
 
78
                           *ne =
 
79
        (struct ECPGstruct_member *) mm_alloc(sizeof(struct ECPGstruct_member));
 
80
 
 
81
        ne->name = strdup(name);
 
82
        ne->type = type;
 
83
        ne->next = NULL;
 
84
 
 
85
        for (ptr = *start; ptr && ptr->next; ptr = ptr->next);
 
86
 
 
87
        if (ptr)
 
88
                ptr->next = ne;
 
89
        else
 
90
                *start = ne;
 
91
}
 
92
 
 
93
struct ECPGtype *
 
94
ECPGmake_simple_type(enum ECPGttype type, char *size)
 
95
{
 
96
        struct ECPGtype *ne = (struct ECPGtype *) mm_alloc(sizeof(struct ECPGtype));
 
97
 
 
98
        ne->type = type;
 
99
        ne->size = size;
 
100
        ne->u.element = NULL;
 
101
        ne->struct_sizeof = NULL;
 
102
 
 
103
        return ne;
 
104
}
 
105
 
 
106
struct ECPGtype *
 
107
ECPGmake_array_type(struct ECPGtype * type, char *size)
 
108
{
 
109
        struct ECPGtype *ne = ECPGmake_simple_type(ECPGt_array, size);
 
110
 
 
111
        ne->u.element = type;
 
112
 
 
113
        return ne;
 
114
}
 
115
 
 
116
struct ECPGtype *
 
117
ECPGmake_struct_type(struct ECPGstruct_member * rm, enum ECPGttype type, char *struct_sizeof)
 
118
{
 
119
        struct ECPGtype *ne = ECPGmake_simple_type(type, make_str("1"));
 
120
 
 
121
        ne->u.members = ECPGstruct_member_dup(rm);
 
122
        ne->struct_sizeof = struct_sizeof;
 
123
 
 
124
        return ne;
 
125
}
 
126
 
 
127
static const char *
 
128
get_type(enum ECPGttype type)
 
129
{
 
130
        switch (type)
 
131
        {
 
132
                case ECPGt_char:
 
133
                        return ("ECPGt_char");
 
134
                        break;
 
135
                case ECPGt_unsigned_char:
 
136
                        return ("ECPGt_unsigned_char");
 
137
                        break;
 
138
                case ECPGt_short:
 
139
                        return ("ECPGt_short");
 
140
                        break;
 
141
                case ECPGt_unsigned_short:
 
142
                        return ("ECPGt_unsigned_short");
 
143
                        break;
 
144
                case ECPGt_int:
 
145
                        return ("ECPGt_int");
 
146
                        break;
 
147
                case ECPGt_unsigned_int:
 
148
                        return ("ECPGt_unsigned_int");
 
149
                        break;
 
150
                case ECPGt_long:
 
151
                        return ("ECPGt_long");
 
152
                        break;
 
153
                case ECPGt_unsigned_long:
 
154
                        return ("ECPGt_unsigned_long");
 
155
                        break;
 
156
                case ECPGt_long_long:
 
157
                        return ("ECPGt_long_long");
 
158
                        break;
 
159
                case ECPGt_unsigned_long_long:
 
160
                        return ("ECPGt_unsigned_long_long");
 
161
                        break;
 
162
                case ECPGt_float:
 
163
                        return ("ECPGt_float");
 
164
                        break;
 
165
                case ECPGt_double:
 
166
                        return ("ECPGt_double");
 
167
                        break;
 
168
                case ECPGt_bool:
 
169
                        return ("ECPGt_bool");
 
170
                        break;
 
171
                case ECPGt_varchar:
 
172
                        return ("ECPGt_varchar");
 
173
                case ECPGt_NO_INDICATOR:                /* no indicator */
 
174
                        return ("ECPGt_NO_INDICATOR");
 
175
                        break;
 
176
                case ECPGt_char_variable:               /* string that should not be
 
177
                                                                                 * quoted */
 
178
                        return ("ECPGt_char_variable");
 
179
                        break;
 
180
                case ECPGt_const:               /* constant string quoted */
 
181
                        return ("ECPGt_const");
 
182
                        break;
 
183
                case ECPGt_decimal:
 
184
                        return ("ECPGt_decimal");
 
185
                        break;
 
186
                case ECPGt_numeric:
 
187
                        return ("ECPGt_numeric");
 
188
                        break;
 
189
                case ECPGt_interval:
 
190
                        return ("ECPGt_interval");
 
191
                        break;
 
192
                case ECPGt_descriptor:
 
193
                        return ("ECPGt_descriptor");
 
194
                        break;
 
195
                case ECPGt_date:
 
196
                        return ("ECPGt_date");
 
197
                        break;
 
198
                case ECPGt_timestamp:
 
199
                        return ("ECPGt_timestamp");
 
200
                        break;
 
201
                default:
 
202
                        mmerror(PARSE_ERROR, ET_ERROR, "illegal variable type %d\n", type);
 
203
        }
 
204
 
 
205
        return NULL;
 
206
}
 
207
 
 
208
/* Dump a type.
 
209
   The type is dumped as:
 
210
   type-tag <comma>                                - enum ECPGttype
 
211
   reference-to-variable <comma>                   - char *
 
212
   size <comma>                                    - long size of this field (if varchar)
 
213
   arrsize <comma>                                 - long number of elements in the arr
 
214
   offset <comma>                                  - offset to the next element
 
215
   Where:
 
216
   type-tag is one of the simple types or varchar.
 
217
   reference-to-variable can be a reference to a struct element.
 
218
   arrsize is the size of the array in case of array fetches. Otherwise 0.
 
219
   size is the maxsize in case it is a varchar. Otherwise it is the size of
 
220
   the variable (required to do array fetches of structs).
 
221
 */
 
222
static void ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype type,
 
223
                                  char *varcharsize,
 
224
                                  char *arrsiz, const char *siz, const char *prefix);
 
225
static void ECPGdump_a_struct(FILE *o, const char *name, const char *ind_name, char *arrsiz,
 
226
                                  struct ECPGtype * type, struct ECPGtype * ind_type, const char *offset, const char *prefix, const char *ind_prefix);
 
227
 
 
228
void
 
229
ECPGdump_a_type(FILE *o, const char *name, struct ECPGtype * type,
 
230
                                const char *ind_name, struct ECPGtype * ind_type,
 
231
                                const char *prefix, const char *ind_prefix,
 
232
                                char *arr_str_siz, const char *struct_sizeof,
 
233
                                const char *ind_struct_sizeof)
 
234
{
 
235
        switch (type->type)
 
236
        {
 
237
                case ECPGt_array:
 
238
                        if (indicator_set && ind_type->type != ECPGt_array)
 
239
                                mmerror(INDICATOR_NOT_ARRAY, ET_FATAL, "Indicator for array/pointer has to be array/pointer.\n");
 
240
                        switch (type->u.element->type)
 
241
                        {
 
242
                                case ECPGt_array:
 
243
                                        mmerror(PARSE_ERROR, ET_ERROR, "No nested arrays allowed (except strings)");            /* array of array */
 
244
                                        break;
 
245
                                case ECPGt_struct:
 
246
                                case ECPGt_union:
 
247
                                        ECPGdump_a_struct(o, name,
 
248
                                                                          ind_name,
 
249
                                                                          type->size,
 
250
                                                                          type->u.element,
 
251
                                                                          (ind_type->type == ECPGt_NO_INDICATOR) ? ind_type : ind_type->u.element,
 
252
                                                                          NULL, prefix, ind_prefix);
 
253
                                        break;
 
254
                                default:
 
255
                                        if (!IS_SIMPLE_TYPE(type->u.element->type))
 
256
                                                yyerror("Internal error: unknown datatype, please inform pgsql-bugs@postgresql.org");
 
257
 
 
258
                                        ECPGdump_a_simple(o, name,
 
259
                                                                          type->u.element->type,
 
260
                                                type->u.element->size, type->size, NULL, prefix);
 
261
 
 
262
                                        if (ind_type != NULL)
 
263
                                        {
 
264
                                                if (ind_type->type == ECPGt_NO_INDICATOR)
 
265
                                                        ECPGdump_a_simple(o, ind_name, ind_type->type, ind_type->size, make_str("-1"), NULL, ind_prefix);
 
266
                                                else
 
267
                                                {
 
268
                                                        ECPGdump_a_simple(o, ind_name, ind_type->u.element->type,
 
269
                                                                                          ind_type->u.element->size, ind_type->size, NULL, ind_prefix);
 
270
                                                }
 
271
                                        }
 
272
                        }
 
273
                        break;
 
274
                case ECPGt_struct:
 
275
                        if (indicator_set && ind_type->type != ECPGt_struct)
 
276
                                mmerror(INDICATOR_NOT_STRUCT, ET_FATAL, "Indicator for struct has to be struct.\n");
 
277
 
 
278
                        ECPGdump_a_struct(o, name, ind_name, make_str("1"), type, ind_type, NULL, prefix, ind_prefix);
 
279
                        break;
 
280
                case ECPGt_union:               /* cannot dump a complete union */
 
281
                        yyerror("Type of union has to be specified");
 
282
                        break;
 
283
                case ECPGt_char_variable:
 
284
                        if (indicator_set && (ind_type->type == ECPGt_struct || ind_type->type == ECPGt_array))
 
285
                                mmerror(INDICATOR_NOT_SIMPLE, ET_FATAL, "Indicator for simple datatype has to be simple.\n");
 
286
 
 
287
                        ECPGdump_a_simple(o, name, type->type, make_str("1"), (arr_str_siz && strcmp(arr_str_siz, "0") != 0) ? arr_str_siz : make_str("1"), struct_sizeof, prefix);
 
288
                        ECPGdump_a_simple(o, ind_name, ind_type->type, ind_type->size, (arr_str_siz && strcmp(arr_str_siz, "0") != 0) ? arr_str_siz : make_str("-1"), ind_struct_sizeof, ind_prefix);
 
289
                        break;
 
290
                case ECPGt_descriptor:
 
291
                        if (indicator_set && (ind_type->type == ECPGt_struct || ind_type->type == ECPGt_array))
 
292
                                mmerror(INDICATOR_NOT_SIMPLE, ET_FATAL, "Indicator for simple datatype has to be simple.\n");
 
293
 
 
294
                        ECPGdump_a_simple(o, name, type->type, NULL, make_str("-1"), NULL, prefix);
 
295
                        ECPGdump_a_simple(o, ind_name, ind_type->type, ind_type->size, make_str("-1"), NULL, ind_prefix);
 
296
                        break;
 
297
                default:
 
298
                        if (indicator_set && (ind_type->type == ECPGt_struct || ind_type->type == ECPGt_array))
 
299
                                mmerror(INDICATOR_NOT_SIMPLE, ET_FATAL, "Indicator for simple datatype has to be simple.\n");
 
300
 
 
301
                        ECPGdump_a_simple(o, name, type->type, type->size, (arr_str_siz && strcmp(arr_str_siz, "0") != 0) ? arr_str_siz : make_str("-1"), struct_sizeof, prefix);
 
302
                        if (ind_type != NULL)
 
303
                                ECPGdump_a_simple(o, ind_name, ind_type->type, ind_type->size, (arr_str_siz && strcmp(arr_str_siz, "0") != 0) ? arr_str_siz : make_str("-1"), ind_struct_sizeof, ind_prefix);
 
304
                        break;
 
305
        }
 
306
}
 
307
 
 
308
 
 
309
/* If siz is NULL, then the offset is 0, if not use siz as a
 
310
   string, it represents the offset needed if we are in an array of structs. */
 
311
static void
 
312
ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype type,
 
313
                                  char *varcharsize,
 
314
                                  char *arrsize,
 
315
                                  const char *siz,
 
316
                                  const char *prefix
 
317
)
 
318
{
 
319
        if (type == ECPGt_NO_INDICATOR)
 
320
                fprintf(o, "\n\tECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ");
 
321
        else if (type == ECPGt_descriptor)
 
322
                /* remember that name here already contains quotes (if needed) */
 
323
                fprintf(o, "\n\tECPGt_descriptor, %s, 0L, 0L, 0L, ", name);
 
324
        else
 
325
        {
 
326
                char       *variable = (char *) mm_alloc(strlen(name) + ((prefix == NULL) ? 0 : strlen(prefix)) + 4);
 
327
                char       *offset = (char *) mm_alloc(strlen(name) + strlen("sizeof(struct varchar_)") + 1 + strlen(varcharsize));
 
328
 
 
329
                switch (type)
 
330
                {
 
331
                                /*
 
332
                                 * we have to use the & operator except for arrays and
 
333
                                 * pointers
 
334
                                 */
 
335
 
 
336
                        case ECPGt_varchar:
 
337
 
 
338
                                /*
 
339
                                 * we have to use the pointer except for arrays with given
 
340
                                 * bounds
 
341
                                 */
 
342
                                if (((atoi(arrsize) > 0) ||
 
343
                                         (atoi(arrsize) == 0 && strcmp(arrsize, "0") != 0)) &&
 
344
                                        siz == NULL)
 
345
                                        sprintf(variable, "(%s%s)", prefix ? prefix : "", name);
 
346
                                else
 
347
                                        sprintf(variable, "&(%s%s)", prefix ? prefix : "", name);
 
348
 
 
349
                                sprintf(offset, "sizeof(struct varchar_%s)", name);
 
350
                                break;
 
351
                        case ECPGt_char:
 
352
                        case ECPGt_unsigned_char:
 
353
                        case ECPGt_char_variable:
 
354
 
 
355
                                /*
 
356
                                 * we have to use the pointer except for arrays with given
 
357
                                 * bounds, ecpglib will distinguish between * and []
 
358
                                 */
 
359
                                if ((atoi(varcharsize) > 1 ||
 
360
                                         (atoi(arrsize) > 0) ||
 
361
                                         (atoi(varcharsize) == 0 && strcmp(varcharsize, "0") != 0) ||
 
362
                                         (atoi(arrsize) == 0 && strcmp(arrsize, "0") != 0))
 
363
                                        && siz == NULL)
 
364
                                        sprintf(variable, "(%s%s)", prefix ? prefix : "", name);
 
365
                                else
 
366
                                        sprintf(variable, "&(%s%s)", prefix ? prefix : "", name);
 
367
 
 
368
                                sprintf(offset, "(%s)*sizeof(char)", strcmp(varcharsize, "0") == 0 ? "1" : varcharsize);
 
369
                                break;
 
370
                        case ECPGt_numeric:
 
371
 
 
372
                                /*
 
373
                                 * we have to use a pointer here
 
374
                                 */
 
375
                                sprintf(variable, "&(%s%s)", prefix ? prefix : "", name);
 
376
                                sprintf(offset, "sizeof(numeric)");
 
377
                                break;
 
378
                        case ECPGt_interval:
 
379
 
 
380
                                /*
 
381
                                 * we have to use a pointer here
 
382
                                 */
 
383
                                sprintf(variable, "&(%s%s)", prefix ? prefix : "", name);
 
384
                                sprintf(offset, "sizeof(interval)");
 
385
                                break;
 
386
                        case ECPGt_date:
 
387
 
 
388
                                /*
 
389
                                 * we have to use a pointer and translate the variable
 
390
                                 * type
 
391
                                 */
 
392
                                sprintf(variable, "&(%s%s)", prefix ? prefix : "", name);
 
393
                                sprintf(offset, "sizeof(date)");
 
394
                                break;
 
395
                        case ECPGt_timestamp:
 
396
 
 
397
                                /*
 
398
                                 * we have to use a pointer and translate the variable
 
399
                                 * type
 
400
                                 */
 
401
                                sprintf(variable, "&(%s%s)", prefix ? prefix : "", name);
 
402
                                sprintf(offset, "sizeof(timestamp)");
 
403
                                break;
 
404
                        case ECPGt_const:
 
405
 
 
406
                                /*
 
407
                                 * just dump the const as string
 
408
                                 */
 
409
                                sprintf(variable, "\"%s\"", name);
 
410
                                sprintf(offset, "strlen(\"%s\")", name);
 
411
                                break;
 
412
                        default:
 
413
 
 
414
                                /*
 
415
                                 * we have to use the pointer except for arrays with given
 
416
                                 * bounds
 
417
                                 */
 
418
                                if (((atoi(arrsize) > 0) ||
 
419
                                         (atoi(arrsize) == 0 && strcmp(arrsize, "0") != 0)) &&
 
420
                                        siz == NULL)
 
421
                                        sprintf(variable, "(%s%s)", prefix ? prefix : "", name);
 
422
                                else
 
423
                                        sprintf(variable, "&(%s%s)", prefix ? prefix : "", name);
 
424
 
 
425
                                sprintf(offset, "sizeof(%s)", ECPGtype_name(type));
 
426
                                break;
 
427
                }
 
428
 
 
429
                if (atoi(arrsize) < 0)
 
430
                        strcpy(arrsize, "1");
 
431
 
 
432
                if (siz == NULL || strcmp(arrsize, "0") == 0 || strcmp(arrsize, "1") == 0)
 
433
                        fprintf(o, "\n\t%s,%s,(long)%s,(long)%s,%s, ", get_type(type), variable, varcharsize, arrsize, offset);
 
434
                else
 
435
                        fprintf(o, "\n\t%s,%s,(long)%s,(long)%s,%s, ", get_type(type), variable, varcharsize, arrsize, siz);
 
436
 
 
437
                free(variable);
 
438
                free(offset);
 
439
        }
 
440
}
 
441
 
 
442
 
 
443
/* Penetrate a struct and dump the contents. */
 
444
static void
 
445
ECPGdump_a_struct(FILE *o, const char *name, const char *ind_name, char *arrsiz, struct ECPGtype * type, struct ECPGtype * ind_type, const char *offsetarg, const char *prefix, const char *ind_prefix)
 
446
{
 
447
        /*
 
448
         * If offset is NULL, then this is the first recursive level. If not
 
449
         * then we are in a struct in a struct and the offset is used as
 
450
         * offset.
 
451
         */
 
452
        struct ECPGstruct_member *p,
 
453
                           *ind_p = NULL;
 
454
        char            obuf[BUFSIZ];
 
455
        char            pbuf[BUFSIZ],
 
456
                                ind_pbuf[BUFSIZ];
 
457
        const char *offset;
 
458
 
 
459
        if (offsetarg == NULL)
 
460
        {
 
461
                sprintf(obuf, "sizeof(%s)", name);
 
462
                offset = obuf;
 
463
        }
 
464
        else
 
465
                offset = offsetarg;
 
466
 
 
467
        if (atoi(arrsiz) == 1)
 
468
                sprintf(pbuf, "%s%s.", prefix ? prefix : "", name);
 
469
        else
 
470
                sprintf(pbuf, "%s%s->", prefix ? prefix : "", name);
 
471
 
 
472
        prefix = pbuf;
 
473
 
 
474
        if (ind_type == &ecpg_no_indicator)
 
475
                ind_p = &struct_no_indicator;
 
476
        else if (ind_type != NULL)
 
477
        {
 
478
                if (atoi(arrsiz) == 1)
 
479
                        sprintf(ind_pbuf, "%s%s.", ind_prefix ? ind_prefix : "", ind_name);
 
480
                else
 
481
                        sprintf(ind_pbuf, "%s%s->", ind_prefix ? ind_prefix : "", ind_name);
 
482
 
 
483
                ind_prefix = ind_pbuf;
 
484
                ind_p = ind_type->u.members;
 
485
        }
 
486
 
 
487
        for (p = type->u.members; p; p = p->next)
 
488
        {
 
489
                ECPGdump_a_type(o, p->name, p->type,
 
490
                                                (ind_p != NULL) ? ind_p->name : NULL,
 
491
                                                (ind_p != NULL) ? ind_p->type : NULL,
 
492
                                                prefix, ind_prefix, arrsiz, type->struct_sizeof,
 
493
                                                (ind_p != NULL) ? ind_type->struct_sizeof : NULL);
 
494
                if (ind_p != NULL && ind_p != &struct_no_indicator)
 
495
                        ind_p = ind_p->next;
 
496
        }
 
497
}
 
498
 
 
499
void
 
500
ECPGfree_struct_member(struct ECPGstruct_member * rm)
 
501
{
 
502
        while (rm)
 
503
        {
 
504
                struct ECPGstruct_member *p = rm;
 
505
 
 
506
                rm = rm->next;
 
507
                free(p->name);
 
508
                free(p->type);
 
509
                free(p);
 
510
        }
 
511
}
 
512
 
 
513
void
 
514
ECPGfree_type(struct ECPGtype * type)
 
515
{
 
516
        if (!IS_SIMPLE_TYPE(type->type))
 
517
        {
 
518
                switch (type->type)
 
519
                {
 
520
                        case ECPGt_array:
 
521
                                switch (type->u.element->type)
 
522
                                {
 
523
                                        case ECPGt_array:
 
524
                                                yyerror("internal error, found multidimensional array\n");
 
525
                                                break;
 
526
                                        case ECPGt_struct:
 
527
                                        case ECPGt_union:
 
528
                                                /* Array of structs. */
 
529
                                                ECPGfree_struct_member(type->u.element->u.members);
 
530
                                                free(type->u.element);
 
531
                                                break;
 
532
                                        default:
 
533
                                                if (!IS_SIMPLE_TYPE(type->u.element->type))
 
534
                                                        yyerror("Internal error: unknown datatype, please inform pgsql-bugs@postgresql.org");
 
535
 
 
536
                                                free(type->u.element);
 
537
                                }
 
538
                                break;
 
539
                        case ECPGt_struct:
 
540
                        case ECPGt_union:
 
541
                                ECPGfree_struct_member(type->u.members);
 
542
                                break;
 
543
                        default:
 
544
                                mmerror(PARSE_ERROR, ET_ERROR, "illegal variable type %d\n", type->type);
 
545
                                break;
 
546
                }
 
547
        }
 
548
        free(type);
 
549
}
 
550
 
 
551
const char *
 
552
get_dtype(enum ECPGdtype type)
 
553
{
 
554
        switch (type)
 
555
        {
 
556
                case ECPGd_count:
 
557
                        return ("ECPGd_countr");
 
558
                        break;
 
559
                case ECPGd_data:
 
560
                        return ("ECPGd_data");
 
561
                        break;
 
562
                case ECPGd_di_code:
 
563
                        return ("ECPGd_di_code");
 
564
                        break;
 
565
                case ECPGd_di_precision:
 
566
                        return ("ECPGd_di_precision");
 
567
                        break;
 
568
                case ECPGd_indicator:
 
569
                        return ("ECPGd_indicator");
 
570
                        break;
 
571
                case ECPGd_key_member:
 
572
                        return ("ECPGd_key_member");
 
573
                        break;
 
574
                case ECPGd_length:
 
575
                        return ("ECPGd_length");
 
576
                        break;
 
577
                case ECPGd_name:
 
578
                        return ("ECPGd_name");
 
579
                        break;
 
580
                case ECPGd_nullable:
 
581
                        return ("ECPGd_nullable");
 
582
                        break;
 
583
                case ECPGd_octet:
 
584
                        return ("ECPGd_octet");
 
585
                        break;
 
586
                case ECPGd_precision:
 
587
                        return ("ECPGd_precision");
 
588
                        break;
 
589
                case ECPGd_ret_length:
 
590
                        return ("ECPGd_ret_length");
 
591
                case ECPGd_ret_octet:
 
592
                        return ("ECPGd_ret_octet");
 
593
                        break;
 
594
                case ECPGd_scale:
 
595
                        return ("ECPGd_scale");
 
596
                        break;
 
597
                case ECPGd_type:
 
598
                        return ("ECPGd_type");
 
599
                        break;
 
600
                case ECPGd_cardinality:
 
601
                        return ("ECPGd_cardinality");
 
602
                default:
 
603
                        mmerror(PARSE_ERROR, ET_ERROR, "illegal descriptor item %d\n", type);
 
604
        }
 
605
 
 
606
        return NULL;
 
607
}