summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Bendersky <eliben@users.noreply.github.com>2016-09-10 08:27:48 -0700
committerGitHub <noreply@github.com>2016-09-10 08:27:48 -0700
commitde582ad48bd94a15d352e4a43691d26dfd5ff109 (patch)
tree30d05f3c50fe50e3832a63bcdbe2f9a6be5d0253
parentf8718097468025958a024b62942b032807d01bb9 (diff)
parent749650a2e24051cdd6a7bfa803c03e0a5fa77103 (diff)
downloadpycparser-de582ad48bd94a15d352e4a43691d26dfd5ff109.tar.gz
Merge pull request #145 from Ksero/Issue87
Fix eliben/pycparser#87 : offsetof() support is incomplete
-rw-r--r--pycparser/c_parser.py17
-rwxr-xr-xtests/test_c_parser.py6
2 files changed, 22 insertions, 1 deletions
diff --git a/pycparser/c_parser.py b/pycparser/c_parser.py
index 53f445a..cf062fb 100644
--- a/pycparser/c_parser.py
+++ b/pycparser/c_parser.py
@@ -1608,13 +1608,28 @@ class CParser(PLYParser):
p[0] = p[2]
def p_primary_expression_5(self, p):
- """ primary_expression : OFFSETOF LPAREN type_name COMMA identifier RPAREN
+ """ primary_expression : OFFSETOF LPAREN type_name COMMA offsetof_member_designator RPAREN
"""
coord = self._coord(p.lineno(1))
p[0] = c_ast.FuncCall(c_ast.ID(p[1], coord),
c_ast.ExprList([p[3], p[5]], coord),
coord)
+ def p_offsetof_member_designator(self, p):
+ """ offsetof_member_designator : identifier
+ | offsetof_member_designator PERIOD identifier
+ | offsetof_member_designator LBRACKET expression RBRACKET
+ """
+ if len(p) == 2:
+ p[0] = p[1]
+ elif len(p) == 4:
+ field = c_ast.ID(p[3], self._coord(p.lineno(3)))
+ p[0] = c_ast.StructRef(p[1], p[2], field, p[1].coord)
+ elif len(p) == 5:
+ p[0] = c_ast.ArrayRef(p[1], p[3], p[1].coord)
+ else:
+ raise NotImplementedError("Unexpected parsing state. len(p): %u" % len(p))
+
def p_argument_expression_list(self, p):
""" argument_expression_list : assignment_expression
| argument_expression_list COMMA assignment_expression
diff --git a/tests/test_c_parser.py b/tests/test_c_parser.py
index 277c750..3adb62c 100755
--- a/tests/test_c_parser.py
+++ b/tests/test_c_parser.py
@@ -480,6 +480,8 @@ class TestCParser_fundamentals(TestCParser_base):
void foo() {
int a = offsetof(struct S, p);
a.b = offsetof(struct sockaddr, sp) + strlen(bar);
+ int a = offsetof(struct S, p.q.r);
+ int a = offsetof(struct S, p[5].q[4][5]);
}
"""
compound = self.parse(e).ext[0].body
@@ -489,6 +491,10 @@ class TestCParser_fundamentals(TestCParser_base):
self.assertEqual(s1.name.name, 'offsetof')
self.assertTrue(isinstance(s1.args.exprs[0], Typename))
self.assertTrue(isinstance(s1.args.exprs[1], ID))
+ s3 = compound.block_items[2].init
+ self.assertTrue(isinstance(s3.args.exprs[1], StructRef))
+ s4 = compound.block_items[3].init
+ self.assertTrue(isinstance(s4.args.exprs[1], ArrayRef))
# The C99 compound literal feature
#