+ Sat Feb 21 19:10:55 CET 1998
authorMarc G. Fournier
Tue, 24 Feb 1998 15:52:13 +0000 (15:52 +0000)
committerMarc G. Fournier
Tue, 24 Feb 1998 15:52:13 +0000 (15:52 +0000)
+
+       - use char[] as string not as array of bytes that is integers
+
+ Sun Feb 22 16:37:36 CET 1998
+
+       - use long for all size variables
+       - added execute immediate statement
+
+ Sun Feb 22 20:41:32 CET 1998
+
+       - use varcharsize = 1 for all simple types, 0 means pointer, > 1
+         means array if type is char resp. unsigned char
+
+ Thu Feb 24 12:26:12 CET 1998
+
+       - allow 'go to' in whenever statement as well as 'goto'
+       - new argument 'stop' for whenever statement

From: Michael Meskes 

src/interfaces/ecpg/ChangeLog
src/interfaces/ecpg/Makefile
src/interfaces/ecpg/TODO
src/interfaces/ecpg/lib/ecpglib.c
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 ff721fa50137f683e02d808f7789df865dcbb06f..bb39d213947b2975fbca9b069f092d15a724bdc0 100644 (file)
@@ -38,3 +38,21 @@ Thu Feb 19 12:48:14 CET 1998
 
    - added do option to whenever statement
 
+Sat Feb 21 19:10:55 CET 1998
+
+   - use char[] as string not as array of bytes that is integers
+
+Sun Feb 22 16:37:36 CET 1998
+
+   - use long for all size variables
+   - added execute immediate statement
+
+Sun Feb 22 20:41:32 CET 1998
+
+   - use varcharsize = 1 for all simple types, 0 means pointer, > 1
+     means array if type is char resp. unsigned char
+
+Thu Feb 24 12:26:12 CET 1998
+
+   - allow 'go to' in whenever statement as well as 'goto'
+   - new argument 'stop' for whenever statement
index ee99aaeab500dae25f3e2096e00e0edb4e4db06b..f4768822a65ca9f9485aa3a0a674c6fbbca1444e 100644 (file)
@@ -1,5 +1,4 @@
-SUBDIRS = include lib preproc doc
-
 all install uninstall clean:
+   $(MAKE) -C include $@
    $(MAKE) -C lib $@
    $(MAKE) -C preproc $@
index 3de01c497afa73c0a42cc2bc622b0f44e83dfbd7..dab3e0b4deb5d26fa768e7df3e3d2a547a296872 100644 (file)
@@ -40,8 +40,22 @@ could be realised in a script.
 
 Now comes my list (MM):
 
-What do we do with enum data types?
+The return code is alway -1 in case of an error. You cannot see which error
+occured by examining the return code.
 
-The cursor is opened when the declare statement is issued. 
+The cursor is opened when the declare statement is issued.
+
+ecpg does not understand enum datatypes.
 
 The is no exec sql prepare statement.
+
+The complete structure definition has to be listed inside the declare
+section for ecpg to be able to understand it.
+
+Each variable has to be defined on a line on its own.
+
+There is no way yet to fill a complete array with one call except arrays of
+[unsigned] char which are considered strings.
+
+ecpg cannot use pointer variables except [unsigned] char *
+
index 19ec7f3b69a79ff18066c290a6c8f9c1ffe5ec92..823a335c7647daface43855b88b134fc0f75ab43 100644 (file)
@@ -96,9 +96,9 @@ ECPGdo(int lineno, char *query,...)
    while (type != ECPGt_EOIT)
    {
        void       *value = NULL;
-       short       varcharsize;
-       short       size;
-       short       arrsize;
+       long        varcharsize;
+       long        size;
+       long        arrsize;
 
        char       *newcopy;
        char       *mallocedval = NULL;
@@ -110,20 +110,18 @@ ECPGdo(int lineno, char *query,...)
           contents to arrive in a comma-separated list on insert (I think). */
 
        value = va_arg(ap, void *);
-       varcharsize = va_arg(ap, short);
-       size = va_arg(ap, short);
-       arrsize = va_arg(ap, short);
+       varcharsize = va_arg(ap, long);
+       size = va_arg(ap, long);
+       arrsize = va_arg(ap, long);
 
        switch (type)
        {
-           case ECPGt_char:
            case ECPGt_short:
            case ECPGt_int:
                sprintf(buff, "%d", *(int *) value);
                tobeinserted = buff;
                break;
 
-           case ECPGt_unsigned_char:
            case ECPGt_unsigned_short:
            case ECPGt_unsigned_int:
                sprintf(buff, "%d", *(unsigned int *) value);
@@ -155,6 +153,27 @@ ECPGdo(int lineno, char *query,...)
                tobeinserted = buff;
                break;
 
+           case ECPGt_char:
+           case ECPGt_unsigned_char:
+               {
+                   /* set slen to string length if type is char * */
+                   int slen = (varcharsize == 0) ? strlen((char *) value) : varcharsize;
+               
+                   newcopy = (char *) malloc(slen + 1);
+                   strncpy(newcopy, (char *) value, slen);
+                   newcopy[slen] = '\0';
+
+                   mallocedval = (char *) malloc(2 * strlen(newcopy) + 3);
+                   strcpy(mallocedval, "'");
+                   strcat(mallocedval, quote_postgres(newcopy));
+                   strcat(mallocedval, "'");
+
+                   free(newcopy);
+
+                   tobeinserted = mallocedval;
+               }
+               break;
+
            case ECPGt_varchar:
            case ECPGt_varchar2:
                {
@@ -274,7 +293,7 @@ ECPGdo(int lineno, char *query,...)
 
                if (n < 1)
                {
-                   ECPGlog("ECPGdo lineno %d: Incorrect number of matches: %d\n",
+                   ECPGlog("ECPGdo line %d: Incorrect number of matches: %d\n",
                            lineno, n);
                    register_error(1, "Data not found line %d.", lineno);
                    break;
@@ -293,9 +312,9 @@ ECPGdo(int lineno, char *query,...)
                for (x = 0; x < m && status; x++)
                {
                    void       *value = NULL;
-                   short       varcharsize;
-                   short       size;
-                   short       arrsize;
+                   long        varcharsize;
+                   long        size;
+                   long        arrsize;
 
                    char       *pval = PQgetvalue(results, 0, x);
 
@@ -311,9 +330,9 @@ ECPGdo(int lineno, char *query,...)
                    /* We will have to decode the value */
                    type = va_arg(ap, enum ECPGttype);
                    value = va_arg(ap, void *);
-                   varcharsize = va_arg(ap, short);
-                   size = va_arg(ap, short);
-                   arrsize = va_arg(ap, short);
+                   varcharsize = va_arg(ap, long);
+                   size = va_arg(ap, long);
+                   arrsize = va_arg(ap, long);
 
                    switch (type)
                    {
@@ -321,7 +340,6 @@ ECPGdo(int lineno, char *query,...)
                            unsigned long ures;
                            double      dres;
 
-                       case ECPGt_char:
                        case ECPGt_short:
                        case ECPGt_int:
                        case ECPGt_long:
@@ -342,9 +360,6 @@ ECPGdo(int lineno, char *query,...)
                            /* Again?! Yes */
                            switch (type)
                            {
-                               case ECPGt_char:
-                                   *(char *) value = (char) res;
-                                   break;
                                case ECPGt_short:
                                    *(short *) value = (short) res;
                                    break;
@@ -360,7 +375,6 @@ ECPGdo(int lineno, char *query,...)
                            }
                            break;
 
-                       case ECPGt_unsigned_char:
                        case ECPGt_unsigned_short:
                        case ECPGt_unsigned_int:
                        case ECPGt_unsigned_long:
@@ -381,9 +395,6 @@ ECPGdo(int lineno, char *query,...)
                            /* Again?! Yes */
                            switch (type)
                            {
-                               case ECPGt_unsigned_char:
-                                   *(unsigned char *) value = (unsigned char) ures;
-                                   break;
                                case ECPGt_unsigned_short:
                                    *(unsigned short *) value = (unsigned short) ures;
                                    break;
@@ -452,6 +463,20 @@ ECPGdo(int lineno, char *query,...)
                            return false;
                            break;
 
+                       case ECPGt_char:
+                       case ECPGt_unsigned_char:
+                           {
+                               if (varcharsize == 0)
+                               {
+                                   /* char* */
+                                   strncpy((char *) value, pval, strlen(pval));
+                                   ((char *) value)[strlen(pval)] = '\0';
+                               }
+                               else
+                                   strncpy((char *) value, pval, varcharsize);
+                           }
+                           break;
+                           
                        case ECPGt_varchar:
                            {
                                struct ECPGgeneric_varchar *var =
index 5dddd9042c21f3cf7e36101a762323941ad3d9ac..c6438be2326c2361e405245ba28c3c032e533894 100644 (file)
@@ -5,22 +5,22 @@ MAJOR_VERSION=1
 MINOR_VERSION=0
 PATCHLEVEL=0
 
-CFLAGS=-I$(SRCDIR)/include -I../include -Wall -DMAJOR_VERSION=$(MAJOR_VERSION) -DMINOR_VERSION=$(MINOR_VERSION) -DPATCHLEVEL=$(PATCHLEVEL)
+CFLAGS+=-I$(SRCDIR)/include -I../include -Wall -DMAJOR_VERSION=$(MAJOR_VERSION) -DMINOR_VERSION=$(MINOR_VERSION) -DPATCHLEVEL=$(PATCHLEVEL)
 
 all:: ecpg
 
 clean:
-   rm -f *.o core a.out ecpg y.tab.h y.tab.c *~
+   rm -f *.o core a.out ecpg y.tab.h y.tab.c pgc.c *~
 
 install: all
-   $(INSTALL) $(INSTLOPTS) ecpg $(DESTDIR)$(BINDIR)
+   $(INSTALL) $(INSTL_EXE_OPTS) ecpg $(DESTDIR)$(BINDIR)
 
 uninstall:
    rm -f $(DESTDIR)$(BINDIR)/ecpg
 
 # Rule that really do something.
 ecpg: y.tab.o pgc.o type.o ecpg.o ../lib/typename.o
-   $(CC) -Wall -o ecpg y.tab.o pgc.o type.o ecpg.o ../lib/typename.o $(LEXLIB)
+   $(CC) -o ecpg y.tab.o pgc.o type.o ecpg.o ../lib/typename.o $(LEXLIB)
 
 y.tab.h y.tab.c: preproc.y
    $(YACC) $(YFLAGS) $<
index f3def3d2e98119403afb56b6b7b6136e710903c8..5523d0fce71faed967b50ab7757d091dcb98c050 100644 (file)
@@ -29,6 +29,7 @@ end   [eE][nN][dD]
 exec   [eE][xX][eE][cC]
 execute    [eE][xX][eE][cC][uU][tT][eE]
 found  [fF][oO][uU][nN][dD]
+go [gG][oO]
 goto    [gG][oO][tT][oO]
 immediate [iI][mM][mM][eE][dD][iI][aA][tT][eE]
 include [iI][nN][cC][lL][uU][dD][eE]
@@ -41,6 +42,8 @@ section   [sS][eE][cC][tT][iI][oO][nN]
 sql    [sS][qQ][lL]
 sqlerror [sS][qQ][lL][eE][rR][rR][oO][rR]
 sqlprint [sS][qQ][lL][pP][rR][iI][nN][tT]
+stop   [sS][tT][oO][pP]
+to     [tT][oO]
 varchar    [vV][aA][rR][cC][hH][aA][rR]
 varchar2   [vV][aA][rR][cC][hH][aA][rR]2
 whenever [wW][hH][eE][nN][eE][vV][eE][rR]
@@ -69,6 +72,8 @@ work    [wW][oO][rR][kK]
 {continue}        { dbg(SQL_CONTINUE); return SQL_CONTINUE; }
 {into}        { dbg(SQL_INTO); return SQL_INTO; }
 {goto}        { dbg(SQL_GOTO); return SQL_GOTO; }
+{go}{ws}{to}  { dbg(SQL_GOTO); return SQL_GOTO; }
+{stop}        { dbg(SQL_STOP); return SQL_STOP; }
 {do}      { dbg(SQL_DO); return SQL_DO; }
              
 {length}       { dbg(S_LENGTH); return S_LENGTH; }
index 52b814ac1948c9befc823a1e5aadaa82cdc9f396..2a77c441a6e259f7b2324b1cc4a1eab4ff1e629e 100644 (file)
@@ -52,7 +52,9 @@ print_action(struct when *w)
                 break;
        case W_DO:   fprintf(yyout, "%s;", w->str);
                 break;
-       default:     fprintf(yyout, "{/* not implemented yet */}");
+       case W_STOP:     fprintf(yyout, "exit (1);");
+                break;
+       default:     fprintf(yyout, "{/* %d not implemented yet */}", w->code);
                 break;
    }
 }
@@ -168,8 +170,8 @@ struct arguments {
 static struct arguments * argsinsert = NULL;
 static struct arguments * argsresult = NULL;
 
-void
-reset_variables()
+static void
+reset_variables(void)
 {
     argsinsert = NULL;
     argsresult = NULL;
@@ -177,7 +179,7 @@ reset_variables()
 
 
 /* Add a variable to a request. */
-void
+static void
 add_variable(struct arguments ** list, struct variable * var)
 {
     struct arguments * p = (struct arguments *)malloc(sizeof(struct arguments));
@@ -191,7 +193,7 @@ add_variable(struct arguments ** list, struct variable * var)
    This is a recursive function that works from the end of the list and
    deletes the list as we go on.
  */
-void
+static void
 dump_variables(struct arguments * list)
 {
     if (list == NULL)
@@ -217,7 +219,7 @@ dump_variables(struct arguments * list)
     int                tagname;
     struct ECPGtemp_type   type;
     char *         symbolname;
-    int                indexsize;
+    long           indexsize;
     enum ECPGttype     type_enum;
     struct when            action;
 }
@@ -227,19 +229,20 @@ dump_variables(struct arguments * list)
 %token  SQL_CONNECT SQL_OPEN SQL_EXECUTE SQL_IMMEDIATE
 %token  SQL_COMMIT SQL_ROLLBACK SQL_RELEASE SQL_WORK SQL_WHENEVER
 %token  SQL_SQLERROR SQL_NOT_FOUND SQL_BREAK SQL_CONTINUE
-%token  SQL_DO SQL_GOTO SQL_SQLPRINT
+%token  SQL_DO SQL_GOTO SQL_SQLPRINT SQL_STOP
 
 %token  S_SYMBOL S_LENGTH S_ANYTHING S_LABEL
 %token  S_VARCHAR S_VARCHAR2
-%token  S_EXTERN S_STATIC S_AUTO S_CONST S_REGISTER S_STRUCT S_SIGNED
+%token  S_EXTERN S_STATIC S_AUTO S_CONST S_REGISTER S_STRUCT
 %token  S_UNSIGNED S_SIGNED
 %token  S_LONG S_SHORT S_INT S_CHAR S_FLOAT S_DOUBLE S_BOOL
 %token  '[' ']' ';' ',' '{' '}' '=' '*' '(' ')'
 
-%type  type type_detailed varchar_type simple_type array_type struct_type
+%type  type type_detailed varchar_type simple_type struct_type string_type
+/* % type  array_type pointer_type */
 %type  symbol label
 %type  maybe_storage_clause varchar_tag db_name
-%type  simple_tag
+%type  simple_tag char_tag
 %type  index length
 %type  action
 %type  canything sqlanything both_anything vartext commit_release
@@ -286,7 +289,7 @@ variable_declaration : type initializer ';' {
     if (struct_level == 0)
     {
    new_variable($1.name, $1.typ);
-   free($1.name);
+   free((void *)$1.name);
     }
     fprintf(yyout, ";"); 
 }
@@ -319,15 +322,16 @@ symbol : S_SYMBOL {
 type : maybe_storage_clause type_detailed { $$ = $2; };
 type_detailed : varchar_type { $$ = $1; }
          | simple_type { $$ = $1; }
-         | array_type {$$ = $1; }
-         | pointer_type {$$ = $1; }
+         | string_type { $$ = $1; }
+/*       | array_type {$$ = $1; }
+         | pointer_type {$$ = $1; }*/
          | struct_type {$$ = $1; };
 
 varchar_type : varchar_tag symbol index {
-    if ($3 > 0)
-   fprintf(yyout, "struct varchar_%s { int len; char arr[%d]; } %s", $2, $3, $2);
+    if ($3 > 0L)
+   fprintf(yyout, "struct varchar_%s { int len; char arr[%ld]; } %s", $2, $3, $2);
     else
-   fprintf(yyout, "struct varchar_%s { int len; char arr[%d]; } %s", $2, $3, $2);
+   fprintf(yyout, "struct varchar_%s { int len; char arr[]; } %s", $2, $2);
     if (struct_level == 0)
     {
    $$.name = $2;
@@ -345,15 +349,53 @@ simple_type : simple_tag symbol {
     if (struct_level == 0)
     {
    $$.name = $2;
-   $$.typ = ECPGmake_simple_type($1);
+   $$.typ = ECPGmake_simple_type($1, 1);
     }
     else
-        ECPGmake_record_member($2, ECPGmake_simple_type($1), &(record_member_list[struct_level-1]));
+        ECPGmake_record_member($2, ECPGmake_simple_type($1, 1), &(record_member_list[struct_level-1]));
 }
 
+string_type : char_tag symbol index {
+    if ($3 > 0L)
+       fprintf(yyout, "%s %s [%ld]", ECPGtype_name($1), $2, $3);
+    else
+       fprintf(yyout, "%s %s []", ECPGtype_name($1), $2);
+    if (struct_level == 0)
+    {
+   $$.name = $2;
+   $$.typ = ECPGmake_simple_type($1, $3);
+    }
+    else
+   ECPGmake_record_member($2, ECPGmake_simple_type($1, $3), &(record_member_list[struct_level-1]));
+}
+   |   char_tag '*' symbol {
+    fprintf(yyout, "%s *%s", ECPGtype_name($1), $3);
+    if (struct_level == 0)
+    {
+   $$.name = $3;
+   $$.typ = ECPGmake_simple_type($1, 0);
+    }
+    else
+   ECPGmake_record_member($3, ECPGmake_simple_type($1, 0), &(record_member_list[struct_level-1]));
+}
+   |   char_tag symbol {
+    fprintf(yyout, "%s %s", ECPGtype_name($1), $2);
+    if (struct_level == 0)
+    {
+   $$.name = $2;
+   $$.typ = ECPGmake_simple_type($1, 1);
+    }
+    else
+        ECPGmake_record_member($2, ECPGmake_simple_type($1, 1), &(record_member_list[struct_level-1]));
+}
+
+char_tag : S_CHAR { $$ = ECPGt_char; }
+           | S_UNSIGNED S_CHAR { $$ = ECPGt_unsigned_char; }
+
+/*
 array_type : simple_tag symbol index {
     if ($3 > 0)
-       fprintf(yyout, "%s %s [%d]", ECPGtype_name($1), $2, $3);
+       fprintf(yyout, "%s %s [%ld]", ECPGtype_name($1), $2, $3);
     else
        fprintf(yyout, "%s %s []", ECPGtype_name($1), $2);
     if (struct_level == 0)
@@ -375,6 +417,7 @@ pointer_type : simple_tag '*' symbol {
     else
    ECPGmake_record_member($3, ECPGmake_array_type(ECPGmake_simple_type($1), 0), &(record_member_list[struct_level-1]));
 }
+*/
 
 s_struct : S_STRUCT symbol {
     struct_level++;
@@ -394,9 +437,7 @@ struct_type : s_struct '{' variable_declarations '}' symbol {
     record_member_list[struct_level] = NULL;
 }
 
-simple_tag : S_CHAR { $$ = ECPGt_char; }
-           | S_UNSIGNED S_CHAR { $$ = ECPGt_unsigned_char; }
-      | S_SHORT { $$ = ECPGt_short; }
+simple_tag : S_SHORT { $$ = ECPGt_short; }
            | S_UNSIGNED S_SHORT { $$ = ECPGt_unsigned_short; }
       | S_INT { $$ = ECPGt_int; }
            | S_UNSIGNED S_INT { $$ = ECPGt_unsigned_int; }
@@ -415,9 +456,9 @@ maybe_storage_clause : S_EXTERN { fwrite(yytext, yyleng, 1, yyout); }
                        | /* empty */ { };
     
 index : '[' length ']' { $$ = $2; }
-   | '[' ']' { $$ = 0; }
+   | '[' ']' { $$ = 0L; }
 
-length : S_LENGTH { $$ = atoi(yytext); }
+length : S_LENGTH { $$ = atol(yytext); }
 
 sqlinclude : SQL_START SQL_INCLUDE { fprintf(yyout, "#include \""); }
    filename SQL_SEMI { fprintf(yyout, ".h\""); output_line_number(); };
@@ -430,7 +471,7 @@ sqlconnect : SQL_START SQL_CONNECT { fprintf(yyout, "ECPGconnect("); }
         SQL_SEMI { fprintf(yyout, ");"); whenever_action();}
 
 db_name : SQL_STRING { fprintf(yyout, "\""); fwrite(yytext + 1, yyleng - 2, 1, yyout); fprintf(yyout, "\""); }
-   | ':' symbol { /* check if we have a char variabnle */
+   | ':' symbol { /* check if we have a char variable */
            struct variable *p = find_variable($2);
            enum ECPGttype typ = p->type->typ;
 
@@ -465,45 +506,55 @@ sqlrollback : SQL_START SQL_ROLLBACK SQL_SEMI {
     whenever_action();
 };
 
-sqlexecute : SQL_START { /* Reset stack */
-    reset_variables();
-    fprintf(yyout, "ECPGdo(__LINE__, \"");
-} SQL_EXECUTE SQL_IMMEDIATE sqlstatement_words SQL_SEMI {  
-    /* Dump */
-    fprintf(yyout, "\", ");           
-    dump_variables(argsinsert);
-    fprintf(yyout, "ECPGt_EOIT, ");
-    /* dump_variables(argsresult); output variables must not exist here */
-    fprintf(yyout, "ECPGt_EORT );");
+sqlexecute : SQL_START SQL_EXECUTE SQL_IMMEDIATE  ':' symbol  SQL_SEMI {  
+    fprintf(yyout, "ECPGdo(__LINE__, %s, ECPGt_EOIT, ECPGt_EORT );", $5);
     whenever_action();
 };
 
-sqlwhenever : SQL_START SQL_WHENEVER SQL_SQLERROR action SQL_SEMI{
-   when_error = $4;
+sqlwhenever : SQL_START SQL_WHENEVER SQL_SQLERROR {
+   fprintf(yyout, "/* exec sql whenever sqlerror ");
+}  action SQL_SEMI{
+   when_error.code = $5.code;
+   when_error.str = $5.str;
+   fprintf(yyout, "; */\n");
 }
-   | SQL_START SQL_WHENEVER SQL_NOT_FOUND action SQL_SEMI{
-   when_nf = $4;
+   | SQL_START SQL_WHENEVER SQL_NOT_FOUND {
+   fprintf(yyout, "/* exec sql whenever not found ");
+}   action SQL_SEMI{
+   when_nf.code = $5.code;
+   when_nf.str=$5.str;
+   fprintf(yyout, "; */\n");
 }
 
 action : SQL_BREAK {
    $$.code = W_BREAK;
    $$.str = NULL;
+   fprintf(yyout, "break");
 }
        | SQL_CONTINUE {
    $$.code = W_CONTINUE;
    $$.str = NULL;
+   fprintf(yyout, "continue");
 }
        | SQL_SQLPRINT {
    $$.code = W_SQLPRINT;
    $$.str = NULL;
+   fprintf(yyout, "sqlprint");
+}
+       | SQL_STOP {
+   $$.code = W_STOP;
+   $$.str = NULL;
+   fprintf(yyout, "stop");
 }
        | SQL_GOTO label {
    $$.code = W_GOTO;
    $$.str = $2;
+   fprintf(yyout, "goto %s", $2);
 }
-   | SQL_GOTO symbol {
+       | SQL_GOTO symbol {
         $$.code = W_GOTO;
         $$.str = $2;
+   fprintf(yyout, "goto %s", $2);
 }
        | SQL_DO symbol '(' {
    do_str = (char *) mm_alloc(do_length = strlen($2) + 4);
@@ -513,6 +564,7 @@ action : SQL_BREAK {
    do_str[strlen(do_str)]=')';
    $$.code = W_DO;
    $$.str = do_str;
+   fprintf(yyout, "do %s", do_str);
    do_str = NULL;
    do_length = 0;
 }
@@ -599,6 +651,7 @@ blockend : '}' {
     fwrite(yytext, yyleng, 1, yyout);
 }
 %%
+
 static void yyerror(char * error)
 {
     fprintf(stderr, "%s in line %d\n", error, yylineno);
index bac44a72ed33ab431d47e2d9a81c761ad596b63e..a436997aaa246a1b76f4680385af679c96c3b351 100644 (file)
@@ -57,21 +57,21 @@ ECPGmake_record_member(char *name, struct ECPGtype *type, struct ECPGrecord_memb
 }
 
 struct ECPGtype *
-ECPGmake_simple_type(enum ECPGttype typ)
+ECPGmake_simple_type(enum ECPGttype typ, long siz)
 {
         struct ECPGtype *ne = (struct ECPGtype *) mm_alloc(sizeof(struct ECPGtype));
 
         ne->typ = typ;
-        ne->size = 0;
+        ne->size = siz;
         ne->u.element = 0;
 
         return ne;
 }
 
 struct ECPGtype *
-ECPGmake_varchar_type(enum ECPGttype typ, unsigned short siz)
+ECPGmake_varchar_type(enum ECPGttype typ, long siz)
 {
-        struct ECPGtype *ne = ECPGmake_simple_type(typ);
+        struct ECPGtype *ne = ECPGmake_simple_type(typ, 1);
 
         ne->size = siz;
 
@@ -79,9 +79,9 @@ ECPGmake_varchar_type(enum ECPGttype typ, unsigned short siz)
 }
 
 struct ECPGtype *
-ECPGmake_array_type(struct ECPGtype *typ, unsigned short siz)
+ECPGmake_array_type(struct ECPGtype *typ, long siz)
 {
-        struct ECPGtype *ne = ECPGmake_simple_type(ECPGt_array);
+        struct ECPGtype *ne = ECPGmake_simple_type(ECPGt_array, siz);
 
         ne->size = siz;
         ne->u.element = typ;
@@ -92,7 +92,7 @@ ECPGmake_array_type(struct ECPGtype *typ, unsigned short siz)
 struct ECPGtype *
 ECPGmake_record_type(struct ECPGrecord_member *rm)
 {
-        struct ECPGtype *ne = ECPGmake_simple_type(ECPGt_record);
+        struct ECPGtype *ne = ECPGmake_simple_type(ECPGt_record, 1);
 
         ne->u.members = rm;
 
@@ -104,9 +104,9 @@ ECPGmake_record_type(struct ECPGrecord_member *rm)
    The type is dumped as:
    type-tag                 - enum ECPGttype
    reference-to-variable    - void *
-   size                     - short size of this field (if varchar)
-   arrsize                  - short number of elements in the arr
-   offset                   - short offset to the next element
+   size                     - long size of this field (if varchar)
+   arrsize                  - long number of elements in the arr
+   offset                   - offset to the next element
    Where:
    type-tag is one of the simple types or varchar.
    reference-to-variable can be a reference to a struct element.
@@ -115,9 +115,9 @@ ECPGmake_record_type(struct ECPGrecord_member *rm)
    the variable (required to do array fetches of records).
  */
 void            ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype typ,
-                                                          short varcharsize,
-                                                          unsigned short arrsiz, const char *siz, const char *prefix);
-void            ECPGdump_a_record(FILE *o, const char *name, unsigned short arrsiz,
+                                                          long varcharsize,
+                                                          long arrsiz, const char *siz, const char *prefix);
+void            ECPGdump_a_record(FILE *o, const char *name, long arrsiz,
                                                           struct ECPGtype *typ, const char *offset, const char *prefix);
 
 
@@ -162,67 +162,75 @@ ECPGdump_a_type(FILE *o, const char *name, struct ECPGtype *typ, const char *pre
    string, it represents the offset needed if we are in an array of records. */
 void
 ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype typ,
-                                  short varcharsize,
-                                  unsigned short arrsiz,
+                                  long varcharsize,
+                                  long arrsiz,
                                   const char *siz,
                                   const char *prefix)
 {
         switch (typ)
         {
                 case ECPGt_char:
-                        fprintf(o, "\n\tECPGt_char,&%s%s,0,%d,%s, ", prefix ? prefix : "", name, arrsiz,
+                   if (varcharsize == 0) /* pointer */
+                       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,
                                         siz == NULL ? "sizeof(char)" : siz);
                         break;
                 case ECPGt_unsigned_char:
-                        fprintf(o, "\n\tECPGt_unsigned_char,&%s%s,0,%d,%s, ", prefix ? prefix : "", name, arrsiz,
+                   if (varcharsize == 0) /* pointer */
+                       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,
                                         siz == NULL ? "sizeof(unsigned char)" : siz);
                         break;
                 case ECPGt_short:
-                        fprintf(o, "\n\tECPGt_short,&%s%s,0,%d,%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,0,%d,%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,0,%d,%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,0,%d,%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,0,%d,%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,0,%d,%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,0,%d,%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,0,%d,%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,0,%d,%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,%d,%d,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,%d,%d,%s, ",
+                                fprintf(o, "\n\tECPGt_varchar,&%s%s,%ldL,%ldL,%s, ",
                                                 prefix ? prefix : "", name,
                                                 varcharsize,
                                                 arrsiz, siz);
@@ -235,7 +243,7 @@ ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype typ,
 
 /* Penetrate a record and dump the contents. */
 void
-ECPGdump_a_record(FILE *o, const char *name, unsigned short arrsiz, struct ECPGtype *typ, const char *offsetarg, const char *prefix)
+ECPGdump_a_record(FILE *o, const char *name, long arrsiz, struct ECPGtype *typ, const char *offsetarg, const char *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 offset.
index 80a7266f9c7442decbfe3d76b4ef13e03531ac1d..8ff6ed1b9c205ec1c3c2172ecd1ff6d0f5c5c8f9 100644 (file)
@@ -9,7 +9,7 @@ struct ECPGrecord_member {
 
 struct ECPGtype {
     enum ECPGttype typ;
-    unsigned short size;   /* For array it is the number of elements.
+    long       size;   /* For array it is the number of elements.
                 * For varchar it is the maxsize of the area.
                 */
     union {
@@ -23,9 +23,9 @@ struct ECPGtype {
 
 /* Everything is malloced. */
 struct ECPGrecord_member * ECPGmake_record_member(char *, struct ECPGtype *, struct ECPGrecord_member **);
-struct ECPGtype * ECPGmake_simple_type(enum ECPGttype);
-struct ECPGtype * ECPGmake_varchar_type(enum ECPGttype, unsigned short);
-struct ECPGtype * ECPGmake_array_type(struct ECPGtype *, unsigned short);
+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 *);
 
 /* Frees a type. */
@@ -59,7 +59,8 @@ enum WHEN {
         W_BREAK,
         W_SQLPRINT,
         W_GOTO,
-        W_DO
+        W_DO,
+        W_STOP
 };
 
 struct when
index a6f90979438715cce4a9c599b322efe1ccaaaa76..ed11be6c2a21a4477fe0b763bd2a9103cc9de67e 100644 (file)
@@ -34,6 +34,16 @@ exec sql end declare section;
    strcpy(msg, "connect");
    exec sql connect 'mm';
 
+   strcpy(msg, "create");
+   exec sql create table meskes(name char8, born int4, age int2);
+
+   strcpy(msg, "insert");
+   exec sql insert into meskes(name, born, age) values ('Petra', 19661202, 31);
+   exec sql insert into meskes(name, born, age) values ('Michael', 19660117, 32);
+   exec sql insert into meskes(name, born, age) values ('Carsten', 19910103, 7);
+   exec sql insert into meskes(name, born, age) values ('Marc', 19930907, 4);
+   exec sql insert into meskes(name, born, age) values ('Chris', 19970923, 0);
+
    strcpy(msg, "declare");
    exec sql declare cur cursor for 
        select name, born, age from meskes;
@@ -41,14 +51,23 @@ exec sql end declare section;
    exec sql open cur;
 
    while (1) {
+       /* make sure we leave this loop */
+       exec sql whenever not found break;
+
        strcpy(msg, "fetch");
        exec sql fetch in cur into :personal;
        printf ("%8.8s was born %d (age = %d)\n", personal.name.arr, personal.birth.born, personal.birth.age);
    }
 
+   /* back to normal behaviour */
+   exec sql whenever not found sqlprint;
+
    strcpy(msg, "close");
    exec sql close cur;
 
+   strcpy(msg, "drop");
+   exec sql drop table meskes;
+
    strcpy(msg, "commit");
    exec sql commit;