Skip to content

Commit

Permalink
Merge branch 'hotfix/v1.7.5'
Browse files Browse the repository at this point in the history
  • Loading branch information
iMichka committed May 24, 2016
2 parents e02c689 + 52ad762 commit 54201e5
Show file tree
Hide file tree
Showing 14 changed files with 222 additions and 68 deletions.
4 changes: 2 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ pygccxml
.. image:: https://coveralls.io/repos/gccxml/pygccxml/badge.svg?branch=master
:target: https://coveralls.io/r/gccxml/pygccxml?branch=master
:alt: Code coverage status
.. image:: https://readthedocs.io/projects/pygccxml/badge/?version=master
:target: https://readthedocs.io/projects/pygccxml/?badge=master
.. image:: https://readthedocs.org/projects/pygccxml/badge/?version=master
:target: http://pygccxml.readthedocs.io/en/master/?badge=master
:alt: Documentation status
.. image:: https://www.quantifiedcode.com/api/v1/project/117af14ef32a455fb7b3762e21083fb3/snapshot/origin:master:HEAD/badge.svg
:target: https://www.quantifiedcode.com/app/project/117af14ef32a455fb7b3762e21083fb3?branch=origin%2Fmaster&tab=basics
Expand Down
4 changes: 2 additions & 2 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@
# built documents.
#
# The short X.Y version.
version = '1.7.4'
version = '1.7.5'
# The full version, including alpha/beta/rc tags.
release = '1.7.4'
release = '1.7.5'

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down
16 changes: 16 additions & 0 deletions docs/history.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,22 @@ to python 3 (keeping it compatible with python 2).
In Mai 2014, Michka Popoff and the Insight Software Consortium revived pygccxml
by setting up a git repositery on github, hosted along with gccxml.

Version 1.7.5
-------------

1. Improve error message when no castxml or gccxml is found.

2. Fix compilation of tests with c++11.

3. Fix patching of enums in default arguments for C++03.

4. Version numbers are still tagged with the v prefix (1.7.4 was correctly tagged),
as this is recommended by GitHub. The version number in the __init__.py and
setup.py files are without v prefix, because this is what pip requires.

Thanks to the following people for their contribution to this release:
Ashish Sadanandan

Version 1.7.4
-------------

Expand Down
2 changes: 1 addition & 1 deletion pygccxml/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@
# TODO:
# 1. Add "explicit" property for constructors

__version__ = '1.7.4'
__version__ = '1.7.5'
4 changes: 3 additions & 1 deletion pygccxml/parser/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -450,9 +450,11 @@ def create_compiler_path(xml_generator, compiler_path):
if platform.system() != 'Windows':
# On windows there is no need for the compiler path
p = subprocess.Popen(
['which', 'clang++'], stdout=subprocess.PIPE)
['which', 'clang++'], stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
compiler_path = p.stdout.read().decode("utf-8").rstrip()
p.stdout.close()
p.stderr.close()
# No clang found; use gcc
if compiler_path == '':
compiler_path = '/usr/bin/c++'
Expand Down
29 changes: 20 additions & 9 deletions pygccxml/parser/patcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@

class default_argument_patcher_t(object):

def __init__(self, enums):
def __init__(self, enums, cxx_std):
object.__init__(self)
self.__enums = enums
self.__cxx_std = cxx_std

def __call__(self, decl):
for arg in decl.arguments:
Expand Down Expand Up @@ -54,8 +55,12 @@ def __is_unqualified_enum(self, func, arg):
def __fix_unqualified_enum(self, func, arg):
type_ = declarations.remove_reference(declarations.remove_cv(arg.type))
enum_type = declarations.enum_declaration(type_)
if self.__cxx_std.is_cxx11_or_greater:
qualifier_decl_string = enum_type.decl_string
else:
qualifier_decl_string = enum_type.parent.decl_string
return self.__join_names(
enum_type.parent.decl_string,
qualifier_decl_string,
arg.default_value.split('::')[-1])

def __is_invalid_integral(self, func, arg):
Expand Down Expand Up @@ -92,19 +97,25 @@ def __fix_invalid_integral(self, func, arg):
pass

# may be we deal with enum
# CastXML qualifies the enum value with enum type, so split the
# argument and use only the enum value
enum_value = arg.default_value.split('::')[-1]
parent = func.parent
while parent:
found = self.__find_enum(parent, arg.default_value)
found = self.__find_enum(parent, enum_value)
if found:
if declarations.is_fundamental(arg.type) and ' ' in \
arg.type.decl_string:
template = '(%s)(%s)'
else:
template = '%s(%s)'
if self.__cxx_std.is_cxx11_or_greater:
qualifier_decl_string = found.decl_string
else:
qualifier_decl_string = found.parent.decl_string
return template % (arg.type.decl_string,
self.__join_names(
found.parent.decl_string,
arg.default_value))
self.__join_names(qualifier_decl_string,
enum_value))
else:
parent = parent.parent

Expand Down Expand Up @@ -132,7 +143,7 @@ def __fix_invalid_integral(self, func, arg):

def __find_enum(self, scope, default_value):
# this algorithm could be improved: it could take into account
# 1. unnamed namespaced
# 1. unnamed namespace
# 2. location within files

for enum in self.__enums:
Expand Down Expand Up @@ -221,8 +232,8 @@ def __call__(self, decl):
_casting_oper_patcher_ = casting_operator_patcher_t()


def fix_calldef_decls(decls, enums):
default_arg_patcher = default_argument_patcher_t(enums)
def fix_calldef_decls(decls, enums, cxx_std):
default_arg_patcher = default_argument_patcher_t(enums, cxx_std)
# decls should be flat list of all declarations, you want to apply patch on
for decl in decls:
default_arg_patcher(decl)
Expand Down
34 changes: 9 additions & 25 deletions pygccxml/parser/source_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ def __init__(self, config, cache=None, decl_factory=None, join_decls=True):
self.__join_decls = join_decls
self.__search_directories = []
self.__config = config
self.__cxx_std = utils.cxx_standard(config.cflags)
self.__search_directories.append(config.working_directory)
self.__search_directories.extend(config.include_paths)
if not cache:
Expand Down Expand Up @@ -163,30 +164,12 @@ def __create_command_line_castxml(self, source_file, xmlfile):
# On mac or linux, use gcc or clang (the flag is the same)
cmd.append('--castxml-cc-gnu ')

# Check for -std=xx flags passed to the compiler.
# A regex could be used but this is a moving target.
# See c++1z for example. It is preferable to have a defined
# list of what is allowed. http://clang.llvm.org/cxx_status.html
#
# Version 98 and 03 are only there in the case somebody is using
# these flags; this is the equivalent to not passing these flags.
standards = [
"-std=c++98",
"-std=c++03",
"-std=c++11",
"-std=c++14",
"-std=c++1z"]

std_flag = ""
for standard in standards:
if standard in self.__config.cflags:
std_flag = " " + standard + " "

# A -std= flag was passed, but is not in the list
if "-std=" in self.__config.cflags and std_flag == "":
raise(RuntimeError("Unknown -std=c++xx flag used !"))

if std_flag != "":
if self.__cxx_std.is_implicit:
std_flag = ''
else:
std_flag = ' ' + self.__cxx_std.stdcxx + ' '

if std_flag:
cmd.append(
'"(" ' + self.__config.compiler_path + std_flag + '")"')
else:
Expand Down Expand Up @@ -502,7 +485,8 @@ def __parse_xml_file(self, xml_file):
# void ddd(){ typedef typename X::Y YY;}
# if I will fail on this bug next time, the right way to fix it may be
# different
patcher.fix_calldef_decls(scanner_.calldefs(), scanner_.enums())
patcher.fix_calldef_decls(scanner_.calldefs(), scanner_.enums(),
self.__cxx_std)
decls = [
inst for inst in iter(
decls.values()) if isinstance(
Expand Down
1 change: 1 addition & 0 deletions pygccxml/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from .utils import normalize_path
from .utils import find_xml_generator
from .utils import get_tr1
from .utils import cxx_standard

# Version of xml generator which was used.
xml_generator = None
Expand Down
103 changes: 100 additions & 3 deletions pygccxml/utils/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,24 @@ def find_xml_generator(name=None):

if name is None:
name = "gccxml"
p = subprocess.Popen([command, name], stdout=subprocess.PIPE)
p = subprocess.Popen([command, name], stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
path = p.stdout.read().decode("utf-8")
p.stdout.close()
p.stderr.close()
if path == "":
name = "castxml"
p = subprocess.Popen([command, name], stdout=subprocess.PIPE)
p = subprocess.Popen([command, name], stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
path = p.stdout.read().decode("utf-8")
p.stdout.close()
p.stderr.close()
else:
p = subprocess.Popen([command, name], stdout=subprocess.PIPE)
p = subprocess.Popen([command, name], stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
path = p.stdout.read().decode("utf-8")
p.stdout.close()
p.stderr.close()
if path == "":
raise(Exception(
"No c++ parser found. Please install castxml or gccxml."))
Expand Down Expand Up @@ -346,3 +352,94 @@ def get_tr1(name):
if "tr1" in name:
tr1 = "tr1::"
return tr1


class cxx_standard(object):
"""Helper class for parsing the C++ standard version.
This class holds the C++ standard version the XML generator has been
configured with, and provides helpers functions for querying C++ standard
version related information.
"""

__STD_CXX = {
'-std=c++98': 199711,
'-std=gnu++98': 199711,
'-std=c++03': 199711,
'-std=gnu++03': 199711,
'-std=c++0x': 201103,
'-std=gnu++0x': 201103,
'-std=c++11': 201103,
'-std=gnu++11': 201103,
'-std=c++1y': 201402,
'-std=gnu++1y': 201402,
'-std=c++14': 201402,
'-std=gnu++14': 201402,
'-std=c++1z': float('inf'),
'-std=gnu++1z': float('inf'),
}

def __init__(self, cflags):
"""Class constructor that parses the XML generator's command line
Args:
cflags (str): cflags command line arguments passed to the XML
generator
"""
super(cxx_standard, self).__init__()

self._stdcxx = None
self._is_implicit = False
for key in cxx_standard.__STD_CXX:
if key in cflags:
self._stdcxx = key
self._cplusplus = cxx_standard.__STD_CXX[key]

if not self._stdcxx:
if '-std=' in cflags:
raise RuntimeError('Unknown -std=c++xx flag used')

# Assume c++03 by default
self._stdcxx = '-std=c++03'
self._cplusplus = cxx_standard.__STD_CXX['-std=c++03']
self._is_implicit = True

@property
def stdcxx(self):
"""Returns the -std=c++xx option passed to the constructor"""
return self._stdcxx

@property
def is_implicit(self):
"""Indicates whether a -std=c++xx was specified"""
return self._is_implicit

@property
def is_cxx03(self):
"""Returns true if -std=c++03 is being used"""
return self._cplusplus == cxx_standard.__STD_CXX['-std=c++03']

@property
def is_cxx11(self):
"""Returns true if -std=c++11 is being used"""
return self._cplusplus == cxx_standard.__STD_CXX['-std=c++11']

@property
def is_cxx11_or_greater(self):
"""Returns true if -std=c++11 or a newer standard is being used"""
return self._cplusplus >= cxx_standard.__STD_CXX['-std=c++11']

@property
def is_cxx14(self):
"""Returns true if -std=c++14 is being used"""
return self._cplusplus == cxx_standard.__STD_CXX['-std=c++14']

@property
def is_cxx14_or_greater(self):
"""Returns true if -std=c++14 or a newer standard is being used"""
return self._cplusplus >= cxx_standard.__STD_CXX['-std=c++14']

@property
def is_cxx1z(self):
"""Returns true if -std=c++1z is being used"""
return self._cplusplus == cxx_standard.__STD_CXX['-std=c++1z']
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@
from setuptools import setup

setup(name="pygccxml",
version="1.7.4",
version="1.7.5",
author="Roman Yakovenko",
author_email="roman yakovenko at gmail com",
maintainer="Michka Popoff and the Insight Software Consortium",
maintainer_email="[email protected]",
description="Python package for easy C++ declarations navigation.",
url="https://github.com/gccxml/pygccxml",
download_url="https://github.com/gccxml/pygccxml/archive/1.7.4.tar.gz",
download_url="https://github.com/gccxml/pygccxml/archive/v1.7.5.tar.gz",
license="Boost",
keywords="C++, declaration parser, CastXML, gccxml",
packages=["pygccxml",
Expand Down
4 changes: 2 additions & 2 deletions unittests/data/free_operators.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ bool operator!( const number& x ){
}

number operator*( const number& n, double i ){
number n2 = { n.i * i };
number n2 = { static_cast<int>(n.i * i) };
return n2;
}

number operator*( double i, const number& n ){
number n2 = { n.i * i };
number n2 = { static_cast<int>(n.i * i) };
return n2;
}

Expand Down
23 changes: 23 additions & 0 deletions unittests/data/patcher.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,22 @@ void fix_enum3( fruit arg=orange );

}

#if __cplusplus >= 201103L
namespace ns4{

enum class color {red, green, blue};
void fix_enum4( color arg=color::blue );

}

namespace ns5{

using namespace ns4;
void fix_enum5( color arg=color::blue );

}
#endif

typedef unsigned long long ull;
void fix_numeric( ull arg=(ull)-1 );

Expand Down Expand Up @@ -76,6 +92,13 @@ static int const DEFAULT_1 = 20;
int fun2( int arg1=DEFAULT_1, int arg2=ns1::DEFAULT_1, long arg3=::ns1::st1::DEFAULT_2 );


enum ACE_Log_Priority_Index
{
LM_INVALID_BIT_INDEX = 32
};
static int log_priority_enabled(long priority_index = LM_INVALID_BIT_INDEX);


/*struct default_arg_t{};*/
/*default_arg_t create_default_argument();*/
/*void double_call( default_arg_t x=create_default_argument() );*/
Expand Down
Loading

0 comments on commit 54201e5

Please sign in to comment.