diff --git a/src/interfaces/ecpg/preproc/ecpg.addons b/src/interfaces/ecpg/preproc/ecpg.addons index e94da2a3f8..e7dce4e404 100644 --- a/src/interfaces/ecpg/preproc/ecpg.addons +++ b/src/interfaces/ecpg/preproc/ecpg.addons @@ -3,7 +3,7 @@ ECPG: stmtClosePortalStmt block { if (INFORMIX_MODE) { - if (pg_strcasecmp($1+strlen("close "), "database") == 0) + if (pg_strcasecmp($1 + strlen("close "), "database") == 0) { if (connection) mmerror(PARSE_ERROR, ET_ERROR, "AT option not allowed in CLOSE DATABASE statement"); @@ -22,7 +22,9 @@ ECPG: stmtDeallocateStmt block output_deallocate_prepare_statement($1); } ECPG: stmtDeclareCursorStmt block - { output_simple_statement($1, (strncmp($1, "ECPGset_var", strlen("ECPGset_var")) == 0) ? 4 : 0); } + { + output_simple_statement($1, (strncmp($1, "ECPGset_var", strlen("ECPGset_var")) == 0) ? 4 : 0); + } ECPG: stmtDiscardStmt block ECPG: stmtFetchStmt block { output_statement($1, 1, ECPGst_normal); } @@ -44,10 +46,13 @@ ECPG: stmtExecuteStmt block else { /* case of ecpg_ident or CSTRING */ - char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3); - char *str = mm_strdup($1.name + 1); + char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3); + char *str = mm_strdup($1.name + 1); - /* It must be cut off double quotation because new_variable() double-quotes. */ + /* + * It must be cut off double quotation because new_variable() + * double-quotes. + */ str[strlen(str) - 1] = '\0'; sprintf(length, "%zu", strlen(str)); add_variable_to_tail(&argsinsert, new_variable(str, ECPGmake_simple_type(ECPGt_const, length, 0), 0), &no_indicator); @@ -62,7 +67,8 @@ ECPG: stmtPrepareStmt block output_prepare_statement($1.name, $1.stmt); else if (strlen($1.type) == 0) { - char *stmt = cat_str(3, mm_strdup("\""), $1.stmt, mm_strdup("\"")); + char *stmt = cat_str(3, mm_strdup("\""), $1.stmt, mm_strdup("\"")); + output_prepare_statement($1.name, stmt); } else @@ -72,10 +78,13 @@ ECPG: stmtPrepareStmt block add_variable_to_tail(&argsinsert, find_variable($1.name), &no_indicator); else { - char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3); - char *str = mm_strdup($1.name + 1); + char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3); + char *str = mm_strdup($1.name + 1); - /* It must be cut off double quotation because new_variable() double-quotes. */ + /* + * It must be cut off double quotation because new_variable() + * double-quotes. + */ str[strlen(str) - 1] = '\0'; sprintf(length, "%zu", strlen(str)); add_variable_to_tail(&argsinsert, new_variable(str, ECPGmake_simple_type(ECPGt_const, length, 0), 0), &no_indicator); @@ -98,7 +107,7 @@ ECPG: toplevel_stmtTransactionStmtLegacy block ECPG: stmtViewStmt rule | ECPGAllocateDescr { - fprintf(base_yyout,"ECPGallocate_desc(__LINE__, %s);",$1); + fprintf(base_yyout, "ECPGallocate_desc(__LINE__, %s);", $1); whenever_action(0); free($1); } @@ -118,11 +127,11 @@ ECPG: stmtViewStmt rule } | ECPGCursorStmt { - output_simple_statement($1, (strncmp($1, "ECPGset_var", strlen("ECPGset_var")) == 0) ? 4 : 0); + output_simple_statement($1, (strncmp($1, "ECPGset_var", strlen("ECPGset_var")) == 0) ? 4 : 0); } | ECPGDeallocateDescr { - fprintf(base_yyout,"ECPGdeallocate_desc(__LINE__, %s);",$1); + fprintf(base_yyout, "ECPGdeallocate_desc(__LINE__, %s);", $1); whenever_action(0); free($1); } @@ -152,7 +161,10 @@ ECPG: stmtViewStmt rule whenever_action(2); free($1); } - | ECPGExecuteImmediateStmt { output_statement($1, 0, ECPGst_exec_immediate); } + | ECPGExecuteImmediateStmt + { + output_statement($1, 0, ECPGst_exec_immediate); + } | ECPGFree { const char *con = connection ? connection : "NULL"; @@ -160,7 +172,7 @@ ECPG: stmtViewStmt rule if (strcmp($1, "all") == 0) fprintf(base_yyout, "{ ECPGdeallocate_all(__LINE__, %d, %s);", compat, con); else if ($1[0] == ':') - fprintf(base_yyout, "{ ECPGdeallocate(__LINE__, %d, %s, %s);", compat, con, $1+1); + fprintf(base_yyout, "{ ECPGdeallocate(__LINE__, %d, %s, %s);", compat, con, $1 + 1); else fprintf(base_yyout, "{ ECPGdeallocate(__LINE__, %d, %s, \"%s\");", compat, con, $1); @@ -244,13 +256,14 @@ ECPG: stmtViewStmt rule } ECPG: where_or_current_clauseWHERECURRENT_POFcursor_name block { - char *cursor_marker = $4[0] == ':' ? mm_strdup("$0") : $4; - $$ = cat_str(2,mm_strdup("where current of"), cursor_marker); + char *cursor_marker = $4[0] == ':' ? mm_strdup("$0") : $4; + + $$ = cat_str(2, mm_strdup("where current of"), cursor_marker); } ECPG: CopyStmtCOPYopt_binaryqualified_nameopt_column_listcopy_fromopt_programcopy_file_namecopy_delimiteropt_withcopy_optionswhere_clause addon - if (strcmp($6, "from") == 0 && - (strcmp($7, "stdin") == 0 || strcmp($7, "stdout") == 0)) - mmerror(PARSE_ERROR, ET_WARNING, "COPY FROM STDIN is not implemented"); + if (strcmp($6, "from") == 0 && + (strcmp($7, "stdin") == 0 || strcmp($7, "stdout") == 0)) + mmerror(PARSE_ERROR, ET_WARNING, "COPY FROM STDIN is not implemented"); ECPG: var_valueNumericOnly addon if ($1[0] == '$') { @@ -259,9 +272,9 @@ ECPG: var_valueNumericOnly addon } ECPG: fetch_argscursor_name addon struct cursor *ptr = add_additional_variables($1, false); - if (ptr -> connection) - connection = mm_strdup(ptr -> connection); + if (ptr->connection) + connection = mm_strdup(ptr->connection); if ($1[0] == ':') { free($1); @@ -269,9 +282,9 @@ ECPG: fetch_argscursor_name addon } ECPG: fetch_argsfrom_incursor_name addon struct cursor *ptr = add_additional_variables($2, false); - if (ptr -> connection) - connection = mm_strdup(ptr -> connection); + if (ptr->connection) + connection = mm_strdup(ptr->connection); if ($2[0] == ':') { free($2); @@ -283,9 +296,9 @@ ECPG: fetch_argsFIRST_Popt_from_incursor_name addon ECPG: fetch_argsLAST_Popt_from_incursor_name addon ECPG: fetch_argsALLopt_from_incursor_name addon struct cursor *ptr = add_additional_variables($3, false); - if (ptr -> connection) - connection = mm_strdup(ptr -> connection); + if (ptr->connection) + connection = mm_strdup(ptr->connection); if ($3[0] == ':') { free($3); @@ -293,9 +306,9 @@ ECPG: fetch_argsALLopt_from_incursor_name addon } ECPG: fetch_argsSignedIconstopt_from_incursor_name addon struct cursor *ptr = add_additional_variables($3, false); - if (ptr -> connection) - connection = mm_strdup(ptr -> connection); + if (ptr->connection) + connection = mm_strdup(ptr->connection); if ($3[0] == ':') { free($3); @@ -309,9 +322,9 @@ ECPG: fetch_argsSignedIconstopt_from_incursor_name addon ECPG: fetch_argsFORWARDALLopt_from_incursor_name addon ECPG: fetch_argsBACKWARDALLopt_from_incursor_name addon struct cursor *ptr = add_additional_variables($4, false); - if (ptr -> connection) - connection = mm_strdup(ptr -> connection); + if (ptr->connection) + connection = mm_strdup(ptr->connection); if ($4[0] == ':') { free($4); @@ -322,9 +335,9 @@ ECPG: fetch_argsRELATIVE_PSignedIconstopt_from_incursor_name addon ECPG: fetch_argsFORWARDSignedIconstopt_from_incursor_name addon ECPG: fetch_argsBACKWARDSignedIconstopt_from_incursor_name addon struct cursor *ptr = add_additional_variables($4, false); - if (ptr -> connection) - connection = mm_strdup(ptr -> connection); + if (ptr->connection) + connection = mm_strdup(ptr->connection); if ($4[0] == ':') { free($4); @@ -337,13 +350,14 @@ ECPG: fetch_argsBACKWARDSignedIconstopt_from_incursor_name addon } ECPG: cursor_namename rule | char_civar - { - char *curname = mm_alloc(strlen($1) + 2); - sprintf(curname, ":%s", $1); - free($1); - $1 = curname; - $$ = $1; - } + { + char *curname = mm_alloc(strlen($1) + 2); + + sprintf(curname, ":%s", $1); + free($1); + $1 = curname; + $$ = $1; + } ECPG: ExplainableStmtExecuteStmt block { $$ = $1.name; @@ -367,28 +381,31 @@ ECPG: ExecuteStmtEXECUTEprepared_nameexecute_param_clauseexecute_rest block } ECPG: ExecuteStmtCREATEOptTempTABLEcreate_as_targetASEXECUTEprepared_nameexecute_param_clauseopt_with_dataexecute_rest block { - $$.name = cat_str(8,mm_strdup("create"),$2,mm_strdup("table"),$4,mm_strdup("as execute"),$7,$8,$9); + $$.name = cat_str(8, mm_strdup("create"), $2, mm_strdup("table"), $4, mm_strdup("as execute"), $7, $8, $9); } ECPG: ExecuteStmtCREATEOptTempTABLEIF_PNOTEXISTScreate_as_targetASEXECUTEprepared_nameexecute_param_clauseopt_with_dataexecute_rest block { - $$.name = cat_str(8,mm_strdup("create"),$2,mm_strdup("table if not exists"),$7,mm_strdup("as execute"),$10,$11,$12); + $$.name = cat_str(8, mm_strdup("create"), $2, mm_strdup("table if not exists"), $7, mm_strdup("as execute"), $10, $11, $12); } ECPG: DeclareCursorStmtDECLAREcursor_namecursor_optionsCURSORopt_holdFORSelectStmt block { - struct cursor *ptr, *this; - char *cursor_marker = $2[0] == ':' ? mm_strdup("$0") : mm_strdup($2); - char *comment, *c1, *c2; - int (* strcmp_fn)(const char *, const char *) = (($2[0] == ':' || $2[0] == '"') ? strcmp : pg_strcasecmp); + struct cursor *ptr, + *this; + char *cursor_marker = $2[0] == ':' ? mm_strdup("$0") : mm_strdup($2); + char *comment, + *c1, + *c2; + int (*strcmp_fn) (const char *, const char *) = (($2[0] == ':' || $2[0] == '"') ? strcmp : pg_strcasecmp); - if (INFORMIX_MODE && pg_strcasecmp($2, "database") == 0) - mmfatal(PARSE_ERROR, "\"database\" cannot be used as cursor name in INFORMIX mode"); + if (INFORMIX_MODE && pg_strcasecmp($2, "database") == 0) + mmfatal(PARSE_ERROR, "\"database\" cannot be used as cursor name in INFORMIX mode"); for (ptr = cur; ptr != NULL; ptr = ptr->next) { if (strcmp_fn($2, ptr->name) == 0) { if ($2[0] == ':') - mmerror(PARSE_ERROR, ET_ERROR, "using variable \"%s\" in different declare statements is not supported", $2+1); + mmerror(PARSE_ERROR, ET_ERROR, "using variable \"%s\" in different declare statements is not supported", $2 + 1); else mmerror(PARSE_ERROR, ET_ERROR, "cursor \"%s\" is already defined", $2); } @@ -401,7 +418,7 @@ ECPG: DeclareCursorStmtDECLAREcursor_namecursor_optionsCURSORopt_holdFORSelectSt this->function = (current_function ? mm_strdup(current_function) : NULL); this->connection = connection ? mm_strdup(connection) : NULL; this->opened = false; - this->command = cat_str(7, mm_strdup("declare"), cursor_marker, $3, mm_strdup("cursor"), $5, mm_strdup("for"), $7); + this->command = cat_str(7, mm_strdup("declare"), cursor_marker, $3, mm_strdup("cursor"), $5, mm_strdup("for"), $7); this->argsinsert = argsinsert; this->argsinsert_oos = NULL; this->argsresult = argsresult; @@ -422,15 +439,15 @@ ECPG: DeclareCursorStmtDECLAREcursor_namecursor_optionsCURSORopt_holdFORSelectSt } ECPG: ClosePortalStmtCLOSEcursor_name block { - char *cursor_marker = $2[0] == ':' ? mm_strdup("$0") : $2; + char *cursor_marker = $2[0] == ':' ? mm_strdup("$0") : $2; struct cursor *ptr = NULL; - for (ptr = cur; ptr != NULL; ptr = ptr -> next) - { - if (strcmp($2, ptr -> name) == 0) - { - if (ptr -> connection) - connection = mm_strdup(ptr -> connection); + for (ptr = cur; ptr != NULL; ptr = ptr->next) + { + if (strcmp($2, ptr->name) == 0) + { + if (ptr->connection) + connection = mm_strdup(ptr->connection); break; } } @@ -444,15 +461,22 @@ ECPG: opt_hold block $$ = EMPTY; } ECPG: into_clauseINTOOptTempTableName block - { - FoundInto = 1; - $$= cat2_str(mm_strdup("into"), $2); - } - | ecpg_into { $$ = EMPTY; } + { + FoundInto = 1; + $$ = cat2_str(mm_strdup("into"), $2); + } + | ecpg_into + { + $$ = EMPTY; + } ECPG: TypenameSimpleTypenameopt_array_bounds block - { $$ = cat2_str($1, $2.str); } + { + $$ = cat2_str($1, $2.str); + } ECPG: TypenameSETOFSimpleTypenameopt_array_bounds block - { $$ = cat_str(3, mm_strdup("setof"), $2, $3.str); } + { + $$ = cat_str(3, mm_strdup("setof"), $2, $3.str); + } ECPG: opt_array_boundsopt_array_bounds'['']' block { $$.index1 = $1.index1; @@ -477,22 +501,24 @@ ECPG: opt_array_bounds { $$.index1 = mm_strdup("-1"); $$.index2 = mm_strdup("-1"); - $$.str= EMPTY; + $$.str = EMPTY; } ECPG: IconstICONST block - { $$ = make_name(); } + { + $$ = make_name(); + } ECPG: AexprConstNULL_P rule - | civar { $$ = $1; } - | civarind { $$ = $1; } + | civar { $$ = $1; } + | civarind { $$ = $1; } ECPG: ColIdcol_name_keyword rule - | ECPGKeywords { $$ = $1; } - | ECPGCKeywords { $$ = $1; } - | CHAR_P { $$ = mm_strdup("char"); } - | VALUES { $$ = mm_strdup("values"); } + | ECPGKeywords { $$ = $1; } + | ECPGCKeywords { $$ = $1; } + | CHAR_P { $$ = mm_strdup("char"); } + | VALUES { $$ = mm_strdup("values"); } ECPG: type_function_nametype_func_name_keyword rule - | ECPGKeywords { $$ = $1; } - | ECPGTypeName { $$ = $1; } - | ECPGCKeywords { $$ = $1; } + | ECPGKeywords { $$ = $1; } + | ECPGTypeName { $$ = $1; } + | ECPGCKeywords { $$ = $1; } ECPG: VariableShowStmtSHOWALL block { mmerror(PARSE_ERROR, ET_ERROR, "SHOW ALL is not implemented"); @@ -505,73 +531,81 @@ ECPG: FetchStmtMOVEfetch_args rule } | FETCH FORWARD cursor_name opt_ecpg_fetch_into { - char *cursor_marker = $3[0] == ':' ? mm_strdup("$0") : $3; + char *cursor_marker = $3[0] == ':' ? mm_strdup("$0") : $3; struct cursor *ptr = add_additional_variables($3, false); - if (ptr -> connection) - connection = mm_strdup(ptr -> connection); + + if (ptr->connection) + connection = mm_strdup(ptr->connection); $$ = cat_str(2, mm_strdup("fetch forward"), cursor_marker); } | FETCH FORWARD from_in cursor_name opt_ecpg_fetch_into { - char *cursor_marker = $4[0] == ':' ? mm_strdup("$0") : $4; + char *cursor_marker = $4[0] == ':' ? mm_strdup("$0") : $4; struct cursor *ptr = add_additional_variables($4, false); - if (ptr -> connection) - connection = mm_strdup(ptr -> connection); + + if (ptr->connection) + connection = mm_strdup(ptr->connection); $$ = cat_str(2, mm_strdup("fetch forward from"), cursor_marker); } | FETCH BACKWARD cursor_name opt_ecpg_fetch_into { - char *cursor_marker = $3[0] == ':' ? mm_strdup("$0") : $3; + char *cursor_marker = $3[0] == ':' ? mm_strdup("$0") : $3; struct cursor *ptr = add_additional_variables($3, false); - if (ptr -> connection) - connection = mm_strdup(ptr -> connection); + + if (ptr->connection) + connection = mm_strdup(ptr->connection); $$ = cat_str(2, mm_strdup("fetch backward"), cursor_marker); } | FETCH BACKWARD from_in cursor_name opt_ecpg_fetch_into { - char *cursor_marker = $4[0] == ':' ? mm_strdup("$0") : $4; + char *cursor_marker = $4[0] == ':' ? mm_strdup("$0") : $4; struct cursor *ptr = add_additional_variables($4, false); - if (ptr -> connection) - connection = mm_strdup(ptr -> connection); + + if (ptr->connection) + connection = mm_strdup(ptr->connection); $$ = cat_str(2, mm_strdup("fetch backward from"), cursor_marker); } | MOVE FORWARD cursor_name { - char *cursor_marker = $3[0] == ':' ? mm_strdup("$0") : $3; + char *cursor_marker = $3[0] == ':' ? mm_strdup("$0") : $3; struct cursor *ptr = add_additional_variables($3, false); - if (ptr -> connection) - connection = mm_strdup(ptr -> connection); + + if (ptr->connection) + connection = mm_strdup(ptr->connection); $$ = cat_str(2, mm_strdup("move forward"), cursor_marker); } | MOVE FORWARD from_in cursor_name { - char *cursor_marker = $4[0] == ':' ? mm_strdup("$0") : $4; + char *cursor_marker = $4[0] == ':' ? mm_strdup("$0") : $4; struct cursor *ptr = add_additional_variables($4, false); - if (ptr -> connection) - connection = mm_strdup(ptr -> connection); + + if (ptr->connection) + connection = mm_strdup(ptr->connection); $$ = cat_str(2, mm_strdup("move forward from"), cursor_marker); } | MOVE BACKWARD cursor_name { - char *cursor_marker = $3[0] == ':' ? mm_strdup("$0") : $3; + char *cursor_marker = $3[0] == ':' ? mm_strdup("$0") : $3; struct cursor *ptr = add_additional_variables($3, false); - if (ptr -> connection) - connection = mm_strdup(ptr -> connection); + + if (ptr->connection) + connection = mm_strdup(ptr->connection); $$ = cat_str(2, mm_strdup("move backward"), cursor_marker); } | MOVE BACKWARD from_in cursor_name { - char *cursor_marker = $4[0] == ':' ? mm_strdup("$0") : $4; + char *cursor_marker = $4[0] == ':' ? mm_strdup("$0") : $4; struct cursor *ptr = add_additional_variables($4, false); - if (ptr -> connection) - connection = mm_strdup(ptr -> connection); + + if (ptr->connection) + connection = mm_strdup(ptr->connection); $$ = cat_str(2, mm_strdup("move backward from"), cursor_marker); } @@ -581,4 +615,7 @@ ECPG: limit_clauseLIMITselect_limit_value','select_offset_value block $$ = cat_str(4, mm_strdup("limit"), $2, mm_strdup(","), $4); } ECPG: SignedIconstIconst rule - | civar { $$ = $1; } + | civar + { + $$ = $1; + } diff --git a/src/interfaces/ecpg/preproc/ecpg.header b/src/interfaces/ecpg/preproc/ecpg.header index 3790a601d1..28e1b2aac4 100644 --- a/src/interfaces/ecpg/preproc/ecpg.header +++ b/src/interfaces/ecpg/preproc/ecpg.header @@ -37,24 +37,25 @@ extern int base_yynerrs; /* * Variables containing simple states. */ -int struct_level = 0; -int braces_open; /* brace level counter */ -char *current_function; -int ecpg_internal_var = 0; -char *connection = NULL; -char *input_filename = NULL; +int struct_level = 0; +int braces_open; /* brace level counter */ +char *current_function; +int ecpg_internal_var = 0; +char *connection = NULL; +char *input_filename = NULL; static int FoundInto = 0; static int initializer = 0; static int pacounter = 1; -static char pacounter_buffer[sizeof(int) * CHAR_BIT * 10 / 3]; /* a rough guess at the size we need */ +static char pacounter_buffer[sizeof(int) * CHAR_BIT * 10 / 3]; /* a rough guess at the + * size we need */ static struct this_type actual_type[STRUCT_DEPTH]; static char *actual_startline[STRUCT_DEPTH]; static int varchar_counter = 1; static int bytea_counter = 1; /* temporarily store struct members while creating the data structure */ -struct ECPGstruct_member *struct_member_list[STRUCT_DEPTH] = { NULL }; +struct ECPGstruct_member *struct_member_list[STRUCT_DEPTH] = {NULL}; /* also store struct type so we can do a sizeof() later */ static char *ECPGstruct_sizeof = NULL; @@ -82,7 +83,7 @@ vmmerror(int error_code, enum errortype type, const char *error, va_list ap) fprintf(stderr, "%s:%d: ", input_filename, base_yylineno); - switch(type) + switch (type) { case ET_WARNING: fprintf(stderr, _("WARNING: ")); @@ -96,7 +97,7 @@ vmmerror(int error_code, enum errortype type, const char *error, va_list ap) fprintf(stderr, "\n"); - switch(type) + switch (type) { case ET_WARNING: break; @@ -107,7 +108,7 @@ vmmerror(int error_code, enum errortype type, const char *error, va_list ap) } void -mmerror(int error_code, enum errortype type, const char *error, ...) +mmerror(int error_code, enum errortype type, const char *error,...) { va_list ap; @@ -117,7 +118,7 @@ mmerror(int error_code, enum errortype type, const char *error, ...) } void -mmfatal(int error_code, const char *error, ...) +mmfatal(int error_code, const char *error,...) { va_list ap; @@ -142,7 +143,7 @@ mmfatal(int error_code, const char *error, ...) static char * cat2_str(char *str1, char *str2) { - char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) + 2); + char *res_str = (char *) mm_alloc(strlen(str1) + strlen(str2) + 2); strcpy(res_str, str1); if (strlen(str1) != 0 && strlen(str2) != 0) @@ -154,11 +155,11 @@ cat2_str(char *str1, char *str2) } static char * -cat_str(int count, ...) +cat_str(int count,...) { va_list args; int i; - char *res_str; + char *res_str; va_start(args, count); @@ -176,7 +177,7 @@ cat_str(int count, ...) static char * make2_str(char *str1, char *str2) { - char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) + 1); + char *res_str = (char *) mm_alloc(strlen(str1) + strlen(str2) + 1); strcpy(res_str, str1); strcat(res_str, str2); @@ -188,7 +189,7 @@ make2_str(char *str1, char *str2) static char * make3_str(char *str1, char *str2, char *str3) { - char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) +strlen(str3) + 1); + char *res_str = (char *) mm_alloc(strlen(str1) + strlen(str2) + strlen(str3) + 1); strcpy(res_str, str1); strcat(res_str, str2); @@ -210,13 +211,18 @@ static char * create_questionmarks(char *name, bool array) { struct variable *p = find_variable(name); - int count; - char *result = EMPTY; + int count; + char *result = EMPTY; - /* In case we have a struct, we have to print as many "?" as there are attributes in the struct + /* + * In case we have a struct, we have to print as many "?" as there are + * attributes in the struct + * * An array is only allowed together with an element argument - * This is essentially only used for inserts, but using a struct as input parameter is an error anywhere else - * so we don't have to worry here. */ + * + * This is essentially only used for inserts, but using a struct as input + * parameter is an error anywhere else so we don't have to worry here. + */ if (p->type->type == ECPGt_struct || (array && p->type->type == ECPGt_array && p->type->u.element->type == ECPGt_struct)) { @@ -227,12 +233,12 @@ create_questionmarks(char *name, bool array) else m = p->type->u.element->u.members; - for (count = 0; m != NULL; m=m->next, count++); + for (count = 0; m != NULL; m = m->next, count++); } else count = 1; - for (; count > 0; count --) + for (; count > 0; count--) { sprintf(pacounter_buffer, "$%d", pacounter++); result = cat_str(3, result, mm_strdup(pacounter_buffer), mm_strdup(" , ")); @@ -240,42 +246,45 @@ create_questionmarks(char *name, bool array) /* removed the trailing " ," */ - result[strlen(result)-3] = '\0'; + result[strlen(result) - 3] = '\0'; return result; } static char * adjust_outofscope_cursor_vars(struct cursor *cur) { - /* Informix accepts DECLARE with variables that are out of scope when OPEN is called. - * For instance you can DECLARE a cursor in one function, and OPEN/FETCH/CLOSE - * it in another functions. This is very useful for e.g. event-driver programming, - * but may also lead to dangerous programming. The limitation when this is allowed - * and doesn't cause problems have to be documented, like the allocated variables - * must not be realloc()'ed. + /* + * Informix accepts DECLARE with variables that are out of scope when OPEN + * is called. For instance you can DECLARE a cursor in one function, and + * OPEN/FETCH/CLOSE it in another functions. This is very useful for e.g. + * event-driver programming, but may also lead to dangerous programming. + * The limitation when this is allowed and doesn't cause problems have to + * be documented, like the allocated variables must not be realloc()'ed. * - * We have to change the variables to our own struct and just store the pointer - * instead of the variable. Do it only for local variables, not for globals. + * We have to change the variables to our own struct and just store the + * pointer instead of the variable. Do it only for local variables, not + * for globals. */ - char *result = EMPTY; - int insert; + char *result = EMPTY; + int insert; for (insert = 1; insert >= 0; insert--) { struct arguments *list; struct arguments *ptr; struct arguments *newlist = NULL; - struct variable *newvar, *newind; + struct variable *newvar, + *newind; list = (insert ? cur->argsinsert : cur->argsresult); for (ptr = list; ptr != NULL; ptr = ptr->next) { - char var_text[20]; - char *original_var; - bool skip_set_var = false; - bool var_ptr = false; + char var_text[20]; + char *original_var; + bool skip_set_var = false; + bool var_ptr = false; /* change variable name to "ECPGget_var()" */ original_var = ptr->variable->name; @@ -350,10 +359,10 @@ adjust_outofscope_cursor_vars(struct cursor *cur) || ptr->variable->type->u.element->type == ECPGt_union) { newvar = new_variable(cat_str(5, mm_strdup("(*("), - mm_strdup(ptr->variable->type->u.element->type_name), - mm_strdup(" *)(ECPGget_var("), - mm_strdup(var_text), - mm_strdup(")")), + mm_strdup(ptr->variable->type->u.element->type_name), + mm_strdup(" *)(ECPGget_var("), + mm_strdup(var_text), + mm_strdup(")")), ECPGmake_struct_type(ptr->variable->type->u.element->u.members, ptr->variable->type->u.element->type, ptr->variable->type->u.element->type_name, @@ -387,7 +396,10 @@ adjust_outofscope_cursor_vars(struct cursor *cur) var_ptr = true; } - /* create call to "ECPGset_var(, , . )" */ + /* + * create call to "ECPGset_var(, , . + * )" + */ if (!skip_set_var) { sprintf(var_text, "%d, %s", ecpg_internal_var++, var_ptr ? "&(" : "("); @@ -396,7 +408,10 @@ adjust_outofscope_cursor_vars(struct cursor *cur) mm_strdup("), __LINE__);\n")); } - /* now the indicator if there is one and it's not a global variable */ + /* + * now the indicator if there is one and it's not a global + * variable + */ if ((ptr->indicator->type->type == ECPGt_NO_INDICATOR) || (ptr->indicator->brace_level == 0)) { newind = ptr->indicator; @@ -412,10 +427,10 @@ adjust_outofscope_cursor_vars(struct cursor *cur) || ptr->indicator->type->type == ECPGt_union) { newind = new_variable(cat_str(5, mm_strdup("(*("), - mm_strdup(ptr->indicator->type->type_name), - mm_strdup(" *)(ECPGget_var("), - mm_strdup(var_text), - mm_strdup(")")), + mm_strdup(ptr->indicator->type->type_name), + mm_strdup(" *)(ECPGget_var("), + mm_strdup(var_text), + mm_strdup(")")), ECPGmake_struct_type(ptr->indicator->type->u.members, ptr->indicator->type->type, ptr->indicator->type->type_name, @@ -429,10 +444,10 @@ adjust_outofscope_cursor_vars(struct cursor *cur) || ptr->indicator->type->u.element->type == ECPGt_union) { newind = new_variable(cat_str(5, mm_strdup("(*("), - mm_strdup(ptr->indicator->type->u.element->type_name), - mm_strdup(" *)(ECPGget_var("), - mm_strdup(var_text), - mm_strdup(")")), + mm_strdup(ptr->indicator->type->u.element->type_name), + mm_strdup(" *)(ECPGget_var("), + mm_strdup(var_text), + mm_strdup(")")), ECPGmake_struct_type(ptr->indicator->type->u.element->u.members, ptr->indicator->type->u.element->type, ptr->indicator->type->u.element->type_name, @@ -476,7 +491,10 @@ adjust_outofscope_cursor_vars(struct cursor *cur) var_ptr = true; } - /* create call to "ECPGset_var(, . )" */ + /* + * create call to "ECPGset_var(, . )" + */ sprintf(var_text, "%d, %s", ecpg_internal_var++, var_ptr ? "&(" : "("); result = cat_str(5, result, mm_strdup("ECPGset_var("), mm_strdup(var_text), mm_strdup(original_var), @@ -505,9 +523,9 @@ add_additional_variables(char *name, bool insert) { struct cursor *ptr; struct arguments *p; - int (* strcmp_fn)(const char *, const char *) = ((name[0] == ':' || name[0] == '"') ? strcmp : pg_strcasecmp); + int (*strcmp_fn) (const char *, const char *) = ((name[0] == ':' || name[0] == '"') ? strcmp : pg_strcasecmp); - for (ptr = cur; ptr != NULL; ptr=ptr->next) + for (ptr = cur; ptr != NULL; ptr = ptr->next) { if (strcmp_fn(ptr->name, name) == 0) break; @@ -521,8 +539,12 @@ add_additional_variables(char *name, bool insert) if (insert) { - /* add all those input variables that were given earlier - * note that we have to append here but have to keep the existing order */ + /* + * add all those input variables that were given earlier + * + * note that we have to append here but have to keep the existing + * order + */ for (p = (SAMEFUNC(ptr) ? ptr->argsinsert : ptr->argsinsert_oos); p; p = p->next) add_variable_to_tail(&argsinsert, p->variable, p->indicator); } @@ -539,7 +561,8 @@ add_typedef(char *name, char *dimension, char *length, enum ECPGttype type_enum, char *type_dimension, char *type_index, int initializer, int array) { /* add entry to list */ - struct typedefs *ptr, *this; + struct typedefs *ptr, + *this; if ((type_enum == ECPGt_struct || type_enum == ECPGt_union) && @@ -570,7 +593,7 @@ add_typedef(char *name, char *dimension, char *length, enum ECPGttype type_enum, this->type->type_index = length; /* length of string */ this->type->type_sizeof = ECPGstruct_sizeof; this->struct_member_list = (type_enum == ECPGt_struct || type_enum == ECPGt_union) ? - ECPGstruct_member_dup(struct_member_list[struct_level]) : NULL; + ECPGstruct_member_dup(struct_member_list[struct_level]) : NULL; if (type_enum != ECPGt_varchar && type_enum != ECPGt_bytea && @@ -593,15 +616,16 @@ static bool check_declared_list(const char *name) { struct declared_list *ptr = NULL; - for (ptr = g_declared_list; ptr != NULL; ptr = ptr -> next) + + for (ptr = g_declared_list; ptr != NULL; ptr = ptr->next) { if (!ptr->connection) continue; - if (strcmp(name, ptr -> name) == 0) + if (strcmp(name, ptr->name) == 0) { if (connection && strcmp(ptr->connection, connection) != 0) mmerror(PARSE_ERROR, ET_WARNING, "connection %s is overwritten with %s by DECLARE statement %s", connection, ptr->connection, name); - connection = mm_strdup(ptr -> connection); + connection = mm_strdup(ptr->connection); return true; } } @@ -614,18 +638,18 @@ check_declared_list(const char *name) %locations %union { - double dval; - char *str; - int ival; - struct when action; - struct index index; - int tagname; - struct this_type type; - enum ECPGttype type_enum; - enum ECPGdtype dtype_enum; - struct fetch_desc descriptor; - struct su_symbol struct_union; - struct prep prep; - struct exec exec; - struct describe describe; + double dval; + char *str; + int ival; + struct when action; + struct index index; + int tagname; + struct this_type type; + enum ECPGttype type_enum; + enum ECPGdtype dtype_enum; + struct fetch_desc descriptor; + struct su_symbol struct_union; + struct prep prep; + struct exec exec; + struct describe describe; } diff --git a/src/interfaces/ecpg/preproc/ecpg.trailer b/src/interfaces/ecpg/preproc/ecpg.trailer index b2aa44f36d..b6233e5e53 100644 --- a/src/interfaces/ecpg/preproc/ecpg.trailer +++ b/src/interfaces/ecpg/preproc/ecpg.trailer @@ -1,465 +1,610 @@ /* src/interfaces/ecpg/preproc/ecpg.trailer */ -statements: /*EMPTY*/ - | statements statement - ; +statements: /* EMPTY */ + | statements statement + ; statement: ecpgstart at toplevel_stmt ';' - { - if (connection) - free(connection); - connection = NULL; - } - | ecpgstart toplevel_stmt ';' - { - if (connection) - free(connection); - connection = NULL; - } - | ecpgstart ECPGVarDeclaration - { - fprintf(base_yyout, "%s", $2); - free($2); - output_line_number(); - } - | ECPGDeclaration - | c_thing { fprintf(base_yyout, "%s", $1); free($1); } - | CPP_LINE { fprintf(base_yyout, "%s", $1); free($1); } - | '{' { braces_open++; fputs("{", base_yyout); } - | '}' + { + if (connection) + free(connection); + connection = NULL; + } + | ecpgstart toplevel_stmt ';' + { + if (connection) + free(connection); + connection = NULL; + } + | ecpgstart ECPGVarDeclaration + { + fprintf(base_yyout, "%s", $2); + free($2); + output_line_number(); + } + | ECPGDeclaration + | c_thing + { + fprintf(base_yyout, "%s", $1); + free($1); + } + | CPP_LINE + { + fprintf(base_yyout, "%s", $1); + free($1); + } + | '{' + { + braces_open++; + fputs("{", base_yyout); + } + | '}' + { + remove_typedefs(braces_open); + remove_variables(braces_open--); + if (braces_open == 0) { - remove_typedefs(braces_open); - remove_variables(braces_open--); - if (braces_open == 0) - { - free(current_function); - current_function = NULL; - } - fputs("}", base_yyout); + free(current_function); + current_function = NULL; } - ; + fputs("}", base_yyout); + } + ; -CreateAsStmt: CREATE OptTemp TABLE create_as_target AS {FoundInto = 0;} SelectStmt opt_with_data - { - if (FoundInto == 1) - mmerror(PARSE_ERROR, ET_ERROR, "CREATE TABLE AS cannot specify INTO"); +CreateAsStmt: CREATE OptTemp TABLE create_as_target AS + { + FoundInto = 0; + } SelectStmt opt_with_data + { + if (FoundInto == 1) + mmerror(PARSE_ERROR, ET_ERROR, "CREATE TABLE AS cannot specify INTO"); - $$ = cat_str(7, mm_strdup("create"), $2, mm_strdup("table"), $4, mm_strdup("as"), $7, $8); - } - | CREATE OptTemp TABLE IF_P NOT EXISTS create_as_target AS {FoundInto = 0;} SelectStmt opt_with_data - { - if (FoundInto == 1) - mmerror(PARSE_ERROR, ET_ERROR, "CREATE TABLE AS cannot specify INTO"); + $$ = cat_str(7, mm_strdup("create"), $2, mm_strdup("table"), $4, mm_strdup("as"), $7, $8); + } + | CREATE OptTemp TABLE IF_P NOT EXISTS create_as_target AS + { + FoundInto = 0; + } SelectStmt opt_with_data + { + if (FoundInto == 1) + mmerror(PARSE_ERROR, ET_ERROR, "CREATE TABLE AS cannot specify INTO"); - $$ = cat_str(7, mm_strdup("create"), $2, mm_strdup("table if not exists"), $7, mm_strdup("as"), $10, $11); - } - ; + $$ = cat_str(7, mm_strdup("create"), $2, mm_strdup("table if not exists"), $7, mm_strdup("as"), $10, $11); + } + ; at: AT connection_object - { - connection = $2; - /* - * Do we have a variable as connection target? Remove the variable - * from the variable list or else it will be used twice. - */ - if (argsinsert != NULL) - argsinsert = NULL; - } - ; + { + connection = $2; + + /* + * Do we have a variable as connection target? Remove the variable + * from the variable list or else it will be used twice. + */ + if (argsinsert != NULL) + argsinsert = NULL; + } + ; /* * the exec sql connect statement: connect to the given database */ ECPGConnect: SQL_CONNECT TO connection_target opt_connection_name opt_user - { $$ = cat_str(5, $3, mm_strdup(","), $5, mm_strdup(","), $4); } - | SQL_CONNECT TO DEFAULT - { $$ = mm_strdup("NULL, NULL, NULL, \"DEFAULT\""); } - /* also allow ORACLE syntax */ - | SQL_CONNECT ora_user - { $$ = cat_str(3, mm_strdup("NULL,"), $2, mm_strdup(", NULL")); } - | DATABASE connection_target - { $$ = cat2_str($2, mm_strdup(", NULL, NULL, NULL")); } - ; + { + $$ = cat_str(5, $3, mm_strdup(","), $5, mm_strdup(","), $4); + } + | SQL_CONNECT TO DEFAULT + { + $$ = mm_strdup("NULL, NULL, NULL, \"DEFAULT\""); + } + /* also allow ORACLE syntax */ + | SQL_CONNECT ora_user + { + $$ = cat_str(3, mm_strdup("NULL,"), $2, mm_strdup(", NULL")); + } + | DATABASE connection_target + { + $$ = cat2_str($2, mm_strdup(", NULL, NULL, NULL")); + } + ; connection_target: opt_database_name opt_server opt_port - { - /* old style: dbname[@server][:port] */ - if (strlen($2) > 0 && *($2) != '@') - mmerror(PARSE_ERROR, ET_ERROR, "expected \"@\", found \"%s\"", $2); + { + /* old style: dbname[@server][:port] */ + if (strlen($2) > 0 && *($2) != '@') + mmerror(PARSE_ERROR, ET_ERROR, "expected \"@\", found \"%s\"", $2); - /* C strings need to be handled differently */ - if ($1[0] == '\"') - $$ = $1; - else - $$ = make3_str(mm_strdup("\""), make3_str($1, $2, $3), mm_strdup("\"")); - } - | db_prefix ':' server opt_port '/' opt_database_name opt_options - { - /* new style: :postgresql://server[:port][/dbname] */ - if (strncmp($1, "unix:postgresql", strlen("unix:postgresql")) != 0 && strncmp($1, "tcp:postgresql", strlen("tcp:postgresql")) != 0) - mmerror(PARSE_ERROR, ET_ERROR, "only protocols \"tcp\" and \"unix\" and database type \"postgresql\" are supported"); - - if (strncmp($3, "//", strlen("//")) != 0) - mmerror(PARSE_ERROR, ET_ERROR, "expected \"://\", found \"%s\"", $3); - - if (strncmp($1, "unix", strlen("unix")) == 0 && - strncmp($3 + strlen("//"), "localhost", strlen("localhost")) != 0 && - strncmp($3 + strlen("//"), "127.0.0.1", strlen("127.0.0.1")) != 0) - mmerror(PARSE_ERROR, ET_ERROR, "Unix-domain sockets only work on \"localhost\" but not on \"%s\"", $3 + strlen("//")); - - $$ = make3_str(make3_str(mm_strdup("\""), $1, mm_strdup(":")), $3, make3_str(make3_str($4, mm_strdup("/"), $6), $7, mm_strdup("\""))); - } - | char_variable - { + /* C strings need to be handled differently */ + if ($1[0] == '\"') $$ = $1; - } - | ecpg_sconst - { - /* We can only process double quoted strings not single quotes ones, - * so we change the quotes. - * Note, that the rule for ecpg_sconst adds these single quotes. */ - $1[0] = '\"'; - $1[strlen($1)-1] = '\"'; - $$ = $1; - } - ; + else + $$ = make3_str(mm_strdup("\""), make3_str($1, $2, $3), mm_strdup("\"")); + } + | db_prefix ':' server opt_port '/' opt_database_name opt_options + { + /* new style: :postgresql://server[:port][/dbname] */ + if (strncmp($1, "unix:postgresql", strlen("unix:postgresql")) != 0 && strncmp($1, "tcp:postgresql", strlen("tcp:postgresql")) != 0) + mmerror(PARSE_ERROR, ET_ERROR, "only protocols \"tcp\" and \"unix\" and database type \"postgresql\" are supported"); -opt_database_name: name { $$ = $1; } - | /*EMPTY*/ { $$ = EMPTY; } - ; + if (strncmp($3, "//", strlen("//")) != 0) + mmerror(PARSE_ERROR, ET_ERROR, "expected \"://\", found \"%s\"", $3); + + if (strncmp($1, "unix", strlen("unix")) == 0 && + strncmp($3 + strlen("//"), "localhost", strlen("localhost")) != 0 && + strncmp($3 + strlen("//"), "127.0.0.1", strlen("127.0.0.1")) != 0) + mmerror(PARSE_ERROR, ET_ERROR, "Unix-domain sockets only work on \"localhost\" but not on \"%s\"", $3 + strlen("//")); + + $$ = make3_str(make3_str(mm_strdup("\""), $1, mm_strdup(":")), $3, make3_str(make3_str($4, mm_strdup("/"), $6), $7, mm_strdup("\""))); + } + | char_variable + { + $$ = $1; + } + | ecpg_sconst + { + /* + * We can only process double quoted strings not single quotes ones, + * so we change the quotes. Note, that the rule for ecpg_sconst adds + * these single quotes. + */ + $1[0] = '\"'; + $1[strlen($1) - 1] = '\"'; + $$ = $1; + } + ; + +opt_database_name: name + { + $$ = $1; + } + | /* EMPTY */ + { + $$ = EMPTY; + } + ; db_prefix: ecpg_ident cvariable - { - if (strcmp($2, "postgresql") != 0 && strcmp($2, "postgres") != 0) - mmerror(PARSE_ERROR, ET_ERROR, "expected \"postgresql\", found \"%s\"", $2); + { + if (strcmp($2, "postgresql") != 0 && strcmp($2, "postgres") != 0) + mmerror(PARSE_ERROR, ET_ERROR, "expected \"postgresql\", found \"%s\"", $2); - if (strcmp($1, "tcp") != 0 && strcmp($1, "unix") != 0) - mmerror(PARSE_ERROR, ET_ERROR, "invalid connection type: %s", $1); + if (strcmp($1, "tcp") != 0 && strcmp($1, "unix") != 0) + mmerror(PARSE_ERROR, ET_ERROR, "invalid connection type: %s", $1); - $$ = make3_str($1, mm_strdup(":"), $2); - } - ; + $$ = make3_str($1, mm_strdup(":"), $2); + } + ; server: Op server_name - { - if (strcmp($1, "@") != 0 && strcmp($1, "//") != 0) - mmerror(PARSE_ERROR, ET_ERROR, "expected \"@\" or \"://\", found \"%s\"", $1); + { + if (strcmp($1, "@") != 0 && strcmp($1, "//") != 0) + mmerror(PARSE_ERROR, ET_ERROR, "expected \"@\" or \"://\", found \"%s\"", $1); - $$ = make2_str($1, $2); - } - ; + $$ = make2_str($1, $2); + } + ; -opt_server: server { $$ = $1; } - | /*EMPTY*/ { $$ = EMPTY; } - ; +opt_server: server + { + $$ = $1; + } + | /* EMPTY */ + { + $$ = EMPTY; + } + ; -server_name: ColId { $$ = $1; } - | ColId '.' server_name { $$ = make3_str($1, mm_strdup("."), $3); } - | IP { $$ = make_name(); } - ; +server_name: ColId + { + $$ = $1; + } + | ColId '.' server_name + { + $$ = make3_str($1, mm_strdup("."), $3); + } + | IP + { + $$ = make_name(); + } + ; -opt_port: ':' Iconst { $$ = make2_str(mm_strdup(":"), $2); } - | /*EMPTY*/ { $$ = EMPTY; } - ; +opt_port: ':' Iconst + { + $$ = make2_str(mm_strdup(":"), $2); + } + | /* EMPTY */ + { + $$ = EMPTY; + } + ; -opt_connection_name: AS connection_object { $$ = $2; } - | /*EMPTY*/ { $$ = mm_strdup("NULL"); } - ; +opt_connection_name: AS connection_object + { + $$ = $2; + } + | /* EMPTY */ + { + $$ = mm_strdup("NULL"); + } + ; -opt_user: USER ora_user { $$ = $2; } - | /*EMPTY*/ { $$ = mm_strdup("NULL, NULL"); } - ; +opt_user: USER ora_user + { + $$ = $2; + } + | /* EMPTY */ + { + $$ = mm_strdup("NULL, NULL"); + } + ; ora_user: user_name - { $$ = cat2_str($1, mm_strdup(", NULL")); } - | user_name '/' user_name - { $$ = cat_str(3, $1, mm_strdup(","), $3); } - | user_name SQL_IDENTIFIED BY user_name - { $$ = cat_str(3, $1, mm_strdup(","), $4); } - | user_name USING user_name - { $$ = cat_str(3, $1, mm_strdup(","), $3); } - ; + { + $$ = cat2_str($1, mm_strdup(", NULL")); + } + | user_name '/' user_name + { + $$ = cat_str(3, $1, mm_strdup(","), $3); + } + | user_name SQL_IDENTIFIED BY user_name + { + $$ = cat_str(3, $1, mm_strdup(","), $4); + } + | user_name USING user_name + { + $$ = cat_str(3, $1, mm_strdup(","), $3); + } + ; user_name: RoleId - { - if ($1[0] == '\"') - $$ = $1; - else - $$ = make3_str(mm_strdup("\""), $1, mm_strdup("\"")); - } - | ecpg_sconst - { - if ($1[0] == '\"') - $$ = $1; - else - $$ = make3_str(mm_strdup("\""), $1, mm_strdup("\"")); - } - | civar - { - enum ECPGttype type = argsinsert->variable->type->type; + { + if ($1[0] == '\"') + $$ = $1; + else + $$ = make3_str(mm_strdup("\""), $1, mm_strdup("\"")); + } + | ecpg_sconst + { + if ($1[0] == '\"') + $$ = $1; + else + $$ = make3_str(mm_strdup("\""), $1, mm_strdup("\"")); + } + | civar + { + enum ECPGttype type = argsinsert->variable->type->type; - /* if array see what's inside */ - if (type == ECPGt_array) - type = argsinsert->variable->type->u.element->type; + /* if array see what's inside */ + if (type == ECPGt_array) + type = argsinsert->variable->type->u.element->type; - /* handle varchars */ - if (type == ECPGt_varchar) - $$ = make2_str(mm_strdup(argsinsert->variable->name), mm_strdup(".arr")); - else - $$ = mm_strdup(argsinsert->variable->name); - } - ; + /* handle varchars */ + if (type == ECPGt_varchar) + $$ = make2_str(mm_strdup(argsinsert->variable->name), mm_strdup(".arr")); + else + $$ = mm_strdup(argsinsert->variable->name); + } + ; char_variable: cvariable + { + /* check if we have a string variable */ + struct variable *p = find_variable($1); + enum ECPGttype type = p->type->type; + + /* If we have just one character this is not a string */ + if (atol(p->type->size) == 1) + mmerror(PARSE_ERROR, ET_ERROR, "invalid data type"); + else { - /* check if we have a string variable */ - struct variable *p = find_variable($1); - enum ECPGttype type = p->type->type; + /* if array see what's inside */ + if (type == ECPGt_array) + type = p->type->u.element->type; - /* If we have just one character this is not a string */ - if (atol(p->type->size) == 1) - mmerror(PARSE_ERROR, ET_ERROR, "invalid data type"); - else + switch (type) { - /* if array see what's inside */ - if (type == ECPGt_array) - type = p->type->u.element->type; - - switch (type) - { - case ECPGt_char: - case ECPGt_unsigned_char: - case ECPGt_string: - $$ = $1; - break; - case ECPGt_varchar: - $$ = make2_str($1, mm_strdup(".arr")); - break; - default: - mmerror(PARSE_ERROR, ET_ERROR, "invalid data type"); - $$ = $1; - break; - } + case ECPGt_char: + case ECPGt_unsigned_char: + case ECPGt_string: + $$ = $1; + break; + case ECPGt_varchar: + $$ = make2_str($1, mm_strdup(".arr")); + break; + default: + mmerror(PARSE_ERROR, ET_ERROR, "invalid data type"); + $$ = $1; + break; } } - ; + } + ; opt_options: Op connect_options - { - if (strlen($1) == 0) - mmerror(PARSE_ERROR, ET_ERROR, "incomplete statement"); + { + if (strlen($1) == 0) + mmerror(PARSE_ERROR, ET_ERROR, "incomplete statement"); - if (strcmp($1, "?") != 0) - mmerror(PARSE_ERROR, ET_ERROR, "unrecognized token \"%s\"", $1); + if (strcmp($1, "?") != 0) + mmerror(PARSE_ERROR, ET_ERROR, "unrecognized token \"%s\"", $1); - $$ = make2_str(mm_strdup("?"), $2); - } - | /*EMPTY*/ { $$ = EMPTY; } - ; + $$ = make2_str(mm_strdup("?"), $2); + } + | /* EMPTY */ + { + $$ = EMPTY; + } + ; -connect_options: ColId opt_opt_value - { - $$ = make2_str($1, $2); - } - | ColId opt_opt_value Op connect_options - { - if (strlen($3) == 0) - mmerror(PARSE_ERROR, ET_ERROR, "incomplete statement"); +connect_options: ColId opt_opt_value + { + $$ = make2_str($1, $2); + } + | ColId opt_opt_value Op connect_options + { + if (strlen($3) == 0) + mmerror(PARSE_ERROR, ET_ERROR, "incomplete statement"); - if (strcmp($3, "&") != 0) - mmerror(PARSE_ERROR, ET_ERROR, "unrecognized token \"%s\"", $3); + if (strcmp($3, "&") != 0) + mmerror(PARSE_ERROR, ET_ERROR, "unrecognized token \"%s\"", $3); - $$ = cat_str(3, make2_str($1, $2), $3, $4); - } - ; + $$ = cat_str(3, make2_str($1, $2), $3, $4); + } + ; -opt_opt_value: /*EMPTY*/ - { $$ = EMPTY; } - | '=' Iconst - { $$ = make2_str(mm_strdup("="), $2); } - | '=' ecpg_ident - { $$ = make2_str(mm_strdup("="), $2); } - | '=' civar - { $$ = make2_str(mm_strdup("="), $2); } - ; +opt_opt_value: /* EMPTY */ + { + $$ = EMPTY; + } + | '=' Iconst + { + $$ = make2_str(mm_strdup("="), $2); + } + | '=' ecpg_ident + { + $$ = make2_str(mm_strdup("="), $2); + } + | '=' civar + { + $$ = make2_str(mm_strdup("="), $2); + } + ; prepared_name: name + { + if ($1[0] == '\"' && $1[strlen($1) - 1] == '\"') /* already quoted? */ + $$ = $1; + else /* not quoted => convert to lowercase */ { - if ($1[0] == '\"' && $1[strlen($1)-1] == '\"') /* already quoted? */ - $$ = $1; - else /* not quoted => convert to lowercase */ - { - size_t i; + size_t i; - for (i = 0; i< strlen($1); i++) - $1[i] = tolower((unsigned char) $1[i]); + for (i = 0; i < strlen($1); i++) + $1[i] = tolower((unsigned char) $1[i]); - $$ = make3_str(mm_strdup("\""), $1, mm_strdup("\"")); - } + $$ = make3_str(mm_strdup("\""), $1, mm_strdup("\"")); } - | char_variable { $$ = $1; } - ; + } + | char_variable + { + $$ = $1; + } + ; /* * Declare Statement */ ECPGDeclareStmt: DECLARE prepared_name STATEMENT + { + struct declared_list *ptr = NULL; + + /* Check whether the declared name has been defined or not */ + for (ptr = g_declared_list; ptr != NULL; ptr = ptr->next) { - struct declared_list *ptr = NULL; - /* Check whether the declared name has been defined or not */ - for (ptr = g_declared_list; ptr != NULL; ptr = ptr->next) + if (strcmp($2, ptr->name) == 0) { - if (strcmp($2, ptr->name) == 0) - { - /* re-definition is not allowed */ - mmerror(PARSE_ERROR, ET_ERROR, "name \"%s\" is already declared", ptr->name); - } + /* re-definition is not allowed */ + mmerror(PARSE_ERROR, ET_ERROR, "name \"%s\" is already declared", ptr->name); } - - /* Add a new declared name into the g_declared_list */ - ptr = NULL; - ptr = (struct declared_list *)mm_alloc(sizeof(struct declared_list)); - if (ptr) - { - /* initial definition */ - ptr -> name = $2; - if (connection) - ptr -> connection = mm_strdup(connection); - else - ptr -> connection = NULL; - - ptr -> next = g_declared_list; - g_declared_list = ptr; - } - - $$ = cat_str(3 , mm_strdup("/* declare "), mm_strdup($2), mm_strdup(" as an SQL identifier */")); } -; + + /* Add a new declared name into the g_declared_list */ + ptr = NULL; + ptr = (struct declared_list *) mm_alloc(sizeof(struct declared_list)); + if (ptr) + { + /* initial definition */ + ptr->name = $2; + if (connection) + ptr->connection = mm_strdup(connection); + else + ptr->connection = NULL; + + ptr->next = g_declared_list; + g_declared_list = ptr; + } + + $$ = cat_str(3, mm_strdup("/* declare "), mm_strdup($2), mm_strdup(" as an SQL identifier */")); + } + ; /* * Declare a prepared cursor. The syntax is different from the standard * declare statement, so we create a new rule. */ -ECPGCursorStmt: DECLARE cursor_name cursor_options CURSOR opt_hold FOR prepared_name +ECPGCursorStmt: DECLARE cursor_name cursor_options CURSOR opt_hold FOR prepared_name + { + struct cursor *ptr, + *this; + char *cursor_marker = $2[0] == ':' ? mm_strdup("$0") : mm_strdup($2); + int (*strcmp_fn) (const char *, const char *) = (($2[0] == ':' || $2[0] == '"') ? strcmp : pg_strcasecmp); + struct variable *thisquery = (struct variable *) mm_alloc(sizeof(struct variable)); + char *comment; + char *con; + + if (INFORMIX_MODE && pg_strcasecmp($2, "database") == 0) + mmfatal(PARSE_ERROR, "\"database\" cannot be used as cursor name in INFORMIX mode"); + + check_declared_list($7); + con = connection ? connection : "NULL"; + for (ptr = cur; ptr != NULL; ptr = ptr->next) { - struct cursor *ptr, *this; - char *cursor_marker = $2[0] == ':' ? mm_strdup("$0") : mm_strdup($2); - int (* strcmp_fn)(const char *, const char *) = (($2[0] == ':' || $2[0] == '"') ? strcmp : pg_strcasecmp); - struct variable *thisquery = (struct variable *)mm_alloc(sizeof(struct variable)); - char *comment; - char *con; - - if (INFORMIX_MODE && pg_strcasecmp($2, "database") == 0) - mmfatal(PARSE_ERROR, "\"database\" cannot be used as cursor name in INFORMIX mode"); - - check_declared_list($7); - con = connection ? connection : "NULL"; - for (ptr = cur; ptr != NULL; ptr = ptr->next) + if (strcmp_fn($2, ptr->name) == 0) { - if (strcmp_fn($2, ptr->name) == 0) - { - /* re-definition is a bug */ - if ($2[0] == ':') - mmerror(PARSE_ERROR, ET_ERROR, "using variable \"%s\" in different declare statements is not supported", $2+1); - else - mmerror(PARSE_ERROR, ET_ERROR, "cursor \"%s\" is already defined", $2); - } + /* re-definition is a bug */ + if ($2[0] == ':') + mmerror(PARSE_ERROR, ET_ERROR, "using variable \"%s\" in different declare statements is not supported", $2 + 1); + else + mmerror(PARSE_ERROR, ET_ERROR, "cursor \"%s\" is already defined", $2); } - - this = (struct cursor *) mm_alloc(sizeof(struct cursor)); - - /* initial definition */ - this->next = cur; - this->name = $2; - this->function = (current_function ? mm_strdup(current_function) : NULL); - this->connection = connection ? mm_strdup(connection) : NULL; - this->command = cat_str(6, mm_strdup("declare"), cursor_marker, $3, mm_strdup("cursor"), $5, mm_strdup("for $1")); - this->argsresult = NULL; - this->argsresult_oos = NULL; - - thisquery->type = &ecpg_query; - thisquery->brace_level = 0; - thisquery->next = NULL; - thisquery->name = (char *) mm_alloc(sizeof("ECPGprepared_statement(, , __LINE__)") + strlen(con) + strlen($7)); - sprintf(thisquery->name, "ECPGprepared_statement(%s, %s, __LINE__)", con, $7); - - this->argsinsert = NULL; - this->argsinsert_oos = NULL; - if ($2[0] == ':') - { - struct variable *var = find_variable($2 + 1); - remove_variable_from_list(&argsinsert, var); - add_variable_to_head(&(this->argsinsert), var, &no_indicator); - } - add_variable_to_head(&(this->argsinsert), thisquery, &no_indicator); - - cur = this; - - comment = cat_str(3, mm_strdup("/*"), mm_strdup(this->command), mm_strdup("*/")); - - $$ = cat_str(2, adjust_outofscope_cursor_vars(this), - comment); } - ; + + this = (struct cursor *) mm_alloc(sizeof(struct cursor)); + + /* initial definition */ + this->next = cur; + this->name = $2; + this->function = (current_function ? mm_strdup(current_function) : NULL); + this->connection = connection ? mm_strdup(connection) : NULL; + this->command = cat_str(6, mm_strdup("declare"), cursor_marker, $3, mm_strdup("cursor"), $5, mm_strdup("for $1")); + this->argsresult = NULL; + this->argsresult_oos = NULL; + + thisquery->type = &ecpg_query; + thisquery->brace_level = 0; + thisquery->next = NULL; + thisquery->name = (char *) mm_alloc(sizeof("ECPGprepared_statement(, , __LINE__)") + strlen(con) + strlen($7)); + sprintf(thisquery->name, "ECPGprepared_statement(%s, %s, __LINE__)", con, $7); + + this->argsinsert = NULL; + this->argsinsert_oos = NULL; + if ($2[0] == ':') + { + struct variable *var = find_variable($2 + 1); + + remove_variable_from_list(&argsinsert, var); + add_variable_to_head(&(this->argsinsert), var, &no_indicator); + } + add_variable_to_head(&(this->argsinsert), thisquery, &no_indicator); + + cur = this; + + comment = cat_str(3, mm_strdup("/*"), mm_strdup(this->command), mm_strdup("*/")); + + $$ = cat_str(2, adjust_outofscope_cursor_vars(this), + comment); + } + ; ECPGExecuteImmediateStmt: EXECUTE IMMEDIATE execstring - { - /* execute immediate means prepare the statement and - * immediately execute it */ - $$ = $3; - }; + { + /* + * execute immediate means prepare the statement and immediately + * execute it + */ + $$ = $3; + } + ; + /* * variable declaration outside exec sql declare block */ ECPGVarDeclaration: single_vt_declaration; -single_vt_declaration: type_declaration { $$ = $1; } - | var_declaration { $$ = $1; } - ; +single_vt_declaration: type_declaration + { + $$ = $1; + } + | var_declaration + { + $$ = $1; + } + ; -precision: NumericOnly { $$ = $1; }; +precision: NumericOnly + { + $$ = $1; + } + ; -opt_scale: ',' NumericOnly { $$ = $2; } - | /* EMPTY */ { $$ = EMPTY; } - ; +opt_scale: ',' NumericOnly + { + $$ = $2; + } + | /* EMPTY */ + { + $$ = EMPTY; + } + ; -ecpg_interval: opt_interval { $$ = $1; } - | YEAR_P TO MINUTE_P { $$ = mm_strdup("year to minute"); } - | YEAR_P TO SECOND_P { $$ = mm_strdup("year to second"); } - | DAY_P TO DAY_P { $$ = mm_strdup("day to day"); } - | MONTH_P TO MONTH_P { $$ = mm_strdup("month to month"); } - ; +ecpg_interval: opt_interval { $$ = $1; } + | YEAR_P TO MINUTE_P { $$ = mm_strdup("year to minute"); } + | YEAR_P TO SECOND_P { $$ = mm_strdup("year to second"); } + | DAY_P TO DAY_P { $$ = mm_strdup("day to day"); } + | MONTH_P TO MONTH_P { $$ = mm_strdup("month to month"); } + ; /* * variable declaration inside exec sql declare block */ ECPGDeclaration: sql_startdeclare - { fputs("/* exec sql begin declare section */", base_yyout); } - var_type_declarations sql_enddeclare - { - fprintf(base_yyout, "%s/* exec sql end declare section */", $3); - free($3); - output_line_number(); - } - ; + { + fputs("/* exec sql begin declare section */", base_yyout); + } + var_type_declarations sql_enddeclare + { + fprintf(base_yyout, "%s/* exec sql end declare section */", $3); + free($3); + output_line_number(); + } + ; -sql_startdeclare: ecpgstart BEGIN_P DECLARE SQL_SECTION ';' {}; +sql_startdeclare: ecpgstart BEGIN_P DECLARE SQL_SECTION ';' + { + } + ; -sql_enddeclare: ecpgstart END_P DECLARE SQL_SECTION ';' {}; +sql_enddeclare: ecpgstart END_P DECLARE SQL_SECTION ';' + { + } + ; -var_type_declarations: /*EMPTY*/ { $$ = EMPTY; } - | vt_declarations { $$ = $1; } - ; +var_type_declarations: /* EMPTY */ + { + $$ = EMPTY; + } + | vt_declarations + { + $$ = $1; + } + ; -vt_declarations: single_vt_declaration { $$ = $1; } - | CPP_LINE { $$ = $1; } - | vt_declarations single_vt_declaration { $$ = cat2_str($1, $2); } - | vt_declarations CPP_LINE { $$ = cat2_str($1, $2); } - ; +vt_declarations: single_vt_declaration + { + $$ = $1; + } + | CPP_LINE + { + $$ = $1; + } + | vt_declarations single_vt_declaration + { + $$ = cat2_str($1, $2); + } + | vt_declarations CPP_LINE + { + $$ = cat2_str($1, $2); + } + ; -variable_declarations: var_declaration { $$ = $1; } - | variable_declarations var_declaration { $$ = cat2_str($1, $2); } - ; +variable_declarations: var_declaration + { + $$ = $1; + } + | variable_declarations var_declaration + { + $$ = cat2_str($1, $2); + } + ; type_declaration: S_TYPEDEF { @@ -467,167 +612,288 @@ type_declaration: S_TYPEDEF /* an initializer specified */ initializer = 0; } - var_type opt_pointer ECPGColLabel opt_array_bounds ';' + var_type opt_pointer ECPGColLabel opt_array_bounds ';' { add_typedef($5, $6.index1, $6.index2, $3.type_enum, $3.type_dimension, $3.type_index, initializer, *$4 ? 1 : 0); fprintf(base_yyout, "typedef %s %s %s %s;\n", $3.type_str, *$4 ? "*" : "", $5, $6.str); output_line_number(); $$ = mm_strdup(""); - }; + } + ; var_declaration: - storage_declaration var_type - { - actual_type[struct_level].type_storage = $1; - actual_type[struct_level].type_enum = $2.type_enum; - actual_type[struct_level].type_str = $2.type_str; - 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; + storage_declaration var_type + { + actual_type[struct_level].type_storage = $1; + actual_type[struct_level].type_enum = $2.type_enum; + actual_type[struct_level].type_str = $2.type_str; + 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; - actual_startline[struct_level] = hashline_number(); - } - variable_list ';' - { - $$ = cat_str(5, actual_startline[struct_level], $1, $2.type_str, $4, mm_strdup(";\n")); - } - | var_type - { - actual_type[struct_level].type_storage = EMPTY; - actual_type[struct_level].type_enum = $1.type_enum; - actual_type[struct_level].type_str = $1.type_str; - 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_startline[struct_level] = hashline_number(); + } + variable_list ';' + { + $$ = cat_str(5, actual_startline[struct_level], $1, $2.type_str, $4, mm_strdup(";\n")); + } + | var_type + { + actual_type[struct_level].type_storage = EMPTY; + actual_type[struct_level].type_enum = $1.type_enum; + actual_type[struct_level].type_str = $1.type_str; + 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_startline[struct_level] = hashline_number(); - } - variable_list ';' - { - $$ = cat_str(4, actual_startline[struct_level], $1.type_str, $3, mm_strdup(";\n")); - } - | struct_union_type_with_symbol ';' - { - $$ = cat2_str($1, mm_strdup(";")); - } - ; + actual_startline[struct_level] = hashline_number(); + } + variable_list ';' + { + $$ = cat_str(4, actual_startline[struct_level], $1.type_str, $3, mm_strdup(";\n")); + } + | struct_union_type_with_symbol ';' + { + $$ = cat2_str($1, mm_strdup(";")); + } + ; -opt_bit_field: ':' Iconst { $$ =cat2_str(mm_strdup(":"), $2); } - | /* EMPTY */ { $$ = EMPTY; } - ; +opt_bit_field: ':' Iconst + { + $$ = cat2_str(mm_strdup(":"), $2); + } + | /* EMPTY */ + { + $$ = EMPTY; + } + ; storage_declaration: storage_clause storage_modifier - {$$ = cat2_str ($1, $2); } - | storage_clause {$$ = $1; } - | storage_modifier {$$ = $1; } - ; + { + $$ = cat2_str($1, $2); + } + | storage_clause + { + $$ = $1; + } + | storage_modifier + { + $$ = $1; + } + ; -storage_clause : S_EXTERN { $$ = mm_strdup("extern"); } - | S_STATIC { $$ = mm_strdup("static"); } - | S_REGISTER { $$ = mm_strdup("register"); } - | S_AUTO { $$ = mm_strdup("auto"); } - ; +storage_clause: S_EXTERN { $$ = mm_strdup("extern"); } + | S_STATIC { $$ = mm_strdup("static"); } + | S_REGISTER { $$ = mm_strdup("register"); } + | S_AUTO { $$ = mm_strdup("auto"); } + ; -storage_modifier : S_CONST { $$ = mm_strdup("const"); } - | S_VOLATILE { $$ = mm_strdup("volatile"); } - ; +storage_modifier: S_CONST { $$ = mm_strdup("const"); } + | S_VOLATILE { $$ = mm_strdup("volatile"); } + ; -var_type: simple_type +var_type: simple_type + { + $$.type_enum = $1; + $$.type_str = mm_strdup(ecpg_type_name($1)); + $$.type_dimension = mm_strdup("-1"); + $$.type_index = mm_strdup("-1"); + $$.type_sizeof = NULL; + } + | struct_union_type + { + $$.type_str = $1; + $$.type_dimension = mm_strdup("-1"); + $$.type_index = mm_strdup("-1"); + + if (strncmp($1, "struct", sizeof("struct") - 1) == 0) { - $$.type_enum = $1; - $$.type_str = mm_strdup(ecpg_type_name($1)); - $$.type_dimension = mm_strdup("-1"); - $$.type_index = mm_strdup("-1"); + $$.type_enum = ECPGt_struct; + $$.type_sizeof = ECPGstruct_sizeof; + } + else + { + $$.type_enum = ECPGt_union; $$.type_sizeof = NULL; } - | struct_union_type - { - $$.type_str = $1; - $$.type_dimension = mm_strdup("-1"); - $$.type_index = mm_strdup("-1"); - - 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 - { - $$.type_str = $1; - $$.type_enum = ECPGt_int; - $$.type_dimension = mm_strdup("-1"); - $$.type_index = mm_strdup("-1"); - $$.type_sizeof = NULL; - } - | NUMERIC '(' precision opt_scale ')' + } + | enum_type + { + $$.type_str = $1; + $$.type_enum = ECPGt_int; + $$.type_dimension = mm_strdup("-1"); + $$.type_index = mm_strdup("-1"); + $$.type_sizeof = NULL; + } + | NUMERIC '(' precision opt_scale ')' + { + $$.type_enum = ECPGt_numeric; + $$.type_str = mm_strdup("numeric"); + $$.type_dimension = mm_strdup("-1"); + $$.type_index = mm_strdup("-1"); + $$.type_sizeof = NULL; + } + | DECIMAL_P '(' precision opt_scale ')' + { + $$.type_enum = ECPGt_decimal; + $$.type_str = mm_strdup("decimal"); + $$.type_dimension = mm_strdup("-1"); + $$.type_index = mm_strdup("-1"); + $$.type_sizeof = NULL; + } + | IDENT '(' precision opt_scale ')' + { + /* + * In C parsing mode, NUMERIC and DECIMAL are not keywords, so they + * will show up here as a plain identifier, and we need this duplicate + * code to recognize them. + */ + if (strcmp($1, "numeric") == 0) { $$.type_enum = ECPGt_numeric; $$.type_str = mm_strdup("numeric"); - $$.type_dimension = mm_strdup("-1"); - $$.type_index = mm_strdup("-1"); - $$.type_sizeof = NULL; } - | DECIMAL_P '(' precision opt_scale ')' + else if (strcmp($1, "decimal") == 0) { $$.type_enum = ECPGt_decimal; $$.type_str = mm_strdup("decimal"); - $$.type_dimension = mm_strdup("-1"); - $$.type_index = mm_strdup("-1"); - $$.type_sizeof = NULL; } - | IDENT '(' precision opt_scale ')' + else { - /* - * In C parsing mode, NUMERIC and DECIMAL are not keywords, so - * they will show up here as a plain identifier, and we need - * this duplicate code to recognize them. - */ - if (strcmp($1, "numeric") == 0) - { - $$.type_enum = ECPGt_numeric; - $$.type_str = mm_strdup("numeric"); - } - else if (strcmp($1, "decimal") == 0) - { - $$.type_enum = ECPGt_decimal; - $$.type_str = mm_strdup("decimal"); - } - else - { - mmerror(PARSE_ERROR, ET_ERROR, "only data types numeric and decimal have precision/scale argument"); - $$.type_enum = ECPGt_numeric; - $$.type_str = mm_strdup("numeric"); - } + mmerror(PARSE_ERROR, ET_ERROR, "only data types numeric and decimal have precision/scale argument"); + $$.type_enum = ECPGt_numeric; + $$.type_str = mm_strdup("numeric"); + } + $$.type_dimension = mm_strdup("-1"); + $$.type_index = mm_strdup("-1"); + $$.type_sizeof = NULL; + } + | VARCHAR + { + $$.type_enum = ECPGt_varchar; + $$.type_str = EMPTY; /* mm_strdup("varchar"); */ + $$.type_dimension = mm_strdup("-1"); + $$.type_index = mm_strdup("-1"); + $$.type_sizeof = NULL; + } + | FLOAT_P + { + /* Note: DOUBLE is handled in simple_type */ + $$.type_enum = ECPGt_float; + $$.type_str = mm_strdup("float"); + $$.type_dimension = mm_strdup("-1"); + $$.type_index = mm_strdup("-1"); + $$.type_sizeof = NULL; + } + | NUMERIC + { + $$.type_enum = ECPGt_numeric; + $$.type_str = mm_strdup("numeric"); + $$.type_dimension = mm_strdup("-1"); + $$.type_index = mm_strdup("-1"); + $$.type_sizeof = NULL; + } + | DECIMAL_P + { + $$.type_enum = ECPGt_decimal; + $$.type_str = mm_strdup("decimal"); + $$.type_dimension = mm_strdup("-1"); + $$.type_index = mm_strdup("-1"); + $$.type_sizeof = NULL; + } + | TIMESTAMP + { + $$.type_enum = ECPGt_timestamp; + $$.type_str = mm_strdup("timestamp"); + $$.type_dimension = mm_strdup("-1"); + $$.type_index = mm_strdup("-1"); + $$.type_sizeof = NULL; + } + | STRING_P + { + if (INFORMIX_MODE) + { + /* In Informix mode, "string" is automatically a typedef */ + $$.type_enum = ECPGt_string; + $$.type_str = mm_strdup("char"); $$.type_dimension = mm_strdup("-1"); $$.type_index = mm_strdup("-1"); $$.type_sizeof = NULL; } - | VARCHAR + else + { + /* Otherwise, legal only if user typedef'ed it */ + struct typedefs *this = get_typedef("string", false); + + $$.type_str = (this->type->type_enum == ECPGt_varchar || this->type->type_enum == ECPGt_bytea) ? EMPTY : mm_strdup(this->name); + $$.type_enum = this->type->type_enum; + $$.type_dimension = this->type->type_dimension; + $$.type_index = this->type->type_index; + if (this->type->type_sizeof && strlen(this->type->type_sizeof) != 0) + $$.type_sizeof = this->type->type_sizeof; + else + $$.type_sizeof = cat_str(3, mm_strdup("sizeof("), mm_strdup(this->name), mm_strdup(")")); + + struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list); + } + } + | INTERVAL ecpg_interval + { + $$.type_enum = ECPGt_interval; + $$.type_str = mm_strdup("interval"); + $$.type_dimension = mm_strdup("-1"); + $$.type_index = mm_strdup("-1"); + $$.type_sizeof = NULL; + } + | IDENT ecpg_interval + { + /* + * In C parsing mode, the above SQL type names are not keywords, so + * they will show up here as a plain identifier, and we need this + * duplicate code to recognize them. + * + * Note that we also handle the type names bytea, date, and datetime + * here, but not above because those are not currently SQL keywords. + * If they ever become so, they must gain duplicate productions above. + */ + if (strlen($2) != 0 && strcmp($1, "datetime") != 0 && strcmp($1, "interval") != 0) + mmerror(PARSE_ERROR, ET_ERROR, "interval specification not allowed here"); + + if (strcmp($1, "varchar") == 0) { $$.type_enum = ECPGt_varchar; - $$.type_str = EMPTY; /*mm_strdup("varchar");*/ + $$.type_str = EMPTY; /* mm_strdup("varchar"); */ $$.type_dimension = mm_strdup("-1"); $$.type_index = mm_strdup("-1"); $$.type_sizeof = NULL; } - | FLOAT_P + else if (strcmp($1, "bytea") == 0) + { + $$.type_enum = ECPGt_bytea; + $$.type_str = EMPTY; + $$.type_dimension = mm_strdup("-1"); + $$.type_index = mm_strdup("-1"); + $$.type_sizeof = NULL; + } + else if (strcmp($1, "float") == 0) { - /* Note: DOUBLE is handled in simple_type */ $$.type_enum = ECPGt_float; $$.type_str = mm_strdup("float"); $$.type_dimension = mm_strdup("-1"); $$.type_index = mm_strdup("-1"); $$.type_sizeof = NULL; } - | NUMERIC + else if (strcmp($1, "double") == 0) + { + $$.type_enum = ECPGt_double; + $$.type_str = mm_strdup("double"); + $$.type_dimension = mm_strdup("-1"); + $$.type_index = mm_strdup("-1"); + $$.type_sizeof = NULL; + } + else if (strcmp($1, "numeric") == 0) { $$.type_enum = ECPGt_numeric; $$.type_str = mm_strdup("numeric"); @@ -635,7 +901,7 @@ var_type: simple_type $$.type_index = mm_strdup("-1"); $$.type_sizeof = NULL; } - | DECIMAL_P + else if (strcmp($1, "decimal") == 0) { $$.type_enum = ECPGt_decimal; $$.type_str = mm_strdup("decimal"); @@ -643,7 +909,15 @@ var_type: simple_type $$.type_index = mm_strdup("-1"); $$.type_sizeof = NULL; } - | TIMESTAMP + else if (strcmp($1, "date") == 0) + { + $$.type_enum = ECPGt_date; + $$.type_str = mm_strdup("date"); + $$.type_dimension = mm_strdup("-1"); + $$.type_index = mm_strdup("-1"); + $$.type_sizeof = NULL; + } + else if (strcmp($1, "timestamp") == 0) { $$.type_enum = ECPGt_timestamp; $$.type_str = mm_strdup("timestamp"); @@ -651,35 +925,7 @@ var_type: simple_type $$.type_index = mm_strdup("-1"); $$.type_sizeof = NULL; } - | STRING_P - { - if (INFORMIX_MODE) - { - /* In Informix mode, "string" is automatically a typedef */ - $$.type_enum = ECPGt_string; - $$.type_str = mm_strdup("char"); - $$.type_dimension = mm_strdup("-1"); - $$.type_index = mm_strdup("-1"); - $$.type_sizeof = NULL; - } - else - { - /* Otherwise, legal only if user typedef'ed it */ - struct typedefs *this = get_typedef("string", false); - - $$.type_str = (this->type->type_enum == ECPGt_varchar || this->type->type_enum == ECPGt_bytea) ? EMPTY : mm_strdup(this->name); - $$.type_enum = this->type->type_enum; - $$.type_dimension = this->type->type_dimension; - $$.type_index = this->type->type_index; - if (this->type->type_sizeof && strlen(this->type->type_sizeof) != 0) - $$.type_sizeof = this->type->type_sizeof; - else - $$.type_sizeof = cat_str(3, mm_strdup("sizeof("), mm_strdup(this->name), mm_strdup(")")); - - struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list); - } - } - | INTERVAL ecpg_interval + else if (strcmp($1, "interval") == 0) { $$.type_enum = ECPGt_interval; $$.type_str = mm_strdup("interval"); @@ -687,530 +933,564 @@ var_type: simple_type $$.type_index = mm_strdup("-1"); $$.type_sizeof = NULL; } - | IDENT ecpg_interval + else if (strcmp($1, "datetime") == 0) { - /* - * In C parsing mode, the above SQL type names are not keywords, - * so they will show up here as a plain identifier, and we need - * this duplicate code to recognize them. - * - * Note that we also handle the type names bytea, date, and - * datetime here, but not above because those are not currently - * SQL keywords. If they ever become so, they must gain duplicate - * productions above. - */ - if (strlen($2) != 0 && strcmp ($1, "datetime") != 0 && strcmp ($1, "interval") != 0) - mmerror (PARSE_ERROR, ET_ERROR, "interval specification not allowed here"); - - if (strcmp($1, "varchar") == 0) - { - $$.type_enum = ECPGt_varchar; - $$.type_str = EMPTY; /*mm_strdup("varchar");*/ - $$.type_dimension = mm_strdup("-1"); - $$.type_index = mm_strdup("-1"); - $$.type_sizeof = NULL; - } - else if (strcmp($1, "bytea") == 0) - { - $$.type_enum = ECPGt_bytea; - $$.type_str = EMPTY; - $$.type_dimension = mm_strdup("-1"); - $$.type_index = mm_strdup("-1"); - $$.type_sizeof = NULL; - } - else if (strcmp($1, "float") == 0) - { - $$.type_enum = ECPGt_float; - $$.type_str = mm_strdup("float"); - $$.type_dimension = mm_strdup("-1"); - $$.type_index = mm_strdup("-1"); - $$.type_sizeof = NULL; - } - else if (strcmp($1, "double") == 0) - { - $$.type_enum = ECPGt_double; - $$.type_str = mm_strdup("double"); - $$.type_dimension = mm_strdup("-1"); - $$.type_index = mm_strdup("-1"); - $$.type_sizeof = NULL; - } - else if (strcmp($1, "numeric") == 0) - { - $$.type_enum = ECPGt_numeric; - $$.type_str = mm_strdup("numeric"); - $$.type_dimension = mm_strdup("-1"); - $$.type_index = mm_strdup("-1"); - $$.type_sizeof = NULL; - } - else if (strcmp($1, "decimal") == 0) - { - $$.type_enum = ECPGt_decimal; - $$.type_str = mm_strdup("decimal"); - $$.type_dimension = mm_strdup("-1"); - $$.type_index = mm_strdup("-1"); - $$.type_sizeof = NULL; - } - else if (strcmp($1, "date") == 0) - { - $$.type_enum = ECPGt_date; - $$.type_str = mm_strdup("date"); - $$.type_dimension = mm_strdup("-1"); - $$.type_index = mm_strdup("-1"); - $$.type_sizeof = NULL; - } - else if (strcmp($1, "timestamp") == 0) - { - $$.type_enum = ECPGt_timestamp; - $$.type_str = mm_strdup("timestamp"); - $$.type_dimension = mm_strdup("-1"); - $$.type_index = mm_strdup("-1"); - $$.type_sizeof = NULL; - } - else if (strcmp($1, "interval") == 0) - { - $$.type_enum = ECPGt_interval; - $$.type_str = mm_strdup("interval"); - $$.type_dimension = mm_strdup("-1"); - $$.type_index = mm_strdup("-1"); - $$.type_sizeof = NULL; - } - else if (strcmp($1, "datetime") == 0) - { - $$.type_enum = ECPGt_timestamp; - $$.type_str = mm_strdup("timestamp"); - $$.type_dimension = mm_strdup("-1"); - $$.type_index = mm_strdup("-1"); - $$.type_sizeof = NULL; - } - else if ((strcmp($1, "string") == 0) && INFORMIX_MODE) - { - $$.type_enum = ECPGt_string; - $$.type_str = mm_strdup("char"); - $$.type_dimension = mm_strdup("-1"); - $$.type_index = mm_strdup("-1"); - $$.type_sizeof = NULL; - } - else - { - /* Otherwise, it must be a user-defined typedef name */ - struct typedefs *this = get_typedef($1, false); - - $$.type_str = (this->type->type_enum == ECPGt_varchar || this->type->type_enum == ECPGt_bytea) ? EMPTY : mm_strdup(this->name); - $$.type_enum = this->type->type_enum; - $$.type_dimension = this->type->type_dimension; - $$.type_index = this->type->type_index; - if (this->type->type_sizeof && strlen(this->type->type_sizeof) != 0) - $$.type_sizeof = this->type->type_sizeof; - else - $$.type_sizeof = cat_str(3, mm_strdup("sizeof("), mm_strdup(this->name), mm_strdup(")")); - - struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list); - } + $$.type_enum = ECPGt_timestamp; + $$.type_str = mm_strdup("timestamp"); + $$.type_dimension = mm_strdup("-1"); + $$.type_index = mm_strdup("-1"); + $$.type_sizeof = NULL; } - | s_struct_union_symbol + else if ((strcmp($1, "string") == 0) && INFORMIX_MODE) { - /* this is for named structs/unions */ - char *name; - struct typedefs *this; - bool forward = (forward_name != NULL && strcmp($1.symbol, forward_name) == 0 && strcmp($1.su, "struct") == 0); + $$.type_enum = ECPGt_string; + $$.type_str = mm_strdup("char"); + $$.type_dimension = mm_strdup("-1"); + $$.type_index = mm_strdup("-1"); + $$.type_sizeof = NULL; + } + else + { + /* Otherwise, it must be a user-defined typedef name */ + struct typedefs *this = get_typedef($1, false); - name = cat2_str($1.su, $1.symbol); - /* Do we have a forward definition? */ - if (!forward) - { - /* No */ - - this = get_typedef(name, false); - $$.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_str = (this->type->type_enum == ECPGt_varchar || this->type->type_enum == ECPGt_bytea) ? EMPTY : mm_strdup(this->name); + $$.type_enum = this->type->type_enum; + $$.type_dimension = this->type->type_dimension; + $$.type_index = this->type->type_index; + if (this->type->type_sizeof && strlen(this->type->type_sizeof) != 0) $$.type_sizeof = this->type->type_sizeof; - struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list); - free(name); - } else - { - $$.type_str = name; - $$.type_enum = ECPGt_long; - $$.type_dimension = mm_strdup("-1"); - $$.type_index = mm_strdup("-1"); - $$.type_sizeof = mm_strdup(""); - struct_member_list[struct_level] = NULL; - } + $$.type_sizeof = cat_str(3, mm_strdup("sizeof("), mm_strdup(this->name), mm_strdup(")")); + + struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list); } - ; + } + | s_struct_union_symbol + { + /* this is for named structs/unions */ + char *name; + struct typedefs *this; + bool forward = (forward_name != NULL && strcmp($1.symbol, forward_name) == 0 && strcmp($1.su, "struct") == 0); + + name = cat2_str($1.su, $1.symbol); + /* Do we have a forward definition? */ + if (!forward) + { + /* No */ + + this = get_typedef(name, false); + $$.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); + } + else + { + $$.type_str = name; + $$.type_enum = ECPGt_long; + $$.type_dimension = mm_strdup("-1"); + $$.type_index = mm_strdup("-1"); + $$.type_sizeof = mm_strdup(""); + struct_member_list[struct_level] = NULL; + } + } + ; enum_type: ENUM_P symbol enum_definition - { $$ = cat_str(3, mm_strdup("enum"), $2, $3); } - | ENUM_P enum_definition - { $$ = cat2_str(mm_strdup("enum"), $2); } - | ENUM_P symbol - { $$ = cat2_str(mm_strdup("enum"), $2); } - ; + { + $$ = cat_str(3, mm_strdup("enum"), $2, $3); + } + | ENUM_P enum_definition + { + $$ = cat2_str(mm_strdup("enum"), $2); + } + | ENUM_P symbol + { + $$ = cat2_str(mm_strdup("enum"), $2); + } + ; enum_definition: '{' c_list '}' - { $$ = cat_str(3, mm_strdup("{"), $2, mm_strdup("}")); }; + { + $$ = cat_str(3, mm_strdup("{"), $2, mm_strdup("}")); + } + ; 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"); + forward_name = mm_strdup($1.symbol); + } + '{' variable_declarations '}' + { + struct typedefs *ptr, + *this; + struct this_type su_type; + + ECPGfree_struct_member(struct_member_list[struct_level]); + struct_member_list[struct_level] = NULL; + struct_level--; + if (strncmp($1.su, "struct", sizeof("struct") - 1) == 0) + su_type.type_enum = ECPGt_struct; + else + su_type.type_enum = ECPGt_union; + su_type.type_str = cat2_str($1.su, $1.symbol); + free(forward_name); + forward_name = NULL; + + /* + * This is essentially a typedef but needs the keyword struct/union as + * well. So we create the typedef for each struct definition with + * symbol + */ + for (ptr = types; ptr != NULL; ptr = ptr->next) { - struct_member_list[struct_level++] = NULL; - if (struct_level >= STRUCT_DEPTH) - mmerror(PARSE_ERROR, ET_ERROR, "too many levels in nested structure/union definition"); - forward_name = mm_strdup($1.symbol); + if (strcmp(su_type.type_str, ptr->name) == 0) + /* re-definition is a bug */ + mmerror(PARSE_ERROR, ET_ERROR, "type \"%s\" is already defined", su_type.type_str); } - '{' variable_declarations '}' - { - struct typedefs *ptr, *this; - struct this_type su_type; - ECPGfree_struct_member(struct_member_list[struct_level]); - struct_member_list[struct_level] = NULL; - struct_level--; - if (strncmp($1.su, "struct", sizeof("struct")-1) == 0) - su_type.type_enum = ECPGt_struct; - else - su_type.type_enum = ECPGt_union; - su_type.type_str = cat2_str($1.su, $1.symbol); - free(forward_name); - forward_name = NULL; + this = (struct typedefs *) mm_alloc(sizeof(struct typedefs)); - /* This is essentially a typedef but needs the keyword struct/union as well. - * So we create the typedef for each struct definition with symbol */ - for (ptr = types; ptr != NULL; ptr = ptr->next) - { - if (strcmp(su_type.type_str, ptr->name) == 0) - /* re-definition is a bug */ - mmerror(PARSE_ERROR, ET_ERROR, "type \"%s\" is already defined", su_type.type_str); - } + /* initial definition */ + this->next = types; + this->name = mm_strdup(su_type.type_str); + this->brace_level = braces_open; + this->type = (struct this_type *) mm_alloc(sizeof(struct this_type)); + this->type->type_enum = su_type.type_enum; + this->type->type_str = mm_strdup(su_type.type_str); + this->type->type_dimension = mm_strdup("-1"); /* dimension of array */ + this->type->type_index = mm_strdup("-1"); /* length of string */ + this->type->type_sizeof = ECPGstruct_sizeof; + this->struct_member_list = struct_member_list[struct_level]; - this = (struct typedefs *) mm_alloc(sizeof(struct typedefs)); + types = this; + $$ = cat_str(4, su_type.type_str, mm_strdup("{"), $4, mm_strdup("}")); + } + ; - /* initial definition */ - this->next = types; - this->name = mm_strdup(su_type.type_str); - this->brace_level = braces_open; - this->type = (struct this_type *) mm_alloc(sizeof(struct this_type)); - this->type->type_enum = su_type.type_enum; - this->type->type_str = mm_strdup(su_type.type_str); - this->type->type_dimension = mm_strdup("-1"); /* dimension of array */ - this->type->type_index = mm_strdup("-1"); /* length of string */ - this->type->type_sizeof = ECPGstruct_sizeof; - this->struct_member_list = struct_member_list[struct_level]; - - types = this; - $$ = cat_str(4, su_type.type_str, mm_strdup("{"), $4, mm_strdup("}")); - } - ; - -struct_union_type: struct_union_type_with_symbol { $$ = $1; } - | 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; - struct_level--; - $$ = cat_str(4, $1, mm_strdup("{"), $4, mm_strdup("}")); - } - ; +struct_union_type: struct_union_type_with_symbol + { + $$ = $1; + } + | 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; + struct_level--; + $$ = cat_str(4, $1, mm_strdup("{"), $4, mm_strdup("}")); + } + ; s_struct_union_symbol: SQL_STRUCT symbol - { - $$.su = mm_strdup("struct"); - $$.symbol = $2; - ECPGstruct_sizeof = cat_str(3, mm_strdup("sizeof("), cat2_str(mm_strdup($$.su), mm_strdup($$.symbol)), mm_strdup(")")); - } - | UNION symbol - { - $$.su = mm_strdup("union"); - $$.symbol = $2; - } - ; + { + $$.su = mm_strdup("struct"); + $$.symbol = $2; + ECPGstruct_sizeof = cat_str(3, mm_strdup("sizeof("), cat2_str(mm_strdup($$.su), mm_strdup($$.symbol)), mm_strdup(")")); + } + | UNION symbol + { + $$.su = mm_strdup("union"); + $$.symbol = $2; + } + ; s_struct_union: SQL_STRUCT - { - ECPGstruct_sizeof = mm_strdup(""); /* This must not be NULL to distinguish from simple types. */ - $$ = mm_strdup("struct"); - } - | UNION - { - $$ = mm_strdup("union"); - } - ; + { + ECPGstruct_sizeof = mm_strdup(""); /* This must not be NULL to + * distinguish from simple types. */ + $$ = mm_strdup("struct"); + } + | UNION + { + $$ = mm_strdup("union"); + } + ; -simple_type: unsigned_type { $$=$1; } - | opt_signed signed_type { $$=$2; } - ; +simple_type: unsigned_type { $$ = $1; } + | opt_signed signed_type { $$ = $2; } + ; -unsigned_type: SQL_UNSIGNED SQL_SHORT { $$ = ECPGt_unsigned_short; } - | SQL_UNSIGNED SQL_SHORT INT_P { $$ = ECPGt_unsigned_short; } - | SQL_UNSIGNED { $$ = ECPGt_unsigned_int; } - | SQL_UNSIGNED INT_P { $$ = ECPGt_unsigned_int; } - | SQL_UNSIGNED SQL_LONG { $$ = ECPGt_unsigned_long; } - | SQL_UNSIGNED SQL_LONG INT_P { $$ = ECPGt_unsigned_long; } - | SQL_UNSIGNED SQL_LONG SQL_LONG { $$ = ECPGt_unsigned_long_long; } - | SQL_UNSIGNED SQL_LONG SQL_LONG INT_P { $$ = ECPGt_unsigned_long_long; } - | SQL_UNSIGNED CHAR_P { $$ = ECPGt_unsigned_char; } - ; +unsigned_type: SQL_UNSIGNED SQL_SHORT { $$ = ECPGt_unsigned_short; } + | SQL_UNSIGNED SQL_SHORT INT_P { $$ = ECPGt_unsigned_short; } + | SQL_UNSIGNED { $$ = ECPGt_unsigned_int; } + | SQL_UNSIGNED INT_P { $$ = ECPGt_unsigned_int; } + | SQL_UNSIGNED SQL_LONG { $$ = ECPGt_unsigned_long; } + | SQL_UNSIGNED SQL_LONG INT_P { $$ = ECPGt_unsigned_long; } + | SQL_UNSIGNED SQL_LONG SQL_LONG { $$ = ECPGt_unsigned_long_long; } + | SQL_UNSIGNED SQL_LONG SQL_LONG INT_P { $$ = ECPGt_unsigned_long_long; } + | SQL_UNSIGNED CHAR_P { $$ = ECPGt_unsigned_char; } + ; -signed_type: SQL_SHORT { $$ = ECPGt_short; } - | SQL_SHORT INT_P { $$ = ECPGt_short; } - | INT_P { $$ = ECPGt_int; } - | SQL_LONG { $$ = ECPGt_long; } - | SQL_LONG INT_P { $$ = ECPGt_long; } - | SQL_LONG SQL_LONG { $$ = ECPGt_long_long; } - | SQL_LONG SQL_LONG INT_P { $$ = ECPGt_long_long; } - | SQL_BOOL { $$ = ECPGt_bool; } - | CHAR_P { $$ = ECPGt_char; } - | DOUBLE_P { $$ = ECPGt_double; } - ; +signed_type: SQL_SHORT { $$ = ECPGt_short; } + | SQL_SHORT INT_P { $$ = ECPGt_short; } + | INT_P { $$ = ECPGt_int; } + | SQL_LONG { $$ = ECPGt_long; } + | SQL_LONG INT_P { $$ = ECPGt_long; } + | SQL_LONG SQL_LONG { $$ = ECPGt_long_long; } + | SQL_LONG SQL_LONG INT_P { $$ = ECPGt_long_long; } + | SQL_BOOL { $$ = ECPGt_bool; } + | CHAR_P { $$ = ECPGt_char; } + | DOUBLE_P { $$ = ECPGt_double; } + ; opt_signed: SQL_SIGNED - | /* EMPTY */ - ; + | /* EMPTY */ + ; variable_list: variable - { $$ = $1; } - | variable_list ',' variable - { - if (actual_type[struct_level].type_enum == ECPGt_varchar || actual_type[struct_level].type_enum == ECPGt_bytea) - $$ = cat_str(4, $1, mm_strdup(";"), mm_strdup(actual_type[struct_level].type_storage), $3); - else - $$ = cat_str(3, $1, mm_strdup(","), $3); - } - ; + { + $$ = $1; + } + | variable_list ',' variable + { + if (actual_type[struct_level].type_enum == ECPGt_varchar || actual_type[struct_level].type_enum == ECPGt_bytea) + $$ = cat_str(4, $1, mm_strdup(";"), mm_strdup(actual_type[struct_level].type_storage), $3); + else + $$ = cat_str(3, $1, mm_strdup(","), $3); + } + ; variable: opt_pointer ECPGColLabel opt_array_bounds opt_bit_field opt_initializer + { + struct ECPGtype *type; + char *dimension = $3.index1; /* dimension of array */ + char *length = $3.index2; /* length of string */ + char *dim_str; + char *vcn; + int *varlen_type_counter; + char *struct_name; + + adjust_array(actual_type[struct_level].type_enum, &dimension, &length, actual_type[struct_level].type_dimension, actual_type[struct_level].type_index, strlen($1), false); + switch (actual_type[struct_level].type_enum) { - struct ECPGtype * type; - char *dimension = $3.index1; /* dimension of array */ - char *length = $3.index2; /* length of string */ - char *dim_str; - char *vcn; - int *varlen_type_counter; - char *struct_name; + case ECPGt_struct: + case ECPGt_union: + if (atoi(dimension) < 0) + type = ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum, actual_type[struct_level].type_str, actual_type[struct_level].type_sizeof); + else + type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum, actual_type[struct_level].type_str, actual_type[struct_level].type_sizeof), dimension); - adjust_array(actual_type[struct_level].type_enum, &dimension, &length, actual_type[struct_level].type_dimension, actual_type[struct_level].type_index, strlen($1), false); - switch (actual_type[struct_level].type_enum) - { - case ECPGt_struct: - case ECPGt_union: - if (atoi(dimension) < 0) - type = ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum, actual_type[struct_level].type_str, actual_type[struct_level].type_sizeof); - else - type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum, actual_type[struct_level].type_str, actual_type[struct_level].type_sizeof), dimension); + $$ = cat_str(5, $1, mm_strdup($2), $3.str, $4, $5); + break; - $$ = cat_str(5, $1, mm_strdup($2), $3.str, $4, $5); - break; + case ECPGt_varchar: + case ECPGt_bytea: + if (actual_type[struct_level].type_enum == ECPGt_varchar) + { + varlen_type_counter = &varchar_counter; + struct_name = " struct varchar_"; + } + else + { + varlen_type_counter = &bytea_counter; + struct_name = " struct bytea_"; + } + if (atoi(dimension) < 0) + type = ECPGmake_simple_type(actual_type[struct_level].type_enum, length, *varlen_type_counter); + else + type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, length, *varlen_type_counter), dimension); - case ECPGt_varchar: - case ECPGt_bytea: - if (actual_type[struct_level].type_enum == ECPGt_varchar) + if (strcmp(dimension, "0") == 0 || abs(atoi(dimension)) == 1) + dim_str = mm_strdup(""); + else + dim_str = cat_str(3, mm_strdup("["), mm_strdup(dimension), mm_strdup("]")); + + /* + * cannot check for atoi <= 0 because a defined constant will + * yield 0 here as well + */ + if (atoi(length) < 0 || strcmp(length, "0") == 0) + mmerror(PARSE_ERROR, ET_ERROR, "pointers to varchar are not implemented"); + + /* + * make sure varchar struct name is unique by adding a unique + * counter to its definition + */ + vcn = (char *) mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3); + sprintf(vcn, "%d", *varlen_type_counter); + if (strcmp(dimension, "0") == 0) + $$ = cat_str(7, make2_str(mm_strdup(struct_name), vcn), mm_strdup(" { int len; char arr["), mm_strdup(length), mm_strdup("]; } *"), mm_strdup($2), $4, $5); + else + $$ = cat_str(8, make2_str(mm_strdup(struct_name), vcn), mm_strdup(" { int len; char arr["), mm_strdup(length), mm_strdup("]; } "), mm_strdup($2), dim_str, $4, $5); + (*varlen_type_counter)++; + break; + + case ECPGt_char: + case ECPGt_unsigned_char: + case ECPGt_string: + if (atoi(dimension) == -1) + { + int i = strlen($5); + + if (atoi(length) == -1 && i > 0) /* char [] = + * "string" */ { - varlen_type_counter = &varchar_counter; - struct_name = " struct varchar_"; + /* + * if we have an initializer but no string size set, + * let's use the initializer's length + */ + free(length); + length = mm_alloc(i + sizeof("sizeof()")); + sprintf(length, "sizeof(%s)", $5 + 2); } - else - { - varlen_type_counter = &bytea_counter; - struct_name = " struct bytea_"; - } - if (atoi(dimension) < 0) - type = ECPGmake_simple_type(actual_type[struct_level].type_enum, length, *varlen_type_counter); - else - type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, length, *varlen_type_counter), dimension); + type = ECPGmake_simple_type(actual_type[struct_level].type_enum, length, 0); + } + else + type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, length, 0), dimension); - if (strcmp(dimension, "0") == 0 || abs(atoi(dimension)) == 1) - dim_str=mm_strdup(""); - else - dim_str=cat_str(3, mm_strdup("["), mm_strdup(dimension), mm_strdup("]")); - /* cannot check for atoi <= 0 because a defined constant will yield 0 here as well */ - if (atoi(length) < 0 || strcmp(length, "0") == 0) - mmerror(PARSE_ERROR, ET_ERROR, "pointers to varchar are not implemented"); + $$ = cat_str(5, $1, mm_strdup($2), $3.str, $4, $5); + break; - /* make sure varchar struct name is unique by adding a unique counter to its definition */ - vcn = (char *) mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3); - sprintf(vcn, "%d", *varlen_type_counter); - if (strcmp(dimension, "0") == 0) - $$ = cat_str(7, make2_str(mm_strdup(struct_name), vcn), mm_strdup(" { int len; char arr["), mm_strdup(length), mm_strdup("]; } *"), mm_strdup($2), $4, $5); - else - $$ = cat_str(8, make2_str(mm_strdup(struct_name), vcn), mm_strdup(" { int len; char arr["), mm_strdup(length), mm_strdup("]; } "), mm_strdup($2), dim_str, $4, $5); - (*varlen_type_counter)++; - break; + default: + if (atoi(dimension) < 0) + type = ECPGmake_simple_type(actual_type[struct_level].type_enum, mm_strdup("1"), 0); + else + type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, mm_strdup("1"), 0), dimension); - case ECPGt_char: - case ECPGt_unsigned_char: - case ECPGt_string: - if (atoi(dimension) == -1) - { - int i = strlen($5); - - if (atoi(length) == -1 && i > 0) /* char [] = "string" */ - { - /* if we have an initializer but no string size set, let's use the initializer's length */ - free(length); - length = mm_alloc(i+sizeof("sizeof()")); - sprintf(length, "sizeof(%s)", $5+2); - } - type = ECPGmake_simple_type(actual_type[struct_level].type_enum, length, 0); - } - else - type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, length, 0), dimension); - - $$ = cat_str(5, $1, mm_strdup($2), $3.str, $4, $5); - break; - - default: - if (atoi(dimension) < 0) - type = ECPGmake_simple_type(actual_type[struct_level].type_enum, mm_strdup("1"), 0); - else - type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, mm_strdup("1"), 0), dimension); - - $$ = cat_str(5, $1, mm_strdup($2), $3.str, $4, $5); - break; - } - - if (struct_level == 0) - new_variable($2, type, braces_open); - else - ECPGmake_struct_member($2, type, &(struct_member_list[struct_level - 1])); - - free($2); + $$ = cat_str(5, $1, mm_strdup($2), $3.str, $4, $5); + break; } - ; -opt_initializer: /*EMPTY*/ - { $$ = EMPTY; } - | '=' c_term - { - initializer = 1; - $$ = cat2_str(mm_strdup("="), $2); - } - ; + if (struct_level == 0) + new_variable($2, type, braces_open); + else + ECPGmake_struct_member($2, type, &(struct_member_list[struct_level - 1])); -opt_pointer: /*EMPTY*/ { $$ = EMPTY; } - | '*' { $$ = mm_strdup("*"); } - | '*' '*' { $$ = mm_strdup("**"); } - ; + free($2); + } + ; + +opt_initializer: /* EMPTY */ + { + $$ = EMPTY; + } + | '=' c_term + { + initializer = 1; + $$ = cat2_str(mm_strdup("="), $2); + } + ; + +opt_pointer: /* EMPTY */ + { + $$ = EMPTY; + } + | '*' + { + $$ = mm_strdup("*"); + } + | '*' '*' + { + $$ = mm_strdup("**"); + } + ; /* * We try to simulate the correct DECLARE syntax here so we get dynamic SQL */ ECPGDeclare: DECLARE STATEMENT ecpg_ident - { - /* this is only supported for compatibility */ - $$ = cat_str(3, mm_strdup("/* declare statement"), $3, mm_strdup("*/")); - } - ; + { + /* this is only supported for compatibility */ + $$ = cat_str(3, mm_strdup("/* declare statement"), $3, mm_strdup("*/")); + } + ; /* * the exec sql disconnect statement: disconnect from the given database */ -ECPGDisconnect: SQL_DISCONNECT dis_name { $$ = $2; } - ; +ECPGDisconnect: SQL_DISCONNECT dis_name + { + $$ = $2; + } + ; -dis_name: connection_object { $$ = $1; } - | CURRENT_P { $$ = mm_strdup("\"CURRENT\""); } - | ALL { $$ = mm_strdup("\"ALL\""); } - | /* EMPTY */ { $$ = mm_strdup("\"CURRENT\""); } - ; +dis_name: connection_object + { + $$ = $1; + } + | CURRENT_P + { + $$ = mm_strdup("\"CURRENT\""); + } + | ALL + { + $$ = mm_strdup("\"ALL\""); + } + | /* EMPTY */ + { + $$ = mm_strdup("\"CURRENT\""); + } + ; -connection_object: name { $$ = make3_str(mm_strdup("\""), $1, mm_strdup("\"")); } - | DEFAULT { $$ = mm_strdup("\"DEFAULT\""); } - | char_variable { $$ = $1; } - ; +connection_object: name + { + $$ = make3_str(mm_strdup("\""), $1, mm_strdup("\"")); + } + | DEFAULT + { + $$ = mm_strdup("\"DEFAULT\""); + } + | char_variable + { + $$ = $1; + } + ; execstring: char_variable - { $$ = $1; } - | CSTRING - { $$ = make3_str(mm_strdup("\""), $1, mm_strdup("\"")); } - ; + { + $$ = $1; + } + | CSTRING + { + $$ = make3_str(mm_strdup("\""), $1, mm_strdup("\"")); + } + ; /* * the exec sql free command to deallocate a previously * prepared statement */ -ECPGFree: SQL_FREE cursor_name { $$ = $2; } - | SQL_FREE ALL { $$ = mm_strdup("all"); } - ; +ECPGFree: SQL_FREE cursor_name + { + $$ = $2; + } + | SQL_FREE ALL + { + $$ = mm_strdup("all"); + } + ; /* * open is an open cursor, at the moment this has to be removed */ ECPGOpen: SQL_OPEN cursor_name opt_ecpg_using - { - if ($2[0] == ':') - remove_variable_from_list(&argsinsert, find_variable($2 + 1)); - $$ = $2; - } - ; + { + if ($2[0] == ':') + remove_variable_from_list(&argsinsert, find_variable($2 + 1)); + $$ = $2; + } + ; -opt_ecpg_using: /*EMPTY*/ { $$ = EMPTY; } - | ecpg_using { $$ = $1; } - ; +opt_ecpg_using: /* EMPTY */ + { + $$ = EMPTY; + } + | ecpg_using + { + $$ = $1; + } + ; -ecpg_using: USING using_list { $$ = EMPTY; } - | using_descriptor { $$ = $1; } - ; +ecpg_using: USING using_list + { + $$ = EMPTY; + } + | using_descriptor + { + $$ = $1; + } + ; using_descriptor: USING SQL_P SQL_DESCRIPTOR quoted_ident_stringvar - { - add_variable_to_head(&argsinsert, descriptor_variable($4,0), &no_indicator); - $$ = EMPTY; - } - | USING SQL_DESCRIPTOR name - { - add_variable_to_head(&argsinsert, sqlda_variable($3), &no_indicator); - $$ = EMPTY; - } - ; + { + add_variable_to_head(&argsinsert, descriptor_variable($4, 0), &no_indicator); + $$ = EMPTY; + } + | USING SQL_DESCRIPTOR name + { + add_variable_to_head(&argsinsert, sqlda_variable($3), &no_indicator); + $$ = EMPTY; + } + ; into_descriptor: INTO SQL_P SQL_DESCRIPTOR quoted_ident_stringvar - { - add_variable_to_head(&argsresult, descriptor_variable($4,1), &no_indicator); - $$ = EMPTY; - } - | INTO SQL_DESCRIPTOR name - { - add_variable_to_head(&argsresult, sqlda_variable($3), &no_indicator); - $$ = EMPTY; - } - ; + { + add_variable_to_head(&argsresult, descriptor_variable($4, 1), &no_indicator); + $$ = EMPTY; + } + | INTO SQL_DESCRIPTOR name + { + add_variable_to_head(&argsresult, sqlda_variable($3), &no_indicator); + $$ = EMPTY; + } + ; into_sqlda: INTO name - { - add_variable_to_head(&argsresult, sqlda_variable($2), &no_indicator); - $$ = EMPTY; - } - ; + { + add_variable_to_head(&argsresult, sqlda_variable($2), &no_indicator); + $$ = EMPTY; + } + ; -using_list: UsingValue | UsingValue ',' using_list; +using_list: UsingValue | UsingValue ',' using_list + ; UsingValue: UsingConst - { - char *length = mm_alloc(32); + { + char *length = mm_alloc(32); - sprintf(length, "%zu", strlen($1)); - add_variable_to_head(&argsinsert, new_variable($1, ECPGmake_simple_type(ECPGt_const, length, 0), 0), &no_indicator); - } - | civar { $$ = EMPTY; } - | civarind { $$ = EMPTY; } - ; + sprintf(length, "%zu", strlen($1)); + add_variable_to_head(&argsinsert, new_variable($1, ECPGmake_simple_type(ECPGt_const, length, 0), 0), &no_indicator); + } + | civar + { + $$ = EMPTY; + } + | civarind + { + $$ = EMPTY; + } + ; -UsingConst: Iconst { $$ = $1; } - | '+' Iconst { $$ = cat_str(2, mm_strdup("+"), $2); } - | '-' Iconst { $$ = cat_str(2, mm_strdup("-"), $2); } - | ecpg_fconst { $$ = $1; } - | '+' ecpg_fconst { $$ = cat_str(2, mm_strdup("+"), $2); } - | '-' ecpg_fconst { $$ = cat_str(2, mm_strdup("-"), $2); } - | ecpg_sconst { $$ = $1; } - | ecpg_bconst { $$ = $1; } - | ecpg_xconst { $$ = $1; } - ; +UsingConst: Iconst + { + $$ = $1; + } + | '+' Iconst + { + $$ = cat_str(2, mm_strdup("+"), $2); + } + | '-' Iconst + { + $$ = cat_str(2, mm_strdup("-"), $2); + } + | ecpg_fconst + { + $$ = $1; + } + | '+' ecpg_fconst + { + $$ = cat_str(2, mm_strdup("+"), $2); + } + | '-' ecpg_fconst + { + $$ = cat_str(2, mm_strdup("-"), $2); + } + | ecpg_sconst + { + $$ = $1; + } + | ecpg_bconst + { + $$ = $1; + } + | ecpg_xconst + { + $$ = $1; + } + ; /* * We accept DESCRIBE [OUTPUT] but do nothing with DESCRIBE INPUT so far. @@ -1223,6 +1503,7 @@ ECPGDescribe: SQL_DESCRIBE INPUT_P prepared_name using_descriptor | SQL_DESCRIBE opt_output prepared_name using_descriptor { struct variable *var; + var = argsinsert->variable; remove_variable_from_list(&argsinsert, var); add_variable_to_head(&argsresult, var, &no_indicator); @@ -1247,8 +1528,14 @@ ECPGDescribe: SQL_DESCRIBE INPUT_P prepared_name using_descriptor } ; -opt_output: SQL_OUTPUT { $$ = mm_strdup("output"); } - | /* EMPTY */ { $$ = EMPTY; } +opt_output: SQL_OUTPUT + { + $$ = mm_strdup("output"); + } + | /* EMPTY */ + { + $$ = EMPTY; + } ; /* @@ -1261,425 +1548,465 @@ opt_output: SQL_OUTPUT { $$ = mm_strdup("output"); } * allocate a descriptor */ ECPGAllocateDescr: SQL_ALLOCATE SQL_DESCRIPTOR quoted_ident_stringvar - { - add_descriptor($3,connection); - $$ = $3; - } - ; + { + add_descriptor($3, connection); + $$ = $3; + } + ; /* * deallocate a descriptor */ -ECPGDeallocateDescr: DEALLOCATE SQL_DESCRIPTOR quoted_ident_stringvar - { - drop_descriptor($3,connection); - $$ = $3; - } - ; +ECPGDeallocateDescr: DEALLOCATE SQL_DESCRIPTOR quoted_ident_stringvar + { + drop_descriptor($3, connection); + $$ = $3; + } + ; /* * manipulate a descriptor header */ ECPGGetDescriptorHeader: SQL_GET SQL_DESCRIPTOR quoted_ident_stringvar ECPGGetDescHeaderItems - { $$ = $3; } - ; + { + $$ = $3; + } + ; ECPGGetDescHeaderItems: ECPGGetDescHeaderItem - | ECPGGetDescHeaderItems ',' ECPGGetDescHeaderItem - ; + | ECPGGetDescHeaderItems ',' ECPGGetDescHeaderItem + ; ECPGGetDescHeaderItem: cvariable '=' desc_header_item - { push_assignment($1, $3); } - ; - + { + push_assignment($1, $3); + } + ; ECPGSetDescriptorHeader: SET SQL_DESCRIPTOR quoted_ident_stringvar ECPGSetDescHeaderItems - { $$ = $3; } - ; + { + $$ = $3; + } + ; ECPGSetDescHeaderItems: ECPGSetDescHeaderItem - | ECPGSetDescHeaderItems ',' ECPGSetDescHeaderItem - ; + | ECPGSetDescHeaderItems ',' ECPGSetDescHeaderItem + ; ECPGSetDescHeaderItem: desc_header_item '=' IntConstVar - { - push_assignment($3, $1); - } - ; + { + push_assignment($3, $1); + } + ; IntConstVar: Iconst - { - char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3); + { + char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3); - sprintf(length, "%zu", strlen($1)); - new_variable($1, ECPGmake_simple_type(ECPGt_const, length, 0), 0); - $$ = $1; - } - | cvariable - { - $$ = $1; - } - ; + sprintf(length, "%zu", strlen($1)); + new_variable($1, ECPGmake_simple_type(ECPGt_const, length, 0), 0); + $$ = $1; + } + | cvariable + { + $$ = $1; + } + ; -desc_header_item: SQL_COUNT { $$ = ECPGd_count; } - ; +desc_header_item: SQL_COUNT + { + $$ = ECPGd_count; + } + ; /* * manipulate a descriptor */ -ECPGGetDescriptor: SQL_GET SQL_DESCRIPTOR quoted_ident_stringvar VALUE_P IntConstVar ECPGGetDescItems - { $$.str = $5; $$.name = $3; } - ; +ECPGGetDescriptor: SQL_GET SQL_DESCRIPTOR quoted_ident_stringvar VALUE_P IntConstVar ECPGGetDescItems + { + $$.str = $5; + $$.name = $3; + } + ; ECPGGetDescItems: ECPGGetDescItem - | ECPGGetDescItems ',' ECPGGetDescItem - ; + | ECPGGetDescItems ',' ECPGGetDescItem + ; -ECPGGetDescItem: cvariable '=' descriptor_item { push_assignment($1, $3); }; +ECPGGetDescItem: cvariable '=' descriptor_item + { + push_assignment($1, $3); + } + ; - -ECPGSetDescriptor: SET SQL_DESCRIPTOR quoted_ident_stringvar VALUE_P IntConstVar ECPGSetDescItems - { $$.str = $5; $$.name = $3; } - ; +ECPGSetDescriptor: SET SQL_DESCRIPTOR quoted_ident_stringvar VALUE_P IntConstVar ECPGSetDescItems + { + $$.str = $5; + $$.name = $3; + } + ; ECPGSetDescItems: ECPGSetDescItem - | ECPGSetDescItems ',' ECPGSetDescItem - ; + | ECPGSetDescItems ',' ECPGSetDescItem + ; ECPGSetDescItem: descriptor_item '=' AllConstVar - { - push_assignment($3, $1); - } - ; + { + push_assignment($3, $1); + } + ; AllConstVar: ecpg_fconst - { - char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3); + { + char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3); - sprintf(length, "%zu", strlen($1)); - new_variable($1, ECPGmake_simple_type(ECPGt_const, length, 0), 0); - $$ = $1; - } + sprintf(length, "%zu", strlen($1)); + new_variable($1, ECPGmake_simple_type(ECPGt_const, length, 0), 0); + $$ = $1; + } + | IntConstVar + { + $$ = $1; + } + | '-' ecpg_fconst + { + char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3); + char *var = cat2_str(mm_strdup("-"), $2); - | IntConstVar - { - $$ = $1; - } + sprintf(length, "%zu", strlen(var)); + new_variable(var, ECPGmake_simple_type(ECPGt_const, length, 0), 0); + $$ = var; + } + | '-' Iconst + { + char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3); + char *var = cat2_str(mm_strdup("-"), $2); - | '-' ecpg_fconst - { - char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3); - char *var = cat2_str(mm_strdup("-"), $2); + sprintf(length, "%zu", strlen(var)); + new_variable(var, ECPGmake_simple_type(ECPGt_const, length, 0), 0); + $$ = var; + } + | ecpg_sconst + { + char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3); + char *var = $1 + 1; - sprintf(length, "%zu", strlen(var)); - new_variable(var, ECPGmake_simple_type(ECPGt_const, length, 0), 0); - $$ = var; - } + var[strlen(var) - 1] = '\0'; + sprintf(length, "%zu", strlen(var)); + new_variable(var, ECPGmake_simple_type(ECPGt_const, length, 0), 0); + $$ = var; + } + ; - | '-' Iconst - { - char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3); - char *var = cat2_str(mm_strdup("-"), $2); - - sprintf(length, "%zu", strlen(var)); - new_variable(var, ECPGmake_simple_type(ECPGt_const, length, 0), 0); - $$ = var; - } - - | ecpg_sconst - { - char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3); - char *var = $1 + 1; - - var[strlen(var) - 1] = '\0'; - sprintf(length, "%zu", strlen(var)); - new_variable(var, ECPGmake_simple_type(ECPGt_const, length, 0), 0); - $$ = var; - } - ; - -descriptor_item: SQL_CARDINALITY { $$ = ECPGd_cardinality; } - | DATA_P { $$ = ECPGd_data; } - | SQL_DATETIME_INTERVAL_CODE { $$ = ECPGd_di_code; } - | SQL_DATETIME_INTERVAL_PRECISION { $$ = ECPGd_di_precision; } - | SQL_INDICATOR { $$ = ECPGd_indicator; } - | SQL_KEY_MEMBER { $$ = ECPGd_key_member; } - | SQL_LENGTH { $$ = ECPGd_length; } - | NAME_P { $$ = ECPGd_name; } - | SQL_NULLABLE { $$ = ECPGd_nullable; } - | SQL_OCTET_LENGTH { $$ = ECPGd_octet; } - | PRECISION { $$ = ECPGd_precision; } - | SQL_RETURNED_LENGTH { $$ = ECPGd_length; } - | SQL_RETURNED_OCTET_LENGTH { $$ = ECPGd_ret_octet; } - | SQL_SCALE { $$ = ECPGd_scale; } - | TYPE_P { $$ = ECPGd_type; } - ; +descriptor_item: SQL_CARDINALITY { $$ = ECPGd_cardinality; } + | DATA_P { $$ = ECPGd_data; } + | SQL_DATETIME_INTERVAL_CODE { $$ = ECPGd_di_code; } + | SQL_DATETIME_INTERVAL_PRECISION { $$ = ECPGd_di_precision; } + | SQL_INDICATOR { $$ = ECPGd_indicator; } + | SQL_KEY_MEMBER { $$ = ECPGd_key_member; } + | SQL_LENGTH { $$ = ECPGd_length; } + | NAME_P { $$ = ECPGd_name; } + | SQL_NULLABLE { $$ = ECPGd_nullable; } + | SQL_OCTET_LENGTH { $$ = ECPGd_octet; } + | PRECISION { $$ = ECPGd_precision; } + | SQL_RETURNED_LENGTH { $$ = ECPGd_length; } + | SQL_RETURNED_OCTET_LENGTH { $$ = ECPGd_ret_octet; } + | SQL_SCALE { $$ = ECPGd_scale; } + | TYPE_P { $$ = ECPGd_type; } + ; /* * set/reset the automatic transaction mode, this needs a different handling * as the other set commands */ -ECPGSetAutocommit: SET SQL_AUTOCOMMIT '=' on_off { $$ = $4; } - | SET SQL_AUTOCOMMIT TO on_off { $$ = $4; } - ; +ECPGSetAutocommit: SET SQL_AUTOCOMMIT '=' on_off + { + $$ = $4; + } + | SET SQL_AUTOCOMMIT TO on_off + { + $$ = $4; + } + ; -on_off: ON { $$ = mm_strdup("on"); } - | OFF { $$ = mm_strdup("off"); } - ; +on_off: ON + { + $$ = mm_strdup("on"); + } + | OFF + { + $$ = mm_strdup("off"); + } + ; /* * set the actual connection, this needs a different handling as the other * set commands */ -ECPGSetConnection: SET CONNECTION TO connection_object { $$ = $4; } - | SET CONNECTION '=' connection_object { $$ = $4; } - | SET CONNECTION connection_object { $$ = $3; } - ; +ECPGSetConnection: SET CONNECTION TO connection_object + { + $$ = $4; + } + | SET CONNECTION '=' connection_object + { + $$ = $4; + } + | SET CONNECTION connection_object + { + $$ = $3; + } + ; /* * define a new type for embedded SQL */ ECPGTypedef: TYPE_P - { - /* reset this variable so we see if there was */ - /* an initializer specified */ - initializer = 0; - } - ECPGColLabel IS var_type opt_array_bounds opt_reference - { - add_typedef($3, $6.index1, $6.index2, $5.type_enum, $5.type_dimension, $5.type_index, initializer, *$7 ? 1 : 0); + { + /* reset this variable so we see if there was */ + /* an initializer specified */ + initializer = 0; + } + ECPGColLabel IS var_type opt_array_bounds opt_reference + { + add_typedef($3, $6.index1, $6.index2, $5.type_enum, $5.type_dimension, $5.type_index, initializer, *$7 ? 1 : 0); - if (auto_create_c == false) - $$ = cat_str(7, mm_strdup("/* exec sql type"), mm_strdup($3), mm_strdup("is"), mm_strdup($5.type_str), mm_strdup($6.str), $7, mm_strdup("*/")); - else - $$ = cat_str(6, mm_strdup("typedef "), mm_strdup($5.type_str), *$7?mm_strdup("*"):mm_strdup(""), mm_strdup($3), mm_strdup($6.str), mm_strdup(";")); - } - ; + if (auto_create_c == false) + $$ = cat_str(7, mm_strdup("/* exec sql type"), mm_strdup($3), mm_strdup("is"), mm_strdup($5.type_str), mm_strdup($6.str), $7, mm_strdup("*/")); + else + $$ = cat_str(6, mm_strdup("typedef "), mm_strdup($5.type_str), *$7 ? mm_strdup("*") : mm_strdup(""), mm_strdup($3), mm_strdup($6.str), mm_strdup(";")); + } + ; -opt_reference: SQL_REFERENCE { $$ = mm_strdup("reference"); } - | /*EMPTY*/ { $$ = EMPTY; } - ; +opt_reference: SQL_REFERENCE + { + $$ = mm_strdup("reference"); + } + | /* EMPTY */ + { + $$ = EMPTY; + } + ; /* * define the type of one variable for embedded SQL */ ECPGVar: SQL_VAR - { - /* reset this variable so we see if there was */ - /* an initializer specified */ - initializer = 0; - } - ColLabel IS var_type opt_array_bounds opt_reference - { - struct variable *p = find_variable($3); - char *dimension = $6.index1; - char *length = $6.index2; - struct ECPGtype * type; + { + /* reset this variable so we see if there was */ + /* an initializer specified */ + initializer = 0; + } + ColLabel IS var_type opt_array_bounds opt_reference + { + struct variable *p = find_variable($3); + char *dimension = $6.index1; + char *length = $6.index2; + struct ECPGtype *type; - if (($5.type_enum == ECPGt_struct || - $5.type_enum == ECPGt_union) && - initializer == 1) - mmerror(PARSE_ERROR, ET_ERROR, "initializer not allowed in EXEC SQL VAR command"); - else + if (($5.type_enum == ECPGt_struct || + $5.type_enum == ECPGt_union) && + initializer == 1) + mmerror(PARSE_ERROR, ET_ERROR, "initializer not allowed in EXEC SQL VAR command"); + else + { + adjust_array($5.type_enum, &dimension, &length, $5.type_dimension, $5.type_index, *$7 ? 1 : 0, false); + + switch ($5.type_enum) { - adjust_array($5.type_enum, &dimension, &length, $5.type_dimension, $5.type_index, *$7?1:0, false); - - switch ($5.type_enum) - { case ECPGt_struct: case ECPGt_union: - if (atoi(dimension) < 0) - type = ECPGmake_struct_type(struct_member_list[struct_level], $5.type_enum, $5.type_str, $5.type_sizeof); - else - type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], $5.type_enum, $5.type_str, $5.type_sizeof), dimension); - break; + if (atoi(dimension) < 0) + type = ECPGmake_struct_type(struct_member_list[struct_level], $5.type_enum, $5.type_str, $5.type_sizeof); + else + type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], $5.type_enum, $5.type_str, $5.type_sizeof), dimension); + break; case ECPGt_varchar: case ECPGt_bytea: - if (atoi(dimension) == -1) - type = ECPGmake_simple_type($5.type_enum, length, 0); - else - type = ECPGmake_array_type(ECPGmake_simple_type($5.type_enum, length, 0), dimension); - break; + if (atoi(dimension) == -1) + type = ECPGmake_simple_type($5.type_enum, length, 0); + else + type = ECPGmake_array_type(ECPGmake_simple_type($5.type_enum, length, 0), dimension); + break; case ECPGt_char: case ECPGt_unsigned_char: case ECPGt_string: - if (atoi(dimension) == -1) - type = ECPGmake_simple_type($5.type_enum, length, 0); - else - type = ECPGmake_array_type(ECPGmake_simple_type($5.type_enum, length, 0), dimension); - break; + if (atoi(dimension) == -1) + type = ECPGmake_simple_type($5.type_enum, length, 0); + else + type = ECPGmake_array_type(ECPGmake_simple_type($5.type_enum, length, 0), dimension); + break; default: - if (atoi(length) >= 0) - mmerror(PARSE_ERROR, ET_ERROR, "multidimensional arrays for simple data types are not supported"); + if (atoi(length) >= 0) + mmerror(PARSE_ERROR, ET_ERROR, "multidimensional arrays for simple data types are not supported"); - if (atoi(dimension) < 0) - type = ECPGmake_simple_type($5.type_enum, mm_strdup("1"), 0); - else - type = ECPGmake_array_type(ECPGmake_simple_type($5.type_enum, mm_strdup("1"), 0), dimension); - break; - } - - ECPGfree_type(p->type); - p->type = type; + if (atoi(dimension) < 0) + type = ECPGmake_simple_type($5.type_enum, mm_strdup("1"), 0); + else + type = ECPGmake_array_type(ECPGmake_simple_type($5.type_enum, mm_strdup("1"), 0), dimension); + break; } - $$ = cat_str(7, mm_strdup("/* exec sql var"), mm_strdup($3), mm_strdup("is"), mm_strdup($5.type_str), mm_strdup($6.str), $7, mm_strdup("*/")); + ECPGfree_type(p->type); + p->type = type; } - ; + + $$ = cat_str(7, mm_strdup("/* exec sql var"), mm_strdup($3), mm_strdup("is"), mm_strdup($5.type_str), mm_strdup($6.str), $7, mm_strdup("*/")); + } + ; /* * whenever statement: decide what to do in case of error/no data found * according to SQL standards we lack: SQLSTATE, CONSTRAINT and SQLEXCEPTION */ ECPGWhenever: SQL_WHENEVER SQL_SQLERROR action - { - when_error.code = $3.code; - when_error.command = $3.command; - $$ = cat_str(3, mm_strdup("/* exec sql whenever sqlerror "), $3.str, mm_strdup("; */")); - } - | SQL_WHENEVER NOT SQL_FOUND action - { - when_nf.code = $4.code; - when_nf.command = $4.command; - $$ = cat_str(3, mm_strdup("/* exec sql whenever not found "), $4.str, mm_strdup("; */")); - } - | SQL_WHENEVER SQL_SQLWARNING action - { - when_warn.code = $3.code; - when_warn.command = $3.command; - $$ = cat_str(3, mm_strdup("/* exec sql whenever sql_warning "), $3.str, mm_strdup("; */")); - } - ; + { + when_error.code = $3.code; + when_error.command = $3.command; + $$ = cat_str(3, mm_strdup("/* exec sql whenever sqlerror "), $3.str, mm_strdup("; */")); + } + | SQL_WHENEVER NOT SQL_FOUND action + { + when_nf.code = $4.code; + when_nf.command = $4.command; + $$ = cat_str(3, mm_strdup("/* exec sql whenever not found "), $4.str, mm_strdup("; */")); + } + | SQL_WHENEVER SQL_SQLWARNING action + { + when_warn.code = $3.code; + when_warn.command = $3.command; + $$ = cat_str(3, mm_strdup("/* exec sql whenever sql_warning "), $3.str, mm_strdup("; */")); + } + ; -action : CONTINUE_P - { - $$.code = W_NOTHING; - $$.command = NULL; - $$.str = mm_strdup("continue"); - } - | SQL_SQLPRINT - { - $$.code = W_SQLPRINT; - $$.command = NULL; - $$.str = mm_strdup("sqlprint"); - } - | SQL_STOP - { - $$.code = W_STOP; - $$.command = NULL; - $$.str = mm_strdup("stop"); - } - | SQL_GOTO name - { - $$.code = W_GOTO; - $$.command = mm_strdup($2); - $$.str = cat2_str(mm_strdup("goto "), $2); - } - | SQL_GO TO name - { - $$.code = W_GOTO; - $$.command = mm_strdup($3); - $$.str = cat2_str(mm_strdup("goto "), $3); - } - | DO name '(' c_args ')' - { - $$.code = W_DO; - $$.command = cat_str(4, $2, mm_strdup("("), $4, mm_strdup(")")); - $$.str = cat2_str(mm_strdup("do"), mm_strdup($$.command)); - } - | DO SQL_BREAK - { - $$.code = W_BREAK; - $$.command = NULL; - $$.str = mm_strdup("break"); - } - | DO CONTINUE_P - { - $$.code = W_CONTINUE; - $$.command = NULL; - $$.str = mm_strdup("continue"); - } - | CALL name '(' c_args ')' - { - $$.code = W_DO; - $$.command = cat_str(4, $2, mm_strdup("("), $4, mm_strdup(")")); - $$.str = cat2_str(mm_strdup("call"), mm_strdup($$.command)); - } - | CALL name - { - $$.code = W_DO; - $$.command = cat2_str($2, mm_strdup("()")); - $$.str = cat2_str(mm_strdup("call"), mm_strdup($$.command)); - } - ; +action: CONTINUE_P + { + $$.code = W_NOTHING; + $$.command = NULL; + $$.str = mm_strdup("continue"); + } + | SQL_SQLPRINT + { + $$.code = W_SQLPRINT; + $$.command = NULL; + $$.str = mm_strdup("sqlprint"); + } + | SQL_STOP + { + $$.code = W_STOP; + $$.command = NULL; + $$.str = mm_strdup("stop"); + } + | SQL_GOTO name + { + $$.code = W_GOTO; + $$.command = mm_strdup($2); + $$.str = cat2_str(mm_strdup("goto "), $2); + } + | SQL_GO TO name + { + $$.code = W_GOTO; + $$.command = mm_strdup($3); + $$.str = cat2_str(mm_strdup("goto "), $3); + } + | DO name '(' c_args ')' + { + $$.code = W_DO; + $$.command = cat_str(4, $2, mm_strdup("("), $4, mm_strdup(")")); + $$.str = cat2_str(mm_strdup("do"), mm_strdup($$.command)); + } + | DO SQL_BREAK + { + $$.code = W_BREAK; + $$.command = NULL; + $$.str = mm_strdup("break"); + } + | DO CONTINUE_P + { + $$.code = W_CONTINUE; + $$.command = NULL; + $$.str = mm_strdup("continue"); + } + | CALL name '(' c_args ')' + { + $$.code = W_DO; + $$.command = cat_str(4, $2, mm_strdup("("), $4, mm_strdup(")")); + $$.str = cat2_str(mm_strdup("call"), mm_strdup($$.command)); + } + | CALL name + { + $$.code = W_DO; + $$.command = cat2_str($2, mm_strdup("()")); + $$.str = cat2_str(mm_strdup("call"), mm_strdup($$.command)); + } + ; /* some other stuff for ecpg */ /* additional unreserved keywords */ -ECPGKeywords: ECPGKeywords_vanames { $$ = $1; } - | ECPGKeywords_rest { $$ = $1; } - ; +ECPGKeywords: ECPGKeywords_vanames { $$ = $1; } + | ECPGKeywords_rest { $$ = $1; } + ; -ECPGKeywords_vanames: SQL_BREAK { $$ = mm_strdup("break"); } - | SQL_CARDINALITY { $$ = mm_strdup("cardinality"); } - | SQL_COUNT { $$ = mm_strdup("count"); } - | SQL_DATETIME_INTERVAL_CODE { $$ = mm_strdup("datetime_interval_code"); } - | SQL_DATETIME_INTERVAL_PRECISION { $$ = mm_strdup("datetime_interval_precision"); } - | SQL_FOUND { $$ = mm_strdup("found"); } - | SQL_GO { $$ = mm_strdup("go"); } - | SQL_GOTO { $$ = mm_strdup("goto"); } - | SQL_IDENTIFIED { $$ = mm_strdup("identified"); } - | SQL_INDICATOR { $$ = mm_strdup("indicator"); } - | SQL_KEY_MEMBER { $$ = mm_strdup("key_member"); } - | SQL_LENGTH { $$ = mm_strdup("length"); } - | SQL_NULLABLE { $$ = mm_strdup("nullable"); } - | SQL_OCTET_LENGTH { $$ = mm_strdup("octet_length"); } - | SQL_RETURNED_LENGTH { $$ = mm_strdup("returned_length"); } - | SQL_RETURNED_OCTET_LENGTH { $$ = mm_strdup("returned_octet_length"); } - | SQL_SCALE { $$ = mm_strdup("scale"); } - | SQL_SECTION { $$ = mm_strdup("section"); } - | SQL_SQLERROR { $$ = mm_strdup("sqlerror"); } - | SQL_SQLPRINT { $$ = mm_strdup("sqlprint"); } - | SQL_SQLWARNING { $$ = mm_strdup("sqlwarning"); } - | SQL_STOP { $$ = mm_strdup("stop"); } - ; +ECPGKeywords_vanames: SQL_BREAK { $$ = mm_strdup("break"); } + | SQL_CARDINALITY { $$ = mm_strdup("cardinality"); } + | SQL_COUNT { $$ = mm_strdup("count"); } + | SQL_DATETIME_INTERVAL_CODE { $$ = mm_strdup("datetime_interval_code"); } + | SQL_DATETIME_INTERVAL_PRECISION { $$ = mm_strdup("datetime_interval_precision"); } + | SQL_FOUND { $$ = mm_strdup("found"); } + | SQL_GO { $$ = mm_strdup("go"); } + | SQL_GOTO { $$ = mm_strdup("goto"); } + | SQL_IDENTIFIED { $$ = mm_strdup("identified"); } + | SQL_INDICATOR { $$ = mm_strdup("indicator"); } + | SQL_KEY_MEMBER { $$ = mm_strdup("key_member"); } + | SQL_LENGTH { $$ = mm_strdup("length"); } + | SQL_NULLABLE { $$ = mm_strdup("nullable"); } + | SQL_OCTET_LENGTH { $$ = mm_strdup("octet_length"); } + | SQL_RETURNED_LENGTH { $$ = mm_strdup("returned_length"); } + | SQL_RETURNED_OCTET_LENGTH { $$ = mm_strdup("returned_octet_length"); } + | SQL_SCALE { $$ = mm_strdup("scale"); } + | SQL_SECTION { $$ = mm_strdup("section"); } + | SQL_SQLERROR { $$ = mm_strdup("sqlerror"); } + | SQL_SQLPRINT { $$ = mm_strdup("sqlprint"); } + | SQL_SQLWARNING { $$ = mm_strdup("sqlwarning"); } + | SQL_STOP { $$ = mm_strdup("stop"); } + ; -ECPGKeywords_rest: SQL_CONNECT { $$ = mm_strdup("connect"); } - | SQL_DESCRIBE { $$ = mm_strdup("describe"); } - | SQL_DISCONNECT { $$ = mm_strdup("disconnect"); } - | SQL_OPEN { $$ = mm_strdup("open"); } - | SQL_VAR { $$ = mm_strdup("var"); } - | SQL_WHENEVER { $$ = mm_strdup("whenever"); } - ; +ECPGKeywords_rest: SQL_CONNECT { $$ = mm_strdup("connect"); } + | SQL_DESCRIBE { $$ = mm_strdup("describe"); } + | SQL_DISCONNECT { $$ = mm_strdup("disconnect"); } + | SQL_OPEN { $$ = mm_strdup("open"); } + | SQL_VAR { $$ = mm_strdup("var"); } + | SQL_WHENEVER { $$ = mm_strdup("whenever"); } + ; /* additional keywords that can be SQL type names (but not ECPGColLabels) */ -ECPGTypeName: SQL_BOOL { $$ = mm_strdup("bool"); } - | SQL_LONG { $$ = mm_strdup("long"); } - | SQL_OUTPUT { $$ = mm_strdup("output"); } - | SQL_SHORT { $$ = mm_strdup("short"); } - | SQL_STRUCT { $$ = mm_strdup("struct"); } - | SQL_SIGNED { $$ = mm_strdup("signed"); } - | SQL_UNSIGNED { $$ = mm_strdup("unsigned"); } - ; +ECPGTypeName: SQL_BOOL { $$ = mm_strdup("bool"); } + | SQL_LONG { $$ = mm_strdup("long"); } + | SQL_OUTPUT { $$ = mm_strdup("output"); } + | SQL_SHORT { $$ = mm_strdup("short"); } + | SQL_STRUCT { $$ = mm_strdup("struct"); } + | SQL_SIGNED { $$ = mm_strdup("signed"); } + | SQL_UNSIGNED { $$ = mm_strdup("unsigned"); } + ; -symbol: ColLabel { $$ = $1; } - ; +symbol: ColLabel { $$ = $1; } + ; -ECPGColId: ecpg_ident { $$ = $1; } - | unreserved_keyword { $$ = $1; } - | col_name_keyword { $$ = $1; } - | ECPGunreserved_interval { $$ = $1; } - | ECPGKeywords { $$ = $1; } - | ECPGCKeywords { $$ = $1; } - | CHAR_P { $$ = mm_strdup("char"); } - | VALUES { $$ = mm_strdup("values"); } - ; +ECPGColId: ecpg_ident { $$ = $1; } + | unreserved_keyword { $$ = $1; } + | col_name_keyword { $$ = $1; } + | ECPGunreserved_interval { $$ = $1; } + | ECPGKeywords { $$ = $1; } + | ECPGCKeywords { $$ = $1; } + | CHAR_P { $$ = mm_strdup("char"); } + | VALUES { $$ = mm_strdup("values"); } + ; /* * Name classification hierarchy. @@ -1691,59 +2018,59 @@ ECPGColId: ecpg_ident { $$ = $1; } /* Column identifier --- names that can be column, table, etc names. */ -ColId: ecpg_ident { $$ = $1; } - | all_unreserved_keyword { $$ = $1; } - | col_name_keyword { $$ = $1; } - | ECPGKeywords { $$ = $1; } - | ECPGCKeywords { $$ = $1; } - | CHAR_P { $$ = mm_strdup("char"); } - | VALUES { $$ = mm_strdup("values"); } - ; +ColId: ecpg_ident { $$ = $1; } + | all_unreserved_keyword { $$ = $1; } + | col_name_keyword { $$ = $1; } + | ECPGKeywords { $$ = $1; } + | ECPGCKeywords { $$ = $1; } + | CHAR_P { $$ = mm_strdup("char"); } + | VALUES { $$ = mm_strdup("values"); } + ; /* Type/function identifier --- names that can be type or function names. */ -type_function_name: ecpg_ident { $$ = $1; } - | all_unreserved_keyword { $$ = $1; } - | type_func_name_keyword { $$ = $1; } - | ECPGKeywords { $$ = $1; } - | ECPGCKeywords { $$ = $1; } - | ECPGTypeName { $$ = $1; } - ; +type_function_name: ecpg_ident { $$ = $1; } + | all_unreserved_keyword { $$ = $1; } + | type_func_name_keyword { $$ = $1; } + | ECPGKeywords { $$ = $1; } + | ECPGCKeywords { $$ = $1; } + | ECPGTypeName { $$ = $1; } + ; /* Column label --- allowed labels in "AS" clauses. * This presently includes *all* Postgres keywords. */ -ColLabel: ECPGColLabel { $$ = $1; } - | ECPGTypeName { $$ = $1; } - | CHAR_P { $$ = mm_strdup("char"); } - | CURRENT_P { $$ = mm_strdup("current"); } - | INPUT_P { $$ = mm_strdup("input"); } - | INT_P { $$ = mm_strdup("int"); } - | TO { $$ = mm_strdup("to"); } - | UNION { $$ = mm_strdup("union"); } - | VALUES { $$ = mm_strdup("values"); } - | ECPGCKeywords { $$ = $1; } - | ECPGunreserved_interval { $$ = $1; } - ; +ColLabel: ECPGColLabel { $$ = $1; } + | ECPGTypeName { $$ = $1; } + | CHAR_P { $$ = mm_strdup("char"); } + | CURRENT_P { $$ = mm_strdup("current"); } + | INPUT_P { $$ = mm_strdup("input"); } + | INT_P { $$ = mm_strdup("int"); } + | TO { $$ = mm_strdup("to"); } + | UNION { $$ = mm_strdup("union"); } + | VALUES { $$ = mm_strdup("values"); } + | ECPGCKeywords { $$ = $1; } + | ECPGunreserved_interval { $$ = $1; } + ; -ECPGColLabel: ecpg_ident { $$ = $1; } - | unreserved_keyword { $$ = $1; } - | col_name_keyword { $$ = $1; } - | type_func_name_keyword { $$ = $1; } - | reserved_keyword { $$ = $1; } - | ECPGKeywords_vanames { $$ = $1; } - | ECPGKeywords_rest { $$ = $1; } - | CONNECTION { $$ = mm_strdup("connection"); } - ; +ECPGColLabel: ecpg_ident { $$ = $1; } + | unreserved_keyword { $$ = $1; } + | col_name_keyword { $$ = $1; } + | type_func_name_keyword { $$ = $1; } + | reserved_keyword { $$ = $1; } + | ECPGKeywords_vanames { $$ = $1; } + | ECPGKeywords_rest { $$ = $1; } + | CONNECTION { $$ = mm_strdup("connection"); } + ; -ECPGCKeywords: S_AUTO { $$ = mm_strdup("auto"); } - | S_CONST { $$ = mm_strdup("const"); } - | S_EXTERN { $$ = mm_strdup("extern"); } - | S_REGISTER { $$ = mm_strdup("register"); } - | S_STATIC { $$ = mm_strdup("static"); } - | S_TYPEDEF { $$ = mm_strdup("typedef"); } - | S_VOLATILE { $$ = mm_strdup("volatile"); } - ; +ECPGCKeywords: S_AUTO { $$ = mm_strdup("auto"); } + | S_CONST { $$ = mm_strdup("const"); } + | S_EXTERN { $$ = mm_strdup("extern"); } + | S_REGISTER { $$ = mm_strdup("register"); } + | S_STATIC { $$ = mm_strdup("static"); } + | S_TYPEDEF { $$ = mm_strdup("typedef"); } + | S_VOLATILE { $$ = mm_strdup("volatile"); } + ; /* "Unreserved" keywords --- available for use as any kind of name. */ @@ -1760,250 +2087,402 @@ ECPGCKeywords: S_AUTO { $$ = mm_strdup("auto"); } * The mentioned exclusions are done by $replace_line settings in parse.pl. */ all_unreserved_keyword: unreserved_keyword { $$ = $1; } - | ECPGunreserved_interval { $$ = $1; } - | CONNECTION { $$ = mm_strdup("connection"); } - ; + | ECPGunreserved_interval { $$ = $1; } + | CONNECTION { $$ = mm_strdup("connection"); } + ; -ECPGunreserved_interval: DAY_P { $$ = mm_strdup("day"); } - | HOUR_P { $$ = mm_strdup("hour"); } - | MINUTE_P { $$ = mm_strdup("minute"); } - | MONTH_P { $$ = mm_strdup("month"); } - | SECOND_P { $$ = mm_strdup("second"); } - | YEAR_P { $$ = mm_strdup("year"); } - ; +ECPGunreserved_interval: DAY_P { $$ = mm_strdup("day"); } + | HOUR_P { $$ = mm_strdup("hour"); } + | MINUTE_P { $$ = mm_strdup("minute"); } + | MONTH_P { $$ = mm_strdup("month"); } + | SECOND_P { $$ = mm_strdup("second"); } + | YEAR_P { $$ = mm_strdup("year"); } + ; +into_list: coutputvariable | into_list ',' coutputvariable + ; -into_list : coutputvariable | into_list ',' coutputvariable - ; +ecpgstart: SQL_START + { + reset_variables(); + pacounter = 1; + } + ; -ecpgstart: SQL_START { - reset_variables(); - pacounter = 1; - } - ; - -c_args: /*EMPTY*/ { $$ = EMPTY; } - | c_list { $$ = $1; } - ; +c_args: /* EMPTY */ + { + $$ = EMPTY; + } + | c_list + { + $$ = $1; + } + ; coutputvariable: cvariable indicator - { add_variable_to_head(&argsresult, find_variable($1), find_variable($2)); } - | cvariable - { add_variable_to_head(&argsresult, find_variable($1), &no_indicator); } - ; + { + add_variable_to_head(&argsresult, find_variable($1), find_variable($2)); + } + | cvariable + { + add_variable_to_head(&argsresult, find_variable($1), &no_indicator); + } + ; civarind: cvariable indicator - { - if (find_variable($2)->type->type == ECPGt_array) - mmerror(PARSE_ERROR, ET_ERROR, "arrays of indicators are not allowed on input"); + { + if (find_variable($2)->type->type == ECPGt_array) + mmerror(PARSE_ERROR, ET_ERROR, "arrays of indicators are not allowed on input"); - add_variable_to_head(&argsinsert, find_variable($1), find_variable($2)); - $$ = create_questionmarks($1, false); - } - ; + add_variable_to_head(&argsinsert, find_variable($1), find_variable($2)); + $$ = create_questionmarks($1, false); + } + ; char_civar: char_variable - { - char *ptr = strstr($1, ".arr"); + { + char *ptr = strstr($1, ".arr"); - if (ptr) /* varchar, we need the struct name here, not the struct element */ - *ptr = '\0'; - add_variable_to_head(&argsinsert, find_variable($1), &no_indicator); - $$ = $1; - } - ; + if (ptr) /* varchar, we need the struct name here, not + * the struct element */ + *ptr = '\0'; + add_variable_to_head(&argsinsert, find_variable($1), &no_indicator); + $$ = $1; + } + ; civar: cvariable + { + add_variable_to_head(&argsinsert, find_variable($1), &no_indicator); + $$ = create_questionmarks($1, false); + } + ; + +indicator: cvariable + { + check_indicator((find_variable($1))->type); + $$ = $1; + } + | SQL_INDICATOR cvariable + { + check_indicator((find_variable($2))->type); + $$ = $2; + } + | SQL_INDICATOR name + { + check_indicator((find_variable($2))->type); + $$ = $2; + } + ; + +cvariable: CVARIABLE + { + /* + * As long as multidimensional arrays are not implemented we have to + * check for those here + */ + char *ptr = $1; + int brace_open = 0, + brace = false; + + for (; *ptr; ptr++) { - add_variable_to_head(&argsinsert, find_variable($1), &no_indicator); - $$ = create_questionmarks($1, false); - } - ; - -indicator: cvariable { check_indicator((find_variable($1))->type); $$ = $1; } - | SQL_INDICATOR cvariable { check_indicator((find_variable($2))->type); $$ = $2; } - | SQL_INDICATOR name { check_indicator((find_variable($2))->type); $$ = $2; } - ; - -cvariable: CVARIABLE - { - /* As long as multidimensional arrays are not implemented we have to check for those here */ - char *ptr = $1; - int brace_open=0, brace = false; - - for (; *ptr; ptr++) + switch (*ptr) { - switch (*ptr) - { - case '[': - if (brace) - mmfatal(PARSE_ERROR, "multidimensional arrays for simple data types are not supported"); - brace_open++; - break; - case ']': - brace_open--; - if (brace_open == 0) - brace = true; - break; - case '\t': - case ' ': - break; - default: - if (brace_open == 0) - brace = false; - break; - } + case '[': + if (brace) + mmfatal(PARSE_ERROR, "multidimensional arrays for simple data types are not supported"); + brace_open++; + break; + case ']': + brace_open--; + if (brace_open == 0) + brace = true; + break; + case '\t': + case ' ': + break; + default: + if (brace_open == 0) + brace = false; + break; } - $$ = $1; } - ; + $$ = $1; + } + ; -ecpg_param: PARAM { $$ = make_name(); } ; +ecpg_param: PARAM + { + $$ = make_name(); + } + ; -ecpg_bconst: BCONST { $$ = $1; } ; +ecpg_bconst: BCONST + { + $$ = $1; + } + ; -ecpg_fconst: FCONST { $$ = make_name(); } ; +ecpg_fconst: FCONST + { + $$ = make_name(); + } + ; -ecpg_sconst: SCONST { $$ = $1; } ; +ecpg_sconst: SCONST + { + $$ = $1; + } + ; -ecpg_xconst: XCONST { $$ = $1; } ; +ecpg_xconst: XCONST + { + $$ = $1; + } + ; -ecpg_ident: IDENT { $$ = $1; } - | CSTRING { $$ = make3_str(mm_strdup("\""), $1, mm_strdup("\"")); } - ; +ecpg_ident: IDENT + { + $$ = $1; + } + | CSTRING + { + $$ = make3_str(mm_strdup("\""), $1, mm_strdup("\"")); + } + ; quoted_ident_stringvar: name - { $$ = make3_str(mm_strdup("\""), $1, mm_strdup("\"")); } - | char_variable - { $$ = make3_str(mm_strdup("("), $1, mm_strdup(")")); } - ; + { + $$ = make3_str(mm_strdup("\""), $1, mm_strdup("\"")); + } + | char_variable + { + $$ = make3_str(mm_strdup("("), $1, mm_strdup(")")); + } + ; /* * C stuff */ -c_stuff_item: c_anything { $$ = $1; } - | '(' ')' { $$ = mm_strdup("()"); } - | '(' c_stuff ')' - { $$ = cat_str(3, mm_strdup("("), $2, mm_strdup(")")); } - ; - -c_stuff: c_stuff_item { $$ = $1; } - | c_stuff c_stuff_item - { $$ = cat2_str($1, $2); } - ; - -c_list: c_term { $$ = $1; } - | c_list ',' c_term { $$ = cat_str(3, $1, mm_strdup(","), $3); } - ; - -c_term: c_stuff { $$ = $1; } - | '{' c_list '}' { $$ = cat_str(3, mm_strdup("{"), $2, mm_strdup("}")); } - ; - -c_thing: c_anything { $$ = $1; } - | '(' { $$ = mm_strdup("("); } - | ')' { $$ = mm_strdup(")"); } - | ',' { $$ = mm_strdup(","); } - | ';' { $$ = mm_strdup(";"); } - ; - -c_anything: ecpg_ident { $$ = $1; } - | Iconst { $$ = $1; } - | ecpg_fconst { $$ = $1; } - | ecpg_sconst { $$ = $1; } - | '*' { $$ = mm_strdup("*"); } - | '+' { $$ = mm_strdup("+"); } - | '-' { $$ = mm_strdup("-"); } - | '/' { $$ = mm_strdup("/"); } - | '%' { $$ = mm_strdup("%"); } - | NULL_P { $$ = mm_strdup("NULL"); } - | S_ADD { $$ = mm_strdup("+="); } - | S_AND { $$ = mm_strdup("&&"); } - | S_ANYTHING { $$ = make_name(); } - | S_AUTO { $$ = mm_strdup("auto"); } - | S_CONST { $$ = mm_strdup("const"); } - | S_DEC { $$ = mm_strdup("--"); } - | S_DIV { $$ = mm_strdup("/="); } - | S_DOTPOINT { $$ = mm_strdup(".*"); } - | S_EQUAL { $$ = mm_strdup("=="); } - | S_EXTERN { $$ = mm_strdup("extern"); } - | S_INC { $$ = mm_strdup("++"); } - | S_LSHIFT { $$ = mm_strdup("<<"); } - | S_MEMBER { $$ = mm_strdup("->"); } - | S_MEMPOINT { $$ = mm_strdup("->*"); } - | S_MOD { $$ = mm_strdup("%="); } - | S_MUL { $$ = mm_strdup("*="); } - | S_NEQUAL { $$ = mm_strdup("!="); } - | S_OR { $$ = mm_strdup("||"); } - | S_REGISTER { $$ = mm_strdup("register"); } - | S_RSHIFT { $$ = mm_strdup(">>"); } - | S_STATIC { $$ = mm_strdup("static"); } - | S_SUB { $$ = mm_strdup("-="); } - | S_TYPEDEF { $$ = mm_strdup("typedef"); } - | S_VOLATILE { $$ = mm_strdup("volatile"); } - | SQL_BOOL { $$ = mm_strdup("bool"); } - | ENUM_P { $$ = mm_strdup("enum"); } - | HOUR_P { $$ = mm_strdup("hour"); } - | INT_P { $$ = mm_strdup("int"); } - | SQL_LONG { $$ = mm_strdup("long"); } - | MINUTE_P { $$ = mm_strdup("minute"); } - | MONTH_P { $$ = mm_strdup("month"); } - | SECOND_P { $$ = mm_strdup("second"); } - | SQL_SHORT { $$ = mm_strdup("short"); } - | SQL_SIGNED { $$ = mm_strdup("signed"); } - | SQL_STRUCT { $$ = mm_strdup("struct"); } - | SQL_UNSIGNED { $$ = mm_strdup("unsigned"); } - | YEAR_P { $$ = mm_strdup("year"); } - | CHAR_P { $$ = mm_strdup("char"); } - | FLOAT_P { $$ = mm_strdup("float"); } - | TO { $$ = mm_strdup("to"); } - | UNION { $$ = mm_strdup("union"); } - | VARCHAR { $$ = mm_strdup("varchar"); } - | '[' { $$ = mm_strdup("["); } - | ']' { $$ = mm_strdup("]"); } - | '=' { $$ = mm_strdup("="); } - | ':' { $$ = mm_strdup(":"); } - ; - -DeallocateStmt: DEALLOCATE prepared_name { check_declared_list($2); $$ = $2; } - | DEALLOCATE PREPARE prepared_name { check_declared_list($3); $$ = $3; } - | DEALLOCATE ALL { $$ = mm_strdup("all"); } - | DEALLOCATE PREPARE ALL { $$ = mm_strdup("all"); } - ; - -Iresult: Iconst { $$ = $1; } - | '(' Iresult ')' { $$ = cat_str(3, mm_strdup("("), $2, mm_strdup(")")); } - | Iresult '+' Iresult { $$ = cat_str(3, $1, mm_strdup("+"), $3); } - | Iresult '-' Iresult { $$ = cat_str(3, $1, mm_strdup("-"), $3); } - | Iresult '*' Iresult { $$ = cat_str(3, $1, mm_strdup("*"), $3); } - | Iresult '/' Iresult { $$ = cat_str(3, $1, mm_strdup("/"), $3); } - | Iresult '%' Iresult { $$ = cat_str(3, $1, mm_strdup("%"), $3); } - | ecpg_sconst { $$ = $1; } - | ColId { $$ = $1; } - | ColId '(' var_type ')' { if (pg_strcasecmp($1, "sizeof") != 0) - mmerror(PARSE_ERROR, ET_ERROR, "operator not allowed in variable definition"); - else - $$ = cat_str(4, $1, mm_strdup("("), $3.type_str, mm_strdup(")")); - } - ; - -execute_rest: /* EMPTY */ { $$ = EMPTY; } - | ecpg_using opt_ecpg_into { $$ = EMPTY; } - | ecpg_into ecpg_using { $$ = EMPTY; } - | ecpg_into { $$ = EMPTY; } +c_stuff_item: c_anything + { + $$ = $1; + } + | '(' ')' + { + $$ = mm_strdup("()"); + } + | '(' c_stuff ')' + { + $$ = cat_str(3, mm_strdup("("), $2, mm_strdup(")")); + } ; -ecpg_into: INTO into_list { $$ = EMPTY; } - | into_descriptor { $$ = $1; } +c_stuff: c_stuff_item + { + $$ = $1; + } + | c_stuff c_stuff_item + { + $$ = cat2_str($1, $2); + } ; -opt_ecpg_into: /* EMPTY */ { $$ = EMPTY; } - | ecpg_into { $$ = $1; } +c_list: c_term + { + $$ = $1; + } + | c_list ',' c_term + { + $$ = cat_str(3, $1, mm_strdup(","), $3); + } ; -ecpg_fetch_into: ecpg_into { $$ = $1; } +c_term: c_stuff + { + $$ = $1; + } + | '{' c_list '}' + { + $$ = cat_str(3, mm_strdup("{"), $2, mm_strdup("}")); + } + ; + +c_thing: c_anything { $$ = $1; } + | '(' { $$ = mm_strdup("("); } + | ')' { $$ = mm_strdup(")"); } + | ',' { $$ = mm_strdup(","); } + | ';' { $$ = mm_strdup(";"); } + ; + +c_anything: ecpg_ident { $$ = $1; } + | Iconst { $$ = $1; } + | ecpg_fconst { $$ = $1; } + | ecpg_sconst { $$ = $1; } + | '*' { $$ = mm_strdup("*"); } + | '+' { $$ = mm_strdup("+"); } + | '-' { $$ = mm_strdup("-"); } + | '/' { $$ = mm_strdup("/"); } + | '%' { $$ = mm_strdup("%"); } + | NULL_P { $$ = mm_strdup("NULL"); } + | S_ADD { $$ = mm_strdup("+="); } + | S_AND { $$ = mm_strdup("&&"); } + | S_ANYTHING { $$ = make_name(); } + | S_AUTO { $$ = mm_strdup("auto"); } + | S_CONST { $$ = mm_strdup("const"); } + | S_DEC { $$ = mm_strdup("--"); } + | S_DIV { $$ = mm_strdup("/="); } + | S_DOTPOINT { $$ = mm_strdup(".*"); } + | S_EQUAL { $$ = mm_strdup("=="); } + | S_EXTERN { $$ = mm_strdup("extern"); } + | S_INC { $$ = mm_strdup("++"); } + | S_LSHIFT { $$ = mm_strdup("<<"); } + | S_MEMBER { $$ = mm_strdup("->"); } + | S_MEMPOINT { $$ = mm_strdup("->*"); } + | S_MOD { $$ = mm_strdup("%="); } + | S_MUL { $$ = mm_strdup("*="); } + | S_NEQUAL { $$ = mm_strdup("!="); } + | S_OR { $$ = mm_strdup("||"); } + | S_REGISTER { $$ = mm_strdup("register"); } + | S_RSHIFT { $$ = mm_strdup(">>"); } + | S_STATIC { $$ = mm_strdup("static"); } + | S_SUB { $$ = mm_strdup("-="); } + | S_TYPEDEF { $$ = mm_strdup("typedef"); } + | S_VOLATILE { $$ = mm_strdup("volatile"); } + | SQL_BOOL { $$ = mm_strdup("bool"); } + | ENUM_P { $$ = mm_strdup("enum"); } + | HOUR_P { $$ = mm_strdup("hour"); } + | INT_P { $$ = mm_strdup("int"); } + | SQL_LONG { $$ = mm_strdup("long"); } + | MINUTE_P { $$ = mm_strdup("minute"); } + | MONTH_P { $$ = mm_strdup("month"); } + | SECOND_P { $$ = mm_strdup("second"); } + | SQL_SHORT { $$ = mm_strdup("short"); } + | SQL_SIGNED { $$ = mm_strdup("signed"); } + | SQL_STRUCT { $$ = mm_strdup("struct"); } + | SQL_UNSIGNED { $$ = mm_strdup("unsigned"); } + | YEAR_P { $$ = mm_strdup("year"); } + | CHAR_P { $$ = mm_strdup("char"); } + | FLOAT_P { $$ = mm_strdup("float"); } + | TO { $$ = mm_strdup("to"); } + | UNION { $$ = mm_strdup("union"); } + | VARCHAR { $$ = mm_strdup("varchar"); } + | '[' { $$ = mm_strdup("["); } + | ']' { $$ = mm_strdup("]"); } + | '=' { $$ = mm_strdup("="); } + | ':' { $$ = mm_strdup(":"); } + ; + +DeallocateStmt: DEALLOCATE prepared_name + { + check_declared_list($2); + $$ = $2; + } + | DEALLOCATE PREPARE prepared_name + { + check_declared_list($3); + $$ = $3; + } + | DEALLOCATE ALL + { + $$ = mm_strdup("all"); + } + | DEALLOCATE PREPARE ALL + { + $$ = mm_strdup("all"); + } + ; + +Iresult: Iconst + { + $$ = $1; + } + | '(' Iresult ')' + { + $$ = cat_str(3, mm_strdup("("), $2, mm_strdup(")")); + } + | Iresult '+' Iresult + { + $$ = cat_str(3, $1, mm_strdup("+"), $3); + } + | Iresult '-' Iresult + { + $$ = cat_str(3, $1, mm_strdup("-"), $3); + } + | Iresult '*' Iresult + { + $$ = cat_str(3, $1, mm_strdup("*"), $3); + } + | Iresult '/' Iresult + { + $$ = cat_str(3, $1, mm_strdup("/"), $3); + } + | Iresult '%' Iresult + { + $$ = cat_str(3, $1, mm_strdup("%"), $3); + } + | ecpg_sconst + { + $$ = $1; + } + | ColId + { + $$ = $1; + } + | ColId '(' var_type ')' + { + if (pg_strcasecmp($1, "sizeof") != 0) + mmerror(PARSE_ERROR, ET_ERROR, "operator not allowed in variable definition"); + else + $$ = cat_str(4, $1, mm_strdup("("), $3.type_str, mm_strdup(")")); + } + ; + +execute_rest: /* EMPTY */ + { + $$ = EMPTY; + } + | ecpg_using opt_ecpg_into + { + $$ = EMPTY; + } + | ecpg_into ecpg_using + { + $$ = EMPTY; + } + | ecpg_into + { + $$ = EMPTY; + } + ; + +ecpg_into: INTO into_list + { + $$ = EMPTY; + } + | into_descriptor + { + $$ = $1; + } + ; + +opt_ecpg_into: /* EMPTY */ + { + $$ = EMPTY; + } + | ecpg_into + { + $$ = $1; + } + ; + +ecpg_fetch_into: ecpg_into + { + $$ = $1; + } | using_descriptor { struct variable *var; @@ -2015,20 +2494,31 @@ ecpg_fetch_into: ecpg_into { $$ = $1; } } ; -opt_ecpg_fetch_into: /* EMPTY */ { $$ = EMPTY; } - | ecpg_fetch_into { $$ = $1; } +opt_ecpg_fetch_into: /* EMPTY */ + { + $$ = EMPTY; + } + | ecpg_fetch_into + { + $$ = $1; + } ; %% -void base_yyerror(const char *error) +void +base_yyerror(const char *error) { /* translator: %s is typically the translation of "syntax error" */ mmerror(PARSE_ERROR, ET_ERROR, "%s at or near \"%s\"", _(error), token_start ? token_start : base_yytext); } -void parser_init(void) +void +parser_init(void) { - /* This function is empty. It only exists for compatibility with the backend parser right now. */ + /* + * This function is empty. It only exists for compatibility with the + * backend parser right now. + */ } diff --git a/src/interfaces/ecpg/preproc/pgc.l b/src/interfaces/ecpg/preproc/pgc.l index 27261f42d8..f363a34659 100644 --- a/src/interfaces/ecpg/preproc/pgc.l +++ b/src/interfaces/ecpg/preproc/pgc.l @@ -35,8 +35,8 @@ extern YYSTYPE base_yylval; -static int xcdepth = 0; /* depth of nesting in slash-star comments */ -static char *dolqstart = NULL; /* current $foo$ quote start string */ +static int xcdepth = 0; /* depth of nesting in slash-star comments */ +static char *dolqstart = NULL; /* current $foo$ quote start string */ /* * literalbuf is used to accumulate literal values when multiple rules @@ -44,15 +44,15 @@ static char *dolqstart = NULL; /* current $foo$ quote start string */ * to empty, addlit to add text. Note that the buffer is permanently * malloc'd to the largest size needed so far in the current run. */ -static char *literalbuf = NULL; /* expandable buffer */ -static int literallen; /* actual current length */ -static int literalalloc; /* current allocated buffer size */ +static char *literalbuf = NULL; /* expandable buffer */ +static int literallen; /* actual current length */ +static int literalalloc; /* current allocated buffer size */ /* Used for detecting global state together with braces_open */ -static int parenths_open; +static int parenths_open; /* Used to tell parse_include() whether the command was #include or #include_next */ -static bool include_next; +static bool include_next; #define startlit() (literalbuf[0] = '\0', literallen = 0) static void addlit(char *ytext, int yleng); @@ -63,11 +63,11 @@ static bool ecpg_isspace(char ch); static bool isdefine(void); static bool isinformixdefine(void); -char *token_start; +char *token_start; /* vars to keep track of start conditions when scanning literals */ -static int state_before_str_start; -static int state_before_str_stop; +static int state_before_str_start; +static int state_before_str_stop; /* * State for handling include files and macro expansion. We use a new @@ -78,10 +78,10 @@ static int state_before_str_stop; */ static struct _yy_buffer { - YY_BUFFER_STATE buffer; - long lineno; - char *filename; - struct _yy_buffer *next; + YY_BUFFER_STATE buffer; + long lineno; + char *filename; + struct _yy_buffer *next; } *yy_buffer = NULL; /* @@ -541,7 +541,9 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ {xbinside} { addlit(yytext, yyleng); } -<> { mmfatal(PARSE_ERROR, "unterminated bit string literal"); } +<> { + mmfatal(PARSE_ERROR, "unterminated bit string literal"); + } {xhstart} { token_start = yytext; @@ -549,7 +551,9 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ BEGIN(xh); startlit(); } -<> { mmfatal(PARSE_ERROR, "unterminated hexadecimal string literal"); } +<> { + mmfatal(PARSE_ERROR, "unterminated hexadecimal string literal"); + } {xqstart} { token_start = yytext; @@ -560,9 +564,7 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ { {xnstart} { - /* National character. - * Transfer it as-is to the backend. - */ + /* National character. Transfer it as-is to the backend. */ token_start = yytext; state_before_str_start = YYSTATE; BEGIN(xn); @@ -651,29 +653,37 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ } } -{xqdouble} { addlit(yytext, yyleng); } -{xqcquote} { addlit(yytext, yyleng); } -{xqinside} { addlit(yytext, yyleng); } -{xeinside} { +{xqdouble} { addlit(yytext, yyleng); } -{xeunicode} { +{xqcquote} { addlit(yytext, yyleng); } -{xeescape} { +{xqinside} { addlit(yytext, yyleng); } -{xeoctesc} { +{xeinside} { addlit(yytext, yyleng); } -{xehexesc} { +{xeunicode} { + addlit(yytext, yyleng); + } +{xeescape} { + addlit(yytext, yyleng); + } +{xeoctesc} { + addlit(yytext, yyleng); + } +{xehexesc} { addlit(yytext, yyleng); } . { /* This is only needed for \ just before EOF */ addlitchar(yytext[0]); } -<> { mmfatal(PARSE_ERROR, "unterminated quoted string"); } +<> { + mmfatal(PARSE_ERROR, "unterminated quoted string"); + } { {dolqdelim} { @@ -693,7 +703,7 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ } } /* */ -{dolqdelim} { +{dolqdelim} { if (strcmp(yytext, dolqstart) == 0) { addlit(yytext, yyleng); @@ -724,7 +734,9 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ /* single quote or dollar sign */ addlitchar(yytext[0]); } -<> { mmfatal(PARSE_ERROR, "unterminated dollar-quoted string"); } +<> { + mmfatal(PARSE_ERROR, "unterminated dollar-quoted string"); + } { {xdstart} { @@ -743,6 +755,7 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ BEGIN(state_before_str_start); if (literallen == 0) mmerror(PARSE_ERROR, ET_ERROR, "zero-length delimited identifier"); + /* * The server will truncate the identifier here. We do * not, as (1) it does not change the result; (2) we don't @@ -763,26 +776,34 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ BEGIN(state_before_str_start); if (literallen == 0) mmerror(PARSE_ERROR, ET_ERROR, "zero-length delimited identifier"); - /* The backend will truncate the identifier here. We do not as it does not change the result. */ + + /* + * The backend will truncate the identifier here. We do + * not as it does not change the result. + */ base_yylval.str = psprintf("U&\"%s\"", literalbuf); return UIDENT; } -{xddouble} { +{xddouble} { addlit(yytext, yyleng); } -{xdinside} { +{xdinside} { addlit(yytext, yyleng); } -<> { mmfatal(PARSE_ERROR, "unterminated quoted identifier"); } +<> { + mmfatal(PARSE_ERROR, "unterminated quoted identifier"); + } {xdstart} { state_before_str_start = YYSTATE; BEGIN(xdc); startlit(); } -{xdcinside} { +{xdcinside} { addlit(yytext, yyleng); } -<> { mmfatal(PARSE_ERROR, "unterminated quoted string"); } +<> { + mmfatal(PARSE_ERROR, "unterminated quoted string"); + } { {typecast} { @@ -819,21 +840,20 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ return NOT_EQUALS; } -{informix_special} { - /* are we simulating Informix? */ - if (INFORMIX_MODE) - { - unput(':'); - } - else - return yytext[0]; +{informix_special} { + /* are we simulating Informix? */ + if (INFORMIX_MODE) + { + unput(':'); + } + else + return yytext[0]; } {self} { /* - * We may find a ';' inside a structure - * definition in a TYPE or VAR statement. - * This is not an EOL marker. + * We may find a ';' inside a structure definition in a + * TYPE or VAR statement. This is not an EOL marker. */ if (yytext[0] == ';' && struct_level == 0) BEGIN(C); @@ -878,7 +898,8 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ for (ic = nchars - 2; ic >= 0; ic--) { - char c = yytext[ic]; + char c = yytext[ic]; + if (c == '~' || c == '!' || c == '@' || c == '#' || c == '^' || c == '&' || c == '|' || c == '`' || c == '?' || @@ -891,11 +912,12 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ * didn't find a qualifying character, so remove * all trailing [+-] */ - do { + do + { nchars--; } while (nchars > 1 && - (yytext[nchars - 1] == '+' || - yytext[nchars - 1] == '-')); + (yytext[nchars - 1] == '+' || + yytext[nchars - 1] == '-')); } } @@ -903,6 +925,7 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ { /* Strip the unwanted chars from the token */ yyless(nchars); + /* * If what we have left is only one char, and it's * one of the characters matching "self", then @@ -912,6 +935,7 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ if (nchars == 1 && strchr(",()[].;:+-*/%^<>=", yytext[0])) return yytext[0]; + /* * Likewise, if what we have left is two chars, and * those match the tokens ">=", "<=", "=>", "<>" or @@ -999,16 +1023,16 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ * Note that some trailing junk is valid in C (such as 100LL), so we * contain this to SQL mode. */ -{decinteger_junk} { +{decinteger_junk} { mmfatal(PARSE_ERROR, "trailing junk after numeric literal"); } -{hexinteger_junk} { +{hexinteger_junk} { mmfatal(PARSE_ERROR, "trailing junk after numeric literal"); } -{octinteger_junk} { +{octinteger_junk} { mmfatal(PARSE_ERROR, "trailing junk after numeric literal"); } -{bininteger_junk} { +{bininteger_junk} { mmfatal(PARSE_ERROR, "trailing junk after numeric literal"); } {numeric_junk} { @@ -1019,7 +1043,7 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ } :{identifier}((("->"|\.){identifier})|(\[{array}\]))* { - base_yylval.str = mm_strdup(yytext+1); + base_yylval.str = mm_strdup(yytext + 1); return CVARIABLE; } @@ -1027,7 +1051,7 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ /* First check to see if it's a define symbol to expand */ if (!isdefine()) { - int kwvalue; + int kwvalue; /* * User-defined typedefs override SQL keywords, but @@ -1053,8 +1077,8 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ * * The backend will attempt to truncate and case-fold * the identifier, but I see no good reason for ecpg - * to do so; that's just another way that ecpg could get - * out of step with the backend. + * to do so; that's just another way that ecpg could + * get out of step with the backend. */ base_yylval.str = mm_strdup(yytext); return IDENT; @@ -1070,75 +1094,82 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ * Begin ECPG-specific rules */ -{exec_sql} { BEGIN(SQL); return SQL_START; } +{exec_sql} { + BEGIN(SQL); + return SQL_START; + } {informix_special} { - /* are we simulating Informix? */ - if (INFORMIX_MODE) - { - BEGIN(SQL); - return SQL_START; - } - else - return S_ANYTHING; - } -{ccomment} { ECHO; } -{cppinclude} { - if (system_includes) - { - include_next = false; - BEGIN(incl); - } - else - { - base_yylval.str = mm_strdup(yytext); - return CPP_LINE; - } + /* are we simulating Informix? */ + if (INFORMIX_MODE) + { + BEGIN(SQL); + return SQL_START; } -{cppinclude_next} { - if (system_includes) - { - include_next = true; - BEGIN(incl); - } - else - { - base_yylval.str = mm_strdup(yytext); - return CPP_LINE; - } + else + return S_ANYTHING; + } +{ccomment} { + ECHO; + } +{cppinclude} { + if (system_includes) + { + include_next = false; + BEGIN(incl); } -{cppline} { + else + { base_yylval.str = mm_strdup(yytext); return CPP_LINE; } -{identifier} { - /* - * Try to detect a function name: - * look for identifiers at the global scope - * keep the last identifier before the first '(' and '{' - */ - if (braces_open == 0 && parenths_open == 0) - { - if (current_function) - free(current_function); - current_function = mm_strdup(yytext); - } - /* Informix uses SQL defines only in SQL space */ - /* however, some defines have to be taken care of for compatibility */ - if ((!INFORMIX_MODE || !isinformixdefine()) && !isdefine()) - { - int kwvalue; + } +{cppinclude_next} { + if (system_includes) + { + include_next = true; + BEGIN(incl); + } + else + { + base_yylval.str = mm_strdup(yytext); + return CPP_LINE; + } + } +{cppline} { + base_yylval.str = mm_strdup(yytext); + return CPP_LINE; + } +{identifier} { + /* + * Try to detect a function name: + * look for identifiers at the global scope + * keep the last identifier before the first '(' and '{' + */ + if (braces_open == 0 && parenths_open == 0) + { + if (current_function) + free(current_function); + current_function = mm_strdup(yytext); + } + /* Informix uses SQL defines only in SQL space */ + /* however, some defines have to be taken care of for compatibility */ + if ((!INFORMIX_MODE || !isinformixdefine()) && !isdefine()) + { + int kwvalue; - kwvalue = ScanCKeywordLookup(yytext); - if (kwvalue >= 0) - return kwvalue; - else - { - base_yylval.str = mm_strdup(yytext); - return IDENT; - } + kwvalue = ScanCKeywordLookup(yytext); + if (kwvalue >= 0) + return kwvalue; + else + { + base_yylval.str = mm_strdup(yytext); + return IDENT; } } -{xcstop} { mmerror(PARSE_ERROR, ET_ERROR, "nested /* ... */ comments"); } + } +{xcstop} { + mmerror(PARSE_ERROR, ET_ERROR, "nested /* ... */ comments"); + } ":" { return ':'; } ";" { return ';'; } "," { return ','; } @@ -1174,44 +1205,46 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ {other} { return S_ANYTHING; } {exec_sql}{define}{space}* { BEGIN(def_ident); } {informix_special}{define}{space}* { - /* are we simulating Informix? */ - if (INFORMIX_MODE) - { - BEGIN(def_ident); - } - else - { - yyless(1); - return S_ANYTHING; - } + /* are we simulating Informix? */ + if (INFORMIX_MODE) + { + BEGIN(def_ident); } -{exec_sql}{undef}{space}* { BEGIN(undef); } + else + { + yyless(1); + return S_ANYTHING; + } + } +{exec_sql}{undef}{space}* { + BEGIN(undef); + } {informix_special}{undef}{space}* { - /* are we simulating Informix? */ - if (INFORMIX_MODE) - { - BEGIN(undef); - } - else - { - yyless(1); - return S_ANYTHING; - } + /* are we simulating Informix? */ + if (INFORMIX_MODE) + { + BEGIN(undef); } + else + { + yyless(1); + return S_ANYTHING; + } + } {identifier}{space}*";" { - struct _defines *ptr, *ptr2 = NULL; - int i; + struct _defines *ptr, + *ptr2 = NULL; + int i; /* - * Skip the ";" and trailing whitespace. Note that yytext - * contains at least one non-space character plus the ";" + * Skip the ";" and trailing whitespace. Note that yytext + * contains at least one non-space character plus the ";" */ - for (i = strlen(yytext)-2; + for (i = strlen(yytext) - 2; i > 0 && ecpg_isspace(yytext[i]); i--) ; - yytext[i+1] = '\0'; - + yytext[i + 1] = '\0'; /* Find and unset any matching define; should be only 1 */ for (ptr = defines; ptr; ptr2 = ptr, ptr = ptr->next) @@ -1237,88 +1270,90 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ BEGIN(C); } {other}|\n { - mmfatal(PARSE_ERROR, "missing identifier in EXEC SQL UNDEF command"); - yyterminate(); + mmfatal(PARSE_ERROR, "missing identifier in EXEC SQL UNDEF command"); + yyterminate(); + } +{exec_sql}{include}{space}* { + BEGIN(incl); } -{exec_sql}{include}{space}* { BEGIN(incl); } {informix_special}{include}{space}* { - /* are we simulating Informix? */ - if (INFORMIX_MODE) - { - BEGIN(incl); - } - else - { - yyless(1); - return S_ANYTHING; - } + /* are we simulating Informix? */ + if (INFORMIX_MODE) + { + BEGIN(incl); } + else + { + yyless(1); + return S_ANYTHING; + } + } {exec_sql}{ifdef}{space}* { - if (preproc_tos >= MAX_NESTED_IF-1) - mmfatal(PARSE_ERROR, "too many nested EXEC SQL IFDEF conditions"); - preproc_tos++; - stacked_if_value[preproc_tos].active = false; - stacked_if_value[preproc_tos].saw_active = false; - stacked_if_value[preproc_tos].else_branch = false; - ifcond = true; - BEGIN(xcond); - } + if (preproc_tos >= MAX_NESTED_IF - 1) + mmfatal(PARSE_ERROR, "too many nested EXEC SQL IFDEF conditions"); + preproc_tos++; + stacked_if_value[preproc_tos].active = false; + stacked_if_value[preproc_tos].saw_active = false; + stacked_if_value[preproc_tos].else_branch = false; + ifcond = true; + BEGIN(xcond); + } {informix_special}{ifdef}{space}* { - /* are we simulating Informix? */ - if (INFORMIX_MODE) - { - if (preproc_tos >= MAX_NESTED_IF-1) - mmfatal(PARSE_ERROR, "too many nested EXEC SQL IFDEF conditions"); - preproc_tos++; - stacked_if_value[preproc_tos].active = false; - stacked_if_value[preproc_tos].saw_active = false; - stacked_if_value[preproc_tos].else_branch = false; - ifcond = true; - BEGIN(xcond); - } - else - { - yyless(1); - return S_ANYTHING; - } - } -{exec_sql}{ifndef}{space}* { - if (preproc_tos >= MAX_NESTED_IF-1) - mmfatal(PARSE_ERROR, "too many nested EXEC SQL IFDEF conditions"); - preproc_tos++; - stacked_if_value[preproc_tos].active = false; - stacked_if_value[preproc_tos].saw_active = false; - stacked_if_value[preproc_tos].else_branch = false; - ifcond = false; - BEGIN(xcond); - } -{informix_special}{ifndef}{space}* { - /* are we simulating Informix? */ - if (INFORMIX_MODE) - { - if (preproc_tos >= MAX_NESTED_IF-1) - mmfatal(PARSE_ERROR, "too many nested EXEC SQL IFDEF conditions"); - preproc_tos++; - stacked_if_value[preproc_tos].active = false; - stacked_if_value[preproc_tos].saw_active = false; - stacked_if_value[preproc_tos].else_branch = false; - ifcond = false; - BEGIN(xcond); - } - else - { - yyless(1); - return S_ANYTHING; - } - } -{exec_sql}{elif}{space}* { - if (preproc_tos == 0) - mmfatal(PARSE_ERROR, "missing matching \"EXEC SQL IFDEF\" / \"EXEC SQL IFNDEF\""); - if (stacked_if_value[preproc_tos].else_branch) - mmfatal(PARSE_ERROR, "missing \"EXEC SQL ENDIF;\""); + /* are we simulating Informix? */ + if (INFORMIX_MODE) + { + if (preproc_tos >= MAX_NESTED_IF - 1) + mmfatal(PARSE_ERROR, "too many nested EXEC SQL IFDEF conditions"); + preproc_tos++; + stacked_if_value[preproc_tos].active = false; + stacked_if_value[preproc_tos].saw_active = false; + stacked_if_value[preproc_tos].else_branch = false; ifcond = true; BEGIN(xcond); } + else + { + yyless(1); + return S_ANYTHING; + } + } +{exec_sql}{ifndef}{space}* { + if (preproc_tos >= MAX_NESTED_IF - 1) + mmfatal(PARSE_ERROR, "too many nested EXEC SQL IFDEF conditions"); + preproc_tos++; + stacked_if_value[preproc_tos].active = false; + stacked_if_value[preproc_tos].saw_active = false; + stacked_if_value[preproc_tos].else_branch = false; + ifcond = false; + BEGIN(xcond); + } +{informix_special}{ifndef}{space}* { + /* are we simulating Informix? */ + if (INFORMIX_MODE) + { + if (preproc_tos >= MAX_NESTED_IF - 1) + mmfatal(PARSE_ERROR, "too many nested EXEC SQL IFDEF conditions"); + preproc_tos++; + stacked_if_value[preproc_tos].active = false; + stacked_if_value[preproc_tos].saw_active = false; + stacked_if_value[preproc_tos].else_branch = false; + ifcond = false; + BEGIN(xcond); + } + else + { + yyless(1); + return S_ANYTHING; + } + } +{exec_sql}{elif}{space}* { + if (preproc_tos == 0) + mmfatal(PARSE_ERROR, "missing matching \"EXEC SQL IFDEF\" / \"EXEC SQL IFNDEF\""); + if (stacked_if_value[preproc_tos].else_branch) + mmfatal(PARSE_ERROR, "missing \"EXEC SQL ENDIF;\""); + ifcond = true; + BEGIN(xcond); + } {informix_special}{elif}{space}* { /* are we simulating Informix? */ if (INFORMIX_MODE) @@ -1337,7 +1372,8 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ } } -{exec_sql}{else}{space}*";" { /* only exec sql endif pops the stack, so take care of duplicated 'else' */ +{exec_sql}{else}{space}*";" { + /* only exec sql endif pops the stack, so take care of duplicated 'else' */ if (preproc_tos == 0) mmfatal(PARSE_ERROR, "missing matching \"EXEC SQL IFDEF\" / \"EXEC SQL IFNDEF\""); else if (stacked_if_value[preproc_tos].else_branch) @@ -1346,7 +1382,7 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ { stacked_if_value[preproc_tos].else_branch = true; stacked_if_value[preproc_tos].active = - (stacked_if_value[preproc_tos-1].active && + (stacked_if_value[preproc_tos - 1].active && !stacked_if_value[preproc_tos].saw_active); stacked_if_value[preproc_tos].saw_active = true; @@ -1356,7 +1392,7 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ BEGIN(xskip); } } -{informix_special}{else}{space}*";" { +{informix_special}{else}{space}*";" { /* are we simulating Informix? */ if (INFORMIX_MODE) { @@ -1368,7 +1404,7 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ { stacked_if_value[preproc_tos].else_branch = true; stacked_if_value[preproc_tos].active = - (stacked_if_value[preproc_tos-1].active && + (stacked_if_value[preproc_tos - 1].active && !stacked_if_value[preproc_tos].saw_active); stacked_if_value[preproc_tos].saw_active = true; @@ -1391,11 +1427,11 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ preproc_tos--; if (stacked_if_value[preproc_tos].active) - BEGIN(C); + BEGIN(C); else - BEGIN(xskip); + BEGIN(xskip); } -{informix_special}{endif}{space}*";" { +{informix_special}{endif}{space}*";" { /* are we simulating Informix? */ if (INFORMIX_MODE) { @@ -1416,23 +1452,24 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ } } -{other} { /* ignore */ } +{other} { /* ignore */ } {identifier}{space}*";" { { struct _defines *defptr; unsigned int i; - bool this_active; + bool this_active; /* - * Skip the ";" and trailing whitespace. Note that yytext - * contains at least one non-space character plus the ";" + * Skip the ";" and trailing whitespace. Note that + * yytext contains at least one non-space character + * plus the ";" */ - for (i = strlen(yytext)-2; + for (i = strlen(yytext) - 2; i > 0 && ecpg_isspace(yytext[i]); i--) - ; - yytext[i+1] = '\0'; + /* skip */ ; + yytext[i + 1] = '\0'; /* Does a definition exist? */ for (defptr = defines; defptr; defptr = defptr->next) @@ -1448,7 +1485,7 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ this_active = (defptr ? ifcond : !ifcond); stacked_if_value[preproc_tos].active = - (stacked_if_value[preproc_tos-1].active && + (stacked_if_value[preproc_tos - 1].active && !stacked_if_value[preproc_tos].saw_active && this_active); stacked_if_value[preproc_tos].saw_active |= this_active; @@ -1460,59 +1497,59 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ BEGIN(xskip); } -{other}|\n { - mmfatal(PARSE_ERROR, "missing identifier in EXEC SQL IFDEF command"); - yyterminate(); - } +{other}|\n { + mmfatal(PARSE_ERROR, "missing identifier in EXEC SQL IFDEF command"); + yyterminate(); + } {identifier} { - newdefsymbol = mm_strdup(yytext); - BEGIN(def); - startlit(); - } -{other}|\n { - mmfatal(PARSE_ERROR, "missing identifier in EXEC SQL DEFINE command"); - yyterminate(); - } -{space}*";" { - struct _defines *ptr; + newdefsymbol = mm_strdup(yytext); + BEGIN(def); + startlit(); + } +{other}|\n { + mmfatal(PARSE_ERROR, "missing identifier in EXEC SQL DEFINE command"); + yyterminate(); + } +{space}*";" { + struct _defines *ptr; - /* Does it already exist? */ - for (ptr = defines; ptr != NULL; ptr = ptr->next) + /* Does it already exist? */ + for (ptr = defines; ptr != NULL; ptr = ptr->next) + { + if (strcmp(newdefsymbol, ptr->name) == 0) { - if (strcmp(newdefsymbol, ptr->name) == 0) - { - free(ptr->value); - ptr->value = mm_strdup(literalbuf); - /* Don't leak newdefsymbol */ - free(newdefsymbol); - break; - } - } - if (ptr == NULL) - { - /* Not present, make a new entry */ - ptr = (struct _defines *) mm_alloc(sizeof(struct _defines)); - - ptr->name = newdefsymbol; + free(ptr->value); ptr->value = mm_strdup(literalbuf); - ptr->cmdvalue = NULL; - ptr->used = NULL; - ptr->next = defines; - defines = ptr; + /* Don't leak newdefsymbol */ + free(newdefsymbol); + break; } - - BEGIN(C); } -[^;] { addlit(yytext, yyleng); } -\<[^\>]+\>{space}*";"? { parse_include(); } + if (ptr == NULL) + { + /* Not present, make a new entry */ + ptr = (struct _defines *) mm_alloc(sizeof(struct _defines)); + + ptr->name = newdefsymbol; + ptr->value = mm_strdup(literalbuf); + ptr->cmdvalue = NULL; + ptr->used = NULL; + ptr->next = defines; + defines = ptr; + } + + BEGIN(C); + } +[^;] { addlit(yytext, yyleng); } +\<[^\>]+\>{space}*";"? { parse_include(); } {dquote}{xdinside}{dquote}{space}*";"? { parse_include(); } -[^;\<\>\"]+";" { parse_include(); } -{other}|\n { +[^;\<\>\"]+";" { parse_include(); } +{other}|\n { mmfatal(PARSE_ERROR, "syntax error in EXEC SQL INCLUDE command"); yyterminate(); } -<> { +<> { if (yy_buffer == NULL) { /* No more input */ @@ -1527,7 +1564,7 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ { /* Revert to previous input source */ struct _yy_buffer *yb = yy_buffer; - int i; + int i; struct _defines *ptr; /* Check to see if we are exiting a macro value */ @@ -1559,11 +1596,12 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ if (i != 0) output_line_number(); - } } -{other}|\n { mmfatal(PARSE_ERROR, "internal error: unreachable state; please report this to <%s>", PACKAGE_BUGREPORT); } +{other}|\n { + mmfatal(PARSE_ERROR, "internal error: unreachable state; please report this to <%s>", PACKAGE_BUGREPORT); + } %% @@ -1599,15 +1637,15 @@ static void addlit(char *ytext, int yleng) { /* enlarge buffer if needed */ - if ((literallen+yleng) >= literalalloc) + if ((literallen + yleng) >= literalalloc) { do literalalloc *= 2; - while ((literallen+yleng) >= literalalloc); + while ((literallen + yleng) >= literalalloc); literalbuf = (char *) realloc(literalbuf, literalalloc); } /* append new data, add trailing null */ - memcpy(literalbuf+literallen, ytext, yleng); + memcpy(literalbuf + literallen, ytext, yleng); literallen += yleng; literalbuf[literallen] = '\0'; } @@ -1616,7 +1654,7 @@ static void addlitchar(unsigned char ychar) { /* enlarge buffer if needed */ - if ((literallen+1) >= literalalloc) + if ((literallen + 1) >= literalalloc) { literalalloc *= 2; literalbuf = (char *) realloc(literalbuf, literalalloc); @@ -1655,12 +1693,12 @@ parse_include(void) /* got the include file name */ struct _yy_buffer *yb; struct _include_path *ip; - char inc_file[MAXPGPATH]; + char inc_file[MAXPGPATH]; unsigned int i; yb = mm_alloc(sizeof(struct _yy_buffer)); - yb->buffer = YY_CURRENT_BUFFER; + yb->buffer = YY_CURRENT_BUFFER; yb->lineno = yylineno; yb->filename = input_filename; yb->next = yy_buffer; @@ -1668,10 +1706,10 @@ parse_include(void) yy_buffer = yb; /* - * skip the ";" if there is one and trailing whitespace. Note that - * yytext contains at least one non-space character plus the ";" + * skip the ";" if there is one and trailing whitespace. Note that yytext + * contains at least one non-space character plus the ";" */ - for (i = strlen(yytext)-2; + for (i = strlen(yytext) - 2; i > 0 && ecpg_isspace(yytext[i]); i--) ; @@ -1679,17 +1717,21 @@ parse_include(void) if (yytext[i] == ';') i--; - yytext[i+1] = '\0'; + yytext[i + 1] = '\0'; yyin = NULL; /* If file name is enclosed in '"' remove these and look only in '.' */ - /* Informix does look into all include paths though, except filename starts with '/' */ + + /* + * Informix does look into all include paths though, except filename + * starts with '/' + */ if (yytext[0] == '"' && yytext[i] == '"' && ((compat != ECPG_COMPAT_INFORMIX && compat != ECPG_COMPAT_INFORMIX_SE) || yytext[1] == '/')) { yytext[i] = '\0'; - memmove(yytext, yytext+1, strlen(yytext)); + memmove(yytext, yytext + 1, strlen(yytext)); strlcpy(inc_file, yytext, sizeof(inc_file)); yyin = fopen(inc_file, "r"); @@ -1708,7 +1750,7 @@ parse_include(void) if ((yytext[0] == '"' && yytext[i] == '"') || (yytext[0] == '<' && yytext[i] == '>')) { yytext[i] = '\0'; - memmove(yytext, yytext+1, strlen(yytext)); + memmove(yytext, yytext + 1, strlen(yytext)); } for (ip = include_paths; yyin == NULL && ip != NULL; ip = ip->next) @@ -1718,7 +1760,7 @@ parse_include(void) fprintf(stderr, _("Error: include path \"%s/%s\" is too long on line %d, skipping\n"), ip->path, yytext, yylineno); continue; } - snprintf (inc_file, sizeof(inc_file), "%s/%s", ip->path, yytext); + snprintf(inc_file, sizeof(inc_file), "%s/%s", ip->path, yytext); yyin = fopen(inc_file, "r"); if (!yyin) { @@ -1728,10 +1770,14 @@ parse_include(void) yyin = fopen(inc_file, "r"); } } - /* if the command was "include_next" we have to disregard the first hit */ + + /* + * if the command was "include_next" we have to disregard the + * first hit + */ if (yyin && include_next) { - fclose (yyin); + fclose(yyin); yyin = NULL; include_next = false; } @@ -1741,7 +1787,7 @@ parse_include(void) mmfatal(NO_INCLUDE_FILE, "could not open include file \"%s\" on line %d", yytext, yylineno); input_filename = mm_strdup(inc_file); - yy_switch_to_buffer(yy_create_buffer(yyin,YY_BUF_SIZE)); + yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); yylineno = 1; output_line_number(); @@ -1786,7 +1832,7 @@ isdefine(void) yb = mm_alloc(sizeof(struct _yy_buffer)); - yb->buffer = YY_CURRENT_BUFFER; + yb->buffer = YY_CURRENT_BUFFER; yb->lineno = yylineno; yb->filename = mm_strdup(input_filename); yb->next = yy_buffer; @@ -1830,7 +1876,7 @@ isinformixdefine(void) yb = mm_alloc(sizeof(struct _yy_buffer)); - yb->buffer = YY_CURRENT_BUFFER; + yb->buffer = YY_CURRENT_BUFFER; yb->lineno = yylineno; yb->filename = mm_strdup(input_filename); yb->next = yy_buffer;