From: Michael Meskes
authorMarc G. Fournier
Mon, 27 Apr 1998 14:35:58 +0000 (14:35 +0000)
committerMarc G. Fournier
Mon, 27 Apr 1998 14:35:58 +0000 (14:35 +0000)
And the next update. Now you can use only parts of a struct like this:

exec sql select a into :struct.string from foo;

src/interfaces/ecpg/ChangeLog
src/interfaces/ecpg/TODO
src/interfaces/ecpg/include/ecpgtype.h
src/interfaces/ecpg/preproc/Makefile
src/interfaces/ecpg/preproc/pgc.l
src/interfaces/ecpg/preproc/preproc.y
src/interfaces/ecpg/preproc/type.c
src/interfaces/ecpg/preproc/type.h
src/interfaces/ecpg/test/test2.pgc

index f316bc33c5363cd496a2d29e38511c94f90c35be..a8f3335447b26810a722c503bebbf165d5643f19 100644 (file)
@@ -142,3 +142,10 @@ Fri Apr 24 13:50:15 CEST 1998
 
    - Fixed some bugs.
    - Set version to 2.1.1
+
+Mon Apr 27 14:26:55 CEST 1998
+
+   - Parser now able to understand and process syntax like :foo->bar
+     and :foo.bar as variables.
+   - Set version to 2.2.0
+
index f092d1b2bde1dfd622c8c16436c8a4f76fa8aceb..68d3808aed46beee89d7deb8c870643c5e33327a 100644 (file)
@@ -53,6 +53,3 @@ exec sql disconnect {current|default|all|connectionname|connection_hostvar};
  commit release|commit work release auch disconnect
 
 It is not neccessary to check for "not found" after all commands.
-
-It would be nice to be able to specify parts of a structure like :foo.bar or
-:foo->bar.
index 54442e6e3dd6a4bea08b1aee8d3ae5dcc56e10cc..27641df39a5948d2369a76637f550e6b8b230e21 100644 (file)
@@ -18,7 +18,7 @@
  * Complex types:
  * VARCHAR, VARCHAR2 - Strings with length (maxlen is given in the declaration)
  * Arrays of simple types and of VARCHAR, VARCHAR2 (size given in declaration)
- * Records build of simple types, arrays and other records.
+ * Records build of simple types, arrays and other structs.
  *
  * Complicating things:
  * typedefs and struct names!
@@ -41,7 +41,7 @@ enum ECPGttype
    ECPGt_float, ECPGt_double,
    ECPGt_varchar, ECPGt_varchar2,
    ECPGt_array,
-   ECPGt_record,
+   ECPGt_struct,
    ECPGt_EOIT,                 /* End of insert types. */
    ECPGt_EORT,                 /* End of result types. */
    ECPGt_NO_INDICATOR              /* no indicator */
index 8fcb985265555b691aa30d9e2d5a450b96df3ce1..4fcfd5b669f9c9bcda5089326543098a7718f2ea 100644 (file)
@@ -2,8 +2,8 @@ SRCDIR= ../../..
 include $(SRCDIR)/Makefile.global
 
 MAJOR_VERSION=2
-MINOR_VERSION=1
-PATCHLEVEL=1
+MINOR_VERSION=2
+PATCHLEVEL=0
 
 CFLAGS+=-I../include -DMAJOR_VERSION=$(MAJOR_VERSION) \
    -DMINOR_VERSION=$(MINOR_VERSION) -DPATCHLEVEL=$(PATCHLEVEL) \
index cc6bbcb3bdc36cd4fa470bf1259193a5a4c1b282..ed7b37478c3d4ab47b5a202c30a59fbcbe222305 100644 (file)
@@ -306,6 +306,7 @@ sql     [sS][qQ][lL]
                    return (yytext[0]);
                }
 {self}                {   return (yytext[0]); }
+"->"                      { return S_STRUCTPOINTER; }
 {operator}/-[\.0-9]   {
                    yylval.str = strdup((char*)yytext);
                    return (Op);
index 41537eaddabe0fca13606d2f0c672bf3a4e9aa05..021988cf52b4b852239c8b779c2dfbb229d98362 100644 (file)
@@ -17,8 +17,8 @@ static int      QueryIsRule = 0;
 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;
@@ -89,10 +89,83 @@ int braces_open;
 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)
     {
@@ -100,25 +173,23 @@ find_variable(char * name)
        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
@@ -215,7 +286,7 @@ check_indicator(struct ECPGtype *var)
    /* 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:
@@ -225,7 +296,7 @@ check_indicator(struct ECPGtype *var)
        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;
@@ -392,8 +463,8 @@ output_statement(const char * stmt)
 /* 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
@@ -3704,7 +3775,7 @@ declaration: storage_clause type
    {
        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); }
@@ -3723,11 +3794,13 @@ type: simple_type
 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);
    }
@@ -3764,14 +3837,13 @@ variable: opt_pointer symbol opt_index opt_initializer
 
            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:
@@ -3781,7 +3853,7 @@ variable: opt_pointer symbol opt_index opt_initializer
                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);
@@ -3794,7 +3866,7 @@ variable: opt_pointer symbol opt_index opt_initializer
                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);
 
@@ -4230,15 +4302,15 @@ civariableonly : cvariable name {
 }
 
 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; }
 
index 4b4e5927668cf8cacb2467c79e791f55e15e9654..b3430991cf69504d43df0c1cb8ce722b050dffbb 100644 (file)
@@ -40,12 +40,12 @@ mm_realloc(void *ptr, size_t size)
  */
 
 /* 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;
@@ -94,9 +94,9 @@ ECPGmake_array_type(struct ECPGtype * typ, long siz)
 }
 
 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;
 
@@ -116,14 +116,14 @@ ECPGmake_record_type(struct ECPGrecord_member * 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);
 
 
@@ -154,19 +154,19 @@ ECPGdump_a_type(FILE *o, const char *name, struct ECPGtype * typ, const char *in
        {
            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
    {
@@ -176,7 +176,7 @@ ECPGdump_a_type(FILE *o, const char *name, struct ECPGtype * typ, const char *in
 
 
 /* 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,
@@ -189,66 +189,66 @@ ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype typ,
    {
            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);
@@ -263,17 +263,17 @@ ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype typ,
 }
 
 
-/* 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;
@@ -306,18 +306,19 @@ ECPGdump_a_record(FILE *o, const char *name, const char * ind_name, long arrsiz,
 /* 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)
@@ -330,15 +331,17 @@ 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
        {
index 9d66e3a8cb1367ba3ba4a943e273026bd01a96d3..0a6df701fea2124b1b5bb7b9cc8dc6bed3c1c5b2 100644 (file)
@@ -1,11 +1,11 @@
 #include 
 
 struct ECPGtype;
-struct ECPGrecord_member
+struct ECPGstruct_member
 {
    char       *name;
    struct ECPGtype *typ;
-   struct ECPGrecord_member *next;
+   struct ECPGstruct_member *next;
 };
 
 struct ECPGtype
@@ -19,20 +19,20 @@ struct ECPGtype
        struct ECPGtype *element;       /* For an array this is the type
                                         * of the element */
 
-       struct ECPGrecord_member *members;
+       struct ECPGstruct_member *members;
        /* A pointer to a list of members. */
    }           u;
 };
 
 /* Everything is malloced. */
-struct ECPGrecord_member *ECPGmake_record_member(char *, struct ECPGtype *, struct ECPGrecord_member **);
+struct ECPGstruct_member *ECPGmake_struct_member(char *, struct ECPGtype *, struct ECPGstruct_member **);
 struct ECPGtype *ECPGmake_simple_type(enum ECPGttype, long);
 struct ECPGtype *ECPGmake_varchar_type(enum ECPGttype, long);
 struct ECPGtype *ECPGmake_array_type(struct ECPGtype *, long);
-struct ECPGtype *ECPGmake_record_type(struct ECPGrecord_member *);
+struct ECPGtype *ECPGmake_struct_type(struct ECPGstruct_member *);
 
 /* Frees a type. */
-void       ECPGfree_record_member(struct ECPGrecord_member *);
+void       ECPGfree_struct_member(struct ECPGstruct_member *);
 void       ECPGfree_type(struct ECPGtype *);
 
 /* Dump a type.
@@ -43,7 +43,7 @@ void      ECPGfree_type(struct ECPGtype *);
    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_type(FILE *, const char *, struct ECPGtype *,  const char *, struct ECPGtype *, const char *, const char *);
 
index 5330991196c054c9564ac3314a8270b999b5f563..87834aaa6b7de4586e94f2cbef7dc6f526d24c25 100644 (file)
@@ -60,7 +60,7 @@ exec sql end declare section;
 
    while (not_found == 0) {
        strcpy(msg, "fetch");
-       exec sql fetch cur into :personal:ind_personal, :married:ind_married, :personal.birth.born;
+       exec sql fetch cur into :personal:ind_personal, :married:ind_married;
        if (not_found == 0)
            printf ("%8.8s was born %d (age = %d) %s%s\n", personal.name.arr, personal.birth.born, personal.birth.age, ind_married ? "" : "and married ", ind_married ? "" : married);
    }