static enum ECPGttype actual_type[128];
static char *actual_storage[128];
-/* temporarily store record members while creating the data structure */
-struct ECPGrecord_member *record_member_list[128] = { NULL };
+/* temporarily store struct members while creating the data structure */
+struct ECPGstruct_member *struct_member_list[128] = { NULL };
/* keep a list of cursors */
struct cursor *cur = NULL;
static struct variable * allvariables = NULL;
static struct variable *
-find_variable(char * name)
+new_variable(const char * name, struct ECPGtype * type)
+{
+ struct variable * p = (struct variable*) mm_alloc(sizeof(struct variable));
+
+ p->name = strdup(name);
+ p->type = type;
+ p->brace_level = braces_open;
+
+ p->next = allvariables;
+ allvariables = p;
+
+ return(p);
+}
+
+static struct variable * find_variable(char * name);
+
+static struct variable *
+find_struct_member(char *name, char *str, struct ECPGstruct_member *members)
+{
+ char *next = strpbrk(++str, ".-"), c = '\0';
+
+ if (next != NULL)
+ {
+ c = *next;
+ *next = '\0';
+ }
+
+ for (; members; members = members->next)
+ {
+ if (strcmp(members->name, str) == 0)
+ {
+ if (c == '\0')
+ {
+ /* found the end */
+ switch (members->typ->typ)
+ {
+ case ECPGt_struct:
+ return(new_variable(name, ECPGmake_struct_type(members->typ->u.members)));
+ case ECPGt_varchar:
+ return(new_variable(name, ECPGmake_varchar_type(members->typ->typ, members->typ->size)));
+ default:
+ return(new_variable(name, ECPGmake_simple_type(members->typ->typ, members->typ->size)));
+ }
+ }
+ else
+ {
+ *next = c;
+ if (c == '-') next++;
+ return(find_struct_member(name, next, members->typ->u.members));
+ }
+ }
+ }
+
+ return(NULL);
+}
+
+static struct variable *
+find_struct(char * name, char *next)
+{
+ struct variable * p;
+ char c = *next;
+
+ /* first get the mother structure entry */
+ *next = '\0';
+ p = find_variable(name);
+
+ /* restore the name, we will need it later on */
+ *next = c;
+ if (*next == '-') next++;
+
+ return (find_struct_member(name, next, p->type->u.members));
+}
+
+static struct variable *
+find_simple(char * name)
{
struct variable * p;
- char * errorstring = (char *) mm_alloc(strlen(name) + 100);
for (p = allvariables; p; p = p->next)
{
return p;
}
- sprintf(errorstring, "The variable %s is not declared", name);
- yyerror(errorstring);
- free (errorstring);
-
- return NULL;
+ return(NULL);
}
-
-static void
-new_variable(const char * name, struct ECPGtype * type)
+static struct variable *
+find_variable(char * name)
{
- struct variable * p = (struct variable*) mm_alloc(sizeof(struct variable));
+ char * next;
+ struct variable * p =
+ ((next = strpbrk(name, ".-")) != NULL) ? find_struct(name, next) : find_simple(name);
- p->name = strdup(name);
- p->type = type;
- p->brace_level = braces_open;
+ if (p == NULL)
+ {
+ sprintf(errortext, "The variable %s is not declared", name);
+ yyerror(errortext);
+ }
- p->next = allvariables;
- allvariables = p;
+ return(p);
}
static void
/* make sure this is a valid indicator variable */
switch (var->typ)
{
- struct ECPGrecord_member *p;
+ struct ECPGstruct_member *p;
case ECPGt_short:
case ECPGt_int:
case ECPGt_unsigned_long:
break;
- case ECPGt_record:
+ case ECPGt_struct:
for (p = var->u.members; p; p = p->next)
check_indicator(p->typ);
break;
/* C token */
%token S_ANYTHING S_AUTO S_BOOL S_CHAR S_CONST S_DOUBLE S_EXTERN
%token S_FLOAT S_INT
-%token S_LONG S_REGISTER S_SHORT S_SIGNED S_STATIC S_STRUCT S_UNSIGNED
-%token S_VARCHAR
+%token S_LONG S_REGISTER S_SHORT S_SIGNED S_STATIC S_STRUCT
+%token S_STRUCTPOINTER S_UNSIGNED S_VARCHAR
/* I need this and don't know where it is defined inside the backend */
%token TYPECAST
{
actual_storage[struct_level] = $1;
actual_type[struct_level] = $2;
- if ($2 != ECPGt_varchar && $2 != ECPGt_record)
+ if ($2 != ECPGt_varchar && $2 != ECPGt_struct)
fprintf(yyout, "%s %s", $1, ECPGtype_name($2));
}
variable_list ';' { fputc(';', yyout); }
struct_type: s_struct '{' variable_declarations '}'
{
struct_level--;
- $$ = actual_type[struct_level] = ECPGt_record;
+ fputs("} ", yyout);
+ $$ = ECPGt_struct;
}
s_struct : S_STRUCT symbol
{
+ struct_member_list[struct_level] = NULL;
struct_level++;
fprintf(yyout, "struct %s {", $2);
}
switch (actual_type[struct_level])
{
- case ECPGt_record:
+ case ECPGt_struct:
if (struct_level == 0)
- new_variable($2, ECPGmake_record_type(record_member_list[struct_level]));
+ new_variable($2, ECPGmake_struct_type(struct_member_list[struct_level]));
else
- ECPGmake_record_member($2, ECPGmake_record_type(record_member_list[struct_level]), &(record_member_list[struct_level-1]));
+ ECPGmake_struct_member($2, ECPGmake_struct_type(struct_member_list[struct_level]), &(struct_member_list[struct_level-1]));
- record_member_list[struct_level] = NULL;
- fprintf(yyout, "} %s%s%s%s", $1, $2, $3.str, $4);
+ fprintf(yyout, "%s%s%s%s", $1, $2, $3.str, $4);
break;
case ECPGt_varchar:
if (struct_level == 0)
new_variable($2, ECPGmake_varchar_type(actual_type[struct_level], length));
else
- ECPGmake_record_member($2, ECPGmake_varchar_type(actual_type[struct_level], length), &(record_member_list[struct_level-1]));
+ ECPGmake_struct_member($2, ECPGmake_varchar_type(actual_type[struct_level], length), &(struct_member_list[struct_level-1]));
if (length > 0)
fprintf(yyout, "%s struct varchar_%s { int len; char arr[%d]; } %s", actual_storage[struct_level], $2, length, $2);
if (struct_level == 0)
new_variable($2, ECPGmake_simple_type(actual_type[struct_level], length));
else
- ECPGmake_record_member($2, ECPGmake_simple_type(actual_type[struct_level], length), &(record_member_list[struct_level-1]));
+ ECPGmake_struct_member($2, ECPGmake_simple_type(actual_type[struct_level], length), &(struct_member_list[struct_level-1]));
fprintf(yyout, "%s%s%s%s", $1, $2, $3.str, $4);
}
cvariable: CVARIABLE { $$ = $1; }
- | CVARIABLE '.' identlist { $$ = $1; }
- | CVARIABLE '-' '>' identlist { $$ = $1; }
+ | CVARIABLE '.' identlist { $$ = cat3_str($1, ".", $3); }
+ | CVARIABLE S_STRUCTPOINTER identlist { $$ = cat3_str($1, "->", $3); }
identlist: IDENT { $$ = $1; }
- | IDENT '.' identlist { $$ = $1; }
- | IDENT '-' '>' identlist { $$ = $1; }
+ | IDENT '.' identlist { $$ = cat3_str($1, ".", $3); }
+ | IDENT S_STRUCTPOINTER identlist { $$ = cat3_str($1, "->", $3); }
indicator: /* empty */ { $$ = NULL; }
- | cvariable { check_indicator((find_variable($1))->type); $$ = $1; }
+ | cvariable { printf("## %s\n", $1); check_indicator((find_variable($1))->type); $$ = $1; }
| SQL_INDICATOR cvariable { check_indicator((find_variable($2))->type); $$ = $2; }
| SQL_INDICATOR name { check_indicator((find_variable($2))->type); $$ = $2; }
*/
/* The NAME argument is copied. The type argument is preserved as a pointer. */
-struct ECPGrecord_member *
-ECPGmake_record_member(char *name, struct ECPGtype * type, struct ECPGrecord_member ** start)
+struct ECPGstruct_member *
+ECPGmake_struct_member(char *name, struct ECPGtype * type, struct ECPGstruct_member ** start)
{
- struct ECPGrecord_member *ptr,
+ struct ECPGstruct_member *ptr,
*ne =
- (struct ECPGrecord_member *) mm_alloc(sizeof(struct ECPGrecord_member));
+ (struct ECPGstruct_member *) mm_alloc(sizeof(struct ECPGstruct_member));
ne->name = strdup(name);
ne->typ = type;
}
struct ECPGtype *
-ECPGmake_record_type(struct ECPGrecord_member * rm)
+ECPGmake_struct_type(struct ECPGstruct_member * rm)
{
- struct ECPGtype *ne = ECPGmake_simple_type(ECPGt_record, 1);
+ struct ECPGtype *ne = ECPGmake_simple_type(ECPGt_struct, 1);
ne->u.members = rm;
reference-to-variable can be a reference to a struct element.
arrsize is the size of the array in case of array fetches. Otherwise 0.
size is the maxsize in case it is a varchar. Otherwise it is the size of
- the variable (required to do array fetches of records).
+ the variable (required to do array fetches of structs).
*/
void
ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype typ,
long varcharsize,
long arrsiz, const char *siz, const char *prefix);
void
-ECPGdump_a_record(FILE *o, const char *name, const char *ind_name, long arrsiz,
+ECPGdump_a_struct(FILE *o, const char *name, const char *ind_name, long arrsiz,
struct ECPGtype * typ, struct ECPGtype * ind_typ, const char *offset, const char *prefix, const char * ind_prefix);
{
abort(); /* Array of array, */
}
- else if (typ->u.element->typ == ECPGt_record)
+ else if (typ->u.element->typ == ECPGt_struct)
{
- /* Array of records. */
- ECPGdump_a_record(o, name, ind_name, typ->size, typ->u.element, ind_typ->u.element, 0, prefix, ind_prefix);
+ /* Array of structs. */
+ ECPGdump_a_struct(o, name, ind_name, typ->size, typ->u.element, ind_typ->u.element, 0, prefix, ind_prefix);
}
else
{
abort();
}
}
- else if (typ->typ == ECPGt_record)
+ else if (typ->typ == ECPGt_struct)
{
- ECPGdump_a_record(o, name, ind_name, 0, typ, ind_typ, 0, prefix, ind_prefix);
+ ECPGdump_a_struct(o, name, ind_name, 0, typ, ind_typ, 0, prefix, ind_prefix);
}
else
{
/* If siz is NULL, then the offset is 0, if not use siz as a
- string, it represents the offset needed if we are in an array of records. */
+ string, it represents the offset needed if we are in an array of structs. */
void
ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype typ,
long varcharsize,
{
case ECPGt_char:
if (varcharsize == 0) /* pointer */
- fprintf(o, "\n\tECPGt_char,%s%s,%ldL,%ldL,%s, ", prefix ? prefix : "", name, varcharsize, arrsiz,
+ fprintf(o, "\n\tECPGt_char,(%s%s),%ldL,%ldL,%s, ", prefix ? prefix : "", name, varcharsize, arrsiz,
siz == NULL ? "sizeof(char)" : siz);
else
- fprintf(o, "\n\tECPGt_char,&%s%s,%ldL,%ldL,%s, ", prefix ? prefix : "", name, varcharsize, arrsiz,
+ fprintf(o, "\n\tECPGt_char,&(%s%s),%ldL,%ldL,%s, ", prefix ? prefix : "", name, varcharsize, arrsiz,
siz == NULL ? "sizeof(char)" : siz);
break;
case ECPGt_unsigned_char:
if (varcharsize == 0) /* pointer */
- fprintf(o, "\n\tECPGt_unsigned_char,%s%s,%ldL,%ldL,%s, ", prefix ? prefix : "", name, varcharsize, arrsiz,
+ fprintf(o, "\n\tECPGt_unsigned_char,(%s%s),%ldL,%ldL,%s, ", prefix ? prefix : "", name, varcharsize, arrsiz,
siz == NULL ? "sizeof(char)" : siz);
else
- fprintf(o, "\n\tECPGt_unsigned_char,&%s%s,%ldL,%ldL,%s, ", prefix ? prefix : "", name, varcharsize, arrsiz,
+ fprintf(o, "\n\tECPGt_unsigned_char,&(%s%s),%ldL,%ldL,%s, ", prefix ? prefix : "", name, varcharsize, arrsiz,
siz == NULL ? "sizeof(unsigned char)" : siz);
break;
case ECPGt_short:
- fprintf(o, "\n\tECPGt_short,&%s%s,0L,%ldL,%s, ", prefix ? prefix : "", name, arrsiz,
+ fprintf(o, "\n\tECPGt_short,&(%s%s),0L,%ldL,%s, ", prefix ? prefix : "", name, arrsiz,
siz == NULL ? "sizeof(short)" : siz);
break;
case ECPGt_unsigned_short:
fprintf(o,
- "\n\tECPGt_unsigned_short,&%s%s,0L,%ldL,%s, ", prefix ? prefix : "", name, arrsiz,
+ "\n\tECPGt_unsigned_short,&(%s%s),0L,%ldL,%s, ", prefix ? prefix : "", name, arrsiz,
siz == NULL ? "sizeof(unsigned short)" : siz);
break;
case ECPGt_int:
- fprintf(o, "\n\tECPGt_int,&%s%s,0L,%ldL,%s, ", prefix ? prefix : "", name, arrsiz,
+ fprintf(o, "\n\tECPGt_int,&(%s%s),0L,%ldL,%s, ", prefix ? prefix : "", name, arrsiz,
siz == NULL ? "sizeof(int)" : siz);
break;
case ECPGt_unsigned_int:
- fprintf(o, "\n\tECPGt_unsigned_int,&%s%s,0L,%ldL,%s, ", prefix ? prefix : "", name, arrsiz,
+ fprintf(o, "\n\tECPGt_unsigned_int,&(%s%s),0L,%ldL,%s, ", prefix ? prefix : "", name, arrsiz,
siz == NULL ? "sizeof(unsigned int)" : siz);
break;
case ECPGt_long:
- fprintf(o, "\n\tECPGt_long,&%s%s,0L,%ldL,%s, ", prefix ? prefix : "", name, arrsiz,
+ fprintf(o, "\n\tECPGt_long,&(%s%s),0L,%ldL,%s, ", prefix ? prefix : "", name, arrsiz,
siz == NULL ? "sizeof(long)" : siz);
break;
case ECPGt_unsigned_long:
- fprintf(o, "\n\tECPGt_unsigned_int,&%s%s,0L,%ldL,%s, ", prefix ? prefix : "", name, arrsiz,
+ fprintf(o, "\n\tECPGt_unsigned_int,&(%s%s),0L,%ldL,%s, ", prefix ? prefix : "", name, arrsiz,
siz == NULL ? "sizeof(unsigned int)" : siz);
break;
case ECPGt_float:
- fprintf(o, "\n\tECPGt_float,&%s%s,0L,%ldL,%s, ", prefix ? prefix : "", name, arrsiz,
+ fprintf(o, "\n\tECPGt_float,&(%s%s),0L,%ldL,%s, ", prefix ? prefix : "", name, arrsiz,
siz == NULL ? "sizeof(float)" : siz);
break;
case ECPGt_double:
- fprintf(o, "\n\tECPGt_double,&%s%s,0L,%ldL,%s, ", prefix ? prefix : "", name, arrsiz,
+ fprintf(o, "\n\tECPGt_double,&(%s%s),0L,%ldL,%s, ", prefix ? prefix : "", name, arrsiz,
siz == NULL ? "sizeof(double)" : siz);
break;
case ECPGt_bool:
- fprintf(o, "\n\tECPGt_bool,&%s%s,0L,%ldL,%s, ", prefix ? prefix : "", name, arrsiz,
+ fprintf(o, "\n\tECPGt_bool,&(%s%s),0L,%ldL,%s, ", prefix ? prefix : "", name, arrsiz,
siz == NULL ? "sizeof(bool)" : siz);
break;
case ECPGt_varchar:
case ECPGt_varchar2:
if (siz == NULL)
- fprintf(o, "\n\tECPGt_varchar,&%s%s,%ldL,%ldL,sizeof(struct varchar_%s), ",
+ fprintf(o, "\n\tECPGt_varchar,&(%s%s),%ldL,%ldL,sizeof(struct varchar_%s), ",
prefix ? prefix : "", name,
varcharsize,
arrsiz, name);
else
- fprintf(o, "\n\tECPGt_varchar,&%s%s,%ldL,%ldL,%s, ",
+ fprintf(o, "\n\tECPGt_varchar,&(%s%s),%ldL,%ldL,%s, ",
prefix ? prefix : "", name,
varcharsize,
arrsiz, siz);
}
-/* Penetrate a record and dump the contents. */
+/* Penetrate a struct and dump the contents. */
void
-ECPGdump_a_record(FILE *o, const char *name, const char * ind_name, long arrsiz, struct ECPGtype * typ, struct ECPGtype * ind_typ, const char *offsetarg, const char *prefix, const char *ind_prefix)
+ECPGdump_a_struct(FILE *o, const char *name, const char * ind_name, long arrsiz, struct ECPGtype * typ, struct ECPGtype * ind_typ, const char *offsetarg, const char *prefix, const char *ind_prefix)
{
/*
* If offset is NULL, then this is the first recursive level. If not
- * then we are in a record in a record and the offset is used as
+ * then we are in a struct in a struct and the offset is used as
* offset.
*/
- struct ECPGrecord_member *p, *ind_p = NULL;
+ struct ECPGstruct_member *p, *ind_p = NULL;
char obuf[BUFSIZ];
char pbuf[BUFSIZ], ind_pbuf[BUFSIZ];
const char *offset;
/* Freeing is not really that important. Since we throw away the process
anyway. Lets implement that last! */
-void
-ECPGfree_record_member(struct ECPGrecord_member * rm)
+/* won't work anymore because a list of members may appear in several locations */
+/*void
+ECPGfree_struct_member(struct ECPGstruct_member * rm)
{
while (rm)
{
- struct ECPGrecord_member *p = rm;
+ struct ECPGstruct_member *p = rm;
rm = rm->next;
free(p->name);
free(p);
}
-}
+}*/
void
ECPGfree_type(struct ECPGtype * typ)
free(typ->u.element);
else if (typ->u.element->typ == ECPGt_array)
abort(); /* Array of array, */
- else if (typ->u.element->typ == ECPGt_record)
- /* Array of records. */
- ECPGfree_record_member(typ->u.members);
+ else if (typ->u.element->typ == ECPGt_struct)
+ /* Array of structs. */
+ free(typ->u.members);
+ /* ECPGfree_struct_member(typ->u.members);*/
else
abort();
}
- else if (typ->typ == ECPGt_record)
+ else if (typ->typ == ECPGt_struct)
{
- ECPGfree_record_member(typ->u.members);
+ free(typ->u.members);
+ /* ECPGfree_struct_member(typ->u.members);*/
}
else
{