Skip to content

Commit e02c689

Browse files
committed
Merge branch 'hotfix/v1.7.4'
2 parents cd1c87f + 1fdb986 commit e02c689

File tree

13 files changed

+226
-906
lines changed

13 files changed

+226
-906
lines changed

README.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ pygccxml
77
.. image:: https://coveralls.io/repos/gccxml/pygccxml/badge.svg?branch=master
88
:target: https://coveralls.io/r/gccxml/pygccxml?branch=master
99
:alt: Code coverage status
10-
.. image:: https://readthedocs.org/projects/pygccxml/badge/?version=master
11-
:target: https://readthedocs.org/projects/pygccxml/?badge=master
10+
.. image:: https://readthedocs.io/projects/pygccxml/badge/?version=master
11+
:target: https://readthedocs.io/projects/pygccxml/?badge=master
1212
:alt: Documentation status
1313
.. image:: https://www.quantifiedcode.com/api/v1/project/117af14ef32a455fb7b3762e21083fb3/snapshot/origin:master:HEAD/badge.svg
1414
:target: https://www.quantifiedcode.com/app/project/117af14ef32a455fb7b3762e21083fb3?branch=origin%2Fmaster&tab=basics
@@ -37,7 +37,7 @@ For issues with pygccxml you can open an issue here: https://github.com/gccxml/p
3737
Documentation
3838
-------------
3939

40-
For examples and tutorials see the documentation: http://pygccxml.readthedocs.org
40+
For examples and tutorials see the documentation: http://pygccxml.readthedocs.io
4141

4242
Branches
4343
--------

docs/conf.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@
5353
# built documents.
5454
#
5555
# The short X.Y version.
56-
version = 'v1.7.3'
56+
version = '1.7.4'
5757
# The full version, including alpha/beta/rc tags.
58-
release = 'v1.7.3'
58+
release = '1.7.4'
5959

6060
# The language for content autogenerated by Sphinx. Refer to documentation
6161
# for a list of supported languages.

docs/history.rst

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,26 @@ to python 3 (keeping it compatible with python 2).
1111
In Mai 2014, Michka Popoff and the Insight Software Consortium revived pygccxml
1212
by setting up a git repositery on github, hosted along with gccxml.
1313

14+
Version 1.7.4
15+
-------------
16+
17+
1. CV-qualified arrays were not being handled correctly by type traits
18+
manipulations functions. For instance, 'int const[N]' would not be
19+
detected as 'const'. Similar problems existed for volatile qualified
20+
arrays too. See #35 for more details. A newer version of CastXML is
21+
recommended (xml output version >= 1.138)
22+
23+
2. Close subprocess stdout stream once value has been read.
24+
Fixes some warnings under python3.
25+
26+
3. Since this release, pyggcxml's version numbers do not contain the ``v``
27+
prefix anymore. This was breaking distribution on PyPI (pypi.python.org).
28+
29+
4. The documentation is now at http://pygccxml.readthedocs.io/
30+
31+
Thanks to the following people for their contribution to this release:
32+
Ashish Sadanandan
33+
1434
Version 1.7.3
1535
-------------
1636

pygccxml/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,4 @@
4040
# TODO:
4141
# 1. Add "explicit" property for constructors
4242

43-
__version__ = 'v1.7.3'
43+
__version__ = '1.7.4'

pygccxml/declarations/type_traits.py

Lines changed: 52 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -284,19 +284,46 @@ def remove_reference(type):
284284
def is_const(type):
285285
"""returns True, if type represents C++ const type, False otherwise"""
286286
nake_type = remove_alias(type)
287-
return isinstance(nake_type, cpptypes.const_t)
287+
if isinstance(nake_type, cpptypes.const_t):
288+
return True
289+
elif isinstance(nake_type, cpptypes.volatile_t):
290+
return is_const(nake_type.base)
291+
elif isinstance(nake_type, cpptypes.array_t):
292+
return is_const(nake_type.base)
293+
return False
288294

289295

290-
def remove_const(type):
296+
def remove_const(type_):
291297
"""removes const from the type definition
292298
293299
If type is not const type, it will be returned as is
294300
"""
295301

296-
nake_type = remove_alias(type)
302+
nake_type = remove_alias(type_)
297303
if not is_const(nake_type):
298-
return type
304+
return type_
299305
else:
306+
# Handling for const and volatile qualified types. There is a
307+
# difference in behavior between GCCXML and CastXML for cv-qual arrays.
308+
# GCCXML produces the following nesting of types:
309+
# -> volatile_t(const_t(array_t))
310+
# while CastXML produces the following nesting:
311+
# -> array_t(volatile_t(const_t))
312+
# For both cases, we must unwrap the types, remove const_t, and add
313+
# back the outer layers
314+
if isinstance(nake_type, cpptypes.array_t):
315+
is_v = is_volatile(nake_type)
316+
if is_v:
317+
result_type = nake_type.base.base.base
318+
else:
319+
result_type = nake_type.base.base
320+
if is_v:
321+
result_type = cpptypes.volatile_t(result_type)
322+
return cpptypes.array_t(result_type, nake_type.size)
323+
324+
elif isinstance(nake_type, cpptypes.volatile_t):
325+
return cpptypes.volatile_t(nake_type.base.base)
326+
300327
return nake_type.base
301328

302329

@@ -322,7 +349,13 @@ def is_same(type1, type2):
322349
def is_volatile(type):
323350
"""returns True, if type represents C++ volatile type, False otherwise"""
324351
nake_type = remove_alias(type)
325-
return isinstance(nake_type, cpptypes.volatile_t)
352+
if isinstance(nake_type, cpptypes.volatile_t):
353+
return True
354+
elif isinstance(nake_type, cpptypes.const_t):
355+
return is_volatile(nake_type.base)
356+
elif isinstance(nake_type, cpptypes.array_t):
357+
return is_volatile(nake_type.base)
358+
return False
326359

327360

328361
def remove_volatile(type):
@@ -334,6 +367,16 @@ def remove_volatile(type):
334367
if not is_volatile(nake_type):
335368
return type
336369
else:
370+
if isinstance(nake_type, cpptypes.array_t):
371+
is_c = is_const(nake_type)
372+
if is_c:
373+
base_type = nake_type.base.base.base
374+
else:
375+
base_type = nake_type.base.base
376+
result_type = base_type
377+
if is_c:
378+
result_type = cpptypes.const_t(result_type)
379+
return cpptypes.array_t(result_type, nake_type.size)
337380
return nake_type.base
338381

339382

@@ -344,12 +387,12 @@ def remove_cv(type):
344387
if not is_const(nake_type) and not is_volatile(nake_type):
345388
return type
346389
result = nake_type
347-
if is_const(nake_type):
348-
result = nake_type.base
390+
if is_const(result):
391+
result = remove_const(result)
349392
if is_volatile(result):
350-
result = result.base
393+
result = remove_volatile(result)
351394
if is_const(result):
352-
result = result.base
395+
result = remove_const(result)
353396
return result
354397

355398

pygccxml/parser/config.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,7 @@ def create_compiler_path(xml_generator, compiler_path):
452452
p = subprocess.Popen(
453453
['which', 'clang++'], stdout=subprocess.PIPE)
454454
compiler_path = p.stdout.read().decode("utf-8").rstrip()
455+
p.stdout.close()
455456
# No clang found; use gcc
456457
if compiler_path == '':
457458
compiler_path = '/usr/bin/c++'

pygccxml/utils/utils.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,16 @@ def find_xml_generator(name=None):
5050
name = "gccxml"
5151
p = subprocess.Popen([command, name], stdout=subprocess.PIPE)
5252
path = p.stdout.read().decode("utf-8")
53+
p.stdout.close()
5354
if path == "":
5455
name = "castxml"
5556
p = subprocess.Popen([command, name], stdout=subprocess.PIPE)
5657
path = p.stdout.read().decode("utf-8")
58+
p.stdout.close()
5759
else:
5860
p = subprocess.Popen([command, name], stdout=subprocess.PIPE)
5961
path = p.stdout.read().decode("utf-8")
62+
p.stdout.close()
6063
if path == "":
6164
raise(Exception(
6265
"No c++ parser found. Please install castxml or gccxml."))

setup.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@
77
from setuptools import setup
88

99
setup(name="pygccxml",
10-
version="v1.7.3",
10+
version="1.7.4",
1111
author="Roman Yakovenko",
1212
author_email="roman yakovenko at gmail com",
1313
maintainer="Michka Popoff and the Insight Software Consortium",
1414
maintainer_email="[email protected]",
1515
description="Python package for easy C++ declarations navigation.",
1616
url="https://github.com/gccxml/pygccxml",
17-
download_url="https://github.com/gccxml/pygccxml/archive/master.zip",
17+
download_url="https://github.com/gccxml/pygccxml/archive/1.7.4.tar.gz",
1818
license="Boost",
1919
keywords="C++, declaration parser, CastXML, gccxml",
2020
packages=["pygccxml",

unittests/array_bug_tester.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,65 @@ def test4(self):
5555
'::xyz[2][3]' == aaaa_type.decl_string,
5656
aaaa_type.decl_string)
5757

58+
def test5(self):
59+
code = 'char const arr[4] = {};'
60+
src_reader = parser.source_reader_t(self.config)
61+
global_ns = declarations.get_global_namespace(
62+
src_reader.read_string(code))
63+
arr_type = global_ns.variable('arr').type
64+
if self.config.xml_generator == "gccxml":
65+
self.assertTrue(
66+
'char[4] const' == arr_type.decl_string,
67+
arr_type.decl_string)
68+
else:
69+
self.assertTrue(
70+
'char const[4]' == arr_type.decl_string,
71+
arr_type.decl_string)
72+
self.assertTrue(
73+
declarations.is_array(arr_type))
74+
self.assertTrue(
75+
declarations.is_const(arr_type))
76+
77+
def test6(self):
78+
code = 'char volatile arr[4] = {};'
79+
src_reader = parser.source_reader_t(self.config)
80+
global_ns = declarations.get_global_namespace(
81+
src_reader.read_string(code))
82+
arr_type = global_ns.variable('arr').type
83+
if self.config.xml_generator == "gccxml":
84+
self.assertTrue(
85+
'char[4] volatile' == arr_type.decl_string,
86+
arr_type.decl_string)
87+
else:
88+
self.assertTrue(
89+
'char volatile[4]' == arr_type.decl_string,
90+
arr_type.decl_string)
91+
self.assertTrue(
92+
declarations.is_array(arr_type))
93+
self.assertTrue(
94+
declarations.is_volatile(arr_type))
95+
96+
def test7(self):
97+
code = 'char const volatile arr[4] = {};'
98+
src_reader = parser.source_reader_t(self.config)
99+
global_ns = declarations.get_global_namespace(
100+
src_reader.read_string(code))
101+
arr_type = global_ns.variable('arr').type
102+
if self.config.xml_generator == "gccxml":
103+
self.assertTrue(
104+
'char[4] const volatile' == arr_type.decl_string,
105+
arr_type.decl_string)
106+
else:
107+
self.assertTrue(
108+
'char const volatile[4]' == arr_type.decl_string,
109+
arr_type.decl_string)
110+
self.assertTrue(
111+
declarations.is_array(arr_type))
112+
self.assertTrue(
113+
declarations.is_const(arr_type))
114+
self.assertTrue(
115+
declarations.is_volatile(arr_type))
116+
58117

59118
def create_suite():
60119
suite = unittest.TestSuite()

0 commit comments

Comments
 (0)