Skip to content

Commit 91df434

Browse files
committed
Add elaborated type specifier example
1 parent 284c129 commit 91df434

File tree

5 files changed

+104
-1
lines changed

5 files changed

+104
-1
lines changed

docs/examples.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ Advanced examples
3333
.. toctree::
3434
:maxdepth: 1
3535

36+
examples/elaborated/example.rst
3637
examples/function-pointer/example.rst
3738
examples/caching/example.rst
3839
examples/print-example/example.rst
40+

docs/examples/elaborated/example.hpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Copyright 2014-2017 Insight Software Consortium.
2+
// Copyright 2004-2009 Roman Yakovenko.
3+
// Distributed under the Boost Software License, Version 1.0.
4+
// See http://www.boost.org/LICENSE_1_0.txt
5+
6+
class A {};
7+
8+
A a1;
9+
class A a2;
10+
11+
void function(A arg1, class A arg2);

docs/examples/elaborated/example.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Copyright 2014-2017 Insight Software Consortium.
2+
# Copyright 2004-2009 Roman Yakovenko.
3+
# Distributed under the Boost Software License, Version 1.0.
4+
# See http://www.boost.org/LICENSE_1_0.txt
5+
6+
from pygccxml import utils
7+
from pygccxml import declarations
8+
from pygccxml import parser
9+
10+
import os
11+
import sys
12+
import warnings
13+
warnings.simplefilter("error", Warning)
14+
# Find out the file location within the sources tree
15+
this_module_dir_path = os.path.abspath(
16+
os.path.dirname(sys.modules[__name__].__file__))
17+
18+
# Find out the c++ parser
19+
generator_path, generator_name = utils.find_xml_generator()
20+
21+
# Configure the xml generator
22+
xml_generator_config = parser.xml_generator_configuration_t(
23+
xml_generator_path=generator_path,
24+
xml_generator=generator_name,
25+
castxml_epic_version=1)
26+
27+
# The c++ file we want to parse
28+
filename = "example.hpp"
29+
filename = this_module_dir_path + "/" + filename
30+
31+
decls = parser.parse([filename], xml_generator_config)
32+
global_namespace = declarations.get_global_namespace(decls)
33+
34+
a1 = global_namespace.variable("a1")
35+
print(str(a1.decl_type), type(a1.decl_type))
36+
# > 'A', <class 'pygccxml.declarations.cpptypes.declarated_t'>
37+
38+
print(declarations.is_elaborated(a1.decl_type))
39+
# > False
40+
41+
a2 = global_namespace.variable("a2")
42+
print(str(a2.decl_type), type(a2.decl_type))
43+
# > 'class ::A', <class 'pygccxml.declarations.cpptypes.elaborated_t'>
44+
45+
print(declarations.is_elaborated(a2.decl_type))
46+
# > True
47+
48+
base = declarations.remove_elaborated(a2.decl_type)
49+
print(str(base), type(base))
50+
# > 'A', <class 'pygccxml.declarations.cpptypes.declarated_t'>
51+
52+
# The same can be done with function arguments:
53+
fun = global_namespace.free_function("function")
54+
print(type(fun.arguments[0].decl_type), type(fun.arguments[1].decl_type))
55+
# > <class 'pygccxml.declarations.cpptypes.declarated_t'>,
56+
# <class 'pygccxml.declarations.cpptypes.elaborated_t'>

docs/examples/elaborated/example.rst

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
==========================
2+
Elaborated type specifiers
3+
==========================
4+
5+
Elaborated type specifiers are one of these four possibilities: *class*, *struct*, *union* or *enum*.
6+
7+
In C++ they can often be skipped (but may be useful; see `this interesting topic`_ for example).
8+
In C code they are mandatory.
9+
10+
Let's consider the following c++ file:
11+
12+
.. literalinclude:: example.hpp
13+
:language: c++
14+
:lines: 5-
15+
16+
The following code will show how the elaborated type specifiers are treated in pygccxml.
17+
Please note that this feature is only available since recent versions of *CastXML* (Mar 1, 2017),
18+
and a special flag needs to be passed to pygccxml to make this work (castxml_epic_version=1).
19+
20+
.. literalinclude:: example.py
21+
:language: python
22+
:lines: 6,7,8,17-27,29-
23+
24+
.. _`this interesting topic`: http://stackoverflow.com/questions/1675351/typedef-struct-vs-struct-definitions/1675446#1675446

unittests/example_tester.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@
88
import unittest
99
import subprocess
1010

11+
from . import parser_test_case
1112

12-
class Test(unittest.TestCase):
13+
14+
class Test(parser_test_case.parser_test_case_t):
1315

1416
def test_example(self):
1517
"""Runs the example in the docs directory"""
@@ -30,6 +32,14 @@ def test_example(self):
3032
file_paths.append(os.path.join(root, file_path))
3133

3234
for file_path in file_paths:
35+
36+
if "elaborated" in file_path and\
37+
self.config.castxml_epic_version != 1:
38+
# Don't run this test if the castxml_epic_version was not
39+
# set to 1, because the test needs to be able to run with
40+
# that version
41+
continue
42+
3343
return_code = subprocess.call(
3444
["python", path + "/example_tester_wrap.py", file_path],
3545
env=env)

0 commit comments

Comments
 (0)