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
+
+- 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/998e80d02eb27fa7a59ac23db41ae3854f3...
-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
+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
-#include
-
-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 ')
+ 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__