00001
00002
00003 #include "postgres_fe.h"
00004
00005 #include "extern.h"
00006
00007 static struct variable *allvariables = NULL;
00008
00009 struct variable *
00010 new_variable(const char *name, struct ECPGtype * type, int brace_level)
00011 {
00012 struct variable *p = (struct variable *) mm_alloc(sizeof(struct variable));
00013
00014 p->name = mm_strdup(name);
00015 p->type = type;
00016 p->brace_level = brace_level;
00017
00018 p->next = allvariables;
00019 allvariables = p;
00020
00021 return (p);
00022 }
00023
00024 static struct variable *
00025 find_struct_member(char *name, char *str, struct ECPGstruct_member * members, int brace_level)
00026 {
00027 char *next = strpbrk(++str, ".-["),
00028 *end,
00029 c = '\0';
00030
00031 if (next != NULL)
00032 {
00033 c = *next;
00034 *next = '\0';
00035 }
00036
00037 for (; members; members = members->next)
00038 {
00039 if (strcmp(members->name, str) == 0)
00040 {
00041 if (next == NULL)
00042 {
00043
00044 switch (members->type->type)
00045 {
00046 case ECPGt_array:
00047 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));
00048 case ECPGt_struct:
00049 case ECPGt_union:
00050 return (new_variable(name, ECPGmake_struct_type(members->type->u.members, members->type->type, members->type->type_name, members->type->struct_sizeof), brace_level));
00051 default:
00052 return (new_variable(name, ECPGmake_simple_type(members->type->type, members->type->size, members->type->counter), brace_level));
00053 }
00054 }
00055 else
00056 {
00057 *next = c;
00058 if (c == '[')
00059 {
00060 int count;
00061
00062
00063
00064
00065
00066 for (count = 1, end = next + 1; count; end++)
00067 {
00068 switch (*end)
00069 {
00070 case '[':
00071 count++;
00072 break;
00073 case ']':
00074 count--;
00075 break;
00076 default:
00077 break;
00078 }
00079 }
00080 }
00081 else
00082 end = next;
00083
00084 switch (*end)
00085 {
00086 case '\0':
00087
00088 if (members->type->type != ECPGt_array)
00089 mmerror(PARSE_ERROR, ET_FATAL, "incorrectly formed variable \"%s\"", name);
00090
00091 switch (members->type->u.element->type)
00092 {
00093 case ECPGt_array:
00094 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));
00095 case ECPGt_struct:
00096 case ECPGt_union:
00097 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));
00098 default:
00099 return (new_variable(name, ECPGmake_simple_type(members->type->u.element->type, members->type->u.element->size, members->type->u.element->counter), brace_level));
00100 }
00101 break;
00102 case '-':
00103 if (members->type->type == ECPGt_array)
00104 return (find_struct_member(name, ++end, members->type->u.element->u.members, brace_level));
00105 else
00106 return (find_struct_member(name, ++end, members->type->u.members, brace_level));
00107 break;
00108 break;
00109 case '.':
00110 if (members->type->type == ECPGt_array)
00111 return (find_struct_member(name, end, members->type->u.element->u.members, brace_level));
00112 else
00113 return (find_struct_member(name, end, members->type->u.members, brace_level));
00114 break;
00115 default:
00116 mmerror(PARSE_ERROR, ET_FATAL, "incorrectly formed variable \"%s\"", name);
00117 break;
00118 }
00119 }
00120 }
00121 }
00122
00123 return (NULL);
00124 }
00125
00126 static struct variable *
00127 find_struct(char *name, char *next, char *end)
00128 {
00129 struct variable *p;
00130 char c = *next;
00131
00132
00133 *next = '\0';
00134 p = find_variable(name);
00135
00136 if (c == '-')
00137 {
00138 if (p->type->type != ECPGt_array)
00139 mmerror(PARSE_ERROR, ET_FATAL, "variable \"%s\" is not a pointer", name);
00140
00141 if (p->type->u.element->type != ECPGt_struct && p->type->u.element->type != ECPGt_union)
00142 mmerror(PARSE_ERROR, ET_FATAL, "variable \"%s\" is not a pointer to a structure or a union", name);
00143
00144
00145 *next = c;
00146
00147 return find_struct_member(name, ++end, p->type->u.element->u.members, p->brace_level);
00148 }
00149 else
00150 {
00151 if (next == end)
00152 {
00153 if (p->type->type != ECPGt_struct && p->type->type != ECPGt_union)
00154 mmerror(PARSE_ERROR, ET_FATAL, "variable \"%s\" is neither a structure nor a union", name);
00155
00156
00157 *next = c;
00158
00159 return find_struct_member(name, end, p->type->u.members, p->brace_level);
00160 }
00161 else
00162 {
00163 if (p->type->type != ECPGt_array)
00164 mmerror(PARSE_ERROR, ET_FATAL, "variable \"%s\" is not an array", name);
00165
00166 if (p->type->u.element->type != ECPGt_struct && p->type->u.element->type != ECPGt_union)
00167 mmerror(PARSE_ERROR, ET_FATAL, "variable \"%s\" is not a pointer to a structure or a union", name);
00168
00169
00170 *next = c;
00171
00172 return find_struct_member(name, end, p->type->u.element->u.members, p->brace_level);
00173 }
00174 }
00175 }
00176
00177 static struct variable *
00178 find_simple(char *name)
00179 {
00180 struct variable *p;
00181
00182 for (p = allvariables; p; p = p->next)
00183 {
00184 if (strcmp(p->name, name) == 0)
00185 return p;
00186 }
00187
00188 return (NULL);
00189 }
00190
00191
00192
00193 struct variable *
00194 find_variable(char *name)
00195 {
00196 char *next,
00197 *end;
00198 struct variable *p;
00199 int count;
00200
00201 next = strpbrk(name, ".[-");
00202 if (next)
00203 {
00204 if (*next == '[')
00205 {
00206
00207
00208
00209
00210 for (count = 1, end = next + 1; count; end++)
00211 {
00212 switch (*end)
00213 {
00214 case '[':
00215 count++;
00216 break;
00217 case ']':
00218 count--;
00219 break;
00220 default:
00221 break;
00222 }
00223 }
00224 if (*end == '.')
00225 p = find_struct(name, next, end);
00226 else
00227 {
00228 char c = *next;
00229
00230 *next = '\0';
00231 p = find_simple(name);
00232 if (p == NULL)
00233 mmerror(PARSE_ERROR, ET_FATAL, "variable \"%s\" is not declared", name);
00234
00235 *next = c;
00236 switch (p->type->u.element->type)
00237 {
00238 case ECPGt_array:
00239 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));
00240 case ECPGt_struct:
00241 case ECPGt_union:
00242 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));
00243 default:
00244 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));
00245 }
00246 }
00247 }
00248 else
00249 p = find_struct(name, next, next);
00250 }
00251 else
00252 p = find_simple(name);
00253
00254 if (p == NULL)
00255 mmerror(PARSE_ERROR, ET_FATAL, "variable \"%s\" is not declared", name);
00256
00257 return (p);
00258 }
00259
00260 void
00261 remove_typedefs(int brace_level)
00262 {
00263 struct typedefs *p,
00264 *prev;
00265
00266 for (p = prev = types; p;)
00267 {
00268 if (p->brace_level >= brace_level)
00269 {
00270
00271 if (p == types)
00272 prev = types = p->next;
00273 else
00274 prev->next = p->next;
00275
00276 if (p->type->type_enum == ECPGt_struct || p->type->type_enum == ECPGt_union)
00277 free(p->struct_member_list);
00278 free(p->type);
00279 free(p->name);
00280 free(p);
00281 if (prev == types)
00282 p = types;
00283 else
00284 p = prev ? prev->next : NULL;
00285 }
00286 else
00287 {
00288 prev = p;
00289 p = prev->next;
00290 }
00291 }
00292 }
00293
00294 void
00295 remove_variables(int brace_level)
00296 {
00297 struct variable *p,
00298 *prev;
00299
00300 for (p = prev = allvariables; p;)
00301 {
00302 if (p->brace_level >= brace_level)
00303 {
00304
00305 struct cursor *ptr;
00306
00307 for (ptr = cur; ptr != NULL; ptr = ptr->next)
00308 {
00309 struct arguments *varptr,
00310 *prevvar;
00311
00312 for (varptr = prevvar = ptr->argsinsert; varptr != NULL; varptr = varptr->next)
00313 {
00314 if (p == varptr->variable)
00315 {
00316
00317 if (varptr == ptr->argsinsert)
00318 ptr->argsinsert = varptr->next;
00319 else
00320 prevvar->next = varptr->next;
00321 }
00322 }
00323 for (varptr = prevvar = ptr->argsresult; varptr != NULL; varptr = varptr->next)
00324 {
00325 if (p == varptr->variable)
00326 {
00327
00328 if (varptr == ptr->argsresult)
00329 ptr->argsresult = varptr->next;
00330 else
00331 prevvar->next = varptr->next;
00332 }
00333 }
00334 }
00335
00336
00337 if (p == allvariables)
00338 prev = allvariables = p->next;
00339 else
00340 prev->next = p->next;
00341
00342 ECPGfree_type(p->type);
00343 free(p->name);
00344 free(p);
00345 if (prev == allvariables)
00346 p = allvariables;
00347 else
00348 p = prev ? prev->next : NULL;
00349 }
00350 else
00351 {
00352 prev = p;
00353 p = prev->next;
00354 }
00355 }
00356 }
00357
00358
00359
00360
00361
00362
00363
00364
00365 struct arguments *argsinsert = NULL;
00366 struct arguments *argsresult = NULL;
00367
00368 void
00369 reset_variables(void)
00370 {
00371 argsinsert = NULL;
00372 argsresult = NULL;
00373 }
00374
00375
00376
00377
00378 void
00379 add_variable_to_head(struct arguments ** list, struct variable * var, struct variable * ind)
00380 {
00381 struct arguments *p = (struct arguments *) mm_alloc(sizeof(struct arguments));
00382
00383 p->variable = var;
00384 p->indicator = ind;
00385 p->next = *list;
00386 *list = p;
00387 }
00388
00389
00390 void
00391 add_variable_to_tail(struct arguments ** list, struct variable * var, struct variable * ind)
00392 {
00393 struct arguments *p,
00394 *new = (struct arguments *) mm_alloc(sizeof(struct arguments));
00395
00396 for (p = *list; p && p->next; p = p->next);
00397
00398 new->variable = var;
00399 new->indicator = ind;
00400 new->next = NULL;
00401
00402 if (p)
00403 p->next = new;
00404 else
00405 *list = new;
00406 }
00407
00408 void
00409 remove_variable_from_list(struct arguments ** list, struct variable * var)
00410 {
00411 struct arguments *p,
00412 *prev = NULL;
00413 bool found = false;
00414
00415 for (p = *list; p; p = p->next)
00416 {
00417 if (p->variable == var)
00418 {
00419 found = true;
00420 break;
00421 }
00422 prev = p;
00423 }
00424 if (found)
00425 {
00426 if (prev)
00427 prev->next = p->next;
00428 else
00429 *list = p->next;
00430 }
00431 }
00432
00433
00434
00435
00436
00437 void
00438 dump_variables(struct arguments * list, int mode)
00439 {
00440 if (list == NULL)
00441 return;
00442
00443
00444
00445
00446
00447
00448 dump_variables(list->next, mode);
00449
00450
00451 ECPGdump_a_type(yyout, list->variable->name, list->variable->type, list->variable->brace_level,
00452 list->indicator->name, list->indicator->type, list->indicator->brace_level,
00453 NULL, NULL, mm_strdup("0"), NULL, NULL);
00454
00455
00456 if (mode != 0)
00457 free(list);
00458 }
00459
00460 void
00461 check_indicator(struct ECPGtype * var)
00462 {
00463
00464 switch (var->type)
00465 {
00466 struct ECPGstruct_member *p;
00467
00468 case ECPGt_short:
00469 case ECPGt_int:
00470 case ECPGt_long:
00471 case ECPGt_long_long:
00472 case ECPGt_unsigned_short:
00473 case ECPGt_unsigned_int:
00474 case ECPGt_unsigned_long:
00475 case ECPGt_unsigned_long_long:
00476 break;
00477
00478 case ECPGt_struct:
00479 case ECPGt_union:
00480 for (p = var->u.members; p; p = p->next)
00481 check_indicator(p->type);
00482 break;
00483
00484 case ECPGt_array:
00485 check_indicator(var->u.element);
00486 break;
00487 default:
00488 mmerror(PARSE_ERROR, ET_ERROR, "indicator variable must have an integer type");
00489 break;
00490 }
00491 }
00492
00493 struct typedefs *
00494 get_typedef(char *name)
00495 {
00496 struct typedefs *this;
00497
00498 for (this = types; this && strcmp(this->name, name) != 0; this = this->next);
00499 if (!this)
00500 mmerror(PARSE_ERROR, ET_FATAL, "unrecognized data type name \"%s\"", name);
00501
00502 return (this);
00503 }
00504
00505 void
00506 adjust_array(enum ECPGttype type_enum, char **dimension, char **length, char *type_dimension, char *type_index, int pointer_len, bool type_definition)
00507 {
00508 if (atoi(type_index) >= 0)
00509 {
00510 if (atoi(*length) >= 0)
00511 mmerror(PARSE_ERROR, ET_FATAL, "multidimensional arrays are not supported");
00512
00513 *length = type_index;
00514 }
00515
00516 if (atoi(type_dimension) >= 0)
00517 {
00518 if (atoi(*dimension) >= 0 && atoi(*length) >= 0)
00519 mmerror(PARSE_ERROR, ET_FATAL, "multidimensional arrays are not supported");
00520
00521 if (atoi(*dimension) >= 0)
00522 *length = *dimension;
00523
00524 *dimension = type_dimension;
00525 }
00526
00527 if (pointer_len > 2)
00528 mmerror(PARSE_ERROR, ET_FATAL, ngettext("multilevel pointers (more than 2 levels) are not supported; found %d level",
00529 "multilevel pointers (more than 2 levels) are not supported; found %d levels", pointer_len),
00530 pointer_len);
00531
00532 if (pointer_len > 1 && type_enum != ECPGt_char && type_enum != ECPGt_unsigned_char && type_enum != ECPGt_string)
00533 mmerror(PARSE_ERROR, ET_FATAL, "pointer to pointer is not supported for this data type");
00534
00535 if (pointer_len > 1 && (atoi(*length) >= 0 || atoi(*dimension) >= 0))
00536 mmerror(PARSE_ERROR, ET_FATAL, "multidimensional arrays are not supported");
00537
00538 if (atoi(*length) >= 0 && atoi(*dimension) >= 0 && pointer_len)
00539 mmerror(PARSE_ERROR, ET_FATAL, "multidimensional arrays are not supported");
00540
00541 switch (type_enum)
00542 {
00543 case ECPGt_struct:
00544 case ECPGt_union:
00545
00546 if (pointer_len)
00547 {
00548 *length = *dimension;
00549 *dimension = mm_strdup("0");
00550 }
00551
00552 if (atoi(*length) >= 0)
00553 mmerror(PARSE_ERROR, ET_FATAL, "multidimensional arrays for structures are not supported");
00554
00555 break;
00556 case ECPGt_varchar:
00557
00558 if (pointer_len)
00559 *dimension = mm_strdup("0");
00560
00561
00562 if (atoi(*length) < 0)
00563 {
00564 *length = *dimension;
00565 *dimension = mm_strdup("-1");
00566 }
00567
00568 break;
00569 case ECPGt_char:
00570 case ECPGt_unsigned_char:
00571 case ECPGt_string:
00572
00573 if (pointer_len == 2)
00574 {
00575 *length = *dimension = mm_strdup("0");
00576 break;
00577 }
00578
00579
00580 if (pointer_len == 1)
00581 *length = mm_strdup("0");
00582
00583
00584 if (atoi(*length) < 0)
00585 {
00586
00587
00588
00589
00590 if (atoi(*dimension) < 0 && !type_definition)
00591
00592
00593
00594
00595
00596 *length = mm_strdup("1");
00597 else if (strcmp(*dimension, "0") == 0)
00598 *length = mm_strdup("-1");
00599 else
00600 *length = *dimension;
00601
00602 *dimension = mm_strdup("-1");
00603 }
00604 break;
00605 default:
00606
00607 if (pointer_len)
00608 {
00609 *length = *dimension;
00610 *dimension = mm_strdup("0");
00611 }
00612
00613 if (atoi(*length) >= 0)
00614 mmerror(PARSE_ERROR, ET_FATAL, "multidimensional arrays for simple data types are not supported");
00615
00616 break;
00617 }
00618 }