Commit 33c2da97 authored by Marc G. Fournier's avatar Marc G. Fournier

From: Michael Meskes <meskes@topsystem.de>

Here's the ecpg patch for the local variables bug I reported earlier:
parent 7d55b1c7
...@@ -44,8 +44,5 @@ could be realised in a script. ...@@ -44,8 +44,5 @@ could be realised in a script.
Now comes my list (MM): 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. Variable definitions containing static/volatile have to be possible.
...@@ -356,7 +356,7 @@ you are not interested in how it really works, skip this chapter. ...@@ -356,7 +356,7 @@ you are not interested in how it really works, skip this chapter.
@comment node-name, next, previous, up @comment node-name, next, previous, up
@section To do list @section To do list
In the alpha version the preprocessor has a lot of flaws: This version the preprocessor has some flaws:
@table @asis @table @asis
@item Preprocessor output @item Preprocessor output
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
#include "type.h" #include "type.h"
#include "y.tab.h" #include "y.tab.h"
extern int debugging; #include "extern.h"
#define dbg(arg) if (debugging) fprintf(stderr, "DEBUG, %d: %s\n", yylineno, #arg); #define dbg(arg) if (debugging) fprintf(stderr, "DEBUG, %d: %s\n", yylineno, #arg);
%} %}
...@@ -56,7 +56,7 @@ int { dbg(S_INT); return S_INT; } ...@@ -56,7 +56,7 @@ int { dbg(S_INT); return S_INT; }
char { dbg(S_CHAR); return S_CHAR; } char { dbg(S_CHAR); return S_CHAR; }
float { dbg(S_FLOAT); return S_FLOAT; } float { dbg(S_FLOAT); return S_FLOAT; }
double { dbg(S_DOUBLE); return S_DOUBLE; } 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; } {string} { dbg(SQL_STRING); return SQL_STRING; }
<SQL>{ws} ; <SQL>{ws} ;
...@@ -97,6 +97,8 @@ bool { dbg(S_BOOL); return S_BOOL; } ...@@ -97,6 +97,8 @@ bool { dbg(S_BOOL); return S_BOOL; }
"]" { dbg(]); return ']'; } "]" { dbg(]); return ']'; }
";" { dbg(;); return ';'; } ";" { dbg(;); return ';'; }
"," { dbg(komma); return ','; } "," { dbg(komma); return ','; }
\{ { dbg(blockstart); return '{'; }
\} { dbg(blockend); return'}'; }
<SQL>":" { dbg(:); return ':'; } <SQL>":" { dbg(:); return ':'; }
...@@ -106,6 +108,7 @@ bool { dbg(S_BOOL); return S_BOOL; } ...@@ -106,6 +108,7 @@ bool { dbg(S_BOOL); return S_BOOL; }
void void
lex_init(void) lex_init(void)
{ {
braces_open = 0;
BEGIN C; BEGIN C;
} }
......
...@@ -29,27 +29,24 @@ output_line_number() ...@@ -29,27 +29,24 @@ output_line_number()
/* /*
* Handling of the variables. * 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 * brace level counter
* 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++.
*/ */
int braces_open;
/* This is a linked list of the variable names and types. */ /* This is a linked list of the variable names and types. */
struct variable struct variable
{ {
char * name; char * name;
struct ECPGtype * type; struct ECPGtype * type;
int brace_level;
struct variable * next; struct variable * next;
}; };
static struct variable * allvariables = NULL; static struct variable * allvariables = NULL;
struct variable * static struct variable *
find_variable(char * name) find_variable(char * name)
{ {
struct variable * p; struct variable * p;
...@@ -71,18 +68,42 @@ find_variable(char * name) ...@@ -71,18 +68,42 @@ find_variable(char * name)
} }
void static void
new_variable(const char * name, struct ECPGtype * type) new_variable(const char * name, struct ECPGtype * type)
{ {
struct variable * p = (struct variable*) malloc(sizeof(struct variable)); struct variable * p = (struct variable*) malloc(sizeof(struct variable));
p->name = strdup(name); p->name = strdup(name);
p->type = type; p->type = type;
p->brace_level = braces_open;
p->next = allvariables; p->next = allvariables;
allvariables = p; 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. * Here are the variables that need to be handled on every request.
...@@ -161,7 +182,7 @@ dump_variables(struct arguments * list) ...@@ -161,7 +182,7 @@ dump_variables(struct arguments * list)
%token <tagname> S_EXTERN S_STATIC %token <tagname> S_EXTERN S_STATIC
%token <tagname> S_UNSIGNED S_SIGNED %token <tagname> S_UNSIGNED S_SIGNED
%token <tagname> S_LONG S_SHORT S_INT S_CHAR S_FLOAT S_DOUBLE S_BOOL %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 <type> type type_detailed varchar_type simple_type array_type
%type <symbolname> symbol %type <symbolname> symbol
...@@ -184,7 +205,9 @@ statement : sqldeclaration ...@@ -184,7 +205,9 @@ statement : sqldeclaration
| sqlcommit | sqlcommit
| sqlrollback | sqlrollback
| sqlstatement | sqlstatement
| cthing; | cthing
| blockstart
| blockend;
sqldeclaration : sql_startdeclare sqldeclaration : sql_startdeclare
variable_declarations variable_declarations
...@@ -356,6 +379,15 @@ both_anything : S_LENGTH | S_VARCHAR | S_VARCHAR2 ...@@ -356,6 +379,15 @@ both_anything : S_LENGTH | S_VARCHAR | S_VARCHAR2
| '[' | ']' | ',' | '[' | ']' | ','
| S_ANYTHING; | 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) static void yyerror(char * error)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment