diff options
author | Eli Bendersky <eliben@users.noreply.github.com> | 2016-09-10 08:27:48 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-09-10 08:27:48 -0700 |
commit | de582ad48bd94a15d352e4a43691d26dfd5ff109 (patch) | |
tree | 30d05f3c50fe50e3832a63bcdbe2f9a6be5d0253 | |
parent | f8718097468025958a024b62942b032807d01bb9 (diff) | |
parent | 749650a2e24051cdd6a7bfa803c03e0a5fa77103 (diff) | |
download | pycparser-de582ad48bd94a15d352e4a43691d26dfd5ff109.tar.gz |
Merge pull request #145 from Ksero/Issue87
Fix eliben/pycparser#87 : offsetof() support is incomplete
-rw-r--r-- | pycparser/c_parser.py | 17 | ||||
-rwxr-xr-x | tests/test_c_parser.py | 6 |
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 # |