#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);
%}
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} ;
"]" { dbg(]); return ']'; }
";" { dbg(;); return ';'; }
"," { dbg(komma); return ','; }
+\{ { dbg(blockstart); return '{'; }
+\} { dbg(blockend); return'}'; }
<SQL>":" { dbg(:); return ':'; }
void
lex_init(void)
{
+ braces_open = 0;
BEGIN C;
}
/*
* 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;
}
-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.
%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
| sqlcommit
| sqlrollback
| sqlstatement
- | cthing;
+ | cthing
+ | blockstart
+ | blockend;
sqldeclaration : sql_startdeclare
variable_declarations
| '[' | ']' | ','
| 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)
{