#include "postgres_fe.h"
#include "extern.h"
Go to the source code of this file.
Functions | |
struct variable * | new_variable (const char *name, struct ECPGtype *type, int brace_level) |
static struct variable * | find_struct_member (char *name, char *str, struct ECPGstruct_member *members, int brace_level) |
static struct variable * | find_struct (char *name, char *next, char *end) |
static struct variable * | find_simple (char *name) |
struct variable * | find_variable (char *name) |
void | remove_typedefs (int brace_level) |
void | remove_variables (int brace_level) |
void | reset_variables (void) |
void | add_variable_to_head (struct arguments **list, struct variable *var, struct variable *ind) |
void | add_variable_to_tail (struct arguments **list, struct variable *var, struct variable *ind) |
void | remove_variable_from_list (struct arguments **list, struct variable *var) |
void | dump_variables (struct arguments *list, int mode) |
void | check_indicator (struct ECPGtype *var) |
struct typedefs * | get_typedef (char *name) |
void | adjust_array (enum ECPGttype type_enum, char **dimension, char **length, char *type_dimension, char *type_index, int pointer_len, bool type_definition) |
Variables | |
static struct variable * | allvariables = NULL |
struct arguments * | argsinsert = NULL |
struct arguments * | argsresult = NULL |
void add_variable_to_head | ( | struct arguments ** | list, | |
struct variable * | var, | |||
struct variable * | ind | |||
) |
Definition at line 379 of file variable.c.
References arguments::indicator, mm_alloc(), arguments::next, and arguments::variable.
void add_variable_to_tail | ( | struct arguments ** | list, | |
struct variable * | var, | |||
struct variable * | ind | |||
) |
Definition at line 391 of file variable.c.
References mm_alloc(), variable::next, and arguments::next.
void adjust_array | ( | enum ECPGttype | type_enum, | |
char ** | dimension, | |||
char ** | length, | |||
char * | type_dimension, | |||
char * | type_index, | |||
int | pointer_len, | |||
bool | type_definition | |||
) |
Definition at line 506 of file variable.c.
References ECPGt_char, ECPGt_string, ECPGt_struct, ECPGt_union, ECPGt_unsigned_char, ECPGt_varchar, ET_FATAL, mm_strdup(), mmerror(), ngettext, and PARSE_ERROR.
{ if (atoi(type_index) >= 0) { if (atoi(*length) >= 0) mmerror(PARSE_ERROR, ET_FATAL, "multidimensional arrays are not supported"); *length = type_index; } if (atoi(type_dimension) >= 0) { if (atoi(*dimension) >= 0 && atoi(*length) >= 0) mmerror(PARSE_ERROR, ET_FATAL, "multidimensional arrays are not supported"); if (atoi(*dimension) >= 0) *length = *dimension; *dimension = type_dimension; } if (pointer_len > 2) mmerror(PARSE_ERROR, ET_FATAL, ngettext("multilevel pointers (more than 2 levels) are not supported; found %d level", "multilevel pointers (more than 2 levels) are not supported; found %d levels", pointer_len), pointer_len); if (pointer_len > 1 && type_enum != ECPGt_char && type_enum != ECPGt_unsigned_char && type_enum != ECPGt_string) mmerror(PARSE_ERROR, ET_FATAL, "pointer to pointer is not supported for this data type"); if (pointer_len > 1 && (atoi(*length) >= 0 || atoi(*dimension) >= 0)) mmerror(PARSE_ERROR, ET_FATAL, "multidimensional arrays are not supported"); if (atoi(*length) >= 0 && atoi(*dimension) >= 0 && pointer_len) mmerror(PARSE_ERROR, ET_FATAL, "multidimensional arrays are not supported"); switch (type_enum) { case ECPGt_struct: case ECPGt_union: /* pointer has to get dimension 0 */ if (pointer_len) { *length = *dimension; *dimension = mm_strdup("0"); } if (atoi(*length) >= 0) mmerror(PARSE_ERROR, ET_FATAL, "multidimensional arrays for structures are not supported"); break; case ECPGt_varchar: /* pointer has to get dimension 0 */ if (pointer_len) *dimension = mm_strdup("0"); /* one index is the string length */ if (atoi(*length) < 0) { *length = *dimension; *dimension = mm_strdup("-1"); } break; case ECPGt_char: case ECPGt_unsigned_char: case ECPGt_string: /* char ** */ if (pointer_len == 2) { *length = *dimension = mm_strdup("0"); break; } /* pointer has to get length 0 */ if (pointer_len == 1) *length = mm_strdup("0"); /* one index is the string length */ if (atoi(*length) < 0) { /* * make sure we return length = -1 for arrays without given * bounds */ if (atoi(*dimension) < 0 && !type_definition) /* * do not change this for typedefs since it will be * changed later on when the variable is defined */ *length = mm_strdup("1"); else if (strcmp(*dimension, "0") == 0) *length = mm_strdup("-1"); else *length = *dimension; *dimension = mm_strdup("-1"); } break; default: /* a pointer has dimension = 0 */ if (pointer_len) { *length = *dimension; *dimension = mm_strdup("0"); } if (atoi(*length) >= 0) mmerror(PARSE_ERROR, ET_FATAL, "multidimensional arrays for simple data types are not supported"); break; } }
void check_indicator | ( | struct ECPGtype * | var | ) |
Definition at line 461 of file variable.c.
References check_indicator(), ECPGt_array, ECPGt_int, ECPGt_long, ECPGt_long_long, ECPGt_short, ECPGt_struct, ECPGt_union, ECPGt_unsigned_int, ECPGt_unsigned_long, ECPGt_unsigned_long_long, ECPGt_unsigned_short, ECPGtype::element, ET_ERROR, ECPGtype::members, mmerror(), ECPGstruct_member::next, PARSE_ERROR, ECPGstruct_member::type, ECPGtype::type, and ECPGtype::u.
Referenced by check_indicator().
{ /* make sure this is a valid indicator variable */ switch (var->type) { struct ECPGstruct_member *p; case ECPGt_short: case ECPGt_int: case ECPGt_long: case ECPGt_long_long: case ECPGt_unsigned_short: case ECPGt_unsigned_int: case ECPGt_unsigned_long: case ECPGt_unsigned_long_long: break; case ECPGt_struct: case ECPGt_union: for (p = var->u.members; p; p = p->next) check_indicator(p->type); break; case ECPGt_array: check_indicator(var->u.element); break; default: mmerror(PARSE_ERROR, ET_ERROR, "indicator variable must have an integer type"); break; } }
void dump_variables | ( | struct arguments * | list, | |
int | mode | |||
) |
Definition at line 438 of file variable.c.
References variable::brace_level, dump_variables(), ECPGdump_a_type(), free, arguments::indicator, mm_strdup(), variable::name, arguments::next, NULL, variable::type, arguments::variable, and yyout.
Referenced by dump_variables(), and output_statement().
{ if (list == NULL) return; /* * The list is build up from the beginning so lets first dump the end of * the list: */ dump_variables(list->next, mode); /* Then the current element and its indicator */ ECPGdump_a_type(yyout, list->variable->name, list->variable->type, list->variable->brace_level, list->indicator->name, list->indicator->type, list->indicator->brace_level, NULL, NULL, mm_strdup("0"), NULL, NULL); /* Then release the list element. */ if (mode != 0) free(list); }
static struct variable* find_simple | ( | char * | name | ) | [static, read] |
Definition at line 178 of file variable.c.
References variable::name, variable::next, and NULL.
Referenced by find_variable().
static struct variable* find_struct | ( | char * | name, | |
char * | next, | |||
char * | end | |||
) | [static, read] |
Definition at line 127 of file variable.c.
References variable::brace_level, ECPGt_array, ECPGt_struct, ECPGt_union, ET_FATAL, find_struct_member(), find_variable(), mmerror(), PARSE_ERROR, and variable::type.
Referenced by find_variable().
{ struct variable *p; char c = *next; /* first get the mother structure entry */ *next = '\0'; p = find_variable(name); if (c == '-') { if (p->type->type != ECPGt_array) mmerror(PARSE_ERROR, ET_FATAL, "variable \"%s\" is not a pointer", name); if (p->type->u.element->type != ECPGt_struct && p->type->u.element->type != ECPGt_union) mmerror(PARSE_ERROR, ET_FATAL, "variable \"%s\" is not a pointer to a structure or a union", name); /* restore the name, we will need it later */ *next = c; return find_struct_member(name, ++end, p->type->u.element->u.members, p->brace_level); } else { if (next == end) { if (p->type->type != ECPGt_struct && p->type->type != ECPGt_union) mmerror(PARSE_ERROR, ET_FATAL, "variable \"%s\" is neither a structure nor a union", name); /* restore the name, we will need it later */ *next = c; return find_struct_member(name, end, p->type->u.members, p->brace_level); } else { if (p->type->type != ECPGt_array) mmerror(PARSE_ERROR, ET_FATAL, "variable \"%s\" is not an array", name); if (p->type->u.element->type != ECPGt_struct && p->type->u.element->type != ECPGt_union) mmerror(PARSE_ERROR, ET_FATAL, "variable \"%s\" is not a pointer to a structure or a union", name); /* restore the name, we will need it later */ *next = c; return find_struct_member(name, end, p->type->u.element->u.members, p->brace_level); } } }
static struct variable* find_struct_member | ( | char * | name, | |
char * | str, | |||
struct ECPGstruct_member * | members, | |||
int | brace_level | |||
) | [static, read] |
Definition at line 25 of file variable.c.
References ECPGtype::counter, ECPGmake_array_type(), ECPGmake_simple_type(), ECPGmake_struct_type(), ECPGt_array, ECPGt_struct, ECPGt_union, ECPGtype::element, end, ET_FATAL, ECPGtype::members, mmerror(), ECPGstruct_member::name, new_variable(), ECPGstruct_member::next, next(), NULL, PARSE_ERROR, ECPGtype::size, ECPGtype::struct_sizeof, ECPGtype::type, ECPGstruct_member::type, ECPGtype::type_name, and ECPGtype::u.
Referenced by find_struct().
{ char *next = strpbrk(++str, ".-["), *end, c = '\0'; if (next != NULL) { c = *next; *next = '\0'; } for (; members; members = members->next) { if (strcmp(members->name, str) == 0) { if (next == NULL) { /* found the end */ switch (members->type->type) { case ECPGt_array: 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)); case ECPGt_struct: case ECPGt_union: return (new_variable(name, ECPGmake_struct_type(members->type->u.members, members->type->type, members->type->type_name, members->type->struct_sizeof), brace_level)); default: return (new_variable(name, ECPGmake_simple_type(members->type->type, members->type->size, members->type->counter), brace_level)); } } else { *next = c; if (c == '[') { int count; /* * We don't care about what's inside the array braces so * just eat up the character */ for (count = 1, end = next + 1; count; end++) { switch (*end) { case '[': count++; break; case ']': count--; break; default: break; } } } else end = next; switch (*end) { case '\0': /* found the end, but this time it has to be * an array element */ if (members->type->type != ECPGt_array) mmerror(PARSE_ERROR, ET_FATAL, "incorrectly formed variable \"%s\"", name); switch (members->type->u.element->type) { case ECPGt_array: 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)); case ECPGt_struct: case ECPGt_union: 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)); default: return (new_variable(name, ECPGmake_simple_type(members->type->u.element->type, members->type->u.element->size, members->type->u.element->counter), brace_level)); } break; case '-': if (members->type->type == ECPGt_array) return (find_struct_member(name, ++end, members->type->u.element->u.members, brace_level)); else return (find_struct_member(name, ++end, members->type->u.members, brace_level)); break; break; case '.': if (members->type->type == ECPGt_array) return (find_struct_member(name, end, members->type->u.element->u.members, brace_level)); else return (find_struct_member(name, end, members->type->u.members, brace_level)); break; default: mmerror(PARSE_ERROR, ET_FATAL, "incorrectly formed variable \"%s\"", name); break; } } } } return (NULL); }
struct variable* find_variable | ( | char * | name | ) | [read] |
Definition at line 194 of file variable.c.
References variable::brace_level, ECPGmake_array_type(), ECPGmake_simple_type(), ECPGmake_struct_type(), ECPGt_array, ECPGt_struct, ECPGt_union, ET_FATAL, find_simple(), find_struct(), mmerror(), new_variable(), variable::next, NULL, PARSE_ERROR, and variable::type.
Referenced by ECPGdump_a_type(), ECPGnumeric_lvalue(), find_struct(), output_get_descr(), and output_set_descr().
{ char *next, *end; struct variable *p; int count; next = strpbrk(name, ".[-"); if (next) { if (*next == '[') { /* * We don't care about what's inside the array braces so just eat * up the characters */ for (count = 1, end = next + 1; count; end++) { switch (*end) { case '[': count++; break; case ']': count--; break; default: break; } } if (*end == '.') p = find_struct(name, next, end); else { char c = *next; *next = '\0'; p = find_simple(name); if (p == NULL) mmerror(PARSE_ERROR, ET_FATAL, "variable \"%s\" is not declared", name); *next = c; switch (p->type->u.element->type) { case ECPGt_array: 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)); case ECPGt_struct: case ECPGt_union: 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)); default: 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)); } } } else p = find_struct(name, next, next); } else p = find_simple(name); if (p == NULL) mmerror(PARSE_ERROR, ET_FATAL, "variable \"%s\" is not declared", name); return (p); }
struct typedefs* get_typedef | ( | char * | name | ) | [read] |
Definition at line 494 of file variable.c.
References ET_FATAL, mmerror(), typedefs::next, PARSE_ERROR, and types.
Definition at line 10 of file variable.c.
References variable::brace_level, mm_alloc(), mm_strdup(), variable::name, variable::next, and variable::type.
Referenced by find_struct_member(), and find_variable().
{ struct variable *p = (struct variable *) mm_alloc(sizeof(struct variable)); p->name = mm_strdup(name); p->type = type; p->brace_level = brace_level; p->next = allvariables; allvariables = p; return (p); }
void remove_typedefs | ( | int | brace_level | ) |
Definition at line 261 of file variable.c.
References typedefs::brace_level, ECPGt_struct, ECPGt_union, free, typedefs::name, typedefs::next, typedefs::struct_member_list, typedefs::type, this_type::type_enum, and types.
{ struct typedefs *p, *prev; for (p = prev = types; p;) { if (p->brace_level >= brace_level) { /* remove it */ if (p == types) prev = types = p->next; else prev->next = p->next; if (p->type->type_enum == ECPGt_struct || p->type->type_enum == ECPGt_union) free(p->struct_member_list); free(p->type); free(p->name); free(p); if (prev == types) p = types; else p = prev ? prev->next : NULL; } else { prev = p; p = prev->next; } } }
Definition at line 409 of file variable.c.
References arguments::next, and arguments::variable.
void remove_variables | ( | int | brace_level | ) |
Definition at line 295 of file variable.c.
References cursor::argsinsert, cursor::argsresult, variable::brace_level, cur, ECPGfree_type(), free, variable::name, variable::next, arguments::next, cursor::next, NULL, variable::type, and arguments::variable.
{ struct variable *p, *prev; for (p = prev = allvariables; p;) { if (p->brace_level >= brace_level) { /* is it still referenced by a cursor? */ struct cursor *ptr; for (ptr = cur; ptr != NULL; ptr = ptr->next) { struct arguments *varptr, *prevvar; for (varptr = prevvar = ptr->argsinsert; varptr != NULL; varptr = varptr->next) { if (p == varptr->variable) { /* remove from list */ if (varptr == ptr->argsinsert) ptr->argsinsert = varptr->next; else prevvar->next = varptr->next; } } for (varptr = prevvar = ptr->argsresult; varptr != NULL; varptr = varptr->next) { if (p == varptr->variable) { /* remove from list */ if (varptr == ptr->argsresult) ptr->argsresult = varptr->next; else prevvar->next = varptr->next; } } } /* remove it */ if (p == allvariables) prev = allvariables = p->next; else prev->next = p->next; ECPGfree_type(p->type); free(p->name); free(p); if (prev == allvariables) p = allvariables; else p = prev ? prev->next : NULL; } else { prev = p; p = prev->next; } } }
void reset_variables | ( | void | ) |
Definition at line 369 of file variable.c.
Referenced by output_statement().
{ argsinsert = NULL; argsresult = NULL; }
struct variable* allvariables = NULL [static] |
Definition at line 7 of file variable.c.
struct arguments* argsinsert = NULL |
Definition at line 365 of file variable.c.
Referenced by output_statement().
struct arguments* argsresult = NULL |
Definition at line 366 of file variable.c.
Referenced by output_statement().