summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Reilink <rob@reilink.net>2018-12-31 12:25:02 +0100
committerRob Reilink <rob@reilink.net>2018-12-31 12:25:02 +0100
commit73a573a1b256fc73598bd4d93756bb618fd815fa (patch)
treead71753d635e1e2fe958421a68fb428e8f3ebb62
parenta37e0839583d683d95e70ce1445c0063c7d4bd21 (diff)
downloadply-73a573a1b256fc73598bd4d93756bb618fd815fa.tar.gz
Fixes issue #195, including test case
Additionally, cpp.Preprocessor.evalexpr is split into three methods: evalexpr, evalexpr_expanded, evalexpr_string, to allow for easier customization of the behaviour by overriding any of these stages in a derived class, maintaining the code of the others
-rw-r--r--ply/cpp.py23
-rw-r--r--test/testcpp.py18
2 files changed, 39 insertions, 2 deletions
diff --git a/ply/cpp.py b/ply/cpp.py
index de3956b..8565a6b 100644
--- a/ply/cpp.py
+++ b/ply/cpp.py
@@ -617,11 +617,21 @@ class Preprocessor(object):
del tokens[i+1:j+1]
i += 1
tokens = self.expand_macros(tokens)
+ return self.evalexpr_expanded(tokens)
+
+ # ----------------------------------------------------------------------
+ # evalexpr_expanded()
+ #
+ # Helper for evalexpr that evaluates the expression that had its macros
+ # and defined(...) expressions expanded by evalexpr
+ # ----------------------------------------------------------------------
+
+ def evalexpr_expanded(self, tokens):
for i,t in enumerate(tokens):
if t.type == self.t_ID:
tokens[i] = copy.copy(t)
tokens[i].type = self.t_INTEGER
- tokens[i].value = self.t_INTEGER_TYPE("0L")
+ tokens[i].value = self.t_INTEGER_TYPE("0")
elif t.type == self.t_INTEGER:
tokens[i] = copy.copy(t)
# Strip off any trailing suffixes
@@ -629,10 +639,19 @@ class Preprocessor(object):
while tokens[i].value[-1] not in "0123456789abcdefABCDEF":
tokens[i].value = tokens[i].value[:-1]
- expr = "".join([str(x.value) for x in tokens])
+ return self.evalexpr_string("".join([str(x.value) for x in tokens]))
+
+ # ----------------------------------------------------------------------
+ # evalexpr_string()
+ #
+ # Helper for evalexpr that evaluates a string expression
+ # This implementation does basic C->python conversion and then uses eval()
+ # ----------------------------------------------------------------------
+ def evalexpr_string(self, expr):
expr = expr.replace("&&"," and ")
expr = expr.replace("||"," or ")
expr = expr.replace("!"," not ")
+ expr = expr.replace(" not ="," !=")
try:
result = eval(expr)
except Exception:
diff --git a/test/testcpp.py b/test/testcpp.py
index 45478ff..7e281a3 100644
--- a/test/testcpp.py
+++ b/test/testcpp.py
@@ -114,4 +114,22 @@ a"""
a"""
)
+ def test_evalexpr(self):
+ # #if 1 != 2 is not processed correctly; undefined values are converted
+ # to 0L instead of 0 (issue #195)
+ #
+ self.__test_preprocessing("""\
+#if (1!=0) && (!x || (!(1==2)))
+a;
+#else
+b;
+#endif
+"""
+ , """\
+
+a;
+
+"""
+ )
+
main()