diff options
author | Rob Reilink <rob@reilink.net> | 2018-12-31 12:25:02 +0100 |
---|---|---|
committer | Rob Reilink <rob@reilink.net> | 2018-12-31 12:25:02 +0100 |
commit | 73a573a1b256fc73598bd4d93756bb618fd815fa (patch) | |
tree | ad71753d635e1e2fe958421a68fb428e8f3ebb62 | |
parent | a37e0839583d683d95e70ce1445c0063c7d4bd21 (diff) | |
download | ply-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.py | 23 | ||||
-rw-r--r-- | test/testcpp.py | 18 |
2 files changed, 39 insertions, 2 deletions
@@ -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() |