Skip to content

Commit

Permalink
Merge pull request dabeaz#197 from rreilink/master
Browse files Browse the repository at this point in the history
Fixes issues dabeaz#195, 196
  • Loading branch information
dabeaz authored Jan 19, 2019
2 parents a37e083 + bd76ca8 commit 07911e1
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 4 deletions.
39 changes: 35 additions & 4 deletions ply/cpp.py
Original file line number Diff line number Diff line change
Expand Up @@ -617,22 +617,41 @@ def evalexpr(self,tokens):
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
tokens[i].value = str(tokens[i].value)
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:
Expand Down Expand Up @@ -805,8 +824,7 @@ def include(self,tokens):
for p in path:
iname = os.path.join(p,filename)
try:
with open(iname) as f:
data = f.read()
data = self.read_include_file(iname)
dname = os.path.dirname(iname)
if dname:
self.temp_path.insert(0,dname)
Expand All @@ -820,6 +838,19 @@ def include(self,tokens):
else:
print("Couldn't find '%s'" % filename)

# ----------------------------------------------------------------------
# read_include_file()
#
# Reads a source file for inclusion using #include
# Could be overridden to e.g. customize encoding, limit access to
# certain paths on the filesystem, or provide the contents of system
# include files
# ----------------------------------------------------------------------

def read_include_file(self, filepath):
with open(filepath, 'r', encoding='utf-8', errors='surrogateescape') as file:
return file.read()

# ----------------------------------------------------------------------
# define()
#
Expand Down
2 changes: 2 additions & 0 deletions test/test_cpp_nonascii.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/* ë */
#define x 1
36 changes: 36 additions & 0 deletions test/testcpp.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from six.moves.queue import Empty

import sys
import locale

if ".." not in sys.path:
sys.path.insert(0, "..")
Expand Down Expand Up @@ -114,4 +115,39 @@ def test_index_error(self):
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;
"""
)

def test_include_nonascii(self):
# Issue #196: #included files are read using the current locale's
# getdefaultencoding. if a #included file contains non-ascii characters,
# while default encoding is e.g. US_ASCII, this causes an error
locale.setlocale(locale.LC_ALL, 'C')
self.__test_preprocessing("""\
#include "test_cpp_nonascii.c"
x;
"""
, """\
1;
"""
)

main()

0 comments on commit 07911e1

Please sign in to comment.