diff --git a/src/interfaces/ecpg/ChangeLog b/src/interfaces/ecpg/ChangeLog index 5dd7977cea9997c085a5ead3644e0a14787e9070..e14c274099a163ad496ab608456bce0dfff20f9e 100644 --- a/src/interfaces/ecpg/ChangeLog +++ b/src/interfaces/ecpg/ChangeLog @@ -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 incorrect. - 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 library to 3.4.2. - Set pgtypes library to 1.0.0 diff --git a/src/interfaces/ecpg/preproc/descriptor.c b/src/interfaces/ecpg/preproc/descriptor.c index 742002b4c0f8f90ff08016f9afd945d71ca30a23..1c147820f15fb54f6cad131f4e44216117826345 100644 --- a/src/interfaces/ecpg/preproc/descriptor.c +++ b/src/interfaces/ecpg/preproc/descriptor.c @@ -192,7 +192,7 @@ output_get_descr(char *desc_name, char *index) break; } 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(); fputs("ECPGd_EODT);\n", yyout); diff --git a/src/interfaces/ecpg/preproc/extern.h b/src/interfaces/ecpg/preproc/extern.h index bc0cceaae9998eb963859cac8c0b926a32a7df34..7c20ee405d2cc39d60e733f803d0a8cc35543b67 100644 --- a/src/interfaces/ecpg/preproc/extern.h +++ b/src/interfaces/ecpg/preproc/extern.h @@ -73,8 +73,8 @@ extern void add_descriptor(char *, char *); extern void drop_descriptor(char *, char *); extern struct descriptor *lookup_descriptor(char *, char *); extern struct variable *descriptor_variable(const char *name, int input); -extern void add_variable(struct arguments **, struct variable *, struct variable *); -extern void append_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 *, char *, struct variable *, char *); extern void dump_variables(struct arguments *, int); extern struct typedefs *get_typedef(char *); extern void adjust_array(enum ECPGttype, char **, char **, char *, char *, int); diff --git a/src/interfaces/ecpg/preproc/pgc.l b/src/interfaces/ecpg/preproc/pgc.l index 77ba3666df9b5e76414ae61f97b9617f643b673c..6b197e5655d52bd7f6d41ff95940f76ce2376c05 100644 --- a/src/interfaces/ecpg/preproc/pgc.l +++ b/src/interfaces/ecpg/preproc/pgc.l @@ -12,7 +12,7 @@ * * * 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 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} { /* * We may find a ';' inside a structure * definition in a TYPE or VAR statement. @@ -905,7 +891,7 @@ cppline {space}*#(.*\\{space})+.* <xskip>{other} { /* ignore */ } -<xcond>{identifier}{space}*';' { +<xcond>{identifier}{space}*";" { if ( preproc_tos >= MAX_NESTED_IF-1 ) { mmerror(PARSE_ERROR, ET_FATAL, "Too many nested 'EXEC SQL IFDEF' conditions"); } diff --git a/src/interfaces/ecpg/preproc/preproc.y b/src/interfaces/ecpg/preproc/preproc.y index 95745145d3de8d3acaf63023969dfda11d1fc2d4..bcdf775c9d47798c04fe383e06282b73ed1258f0 100644 --- a/src/interfaces/ecpg/preproc/preproc.y +++ b/src/interfaces/ecpg/preproc/preproc.y @@ -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 */ %{ @@ -384,14 +384,15 @@ make_name(void) %type <str> ECPGSetConnection ECPGTypedef c_args ECPGKeywords %type <str> enum_type civar civarind ECPGCursorStmt ECPGDeallocate %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> s_union union_type ECPGSetAutocommit on_off -%type <str> ECPGAllocateDescr ECPGDeallocateDescr symbol opt_symbol +%type <str> ECPGSetAutocommit on_off variable_declarations +%type <str> ECPGAllocateDescr ECPGDeallocateDescr symbol %type <str> ECPGGetDescriptorHeader ECPGColLabel single_var_declaration %type <str> reserved_keyword unreserved_keyword ecpg_interval %type <str> col_name_keyword func_name_keyword precision opt_scale %type <str> ECPGTypeName variablelist ECPGColLabelCommon +%type <str> s_struct_union_symbol %type <descriptor> ECPGGetDescriptor @@ -399,7 +400,8 @@ make_name(void) %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 @@ -611,10 +613,10 @@ stmt: AlterDatabaseSetStmt { output_statement($1, 0, connection); } /* merge variables given in prepare statement with those given here */ 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) - 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); } @@ -3834,14 +3836,14 @@ StringConst: Sconst { $$ = $1; } ; PosIntStringConst: Iconst { $$ = $1; } - | Sconst { $$ = $1; } + | Sconst { $$ = $1; } | civar { $$ = make_str("?"); } ; NumConst: Fconst { $$ = $1; } | Iconst { $$ = $1; } | '-' Fconst { $$ = cat2_str(make_str("-"), $2); } - | '-' Iconst { $$ = cat2_str(make_str("-"), $2); } + | '-' Iconst { $$ = cat2_str(make_str("-"), $2); } | civar { $$ = make_str("?"); } ; @@ -4121,7 +4123,7 @@ ECPGCursorStmt: DECLARE name opt_cursor CURSOR FOR ident sprintf(thisquery->name, "ECPGprepared_statement(\"%s\")", $6); this->argsinsert = NULL; - add_variable(&(this->argsinsert), thisquery, &no_indicator); + add_variable(&(this->argsinsert), thisquery, NULL, &no_indicator, NULL); cur = this; @@ -4148,26 +4150,63 @@ single_vt_declaration: type_declaration { $$ = $1; } | single_var_declaration { $$ = $1; } ; -single_var_declaration: storage_declaration +single_var_declaration: storage_declaration single_vt_type { actual_type[struct_level].type_enum = $2.type_enum; actual_type[struct_level].type_dimension = $2.type_dimension; actual_type[struct_level].type_index = $2.type_index; 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 ';' { $$ = 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; }; @@ -4277,6 +4316,20 @@ single_vt_type: common_type 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_str = mm_strdup($5); 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->struct_member_list = ($3.type_enum == ECPGt_struct || $3.type_enum == ECPGt_union) ? 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_index = $2.type_index; 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 ';' { $$ = 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 @@ -4399,18 +4489,26 @@ storage_declaration: storage_clause storage_modifier actual_storage[struct_level] = cat2_str(mm_strdup($1), mm_strdup($2)); 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"); } - | S_STATIC { $$ = make_str("static"); } - | S_REGISTER { $$ = make_str("register"); } - | S_AUTO { $$ = make_str("auto"); } - | /*EMPTY*/ { $$ = EMPTY; } + | S_STATIC { $$ = make_str("static"); } + | S_REGISTER { $$ = make_str("register"); } + | S_AUTO { $$ = make_str("auto"); } ; storage_modifier : S_CONST { $$ = make_str("const"); } - | S_VOLATILE { $$ = make_str("volatile"); } - | /*EMPTY*/ { $$ = EMPTY; } + | S_VOLATILE { $$ = make_str("volatile"); } ; common_type: simple_type @@ -4421,21 +4519,22 @@ common_type: simple_type $$.type_index = make_str("-1"); $$.type_sizeof = NULL; } - | struct_type - { - $$.type_enum = ECPGt_struct; - $$.type_str = $1; - $$.type_dimension = make_str("-1"); - $$.type_index = make_str("-1"); - $$.type_sizeof = ECPGstruct_sizeof; - } - | union_type + | struct_union_type { - $$.type_enum = ECPGt_union; $$.type_str = $1; $$.type_dimension = make_str("-1"); $$.type_index = make_str("-1"); - $$.type_sizeof = NULL; + + if (strncmp($1, "struct", sizeof("struct")-1) == 0) + { + $$.type_enum = ECPGt_struct; + $$.type_sizeof = ECPGstruct_sizeof; + } + else + { + $$.type_enum = ECPGt_union; + $$.type_sizeof = NULL; + } } | enum_type { @@ -4553,55 +4652,83 @@ var_type: common_type 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); } - | SQL_ENUM symbol + | SQL_ENUM enum_definition + { $$ = cat2_str(make_str("enum"), $2); } + | SQL_ENUM symbol { $$ = cat2_str(make_str("enum"), $2); } ; enum_definition: '{' c_list '}' { $$ = cat_str(3, make_str("{"), $2, make_str("}")); }; -struct_type: s_struct '{' variable_declarations '}' +struct_union_type_with_symbol: s_struct_union_symbol + { + 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("{"), $3, make_str("}")); + 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("}")); } ; -union_type: s_union '{' variable_declarations '}' +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("{"), $3, make_str("}")); + $$ = cat_str(4, $1, make_str("{"), $4, make_str("}")); } ; -s_struct: SQL_STRUCT opt_symbol +s_struct_union_symbol: SQL_STRUCT symbol { - struct_member_list[struct_level++] = NULL; $$ = cat2_str(make_str("struct"), $2); - 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"); + ECPGstruct_sizeof = cat_str(3, make_str("sizeof("), strdup($$), make_str(")")); } - ; - -s_union: UNION opt_symbol + | UNION symbol { - 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); } ; +s_struct_union: SQL_STRUCT { $$ = make_str("struct"); } + | UNION { $$ = make_str("union"); } + ; + simple_type: unsigned_type { $$=$1; } | opt_signed signed_type { $$=$2; } ; @@ -4670,7 +4797,7 @@ variable: opt_pointer ECPGColLabelCommon opt_array_bounds opt_initializer { struct ECPGtype * type; char *dimension = $3.index1; /* dimension of array */ - char *length = $3.index2; /* lenght of string */ + char *length = $3.index2; /* length of string */ 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)); @@ -4811,7 +4938,7 @@ ECPGExecute : EXECUTE IMMEDIATE execstring thisquery->next = NULL; thisquery->name = $3; - add_variable(&argsinsert, thisquery, &no_indicator); + add_variable(&argsinsert, thisquery, NULL, &no_indicator, NULL); $$ = make_str("?"); } @@ -4825,7 +4952,7 @@ ECPGExecute : EXECUTE IMMEDIATE execstring thisquery->name = (char *) mm_alloc(sizeof("ECPGprepared_statement(\"\")") + strlen($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 { @@ -4866,7 +4993,7 @@ ecpg_into: INTO into_list } | 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; } ; @@ -5044,7 +5171,7 @@ ECPGTypedef: TYPE_P this->type->type_enum = $5.type_enum; this->type->type_str = mm_strdup($3); 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->struct_member_list = ($5.type_enum == ECPGt_struct || $5.type_enum == ECPGt_union) ? struct_member_list[struct_level] : NULL; @@ -5269,10 +5396,6 @@ ECPGTypeName: SQL_BOOL { $$ = make_str("bool"); } | SQL_UNSIGNED { $$ = make_str("unsigned"); } ; -opt_symbol: symbol { $$ = $1; } - | /*EMPTY*/ { $$ = EMPTY; } - ; - symbol: ColLabel { $$ = $1; } ; @@ -5684,24 +5807,50 @@ c_args: /*EMPTY*/ { $$ = EMPTY; } ; coutputvariable: CVARIABLE indicator - { add_variable(&argsresult, find_variable($1), find_variable($2)); } + { add_variable(&argsresult, find_variable($1), NULL, find_variable($2), NULL); } | 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 (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), $7); + } + | CVARIABLE indicator '[' Iresult ']' { - if ($2 != NULL && (find_variable($2))->type->type == ECPGt_array) + 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), ($2 == NULL) ? &no_indicator : find_variable($2)); + 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), $3, &no_indicator, NULL); + $$ = cat_str(4, $1, make_str("["), $3, make_str("]")); + } + | CVARIABLE { - add_variable(&argsinsert, find_variable($1), &no_indicator); + add_variable(&argsinsert, find_variable($1), NULL, &no_indicator, NULL); $$ = $1; } ; @@ -5753,7 +5902,7 @@ c_thing: c_anything { $$ = $1; } c_anything: IDENT { $$ = $1; } | CSTRING { $$ = make3_str(make_str("\""), $1, make_str("\"")); } - | PosIntConst { $$ = $1; } + | Iconst { $$ = $1; } | Fconst { $$ = $1; } | Sconst { $$ = $1; } | '*' { $$ = make_str("*"); } diff --git a/src/interfaces/ecpg/preproc/type.c b/src/interfaces/ecpg/preproc/type.c index d81c9f1374e5c0ca8fc3dbe67267d111502805ef..9c2491544733478f7a5d1cd711af62f44cf8dba0 100644 --- a/src/interfaces/ecpg/preproc/type.c +++ b/src/interfaces/ecpg/preproc/type.c @@ -214,7 +214,8 @@ static void ECPGdump_a_struct(FILE *o, const char *name, const char *ind_name, c void 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, char *arr_str_siz, const char *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) { - 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) ind_p = ind_p->next; } diff --git a/src/interfaces/ecpg/preproc/type.h b/src/interfaces/ecpg/preproc/type.h index 5c74b27cf9e35096193edaffb06196818a1c0fbc..28615af8c9c471574028ed4096d91ebe5d2ea6d8 100644 --- a/src/interfaces/ecpg/preproc/type.h +++ b/src/interfaces/ecpg/preproc/type.h @@ -50,8 +50,8 @@ void ECPGfree_type(struct ECPGtype *); the variable (required to do array fetches of structs). */ void ECPGdump_a_type(FILE *, const char *, struct ECPGtype *, const char *, - struct ECPGtype *, const char *, const char *, char *, - const char *, const char *); + const char *, struct ECPGtype *, const char *, const char *, + const char *, char *, const char *, const char *); /* A simple struct to keep a variable and its type. */ struct ECPGtemp_type @@ -141,7 +141,9 @@ struct variable struct arguments { struct variable *variable; + char *var_array_element; struct variable *indicator; + char *ind_array_element; struct arguments *next; }; diff --git a/src/interfaces/ecpg/preproc/variable.c b/src/interfaces/ecpg/preproc/variable.c index e545ade52955389f508c81ae3624417f2f581cd4..b62ba4d2c4de7e5351c5313b30cf1db337ea23e8 100644 --- a/src/interfaces/ecpg/preproc/variable.c +++ b/src/interfaces/ecpg/preproc/variable.c @@ -194,19 +194,21 @@ reset_variables(void) /* Insert a new variable into our request list. */ 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)); p->variable = var; + p->var_array_element = var_array_element; p->indicator = ind; + p->ind_array_element = ind_array_element; p->next = *list; *list = p; } /* Append a new variable to our request list. */ 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, *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); new->variable = var; + new->var_array_element = var_array_element; new->indicator = ind; + new->ind_array_element = ind_array_element; new->next = NULL; if (p) @@ -241,8 +245,9 @@ dump_variables(struct arguments * list, int mode) dump_variables(list->next, mode); /* Then the current element and its indicator */ - ECPGdump_a_type(yyout, list->variable->name, list->variable->type, - list->indicator->name, list->indicator->type, NULL, NULL, 0, NULL, NULL); + ECPGdump_a_type(yyout, list->variable->name, list->variable->type, list->var_array_element, + list->indicator->name, list->indicator->type, list->ind_array_element, + NULL, NULL, 0, NULL, NULL); /* Then release the list element. */ if (mode != 0) diff --git a/src/interfaces/ecpg/test/test1.pgc b/src/interfaces/ecpg/test/test1.pgc index 28c33b49545950e76d6dcfbcd61667696b2e08ac..f787b8fdb658000a04aef4ae819df893bec454e5 100644 --- a/src/interfaces/ecpg/test/test1.pgc +++ b/src/interfaces/ecpg/test/test1.pgc @@ -126,7 +126,7 @@ exec sql end declare section; amount[i]+=1000; strcpy(msg, "insert"); - exec sql at pm insert into "Test" (name, amount, letter) values (:n, :a, :l); + exec sql at pm insert into "Test" (name, amount, letter) values (:n, :a, :l); } strcpy(msg, "commit"); diff --git a/src/interfaces/ecpg/test/test2.pgc b/src/interfaces/ecpg/test/test2.pgc index 28b7c5c0e48166e37d50a939651f39ca50ef1ec9..701b11afb5c1be297bcee1d356f20ca1cf161a1c 100644 --- a/src/interfaces/ecpg/test/test2.pgc +++ b/src/interfaces/ecpg/test/test2.pgc @@ -9,20 +9,19 @@ typedef char* c; exec sql type ind is union { int integer; short smallint; }; typedef union { int integer; short smallint; } ind; -#define BUFSIZ 8 -exec sql type str is varchar[BUFSIZ]; +#define BUFFERSIZ 8 +exec sql type str is varchar[BUFFERSIZ]; int main () { - typedef struct { long born; short age; } birthinfo; - exec sql type birthinfo is struct { long born; short age; }; + exec sql struct birthinfo { long born; short age; }; exec sql begin declare section; struct personal_struct { str name; - birthinfo birth; + struct birthinfo birth; } personal, *p; struct personal_indicator { int ind_name; - birthinfo ind_birth; + struct birthinfo ind_birth; } ind_personal, *i; ind ind_children; c testname="Petra";