mirror of
https://github.com/postgres/postgres.git
synced 2025-07-05 07:21:24 +03:00
From: Michael Meskes <meskes@topsystem.de>
Here's the ecpg patch for the local variables bug I reported earlier:
This commit is contained in:
@ -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.
|
|||||||
@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 @@
|
|||||||
#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; }
|
|||||||
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; }
|
|||||||
"]" { 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; }
|
|||||||
void
|
void
|
||||||
lex_init(void)
|
lex_init(void)
|
||||||
{
|
{
|
||||||
|
braces_open = 0;
|
||||||
BEGIN C;
|
BEGIN C;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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)
|
|||||||
%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
|
|||||||
| 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
|
|||||||
| '[' | ']' | ','
|
| '[' | ']' | ','
|
||||||
| 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)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user