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