Commit a4420c49 authored by Michael Meskes's avatar Michael Meskes

Fixed several bugs concerning indicators and added error messages instead of segfaults.

parent eda51264
......@@ -1170,5 +1170,10 @@ Thu Dec 6 14:02:56 CET 2001
Sat Dec 8 21:35:45 CET 2001
- Fix ecpg to allow pointer to structs.
Sun Dec 9 16:21:30 CET 2001
- Fixed several bugs concerning indicators and added error messages
instead of segfaults.
- Set ecpg version to 2.9.0.
- Set library version to 3.3.0.
......@@ -55,7 +55,7 @@ extern int yylex(void);
extern void yyerror(char *);
extern void *mm_alloc(size_t), *mm_realloc(void *, size_t);
extern char *mm_strdup(const char *);
extern void mmerror(enum errortype, char *);
extern void mmerror(int, enum errortype, char *);
extern ScanKeyword *ScanECPGKeywordLookup(char *);
extern ScanKeyword *ScanCKeywordLookup(char *);
extern void output_get_descr_header(char *);
......@@ -85,3 +85,5 @@ extern ScanKeyword *ScanKeywordLookup(char *text);
#define PARSE_ERROR 3
#define INDICATOR_NOT_ARRAY 4
#define OUT_OF_MEMORY 5
#define INDICATOR_NOT_STRUCT 6
#define INDICATOR_NOT_SIMPLE 7
......@@ -12,7 +12,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.81 2001/09/19 14:09:32 meskes Exp $
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.82 2001/12/09 15:27:49 meskes Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -306,7 +306,7 @@ cppline {space}*#(.*\\{line_end})*.*
<xc>{xcinside} { ECHO; }
<xc>{op_chars} { ECHO; }
<xc><<EOF>> { mmerror(ET_ERROR, "Unterminated /* comment"); }
<xc><<EOF>> { mmerror(PARSE_ERROR, ET_ERROR, "Unterminated /* comment"); }
<SQL>{xbitstart} {
BEGIN(xbit);
......@@ -315,7 +315,7 @@ cppline {space}*#(.*\\{line_end})*.*
<xbit>{xbitstop} {
BEGIN(SQL);
if (literalbuf[strspn(literalbuf, "01") + 1] != '\0')
mmerror(ET_ERROR, "invalid bit string input.");
mmerror(PARSE_ERROR, ET_ERROR, "invalid bit string input.");
yylval.str = literalbuf;
return BITCONST;
}
......@@ -328,7 +328,7 @@ cppline {space}*#(.*\\{line_end})*.*
<xbit>{xbitcat} {
/* ignore */
}
<xbit><<EOF>> { mmerror(ET_ERROR, "Unterminated bit string"); }
<xbit><<EOF>> { mmerror(PARSE_ERROR, ET_ERROR, "Unterminated bit string"); }
<SQL>{xhstart} {
BEGIN(xh);
......@@ -347,12 +347,12 @@ cppline {space}*#(.*\\{line_end})*.*
|| val != (long) ((int32) val)
#endif
)
mmerror(ET_ERROR, "Bad hexadecimal integer input");
mmerror(PARSE_ERROR, ET_ERROR, "Bad hexadecimal integer input");
yylval.ival = val;
return ICONST;
}
<xh><<EOF>> { mmerror(ET_ERROR, "Unterminated hexadecimal integer"); }
<xh><<EOF>> { mmerror(PARSE_ERROR, ET_ERROR, "Unterminated hexadecimal integer"); }
{xqstart} {
state_before = YYSTATE;
......@@ -373,7 +373,7 @@ cppline {space}*#(.*\\{line_end})*.*
/* ignore */
}
<xq><<EOF>> { mmerror(ET_ERROR, "Unterminated quoted string"); }
<xq><<EOF>> { mmerror(PARSE_ERROR, ET_ERROR, "Unterminated quoted string"); }
<SQL>{xdstart} {
state_before = YYSTATE;
......@@ -396,7 +396,7 @@ cppline {space}*#(.*\\{line_end})*.*
literalbuf, NAMEDATALEN-1, literalbuf);
literalbuf[NAMEDATALEN-1] = '\0';
#endif
mmerror(ET_NOTICE, errortext);
mmerror(PARSE_ERROR, ET_NOTICE, errortext);
}
yylval.str = mm_strdup(literalbuf);
......@@ -413,7 +413,7 @@ cppline {space}*#(.*\\{line_end})*.*
<xd>{xdinside} {
addlit(yytext, yyleng);
}
<xd,xdc><<EOF>> { mmerror(ET_ERROR, "Unterminated quoted identifier"); }
<xd,xdc><<EOF>> { mmerror(PARSE_ERROR, ET_ERROR, "Unterminated quoted identifier"); }
{xdstart} {
state_before = YYSTATE;
BEGIN(xdc);
......@@ -687,10 +687,10 @@ cppline {space}*#(.*\\{line_end})*.*
<C,xskip>{exec_sql}{elif}{space_or_nl}* { /* pop stack */
if ( preproc_tos == 0 ) {
mmerror(ET_FATAL, "Missing matching 'EXEC SQL IFDEF / EXEC SQL IFNDEF'");
mmerror(PARSE_ERROR, ET_FATAL, "Missing matching 'EXEC SQL IFDEF / EXEC SQL IFNDEF'");
}
else if ( stacked_if_value[preproc_tos].else_branch ) {
mmerror(ET_FATAL, "Missing 'EXEC SQL ENDIF;'");
mmerror(PARSE_ERROR, ET_FATAL, "Missing 'EXEC SQL ENDIF;'");
}
else {
preproc_tos--;
......@@ -701,7 +701,7 @@ cppline {space}*#(.*\\{line_end})*.*
<C,xskip>{exec_sql}{else}{space_or_nl}*";" { /* only exec sql endif pops the stack, so take care of duplicated 'else' */
if ( stacked_if_value[preproc_tos].else_branch ) {
mmerror(ET_FATAL, "Duplicated 'EXEC SQL ELSE;'");
mmerror(PARSE_ERROR, ET_FATAL, "Duplicated 'EXEC SQL ELSE;'");
}
else {
stacked_if_value[preproc_tos].else_branch = TRUE;
......@@ -719,7 +719,7 @@ cppline {space}*#(.*\\{line_end})*.*
}
<C,xskip>{exec_sql}{endif}{space_or_nl}*";" {
if ( preproc_tos == 0 ) {
mmerror(ET_FATAL, "Unmatched 'EXEC SQL ENDIF;'");
mmerror(PARSE_ERROR, ET_FATAL, "Unmatched 'EXEC SQL ENDIF;'");
}
else {
preproc_tos--;
......@@ -737,7 +737,7 @@ cppline {space}*#(.*\\{line_end})*.*
<xcond>{identifier}{space_or_nl}*";" {
if ( preproc_tos >= MAX_NESTED_IF-1 ) {
mmerror(ET_FATAL, "Too many nested 'EXEC SQL IFDEF' conditions");
mmerror(PARSE_ERROR, ET_FATAL, "Too many nested 'EXEC SQL IFDEF' conditions");
}
else {
struct _defines *defptr;
......@@ -864,7 +864,7 @@ cppline {space}*#(.*\\{line_end})*.*
if ( preproc_tos > 0 ) {
preproc_tos = 0;
mmerror(ET_FATAL, "Missing 'EXEC SQL ENDIF;'");
mmerror(PARSE_ERROR, ET_FATAL, "Missing 'EXEC SQL ENDIF;'");
}
if (yy_buffer == NULL)
......
This diff is collapsed.
......@@ -2,6 +2,8 @@
#include "extern.h"
#define indicator_set ind_typ != NULL && ind_typ->typ != ECPGt_NO_INDICATOR
struct ECPGstruct_member struct_no_indicator = {"no_indicator", &ecpg_no_indicator, NULL};
/* malloc + error check */
......@@ -11,10 +13,7 @@ mm_alloc(size_t size)
void *ptr = malloc(size);
if (ptr == NULL)
{
fprintf(stderr, "Out of memory\n");
exit(OUT_OF_MEMORY);
}
mmerror(OUT_OF_MEMORY, ET_FATAL, "Out of memory\n");
return ptr;
}
......@@ -26,11 +25,8 @@ mm_strdup(const char *string)
char *new = strdup(string);
if (new == NULL)
{
fprintf(stderr, "Out of memory\n");
exit(OUT_OF_MEMORY);
}
mmerror(OUT_OF_MEMORY, ET_FATAL, "Out of memory\n");
return new;
}
......@@ -202,23 +198,19 @@ static void ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype typ,
static void 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);
void
ECPGdump_a_type(FILE *o, const char *name, struct ECPGtype * typ, const char *ind_name, struct ECPGtype * ind_typ, const char *prefix, const char *ind_prefix)
{
/* if (ind_typ == NULL)
{
ind_typ = &ecpg_no_indicator;
ind_name = "no_indicator";
}*/
switch (typ->typ)
{
case ECPGt_array:
if (indicator_set && ind_typ->typ != ECPGt_array)
mmerror(INDICATOR_NOT_ARRAY, ET_FATAL, "Indicator for array/pointer has to be array/pointer.\n");
switch (typ->u.element->typ)
{
case ECPGt_array:
yyerror("No nested arrays allowed (except strings)"); /* array of array */
mmerror(PARSE_ERROR, ET_ERROR, "No nested arrays allowed (except strings)"); /* array of array */
break;
case ECPGt_struct:
case ECPGt_union:
......@@ -235,33 +227,38 @@ ECPGdump_a_type(FILE *o, const char *name, struct ECPGtype * typ, const char *in
if (ind_typ->typ == ECPGt_NO_INDICATOR)
ECPGdump_a_simple(o, ind_name, ind_typ->typ, ind_typ->size, -1, NULL, ind_prefix);
else
{
if (ind_typ->typ != ECPGt_array)
{
fprintf(stderr, "Indicator for an array has to be array too.\n");
exit(INDICATOR_NOT_ARRAY);
}
ECPGdump_a_simple(o, ind_name, ind_typ->u.element->typ,
ind_typ->u.element->size, ind_typ->size, NULL, prefix);
}
}
}
break;
case ECPGt_struct:
if (indicator_set && ind_typ->typ != ECPGt_struct)
mmerror(INDICATOR_NOT_STRUCT, ET_FATAL, "Indicator for struct has to be struct.\n");
ECPGdump_a_struct(o, name, ind_name, 1, typ, ind_typ, NULL, prefix, ind_prefix);
break;
case ECPGt_union: /* cannot dump a complete union */
yyerror("Type of union has to be specified");
break;
case ECPGt_char_variable:
if (indicator_set && (ind_typ->typ == ECPGt_struct || ind_typ->typ == ECPGt_array))
mmerror(INDICATOR_NOT_SIMPLE, ET_FATAL, "Indicator for simple datatype has to be simple.\n");
ECPGdump_a_simple(o, name, typ->typ, 1, 1, NULL, prefix);
ECPGdump_a_simple(o, ind_name, ind_typ->typ, ind_typ->size, -1, NULL, ind_prefix);
break;
case ECPGt_descriptor:
if (indicator_set && (ind_typ->typ == ECPGt_struct || ind_typ->typ == ECPGt_array))
mmerror(INDICATOR_NOT_SIMPLE, ET_FATAL, "Indicator for simple datatype has to be simple.\n");
ECPGdump_a_simple(o, name, typ->typ, 0, -1, NULL, prefix);
ECPGdump_a_simple(o, ind_name, ind_typ->typ, ind_typ->size, -1, NULL, ind_prefix);
break;
default:
if (indicator_set && (ind_typ->typ == ECPGt_struct || ind_typ->typ == ECPGt_array))
mmerror(INDICATOR_NOT_SIMPLE, ET_FATAL, "Indicator for simple datatype has to be simple.\n");
ECPGdump_a_simple(o, name, typ->typ, typ->size, -1, NULL, prefix);
if (ind_typ != NULL)
ECPGdump_a_simple(o, ind_name, ind_typ->typ, ind_typ->size, -1, NULL, ind_prefix);
......@@ -361,7 +358,7 @@ ECPGdump_a_struct(FILE *o, const char *name, const char *ind_name, long arrsiz,
struct ECPGstruct_member *p,
*ind_p = NULL;
char obuf[BUFSIZ];
char pbuf[BUFSIZ*2],
char pbuf[BUFSIZ],
ind_pbuf[BUFSIZ];
const char *offset;
......
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