diff --git a/src/macro/Directives.cc b/src/macro/Directives.cc
index 7a89e45a0532450d31b6ec0621d3149cddbd1898..e76bf4499589c10e30bb42aa239620bbeb078fb1 100644
--- a/src/macro/Directives.cc
+++ b/src/macro/Directives.cc
@@ -245,19 +245,35 @@ For::interpret(ostream &output, vector<filesystem::path> &paths)
void
If::interpret(ostream &output, vector<filesystem::path> &paths)
{
+ bool first_clause = true;
for (const auto & [expr, body] : expr_and_body)
try
{
- auto tmp = expr->eval();
- RealPtr dp = dynamic_pointer_cast<Real>(tmp);
- BoolPtr bp = dynamic_pointer_cast<Bool>(tmp);
- if (!bp && !dp)
- error(StackTrace("@#if",
- "The condition must evaluate to a boolean or a double", location));
- if ((bp && *bp) || (dp && *dp))
+ if ((ifdef || ifndef) && first_clause)
{
- interpretBody(body, output, paths);
- break;
+ first_clause = false;
+ VariablePtr vp = dynamic_pointer_cast<Variable>(expr);
+ assert(vp);
+ if ((ifdef && env.isVariableDefined(vp->getName()))
+ || (ifndef && !env.isVariableDefined(vp->getName())))
+ {
+ interpretBody(body, output, paths);
+ break;
+ }
+ }
+ else
+ {
+ auto tmp = expr->eval();
+ RealPtr dp = dynamic_pointer_cast<Real>(tmp);
+ BoolPtr bp = dynamic_pointer_cast<Bool>(tmp);
+ if (!bp && !dp)
+ error(StackTrace("@#if",
+ "The condition must evaluate to a boolean or a double", location));
+ if ((bp && *bp) || (dp && *dp))
+ {
+ interpretBody(body, output, paths);
+ break;
+ }
}
}
catch (StackTrace &ex)
@@ -286,31 +302,3 @@ If::interpretBody(const vector<DirectivePtr> &body, ostream &output, vector<file
statement->interpret(output, paths);
}
}
-
-void
-Ifdef::interpret(ostream &output, vector<filesystem::path> &paths)
-{
- for (const auto & [expr, body] : expr_and_body)
- if (VariablePtr vp = dynamic_pointer_cast<Variable>(expr);
- dynamic_pointer_cast<BaseType>(expr)
- || (vp && env.isVariableDefined(vp->getName())))
- {
- interpretBody(body, output, paths);
- break;
- }
- printEndLineInfo(output);
-}
-
-void
-Ifndef::interpret(ostream &output, vector<filesystem::path> &paths)
-{
- for (const auto & [expr, body] : expr_and_body)
- if (VariablePtr vp = dynamic_pointer_cast<Variable>(expr);
- dynamic_pointer_cast<BaseType>(expr)
- || (vp && !env.isVariableDefined(vp->getName())))
- {
- interpretBody(body, output, paths);
- break;
- }
- printEndLineInfo(output);
-}
diff --git a/src/macro/Directives.hh b/src/macro/Directives.hh
index db71ae3f595ccbd87554b0c558c327d1c2ad143e..cc7ec6e1293d9ad0a4270a807344de0a110da7b2 100644
--- a/src/macro/Directives.hh
+++ b/src/macro/Directives.hh
@@ -175,24 +175,25 @@ namespace macro
* If there is an `else` statement it is the last element in the vector. Its condition is true.
*/
const vector<pair<ExpressionPtr, vector<DirectivePtr>>> expr_and_body;
+ const bool ifdef, ifndef;
public:
If(vector<pair<ExpressionPtr, vector<DirectivePtr>>> expr_and_body_arg,
- Environment &env_arg, Tokenizer::location location_arg) :
- Directive(env_arg, move(location_arg)), expr_and_body{move(expr_and_body_arg)} { }
+ Environment &env_arg, Tokenizer::location location_arg,
+ bool ifdef_arg = false, bool ifndef_arg = false) :
+ Directive(env_arg, move(location_arg)), expr_and_body{move(expr_and_body_arg)},
+ ifdef{ifdef_arg}, ifndef{ifndef_arg} { }
void interpret(ostream &output, vector<filesystem::path> &paths) override;
protected:
void interpretBody(const vector<DirectivePtr> &body, ostream &output,
vector<filesystem::path> &paths);
};
-
class Ifdef : public If
{
public:
Ifdef(vector<pair<ExpressionPtr, vector<DirectivePtr>>> expr_and_body_arg,
Environment &env_arg, Tokenizer::location location_arg) :
- If(move(expr_and_body_arg), env_arg, move(location_arg)) { }
- void interpret(ostream &output, vector<filesystem::path> &paths) override;
+ If(move(expr_and_body_arg), env_arg, move(location_arg), true, false) { }
};
@@ -201,8 +202,7 @@ namespace macro
public:
Ifndef(vector<pair<ExpressionPtr, vector<DirectivePtr>>> expr_and_body_arg,
Environment &env_arg, Tokenizer::location location_arg) :
- If(move(expr_and_body_arg), env_arg, move(location_arg)) { }
- void interpret(ostream &output, vector<filesystem::path> &paths) override;
+ If(move(expr_and_body_arg), env_arg, move(location_arg), false, true) { }
};
}
#endif