mirror of
https://github.com/postgres/postgres.git
synced 2025-04-29 13:56:47 +03:00
ecpg now recognizes named structs/unions. So you don't have to list the whole definition everytime you declare a variable anymore.
This commit is contained in:
parent
0b5b3e9e65
commit
d03a067ba0
@ -1432,6 +1432,10 @@ Tue May 20 11:47:00 CEST 2003
|
|||||||
- Reversed my fix for ifdef. It was the example, not ecpg which was
|
- Reversed my fix for ifdef. It was the example, not ecpg which was
|
||||||
incorrect.
|
incorrect.
|
||||||
- Changed DBPATH variable to PG_DBPATH.
|
- Changed DBPATH variable to PG_DBPATH.
|
||||||
|
|
||||||
|
Thu May 22 09:33:54 CEST 2003
|
||||||
|
|
||||||
|
- ecpg now recognizes named struct/union usage.
|
||||||
- Set ecpg version to 2.12.0.
|
- Set ecpg version to 2.12.0.
|
||||||
- Set ecpg library to 3.4.2.
|
- Set ecpg library to 3.4.2.
|
||||||
- Set pgtypes library to 1.0.0
|
- Set pgtypes library to 1.0.0
|
||||||
|
@ -192,7 +192,7 @@ output_get_descr(char *desc_name, char *index)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fprintf(yyout, "%s,", get_dtype(results->value));
|
fprintf(yyout, "%s,", get_dtype(results->value));
|
||||||
ECPGdump_a_type(yyout, v->name, v->type, NULL, NULL, NULL, NULL, make_str("0"), NULL, NULL);
|
ECPGdump_a_type(yyout, v->name, v->type, NULL, NULL, NULL, NULL, NULL, NULL, make_str("0"), NULL, NULL);
|
||||||
}
|
}
|
||||||
drop_assignments();
|
drop_assignments();
|
||||||
fputs("ECPGd_EODT);\n", yyout);
|
fputs("ECPGd_EODT);\n", yyout);
|
||||||
|
@ -73,8 +73,8 @@ extern void add_descriptor(char *, char *);
|
|||||||
extern void drop_descriptor(char *, char *);
|
extern void drop_descriptor(char *, char *);
|
||||||
extern struct descriptor *lookup_descriptor(char *, char *);
|
extern struct descriptor *lookup_descriptor(char *, char *);
|
||||||
extern struct variable *descriptor_variable(const char *name, int input);
|
extern struct variable *descriptor_variable(const char *name, int input);
|
||||||
extern void add_variable(struct arguments **, struct variable *, struct variable *);
|
extern void add_variable(struct arguments **, struct variable *, char *i, struct variable *, char *);
|
||||||
extern void append_variable(struct arguments **, struct variable *, struct variable *);
|
extern void append_variable(struct arguments **, struct variable *, char *, struct variable *, char *);
|
||||||
extern void dump_variables(struct arguments *, int);
|
extern void dump_variables(struct arguments *, int);
|
||||||
extern struct typedefs *get_typedef(char *);
|
extern struct typedefs *get_typedef(char *);
|
||||||
extern void adjust_array(enum ECPGttype, char **, char **, char *, char *, int);
|
extern void adjust_array(enum ECPGttype, char **, char **, char *, char *, int);
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.109 2003/05/20 11:05:27 meskes Exp $
|
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.110 2003/05/22 07:58:41 meskes Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -434,20 +434,6 @@ cppline {space}*#(.*\\{space})+.*
|
|||||||
else
|
else
|
||||||
return yytext[0];
|
return yytext[0];
|
||||||
}
|
}
|
||||||
<C>{informix_special}{struct} {
|
|
||||||
/* are we simulating Informix? */
|
|
||||||
if (compat == ECPG_COMPAT_INFORMIX)
|
|
||||||
{
|
|
||||||
string_unput("typedef struct ");
|
|
||||||
BEGIN SQL;
|
|
||||||
return SQL_START;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
string_unput("struct ");
|
|
||||||
return S_ANYTHING;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
<SQL>{self} { /*
|
<SQL>{self} { /*
|
||||||
* We may find a ';' inside a structure
|
* We may find a ';' inside a structure
|
||||||
* definition in a TYPE or VAR statement.
|
* definition in a TYPE or VAR statement.
|
||||||
@ -905,7 +891,7 @@ cppline {space}*#(.*\\{space})+.*
|
|||||||
|
|
||||||
<xskip>{other} { /* ignore */ }
|
<xskip>{other} { /* ignore */ }
|
||||||
|
|
||||||
<xcond>{identifier}{space}*';' {
|
<xcond>{identifier}{space}*";" {
|
||||||
if ( preproc_tos >= MAX_NESTED_IF-1 ) {
|
if ( preproc_tos >= MAX_NESTED_IF-1 ) {
|
||||||
mmerror(PARSE_ERROR, ET_FATAL, "Too many nested 'EXEC SQL IFDEF' conditions");
|
mmerror(PARSE_ERROR, ET_FATAL, "Too many nested 'EXEC SQL IFDEF' conditions");
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/Attic/preproc.y,v 1.219 2003/05/16 11:30:09 meskes Exp $ */
|
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/Attic/preproc.y,v 1.220 2003/05/22 07:58:41 meskes Exp $ */
|
||||||
|
|
||||||
/* Copyright comment */
|
/* Copyright comment */
|
||||||
%{
|
%{
|
||||||
@ -384,14 +384,15 @@ make_name(void)
|
|||||||
%type <str> ECPGSetConnection ECPGTypedef c_args ECPGKeywords
|
%type <str> ECPGSetConnection ECPGTypedef c_args ECPGKeywords
|
||||||
%type <str> enum_type civar civarind ECPGCursorStmt ECPGDeallocate
|
%type <str> enum_type civar civarind ECPGCursorStmt ECPGDeallocate
|
||||||
%type <str> ECPGFree ECPGDeclare ECPGVar opt_at enum_definition
|
%type <str> ECPGFree ECPGDeclare ECPGVar opt_at enum_definition
|
||||||
%type <str> struct_type s_struct vt_declarations variable_declarations
|
%type <str> struct_union_type s_struct_union vt_declarations
|
||||||
%type <str> var_declaration type_declaration single_vt_declaration
|
%type <str> var_declaration type_declaration single_vt_declaration
|
||||||
%type <str> s_union union_type ECPGSetAutocommit on_off
|
%type <str> ECPGSetAutocommit on_off variable_declarations
|
||||||
%type <str> ECPGAllocateDescr ECPGDeallocateDescr symbol opt_symbol
|
%type <str> ECPGAllocateDescr ECPGDeallocateDescr symbol
|
||||||
%type <str> ECPGGetDescriptorHeader ECPGColLabel single_var_declaration
|
%type <str> ECPGGetDescriptorHeader ECPGColLabel single_var_declaration
|
||||||
%type <str> reserved_keyword unreserved_keyword ecpg_interval
|
%type <str> reserved_keyword unreserved_keyword ecpg_interval
|
||||||
%type <str> col_name_keyword func_name_keyword precision opt_scale
|
%type <str> col_name_keyword func_name_keyword precision opt_scale
|
||||||
%type <str> ECPGTypeName variablelist ECPGColLabelCommon
|
%type <str> ECPGTypeName variablelist ECPGColLabelCommon
|
||||||
|
%type <str> s_struct_union_symbol
|
||||||
|
|
||||||
%type <descriptor> ECPGGetDescriptor
|
%type <descriptor> ECPGGetDescriptor
|
||||||
|
|
||||||
@ -400,6 +401,7 @@ make_name(void)
|
|||||||
%type <dtype_enum> descriptor_item desc_header_item
|
%type <dtype_enum> descriptor_item desc_header_item
|
||||||
|
|
||||||
%type <type> var_type common_type single_vt_type
|
%type <type> var_type common_type single_vt_type
|
||||||
|
%type <type> struct_union_type_with_symbol
|
||||||
|
|
||||||
%type <action> action
|
%type <action> action
|
||||||
|
|
||||||
@ -611,10 +613,10 @@ stmt: AlterDatabaseSetStmt { output_statement($1, 0, connection); }
|
|||||||
|
|
||||||
/* merge variables given in prepare statement with those given here */
|
/* merge variables given in prepare statement with those given here */
|
||||||
for (p = ptr->argsinsert; p; p = p->next)
|
for (p = ptr->argsinsert; p; p = p->next)
|
||||||
append_variable(&argsinsert, p->variable, p->indicator);
|
append_variable(&argsinsert, p->variable, p->var_array_element, p->indicator, p->ind_array_element);
|
||||||
|
|
||||||
for (p = ptr->argsresult; p; p = p->next)
|
for (p = ptr->argsresult; p; p = p->next)
|
||||||
add_variable(&argsresult, p->variable, p->indicator);
|
add_variable(&argsresult, p->variable, p->var_array_element, p->indicator, p->ind_array_element);
|
||||||
|
|
||||||
output_statement(mm_strdup(ptr->command), 0, ptr->connection ? mm_strdup(ptr->connection) : NULL);
|
output_statement(mm_strdup(ptr->command), 0, ptr->connection ? mm_strdup(ptr->connection) : NULL);
|
||||||
}
|
}
|
||||||
@ -4121,7 +4123,7 @@ ECPGCursorStmt: DECLARE name opt_cursor CURSOR FOR ident
|
|||||||
sprintf(thisquery->name, "ECPGprepared_statement(\"%s\")", $6);
|
sprintf(thisquery->name, "ECPGprepared_statement(\"%s\")", $6);
|
||||||
|
|
||||||
this->argsinsert = NULL;
|
this->argsinsert = NULL;
|
||||||
add_variable(&(this->argsinsert), thisquery, &no_indicator);
|
add_variable(&(this->argsinsert), thisquery, NULL, &no_indicator, NULL);
|
||||||
|
|
||||||
cur = this;
|
cur = this;
|
||||||
|
|
||||||
@ -4155,19 +4157,56 @@ single_var_declaration: storage_declaration
|
|||||||
actual_type[struct_level].type_dimension = $2.type_dimension;
|
actual_type[struct_level].type_dimension = $2.type_dimension;
|
||||||
actual_type[struct_level].type_index = $2.type_index;
|
actual_type[struct_level].type_index = $2.type_index;
|
||||||
actual_type[struct_level].type_sizeof = $2.type_sizeof;
|
actual_type[struct_level].type_sizeof = $2.type_sizeof;
|
||||||
|
|
||||||
/* we do not need the string "varchar" for output */
|
|
||||||
/* so replace it with an empty string */
|
|
||||||
/* if ($2.type_enum == ECPGt_varchar)
|
|
||||||
{
|
|
||||||
free($2.type_str);
|
|
||||||
$2.type_str=EMPTY;
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
variable_list ';'
|
variable_list ';'
|
||||||
{
|
{
|
||||||
$$ = cat_str(5, actual_startline[struct_level], $1, $2.type_str, $4, make_str(";\n"));
|
$$ = cat_str(5, actual_startline[struct_level], $1, $2.type_str, $4, make_str(";\n"));
|
||||||
}
|
}
|
||||||
|
| single_vt_type
|
||||||
|
{
|
||||||
|
actual_type[struct_level].type_enum = $1.type_enum;
|
||||||
|
actual_type[struct_level].type_dimension = $1.type_dimension;
|
||||||
|
actual_type[struct_level].type_index = $1.type_index;
|
||||||
|
actual_type[struct_level].type_sizeof = $1.type_sizeof;
|
||||||
|
actual_storage[struct_level] = EMPTY;
|
||||||
|
|
||||||
|
actual_startline[struct_level] = hashline_number();
|
||||||
|
}
|
||||||
|
variable_list ';'
|
||||||
|
{
|
||||||
|
$$ = cat_str(4, actual_startline[struct_level], $1.type_str, $3, make_str(";\n"));
|
||||||
|
}
|
||||||
|
| struct_union_type_with_symbol ';'
|
||||||
|
{
|
||||||
|
/* this is essantially a typedef but needs the keyword struct/union as well */
|
||||||
|
struct typedefs *ptr, *this;
|
||||||
|
|
||||||
|
for (ptr = types; ptr != NULL; ptr = ptr->next)
|
||||||
|
{
|
||||||
|
if (strcmp($1.type_str, ptr->name) == 0)
|
||||||
|
{
|
||||||
|
/* re-definition is a bug */
|
||||||
|
snprintf(errortext, sizeof(errortext), "Type %s already defined", $1.type_str);
|
||||||
|
mmerror(PARSE_ERROR, ET_ERROR, errortext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this = (struct typedefs *) mm_alloc(sizeof(struct typedefs));
|
||||||
|
|
||||||
|
/* initial definition */
|
||||||
|
this->next = types;
|
||||||
|
this->name = $1.type_str;
|
||||||
|
this->type = (struct this_type *) mm_alloc(sizeof(struct this_type));
|
||||||
|
this->type->type_enum = $1.type_enum;
|
||||||
|
this->type->type_str = mm_strdup($1.type_str);
|
||||||
|
this->type->type_dimension = make_str("-1"); /* dimension of array */
|
||||||
|
this->type->type_index = make_str("-1"); /* length of string */
|
||||||
|
this->type->type_sizeof = ECPGstruct_sizeof;
|
||||||
|
this->struct_member_list = struct_member_list[struct_level];
|
||||||
|
|
||||||
|
types = this;
|
||||||
|
$$ = cat2_str($1.type_sizeof, make_str(";"));
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
precision: NumConst { $$ = $1; };
|
precision: NumConst { $$ = $1; };
|
||||||
@ -4277,6 +4316,20 @@ single_vt_type: common_type
|
|||||||
struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list);
|
struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
| s_struct_union_symbol
|
||||||
|
{
|
||||||
|
/* this is for named structs/unions */
|
||||||
|
char *name = $1;
|
||||||
|
struct typedefs *this = get_typedef(name);
|
||||||
|
|
||||||
|
$$.type_str = mm_strdup(this->name);
|
||||||
|
$$.type_enum = this->type->type_enum;
|
||||||
|
$$.type_dimension = this->type->type_dimension;
|
||||||
|
$$.type_index = this->type->type_index;
|
||||||
|
$$.type_sizeof = this->type->type_sizeof;
|
||||||
|
struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list);
|
||||||
|
free(name);
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -4353,7 +4406,7 @@ type_declaration: S_TYPEDEF
|
|||||||
this->type->type_enum = $3.type_enum;
|
this->type->type_enum = $3.type_enum;
|
||||||
this->type->type_str = mm_strdup($5);
|
this->type->type_str = mm_strdup($5);
|
||||||
this->type->type_dimension = dimension; /* dimension of array */
|
this->type->type_dimension = dimension; /* dimension of array */
|
||||||
this->type->type_index = length; /* lenght of string */
|
this->type->type_index = length; /* length of string */
|
||||||
this->type->type_sizeof = ECPGstruct_sizeof;
|
this->type->type_sizeof = ECPGstruct_sizeof;
|
||||||
this->struct_member_list = ($3.type_enum == ECPGt_struct || $3.type_enum == ECPGt_union) ?
|
this->struct_member_list = ($3.type_enum == ECPGt_struct || $3.type_enum == ECPGt_union) ?
|
||||||
struct_member_list[struct_level] : NULL;
|
struct_member_list[struct_level] : NULL;
|
||||||
@ -4379,19 +4432,56 @@ var_declaration: storage_declaration
|
|||||||
actual_type[struct_level].type_dimension = $2.type_dimension;
|
actual_type[struct_level].type_dimension = $2.type_dimension;
|
||||||
actual_type[struct_level].type_index = $2.type_index;
|
actual_type[struct_level].type_index = $2.type_index;
|
||||||
actual_type[struct_level].type_sizeof = $2.type_sizeof;
|
actual_type[struct_level].type_sizeof = $2.type_sizeof;
|
||||||
|
|
||||||
/* we do not need the string "varchar" for output */
|
|
||||||
/* so replace it with an empty string */
|
|
||||||
/* if ($2.type_enum == ECPGt_varchar)
|
|
||||||
{
|
|
||||||
free($2.type_str);
|
|
||||||
$2.type_str=EMPTY;
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
variable_list ';'
|
variable_list ';'
|
||||||
{
|
{
|
||||||
$$ = cat_str(5, actual_startline[struct_level], $1, $2.type_str, $4, make_str(";\n"));
|
$$ = cat_str(5, actual_startline[struct_level], $1, $2.type_str, $4, make_str(";\n"));
|
||||||
}
|
}
|
||||||
|
| var_type
|
||||||
|
{
|
||||||
|
actual_type[struct_level].type_enum = $1.type_enum;
|
||||||
|
actual_type[struct_level].type_dimension = $1.type_dimension;
|
||||||
|
actual_type[struct_level].type_index = $1.type_index;
|
||||||
|
actual_type[struct_level].type_sizeof = $1.type_sizeof;
|
||||||
|
actual_storage[struct_level] = EMPTY;
|
||||||
|
|
||||||
|
actual_startline[struct_level] = hashline_number();
|
||||||
|
}
|
||||||
|
variable_list ';'
|
||||||
|
{
|
||||||
|
$$ = cat_str(4, actual_startline[struct_level], $1.type_str, $3, make_str(";\n"));
|
||||||
|
}
|
||||||
|
| struct_union_type_with_symbol ';'
|
||||||
|
{
|
||||||
|
/* this is essantially a typedef but needs the keyword struct/union as well */
|
||||||
|
struct typedefs *ptr, *this;
|
||||||
|
|
||||||
|
for (ptr = types; ptr != NULL; ptr = ptr->next)
|
||||||
|
{
|
||||||
|
if (strcmp($1.type_str, ptr->name) == 0)
|
||||||
|
{
|
||||||
|
/* re-definition is a bug */
|
||||||
|
snprintf(errortext, sizeof(errortext), "Type %s already defined", $1.type_str);
|
||||||
|
mmerror(PARSE_ERROR, ET_ERROR, errortext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this = (struct typedefs *) mm_alloc(sizeof(struct typedefs));
|
||||||
|
|
||||||
|
/* initial definition */
|
||||||
|
this->next = types;
|
||||||
|
this->name = $1.type_str;
|
||||||
|
this->type = (struct this_type *) mm_alloc(sizeof(struct this_type));
|
||||||
|
this->type->type_enum = $1.type_enum;
|
||||||
|
this->type->type_str = mm_strdup($1.type_str);
|
||||||
|
this->type->type_dimension = make_str("-1"); /* dimension of array */
|
||||||
|
this->type->type_index = make_str("-1"); /* length of string */
|
||||||
|
this->type->type_sizeof = ECPGstruct_sizeof;
|
||||||
|
this->struct_member_list = struct_member_list[struct_level];
|
||||||
|
|
||||||
|
types = this;
|
||||||
|
$$ = cat2_str($1.type_sizeof, make_str(";"));
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
storage_declaration: storage_clause storage_modifier
|
storage_declaration: storage_clause storage_modifier
|
||||||
@ -4399,18 +4489,26 @@ storage_declaration: storage_clause storage_modifier
|
|||||||
actual_storage[struct_level] = cat2_str(mm_strdup($1), mm_strdup($2));
|
actual_storage[struct_level] = cat2_str(mm_strdup($1), mm_strdup($2));
|
||||||
actual_startline[struct_level] = hashline_number();
|
actual_startline[struct_level] = hashline_number();
|
||||||
}
|
}
|
||||||
|
| storage_clause
|
||||||
|
{
|
||||||
|
actual_storage[struct_level] = mm_strdup($1);
|
||||||
|
actual_startline[struct_level] = hashline_number();
|
||||||
|
}
|
||||||
|
| storage_modifier
|
||||||
|
{
|
||||||
|
actual_storage[struct_level] = mm_strdup($1);
|
||||||
|
actual_startline[struct_level] = hashline_number();
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
storage_clause : S_EXTERN { $$ = make_str("extern"); }
|
storage_clause : S_EXTERN { $$ = make_str("extern"); }
|
||||||
| S_STATIC { $$ = make_str("static"); }
|
| S_STATIC { $$ = make_str("static"); }
|
||||||
| S_REGISTER { $$ = make_str("register"); }
|
| S_REGISTER { $$ = make_str("register"); }
|
||||||
| S_AUTO { $$ = make_str("auto"); }
|
| S_AUTO { $$ = make_str("auto"); }
|
||||||
| /*EMPTY*/ { $$ = EMPTY; }
|
|
||||||
;
|
;
|
||||||
|
|
||||||
storage_modifier : S_CONST { $$ = make_str("const"); }
|
storage_modifier : S_CONST { $$ = make_str("const"); }
|
||||||
| S_VOLATILE { $$ = make_str("volatile"); }
|
| S_VOLATILE { $$ = make_str("volatile"); }
|
||||||
| /*EMPTY*/ { $$ = EMPTY; }
|
|
||||||
;
|
;
|
||||||
|
|
||||||
common_type: simple_type
|
common_type: simple_type
|
||||||
@ -4421,22 +4519,23 @@ common_type: simple_type
|
|||||||
$$.type_index = make_str("-1");
|
$$.type_index = make_str("-1");
|
||||||
$$.type_sizeof = NULL;
|
$$.type_sizeof = NULL;
|
||||||
}
|
}
|
||||||
| struct_type
|
| struct_union_type
|
||||||
|
{
|
||||||
|
$$.type_str = $1;
|
||||||
|
$$.type_dimension = make_str("-1");
|
||||||
|
$$.type_index = make_str("-1");
|
||||||
|
|
||||||
|
if (strncmp($1, "struct", sizeof("struct")-1) == 0)
|
||||||
{
|
{
|
||||||
$$.type_enum = ECPGt_struct;
|
$$.type_enum = ECPGt_struct;
|
||||||
$$.type_str = $1;
|
|
||||||
$$.type_dimension = make_str("-1");
|
|
||||||
$$.type_index = make_str("-1");
|
|
||||||
$$.type_sizeof = ECPGstruct_sizeof;
|
$$.type_sizeof = ECPGstruct_sizeof;
|
||||||
}
|
}
|
||||||
| union_type
|
else
|
||||||
{
|
{
|
||||||
$$.type_enum = ECPGt_union;
|
$$.type_enum = ECPGt_union;
|
||||||
$$.type_str = $1;
|
|
||||||
$$.type_dimension = make_str("-1");
|
|
||||||
$$.type_index = make_str("-1");
|
|
||||||
$$.type_sizeof = NULL;
|
$$.type_sizeof = NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
| enum_type
|
| enum_type
|
||||||
{
|
{
|
||||||
$$.type_str = $1;
|
$$.type_str = $1;
|
||||||
@ -4553,10 +4652,25 @@ var_type: common_type
|
|||||||
struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list);
|
struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
| s_struct_union_symbol
|
||||||
|
{
|
||||||
|
/* this is for named structs/unions */
|
||||||
|
char *name = $1;
|
||||||
|
struct typedefs *this = get_typedef(name);
|
||||||
|
$$.type_str = mm_strdup(this->name);
|
||||||
|
$$.type_enum = this->type->type_enum;
|
||||||
|
$$.type_dimension = this->type->type_dimension;
|
||||||
|
$$.type_index = this->type->type_index;
|
||||||
|
$$.type_sizeof = this->type->type_sizeof;
|
||||||
|
struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list);
|
||||||
|
free(name);
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
enum_type: SQL_ENUM opt_symbol enum_definition
|
enum_type: SQL_ENUM symbol enum_definition
|
||||||
{ $$ = cat_str(3, make_str("enum"), $2, $3); }
|
{ $$ = cat_str(3, make_str("enum"), $2, $3); }
|
||||||
|
| SQL_ENUM enum_definition
|
||||||
|
{ $$ = cat2_str(make_str("enum"), $2); }
|
||||||
| SQL_ENUM symbol
|
| SQL_ENUM symbol
|
||||||
{ $$ = cat2_str(make_str("enum"), $2); }
|
{ $$ = cat2_str(make_str("enum"), $2); }
|
||||||
;
|
;
|
||||||
@ -4564,42 +4678,55 @@ enum_type: SQL_ENUM opt_symbol enum_definition
|
|||||||
enum_definition: '{' c_list '}'
|
enum_definition: '{' c_list '}'
|
||||||
{ $$ = cat_str(3, make_str("{"), $2, make_str("}")); };
|
{ $$ = cat_str(3, make_str("{"), $2, make_str("}")); };
|
||||||
|
|
||||||
struct_type: s_struct '{' variable_declarations '}'
|
struct_union_type_with_symbol: s_struct_union_symbol
|
||||||
{
|
|
||||||
ECPGfree_struct_member(struct_member_list[struct_level]);
|
|
||||||
struct_member_list[struct_level] = NULL;
|
|
||||||
free(actual_storage[struct_level--]);
|
|
||||||
$$ = cat_str(4, $1, make_str("{"), $3, make_str("}"));
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
union_type: s_union '{' variable_declarations '}'
|
|
||||||
{
|
|
||||||
ECPGfree_struct_member(struct_member_list[struct_level]);
|
|
||||||
struct_member_list[struct_level] = NULL;
|
|
||||||
free(actual_storage[struct_level--]);
|
|
||||||
$$ = cat_str(4, $1, make_str("{"), $3, make_str("}"));
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
s_struct: SQL_STRUCT opt_symbol
|
|
||||||
{
|
{
|
||||||
struct_member_list[struct_level++] = NULL;
|
struct_member_list[struct_level++] = NULL;
|
||||||
|
if (struct_level >= STRUCT_DEPTH)
|
||||||
|
mmerror(PARSE_ERROR, ET_ERROR, "Too many levels in nested structure/union definition");
|
||||||
|
}
|
||||||
|
'{' variable_declarations '}'
|
||||||
|
{
|
||||||
|
ECPGfree_struct_member(struct_member_list[struct_level]);
|
||||||
|
struct_member_list[struct_level] = NULL;
|
||||||
|
free(actual_storage[struct_level--]);
|
||||||
|
if (strncmp($1, "struct", sizeof("struct")-1) == 0)
|
||||||
|
$$.type_enum = ECPGt_struct;
|
||||||
|
else
|
||||||
|
$$.type_enum = ECPGt_union;
|
||||||
|
$$.type_str = mm_strdup($1);
|
||||||
|
$$.type_sizeof = cat_str(4, $1, make_str("{"), $4, make_str("}"));
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
struct_union_type: struct_union_type_with_symbol { $$ = $1.type_sizeof; }
|
||||||
|
| s_struct_union
|
||||||
|
{
|
||||||
|
struct_member_list[struct_level++] = NULL;
|
||||||
|
if (struct_level >= STRUCT_DEPTH)
|
||||||
|
mmerror(PARSE_ERROR, ET_ERROR, "Too many levels in nested structure/union definition");
|
||||||
|
}
|
||||||
|
'{' variable_declarations '}'
|
||||||
|
{
|
||||||
|
ECPGfree_struct_member(struct_member_list[struct_level]);
|
||||||
|
struct_member_list[struct_level] = NULL;
|
||||||
|
free(actual_storage[struct_level--]);
|
||||||
|
$$ = cat_str(4, $1, make_str("{"), $4, make_str("}"));
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
s_struct_union_symbol: SQL_STRUCT symbol
|
||||||
|
{
|
||||||
$$ = cat2_str(make_str("struct"), $2);
|
$$ = cat2_str(make_str("struct"), $2);
|
||||||
ECPGstruct_sizeof = cat_str(3, make_str("sizeof("), strdup($$), make_str(")"));
|
ECPGstruct_sizeof = cat_str(3, make_str("sizeof("), strdup($$), make_str(")"));
|
||||||
if (struct_level >= STRUCT_DEPTH)
|
}
|
||||||
mmerror(PARSE_ERROR, ET_ERROR, "Too many levels in nested structure definition");
|
| UNION symbol
|
||||||
|
{
|
||||||
|
$$ = cat2_str(make_str("union"), $2);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
s_union: UNION opt_symbol
|
s_struct_union: SQL_STRUCT { $$ = make_str("struct"); }
|
||||||
{
|
| UNION { $$ = make_str("union"); }
|
||||||
struct_member_list[struct_level++] = NULL;
|
|
||||||
if (struct_level >= STRUCT_DEPTH)
|
|
||||||
mmerror(PARSE_ERROR, ET_ERROR, "Too many levels in nested structure definition");
|
|
||||||
|
|
||||||
$$ = cat2_str(make_str("union"), $2);
|
|
||||||
}
|
|
||||||
;
|
;
|
||||||
|
|
||||||
simple_type: unsigned_type { $$=$1; }
|
simple_type: unsigned_type { $$=$1; }
|
||||||
@ -4670,7 +4797,7 @@ variable: opt_pointer ECPGColLabelCommon opt_array_bounds opt_initializer
|
|||||||
{
|
{
|
||||||
struct ECPGtype * type;
|
struct ECPGtype * type;
|
||||||
char *dimension = $3.index1; /* dimension of array */
|
char *dimension = $3.index1; /* dimension of array */
|
||||||
char *length = $3.index2; /* lenght of string */
|
char *length = $3.index2; /* length of string */
|
||||||
char dim[14L];
|
char dim[14L];
|
||||||
|
|
||||||
adjust_array(actual_type[struct_level].type_enum, &dimension, &length, actual_type[struct_level].type_dimension, actual_type[struct_level].type_index, strlen($1));
|
adjust_array(actual_type[struct_level].type_enum, &dimension, &length, actual_type[struct_level].type_dimension, actual_type[struct_level].type_index, strlen($1));
|
||||||
@ -4811,7 +4938,7 @@ ECPGExecute : EXECUTE IMMEDIATE execstring
|
|||||||
thisquery->next = NULL;
|
thisquery->next = NULL;
|
||||||
thisquery->name = $3;
|
thisquery->name = $3;
|
||||||
|
|
||||||
add_variable(&argsinsert, thisquery, &no_indicator);
|
add_variable(&argsinsert, thisquery, NULL, &no_indicator, NULL);
|
||||||
|
|
||||||
$$ = make_str("?");
|
$$ = make_str("?");
|
||||||
}
|
}
|
||||||
@ -4825,7 +4952,7 @@ ECPGExecute : EXECUTE IMMEDIATE execstring
|
|||||||
thisquery->name = (char *) mm_alloc(sizeof("ECPGprepared_statement(\"\")") + strlen($2));
|
thisquery->name = (char *) mm_alloc(sizeof("ECPGprepared_statement(\"\")") + strlen($2));
|
||||||
sprintf(thisquery->name, "ECPGprepared_statement(\"%s\")", $2);
|
sprintf(thisquery->name, "ECPGprepared_statement(\"%s\")", $2);
|
||||||
|
|
||||||
add_variable(&argsinsert, thisquery, &no_indicator);
|
add_variable(&argsinsert, thisquery, NULL, &no_indicator, NULL);
|
||||||
}
|
}
|
||||||
opt_ecpg_using opt_ecpg_into
|
opt_ecpg_using opt_ecpg_into
|
||||||
{
|
{
|
||||||
@ -4866,7 +4993,7 @@ ecpg_into: INTO into_list
|
|||||||
}
|
}
|
||||||
| INTO opt_sql SQL_DESCRIPTOR quoted_ident_stringvar
|
| INTO opt_sql SQL_DESCRIPTOR quoted_ident_stringvar
|
||||||
{
|
{
|
||||||
add_variable(&argsresult, descriptor_variable($4,0), &no_indicator);
|
add_variable(&argsresult, descriptor_variable($4,0), NULL, &no_indicator, NULL);
|
||||||
$$ = EMPTY;
|
$$ = EMPTY;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@ -5044,7 +5171,7 @@ ECPGTypedef: TYPE_P
|
|||||||
this->type->type_enum = $5.type_enum;
|
this->type->type_enum = $5.type_enum;
|
||||||
this->type->type_str = mm_strdup($3);
|
this->type->type_str = mm_strdup($3);
|
||||||
this->type->type_dimension = dimension; /* dimension of array */
|
this->type->type_dimension = dimension; /* dimension of array */
|
||||||
this->type->type_index = length; /* lenght of string */
|
this->type->type_index = length; /* length of string */
|
||||||
this->type->type_sizeof = ECPGstruct_sizeof;
|
this->type->type_sizeof = ECPGstruct_sizeof;
|
||||||
this->struct_member_list = ($5.type_enum == ECPGt_struct || $5.type_enum == ECPGt_union) ?
|
this->struct_member_list = ($5.type_enum == ECPGt_struct || $5.type_enum == ECPGt_union) ?
|
||||||
struct_member_list[struct_level] : NULL;
|
struct_member_list[struct_level] : NULL;
|
||||||
@ -5269,10 +5396,6 @@ ECPGTypeName: SQL_BOOL { $$ = make_str("bool"); }
|
|||||||
| SQL_UNSIGNED { $$ = make_str("unsigned"); }
|
| SQL_UNSIGNED { $$ = make_str("unsigned"); }
|
||||||
;
|
;
|
||||||
|
|
||||||
opt_symbol: symbol { $$ = $1; }
|
|
||||||
| /*EMPTY*/ { $$ = EMPTY; }
|
|
||||||
;
|
|
||||||
|
|
||||||
symbol: ColLabel { $$ = $1; }
|
symbol: ColLabel { $$ = $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -5684,24 +5807,50 @@ c_args: /*EMPTY*/ { $$ = EMPTY; }
|
|||||||
;
|
;
|
||||||
|
|
||||||
coutputvariable: CVARIABLE indicator
|
coutputvariable: CVARIABLE indicator
|
||||||
{ add_variable(&argsresult, find_variable($1), find_variable($2)); }
|
{ add_variable(&argsresult, find_variable($1), NULL, find_variable($2), NULL); }
|
||||||
| CVARIABLE
|
| CVARIABLE
|
||||||
{ add_variable(&argsresult, find_variable($1), &no_indicator); }
|
{ add_variable(&argsresult, find_variable($1), NULL, &no_indicator, NULL); }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
civarind: CVARIABLE indicator
|
civarind: CVARIABLE '[' Iresult ']' indicator '[' Iresult ']'
|
||||||
{
|
{
|
||||||
if ($2 != NULL && (find_variable($2))->type->type == ECPGt_array)
|
if (find_variable($5)->type->type == ECPGt_array)
|
||||||
mmerror(PARSE_ERROR, ET_ERROR, "arrays of indicators are not allowed on input");
|
mmerror(PARSE_ERROR, ET_ERROR, "arrays of indicators are not allowed on input");
|
||||||
|
|
||||||
add_variable(&argsinsert, find_variable($1), ($2 == NULL) ? &no_indicator : find_variable($2));
|
add_variable(&argsinsert, find_variable($1), $3, find_variable($5), $7);
|
||||||
|
}
|
||||||
|
| CVARIABLE indicator '[' Iresult ']'
|
||||||
|
{
|
||||||
|
if (find_variable($2)->type->type == ECPGt_array)
|
||||||
|
mmerror(PARSE_ERROR, ET_ERROR, "arrays of indicators are not allowed on input");
|
||||||
|
|
||||||
|
add_variable(&argsinsert, find_variable($1), NULL, find_variable($2), $4);
|
||||||
|
}
|
||||||
|
| CVARIABLE '[' Iresult ']' indicator
|
||||||
|
{
|
||||||
|
if (find_variable($5)->type->type == ECPGt_array)
|
||||||
|
mmerror(PARSE_ERROR, ET_ERROR, "arrays of indicators are not allowed on input");
|
||||||
|
|
||||||
|
add_variable(&argsinsert, find_variable($1), $3, find_variable($5), NULL);
|
||||||
|
}
|
||||||
|
| CVARIABLE indicator
|
||||||
|
{
|
||||||
|
if (find_variable($2)->type->type == ECPGt_array)
|
||||||
|
mmerror(PARSE_ERROR, ET_ERROR, "arrays of indicators are not allowed on input");
|
||||||
|
|
||||||
|
add_variable(&argsinsert, find_variable($1), NULL, find_variable($2), NULL);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
civar: CVARIABLE
|
civar: CVARIABLE '[' Iresult ']'
|
||||||
{
|
{
|
||||||
add_variable(&argsinsert, find_variable($1), &no_indicator);
|
add_variable(&argsinsert, find_variable($1), $3, &no_indicator, NULL);
|
||||||
|
$$ = cat_str(4, $1, make_str("["), $3, make_str("]"));
|
||||||
|
}
|
||||||
|
| CVARIABLE
|
||||||
|
{
|
||||||
|
add_variable(&argsinsert, find_variable($1), NULL, &no_indicator, NULL);
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@ -5753,7 +5902,7 @@ c_thing: c_anything { $$ = $1; }
|
|||||||
|
|
||||||
c_anything: IDENT { $$ = $1; }
|
c_anything: IDENT { $$ = $1; }
|
||||||
| CSTRING { $$ = make3_str(make_str("\""), $1, make_str("\"")); }
|
| CSTRING { $$ = make3_str(make_str("\""), $1, make_str("\"")); }
|
||||||
| PosIntConst { $$ = $1; }
|
| Iconst { $$ = $1; }
|
||||||
| Fconst { $$ = $1; }
|
| Fconst { $$ = $1; }
|
||||||
| Sconst { $$ = $1; }
|
| Sconst { $$ = $1; }
|
||||||
| '*' { $$ = make_str("*"); }
|
| '*' { $$ = make_str("*"); }
|
||||||
|
@ -214,7 +214,8 @@ static void ECPGdump_a_struct(FILE *o, const char *name, const char *ind_name, c
|
|||||||
|
|
||||||
void
|
void
|
||||||
ECPGdump_a_type(FILE *o, const char *name, struct ECPGtype * type,
|
ECPGdump_a_type(FILE *o, const char *name, struct ECPGtype * type,
|
||||||
const char *ind_name, struct ECPGtype * ind_type,
|
const char *var_array_element, const char *ind_name,
|
||||||
|
struct ECPGtype * ind_type, const char *ind_array_element,
|
||||||
const char *prefix, const char *ind_prefix,
|
const char *prefix, const char *ind_prefix,
|
||||||
char *arr_str_siz, const char *struct_sizeof,
|
char *arr_str_siz, const char *struct_sizeof,
|
||||||
const char *ind_struct_sizeof)
|
const char *ind_struct_sizeof)
|
||||||
@ -450,7 +451,11 @@ ECPGdump_a_struct(FILE *o, const char *name, const char *ind_name, char *arrsiz,
|
|||||||
|
|
||||||
for (p = type->u.members; p; p = p->next)
|
for (p = type->u.members; p; p = p->next)
|
||||||
{
|
{
|
||||||
ECPGdump_a_type(o, p->name, p->type, (ind_p != NULL) ? ind_p->name : NULL, (ind_p != NULL) ? ind_p->type : NULL, prefix, ind_prefix, arrsiz, type->struct_sizeof, (ind_p != NULL) ? ind_type->struct_sizeof : NULL);
|
ECPGdump_a_type(o, p->name, p->type, NULL,
|
||||||
|
(ind_p != NULL) ? ind_p->name : NULL,
|
||||||
|
(ind_p != NULL) ? ind_p->type : NULL, NULL,
|
||||||
|
prefix, ind_prefix, arrsiz, type->struct_sizeof,
|
||||||
|
(ind_p != NULL) ? ind_type->struct_sizeof : NULL);
|
||||||
if (ind_p != NULL && ind_p != &struct_no_indicator)
|
if (ind_p != NULL && ind_p != &struct_no_indicator)
|
||||||
ind_p = ind_p->next;
|
ind_p = ind_p->next;
|
||||||
}
|
}
|
||||||
|
@ -50,8 +50,8 @@ void ECPGfree_type(struct ECPGtype *);
|
|||||||
the variable (required to do array fetches of structs).
|
the variable (required to do array fetches of structs).
|
||||||
*/
|
*/
|
||||||
void ECPGdump_a_type(FILE *, const char *, struct ECPGtype *, const char *,
|
void ECPGdump_a_type(FILE *, const char *, struct ECPGtype *, const char *,
|
||||||
struct ECPGtype *, const char *, const char *, char *,
|
const char *, struct ECPGtype *, const char *, const char *,
|
||||||
const char *, const char *);
|
const char *, char *, const char *, const char *);
|
||||||
|
|
||||||
/* A simple struct to keep a variable and its type. */
|
/* A simple struct to keep a variable and its type. */
|
||||||
struct ECPGtemp_type
|
struct ECPGtemp_type
|
||||||
@ -141,7 +141,9 @@ struct variable
|
|||||||
struct arguments
|
struct arguments
|
||||||
{
|
{
|
||||||
struct variable *variable;
|
struct variable *variable;
|
||||||
|
char *var_array_element;
|
||||||
struct variable *indicator;
|
struct variable *indicator;
|
||||||
|
char *ind_array_element;
|
||||||
struct arguments *next;
|
struct arguments *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -194,19 +194,21 @@ reset_variables(void)
|
|||||||
|
|
||||||
/* Insert a new variable into our request list. */
|
/* Insert a new variable into our request list. */
|
||||||
void
|
void
|
||||||
add_variable(struct arguments ** list, struct variable * var, struct variable * ind)
|
add_variable(struct arguments ** list, struct variable * var, char * var_array_element, struct variable * ind, char * ind_array_element)
|
||||||
{
|
{
|
||||||
struct arguments *p = (struct arguments *) mm_alloc(sizeof(struct arguments));
|
struct arguments *p = (struct arguments *) mm_alloc(sizeof(struct arguments));
|
||||||
|
|
||||||
p->variable = var;
|
p->variable = var;
|
||||||
|
p->var_array_element = var_array_element;
|
||||||
p->indicator = ind;
|
p->indicator = ind;
|
||||||
|
p->ind_array_element = ind_array_element;
|
||||||
p->next = *list;
|
p->next = *list;
|
||||||
*list = p;
|
*list = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Append a new variable to our request list. */
|
/* Append a new variable to our request list. */
|
||||||
void
|
void
|
||||||
append_variable(struct arguments ** list, struct variable * var, struct variable * ind)
|
append_variable(struct arguments ** list, struct variable * var, char * var_array_element, struct variable * ind, char * ind_array_element)
|
||||||
{
|
{
|
||||||
struct arguments *p,
|
struct arguments *p,
|
||||||
*new = (struct arguments *) mm_alloc(sizeof(struct arguments));
|
*new = (struct arguments *) mm_alloc(sizeof(struct arguments));
|
||||||
@ -214,7 +216,9 @@ append_variable(struct arguments ** list, struct variable * var, struct variable
|
|||||||
for (p = *list; p && p->next; p = p->next);
|
for (p = *list; p && p->next; p = p->next);
|
||||||
|
|
||||||
new->variable = var;
|
new->variable = var;
|
||||||
|
new->var_array_element = var_array_element;
|
||||||
new->indicator = ind;
|
new->indicator = ind;
|
||||||
|
new->ind_array_element = ind_array_element;
|
||||||
new->next = NULL;
|
new->next = NULL;
|
||||||
|
|
||||||
if (p)
|
if (p)
|
||||||
@ -241,8 +245,9 @@ dump_variables(struct arguments * list, int mode)
|
|||||||
dump_variables(list->next, mode);
|
dump_variables(list->next, mode);
|
||||||
|
|
||||||
/* Then the current element and its indicator */
|
/* Then the current element and its indicator */
|
||||||
ECPGdump_a_type(yyout, list->variable->name, list->variable->type,
|
ECPGdump_a_type(yyout, list->variable->name, list->variable->type, list->var_array_element,
|
||||||
list->indicator->name, list->indicator->type, NULL, NULL, 0, NULL, NULL);
|
list->indicator->name, list->indicator->type, list->ind_array_element,
|
||||||
|
NULL, NULL, 0, NULL, NULL);
|
||||||
|
|
||||||
/* Then release the list element. */
|
/* Then release the list element. */
|
||||||
if (mode != 0)
|
if (mode != 0)
|
||||||
|
@ -9,20 +9,19 @@ typedef char* c;
|
|||||||
exec sql type ind is union { int integer; short smallint; };
|
exec sql type ind is union { int integer; short smallint; };
|
||||||
typedef union { int integer; short smallint; } ind;
|
typedef union { int integer; short smallint; } ind;
|
||||||
|
|
||||||
#define BUFSIZ 8
|
#define BUFFERSIZ 8
|
||||||
exec sql type str is varchar[BUFSIZ];
|
exec sql type str is varchar[BUFFERSIZ];
|
||||||
|
|
||||||
int
|
int
|
||||||
main ()
|
main ()
|
||||||
{
|
{
|
||||||
typedef struct { long born; short age; } birthinfo;
|
exec sql struct birthinfo { long born; short age; };
|
||||||
exec sql type birthinfo is struct { long born; short age; };
|
|
||||||
exec sql begin declare section;
|
exec sql begin declare section;
|
||||||
struct personal_struct { str name;
|
struct personal_struct { str name;
|
||||||
birthinfo birth;
|
struct birthinfo birth;
|
||||||
} personal, *p;
|
} personal, *p;
|
||||||
struct personal_indicator { int ind_name;
|
struct personal_indicator { int ind_name;
|
||||||
birthinfo ind_birth;
|
struct birthinfo ind_birth;
|
||||||
} ind_personal, *i;
|
} ind_personal, *i;
|
||||||
ind ind_children;
|
ind ind_children;
|
||||||
c testname="Petra";
|
c testname="Petra";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user