Hello community,

here is the log from the commit of package python-cppclean for openSUSE:Factory 
checked in at 2019-09-27 14:47:05
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-cppclean (Old)
 and      /work/SRC/openSUSE:Factory/.python-cppclean.new.2352 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-cppclean"

Fri Sep 27 14:47:05 2019 rev:3 rq:730672 version:0.13

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-cppclean/python-cppclean.changes  
2019-03-05 12:20:17.912933348 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-cppclean.new.2352/python-cppclean.changes    
    2019-09-27 14:47:09.816965220 +0200
@@ -1,0 +2,6 @@
+Fri Sep 13 10:36:10 UTC 2019 - Tomáš Chvátal <[email protected]>
+
+- Update to 0.13:
+  * minor fixes
+
+-------------------------------------------------------------------

Old:
----
  v0.12.tar.gz

New:
----
  v0.13.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-cppclean.spec ++++++
--- /var/tmp/diff_new_pack.21Z06D/_old  2019-09-27 14:47:11.700960321 +0200
+++ /var/tmp/diff_new_pack.21Z06D/_new  2019-09-27 14:47:11.716960280 +0200
@@ -18,7 +18,7 @@
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-cppclean
-Version:        0.12
+Version:        0.13
 Release:        0
 Summary:        Program to find problems in C++ source code
 License:        Apache-2.0
@@ -42,8 +42,6 @@
 
 %prep
 %setup -q -n cppclean-%{version}
-# 
https://github.com/myint/cppclean/commit/998e80d02eb27fa7a59ac23db41ae3854f3c2d19
-rm test/unicode.h
 
 %build
 %python_build

++++++ v0.12.tar.gz -> v0.13.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cppclean-0.12/.gitignore new/cppclean-0.13/.gitignore
--- old/cppclean-0.12/.gitignore        2016-08-07 21:04:26.000000000 +0200
+++ new/cppclean-0.13/.gitignore        2019-07-30 14:18:50.000000000 +0200
@@ -11,3 +11,4 @@
 *.egg*/
 .coverage
 .travis-solo/
+tags
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cppclean-0.12/.travis.yml 
new/cppclean-0.13/.travis.yml
--- old/cppclean-0.12/.travis.yml       2016-08-07 21:04:26.000000000 +0200
+++ new/cppclean-0.13/.travis.yml       2019-07-30 14:18:50.000000000 +0200
@@ -2,9 +2,9 @@
 
 python:
     - "2.7"
-    - "3.3"
     - "3.4"
     - "3.5"
+    - "3.6"
     - "nightly"
 
 install:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cppclean-0.12/Makefile new/cppclean-0.13/Makefile
--- old/cppclean-0.12/Makefile  2016-08-07 21:04:26.000000000 +0200
+++ new/cppclean-0.13/Makefile  2019-07-30 14:18:50.000000000 +0200
@@ -1,3 +1,5 @@
+default: check test
+
 check:
        pylint \
                --reports=no \
@@ -6,11 +8,15 @@
                --disable=bad-continuation \
                --disable=duplicate-code \
                --disable=fixme \
+               --disable=invalid-name \
                --disable=missing-docstring \
+               --disable=no-else-return \
+               --disable=no-self-use \
                --disable=too-many-arguments \
-               --disable=invalid-name \
+               --disable=raising-bad-type \
                --disable=redefined-variable-type \
                --disable=simplifiable-if-statement \
+               --disable=too-few-public-methods \
                --disable=too-many-locals \
                --disable=too-many-return-statements \
                --disable=too-many-instance-attributes \
@@ -18,10 +24,8 @@
                --disable=too-many-branches \
                --disable=too-many-lines \
                --disable=too-many-statements \
-               --disable=no-self-use \
                --disable=undefined-loop-variable \
                --disable=unused-argument \
-               --disable=too-few-public-methods \
                cpp cppclean setup.py
        pycodestyle cpp $(wildcard *.py)
        check-manifest
@@ -29,7 +33,7 @@
 
 coverage:
        @coverage erase
-       @PYTHON='coverage run --parallel-mode' ./test.bash
+       @PYTHON='coverage run --branch --parallel-mode' ./test.bash
        @coverage combine
        @coverage report
 
@@ -39,3 +43,8 @@
 
 readme:
        @restview --long-description --strict
+
+test:
+       ./test.bash
+
+.PHONY: check coverage open_coverage readme test
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cppclean-0.12/cpp/__init__.py 
new/cppclean-0.13/cpp/__init__.py
--- old/cppclean-0.12/cpp/__init__.py   2016-08-07 21:04:26.000000000 +0200
+++ new/cppclean-0.13/cpp/__init__.py   2019-07-30 14:18:50.000000000 +0200
@@ -1 +1 @@
-__version__ = '0.12'
+__version__ = '0.13'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cppclean-0.12/cpp/ast.py new/cppclean-0.13/cpp/ast.py
--- old/cppclean-0.12/cpp/ast.py        2016-08-07 21:04:26.000000000 +0200
+++ new/cppclean-0.13/cpp/ast.py        2019-07-30 14:18:50.000000000 +0200
@@ -19,6 +19,9 @@
 from __future__ import print_function
 from __future__ import unicode_literals
 
+import os
+import collections
+
 from . import keywords
 from . import tokenize
 
@@ -94,11 +97,18 @@
         Node.__init__(self, start, end)
         self.name = name
         self.definition = definition
+        # TODO(christarazi):
+        # Defines aren't bound to namespaces, so this is just a stopgap
+        # solution.
+        self.namespace = []
 
     def __str__(self):
         value = '%s %s' % (self.name, self.definition)
         return self._string_helper(self.__class__.__name__, value)
 
+    def is_exportable(self):
+        return True
+
 
 class Include(Node):
 
@@ -271,7 +281,10 @@
 class Function(_GenericDeclaration):
 
     def __init__(self, start, end, name, return_type, parameters,
-                 specializations, modifiers, templated_types, body, namespace):
+                 specializations, modifiers, templated_types, body, namespace,
+                 initializers=None):
+        if initializers is None:
+            initializers = {}
         _GenericDeclaration.__init__(self, start, end, name, namespace)
         converter = TypeConverter(namespace)
         self.return_type = converter.create_return_type(return_type)
@@ -280,6 +293,7 @@
         self.modifiers = modifiers
         self.body = body
         self.templated_types = templated_types
+        self.initializers = initializers
 
     def is_declaration(self):
         return self.body is None
@@ -308,6 +322,14 @@
 
     def __init__(self, start, end, name, in_class, return_type, parameters,
                  specializations, modifiers, templated_types, body, namespace):
+        # TODO(christarazi):
+        # Add support for ctor initializers.
+        # For now, only inline defined ctors are supported because we would
+        # need to figure out how to keep state of which class is currently
+        # being processed in order to modify its body (var decls).
+        #
+        # Note: ctor initializers are inside Function because a inline defined
+        # class members are parsed as functions rather than methods.
         Function.__init__(self, start, end, name, return_type, parameters,
                           specializations, modifiers, templated_types,
                           body, namespace)
@@ -328,7 +350,6 @@
         templated_types: [Class (Type?)] template type info between <>
         modifiers: [str] type modifiers (keywords) eg, const, mutable, etc.
         reference, pointer, array: bools
-
         """
         _GenericDeclaration.__init__(self, start, end, name, [])
         self.templated_types = templated_types
@@ -392,7 +413,6 @@
 
         Returns:
           [Class(...), ...]
-
         """
         result = []
         name_tokens = []
@@ -613,11 +633,14 @@
 
 class ASTBuilder(object):
 
-    def __init__(self, token_stream, filename, in_class=None,
+    def __init__(self, token_stream, filename, system_includes=tuple(),
+                 nonsystem_includes=tuple(), in_class=None,
                  namespace_stack=None, quiet=False):
         if namespace_stack is None:
             namespace_stack = []
 
+        self.system_includes = system_includes
+        self.nonsystem_includes = nonsystem_includes
         self.tokens = token_stream
         self.filename = filename
         self.token_queue = []
@@ -644,13 +667,17 @@
                 self.namespaces.append(False)
                 continue
             if token.name == '}':
-                if self.namespaces.pop():
+                if self.namespaces and self.namespaces.pop():
                     self.namespace_stack.pop()
                 continue
 
-            result = self._generate_one(token)
-            if result:
-                yield result
+            try:
+                result = self._generate_one(token)
+            except StopIteration:
+                pass
+            else:
+                if result:
+                    yield result
 
     def _create_variable(self, pos_token, name, type_name, type_modifiers,
                          ref_pointer_name_seq, templated_types=None, value=''):
@@ -742,13 +769,24 @@
                 if name.startswith('\\'):
                     name = name[1:].strip()
 
-                system = True
-                filename = name
-                if name[0] in '<"':
-                    assert_parse(name[-1] in '>"', token)
+                filename = name.strip('<>"')
+
+                def _is_file(prefix):
+                    return os.path.isfile(os.path.join(prefix, filename))
+
+                if any([d for d in self.system_includes if _is_file(d)]):
+                    system = True
+                elif any([d for d in self.nonsystem_includes if _is_file(d)]):
+                    system = False
+                else:
+                    system = True
+                    filename = name
+
+                    if name[0] in '<"':
+                        assert_parse(name[-1] in '>"', token)
+                        system = name[0] == '<'
+                        filename = name[1:-1]
 
-                    system = name[0] == '<'
-                    filename = name[1:-1]
                 return Include(token.start, token.end, filename, system)
             if name.startswith('define'):
                 # Remove "define".
@@ -786,6 +824,26 @@
         return self._get_var_tokens_up_to(False,
                                           expected_token)[0]
 
+    def _get_var_tokens_up_to_w_function(self, skip_bracket_content,
+                                         *expected_tokens):
+        # handle the std::function and boost::function case
+        tokens, last = self._get_var_tokens_up_to(False, *expected_tokens)
+        names = [token.name for token in tokens]
+        ctr = collections.Counter(names)
+        if ('(' in expected_tokens and
+            ctr['<'] != ctr['>'] and
+            ctr['function'] == 1 and
+                last.name == '('):
+
+            idx = names.index('function')
+            if idx + 1 < len(tokens) and tokens[idx + 1].name == '<':
+                new_tokens, new_last = \
+                    self._get_var_tokens_up_to(False, '(', ';')
+                tokens.append(last)
+                last = new_last
+                tokens += new_tokens
+        return tokens, last
+
     def _get_var_tokens_up_to(self, skip_bracket_content, *expected_tokens):
         last_token = self._get_next_token()
         tokens = []
@@ -883,7 +941,8 @@
         return tokens, next_token
 
     def get_method(self, modifiers, templated_types):
-        return_type_and_name = self._get_tokens_up_to('(')
+        return_type_and_name = \
+            self._get_var_tokens_up_to_w_function(False, '(')[0]
         assert len(return_type_and_name) >= 1
         return self._get_method(
             return_type_and_name, modifiers, templated_types,
@@ -1027,13 +1086,22 @@
         assert_parse(token.token_type == tokenize.SYNTAX, token)
 
         # Handle ctor initializers.
+        # Supports C++11 method of direct initialization with braces.
+        initializers = {}
         if token.name == ':':
             while token.name != ';' and token.name != '{':
-                _, token = self.get_name()
-                if token.name == '(':
-                    list(self._get_matching_char('(', ')'))
-                elif token.name == '{':
-                    list(self._get_matching_char('{', '}'))
+                # skip preprocesors macros
+                if token.name.startswith(('#if', '#elif', '#else', '#endif')):
+                    token = self._get_next_token()
+                    continue
+                member, token = self.get_name()
+                member = member[0]
+                if token.name == '(' or token.name == '{':
+                    end = '}' if token.name == '{' else ')'
+                    initializers[member] = [
+                        x for x in list(self._get_matching_char(token.name,
+                                                                end))
+                        if x.name != ',' and x.name != end]
                 token = self._get_next_token()
 
         # Handle pointer to functions.
@@ -1100,7 +1168,8 @@
                           templated_types, body, self.namespace_stack)
         return Function(indices.start, indices.end, name.name, return_type,
                         parameters, specializations, modifiers,
-                        templated_types, body, self.namespace_stack)
+                        templated_types, body, self.namespace_stack,
+                        initializers)
 
     def _get_variable(self, tokens):
         name, type_name, templated_types, modifiers, default, _ = \
@@ -1381,7 +1450,7 @@
             elif token.name == 'template':
                 return self.handle_template()
         self._add_back_token(token)
-        tokens, last = self._get_var_tokens_up_to(False, '(', ';')
+        tokens, last = self._get_var_tokens_up_to_w_function(False, '(', ';')
         tokens.append(last)
         self._add_back_tokens(tokens)
         if last.name == '(':
@@ -1428,6 +1497,7 @@
     def _get_class(self, class_type, templated_types):
         class_name = None
         class_token = self._get_next_token()
+        name_tokens = []
         if class_token.token_type != tokenize.NAME:
             assert_parse(class_token.token_type == tokenize.SYNTAX,
                          class_token)
@@ -1480,11 +1550,34 @@
         body = None
         if token.token_type == tokenize.SYNTAX and token.name == '{':
             name = class_name or '__unamed__'
-            ast = ASTBuilder(self.get_scope(), self.filename, name,
+            ast = ASTBuilder(self.get_scope(), self.filename,
+                             self.system_includes, self.nonsystem_includes,
+                             name,
                              self.namespace_stack,
                              quiet=self.quiet)
             body = list(ast.generate())
 
+            ctor = None
+            for member in body:
+                if isinstance(member, Function) and member.name == class_name:
+                    ctor = member
+                    break
+
+            # Merge ctor initializers with class members.
+            if ctor:
+                initializers = body[body.index(ctor)].initializers
+                var_decls = [x for x in body
+                             if isinstance(x, VariableDeclaration)]
+                for var in var_decls:
+                    for key, val in initializers.items():
+                        # TODO: CT
+                        # In the future, support members that have ctors with
+                        # more than one parameter.
+                        if len(val) > 1:
+                            continue
+                        if len(val) == 1 and var.name == key.name:
+                            body[body.index(var)].initial_value = val[0].name
+
             if not self._handling_typedef:
                 token = self._get_next_token()
                 if token.token_type != tokenize.NAME:
@@ -1533,7 +1626,18 @@
     def handle_using(self):
         tokens = self._get_tokens_up_to(';')
         assert tokens
-        return Using(tokens[0].start, tokens[0].end, tokens)
+        new_type = self.converter.to_type(tokens)
+        if 'namespace' in new_type[0].modifiers:
+            return Using(tokens[0].start, tokens[0].end, tokens)
+        else:
+            # aside from namespaces, "using" can be used just like a typedef
+            # e.g., the following lines are equivalent
+            # using Foo = Bar;
+            # typedef Bar Foo;
+            # There is already code written to handle the typedef case so
+            # we return a Typdef object
+            return Typedef(tokens[0].start, tokens[0].end, new_type[0].name,
+                           new_type, self.namespace_stack)
 
     def handle_explicit(self):
         assert self.in_class
@@ -1547,7 +1651,8 @@
         pass
 
 
-def builder_from_source(source, filename, quiet=False):
+def builder_from_source(source, filename, system_includes,
+                        nonsystem_includes, quiet=False):
     """Utility method that returns an ASTBuilder from source code.
 
     Args:
@@ -1556,10 +1661,11 @@
 
     Returns:
       ASTBuilder
-
     """
     return ASTBuilder(tokenize.get_tokens(source),
                       filename,
+                      system_includes,
+                      nonsystem_includes,
                       quiet=quiet)
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cppclean-0.12/cpp/find_warnings.py 
new/cppclean-0.13/cpp/find_warnings.py
--- old/cppclean-0.12/cpp/find_warnings.py      2016-08-07 21:04:26.000000000 
+0200
+++ new/cppclean-0.13/cpp/find_warnings.py      2019-07-30 14:18:50.000000000 
+0200
@@ -20,7 +20,6 @@
 warnings will always be displayed. There is no way to suppress any.
 There also needs to be a way to use annotations in the source code to
 suppress warnings.
-
 """
 
 from __future__ import absolute_import
@@ -51,7 +50,7 @@
 HEADER_EXTENSIONS = frozenset(['.h', '.hh', '.hpp', '.h++', '.hxx', '.cuh'])
 CPP_EXTENSIONS = frozenset(['.cc', '.cpp', '.c++', '.cxx', '.cu'])
 
-# These enumerations are used to determine how an symbol/#include file is used.
+# These enumerations are used to determine how a symbol/#include file is used.
 UNUSED = 0
 USES_REFERENCE = 1
 USES_DECLARATION = 2
@@ -61,7 +60,7 @@
 
 class Module(object):
 
-    """Data container represting a single source file."""
+    """Data container representing a single source file."""
 
     def __init__(self, filename, ast_list):
         self.filename = filename
@@ -89,11 +88,15 @@
     # Cache filename: ast_list
     _module_cache = {}
 
-    def __init__(self, filename, source, ast_list, include_paths, quiet=False):
+    def __init__(self, filename, source, ast_list, include_paths,
+                 system_include_paths, nonsystem_include_paths,
+                 quiet=False):
         self.filename = filename
         self.source = source
         self.ast_list = ast_list
         self.include_paths = include_paths[:]
+        self.system_include_paths = system_include_paths
+        self.nonsystem_include_paths = nonsystem_include_paths
         self.quiet = quiet
         self.symbol_table = symbols.SymbolTable()
 
@@ -147,6 +150,8 @@
             ast_list = None
             try:
                 builder = ast.builder_from_source(source, filename,
+                                                  self.system_include_paths,
+                                                  self.nonsystem_include_paths,
                                                   quiet=self.quiet)
                 ast_list = [_f for _f in builder.generate() if _f]
             except tokenize.TokenError:
@@ -243,8 +248,16 @@
                 decl_uses[name] |= USES_REFERENCE
             except symbols.Error:
                 module = Module(name, None)
-                self.symbol_table.add_symbol(node.name, node.namespace, node,
-                                             module)
+                symbol_table.add_symbol(node.name, node.namespace, node,
+                                        module)
+
+        def _do_lookup(name, namespace):
+            try:
+                file_use_node = symbol_table.lookup_symbol(name, namespace)
+            except symbols.Error:
+                return
+            name = file_use_node[1].filename
+            file_uses[name] = file_uses.get(name, 0) | USES_DECLARATION
 
         def _add_declaration(name, namespace):
             if not name:
@@ -269,38 +282,55 @@
                 decl_uses[name] |= USES_REFERENCE
             elif name in file_uses:
                 # enum and typedef can't be forward declared
-                if (
-                    isinstance(file_use_node[0], ast.Enum) or
-                    isinstance(file_use_node[0], ast.Typedef)
-                ):
+                if isinstance(file_use_node[0], (ast.Enum, ast.Typedef)):
                     file_uses[name] |= USES_DECLARATION
                 else:
                     file_uses[name] |= USES_REFERENCE
 
-        def _add_use(name, namespace):
-            if isinstance(name, list):
+        def _add_use(node, namespace, name=''):
+            if isinstance(node, basestring):
+                name = node
+            elif isinstance(node, list):
                 # name contains a list of tokens.
                 name = '::'.join([n.name for n in name])
-            elif not isinstance(name, basestring):
+
+            # node is a Type so look for its symbol immediately.
+            if name:
+                _do_lookup(name, namespace)
+                return
+
+            # Try to search for the value of the variable declaration for any
+            # symbols, such as `#define` values or other variable names which
+            # may be included in other files.
+            obj = getattr(node, 'initial_value', None)
+            if obj:
+                _do_lookup(obj, namespace)
+
+            # If node is a VariableDeclaration, check if the variable type is
+            # a symbol used in other includes.
+            obj = getattr(node, 'type', None)
+            if obj and isinstance(obj.name, basestring):
+                _do_lookup(obj.name, namespace)
+
+            if not isinstance(node, basestring):
                 # Happens when variables are defined with inlined types, e.g.:
                 #   enum {...} variable;
                 return
-            try:
-                file_use_node = symbol_table.lookup_symbol(name, namespace)
-            except symbols.Error:
-                return
-
-            name = file_use_node[1].filename
-            file_uses[name] = file_uses.get(name, 0) | USES_DECLARATION
 
         def _add_variable(node, namespace, reference=False):
-            if node.reference or node.pointer or reference:
-                _add_reference(node.name, namespace)
+            obj = node.type if isinstance(
+                node, ast.VariableDeclaration) else node
+
+            if obj.reference or obj.pointer or reference:
+                _add_reference(obj.name, namespace)
             else:
-                _add_use(node.name, namespace)
+                # Add a use for the variable declaration type as well as the
+                # variable value.
+                _add_use(obj.name, namespace)
+                _add_use(node, namespace)
             # This needs to recurse when the node is a templated type.
-            _add_template_use(node.name,
-                              node.templated_types,
+            _add_template_use(obj.name,
+                              obj.templated_types,
                               namespace,
                               reference)
 
@@ -318,7 +348,7 @@
                 node = p.type
                 if node.name not in templated_types:
                     if function.body and p.name:
-                        # Assume that if the the function has a body and a name
+                        # Assume that if the function has a body and a name
                         # the parameter type is really used.
                         # NOTE(nnorwitz): this is over-aggressive. It would be
                         # better to iterate through the body and determine
@@ -367,6 +397,9 @@
                     # These are things like auto_ptr which do
                     # not require the class definition, only decl.
                     _add_reference(cls.name, namespace)
+                elif name.startswith('Q') and name.endswith('Pointer'):
+                    # Special case templated classes from the Qt framework.
+                    _add_reference(cls.name, namespace)
                 else:
                     _add_use(cls.name, namespace)
                 _add_template_use(cls.name, cls.templated_types,
@@ -384,7 +417,7 @@
             for node in ast_seq.pop():
                 if isinstance(node, ast.VariableDeclaration):
                     namespace = namespace_stack + node.namespace
-                    _add_variable(node.type, namespace)
+                    _add_variable(node, namespace)
                 elif isinstance(node, ast.Function):
                     namespace = namespace_stack + node.namespace
                     _process_function(node, namespace)
@@ -590,9 +623,12 @@
     return None
 
 
-def run(filename, source, entire_ast, include_paths, quiet):
+def run(filename, source, entire_ast, include_paths,
+        system_include_paths, nonsystem_include_paths, quiet):
     hunter = WarningHunter(filename, source, entire_ast,
                            include_paths=include_paths,
+                           system_include_paths=system_include_paths,
+                           nonsystem_include_paths=nonsystem_include_paths,
                            quiet=quiet)
     hunter.find_warnings()
     hunter.show_warnings()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cppclean-0.12/cpp/nonvirtual_dtors.py 
new/cppclean-0.13/cpp/nonvirtual_dtors.py
--- old/cppclean-0.12/cpp/nonvirtual_dtors.py   2016-08-07 21:04:26.000000000 
+0200
+++ new/cppclean-0.13/cpp/nonvirtual_dtors.py   2019-07-30 14:18:50.000000000 
+0200
@@ -26,11 +26,11 @@
 
 def _find_warnings(filename, source, ast_list):
     count = 0
-    for node in ast_list:
-        if isinstance(node, ast.Class) and node.body:
-            class_node = node
+    for ast_node in ast_list:
+        if isinstance(ast_node, ast.Class) and ast_node.body:
+            class_node = ast_node
             has_virtuals = False
-            for node in node.body:
+            for node in ast_node.body:
                 if isinstance(node, ast.Class) and node.body:
                     _find_warnings(filename, source, [node])
                 elif (isinstance(node, ast.Function) and
@@ -54,5 +54,6 @@
     return count
 
 
-def run(filename, source, entire_ast, include_paths, quiet):
+def run(filename, source, entire_ast, include_paths,
+        system_include_paths, nonsystem_include_paths, quiet):
     return _find_warnings(filename, source, entire_ast)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cppclean-0.12/cpp/static_data.py 
new/cppclean-0.13/cpp/static_data.py
--- old/cppclean-0.12/cpp/static_data.py        2016-08-07 21:04:26.000000000 
+0200
+++ new/cppclean-0.13/cpp/static_data.py        2019-07-30 14:18:50.000000000 
+0200
@@ -60,7 +60,9 @@
                 'constexpr' not in node.type.modifiers
             )
 
-            if is_not_const and (static_is_optional or is_static):
+            is_not_none_type = node.name is not None
+
+            if is_not_const and (static_is_optional or is_static) and 
is_not_none_type:
                 print_warning(node)
                 count += 1
         elif isinstance(node, ast.Function) and node.body:
@@ -110,7 +112,8 @@
     return count
 
 
-def run(filename, source, entire_ast, include_paths, quiet):
+def run(filename, source, entire_ast, include_paths,
+        system_include_paths, nonsystem_include_paths, quiet):
     lines = metrics.Metrics(source)
 
     return (
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cppclean-0.12/cpp/symbols.py 
new/cppclean-0.13/cpp/symbols.py
--- old/cppclean-0.12/cpp/symbols.py    2016-08-07 21:04:26.000000000 +0200
+++ new/cppclean-0.13/cpp/symbols.py    2019-07-30 14:18:50.000000000 +0200
@@ -52,7 +52,6 @@
         Args:
           symbol: Symbol
           namespace: pointer into self.namespaces
-
         """
         for namespace_part in symbol.parts:
             namespace = namespace.get(namespace_part)
@@ -67,7 +66,6 @@
 
         Args:
           symbol: Symbol
-
         """
         assert symbol.parts
         namespace = self.namespaces
@@ -91,7 +89,6 @@
 
         Args:
           symbol: Symbol
-
         """
         namespace = self.namespaces
         # Create a stack of namespaces.
@@ -123,7 +120,6 @@
 
         Raises:
           Error if the symbol cannot be found.
-
         """
         # TODO(nnorwitz): a convenient API for this depends on the
         # representation of the name. e.g., does symbol_name contain
@@ -148,7 +144,6 @@
         """Helper function for adding symbols.
 
         See add_symbol().
-
         """
         result = symbol_name in namespace
         namespace[symbol_name] = node, module
@@ -165,7 +160,6 @@
 
         Returns:
           bool(if symbol was *not* already present)
-
         """
         # TODO(nnorwitz): verify symbol_name doesn't contain :: ?
         if namespace_stack:
@@ -185,7 +179,6 @@
 
         Returns:
           ['names', 'that', 'are', 'namespaces', 'possibly', 'empty', 'list']
-
         """
         namespaces = self.namespaces
         result = []
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cppclean-0.12/cpp/tokenize.py 
new/cppclean-0.13/cpp/tokenize.py
--- old/cppclean-0.12/cpp/tokenize.py   2016-08-07 21:04:26.000000000 +0200
+++ new/cppclean-0.13/cpp/tokenize.py   2019-07-30 14:18:50.000000000 +0200
@@ -25,14 +25,15 @@
 
 # Add $ as a valid identifier char since so much code uses it.
 _letters = 'abcdefghijklmnopqrstuvwxyz'
-VALID_IDENTIFIER_CHARS = frozenset(_letters +
-                                   _letters.upper() +
-                                   '_0123456789$')
+_valid_identifier_first_char = _letters + _letters.upper() + '_$'
+_valid_identifier_char = _valid_identifier_first_char + '0123456789'
+VALID_IDENTIFIER_FIRST_CHARS = frozenset(_valid_identifier_first_char)
+VALID_IDENTIFIER_CHARS = frozenset(_valid_identifier_char)
 HEX_DIGITS = frozenset('0123456789abcdefABCDEF')
 INT_OR_FLOAT_DIGITS = frozenset('01234567890eE-+')
 
 
-# C++0x string preffixes.
+# C++0x string prefixes.
 _STR_PREFIXES = frozenset(('R', 'u8', 'u8R', 'u', 'uR', 'U', 'UR', 'L', 'LR'))
 
 
@@ -58,7 +59,6 @@
 
     start contains the index of the first char of the token in the source
     end contains the index of the last char of the token in the source
-
     """
 
     def __init__(self, token_type, name, start, end):
@@ -109,12 +109,12 @@
 
     Yields:
       Token that represents the next token in the source.
-
     """
     if not source.endswith('\n'):
         source += '\n'
 
     # Cache various valid character sets for speed.
+    valid_identifier_first_chars = VALID_IDENTIFIER_FIRST_CHARS
     valid_identifier_chars = VALID_IDENTIFIER_CHARS
     hex_digits = HEX_DIGITS
     int_or_float_digits = INT_OR_FLOAT_DIGITS
@@ -135,7 +135,8 @@
         token_type = UNKNOWN
         start = i
         c = source[i]
-        if c.isalpha() or c == '_':              # Find a string token.
+        # Find a string token.
+        if c in valid_identifier_first_chars or c == '_':
             token_type = NAME
             while source[i] in valid_identifier_chars:
                 i += 1
@@ -289,7 +290,6 @@
     """Return index of sub_string in string.
 
     Raise TokenError if sub_string is not found.
-
     """
     result = string.find(sub_string, start_index)
     if result == -1:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cppclean-0.12/cppclean new/cppclean-0.13/cppclean
--- old/cppclean-0.12/cppclean  2016-08-07 21:04:26.000000000 +0200
+++ new/cppclean-0.13/cppclean  2019-07-30 14:18:50.000000000 +0200
@@ -88,6 +88,19 @@
                         help='add a header include path; '
                              'specify this multiple times for multiple '
                              'include paths')
+    parser.add_argument('--include-path-system', '-s', action='append',
+                        dest='include_system_paths', default=[],
+                        metavar='sys_path',
+                        help='same as --include-path but explicitly '
+                             'designates all header files found in these '
+                             'directories as "system" includes')
+    parser.add_argument('--include-path-non-system', '-n',
+                        action='append', dest='include_nonsystem_paths',
+                        metavar='nonsys_path',
+                        default=[],
+                        help='same as --include-path but explicitly '
+                             'designates all header files found in these '
+                             'directories as "non-system" includes')
     parser.add_argument('--verbose', action='store_true',
                         help='print verbose messages')
     parser.add_argument('--version', action='version',
@@ -101,6 +114,10 @@
                   if hasattr(filename, 'decode') else filename
                   for filename in args.files]
 
+    all_includes = list(set(
+        args.include_paths + args.include_system_paths +
+        args.include_nonsystem_paths))
+
     status = 0
     for filename in (
         sorted(find_files(args.files,
@@ -116,6 +133,8 @@
 
             builder = ast.builder_from_source(source,
                                               filename,
+                                              args.include_system_paths,
+                                              args.include_nonsystem_paths,
                                               quiet=args.quiet)
             entire_ast = list([_f for _f in builder.generate() if _f])
         except tokenize.TokenError as exception:
@@ -134,7 +153,9 @@
                        nonvirtual_dtors,
                        static_data]:
             if module.run(filename, source, entire_ast,
-                          include_paths=args.include_paths,
+                          include_paths=all_includes,
+                          system_include_paths=args.include_system_paths,
+                          nonsystem_include_paths=args.include_nonsystem_paths,
                           quiet=args.quiet):
                 status = 1
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cppclean-0.12/test/const_define.h 
new/cppclean-0.13/test/const_define.h
--- old/cppclean-0.12/test/const_define.h       1970-01-01 01:00:00.000000000 
+0100
+++ new/cppclean-0.13/test/const_define.h       2019-07-30 14:18:50.000000000 
+0200
@@ -0,0 +1,6 @@
+#ifndef CONST_DEFINE_H
+# define CONST_DEFINE_H
+
+# define CONST_DEFINE 1
+
+#endif //! CONST_DEFINE_H
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cppclean-0.12/test/ctor_init_list.h 
new/cppclean-0.13/test/ctor_init_list.h
--- old/cppclean-0.12/test/ctor_init_list.h     1970-01-01 01:00:00.000000000 
+0100
+++ new/cppclean-0.13/test/ctor_init_list.h     2019-07-30 14:18:50.000000000 
+0200
@@ -0,0 +1,14 @@
+class Foo {
+public:
+    int first,
+#if defined(TEST)
+    int second;
+#endif
+};
+
+Foo::Foo():
+    first(1)
+    #if defined(TEST)   // this 3 lines
+    ,second(2)          // generated
+    #endif              // IndexError: list index out of range
+{}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cppclean-0.12/test/init_lists.h 
new/cppclean-0.13/test/init_lists.h
--- old/cppclean-0.12/test/init_lists.h 1970-01-01 01:00:00.000000000 +0100
+++ new/cppclean-0.13/test/init_lists.h 2019-07-30 14:18:50.000000000 +0200
@@ -0,0 +1,22 @@
+#include "const_define.h"
+
+class A {
+  public:
+    A() :
+      abc(CONST_DEFINE),
+      efg(2),
+      hij(3)
+    {}
+  private:
+    int abc;
+    int efg;
+    int hij;
+};
+
+struct B {
+  int arg1;
+
+  B() :
+    arg1(CONST_DEFINE)
+  {}
+};
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cppclean-0.12/test/invalidchar.h 
new/cppclean-0.13/test/invalidchar.h
--- old/cppclean-0.12/test/invalidchar.h        1970-01-01 01:00:00.000000000 
+0100
+++ new/cppclean-0.13/test/invalidchar.h        2019-07-30 14:18:50.000000000 
+0200
@@ -0,0 +1,4 @@
+// This compiles correctly, and should not hang the tokenizer in an infinite 
loop
+#if 0
+    testé
+#endif
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cppclean-0.12/test/qt.h new/cppclean-0.13/test/qt.h
--- old/cppclean-0.12/test/qt.h 1970-01-01 01:00:00.000000000 +0100
+++ new/cppclean-0.13/test/qt.h 2019-07-30 14:18:50.000000000 +0200
@@ -0,0 +1,10 @@
+class QSomeClass;
+
+class QSomeOtherClass {
+    QPointer<QSomeClass> ptr1;
+    QSharedDataPointer<QSomeClass> ptr2;
+    QSharedPointer<QSomeClass> ptr3;
+    QWeakPointer<QSomeClass> ptr4;
+    QScopedPointer<QSomeClass> ptr5;
+    QScopedArrayPointer<QSomeClass> ptr6;
+};
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cppclean-0.12/test/std_function.h 
new/cppclean-0.13/test/std_function.h
--- old/cppclean-0.12/test/std_function.h       1970-01-01 01:00:00.000000000 
+0100
+++ new/cppclean-0.13/test/std_function.h       2019-07-30 14:18:50.000000000 
+0200
@@ -0,0 +1,5 @@
+template <class T>
+std::function<void(T)>
+foo() {
+    return [&](T a) {return a.method();};
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cppclean-0.12/test/syntax.cc 
new/cppclean-0.13/test/syntax.cc
--- old/cppclean-0.12/test/syntax.cc    1970-01-01 01:00:00.000000000 +0100
+++ new/cppclean-0.13/test/syntax.cc    2019-07-30 14:18:50.000000000 +0200
@@ -0,0 +1,4 @@
+int main()
+{
+}
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cppclean-0.12/test/unicode.h 
new/cppclean-0.13/test/unicode.h
--- old/cppclean-0.12/test/unicode.h    2016-08-07 21:04:26.000000000 +0200
+++ new/cppclean-0.13/test/unicode.h    1970-01-01 01:00:00.000000000 +0100
@@ -1,95 +0,0 @@
-// **********************************************************************
-//
-// Copyright (c) 2003-2010 ZeroC, Inc. All rights reserved.
-//
-// This copy of Ice is licensed to you under the terms described in the
-// ICE_LICENSE file included in this distribution.
-//
-// **********************************************************************
-
-#ifndef ICE_UTIL_UNICODE_H
-#define ICE_UTIL_UNICODE_H
-
-#include <IceUtil/Config.h>
-#include <IceUtil/Exception.h>
-
-namespace IceUtil
-{
-
-enum ConversionFlags
-{
-    strictConversion = 0,
-    lenientConversion
-};
-
-ICE_UTIL_API std::string wstringToString(const std::wstring&, ConversionFlags 
= lenientConversion);
-ICE_UTIL_API std::wstring stringToWstring(const std::string&, ConversionFlags 
= lenientConversion);
-
-typedef unsigned char Byte;
-
-ICE_UTIL_API bool
-isLegalUTF8Sequence(const Byte* source, const Byte* end);
-
-enum ConversionError
-{
-    partialCharacter,
-    badEncoding
-};
-
-//
-// UTFConversionException is raised by wstringToString() or stringToWstring()
-// to report a conversion error 
-//
-class ICE_UTIL_API UTFConversionException : public Exception
-{
-public:
-    
-    UTFConversionException(const char*, int, ConversionError);
-    virtual std::string ice_name() const;
-    virtual void ice_print(std::ostream&) const;
-    virtual Exception* ice_clone() const;
-    virtual void ice_throw() const;
-
-    ConversionError conversionError() const;
-private:
-
-    const ConversionError _conversionError;
-    static const char* _name;    
-};
-
-}
-
-namespace IceUtilInternal
-{
-
-//
-// Converts UTF-8 byte-sequences to and from UTF-16 or UTF-32 (with native
-// endianness) depending on sizeof(wchar_t).
-//
-// These are thin wrappers over the UTF8/16/32 converters provided by 
-// unicode.org
-//
-
-enum ConversionResult
-{
-        conversionOK,           /* conversion successful */
-        sourceExhausted,        /* partial character in source, but hit end */
-        targetExhausted,        /* insuff. room in target for conversion */
-        sourceIllegal           /* source sequence is illegal/malformed */
-};
-
-ICE_UTIL_API ConversionResult 
-convertUTFWstringToUTF8(const wchar_t*& sourceStart, const wchar_t* sourceEnd, 
-                        IceUtil::Byte*& targetStart, IceUtil::Byte* targetEnd, 
IceUtil::ConversionFlags flags);
-
-ICE_UTIL_API ConversionResult
-convertUTF8ToUTFWstring(const IceUtil::Byte*& sourceStart, const 
IceUtil::Byte* sourceEnd, 
-                        wchar_t*& targetStart, wchar_t* targetEnd, 
IceUtil::ConversionFlags flags);
-
-ICE_UTIL_API ConversionResult 
-convertUTF8ToUTFWstring(const IceUtil::Byte*& sourceStart, const 
IceUtil::Byte* sourceEnd, 
-                        std::wstring& target, IceUtil::ConversionFlags flags);
-
-}
-
-#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cppclean-0.12/test/using_as_typedef.h 
new/cppclean-0.13/test/using_as_typedef.h
--- old/cppclean-0.12/test/using_as_typedef.h   1970-01-01 01:00:00.000000000 
+0100
+++ new/cppclean-0.13/test/using_as_typedef.h   2019-07-30 14:18:50.000000000 
+0200
@@ -0,0 +1,3 @@
+class Foo;
+using FooPtr = std::shared_ptr<Foo>;
+void bar(FooPtr foo_ptr);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cppclean-0.12/test.bash new/cppclean-0.13/test.bash
--- old/cppclean-0.12/test.bash 2016-08-07 21:04:26.000000000 +0200
+++ new/cppclean-0.13/test.bash 2019-07-30 14:18:50.000000000 +0200
@@ -8,12 +8,13 @@
 done
 
 $PYTHON ./cppclean test/c++11.h
+$PYTHON ./cppclean test/init_lists.h
 
 rm -f '.tmp'
 $PYTHON ./cppclean \
     --include-path='test/external' \
     --exclude='ignore.cc' \
-    'test' | tr '\\' '/' > '.tmp' || true
+    'test' | tr '\\' '/' 2>&1 > '.tmp' || true
 diff --unified 'test/expected.txt' '.tmp'
 rm -f '.tmp'
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cppclean-0.12/test_ast.py 
new/cppclean-0.13/test_ast.py
--- old/cppclean-0.12/test_ast.py       2016-08-07 21:04:26.000000000 +0200
+++ new/cppclean-0.13/test_ast.py       2019-07-30 14:18:50.000000000 +0200
@@ -20,6 +20,7 @@
 from __future__ import absolute_import
 
 import unittest
+import os
 
 from cpp import ast
 from cpp import tokenize
@@ -34,7 +35,6 @@
     Args:
       cls: Python class to add __eq__ method to
       attrs: string - space separated of attribute names to compare
-
     """
     attrs = attrs.split()
 
@@ -71,6 +71,8 @@
     _install_generic_equal(ast.Typedef, 'name alias namespace')
     _install_generic_equal(ast.VariableDeclaration,
                            'name type initial_value namespace')
+
+
 _install_equal_methods()
 
 
@@ -607,7 +609,6 @@
     an integration test.
 
     It doesn't test any individual method. It tests whole code blocks.
-
     """
 
     def test_variable_array(self):
@@ -969,6 +970,70 @@
                                templated_types=types1,),
                          nodes[0])
 
+    def test_class_ctor_initializer_list(self):
+        code = """
+        class Foo {
+          public:
+            Foo() :
+              arg1(1),
+              arg2(2),
+              arg3(3)
+            {}
+          private:
+            int arg1;
+            int arg2;
+            int arg3;
+        };
+        """
+        nodes = list(MakeBuilder(code).generate())
+        ctor = nodes[0].body[0]
+        arg1 = nodes[0].body[1]
+        arg2 = nodes[0].body[2]
+        arg3 = nodes[0].body[3]
+
+        exp_ctor = Function(
+            'Foo', [], [], modifiers=ast.FUNCTION_CTOR, body=[])
+        exp_var = [VariableDeclaration('arg1', Type('int'), initial_value='1'),
+                   VariableDeclaration('arg2', Type('int'), initial_value='2'),
+                   VariableDeclaration('arg3', Type('int'), initial_value='3')]
+
+        self.assertEqual(exp_ctor.return_type, ctor.return_type)
+        self.assertEqual(exp_ctor, ctor)
+        self.assertEqual(exp_var, [arg1, arg2, arg3])
+        self.assertEqual(Class('Foo', body=[exp_ctor] + exp_var), nodes[0])
+
+    def test_class_ctor_initializer_list_cpp11(self):
+        code = """
+        class Foo {
+          public:
+            Foo() :
+              arg1{1},
+              arg2{2},
+              arg3{3}
+            {}
+          private:
+            int arg1;
+            int arg2;
+            int arg3;
+        };
+        """
+        nodes = list(MakeBuilder(code).generate())
+        ctor = nodes[0].body[0]
+        arg1 = nodes[0].body[1]
+        arg2 = nodes[0].body[2]
+        arg3 = nodes[0].body[3]
+
+        exp_ctor = Function(
+            'Foo', [], [], modifiers=ast.FUNCTION_CTOR, body=[])
+        exp_var = [VariableDeclaration('arg1', Type('int'), initial_value='1'),
+                   VariableDeclaration('arg2', Type('int'), initial_value='2'),
+                   VariableDeclaration('arg3', Type('int'), initial_value='3')]
+
+        self.assertEqual(exp_ctor.return_type, ctor.return_type)
+        self.assertEqual(exp_ctor, ctor)
+        self.assertEqual(exp_var, [arg1, arg2, arg3])
+        self.assertEqual(Class('Foo', body=[exp_ctor] + exp_var), nodes[0])
+
     def test_function_parses_operator_bracket(self):
         code = """
         class A {
@@ -1058,6 +1123,35 @@
         self.assertEqual(1, len(nodes), repr(nodes))
         self.assertEqual(Include('vector', system=True), nodes[0])
 
+    def test_include_path_overrides(self):
+        paths = [os.path.dirname(os.path.realpath(__file__))]
+        fname = 'test/include.h'
+
+        def _tokens():
+            tokens_quotes = get_tokens('#include "test/include.h"')
+            tokens_brackets = get_tokens('#include <test/include.h>')
+            return [tokens_quotes, tokens_brackets]
+
+        def _do_test(tokens, system_includes, nonsystem_includes, is_system):
+            nodes = list(ast.ASTBuilder(
+                tokens, '<test>', system_includes=system_includes,
+                nonsystem_includes=nonsystem_includes).generate())
+            self.assertEqual(1, len(nodes), repr(nodes))
+            self.assertEqual(Include(fname, system=is_system), nodes[0])
+
+        # forcing system
+        for tokens in _tokens():
+            _do_test(tokens, paths, [], True)
+
+        # forcing nonsystem
+        for tokens in _tokens():
+            _do_test(tokens, [], paths, False)
+
+        # let the system infer
+        tokens_quotes, tokens_brackets = _tokens()
+        _do_test(tokens_quotes, [], [], False)
+        _do_test(tokens_brackets, [], [], True)
+
     def test_operator_new_bracket(self):
         nodes = list(
             MakeBuilder('void* operator new[](std::size_t size);').generate())
@@ -1140,5 +1234,6 @@
             Function('fn', list(get_tokens('void')), []),
             nodes[0])
 
+
 if __name__ == '__main__':
     unittest.main()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cppclean-0.12/test_tokenize.py 
new/cppclean-0.13/test_tokenize.py
--- old/cppclean-0.12/test_tokenize.py  2016-08-07 21:04:26.000000000 +0200
+++ new/cppclean-0.13/test_tokenize.py  2019-07-30 14:18:50.000000000 +0200
@@ -53,6 +53,7 @@
             self.start == other.start and
             self.end == other.end)
 
+
 tokenize.Token.__eq__ = __eq__
 
 


Reply via email to