Commit 1d6424b1 authored by Marc G. Fournier's avatar Marc G. Fournier

From: Michael Meskes <meskes@topsystem.de>

Here's my next patch. this one should fix some more bugs. ecpg now fully
understands the whenever statement.
parent ed875a41
...@@ -29,3 +29,12 @@ Mon Feb 16 16:17:21 CET 1998 ...@@ -29,3 +29,12 @@ Mon Feb 16 16:17:21 CET 1998
- enable initialisation in declare section. - enable initialisation in declare section.
- connect call accepts a variable as well. - connect call accepts a variable as well.
Wed Feb 18 21:41:30 CET 1998
- added whenever statement
Thu Feb 19 12:48:14 CET 1998
- added do option to whenever statement
...@@ -3,7 +3,7 @@ This list is still from Linus. MM ...@@ -3,7 +3,7 @@ This list is still from Linus. MM
The variables should be static. The variables should be static.
Preprocessor cannot do syntax checking on your SQL statements Whatever you Preprocessor cannot do syntax checking on your SQL statements Whatever you
write is copied more or less exactly to the postgres95 and you will not be write is copied more or less exactly to the PostgreSQL and you will not be
able to locate your errors until run-time. able to locate your errors until run-time.
No restriction to strings only The PQ interface, and most of all the PQexec No restriction to strings only The PQ interface, and most of all the PQexec
...@@ -42,4 +42,6 @@ Now comes my list (MM): ...@@ -42,4 +42,6 @@ Now comes my list (MM):
What do we do with enum data types? What do we do with enum data types?
'signed' isn't understood so far The cursor is opened when the declare statement is issued.
The is no exec sql prepare statement.
...@@ -24,4 +24,9 @@ struct ECPGgeneric_varchar { ...@@ -24,4 +24,9 @@ struct ECPGgeneric_varchar {
char arr[1]; char arr[1];
}; };
/* print an error message */
void sqlprint(void);
/* define this for simplicity as well as compatibility */
#define SQLCODE sqlca.sqlcode
...@@ -232,7 +232,7 @@ ECPGdo(int lineno, char *query,...) ...@@ -232,7 +232,7 @@ ECPGdo(int lineno, char *query,...)
return false; return false;
} }
/* Now then request is built. */ /* Now the request is built. */
if (committed) if (committed)
{ {
...@@ -646,3 +646,10 @@ ECPGlog(const char *format,...) ...@@ -646,3 +646,10 @@ ECPGlog(const char *format,...)
free(f); free(f);
} }
} }
/* print out an error message */
void sqlprint(void)
{
sqlca.sqlerrm.sqlerrmc[sqlca.sqlerrm.sqlerrml] = '\0';
printf ("sql error %s\n", sqlca.sqlerrm.sqlerrmc);
}
...@@ -54,8 +54,9 @@ main(int argc, char *const argv[]) ...@@ -54,8 +54,9 @@ main(int argc, char *const argv[])
for (fnr = optind; fnr < argc; fnr++) for (fnr = optind; fnr < argc; fnr++)
{ {
char *filename, *ptr2ext; char *filename, *ptr2ext;
int ext = 0;
filename = mm_alloc(strlen(argv[fnr]) + 2); filename = mm_alloc(strlen(argv[fnr]) + 4);
strcpy(filename, argv[fnr]); strcpy(filename, argv[fnr]);
...@@ -63,6 +64,8 @@ main(int argc, char *const argv[]) ...@@ -63,6 +64,8 @@ main(int argc, char *const argv[])
/* no extension or extension not equal .pgc */ /* no extension or extension not equal .pgc */
if (ptr2ext == NULL || strcmp(ptr2ext, ".pgc") != 0) if (ptr2ext == NULL || strcmp(ptr2ext, ".pgc") != 0)
{ {
if (ptr2ext == NULL)
ext = 1; /* we need this information a while later */
ptr2ext = filename + strlen(filename); ptr2ext = filename + strlen(filename);
ptr2ext[0] = '.'; ptr2ext[0] = '.';
} }
...@@ -82,7 +85,19 @@ main(int argc, char *const argv[]) ...@@ -82,7 +85,19 @@ main(int argc, char *const argv[])
} }
} }
yyin = fopen(input_filename = argv[fnr], "r"); if (ext == 1)
{
/* no extension => add .pgc */
ptr2ext = strrchr(filename, '.');
ptr2ext[1] = 'p';
ptr2ext[2] = 'g';
ptr2ext[3] = 'c';
ptr2ext[4] = '\0';
input_filename = filename;
}
else
input_filename = argv[fnr];
yyin = fopen(input_filename, "r");
if (yyin == NULL) if (yyin == NULL)
perror(argv[fnr]); perror(argv[fnr]);
else else
......
...@@ -11,4 +11,4 @@ extern FILE *yyin, *yyout; ...@@ -11,4 +11,4 @@ extern FILE *yyin, *yyout;
extern void lex_init(void); extern void lex_init(void);
extern char * input_filename; extern char * input_filename;
extern int yyparse(void); extern int yyparse(void);
extern void *mm_alloc(size_t); extern void *mm_alloc(size_t), *mm_realloc(void *, size_t);
...@@ -15,25 +15,35 @@ letter [A-Za-z_] ...@@ -15,25 +15,35 @@ letter [A-Za-z_]
digit [0-9] digit [0-9]
length {digit}+ length {digit}+
symbol {letter}({letter}|{digit})* symbol {letter}({letter}|{digit})*
label ({letter}|{digit})*
string '[^']*' string '[^']*'
exec [eE][xX][eE][cC]
execute [eE][xX][eE][cC][uU][tT][eE]
sql [sS][qQ][lL]
varchar [vV][aA][rR][cC][hH][aA][rR]
varchar2 [vV][aA][rR][cC][hH][aA][rR]2
into [iI][nN][tT][oO]
begin [bB][eE][gG][iI][nN] begin [bB][eE][gG][iI][nN]
end [eE][nN][dD] break [bB][rR][eE][aA][kK]
commit [cC][oO][mM][mM][iI][tT]
connect [cC][oO][nN][nN][eE][cC][tT]
continue [cC][oO][nN][tT][iI][nN][uU][eE]
declare [dD][eE][cC][lL][aA][rR][eE] declare [dD][eE][cC][lL][aA][rR][eE]
section [sS][eE][cC][tT][iI][oO][nN] do [dD][oO]
end [eE][nN][dD]
exec [eE][xX][eE][cC]
execute [eE][xX][eE][cC][uU][tT][eE]
found [fF][oO][uU][nN][dD]
goto [gG][oO][tT][oO]
immediate [iI][mM][mM][eE][dD][iI][aA][tT][eE]
include [iI][nN][cC][lL][uU][dD][eE] include [iI][nN][cC][lL][uU][dD][eE]
connect [cC][oO][nN][nN][eE][cC][tT] into [iI][nN][tT][oO]
not [nN][oO][tT]
open [oO][pP][eE][nN] open [oO][pP][eE][nN]
commit [cC][oO][mM][mM][iI][tT]
immediate [iI][mM][mM][eE][dD][iI][aA][tT][eE]
release [rR][eE][lL][eE][aA][sS][eE] release [rR][eE][lL][eE][aA][sS][eE]
rollback [rR][oO][lL][lL][bB][aA][cC][kK] rollback [rR][oO][lL][lL][bB][aA][cC][kK]
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]
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]
work [wW][oO][rR][kK] work [wW][oO][rR][kK]
%% %%
<C>{exec}{ws}{sql} { BEGIN SQL; dbg(SQL_START); return SQL_START; } <C>{exec}{ws}{sql} { BEGIN SQL; dbg(SQL_START); return SQL_START; }
...@@ -51,8 +61,15 @@ work [wW][oO][rR][kK] ...@@ -51,8 +61,15 @@ work [wW][oO][rR][kK]
<SQL>{release} { dbg(SQL_RELEASE); return SQL_RELEASE; } <SQL>{release} { dbg(SQL_RELEASE); return SQL_RELEASE; }
<SQL>{work} { dbg(SQL_WORK); return SQL_WORK; } <SQL>{work} { dbg(SQL_WORK); return SQL_WORK; }
<SQL>{rollback} { dbg(SQL_ROLLBACK); return SQL_ROLLBACK; } <SQL>{rollback} { dbg(SQL_ROLLBACK); return SQL_ROLLBACK; }
<SQL>{whenever} { dbg(SQL_WHENEVER); return SQL_WHENEVER; }
<SQL>{sqlerror} { dbg(SQL_SQLERROR); return SQL_SQLERROR; }
<SQL>{sqlprint} { dbg(SQL_SQLPRINT); return SQL_SQLPRINT; }
<SQL>{not}{ws}{found} { dbg(SQL_NOT_FOUND); return SQL_NOT_FOUND; }
<SQL>{break} { dbg(SQL_BREAK); return SQL_BREAK; }
<SQL>{continue} { dbg(SQL_CONTINUE); return SQL_CONTINUE; }
<SQL>{into} { dbg(SQL_INTO); return SQL_INTO; } <SQL>{into} { dbg(SQL_INTO); return SQL_INTO; }
<SQL>{goto} { dbg(SQL_GOTO); return SQL_GOTO; }
<SQL>{do} { dbg(SQL_DO); return SQL_DO; }
{length} { dbg(S_LENGTH); return S_LENGTH; } {length} { dbg(S_LENGTH); return S_LENGTH; }
...@@ -67,6 +84,7 @@ double { dbg(S_DOUBLE); return S_DOUBLE; } ...@@ -67,6 +84,7 @@ double { dbg(S_DOUBLE); return S_DOUBLE; }
bool { dbg(S_BOOL); return S_BOOL; } bool { dbg(S_BOOL); return S_BOOL; }
static { dbg(S_STATIC); return S_STATIC; } static { dbg(S_STATIC); return S_STATIC; }
signed { dbg(S_SIGNED); return S_SIGNED; }
extern { dbg(S_EXTERN); return S_EXTERN; } extern { dbg(S_EXTERN); return S_EXTERN; }
auto { dbg(S_AUTO); return S_AUTO; } auto { dbg(S_AUTO); return S_AUTO; }
const { dbg(S_CONST); return S_CONST; } const { dbg(S_CONST); return S_CONST; }
...@@ -77,6 +95,7 @@ struct { dbg(S_STRUCT); return S_STRUCT; } ...@@ -77,6 +95,7 @@ struct { dbg(S_STRUCT); return S_STRUCT; }
{string} { dbg(SQL_STRING); return SQL_STRING; } {string} { dbg(SQL_STRING); return SQL_STRING; }
<SQL>{ws} ; <SQL>{ws} ;
{symbol} { dbg(S_SYMBOL); return S_SYMBOL; } {symbol} { dbg(S_SYMBOL); return S_SYMBOL; }
{label} { dbg(S_LABEL); return S_LABEL; }
<SQL>"!<" { dbg(S_SYMBOL); return S_SYMBOL; } <SQL>"!<" { dbg(S_SYMBOL); return S_SYMBOL; }
<SQL>"!>" { dbg(S_SYMBOL); return S_SYMBOL; } <SQL>"!>" { dbg(S_SYMBOL); return S_SYMBOL; }
...@@ -114,8 +133,10 @@ struct { dbg(S_STRUCT); return S_STRUCT; } ...@@ -114,8 +133,10 @@ struct { dbg(S_STRUCT); return S_STRUCT; }
";" { dbg(;); return ';'; } ";" { dbg(;); return ';'; }
"=" { dbg(=); return '='; } "=" { dbg(=); return '='; }
"," { dbg(komma); return ','; } "," { dbg(komma); return ','; }
\( { dbg(braceopen); return '('; }
\) { dbg(braceclose); return ')'; }
\{ { dbg(blockstart); return '{'; } \{ { dbg(blockstart); return '{'; }
\} { dbg(blockend); return'}'; } \} { dbg(blockend); return '}'; }
\* { dbg(*); return('*'); } \* { dbg(*); return('*'); }
<SQL>":" { dbg(:); return ':'; } <SQL>":" { dbg(:); return ':'; }
......
...@@ -14,6 +14,8 @@ static void yyerror(char *); ...@@ -14,6 +14,8 @@ static void yyerror(char *);
*/ */
int debugging = 0; int debugging = 0;
static int struct_level = 0; static int struct_level = 0;
static char *do_str = NULL;
static int do_length = 0;
/* temporarily store record members while creating the data structure */ /* temporarily store record members while creating the data structure */
struct ECPGrecord_member *record_member_list[128] = { NULL }; struct ECPGrecord_member *record_member_list[128] = { NULL };
...@@ -23,13 +25,54 @@ struct ECPGrecord_member *record_member_list[128] = { NULL }; ...@@ -23,13 +25,54 @@ struct ECPGrecord_member *record_member_list[128] = { NULL };
*/ */
char * input_filename = NULL; char * input_filename = NULL;
void static void
output_line_number() output_line_number()
{ {
if (input_filename) if (input_filename)
fprintf(yyout, "\n#line %d \"%s\"\n", yylineno, input_filename); fprintf(yyout, "\n#line %d \"%s\"\n", yylineno, input_filename);
} }
/*
* store the whenever action here
*/
static struct when when_error, when_nf;
static void
print_action(struct when *w)
{
switch (w->code)
{
case W_CONTINUE: fprintf(yyout, "continue;");
break;
case W_BREAK: fprintf(yyout, "break;");
break;
case W_SQLPRINT: fprintf(yyout, "sqlprint();");
break;
case W_GOTO: fprintf(yyout, "goto %s;", w->str);
break;
case W_DO: fprintf(yyout, "%s;", w->str);
break;
default: fprintf(yyout, "{/* not implemented yet */}");
break;
}
}
static void
whenever_action()
{
if (when_nf.code != W_NOTHING)
{
fprintf(yyout, "\nif (SQLCODE > 0) ");
print_action(&when_nf);
}
if (when_error.code != W_NOTHING)
{
fprintf(yyout, "\nif (SQLCODE < 0) ");
print_action(&when_error);
}
output_line_number();
}
/* /*
* Handling of the variables. * Handling of the variables.
*/ */
...@@ -176,28 +219,31 @@ dump_variables(struct arguments * list) ...@@ -176,28 +219,31 @@ dump_variables(struct arguments * list)
char * symbolname; char * symbolname;
int indexsize; int indexsize;
enum ECPGttype type_enum; enum ECPGttype type_enum;
struct when action;
} }
%token <tagname> SQL_START SQL_SEMI SQL_STRING SQL_INTO %token <tagname> SQL_START SQL_SEMI SQL_STRING SQL_INTO
%token <tagname> SQL_BEGIN SQL_END SQL_DECLARE SQL_SECTION SQL_INCLUDE %token <tagname> SQL_BEGIN SQL_END SQL_DECLARE SQL_SECTION SQL_INCLUDE
%token <tagname> SQL_CONNECT SQL_OPEN SQL_EXECUTE SQL_IMMEDIATE %token <tagname> SQL_CONNECT SQL_OPEN SQL_EXECUTE SQL_IMMEDIATE
%token <tagname> SQL_COMMIT SQL_ROLLBACK SQL_RELEASE SQL_WORK %token <tagname> SQL_COMMIT SQL_ROLLBACK SQL_RELEASE SQL_WORK SQL_WHENEVER
%token <tagname> SQL_SQLERROR SQL_NOT_FOUND SQL_BREAK SQL_CONTINUE
%token <tagname> SQL_DO SQL_GOTO SQL_SQLPRINT
%token <tagname> S_SYMBOL S_LENGTH S_ANYTHING %token <tagname> S_SYMBOL S_LENGTH S_ANYTHING S_LABEL
%token <tagname> S_VARCHAR S_VARCHAR2 %token <tagname> S_VARCHAR S_VARCHAR2
%token <tagname> S_EXTERN S_STATIC S_AUTO S_CONST S_REGISTER S_STRUCT %token <tagname> S_EXTERN S_STATIC S_AUTO S_CONST S_REGISTER S_STRUCT S_SIGNED
%token <tagname> S_UNSIGNED S_SIGNED %token <tagname> S_UNSIGNED S_SIGNED
%token <tagname> S_LONG S_SHORT S_INT S_CHAR S_FLOAT S_DOUBLE S_BOOL %token <tagname> S_LONG S_SHORT S_INT S_CHAR S_FLOAT S_DOUBLE S_BOOL
%token <tagname> '[' ']' ';' ',' '{' '}' '=' '*' %token <tagname> '[' ']' ';' ',' '{' '}' '=' '*' '(' ')'
%type <type> type type_detailed varchar_type simple_type array_type struct_type %type <type> type type_detailed varchar_type simple_type array_type struct_type
%type <symbolname> symbol %type <symbolname> symbol label
%type <tagname> maybe_storage_clause varchar_tag db_name %type <tagname> maybe_storage_clause varchar_tag db_name
%type <type_enum> simple_tag %type <type_enum> simple_tag
%type <indexsize> index length %type <indexsize> index length
%type <action> action
%type <tagname> canything sqlanything both_anything vartext commit_release %type <tagname> canything sqlanything both_anything vartext commit_release
%% %%
prog : statements; prog : statements;
...@@ -211,6 +257,7 @@ statement : sqldeclaration ...@@ -211,6 +257,7 @@ statement : sqldeclaration
| sqlcommit | sqlcommit
| sqlrollback | sqlrollback
| sqlexecute | sqlexecute
| sqlwhenever
| sqlstatement | sqlstatement
| cthing | cthing
| blockstart | blockstart
...@@ -247,8 +294,18 @@ variable_declaration : type initializer ';' { ...@@ -247,8 +294,18 @@ variable_declaration : type initializer ';' {
initializer : /*empty */ initializer : /*empty */
| '=' {fwrite(yytext, yyleng, 1, yyout);} vartext; | '=' {fwrite(yytext, yyleng, 1, yyout);} vartext;
vartext : both_anything {fwrite(yytext, yyleng, 1, yyout);} vartext : /* empty */ {}
| vartext both_anything {fwrite(yytext, yyleng, 1, yyout);} | vartext both_anything {
if (do_length == 0)
fwrite(yytext, yyleng, 1, yyout);
else
{
if (strlen(do_str) + yyleng + 1 >= do_length)
do_str = mm_realloc(do_str, do_length += yyleng);
strcat(do_str, yytext);
}
}
symbol : S_SYMBOL { symbol : S_SYMBOL {
char * name = (char *)malloc(yyleng + 1); char * name = (char *)malloc(yyleng + 1);
...@@ -351,6 +408,7 @@ simple_tag : S_CHAR { $<type_enum>$ = ECPGt_char; } ...@@ -351,6 +408,7 @@ simple_tag : S_CHAR { $<type_enum>$ = ECPGt_char; }
maybe_storage_clause : S_EXTERN { fwrite(yytext, yyleng, 1, yyout); } maybe_storage_clause : S_EXTERN { fwrite(yytext, yyleng, 1, yyout); }
| S_STATIC { fwrite(yytext, yyleng, 1, yyout); } | S_STATIC { fwrite(yytext, yyleng, 1, yyout); }
| S_SIGNED { fwrite(yytext, yyleng, 1, yyout); }
| S_CONST { fwrite(yytext, yyleng, 1, yyout); } | S_CONST { fwrite(yytext, yyleng, 1, yyout); }
| S_REGISTER { fwrite(yytext, yyleng, 1, yyout); } | S_REGISTER { fwrite(yytext, yyleng, 1, yyout); }
| S_AUTO { fwrite(yytext, yyleng, 1, yyout); } | S_AUTO { fwrite(yytext, yyleng, 1, yyout); }
...@@ -369,7 +427,7 @@ filename : cthing ...@@ -369,7 +427,7 @@ filename : cthing
sqlconnect : SQL_START SQL_CONNECT { fprintf(yyout, "ECPGconnect("); } sqlconnect : SQL_START SQL_CONNECT { fprintf(yyout, "ECPGconnect("); }
db_name db_name
SQL_SEMI { fprintf(yyout, ");"); output_line_number();} SQL_SEMI { fprintf(yyout, ");"); whenever_action();}
db_name : SQL_STRING { fprintf(yyout, "\""); fwrite(yytext + 1, yyleng - 2, 1, yyout); fprintf(yyout, "\""); } 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 variabnle */
...@@ -395,7 +453,7 @@ sqlgarbage : /* Empty */ ...@@ -395,7 +453,7 @@ sqlgarbage : /* Empty */
sqlcommit : SQL_START commit_release SQL_SEMI { sqlcommit : SQL_START commit_release SQL_SEMI {
fprintf(yyout, "ECPGcommit(__LINE__);"); fprintf(yyout, "ECPGcommit(__LINE__);");
output_line_number(); whenever_action();
} }
commit_release : SQL_COMMIT commit_release : SQL_COMMIT
...@@ -404,7 +462,7 @@ commit_release : SQL_COMMIT ...@@ -404,7 +462,7 @@ commit_release : SQL_COMMIT
sqlrollback : SQL_START SQL_ROLLBACK SQL_SEMI { sqlrollback : SQL_START SQL_ROLLBACK SQL_SEMI {
fprintf(yyout, "ECPGrollback(__LINE__);"); fprintf(yyout, "ECPGrollback(__LINE__);");
output_line_number(); whenever_action();
}; };
sqlexecute : SQL_START { /* Reset stack */ sqlexecute : SQL_START { /* Reset stack */
...@@ -415,11 +473,59 @@ sqlexecute : SQL_START { /* Reset stack */ ...@@ -415,11 +473,59 @@ sqlexecute : SQL_START { /* Reset stack */
fprintf(yyout, "\", "); fprintf(yyout, "\", ");
dump_variables(argsinsert); dump_variables(argsinsert);
fprintf(yyout, "ECPGt_EOIT, "); fprintf(yyout, "ECPGt_EOIT, ");
dump_variables(argsresult); /* dump_variables(argsresult); output variables must not exist here */
fprintf(yyout, "ECPGt_EORT );"); fprintf(yyout, "ECPGt_EORT );");
output_line_number(); whenever_action();
}; };
sqlwhenever : SQL_START SQL_WHENEVER SQL_SQLERROR action SQL_SEMI{
when_error = $<action>4;
}
| SQL_START SQL_WHENEVER SQL_NOT_FOUND action SQL_SEMI{
when_nf = $<action>4;
}
action : SQL_BREAK {
$<action>$.code = W_BREAK;
$<action>$.str = NULL;
}
| SQL_CONTINUE {
$<action>$.code = W_CONTINUE;
$<action>$.str = NULL;
}
| SQL_SQLPRINT {
$<action>$.code = W_SQLPRINT;
$<action>$.str = NULL;
}
| SQL_GOTO label {
$<action>$.code = W_GOTO;
$<action>$.str = $<symbolname>2;
}
| SQL_GOTO symbol {
$<action>$.code = W_GOTO;
$<action>$.str = $<symbolname>2;
}
| SQL_DO symbol '(' {
do_str = (char *) mm_alloc(do_length = strlen($<symbolname>2) + 4);
sprintf(do_str, "%s (", $<symbolname>2);
} vartext ')' {
do_str[strlen(do_str)+1]='\0';
do_str[strlen(do_str)]=')';
$<action>$.code = W_DO;
$<action>$.str = do_str;
do_str = NULL;
do_length = 0;
}
label : S_LABEL {
char * name = (char *)malloc(yyleng + 1);
strncpy(name, yytext, yyleng);
name[yyleng] = '\0';
$<symbolname>$ = name;
}
sqlstatement : SQL_START { /* Reset stack */ sqlstatement : SQL_START { /* Reset stack */
reset_variables(); reset_variables();
fprintf(yyout, "ECPGdo(__LINE__, \""); fprintf(yyout, "ECPGdo(__LINE__, \"");
...@@ -430,7 +536,7 @@ sqlstatement : SQL_START { /* Reset stack */ ...@@ -430,7 +536,7 @@ sqlstatement : SQL_START { /* Reset stack */
fprintf(yyout, "ECPGt_EOIT, "); fprintf(yyout, "ECPGt_EOIT, ");
dump_variables(argsresult); dump_variables(argsresult);
fprintf(yyout, "ECPGt_EORT );"); fprintf(yyout, "ECPGt_EORT );");
output_line_number(); whenever_action();
}; };
sqlstatement_words : sqlstatement_word sqlstatement_words : sqlstatement_word
...@@ -478,9 +584,9 @@ both_anything : S_LENGTH | S_VARCHAR | S_VARCHAR2 ...@@ -478,9 +584,9 @@ both_anything : S_LENGTH | S_VARCHAR | S_VARCHAR2
| SQL_BEGIN | SQL_END | SQL_BEGIN | SQL_END
| SQL_DECLARE | SQL_SECTION | SQL_DECLARE | SQL_SECTION
| SQL_INCLUDE | SQL_INCLUDE
| S_SYMBOL | S_SYMBOL | S_LABEL
| S_STATIC | S_EXTERN | S_AUTO | S_CONST | S_REGISTER | S_STRUCT | S_STATIC | S_EXTERN | S_AUTO | S_CONST | S_REGISTER | S_STRUCT
| '[' | ']' | ',' | '=' | '*' | '[' | ']' | ',' | '=' | '*' | '(' | ')'
| S_ANYTHING; | S_ANYTHING;
blockstart : '{' { blockstart : '{' {
...@@ -495,6 +601,6 @@ blockend : '}' { ...@@ -495,6 +601,6 @@ blockend : '}' {
%% %%
static void yyerror(char * error) static void yyerror(char * error)
{ {
fprintf(stderr, "%s\n", error); fprintf(stderr, "%s in line %d\n", error, yylineno);
exit(1); exit(1);
} }
...@@ -18,6 +18,20 @@ void *mm_alloc(size_t size) ...@@ -18,6 +18,20 @@ void *mm_alloc(size_t size)
return (ptr); return (ptr);
} }
/* realloc + error check */
void *mm_realloc(void * ptr, size_t size)
{
ptr = realloc(ptr, size);
if (ptr == NULL)
{
fprintf(stderr, "Out of memory\n");
exit(1);
}
return (ptr);
}
/* Constructors /* Constructors
Yes, I mostly write c++-code Yes, I mostly write c++-code
*/ */
......
...@@ -51,3 +51,19 @@ struct ECPGtemp_type { ...@@ -51,3 +51,19 @@ struct ECPGtemp_type {
}; };
extern const char * ECPGtype_name(enum ECPGttype typ); extern const char * ECPGtype_name(enum ECPGttype typ);
/* some stuff for whenever statements */
enum WHEN {
W_NOTHING,
W_CONTINUE,
W_BREAK,
W_SQLPRINT,
W_GOTO,
W_DO
};
struct when
{
enum WHEN code;
char * str;
};
...@@ -2,10 +2,11 @@ ...@@ -2,10 +2,11 @@
exec sql include sqlca; exec sql include sqlca;
#define SQLCODE sqlca.sqlcode
extern void ECPGdebug(int n, FILE *dbgs); extern void ECPGdebug(int n, FILE *dbgs);
exec sql whenever not found sqlprint;
exec sql whenever sqlerror db_error(msg);
void void
db_error (char *msg) db_error (char *msg)
{ {
...@@ -24,37 +25,32 @@ exec sql begin declare section; ...@@ -24,37 +25,32 @@ exec sql begin declare section;
} birth; } birth;
} personal; } personal;
exec sql end declare section; exec sql end declare section;
char msg[128];
FILE *dbgs; FILE *dbgs;
if ((dbgs = fopen("log", "w")) != NULL) if ((dbgs = fopen("log", "w")) != NULL)
ECPGdebug(1, dbgs); ECPGdebug(1, dbgs);
strcpy(msg, "connect");
exec sql connect 'mm'; exec sql connect 'mm';
if (SQLCODE)
db_error ("connect");
strcpy(msg, "declare");
exec sql declare cur cursor for exec sql declare cur cursor for
select name, born, age from meskes; select name, born, age from meskes;
if (SQLCODE) db_error ("declare");
exec sql open cur; exec sql open cur;
if (SQLCODE)
db_error ("open");
while (1) { while (1) {
strcpy(msg, "fetch");
exec sql fetch in cur into :personal; exec sql fetch in cur into :personal;
if (SQLCODE)
break;
printf ("%8.8s was born %d (age = %d)\n", personal.name.arr, personal.birth.born, personal.birth.age); printf ("%8.8s was born %d (age = %d)\n", personal.name.arr, personal.birth.born, personal.birth.age);
} }
if (SQLCODE < 0) strcpy(msg, "close");
db_error ("fetch");
exec sql close cur; exec sql close cur;
if (SQLCODE) db_error ("close");
strcpy(msg, "commit");
exec sql commit; exec sql commit;
if (SQLCODE) db_error ("commit");
if (dbgs != NULL) if (dbgs != NULL)
fclose(dbgs); fclose(dbgs);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment