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 ...@@ -1170,5 +1170,10 @@ Thu Dec 6 14:02:56 CET 2001
Sat Dec 8 21:35:45 CET 2001 Sat Dec 8 21:35:45 CET 2001
- Fix ecpg to allow pointer to structs. - 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 ecpg version to 2.9.0.
- Set library version to 3.3.0. - Set library version to 3.3.0.
...@@ -55,7 +55,7 @@ extern int yylex(void); ...@@ -55,7 +55,7 @@ extern int yylex(void);
extern void yyerror(char *); extern void yyerror(char *);
extern void *mm_alloc(size_t), *mm_realloc(void *, size_t); extern void *mm_alloc(size_t), *mm_realloc(void *, size_t);
extern char *mm_strdup(const char *); 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 *ScanECPGKeywordLookup(char *);
extern ScanKeyword *ScanCKeywordLookup(char *); extern ScanKeyword *ScanCKeywordLookup(char *);
extern void output_get_descr_header(char *); extern void output_get_descr_header(char *);
...@@ -85,3 +85,5 @@ extern ScanKeyword *ScanKeywordLookup(char *text); ...@@ -85,3 +85,5 @@ extern ScanKeyword *ScanKeywordLookup(char *text);
#define PARSE_ERROR 3 #define PARSE_ERROR 3
#define INDICATOR_NOT_ARRAY 4 #define INDICATOR_NOT_ARRAY 4
#define OUT_OF_MEMORY 5 #define OUT_OF_MEMORY 5
#define INDICATOR_NOT_STRUCT 6
#define INDICATOR_NOT_SIMPLE 7
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
* *
* *
* IDENTIFICATION * 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})*.* ...@@ -306,7 +306,7 @@ cppline {space}*#(.*\\{line_end})*.*
<xc>{xcinside} { ECHO; } <xc>{xcinside} { ECHO; }
<xc>{op_chars} { ECHO; } <xc>{op_chars} { ECHO; }
<xc><<EOF>> { mmerror(ET_ERROR, "Unterminated /* comment"); } <xc><<EOF>> { mmerror(PARSE_ERROR, ET_ERROR, "Unterminated /* comment"); }
<SQL>{xbitstart} { <SQL>{xbitstart} {
BEGIN(xbit); BEGIN(xbit);
...@@ -315,7 +315,7 @@ cppline {space}*#(.*\\{line_end})*.* ...@@ -315,7 +315,7 @@ cppline {space}*#(.*\\{line_end})*.*
<xbit>{xbitstop} { <xbit>{xbitstop} {
BEGIN(SQL); BEGIN(SQL);
if (literalbuf[strspn(literalbuf, "01") + 1] != '\0') 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; yylval.str = literalbuf;
return BITCONST; return BITCONST;
} }
...@@ -328,7 +328,7 @@ cppline {space}*#(.*\\{line_end})*.* ...@@ -328,7 +328,7 @@ cppline {space}*#(.*\\{line_end})*.*
<xbit>{xbitcat} { <xbit>{xbitcat} {
/* ignore */ /* ignore */
} }
<xbit><<EOF>> { mmerror(ET_ERROR, "Unterminated bit string"); } <xbit><<EOF>> { mmerror(PARSE_ERROR, ET_ERROR, "Unterminated bit string"); }
<SQL>{xhstart} { <SQL>{xhstart} {
BEGIN(xh); BEGIN(xh);
...@@ -347,12 +347,12 @@ cppline {space}*#(.*\\{line_end})*.* ...@@ -347,12 +347,12 @@ cppline {space}*#(.*\\{line_end})*.*
|| val != (long) ((int32) val) || val != (long) ((int32) val)
#endif #endif
) )
mmerror(ET_ERROR, "Bad hexadecimal integer input"); mmerror(PARSE_ERROR, ET_ERROR, "Bad hexadecimal integer input");
yylval.ival = val; yylval.ival = val;
return ICONST; return ICONST;
} }
<xh><<EOF>> { mmerror(ET_ERROR, "Unterminated hexadecimal integer"); } <xh><<EOF>> { mmerror(PARSE_ERROR, ET_ERROR, "Unterminated hexadecimal integer"); }
{xqstart} { {xqstart} {
state_before = YYSTATE; state_before = YYSTATE;
...@@ -373,7 +373,7 @@ cppline {space}*#(.*\\{line_end})*.* ...@@ -373,7 +373,7 @@ cppline {space}*#(.*\\{line_end})*.*
/* ignore */ /* ignore */
} }
<xq><<EOF>> { mmerror(ET_ERROR, "Unterminated quoted string"); } <xq><<EOF>> { mmerror(PARSE_ERROR, ET_ERROR, "Unterminated quoted string"); }
<SQL>{xdstart} { <SQL>{xdstart} {
state_before = YYSTATE; state_before = YYSTATE;
...@@ -396,7 +396,7 @@ cppline {space}*#(.*\\{line_end})*.* ...@@ -396,7 +396,7 @@ cppline {space}*#(.*\\{line_end})*.*
literalbuf, NAMEDATALEN-1, literalbuf); literalbuf, NAMEDATALEN-1, literalbuf);
literalbuf[NAMEDATALEN-1] = '\0'; literalbuf[NAMEDATALEN-1] = '\0';
#endif #endif
mmerror(ET_NOTICE, errortext); mmerror(PARSE_ERROR, ET_NOTICE, errortext);
} }
yylval.str = mm_strdup(literalbuf); yylval.str = mm_strdup(literalbuf);
...@@ -413,7 +413,7 @@ cppline {space}*#(.*\\{line_end})*.* ...@@ -413,7 +413,7 @@ cppline {space}*#(.*\\{line_end})*.*
<xd>{xdinside} { <xd>{xdinside} {
addlit(yytext, yyleng); addlit(yytext, yyleng);
} }
<xd,xdc><<EOF>> { mmerror(ET_ERROR, "Unterminated quoted identifier"); } <xd,xdc><<EOF>> { mmerror(PARSE_ERROR, ET_ERROR, "Unterminated quoted identifier"); }
{xdstart} { {xdstart} {
state_before = YYSTATE; state_before = YYSTATE;
BEGIN(xdc); BEGIN(xdc);
...@@ -687,10 +687,10 @@ cppline {space}*#(.*\\{line_end})*.* ...@@ -687,10 +687,10 @@ cppline {space}*#(.*\\{line_end})*.*
<C,xskip>{exec_sql}{elif}{space_or_nl}* { /* pop stack */ <C,xskip>{exec_sql}{elif}{space_or_nl}* { /* pop stack */
if ( preproc_tos == 0 ) { 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 ) { 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 { else {
preproc_tos--; preproc_tos--;
...@@ -701,7 +701,7 @@ cppline {space}*#(.*\\{line_end})*.* ...@@ -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' */ <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 ) { 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 { else {
stacked_if_value[preproc_tos].else_branch = TRUE; stacked_if_value[preproc_tos].else_branch = TRUE;
...@@ -719,7 +719,7 @@ cppline {space}*#(.*\\{line_end})*.* ...@@ -719,7 +719,7 @@ cppline {space}*#(.*\\{line_end})*.*
} }
<C,xskip>{exec_sql}{endif}{space_or_nl}*";" { <C,xskip>{exec_sql}{endif}{space_or_nl}*";" {
if ( preproc_tos == 0 ) { if ( preproc_tos == 0 ) {
mmerror(ET_FATAL, "Unmatched 'EXEC SQL ENDIF;'"); mmerror(PARSE_ERROR, ET_FATAL, "Unmatched 'EXEC SQL ENDIF;'");
} }
else { else {
preproc_tos--; preproc_tos--;
...@@ -737,7 +737,7 @@ cppline {space}*#(.*\\{line_end})*.* ...@@ -737,7 +737,7 @@ cppline {space}*#(.*\\{line_end})*.*
<xcond>{identifier}{space_or_nl}*";" { <xcond>{identifier}{space_or_nl}*";" {
if ( preproc_tos >= MAX_NESTED_IF-1 ) { 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 { else {
struct _defines *defptr; struct _defines *defptr;
...@@ -864,7 +864,7 @@ cppline {space}*#(.*\\{line_end})*.* ...@@ -864,7 +864,7 @@ cppline {space}*#(.*\\{line_end})*.*
if ( preproc_tos > 0 ) { if ( preproc_tos > 0 ) {
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) if (yy_buffer == NULL)
......
This diff is collapsed.
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
#include "extern.h" #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}; struct ECPGstruct_member struct_no_indicator = {"no_indicator", &ecpg_no_indicator, NULL};
/* malloc + error check */ /* malloc + error check */
...@@ -11,10 +13,7 @@ mm_alloc(size_t size) ...@@ -11,10 +13,7 @@ mm_alloc(size_t size)
void *ptr = malloc(size); void *ptr = malloc(size);
if (ptr == NULL) if (ptr == NULL)
{ mmerror(OUT_OF_MEMORY, ET_FATAL, "Out of memory\n");
fprintf(stderr, "Out of memory\n");
exit(OUT_OF_MEMORY);
}
return ptr; return ptr;
} }
...@@ -26,10 +25,7 @@ mm_strdup(const char *string) ...@@ -26,10 +25,7 @@ mm_strdup(const char *string)
char *new = strdup(string); char *new = strdup(string);
if (new == NULL) if (new == NULL)
{ mmerror(OUT_OF_MEMORY, ET_FATAL, "Out of memory\n");
fprintf(stderr, "Out of memory\n");
exit(OUT_OF_MEMORY);
}
return new; return new;
} }
...@@ -202,23 +198,19 @@ static void ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype typ, ...@@ -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, 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); struct ECPGtype * typ, struct ECPGtype * ind_typ, const char *offset, const char *prefix, const char *ind_prefix);
void 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) 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) switch (typ->typ)
{ {
case ECPGt_array: 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) switch (typ->u.element->typ)
{ {
case ECPGt_array: 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; break;
case ECPGt_struct: case ECPGt_struct:
case ECPGt_union: case ECPGt_union:
...@@ -235,33 +227,38 @@ ECPGdump_a_type(FILE *o, const char *name, struct ECPGtype * typ, const char *in ...@@ -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) if (ind_typ->typ == ECPGt_NO_INDICATOR)
ECPGdump_a_simple(o, ind_name, ind_typ->typ, ind_typ->size, -1, NULL, ind_prefix); ECPGdump_a_simple(o, ind_name, ind_typ->typ, ind_typ->size, -1, NULL, ind_prefix);
else 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, ECPGdump_a_simple(o, ind_name, ind_typ->u.element->typ,
ind_typ->u.element->size, ind_typ->size, NULL, prefix); ind_typ->u.element->size, ind_typ->size, NULL, prefix);
} }
} }
}
break; break;
case ECPGt_struct: 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); ECPGdump_a_struct(o, name, ind_name, 1, typ, ind_typ, NULL, prefix, ind_prefix);
break; break;
case ECPGt_union: /* cannot dump a complete union */ case ECPGt_union: /* cannot dump a complete union */
yyerror("Type of union has to be specified"); yyerror("Type of union has to be specified");
break; break;
case ECPGt_char_variable: 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, name, typ->typ, 1, 1, NULL, prefix);
ECPGdump_a_simple(o, ind_name, ind_typ->typ, ind_typ->size, -1, NULL, ind_prefix); ECPGdump_a_simple(o, ind_name, ind_typ->typ, ind_typ->size, -1, NULL, ind_prefix);
break; break;
case ECPGt_descriptor: 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, name, typ->typ, 0, -1, NULL, prefix);
ECPGdump_a_simple(o, ind_name, ind_typ->typ, ind_typ->size, -1, NULL, ind_prefix); ECPGdump_a_simple(o, ind_name, ind_typ->typ, ind_typ->size, -1, NULL, ind_prefix);
break; break;
default: 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); ECPGdump_a_simple(o, name, typ->typ, typ->size, -1, NULL, prefix);
if (ind_typ != NULL) if (ind_typ != NULL)
ECPGdump_a_simple(o, ind_name, ind_typ->typ, ind_typ->size, -1, NULL, ind_prefix); 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, ...@@ -361,7 +358,7 @@ ECPGdump_a_struct(FILE *o, const char *name, const char *ind_name, long arrsiz,
struct ECPGstruct_member *p, struct ECPGstruct_member *p,
*ind_p = NULL; *ind_p = NULL;
char obuf[BUFSIZ]; char obuf[BUFSIZ];
char pbuf[BUFSIZ*2], char pbuf[BUFSIZ],
ind_pbuf[BUFSIZ]; ind_pbuf[BUFSIZ];
const char *offset; 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