aboutsummaryrefslogtreecommitdiff
path: root/src/interfaces/ecpg/preproc/pgc.l
diff options
context:
space:
mode:
Diffstat (limited to 'src/interfaces/ecpg/preproc/pgc.l')
-rw-r--r--src/interfaces/ecpg/preproc/pgc.l128
1 files changed, 88 insertions, 40 deletions
diff --git a/src/interfaces/ecpg/preproc/pgc.l b/src/interfaces/ecpg/preproc/pgc.l
index f6052798fd5..466bbac6a7b 100644
--- a/src/interfaces/ecpg/preproc/pgc.l
+++ b/src/interfaces/ecpg/preproc/pgc.l
@@ -79,13 +79,29 @@ struct _yy_buffer
static char *old;
+/*
+ * Vars for handling ifdef/elif/endif constructs. preproc_tos is the current
+ * nesting depth of such constructs, and stacked_if_value[preproc_tos] is the
+ * state for the innermost level. (For convenience, stacked_if_value[0] is
+ * initialized as though we are in the active branch of some outermost IF.)
+ * The active field is true if the current branch is active (being expanded).
+ * The saw_active field is true if we have found any successful branch,
+ * so that all subsequent branches of this level should be skipped.
+ * The else_branch field is true if we've found an 'else' (so that another
+ * 'else' or 'elif' at this level is an error.)
+ * For IFs nested within an inactive branch, all branches always have active
+ * set to false, but saw_active and else_branch are maintained normally.
+ * ifcond is valid only while evaluating an if-condition; it's true if we
+ * are doing ifdef, false if ifndef.
+ */
#define MAX_NESTED_IF 128
static short preproc_tos;
-static short ifcond;
+static bool ifcond;
static struct _if_value
{
- short condition;
- short else_branch;
+ bool active;
+ bool saw_active;
+ bool else_branch;
} stacked_if_value[MAX_NESTED_IF];
%}
@@ -1165,11 +1181,26 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
return S_ANYTHING;
}
}
-<C,xskip>{exec_sql}{ifdef}{space}* { ifcond = true; BEGIN(xcond); }
+<C,xskip>{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);
+ }
<C,xskip>{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);
}
@@ -1179,11 +1210,26 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
return S_ANYTHING;
}
}
-<C,xskip>{exec_sql}{ifndef}{space}* { ifcond = false; BEGIN(xcond); }
+<C,xskip>{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);
+ }
<C,xskip>{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);
}
@@ -1193,16 +1239,13 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
return S_ANYTHING;
}
}
-<C,xskip>{exec_sql}{elif}{space}* { /* pop stack */
- if ( preproc_tos == 0 ) {
+<C,xskip>{exec_sql}{elif}{space}* {
+ if (preproc_tos == 0)
mmfatal(PARSE_ERROR, "missing matching \"EXEC SQL IFDEF\" / \"EXEC SQL IFNDEF\"");
- }
- else if ( stacked_if_value[preproc_tos].else_branch )
+ if (stacked_if_value[preproc_tos].else_branch)
mmfatal(PARSE_ERROR, "missing \"EXEC SQL ENDIF;\"");
- else
- preproc_tos--;
-
- ifcond = true; BEGIN(xcond);
+ ifcond = true;
+ BEGIN(xcond);
}
<C,xskip>{informix_special}{elif}{space}* {
/* are we simulating Informix? */
@@ -1210,11 +1253,8 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
{
if (preproc_tos == 0)
mmfatal(PARSE_ERROR, "missing matching \"EXEC SQL IFDEF\" / \"EXEC SQL IFNDEF\"");
- else if (stacked_if_value[preproc_tos].else_branch)
+ if (stacked_if_value[preproc_tos].else_branch)
mmfatal(PARSE_ERROR, "missing \"EXEC SQL ENDIF;\"");
- else
- preproc_tos--;
-
ifcond = true;
BEGIN(xcond);
}
@@ -1226,16 +1266,19 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
}
<C,xskip>{exec_sql}{else}{space}*";" { /* only exec sql endif pops the stack, so take care of duplicated 'else' */
- if (stacked_if_value[preproc_tos].else_branch)
+ if ( preproc_tos == 0 )
+ mmfatal(PARSE_ERROR, "missing matching \"EXEC SQL IFDEF\" / \"EXEC SQL IFNDEF\"");
+ else if (stacked_if_value[preproc_tos].else_branch)
mmfatal(PARSE_ERROR, "more than one EXEC SQL ELSE");
else
{
stacked_if_value[preproc_tos].else_branch = true;
- stacked_if_value[preproc_tos].condition =
- (stacked_if_value[preproc_tos-1].condition &&
- !stacked_if_value[preproc_tos].condition);
+ stacked_if_value[preproc_tos].active =
+ (stacked_if_value[preproc_tos-1].active &&
+ !stacked_if_value[preproc_tos].saw_active);
+ stacked_if_value[preproc_tos].saw_active = true;
- if (stacked_if_value[preproc_tos].condition)
+ if (stacked_if_value[preproc_tos].active)
BEGIN(C);
else
BEGIN(xskip);
@@ -1245,16 +1288,19 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
/* are we simulating Informix? */
if (INFORMIX_MODE)
{
- if (stacked_if_value[preproc_tos].else_branch)
+ if ( preproc_tos == 0 )
+ mmfatal(PARSE_ERROR, "missing matching \"EXEC SQL IFDEF\" / \"EXEC SQL IFNDEF\"");
+ else if (stacked_if_value[preproc_tos].else_branch)
mmfatal(PARSE_ERROR, "more than one EXEC SQL ELSE");
else
{
stacked_if_value[preproc_tos].else_branch = true;
- stacked_if_value[preproc_tos].condition =
- (stacked_if_value[preproc_tos-1].condition &&
- !stacked_if_value[preproc_tos].condition);
+ stacked_if_value[preproc_tos].active =
+ (stacked_if_value[preproc_tos-1].active &&
+ !stacked_if_value[preproc_tos].saw_active);
+ stacked_if_value[preproc_tos].saw_active = true;
- if (stacked_if_value[preproc_tos].condition)
+ if (stacked_if_value[preproc_tos].active)
BEGIN(C);
else
BEGIN(xskip);
@@ -1272,7 +1318,7 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
else
preproc_tos--;
- if (stacked_if_value[preproc_tos].condition)
+ if (stacked_if_value[preproc_tos].active)
BEGIN(C);
else
BEGIN(xskip);
@@ -1286,7 +1332,7 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
else
preproc_tos--;
- if (stacked_if_value[preproc_tos].condition)
+ if (stacked_if_value[preproc_tos].active)
BEGIN(C);
else
BEGIN(xskip);
@@ -1301,12 +1347,10 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
<xskip>{other} { /* ignore */ }
<xcond>{identifier}{space}*";" {
- if (preproc_tos >= MAX_NESTED_IF-1)
- mmfatal(PARSE_ERROR, "too many nested EXEC SQL IFDEF conditions");
- else
{
struct _defines *defptr;
unsigned int i;
+ bool this_active;
/*
* Skip the ";" and trailing whitespace. Note that yytext
@@ -1324,13 +1368,15 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
defptr = defptr->next)
/* skip */ ;
- preproc_tos++;
- stacked_if_value[preproc_tos].else_branch = false;
- stacked_if_value[preproc_tos].condition =
- (defptr ? ifcond : !ifcond) && stacked_if_value[preproc_tos-1].condition;
+ this_active = (defptr ? ifcond : !ifcond);
+ stacked_if_value[preproc_tos].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;
}
- if (stacked_if_value[preproc_tos].condition)
+ if (stacked_if_value[preproc_tos].active)
BEGIN(C);
else
BEGIN(xskip);
@@ -1442,10 +1488,12 @@ lex_init(void)
parenths_open = 0;
current_function = NULL;
- preproc_tos = 0;
yylineno = 1;
- ifcond = true;
- stacked_if_value[preproc_tos].condition = ifcond;
+
+ /* initialize state for if/else/endif */
+ preproc_tos = 0;
+ stacked_if_value[preproc_tos].active = true;
+ stacked_if_value[preproc_tos].saw_active = true;
stacked_if_value[preproc_tos].else_branch = false;
/* initialize literal buffer to a reasonable but expansible size */