diff --git a/src/interfaces/ecpg/TODO b/src/interfaces/ecpg/TODO index 6d18d049a987bffb9b12ea443ec8c5026ca5c5c3..24c1f15df6fc04d79559e00b5e7e541381525356 100644 --- a/src/interfaces/ecpg/TODO +++ b/src/interfaces/ecpg/TODO @@ -44,8 +44,5 @@ could be realised in a script. Now comes my list (MM): -Ecpg should remove variables from its list as soon as they are undefined and -not rely on cc to report an error. - Variable definitions containing static/volatile have to be possible. diff --git a/src/interfaces/ecpg/doc/ecpg.texinfo b/src/interfaces/ecpg/doc/ecpg.texinfo index b6458104a7a0484e78a8f5237120604b804b8328..ad9361e021378901380177395f9589ec0d23225a 100644 --- a/src/interfaces/ecpg/doc/ecpg.texinfo +++ b/src/interfaces/ecpg/doc/ecpg.texinfo @@ -356,7 +356,7 @@ you are not interested in how it really works, skip this chapter. @comment node-name, next, previous, up @section To do list -In the alpha version the preprocessor has a lot of flaws: +This version the preprocessor has some flaws: @table @asis @item Preprocessor output diff --git a/src/interfaces/ecpg/preproc/pgc.l b/src/interfaces/ecpg/preproc/pgc.l index 7ab3c5764f20e8ffc6212c5c8e3a4498e6df4e66..4e81182b804c338850879f4729b5649498d9e24b 100644 --- a/src/interfaces/ecpg/preproc/pgc.l +++ b/src/interfaces/ecpg/preproc/pgc.l @@ -3,7 +3,7 @@ #include "type.h" #include "y.tab.h" -extern int debugging; +#include "extern.h" #define dbg(arg) if (debugging) fprintf(stderr, "DEBUG, %d: %s\n", yylineno, #arg); %} @@ -56,7 +56,7 @@ int { dbg(S_INT); return S_INT; } char { dbg(S_CHAR); return S_CHAR; } float { dbg(S_FLOAT); return S_FLOAT; } double { dbg(S_DOUBLE); return S_DOUBLE; } -bool { dbg(S_BOOL); return S_BOOL; } +bool { dbg(S_BOOL); return S_BOOL; } {string} { dbg(SQL_STRING); return SQL_STRING; } <SQL>{ws} ; @@ -97,6 +97,8 @@ bool { dbg(S_BOOL); return S_BOOL; } "]" { dbg(]); return ']'; } ";" { dbg(;); return ';'; } "," { dbg(komma); return ','; } +\{ { dbg(blockstart); return '{'; } +\} { dbg(blockend); return'}'; } <SQL>":" { dbg(:); return ':'; } @@ -106,6 +108,7 @@ bool { dbg(S_BOOL); return S_BOOL; } void lex_init(void) { + braces_open = 0; BEGIN C; } diff --git a/src/interfaces/ecpg/preproc/preproc.y b/src/interfaces/ecpg/preproc/preproc.y index 4d4ba6279f9758563c5c39b08af87b08a0464f1e..827c5c40cf5a0062673ca1a9bd053f055d0c8559 100644 --- a/src/interfaces/ecpg/preproc/preproc.y +++ b/src/interfaces/ecpg/preproc/preproc.y @@ -29,27 +29,24 @@ output_line_number() /* * Handling of the variables. */ -/* Since we don't want to keep track of where the functions end we just - * have a list of functions that we search in, most reasently defined - * function. This won't work if we use block scope for variables with the - * same name but different types but in all other cases the c-compiler will - * signal an error (hopefully). - * - * This list is leaked on program exit. This is because I don't think it is - * important enough to spend the extra ten minutes to write the function that - * deletes it. It would be another thing if I would have written in C++. + +/* + * brace level counter */ +int braces_open; + /* This is a linked list of the variable names and types. */ struct variable { char * name; struct ECPGtype * type; + int brace_level; struct variable * next; }; static struct variable * allvariables = NULL; -struct variable * +static struct variable * find_variable(char * name) { struct variable * p; @@ -71,18 +68,42 @@ find_variable(char * name) } -void +static void new_variable(const char * name, struct ECPGtype * type) { struct variable * p = (struct variable*) malloc(sizeof(struct variable)); p->name = strdup(name); p->type = type; + p->brace_level = braces_open; p->next = allvariables; allvariables = p; } +static void +remove_variables(int brace_level) +{ + struct variable * p, *prev; + + for (p = prev = allvariables; p; p = p->next) + { + if (p->brace_level >= brace_level) + { + /* remove it */ + if (p == allvariables) + prev = allvariables = p->next; + else + prev->next = p->next; + + free(p); + p = prev; + } + else + prev = p; + } +} + /* * Here are the variables that need to be handled on every request. @@ -161,7 +182,7 @@ dump_variables(struct arguments * list) %token <tagname> S_EXTERN S_STATIC %token <tagname> S_UNSIGNED S_SIGNED %token <tagname> S_LONG S_SHORT S_INT S_CHAR S_FLOAT S_DOUBLE S_BOOL -%token <tagname> '[' ']' ';' ',' +%token <tagname> '[' ']' ';' ',' '{' '}' %type <type> type type_detailed varchar_type simple_type array_type %type <symbolname> symbol @@ -184,7 +205,9 @@ statement : sqldeclaration | sqlcommit | sqlrollback | sqlstatement - | cthing; + | cthing + | blockstart + | blockend; sqldeclaration : sql_startdeclare variable_declarations @@ -356,6 +379,15 @@ both_anything : S_LENGTH | S_VARCHAR | S_VARCHAR2 | '[' | ']' | ',' | S_ANYTHING; +blockstart : '{' { + braces_open++; + fwrite(yytext, yyleng, 1, yyout); +} + +blockend : '}' { + remove_variables(braces_open--); + fwrite(yytext, yyleng, 1, yyout); +} %% static void yyerror(char * error) {