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