Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
BaiXuePrincess
Paddle
提交
9115ab1c
P
Paddle
项目概览
BaiXuePrincess
/
Paddle
与 Fork 源项目一致
Fork自
PaddlePaddle / Paddle
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
Paddle
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
9115ab1c
编写于
11月 14, 2016
作者:
Y
Yu Yang
提交者:
GitHub
11月 14, 2016
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #450 from reyoung/feature/pre-commit-hooks-scripts
Feature/pre commit hooks scripts
上级
2b841ec8
07af31fd
变更
36
显示空白变更内容
内联
并排
Showing
36 changed file
with
4957 addition
and
4872 deletion
+4957
-4872
.clang-format
.clang-format
+2
-3
.pre-commit-config.yaml
.pre-commit-config.yaml
+24
-0
demo/introduction/README.md
demo/introduction/README.md
+0
-1
demo/mnist/data/get_mnist_data.sh
demo/mnist/data/get_mnist_data.sh
+0
-1
demo/recommendation/data/config.json
demo/recommendation/data/config.json
+0
-1
demo/semantic_role_labeling/test.sh
demo/semantic_role_labeling/test.sh
+0
-1
demo/semantic_role_labeling/train.sh
demo/semantic_role_labeling/train.sh
+0
-1
doc/demo/semantic_role_labeling/semantic_role_labeling.md
doc/demo/semantic_role_labeling/semantic_role_labeling.md
+183
-183
doc/introduction/index.md
doc/introduction/index.md
+0
-1
doc_cn/algorithm/rnn/hierarchical-layer.md
doc_cn/algorithm/rnn/hierarchical-layer.md
+66
-66
doc_cn/algorithm/rnn/hierarchical-rnn.md
doc_cn/algorithm/rnn/hierarchical-rnn.md
+403
-403
doc_cn/algorithm/rnn/rnn-tutorial.md
doc_cn/algorithm/rnn/rnn-tutorial.md
+1
-1
doc_cn/build_and_install/install/paddle_version.txt
doc_cn/build_and_install/install/paddle_version.txt
+1
-1
doc_cn/faq/reduce_min_pool_size.py
doc_cn/faq/reduce_min_pool_size.py
+1
-1
paddle/.common_test_util.sh
paddle/.common_test_util.sh
+1
-1
paddle/CMakeLists.txt
paddle/CMakeLists.txt
+0
-2
paddle/api/PaddleAPIPrivate.h
paddle/api/PaddleAPIPrivate.h
+0
-1
paddle/api/test/CMakeLists.txt
paddle/api/test/CMakeLists.txt
+1
-1
paddle/api/test/testMatrix.py
paddle/api/test/testMatrix.py
+2
-2
paddle/cuda/include/hl_base.h
paddle/cuda/include/hl_base.h
+0
-1
paddle/cuda/include/stub/hl_cuda_cudnn_stub.h
paddle/cuda/include/stub/hl_cuda_cudnn_stub.h
+0
-1
paddle/cuda/src/avx_mathfun.h
paddle/cuda/src/avx_mathfun.h
+0
-1
paddle/gserver/layers/FullyConnectedLayer.h
paddle/gserver/layers/FullyConnectedLayer.h
+0
-1
paddle/math/MathFunctions.h
paddle/math/MathFunctions.h
+0
-1
paddle/parameter/CMakeLists.txt
paddle/parameter/CMakeLists.txt
+1
-1
paddle/parameter/tests/CMakeLists.txt
paddle/parameter/tests/CMakeLists.txt
+1
-1
paddle/scripts/CMakeLists.txt
paddle/scripts/CMakeLists.txt
+1
-1
paddle/scripts/cpplint.py
paddle/scripts/cpplint.py
+4254
-4171
paddle/scripts/deb/build_scripts/build.sh
paddle/scripts/deb/build_scripts/build.sh
+0
-2
paddle/scripts/docker/generate.sh
paddle/scripts/docker/generate.sh
+0
-1
paddle/scripts/travis/common.sh
paddle/scripts/travis/common.sh
+0
-1
paddle/trainer/tests/test.txt
paddle/trainer/tests/test.txt
+0
-1
paddle/trainer/tests/test_gen_dict.txt
paddle/trainer/tests/test_gen_dict.txt
+1
-1
paddle/trainer/tests/train.txt
paddle/trainer/tests/train.txt
+0
-1
paddle/utils/tests/test_CommandLineParser.cpp
paddle/utils/tests/test_CommandLineParser.cpp
+0
-1
python/paddle/trainer/config_parser.py
python/paddle/trainer/config_parser.py
+14
-14
未找到文件。
.clang-format
浏览文件 @
9115ab1c
...
@@ -13,8 +13,6 @@
...
@@ -13,8 +13,6 @@
# The document of clang-format is
# The document of clang-format is
# http://clang.llvm.org/docs/ClangFormat.html
# http://clang.llvm.org/docs/ClangFormat.html
# http://clang.llvm.org/docs/ClangFormatStyleOptions.html
# http://clang.llvm.org/docs/ClangFormatStyleOptions.html
#
# TODO(yuyang18): Add python and other language code style
---
---
Language: Cpp
Language: Cpp
BasedOnStyle: Google
BasedOnStyle: Google
...
@@ -22,8 +20,9 @@ IndentWidth: 2
...
@@ -22,8 +20,9 @@ IndentWidth: 2
TabWidth: 2
TabWidth: 2
ContinuationIndentWidth: 4
ContinuationIndentWidth: 4
AccessModifierOffset: -2 # The private/protected/public has no indent in class
AccessModifierOffset: -2 # The private/protected/public has no indent in class
PointerAlignment: Left # int* p/int& p, not int *p/int &p
Standard: Cpp11
Standard: Cpp11
AllowAllParametersOfDeclarationOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
BinPackParameters: false
BinPackArguments: false
...
...
.pre-commit-config.yaml
0 → 100644
浏览文件 @
9115ab1c
-
repo
:
https://github.com/Lucas-C/pre-commit-hooks.git
sha
:
c25201a00e6b0514370501050cf2a8538ac12270
hooks
:
-
id
:
remove-crlf
-
repo
:
https://github.com/reyoung/mirrors-yapf.git
sha
:
v0.13.2
hooks
:
-
id
:
yapf
-
repo
:
https://github.com/pre-commit/pre-commit-hooks
sha
:
4ef03c4223ad322c7adaa6c6c0efb26b57df3b71
hooks
:
-
id
:
check-added-large-files
-
id
:
check-merge-conflict
-
id
:
check-symlinks
-
id
:
detect-private-key
-
id
:
end-of-file-fixer
# TODO(yuyang): trailing whitespace has some bugs on markdown
# files now, please not add it to pre-commit hook now
# - id: trailing-whitespace
#
# TODO(yuyang): debug-statements not fit for Paddle, because
# not all of our python code is runnable. Some are used for
# documenation
# - id: debug-statements
demo/introduction/README.md
浏览文件 @
9115ab1c
This folder contains scripts used in PaddlePaddle introduction.
This folder contains scripts used in PaddlePaddle introduction.
-
use
`bash train.sh`
to train a simple linear regression model
-
use
`bash train.sh`
to train a simple linear regression model
-
use
`python evaluate_model.py`
to read model parameters. You can see that
`w`
and
`b`
are very close to [2, 0.3].
-
use
`python evaluate_model.py`
to read model parameters. You can see that
`w`
and
`b`
are very close to [2, 0.3].
demo/mnist/data/get_mnist_data.sh
浏览文件 @
9115ab1c
...
@@ -19,4 +19,3 @@ done
...
@@ -19,4 +19,3 @@ done
cd
$DIR
cd
$DIR
rm
-f
*
.list
rm
-f
*
.list
python generate_list.py
python generate_list.py
demo/recommendation/data/config.json
浏览文件 @
9115ab1c
...
@@ -14,4 +14,3 @@
...
@@ -14,4 +14,3 @@
"fields"
:
[
"id"
,
"title"
,
"genres"
]
"fields"
:
[
"id"
,
"title"
,
"genres"
]
}
}
}
}
demo/semantic_role_labeling/test.sh
浏览文件 @
9115ab1c
...
@@ -37,4 +37,3 @@ paddle train \
...
@@ -37,4 +37,3 @@ paddle train \
--use_gpu
=
false
\
--use_gpu
=
false
\
--config_args
=
is_test
=
1
\
--config_args
=
is_test
=
1
\
2>&1 |
tee
'test.log'
2>&1 |
tee
'test.log'
demo/semantic_role_labeling/train.sh
浏览文件 @
9115ab1c
...
@@ -24,4 +24,3 @@ paddle train \
...
@@ -24,4 +24,3 @@ paddle train \
--show_parameter_stats_period
=
10
\
--show_parameter_stats_period
=
10
\
--test_all_data_in_one_period
=
1
\
--test_all_data_in_one_period
=
1
\
2>&1 |
tee
'train.log'
2>&1 |
tee
'train.log'
doc/demo/semantic_role_labeling/semantic_role_labeling.md
浏览文件 @
9115ab1c
doc/introduction/index.md
浏览文件 @
9115ab1c
...
@@ -98,4 +98,3 @@ There, you have recovered the underlying pattern between `X` and `Y` only from o
...
@@ -98,4 +98,3 @@ There, you have recovered the underlying pattern between `X` and `Y` only from o
-
<a
href=
"../build/index.html"
>
Build and Installation
</a>
-
<a
href=
"../build/index.html"
>
Build and Installation
</a>
-
<a
href=
"../demo/quick_start/index_en.html"
>
Quick Start
</a>
-
<a
href=
"../demo/quick_start/index_en.html"
>
Quick Start
</a>
-
<a
href=
"../demo/index.html"
>
Example and Demo
</a>
-
<a
href=
"../demo/index.html"
>
Example and Demo
</a>
doc_cn/algorithm/rnn/hierarchical-layer.md
浏览文件 @
9115ab1c
doc_cn/algorithm/rnn/hierarchical-rnn.md
浏览文件 @
9115ab1c
doc_cn/algorithm/rnn/rnn-tutorial.md
浏览文件 @
9115ab1c
doc_cn/build_and_install/install/paddle_version.txt
浏览文件 @
9115ab1c
doc_cn/faq/reduce_min_pool_size.py
浏览文件 @
9115ab1c
paddle/.common_test_util.sh
浏览文件 @
9115ab1c
paddle/CMakeLists.txt
浏览文件 @
9115ab1c
...
@@ -17,5 +17,3 @@ endif()
...
@@ -17,5 +17,3 @@ endif()
if
(
WITH_SWIG_PY
)
if
(
WITH_SWIG_PY
)
add_subdirectory
(
api
)
add_subdirectory
(
api
)
endif
()
endif
()
paddle/api/PaddleAPIPrivate.h
浏览文件 @
9115ab1c
...
@@ -65,4 +65,3 @@ struct ArgumentsPrivate {
...
@@ -65,4 +65,3 @@ struct ArgumentsPrivate {
return
*
(
std
::
shared_ptr
<
T
>*
)(
rawPtr
);
return
*
(
std
::
shared_ptr
<
T
>*
)(
rawPtr
);
}
}
};
};
paddle/api/test/CMakeLists.txt
浏览文件 @
9115ab1c
paddle/api/test/testMatrix.py
浏览文件 @
9115ab1c
...
@@ -69,8 +69,8 @@ class TestMatrix(unittest.TestCase):
...
@@ -69,8 +69,8 @@ class TestMatrix(unittest.TestCase):
def
test_numpy
(
self
):
def
test_numpy
(
self
):
numpy_mat
=
np
.
matrix
([[
1
,
2
],
[
3
,
4
],
[
5
,
6
]],
dtype
=
"float32"
)
numpy_mat
=
np
.
matrix
([[
1
,
2
],
[
3
,
4
],
[
5
,
6
]],
dtype
=
"float32"
)
m
=
swig_paddle
.
Matrix
.
createCpuDenseFromNumpy
(
numpy_mat
)
m
=
swig_paddle
.
Matrix
.
createCpuDenseFromNumpy
(
numpy_mat
)
self
.
assertEqual
(
self
.
assertEqual
(
(
int
(
m
.
getHeight
()),
int
(
m
.
getWidth
())),
(
int
(
m
.
getHeight
()),
int
(
m
.
getWidth
())),
numpy_mat
.
shape
)
numpy_mat
.
shape
)
# the numpy matrix and paddle matrix shared the same memory.
# the numpy matrix and paddle matrix shared the same memory.
numpy_mat
[
0
,
1
]
=
342.23
numpy_mat
[
0
,
1
]
=
342.23
...
...
paddle/cuda/include/hl_base.h
浏览文件 @
9115ab1c
...
@@ -254,4 +254,3 @@ extern __thread cudaStream_t default_stream;
...
@@ -254,4 +254,3 @@ extern __thread cudaStream_t default_stream;
#endif
/* __NVCC__ */
#endif
/* __NVCC__ */
#endif
/* HL_BASE_H_ */
#endif
/* HL_BASE_H_ */
paddle/cuda/include/stub/hl_cuda_cudnn_stub.h
浏览文件 @
9115ab1c
...
@@ -199,4 +199,3 @@ inline void hl_batch_norm_backward(hl_tensor_descriptor inputDesc,
...
@@ -199,4 +199,3 @@ inline void hl_batch_norm_backward(hl_tensor_descriptor inputDesc,
real
*
savedInvVar
)
{}
real
*
savedInvVar
)
{}
#endif // HL_CUDA_CUDNN_STUB_H_
#endif // HL_CUDA_CUDNN_STUB_H_
paddle/cuda/src/avx_mathfun.h
浏览文件 @
9115ab1c
...
@@ -718,4 +718,3 @@ void sincos256_ps(v8sf x, v8sf *s, v8sf *c) {
...
@@ -718,4 +718,3 @@ void sincos256_ps(v8sf x, v8sf *s, v8sf *c) {
*
s
=
_mm256_xor_ps
(
xmm1
,
sign_bit_sin
);
*
s
=
_mm256_xor_ps
(
xmm1
,
sign_bit_sin
);
*
c
=
_mm256_xor_ps
(
xmm2
,
sign_bit_cos
);
*
c
=
_mm256_xor_ps
(
xmm2
,
sign_bit_cos
);
}
}
paddle/gserver/layers/FullyConnectedLayer.h
浏览文件 @
9115ab1c
...
@@ -48,4 +48,3 @@ public:
...
@@ -48,4 +48,3 @@ public:
};
};
}
// namespace paddle
}
// namespace paddle
paddle/math/MathFunctions.h
浏览文件 @
9115ab1c
...
@@ -80,4 +80,3 @@ void vTanh(const int n, const T* a, T* r);
...
@@ -80,4 +80,3 @@ void vTanh(const int n, const T* a, T* r);
}
// namespace paddle
}
// namespace paddle
#endif // MATHFUNCTIONS_H_
#endif // MATHFUNCTIONS_H_
paddle/parameter/CMakeLists.txt
浏览文件 @
9115ab1c
paddle/parameter/tests/CMakeLists.txt
浏览文件 @
9115ab1c
paddle/scripts/CMakeLists.txt
浏览文件 @
9115ab1c
paddle/scripts/cpplint.py
浏览文件 @
9115ab1c
...
@@ -27,7 +27,6 @@
...
@@ -27,7 +27,6 @@
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""Does google-lint on c++ files.
"""Does google-lint on c++ files.
The goal of this script is to identify places in the code that *may*
The goal of this script is to identify places in the code that *may*
...
@@ -55,7 +54,6 @@ import string
...
@@ -55,7 +54,6 @@ import string
import
sys
import
sys
import
unicodedata
import
unicodedata
_USAGE
=
"""
_USAGE
=
"""
Syntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...]
Syntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...]
[--counting=total|toplevel|detailed] [--root=subdir]
[--counting=total|toplevel|detailed] [--root=subdir]
...
@@ -242,13 +240,11 @@ _ERROR_CATEGORIES = [
...
@@ -242,13 +240,11 @@ _ERROR_CATEGORIES = [
'whitespace/semicolon'
,
'whitespace/semicolon'
,
'whitespace/tab'
,
'whitespace/tab'
,
'whitespace/todo'
,
'whitespace/todo'
,
]
]
# These error categories are no longer enforced by cpplint, but for backwards-
# These error categories are no longer enforced by cpplint, but for backwards-
# compatibility they may still appear in NOLINT comments.
# compatibility they may still appear in NOLINT comments.
_LEGACY_ERROR_CATEGORIES
=
[
_LEGACY_ERROR_CATEGORIES
=
[
'readability/streams'
,
]
'readability/streams'
,
]
# The default state of the category filter. This is overridden by the --filter=
# The default state of the category filter. This is overridden by the --filter=
# flag. By default all errors are on, so only add here categories that should be
# flag. By default all errors are on, so only add here categories that should be
...
@@ -394,8 +390,7 @@ _CPP_HEADERS = frozenset([
...
@@ -394,8 +390,7 @@ _CPP_HEADERS = frozenset([
'cuchar'
,
'cuchar'
,
'cwchar'
,
'cwchar'
,
'cwctype'
,
'cwctype'
,
])
])
# These headers are excluded from [build/include] and [build/include_order]
# These headers are excluded from [build/include] and [build/include_order]
# checks:
# checks:
...
@@ -405,23 +400,26 @@ _CPP_HEADERS = frozenset([
...
@@ -405,23 +400,26 @@ _CPP_HEADERS = frozenset([
_THIRD_PARTY_HEADERS_PATTERN
=
re
.
compile
(
_THIRD_PARTY_HEADERS_PATTERN
=
re
.
compile
(
r
'^(?:[^/]*[A-Z][^/]*\.h|lua\.h|lauxlib\.h|lualib\.h)$'
)
r
'^(?:[^/]*[A-Z][^/]*\.h|lua\.h|lauxlib\.h|lualib\.h)$'
)
# Assertion macros. These are defined in base/logging.h and
# Assertion macros. These are defined in base/logging.h and
# testing/base/gunit.h. Note that the _M versions need to come first
# testing/base/gunit.h. Note that the _M versions need to come first
# for substring matching to work.
# for substring matching to work.
_CHECK_MACROS
=
[
_CHECK_MACROS
=
[
'DCHECK'
,
'CHECK'
,
'DCHECK'
,
'EXPECT_TRUE_M'
,
'EXPECT_TRUE'
,
'CHECK'
,
'ASSERT_TRUE_M'
,
'ASSERT_TRUE'
,
'EXPECT_TRUE_M'
,
'EXPECT_FALSE_M'
,
'EXPECT_FALSE'
,
'EXPECT_TRUE'
,
'ASSERT_FALSE_M'
,
'ASSERT_FALSE'
,
'ASSERT_TRUE_M'
,
]
'ASSERT_TRUE'
,
'EXPECT_FALSE_M'
,
'EXPECT_FALSE'
,
'ASSERT_FALSE_M'
,
'ASSERT_FALSE'
,
]
# Replacement macros for CHECK/DCHECK/EXPECT_TRUE/EXPECT_FALSE
# Replacement macros for CHECK/DCHECK/EXPECT_TRUE/EXPECT_FALSE
_CHECK_REPLACEMENT
=
dict
([(
m
,
{})
for
m
in
_CHECK_MACROS
])
_CHECK_REPLACEMENT
=
dict
([(
m
,
{})
for
m
in
_CHECK_MACROS
])
for
op
,
replacement
in
[(
'=='
,
'EQ'
),
(
'!='
,
'NE'
),
for
op
,
replacement
in
[(
'=='
,
'EQ'
),
(
'!='
,
'NE'
),
(
'>='
,
'GE'
),
(
'>'
,
'GT'
),
(
'>='
,
'GE'
),
(
'>'
,
'GT'
),
(
'<='
,
'LE'
),
(
'<'
,
'LT'
)]:
(
'<='
,
'LE'
),
(
'<'
,
'LT'
)]:
_CHECK_REPLACEMENT
[
'DCHECK'
][
op
]
=
'DCHECK_%s'
%
replacement
_CHECK_REPLACEMENT
[
'DCHECK'
][
op
]
=
'DCHECK_%s'
%
replacement
_CHECK_REPLACEMENT
[
'CHECK'
][
op
]
=
'CHECK_%s'
%
replacement
_CHECK_REPLACEMENT
[
'CHECK'
][
op
]
=
'CHECK_%s'
%
replacement
...
@@ -430,9 +428,8 @@ for op, replacement in [('==', 'EQ'), ('!=', 'NE'),
...
@@ -430,9 +428,8 @@ for op, replacement in [('==', 'EQ'), ('!=', 'NE'),
_CHECK_REPLACEMENT
[
'EXPECT_TRUE_M'
][
op
]
=
'EXPECT_%s_M'
%
replacement
_CHECK_REPLACEMENT
[
'EXPECT_TRUE_M'
][
op
]
=
'EXPECT_%s_M'
%
replacement
_CHECK_REPLACEMENT
[
'ASSERT_TRUE_M'
][
op
]
=
'ASSERT_%s_M'
%
replacement
_CHECK_REPLACEMENT
[
'ASSERT_TRUE_M'
][
op
]
=
'ASSERT_%s_M'
%
replacement
for
op
,
inv_replacement
in
[(
'=='
,
'NE'
),
(
'!='
,
'EQ'
),
for
op
,
inv_replacement
in
[(
'=='
,
'NE'
),
(
'!='
,
'EQ'
),
(
'>='
,
'LT'
),
(
'>='
,
'LT'
),
(
'>'
,
'LE'
),
(
'>'
,
'LE'
),
(
'<='
,
'GT'
),
(
'<'
,
'GE'
)]:
(
'<='
,
'GT'
),
(
'<'
,
'GE'
)]:
_CHECK_REPLACEMENT
[
'EXPECT_FALSE'
][
op
]
=
'EXPECT_%s'
%
inv_replacement
_CHECK_REPLACEMENT
[
'EXPECT_FALSE'
][
op
]
=
'EXPECT_%s'
%
inv_replacement
_CHECK_REPLACEMENT
[
'ASSERT_FALSE'
][
op
]
=
'ASSERT_%s'
%
inv_replacement
_CHECK_REPLACEMENT
[
'ASSERT_FALSE'
][
op
]
=
'ASSERT_%s'
%
inv_replacement
_CHECK_REPLACEMENT
[
'EXPECT_FALSE_M'
][
op
]
=
'EXPECT_%s_M'
%
inv_replacement
_CHECK_REPLACEMENT
[
'EXPECT_FALSE_M'
][
op
]
=
'EXPECT_%s_M'
%
inv_replacement
...
@@ -455,16 +452,15 @@ _ALT_TOKEN_REPLACEMENT = {
...
@@ -455,16 +452,15 @@ _ALT_TOKEN_REPLACEMENT = {
'xor_eq'
:
'^='
,
'xor_eq'
:
'^='
,
'not'
:
'!'
,
'not'
:
'!'
,
'not_eq'
:
'!='
'not_eq'
:
'!='
}
}
# Compile regular expression that matches all the above keywords. The "[ =()]"
# Compile regular expression that matches all the above keywords. The "[ =()]"
# bit is meant to avoid matching these keywords outside of boolean expressions.
# bit is meant to avoid matching these keywords outside of boolean expressions.
#
#
# False positives include C-style multi-line comments and multi-line strings
# False positives include C-style multi-line comments and multi-line strings
# but those have always been troublesome for cpplint.
# but those have always been troublesome for cpplint.
_ALT_TOKEN_REPLACEMENT_PATTERN
=
re
.
compile
(
_ALT_TOKEN_REPLACEMENT_PATTERN
=
re
.
compile
(
r
'[ =()]('
+
(
'|'
.
join
(
r
'[ =()]('
+
(
'|'
.
join
(
_ALT_TOKEN_REPLACEMENT
.
keys
()))
+
r
')(?=[ (]|$)'
)
_ALT_TOKEN_REPLACEMENT
.
keys
()))
+
r
')(?=[ (]|$)'
)
# These constants define types of headers for use with
# These constants define types of headers for use with
# _IncludeState.CheckNextIncludeOrder().
# _IncludeState.CheckNextIncludeOrder().
...
@@ -485,7 +481,6 @@ _MATCH_ASM = re.compile(r'^\s*(?:asm|_asm|__asm|__asm__)'
...
@@ -485,7 +481,6 @@ _MATCH_ASM = re.compile(r'^\s*(?:asm|_asm|__asm|__asm__)'
r
'(?:\s+(volatile|__volatile__))?'
r
'(?:\s+(volatile|__volatile__))?'
r
'\s*[{(]'
)
r
'\s*[{(]'
)
_regexp_compile_cache
=
{}
_regexp_compile_cache
=
{}
# {str, set(int)}: a map from error categories to sets of linenumbers
# {str, set(int)}: a map from error categories to sets of linenumbers
...
@@ -504,6 +499,7 @@ _line_length = 80
...
@@ -504,6 +499,7 @@ _line_length = 80
# This is set by --extensions flag.
# This is set by --extensions flag.
_valid_extensions
=
set
([
'cc'
,
'h'
,
'cpp'
,
'cu'
,
'cuh'
])
_valid_extensions
=
set
([
'cc'
,
'h'
,
'cpp'
,
'cu'
,
'cuh'
])
def
ParseNolintSuppressions
(
filename
,
raw_line
,
linenum
,
error
):
def
ParseNolintSuppressions
(
filename
,
raw_line
,
linenum
,
error
):
"""Updates the global list of error-suppressions.
"""Updates the global list of error-suppressions.
...
@@ -521,9 +517,9 @@ def ParseNolintSuppressions(filename, raw_line, linenum, error):
...
@@ -521,9 +517,9 @@ def ParseNolintSuppressions(filename, raw_line, linenum, error):
if
matched
:
if
matched
:
if
matched
.
group
(
1
):
if
matched
.
group
(
1
):
lines
=
matched
.
group
(
2
)
lines
=
matched
.
group
(
2
)
if
lines
:
if
lines
:
lines
=
int
(
lines
[
2
:])
lines
=
int
(
lines
[
2
:])
suppressed_line
=
[
linenum
+
i
for
i
in
xrange
(
lines
)
]
suppressed_line
=
[
linenum
+
i
for
i
in
xrange
(
lines
)
]
else
:
else
:
suppressed_line
=
linenum
+
1
suppressed_line
=
linenum
+
1
else
:
else
:
...
@@ -540,10 +536,12 @@ def ParseNolintSuppressions(filename, raw_line, linenum, error):
...
@@ -540,10 +536,12 @@ def ParseNolintSuppressions(filename, raw_line, linenum, error):
category
=
category
[
1
:
-
1
]
category
=
category
[
1
:
-
1
]
if
category
in
_ERROR_CATEGORIES
:
if
category
in
_ERROR_CATEGORIES
:
if
isinstance
(
suppressed_line
,
int
):
if
isinstance
(
suppressed_line
,
int
):
_error_suppressions
.
setdefault
(
category
,
set
()).
add
(
suppressed_line
)
_error_suppressions
.
setdefault
(
category
,
set
()).
add
(
suppressed_line
)
else
:
else
:
for
_line
in
suppressed_line
:
for
_line
in
suppressed_line
:
_error_suppressions
.
setdefault
(
category
,
set
()).
add
(
_line
)
_error_suppressions
.
setdefault
(
category
,
set
()).
add
(
_line
)
elif
category
not
in
_LEGACY_ERROR_CATEGORIES
:
elif
category
not
in
_LEGACY_ERROR_CATEGORIES
:
error
(
filename
,
linenum
,
'readability/nolint'
,
5
,
error
(
filename
,
linenum
,
'readability/nolint'
,
5
,
'Unknown NOLINT error category: %s'
%
category
)
'Unknown NOLINT error category: %s'
%
category
)
...
@@ -730,9 +728,8 @@ class _IncludeState(object):
...
@@ -730,9 +728,8 @@ class _IncludeState(object):
error message describing what's wrong.
error message describing what's wrong.
"""
"""
error_message
=
(
'Found %s after %s'
%
error_message
=
(
'Found %s after %s'
%
(
(
self
.
_TYPE_NAMES
[
header_type
],
self
.
_TYPE_NAMES
[
header_type
],
self
.
_SECTION_NAMES
[
self
.
_section
]))
self
.
_SECTION_NAMES
[
self
.
_section
]))
last_section
=
self
.
_section
last_section
=
self
.
_section
...
@@ -828,7 +825,8 @@ class _CppLintState(object):
...
@@ -828,7 +825,8 @@ class _CppLintState(object):
self
.
filters
.
append
(
clean_filt
)
self
.
filters
.
append
(
clean_filt
)
for
filt
in
self
.
filters
:
for
filt
in
self
.
filters
:
if
not
(
filt
.
startswith
(
'+'
)
or
filt
.
startswith
(
'-'
)):
if
not
(
filt
.
startswith
(
'+'
)
or
filt
.
startswith
(
'-'
)):
raise
ValueError
(
'Every filter in --filters must start with + or -'
raise
ValueError
(
'Every filter in --filters must start with + or -'
' (%s does not)'
%
filt
)
' (%s does not)'
%
filt
)
def
BackupFilters
(
self
):
def
BackupFilters
(
self
):
...
@@ -861,6 +859,7 @@ class _CppLintState(object):
...
@@ -861,6 +859,7 @@ class _CppLintState(object):
(
category
,
count
))
(
category
,
count
))
sys
.
stdout
.
write
(
'Total errors found: %d
\n
'
%
self
.
error_count
)
sys
.
stdout
.
write
(
'Total errors found: %d
\n
'
%
self
.
error_count
)
_cpplint_state
=
_CppLintState
()
_cpplint_state
=
_CppLintState
()
...
@@ -906,6 +905,7 @@ def _SetFilters(filters):
...
@@ -906,6 +905,7 @@ def _SetFilters(filters):
"""
"""
_cpplint_state
.
SetFilters
(
filters
)
_cpplint_state
.
SetFilters
(
filters
)
def
_AddFilters
(
filters
):
def
_AddFilters
(
filters
):
"""Adds more filter overrides.
"""Adds more filter overrides.
...
@@ -918,14 +918,17 @@ def _AddFilters(filters):
...
@@ -918,14 +918,17 @@ def _AddFilters(filters):
"""
"""
_cpplint_state
.
AddFilters
(
filters
)
_cpplint_state
.
AddFilters
(
filters
)
def
_BackupFilters
():
def
_BackupFilters
():
""" Saves the current filter list to backup storage."""
""" Saves the current filter list to backup storage."""
_cpplint_state
.
BackupFilters
()
_cpplint_state
.
BackupFilters
()
def
_RestoreFilters
():
def
_RestoreFilters
():
""" Restores filters previously backed up."""
""" Restores filters previously backed up."""
_cpplint_state
.
RestoreFilters
()
_cpplint_state
.
RestoreFilters
()
class
_FunctionState
(
object
):
class
_FunctionState
(
object
):
"""Tracks current function name and the number of lines in its body."""
"""Tracks current function name and the number of lines in its body."""
...
@@ -967,7 +970,8 @@ class _FunctionState(object):
...
@@ -967,7 +970,8 @@ class _FunctionState(object):
trigger
=
base_trigger
*
2
**
_VerboseLevel
()
trigger
=
base_trigger
*
2
**
_VerboseLevel
()
if
self
.
lines_in_function
>
trigger
:
if
self
.
lines_in_function
>
trigger
:
error_level
=
int
(
math
.
log
(
self
.
lines_in_function
/
base_trigger
,
2
))
error_level
=
int
(
math
.
log
(
self
.
lines_in_function
/
base_trigger
,
2
))
# 50 => 0, 100 => 1, 200 => 2, 400 => 3, 800 => 4, 1600 => 5, ...
# 50 => 0, 100 => 1, 200 => 2, 400 => 3, 800 => 4, 1600 => 5, ...
if
error_level
>
5
:
if
error_level
>
5
:
error_level
=
5
error_level
=
5
...
@@ -1058,7 +1062,7 @@ class FileInfo(object):
...
@@ -1058,7 +1062,7 @@ class FileInfo(object):
googlename
=
self
.
RepositoryName
()
googlename
=
self
.
RepositoryName
()
project
,
rest
=
os
.
path
.
split
(
googlename
)
project
,
rest
=
os
.
path
.
split
(
googlename
)
return
(
project
,
)
+
os
.
path
.
splitext
(
rest
)
return
(
project
,
)
+
os
.
path
.
splitext
(
rest
)
def
BaseName
(
self
):
def
BaseName
(
self
):
"""File base name - text after the final slash, before the final period."""
"""File base name - text after the final slash, before the final period."""
...
@@ -1130,14 +1134,14 @@ def Error(filename, linenum, category, confidence, message):
...
@@ -1130,14 +1134,14 @@ def Error(filename, linenum, category, confidence, message):
if
_ShouldPrintError
(
category
,
confidence
,
linenum
):
if
_ShouldPrintError
(
category
,
confidence
,
linenum
):
_cpplint_state
.
IncrementErrorCount
(
category
)
_cpplint_state
.
IncrementErrorCount
(
category
)
if
_cpplint_state
.
output_format
==
'vs7'
:
if
_cpplint_state
.
output_format
==
'vs7'
:
sys
.
stderr
.
write
(
'%s(%s): %s [%s] [%d]
\n
'
%
(
sys
.
stderr
.
write
(
'%s(%s): %s [%s] [%d]
\n
'
%
filename
,
linenum
,
message
,
category
,
confidence
))
(
filename
,
linenum
,
message
,
category
,
confidence
))
elif
_cpplint_state
.
output_format
==
'eclipse'
:
elif
_cpplint_state
.
output_format
==
'eclipse'
:
sys
.
stderr
.
write
(
'%s:%s: warning: %s [%s] [%d]
\n
'
%
(
sys
.
stderr
.
write
(
'%s:%s: warning: %s [%s] [%d]
\n
'
%
filename
,
linenum
,
message
,
category
,
confidence
))
(
filename
,
linenum
,
message
,
category
,
confidence
))
else
:
else
:
sys
.
stderr
.
write
(
'%s:%s: %s [%s] [%d]
\n
'
%
(
sys
.
stderr
.
write
(
'%s:%s: %s [%s] [%d]
\n
'
%
filename
,
linenum
,
message
,
category
,
confidence
))
(
filename
,
linenum
,
message
,
category
,
confidence
))
# Matches standard C++ escape sequences per 2.13.2.3 of the C++ standard.
# Matches standard C++ escape sequences per 2.13.2.3 of the C++ standard.
...
@@ -1154,9 +1158,8 @@ _RE_PATTERN_C_COMMENTS = r'/\*(?:[^*]|\*(?!/))*\*/'
...
@@ -1154,9 +1158,8 @@ _RE_PATTERN_C_COMMENTS = r'/\*(?:[^*]|\*(?!/))*\*/'
# if this doesn't work we try on left side but only if there's a non-character
# if this doesn't work we try on left side but only if there's a non-character
# on the right.
# on the right.
_RE_PATTERN_CLEANSE_LINE_C_COMMENTS
=
re
.
compile
(
_RE_PATTERN_CLEANSE_LINE_C_COMMENTS
=
re
.
compile
(
r
'(\s*'
+
_RE_PATTERN_C_COMMENTS
+
r
'\s*$|'
+
r
'(\s*'
+
_RE_PATTERN_C_COMMENTS
+
r
'\s*$|'
+
_RE_PATTERN_C_COMMENTS
+
_RE_PATTERN_C_COMMENTS
+
r
'\s+|'
+
r
'\s+|'
+
r
'\s+'
+
_RE_PATTERN_C_COMMENTS
+
r
'(?=\W)|'
+
r
'\s+'
+
_RE_PATTERN_C_COMMENTS
+
r
'(?=\W)|'
+
_RE_PATTERN_C_COMMENTS
+
r
')'
)
_RE_PATTERN_C_COMMENTS
+
r
')'
)
...
@@ -1208,7 +1211,8 @@ def CleanseRawStrings(raw_lines):
...
@@ -1208,7 +1211,8 @@ def CleanseRawStrings(raw_lines):
# line and resume copying the original lines, and also insert
# line and resume copying the original lines, and also insert
# a "" on the last line.
# a "" on the last line.
leading_space
=
Match
(
r
'^(\s*)\S'
,
line
)
leading_space
=
Match
(
r
'^(\s*)\S'
,
line
)
line
=
leading_space
.
group
(
1
)
+
'""'
+
line
[
end
+
len
(
delimiter
):]
line
=
leading_space
.
group
(
1
)
+
'""'
+
line
[
end
+
len
(
delimiter
):]
delimiter
=
None
delimiter
=
None
else
:
else
:
# Haven't found the end yet, append a blank line.
# Haven't found the end yet, append a blank line.
...
@@ -1220,7 +1224,8 @@ def CleanseRawStrings(raw_lines):
...
@@ -1220,7 +1224,8 @@ def CleanseRawStrings(raw_lines):
while
delimiter
is
None
:
while
delimiter
is
None
:
# Look for beginning of a raw string.
# Look for beginning of a raw string.
# See 2.14.15 [lex.string] for syntax.
# See 2.14.15 [lex.string] for syntax.
matched
=
Match
(
r
'^(.*)\b(?:R|u8R|uR|UR|LR)"([^\s\\()]*)\((.*)$'
,
line
)
matched
=
Match
(
r
'^(.*)\b(?:R|u8R|uR|UR|LR)"([^\s\\()]*)\((.*)$'
,
line
)
if
matched
:
if
matched
:
delimiter
=
')'
+
matched
.
group
(
2
)
+
'"'
delimiter
=
')'
+
matched
.
group
(
2
)
+
'"'
...
@@ -1280,8 +1285,8 @@ def RemoveMultiLineComments(filename, lines, error):
...
@@ -1280,8 +1285,8 @@ def RemoveMultiLineComments(filename, lines, error):
return
return
lineix_end
=
FindNextMultiLineCommentEnd
(
lines
,
lineix_begin
)
lineix_end
=
FindNextMultiLineCommentEnd
(
lines
,
lineix_begin
)
if
lineix_end
>=
len
(
lines
):
if
lineix_end
>=
len
(
lines
):
error
(
filename
,
lineix_begin
+
1
,
'readability/multiline_comment'
,
5
,
error
(
filename
,
lineix_begin
+
1
,
'readability/multiline_comment'
,
'Could not find end of multi-line comment'
)
5
,
'Could not find end of multi-line comment'
)
return
return
RemoveMultiLineCommentsFromRange
(
lines
,
lineix_begin
,
lineix_end
+
1
)
RemoveMultiLineCommentsFromRange
(
lines
,
lineix_begin
,
lineix_end
+
1
)
lineix
=
lineix_end
+
1
lineix
=
lineix_end
+
1
...
@@ -1321,9 +1326,10 @@ class CleansedLines(object):
...
@@ -1321,9 +1326,10 @@ class CleansedLines(object):
self
.
num_lines
=
len
(
lines
)
self
.
num_lines
=
len
(
lines
)
self
.
lines_without_raw_strings
=
CleanseRawStrings
(
lines
)
self
.
lines_without_raw_strings
=
CleanseRawStrings
(
lines
)
for
linenum
in
range
(
len
(
self
.
lines_without_raw_strings
)):
for
linenum
in
range
(
len
(
self
.
lines_without_raw_strings
)):
self
.
lines
.
append
(
CleanseComments
(
self
.
lines
.
append
(
self
.
lines_without_raw_strings
[
linenum
]))
CleanseComments
(
self
.
lines_without_raw_strings
[
linenum
]))
elided
=
self
.
_CollapseStrings
(
self
.
lines_without_raw_strings
[
linenum
])
elided
=
self
.
_CollapseStrings
(
self
.
lines_without_raw_strings
[
linenum
])
self
.
elided
.
append
(
CleanseComments
(
elided
))
self
.
elided
.
append
(
CleanseComments
(
elided
))
def
NumLines
(
self
):
def
NumLines
(
self
):
...
@@ -1382,7 +1388,8 @@ class CleansedLines(object):
...
@@ -1382,7 +1388,8 @@ class CleansedLines(object):
# separator. So we are fine as long as we don't see something
# separator. So we are fine as long as we don't see something
# like "0.'3" (gcc 4.9.0 will not allow this literal).
# like "0.'3" (gcc 4.9.0 will not allow this literal).
if
Search
(
r
'\b(?:0[bBxX]?|[1-9])[0-9a-fA-F]*$'
,
head
):
if
Search
(
r
'\b(?:0[bBxX]?|[1-9])[0-9a-fA-F]*$'
,
head
):
match_literal
=
Match
(
r
'^((?:\'?[0-9a-zA-Z_])*)(.*)$'
,
"'"
+
tail
)
match_literal
=
Match
(
r
'^((?:\'?[0-9a-zA-Z_])*)(.*)$'
,
"'"
+
tail
)
collapsed
+=
head
+
match_literal
.
group
(
1
).
replace
(
"'"
,
''
)
collapsed
+=
head
+
match_literal
.
group
(
1
).
replace
(
"'"
,
''
)
elided
=
match_literal
.
group
(
2
)
elided
=
match_literal
.
group
(
2
)
else
:
else
:
...
@@ -1452,8 +1459,8 @@ def FindEndOfExpressionInLine(line, startpos, stack):
...
@@ -1452,8 +1459,8 @@ def FindEndOfExpressionInLine(line, startpos, stack):
# Found potential end of template argument list.
# Found potential end of template argument list.
# Ignore "->" and operator functions
# Ignore "->" and operator functions
if
(
i
>
0
and
if
(
i
>
0
and
(
line
[
i
-
1
]
==
'-'
or
Search
(
r
'\boperator\s*$'
,
(
line
[
i
-
1
]
==
'-'
or
Search
(
r
'\boperator\s*$'
,
line
[
0
:
i
-
1
]))):
line
[
0
:
i
-
1
]))):
continue
continue
# Pop the stack if there is a matching '<'. Otherwise, ignore
# Pop the stack if there is a matching '<'. Otherwise, ignore
...
@@ -1547,8 +1554,7 @@ def FindStartOfExpressionInLine(line, endpos, stack):
...
@@ -1547,8 +1554,7 @@ def FindStartOfExpressionInLine(line, endpos, stack):
#
#
# Ignore it if it's a "->" or ">=" or "operator>"
# Ignore it if it's a "->" or ">=" or "operator>"
if
(
i
>
0
and
if
(
i
>
0
and
(
line
[
i
-
1
]
==
'-'
or
(
line
[
i
-
1
]
==
'-'
or
Match
(
r
'\s>=\s'
,
line
[
i
-
1
:])
or
Match
(
r
'\s>=\s'
,
line
[
i
-
1
:])
or
Search
(
r
'\boperator\s*$'
,
line
[
0
:
i
]))):
Search
(
r
'\boperator\s*$'
,
line
[
0
:
i
]))):
i
-=
1
i
-=
1
else
:
else
:
...
@@ -1627,7 +1633,8 @@ def ReverseCloseExpression(clean_lines, linenum, pos):
...
@@ -1627,7 +1633,8 @@ def ReverseCloseExpression(clean_lines, linenum, pos):
while
stack
and
linenum
>
0
:
while
stack
and
linenum
>
0
:
linenum
-=
1
linenum
-=
1
line
=
clean_lines
.
elided
[
linenum
]
line
=
clean_lines
.
elided
[
linenum
]
(
start_pos
,
stack
)
=
FindStartOfExpressionInLine
(
line
,
len
(
line
)
-
1
,
stack
)
(
start_pos
,
stack
)
=
FindStartOfExpressionInLine
(
line
,
len
(
line
)
-
1
,
stack
)
if
start_pos
>
-
1
:
if
start_pos
>
-
1
:
return
(
line
,
linenum
,
start_pos
)
return
(
line
,
linenum
,
start_pos
)
...
@@ -1643,8 +1650,7 @@ def CheckForCopyright(filename, lines, error):
...
@@ -1643,8 +1650,7 @@ def CheckForCopyright(filename, lines, error):
for
line
in
xrange
(
1
,
min
(
len
(
lines
),
11
)):
for
line
in
xrange
(
1
,
min
(
len
(
lines
),
11
)):
if
re
.
search
(
r
'Copyright'
,
lines
[
line
],
re
.
I
):
break
if
re
.
search
(
r
'Copyright'
,
lines
[
line
],
re
.
I
):
break
else
:
# means no copyright line was found
else
:
# means no copyright line was found
error
(
filename
,
0
,
'legal/copyright'
,
5
,
error
(
filename
,
0
,
'legal/copyright'
,
5
,
'No copyright message found. '
'No copyright message found. '
'You should have a line: "Copyright [year] <Copyright Owner>"'
)
'You should have a line: "Copyright [year] <Copyright Owner>"'
)
...
@@ -1741,8 +1747,8 @@ def CheckForHeaderGuard(filename, clean_lines, error):
...
@@ -1741,8 +1747,8 @@ def CheckForHeaderGuard(filename, clean_lines, error):
if
ifndef
!=
cppvar
+
'_'
:
if
ifndef
!=
cppvar
+
'_'
:
error_level
=
5
error_level
=
5
ParseNolintSuppressions
(
filename
,
raw_lines
[
ifndef_linenum
],
ifndef_linenum
,
ParseNolintSuppressions
(
filename
,
raw_lines
[
ifndef_linenum
]
,
error
)
ifndef_linenum
,
error
)
error
(
filename
,
ifndef_linenum
,
'build/header_guard'
,
error_level
,
error
(
filename
,
ifndef_linenum
,
'build/header_guard'
,
error_level
,
'#ifndef header guard has wrong style, please use: %s'
%
cppvar
)
'#ifndef header guard has wrong style, please use: %s'
%
cppvar
)
...
@@ -1763,7 +1769,8 @@ def CheckForHeaderGuard(filename, clean_lines, error):
...
@@ -1763,7 +1769,8 @@ def CheckForHeaderGuard(filename, clean_lines, error):
no_single_line_comments
=
True
no_single_line_comments
=
True
for
i
in
xrange
(
1
,
len
(
raw_lines
)
-
1
):
for
i
in
xrange
(
1
,
len
(
raw_lines
)
-
1
):
line
=
raw_lines
[
i
]
line
=
raw_lines
[
i
]
if
Match
(
r
'^(?:(?:\'(?:\.|[^\'])*\')|(?:"(?:\.|[^"])*")|[^\'"])*//'
,
line
):
if
Match
(
r
'^(?:(?:\'(?:\.|[^\'])*\')|(?:"(?:\.|[^"])*")|[^\'"])*//'
,
line
):
no_single_line_comments
=
False
no_single_line_comments
=
False
break
break
...
@@ -1825,10 +1832,13 @@ def CheckForBadCharacters(filename, lines, error):
...
@@ -1825,10 +1832,13 @@ def CheckForBadCharacters(filename, lines, error):
"""
"""
for
linenum
,
line
in
enumerate
(
lines
):
for
linenum
,
line
in
enumerate
(
lines
):
if
u
'
\ufffd
'
in
line
:
if
u
'
\ufffd
'
in
line
:
error
(
filename
,
linenum
,
'readability/utf8'
,
5
,
error
(
'Line contains invalid UTF-8 (or Unicode replacement character).'
)
filename
,
linenum
,
'readability/utf8'
,
5
,
'Line contains invalid UTF-8 (or Unicode replacement character).'
)
if
'
\0
'
in
line
:
if
'
\0
'
in
line
:
error
(
filename
,
linenum
,
'readability/nul'
,
5
,
'Line contains NUL byte.'
)
error
(
filename
,
linenum
,
'readability/nul'
,
5
,
'Line contains NUL byte.'
)
def
CheckForNewlineAtEOF
(
filename
,
lines
,
error
):
def
CheckForNewlineAtEOF
(
filename
,
lines
,
error
):
...
@@ -1845,7 +1855,8 @@ def CheckForNewlineAtEOF(filename, lines, error):
...
@@ -1845,7 +1855,8 @@ def CheckForNewlineAtEOF(filename, lines, error):
# To verify that the file ends in \n, we just have to make sure the
# To verify that the file ends in \n, we just have to make sure the
# last-but-two element of lines() exists and is empty.
# last-but-two element of lines() exists and is empty.
if
len
(
lines
)
<
3
or
lines
[
-
2
]:
if
len
(
lines
)
<
3
or
lines
[
-
2
]:
error
(
filename
,
len
(
lines
)
-
2
,
'whitespace/ending_newline'
,
5
,
error
(
filename
,
len
(
lines
)
-
2
,
'whitespace/ending_newline'
,
5
,
'Could not find a newline character at the end of the file.'
)
'Could not find a newline character at the end of the file.'
)
...
@@ -1911,10 +1922,8 @@ _THREADING_LIST = (
...
@@ -1911,10 +1922,8 @@ _THREADING_LIST = (
(
'gmtime('
,
'gmtime_r('
,
_UNSAFE_FUNC_PREFIX
+
r
'gmtime\([^)]+\)'
),
(
'gmtime('
,
'gmtime_r('
,
_UNSAFE_FUNC_PREFIX
+
r
'gmtime\([^)]+\)'
),
(
'localtime('
,
'localtime_r('
,
_UNSAFE_FUNC_PREFIX
+
r
'localtime\([^)]+\)'
),
(
'localtime('
,
'localtime_r('
,
_UNSAFE_FUNC_PREFIX
+
r
'localtime\([^)]+\)'
),
(
'rand('
,
'rand_r('
,
_UNSAFE_FUNC_PREFIX
+
r
'rand\(\)'
),
(
'rand('
,
'rand_r('
,
_UNSAFE_FUNC_PREFIX
+
r
'rand\(\)'
),
(
'strtok('
,
'strtok_r('
,
(
'strtok('
,
'strtok_r('
,
_UNSAFE_FUNC_PREFIX
+
r
'strtok\([^)]+\)'
),
_UNSAFE_FUNC_PREFIX
+
r
'strtok\([^)]+\)'
),
(
'ttyname('
,
'ttyname_r('
,
_UNSAFE_FUNC_PREFIX
+
r
'ttyname\([^)]+\)'
),
)
(
'ttyname('
,
'ttyname_r('
,
_UNSAFE_FUNC_PREFIX
+
r
'ttyname\([^)]+\)'
),
)
def
CheckPosixThreading
(
filename
,
clean_lines
,
linenum
,
error
):
def
CheckPosixThreading
(
filename
,
clean_lines
,
linenum
,
error
):
...
@@ -1938,9 +1947,8 @@ def CheckPosixThreading(filename, clean_lines, linenum, error):
...
@@ -1938,9 +1947,8 @@ def CheckPosixThreading(filename, clean_lines, linenum, error):
# function we are looking for
# function we are looking for
if
Search
(
pattern
,
line
):
if
Search
(
pattern
,
line
):
error
(
filename
,
linenum
,
'runtime/threadsafe_fn'
,
2
,
error
(
filename
,
linenum
,
'runtime/threadsafe_fn'
,
2
,
'Consider using '
+
multithread_safe_func
+
'Consider using '
+
multithread_safe_func
+
'...) instead of '
'...) instead of '
+
single_thread_func
+
+
single_thread_func
+
'...) for improved thread safety.'
)
'...) for improved thread safety.'
)
def
CheckVlogArguments
(
filename
,
clean_lines
,
linenum
,
error
):
def
CheckVlogArguments
(
filename
,
clean_lines
,
linenum
,
error
):
...
@@ -1961,10 +1969,10 @@ def CheckVlogArguments(filename, clean_lines, linenum, error):
...
@@ -1961,10 +1969,10 @@ def CheckVlogArguments(filename, clean_lines, linenum, error):
'VLOG() should be used with numeric verbosity level. '
'VLOG() should be used with numeric verbosity level. '
'Use LOG() if you want symbolic severity levels.'
)
'Use LOG() if you want symbolic severity levels.'
)
# Matches invalid increment: *count++, which moves pointer instead of
# Matches invalid increment: *count++, which moves pointer instead of
# incrementing a value.
# incrementing a value.
_RE_PATTERN_INVALID_INCREMENT
=
re
.
compile
(
_RE_PATTERN_INVALID_INCREMENT
=
re
.
compile
(
r
'^\s*\*\w+(\+\+|--);'
)
r
'^\s*\*\w+(\+\+|--);'
)
def
CheckInvalidIncrement
(
filename
,
clean_lines
,
linenum
,
error
):
def
CheckInvalidIncrement
(
filename
,
clean_lines
,
linenum
,
error
):
...
@@ -1985,7 +1993,8 @@ def CheckInvalidIncrement(filename, clean_lines, linenum, error):
...
@@ -1985,7 +1993,8 @@ def CheckInvalidIncrement(filename, clean_lines, linenum, error):
"""
"""
line
=
clean_lines
.
elided
[
linenum
]
line
=
clean_lines
.
elided
[
linenum
]
if
_RE_PATTERN_INVALID_INCREMENT
.
match
(
line
):
if
_RE_PATTERN_INVALID_INCREMENT
.
match
(
line
):
error
(
filename
,
linenum
,
'runtime/invalid_increment'
,
5
,
error
(
filename
,
linenum
,
'runtime/invalid_increment'
,
5
,
'Changing pointer instead of value (or unused value of operator*).'
)
'Changing pointer instead of value (or unused value of operator*).'
)
...
@@ -2104,13 +2113,13 @@ class _ClassInfo(_BlockInfo):
...
@@ -2104,13 +2113,13 @@ class _ClassInfo(_BlockInfo):
seen_last_thing_in_class
=
False
seen_last_thing_in_class
=
False
for
i
in
xrange
(
linenum
-
1
,
self
.
starting_linenum
,
-
1
):
for
i
in
xrange
(
linenum
-
1
,
self
.
starting_linenum
,
-
1
):
match
=
Search
(
match
=
Search
(
r
'\b(DISALLOW_COPY_AND_ASSIGN|DISALLOW_IMPLICIT_CONSTRUCTORS)\('
+
r
'\b(DISALLOW_COPY_AND_ASSIGN|DISALLOW_IMPLICIT_CONSTRUCTORS)\('
self
.
name
+
r
'\)'
,
+
self
.
name
+
r
'\)'
,
clean_lines
.
elided
[
i
])
clean_lines
.
elided
[
i
])
if
match
:
if
match
:
if
seen_last_thing_in_class
:
if
seen_last_thing_in_class
:
error
(
filename
,
i
,
'readability/constructors'
,
3
,
error
(
filename
,
i
,
'readability/constructors'
,
3
,
match
.
group
(
1
)
+
' should be the last thing in the class'
)
match
.
group
(
1
)
+
' should be the last thing in the class'
)
break
break
if
not
Match
(
r
'^\s*$'
,
clean_lines
.
elided
[
i
]):
if
not
Match
(
r
'^\s*$'
,
clean_lines
.
elided
[
i
]):
...
@@ -2126,7 +2135,8 @@ class _ClassInfo(_BlockInfo):
...
@@ -2126,7 +2135,8 @@ class _ClassInfo(_BlockInfo):
else
:
else
:
parent
=
'class '
+
self
.
name
parent
=
'class '
+
self
.
name
error
(
filename
,
linenum
,
'whitespace/indent'
,
3
,
error
(
filename
,
linenum
,
'whitespace/indent'
,
3
,
'Closing brace should be aligned with beginning of %s'
%
parent
)
'Closing brace should be aligned with beginning of %s'
%
parent
)
class
_NamespaceInfo
(
_BlockInfo
):
class
_NamespaceInfo
(
_BlockInfo
):
...
@@ -2153,8 +2163,8 @@ class _NamespaceInfo(_BlockInfo):
...
@@ -2153,8 +2163,8 @@ class _NamespaceInfo(_BlockInfo):
# other than forward declarations). There is currently no logic on
# other than forward declarations). There is currently no logic on
# deciding what these nontrivial things are, so this check is
# deciding what these nontrivial things are, so this check is
# triggered by namespace size only, which works most of the time.
# triggered by namespace size only, which works most of the time.
if
(
linenum
-
self
.
starting_linenum
<
10
if
(
linenum
-
self
.
starting_linenum
<
10
and
and
not
Match
(
r
'};*\s*(//|/\*).*\bnamespace\b'
,
line
)):
not
Match
(
r
'};*\s*(//|/\*).*\bnamespace\b'
,
line
)):
return
return
# Look for matching comment at end of namespace.
# Look for matching comment at end of namespace.
...
@@ -2171,9 +2181,8 @@ class _NamespaceInfo(_BlockInfo):
...
@@ -2171,9 +2181,8 @@ class _NamespaceInfo(_BlockInfo):
# expected namespace.
# expected namespace.
if
self
.
name
:
if
self
.
name
:
# Named namespace
# Named namespace
if
not
Match
((
r
'};*\s*(//|/\*).*\bnamespace\s+'
+
re
.
escape
(
self
.
name
)
+
if
not
Match
((
r
'};*\s*(//|/\*).*\bnamespace\s+'
+
r
'[\*/\.\\\s]*$'
),
re
.
escape
(
self
.
name
)
+
r
'[\*/\.\\\s]*$'
),
line
):
line
):
error
(
filename
,
linenum
,
'readability/namespace'
,
5
,
error
(
filename
,
linenum
,
'readability/namespace'
,
5
,
'Namespace should be terminated with "// namespace %s"'
%
'Namespace should be terminated with "// namespace %s"'
%
self
.
name
)
self
.
name
)
...
@@ -2182,13 +2191,17 @@ class _NamespaceInfo(_BlockInfo):
...
@@ -2182,13 +2191,17 @@ class _NamespaceInfo(_BlockInfo):
if
not
Match
(
r
'};*\s*(//|/\*).*\bnamespace[\*/\.\\\s]*$'
,
line
):
if
not
Match
(
r
'};*\s*(//|/\*).*\bnamespace[\*/\.\\\s]*$'
,
line
):
# If "// namespace anonymous" or "// anonymous namespace (more text)",
# If "// namespace anonymous" or "// anonymous namespace (more text)",
# mention "// anonymous namespace" as an acceptable form
# mention "// anonymous namespace" as an acceptable form
if
Match
(
r
'}.*\b(namespace anonymous|anonymous namespace)\b'
,
line
):
if
Match
(
r
'}.*\b(namespace anonymous|anonymous namespace)\b'
,
error
(
filename
,
linenum
,
'readability/namespace'
,
5
,
line
):
error
(
filename
,
linenum
,
'readability/namespace'
,
5
,
'Anonymous namespace should be terminated with "// namespace"'
'Anonymous namespace should be terminated with "// namespace"'
' or "// anonymous namespace"'
)
' or "// anonymous namespace"'
)
else
:
else
:
error
(
filename
,
linenum
,
'readability/namespace'
,
5
,
error
(
'Anonymous namespace should be terminated with "// namespace"'
)
filename
,
linenum
,
'readability/namespace'
,
5
,
'Anonymous namespace should be terminated with "// namespace"'
)
class
_PreprocessorInfo
(
object
):
class
_PreprocessorInfo
(
object
):
...
@@ -2316,7 +2329,8 @@ class NestingState(object):
...
@@ -2316,7 +2329,8 @@ class NestingState(object):
# We can't be sure if we just find a single '<', and need to
# We can't be sure if we just find a single '<', and need to
# find the matching '>'.
# find the matching '>'.
(
_
,
end_line
,
end_pos
)
=
CloseExpression
(
clean_lines
,
linenum
,
pos
-
1
)
(
_
,
end_line
,
end_pos
)
=
CloseExpression
(
clean_lines
,
linenum
,
pos
-
1
)
if
end_pos
<
0
:
if
end_pos
<
0
:
# Not sure if template argument list or syntax error in file
# Not sure if template argument list or syntax error in file
return
False
return
False
...
@@ -2357,7 +2371,8 @@ class NestingState(object):
...
@@ -2357,7 +2371,8 @@ class NestingState(object):
# whole nesting stack up to this point. This is what we
# whole nesting stack up to this point. This is what we
# keep after the #endif.
# keep after the #endif.
self
.
pp_stack
[
-
1
].
seen_else
=
True
self
.
pp_stack
[
-
1
].
seen_else
=
True
self
.
pp_stack
[
-
1
].
stack_before_else
=
copy
.
deepcopy
(
self
.
stack
)
self
.
pp_stack
[
-
1
].
stack_before_else
=
copy
.
deepcopy
(
self
.
stack
)
# Restore the stack to how it was before the #if
# Restore the stack to how it was before the #if
self
.
stack
=
copy
.
deepcopy
(
self
.
pp_stack
[
-
1
].
stack_before_if
)
self
.
stack
=
copy
.
deepcopy
(
self
.
pp_stack
[
-
1
].
stack_before_if
)
...
@@ -2414,8 +2429,7 @@ class NestingState(object):
...
@@ -2414,8 +2429,7 @@ class NestingState(object):
# Also check if we are starting or ending an inline assembly block.
# Also check if we are starting or ending an inline assembly block.
if
inner_block
.
inline_asm
in
(
_NO_ASM
,
_END_ASM
):
if
inner_block
.
inline_asm
in
(
_NO_ASM
,
_END_ASM
):
if
(
depth_change
!=
0
and
if
(
depth_change
!=
0
and
inner_block
.
open_parentheses
==
1
and
inner_block
.
open_parentheses
==
1
and
_MATCH_ASM
.
match
(
line
)):
_MATCH_ASM
.
match
(
line
)):
# Enter assembly block
# Enter assembly block
inner_block
.
inline_asm
=
_INSIDE_ASM
inner_block
.
inline_asm
=
_INSIDE_ASM
...
@@ -2436,11 +2450,13 @@ class NestingState(object):
...
@@ -2436,11 +2450,13 @@ class NestingState(object):
# declarations even if it weren't followed by a whitespace, this
# declarations even if it weren't followed by a whitespace, this
# is so that we don't confuse our namespace checker. The
# is so that we don't confuse our namespace checker. The
# missing spaces will be flagged by CheckSpacing.
# missing spaces will be flagged by CheckSpacing.
namespace_decl_match
=
Match
(
r
'^\s*namespace\b\s*([:\w]+)?(.*)$'
,
line
)
namespace_decl_match
=
Match
(
r
'^\s*namespace\b\s*([:\w]+)?(.*)$'
,
line
)
if
not
namespace_decl_match
:
if
not
namespace_decl_match
:
break
break
new_namespace
=
_NamespaceInfo
(
namespace_decl_match
.
group
(
1
),
linenum
)
new_namespace
=
_NamespaceInfo
(
namespace_decl_match
.
group
(
1
),
linenum
)
self
.
stack
.
append
(
new_namespace
)
self
.
stack
.
append
(
new_namespace
)
line
=
namespace_decl_match
.
group
(
2
)
line
=
namespace_decl_match
.
group
(
2
)
...
@@ -2469,10 +2485,12 @@ class NestingState(object):
...
@@ -2469,10 +2485,12 @@ class NestingState(object):
# an unmatched '>'. If we see one, assume we are inside a
# an unmatched '>'. If we see one, assume we are inside a
# template argument list.
# template argument list.
end_declaration
=
len
(
class_decl_match
.
group
(
1
))
end_declaration
=
len
(
class_decl_match
.
group
(
1
))
if
not
self
.
InTemplateArgumentList
(
clean_lines
,
linenum
,
end_declaration
):
if
not
self
.
InTemplateArgumentList
(
clean_lines
,
linenum
,
self
.
stack
.
append
(
_ClassInfo
(
end_declaration
):
class_decl_match
.
group
(
3
),
class_decl_match
.
group
(
2
),
self
.
stack
.
append
(
clean_lines
,
linenum
))
_ClassInfo
(
class_decl_match
.
group
(
3
),
class_decl_match
.
group
(
2
),
clean_lines
,
linenum
))
line
=
class_decl_match
.
group
(
4
)
line
=
class_decl_match
.
group
(
4
)
# If we have not yet seen the opening brace for the innermost block,
# If we have not yet seen the opening brace for the innermost block,
...
@@ -2485,8 +2503,7 @@ class NestingState(object):
...
@@ -2485,8 +2503,7 @@ class NestingState(object):
classinfo
=
self
.
stack
[
-
1
]
classinfo
=
self
.
stack
[
-
1
]
access_match
=
Match
(
access_match
=
Match
(
r
'^(.*)\b(public|private|protected|signals)(\s+(?:slots\s*)?)?'
r
'^(.*)\b(public|private|protected|signals)(\s+(?:slots\s*)?)?'
r
':(?:[^:]|$)'
,
r
':(?:[^:]|$)'
,
line
)
line
)
if
access_match
:
if
access_match
:
classinfo
.
access
=
access_match
.
group
(
2
)
classinfo
.
access
=
access_match
.
group
(
2
)
...
@@ -2541,7 +2558,8 @@ class NestingState(object):
...
@@ -2541,7 +2558,8 @@ class NestingState(object):
else
:
# token == '}'
else
:
# token == '}'
# Perform end of block checks and pop the stack.
# Perform end of block checks and pop the stack.
if
self
.
stack
:
if
self
.
stack
:
self
.
stack
[
-
1
].
CheckEnd
(
filename
,
clean_lines
,
linenum
,
error
)
self
.
stack
[
-
1
].
CheckEnd
(
filename
,
clean_lines
,
linenum
,
error
)
self
.
stack
.
pop
()
self
.
stack
.
pop
()
line
=
matched
.
group
(
2
)
line
=
matched
.
group
(
2
)
...
@@ -2579,8 +2597,8 @@ class NestingState(object):
...
@@ -2579,8 +2597,8 @@ class NestingState(object):
obj
.
name
)
obj
.
name
)
def
CheckForNonStandardConstructs
(
filename
,
clean_lines
,
linenum
,
def
CheckForNonStandardConstructs
(
filename
,
clean_lines
,
linenum
,
nesting_state
,
nesting_state
,
error
):
error
):
r
"""Logs an error if we see certain non-ANSI constructs ignored by gcc-2.
r
"""Logs an error if we see certain non-ANSI constructs ignored by gcc-2.
Complain about several constructs which gcc-2 accepts, but which are
Complain about several constructs which gcc-2 accepts, but which are
...
@@ -2632,8 +2650,7 @@ def CheckForNonStandardConstructs(filename, clean_lines, linenum,
...
@@ -2632,8 +2650,7 @@ def CheckForNonStandardConstructs(filename, clean_lines, linenum,
if
Search
(
r
'\b(const|volatile|void|char|short|int|long'
if
Search
(
r
'\b(const|volatile|void|char|short|int|long'
r
'|float|double|signed|unsigned'
r
'|float|double|signed|unsigned'
r
'|schar|u?int8|u?int16|u?int32|u?int64)'
r
'|schar|u?int8|u?int16|u?int32|u?int64)'
r
'\s+(register|static|extern|typedef)\b'
,
r
'\s+(register|static|extern|typedef)\b'
,
line
):
line
):
error
(
filename
,
linenum
,
'build/storage_class'
,
5
,
error
(
filename
,
linenum
,
'build/storage_class'
,
5
,
'Storage class (static, extern, typedef, etc) should be first.'
)
'Storage class (static, extern, typedef, etc) should be first.'
)
...
@@ -2642,12 +2659,14 @@ def CheckForNonStandardConstructs(filename, clean_lines, linenum,
...
@@ -2642,12 +2659,14 @@ def CheckForNonStandardConstructs(filename, clean_lines, linenum,
'Uncommented text after #endif is non-standard. Use a comment.'
)
'Uncommented text after #endif is non-standard. Use a comment.'
)
if
Match
(
r
'\s*class\s+(\w+\s*::\s*)+\w+\s*;'
,
line
):
if
Match
(
r
'\s*class\s+(\w+\s*::\s*)+\w+\s*;'
,
line
):
error
(
filename
,
linenum
,
'build/forward_decl'
,
5
,
error
(
filename
,
linenum
,
'build/forward_decl'
,
5
,
'Inner-style forward declarations are invalid. Remove this line.'
)
'Inner-style forward declarations are invalid. Remove this line.'
)
if
Search
(
r
'(\w+|[+-]?\d+(\.\d*)?)\s*(<|>)\?=?\s*(\w+|[+-]?\d+)(\.\d*)?'
,
if
Search
(
r
'(\w+|[+-]?\d+(\.\d*)?)\s*(<|>)\?=?\s*(\w+|[+-]?\d+)(\.\d*)?'
,
line
):
line
):
error
(
filename
,
linenum
,
'build/deprecated'
,
3
,
error
(
filename
,
linenum
,
'build/deprecated'
,
3
,
'>? and <? (max and min) operators are non-standard and deprecated.'
)
'>? and <? (max and min) operators are non-standard and deprecated.'
)
if
Search
(
r
'^\s*const\s*string\s*&\s*\w+\s*;'
,
line
):
if
Search
(
r
'^\s*const\s*string\s*&\s*\w+\s*;'
,
line
):
...
@@ -2679,9 +2698,7 @@ def CheckForNonStandardConstructs(filename, clean_lines, linenum,
...
@@ -2679,9 +2698,7 @@ def CheckForNonStandardConstructs(filename, clean_lines, linenum,
# strongly suggest something is wrong.
# strongly suggest something is wrong.
explicit_constructor_match
=
Match
(
explicit_constructor_match
=
Match
(
r
'\s+(?:inline\s+)?(explicit\s+)?(?:inline\s+)?%s\s*'
r
'\s+(?:inline\s+)?(explicit\s+)?(?:inline\s+)?%s\s*'
r
'\(((?:[^()]|\([^()]*\))*)\)'
r
'\(((?:[^()]|\([^()]*\))*)\)'
%
re
.
escape
(
base_classname
),
line
)
%
re
.
escape
(
base_classname
),
line
)
if
explicit_constructor_match
:
if
explicit_constructor_match
:
is_marked_explicit
=
explicit_constructor_match
.
group
(
1
)
is_marked_explicit
=
explicit_constructor_match
.
group
(
1
)
...
@@ -2704,38 +2721,40 @@ def CheckForNonStandardConstructs(filename, clean_lines, linenum,
...
@@ -2704,38 +2721,40 @@ def CheckForNonStandardConstructs(filename, clean_lines, linenum,
i
+=
1
i
+=
1
defaulted_args
=
[
arg
for
arg
in
constructor_args
if
'='
in
arg
]
defaulted_args
=
[
arg
for
arg
in
constructor_args
if
'='
in
arg
]
noarg_constructor
=
(
not
constructor_args
or
# empty arg list
noarg_constructor
=
(
not
constructor_args
or
# empty arg list
# 'void' arg specifier
# 'void' arg specifier
(
len
(
constructor_args
)
==
1
and
(
len
(
constructor_args
)
==
1
and
constructor_args
[
0
].
strip
()
==
'void'
))
constructor_args
[
0
].
strip
()
==
'void'
))
onearg_constructor
=
((
len
(
constructor_args
)
==
1
and
# exactly one arg
onearg_constructor
=
(
(
len
(
constructor_args
)
==
1
and
# exactly one arg
not
noarg_constructor
)
or
not
noarg_constructor
)
or
# all but at most one arg defaulted
# all but at most one arg defaulted
(
len
(
constructor_args
)
>=
1
and
(
len
(
constructor_args
)
>=
1
and
not
noarg_constructor
and
not
noarg_constructor
and
len
(
defaulted_args
)
>=
len
(
constructor_args
)
-
1
))
len
(
defaulted_args
)
>=
len
(
constructor_args
)
-
1
))
initializer_list_constructor
=
bool
(
initializer_list_constructor
=
bool
(
onearg_constructor
and
onearg_constructor
and
Search
(
r
'\bstd\s*::\s*initializer_list\b'
,
constructor_args
[
0
]))
Search
(
r
'\bstd\s*::\s*initializer_list\b'
,
constructor_args
[
0
]))
copy_constructor
=
bool
(
copy_constructor
=
bool
(
onearg_constructor
and
onearg_constructor
and
Match
(
r
'(const\s+)?%s(\s*<[^>]*>)?(\s+const)?\s*(?:<\w+>\s*)?&'
Match
(
r
'(const\s+)?%s(\s*<[^>]*>)?(\s+const)?\s*(?:<\w+>\s*)?&'
%
%
re
.
escape
(
base_classname
),
constructor_args
[
0
].
strip
()))
re
.
escape
(
base_classname
),
constructor_args
[
0
].
strip
()))
if
(
not
is_marked_explicit
and
if
(
not
is_marked_explicit
and
onearg_constructor
and
onearg_constructor
and
not
initializer_list_constructor
and
not
copy_constructor
):
not
initializer_list_constructor
and
not
copy_constructor
):
if
defaulted_args
:
if
defaulted_args
:
error
(
filename
,
linenum
,
'runtime/explicit'
,
5
,
error
(
filename
,
linenum
,
'runtime/explicit'
,
5
,
'Constructors callable with one argument '
'Constructors callable with one argument '
'should be marked explicit.'
)
'should be marked explicit.'
)
else
:
else
:
error
(
filename
,
linenum
,
'runtime/explicit'
,
5
,
error
(
filename
,
linenum
,
'runtime/explicit'
,
5
,
'Single-parameter constructors should be marked explicit.'
)
'Single-parameter constructors should be marked explicit.'
)
elif
is_marked_explicit
and
not
onearg_constructor
:
elif
is_marked_explicit
and
not
onearg_constructor
:
if
noarg_constructor
:
if
noarg_constructor
:
error
(
filename
,
linenum
,
'runtime/explicit'
,
5
,
error
(
filename
,
linenum
,
'runtime/explicit'
,
5
,
'Zero-parameter constructors should not be marked explicit.'
)
'Zero-parameter constructors should not be marked explicit.'
)
else
:
else
:
error
(
filename
,
linenum
,
'runtime/explicit'
,
0
,
error
(
filename
,
linenum
,
'runtime/explicit'
,
0
,
...
@@ -2759,10 +2778,8 @@ def CheckSpacingForFunctionCall(filename, clean_lines, linenum, error):
...
@@ -2759,10 +2778,8 @@ def CheckSpacingForFunctionCall(filename, clean_lines, linenum, error):
# first see if we should be looking inside such an expression for a
# first see if we should be looking inside such an expression for a
# function call, to which we can apply more strict standards.
# function call, to which we can apply more strict standards.
fncall
=
line
# if there's no control flow construct, look at whole line
fncall
=
line
# if there's no control flow construct, look at whole line
for
pattern
in
(
r
'\bif\s*\((.*)\)\s*{'
,
for
pattern
in
(
r
'\bif\s*\((.*)\)\s*{'
,
r
'\bfor\s*\((.*)\)\s*{'
,
r
'\bfor\s*\((.*)\)\s*{'
,
r
'\bwhile\s*\((.*)\)\s*[{;]'
,
r
'\bswitch\s*\((.*)\)\s*{'
):
r
'\bwhile\s*\((.*)\)\s*[{;]'
,
r
'\bswitch\s*\((.*)\)\s*{'
):
match
=
Search
(
pattern
,
line
)
match
=
Search
(
pattern
,
line
)
if
match
:
if
match
:
fncall
=
match
.
group
(
1
)
# look inside the parens for function calls
fncall
=
match
.
group
(
1
)
# look inside the parens for function calls
...
@@ -2782,7 +2799,8 @@ def CheckSpacingForFunctionCall(filename, clean_lines, linenum, error):
...
@@ -2782,7 +2799,8 @@ def CheckSpacingForFunctionCall(filename, clean_lines, linenum, error):
# Note that we assume the contents of [] to be short enough that
# Note that we assume the contents of [] to be short enough that
# they'll never need to wrap.
# they'll never need to wrap.
if
(
# Ignore control structures.
if
(
# Ignore control structures.
not
Search
(
r
'\b(if|for|while|switch|return|new|delete|catch|sizeof)\b'
,
not
Search
(
r
'\b(if|for|while|switch|return|new|delete|catch|sizeof)\b'
,
fncall
)
and
fncall
)
and
# Ignore pointers/references to functions.
# Ignore pointers/references to functions.
not
Search
(
r
' \([^)]+\)\([^)]*(\)|,$)'
,
fncall
)
and
not
Search
(
r
' \([^)]+\)\([^)]*(\)|,$)'
,
fncall
)
and
...
@@ -2844,12 +2862,12 @@ def CheckForNamespaceIndentation(filename, nesting_state, clean_lines, line,
...
@@ -2844,12 +2862,12 @@ def CheckForNamespaceIndentation(filename, nesting_state, clean_lines, line,
if
ShouldCheckNamespaceIndentation
(
nesting_state
,
is_namespace_indent_item
,
if
ShouldCheckNamespaceIndentation
(
nesting_state
,
is_namespace_indent_item
,
clean_lines
.
elided
,
line
):
clean_lines
.
elided
,
line
):
CheckItemIndentationInNamespace
(
filename
,
clean_lines
.
elided
,
CheckItemIndentationInNamespace
(
filename
,
clean_lines
.
elided
,
line
,
line
,
error
)
error
)
def
CheckForFunctionLengths
(
filename
,
clean_lines
,
linenum
,
def
CheckForFunctionLengths
(
filename
,
clean_lines
,
linenum
,
function_state
,
function_state
,
error
):
error
):
"""Reports for long function bodies.
"""Reports for long function bodies.
For an overview why this is done, see:
For an overview why this is done, see:
...
@@ -2891,7 +2909,8 @@ def CheckForFunctionLengths(filename, clean_lines, linenum,
...
@@ -2891,7 +2909,8 @@ def CheckForFunctionLengths(filename, clean_lines, linenum,
for
start_linenum
in
xrange
(
linenum
,
clean_lines
.
NumLines
()):
for
start_linenum
in
xrange
(
linenum
,
clean_lines
.
NumLines
()):
start_line
=
lines
[
start_linenum
]
start_line
=
lines
[
start_linenum
]
joined_line
+=
' '
+
start_line
.
lstrip
()
joined_line
+=
' '
+
start_line
.
lstrip
()
if
Search
(
r
'(;|})'
,
start_line
):
# Declarations and trivial functions
if
Search
(
r
'(;|})'
,
start_line
):
# Declarations and trivial functions
body_found
=
True
body_found
=
True
break
# ... ignore
break
# ... ignore
elif
Search
(
r
'{'
,
start_line
):
elif
Search
(
r
'{'
,
start_line
):
...
@@ -2933,14 +2952,14 @@ def CheckComment(line, filename, linenum, next_line_start, error):
...
@@ -2933,14 +2952,14 @@ def CheckComment(line, filename, linenum, next_line_start, error):
if
commentpos
!=
-
1
:
if
commentpos
!=
-
1
:
# Check if the // may be in quotes. If so, ignore it
# Check if the // may be in quotes. If so, ignore it
# Comparisons made explicit for clarity -- pylint: disable=g-explicit-bool-comparison
# Comparisons made explicit for clarity -- pylint: disable=g-explicit-bool-comparison
if
(
line
.
count
(
'"'
,
0
,
commentpos
)
-
if
(
line
.
count
(
'"'
,
0
,
commentpos
)
-
line
.
count
(
'
\\
"'
,
0
,
commentpos
)
line
.
count
(
'
\\
"'
,
0
,
commentpos
))
%
2
==
0
:
# not in quotes
)
%
2
==
0
:
# not in quotes
# Allow one space for new scopes, two spaces otherwise:
# Allow one space for new scopes, two spaces otherwise:
if
(
not
(
Match
(
r
'^.*{ *//'
,
line
)
and
next_line_start
==
commentpos
)
and
if
(
not
(
Match
(
r
'^.*{ *//'
,
line
)
and
next_line_start
==
commentpos
)
((
commentpos
>=
1
and
and
((
commentpos
>=
1
and
line
[
commentpos
-
1
]
not
in
string
.
whitespace
)
or
line
[
commentpos
-
1
]
not
in
string
.
whitespace
)
or
(
commentpos
>=
2
and
(
commentpos
>=
2
and
line
[
commentpos
-
2
]
not
in
string
.
whitespace
))):
line
[
commentpos
-
2
]
not
in
string
.
whitespace
))):
error
(
filename
,
linenum
,
'whitespace/comments'
,
2
,
error
(
filename
,
linenum
,
'whitespace/comments'
,
2
,
'At least two spaces is best between code and comments'
)
'At least two spaces is best between code and comments'
)
...
@@ -3044,8 +3063,7 @@ def CheckSpacing(filename, clean_lines, linenum, nesting_state, error):
...
@@ -3044,8 +3063,7 @@ def CheckSpacing(filename, clean_lines, linenum, nesting_state, error):
#
#
# Also skip blank line checks for 'extern "C"' blocks, which are formatted
# Also skip blank line checks for 'extern "C"' blocks, which are formatted
# like namespaces.
# like namespaces.
if
(
IsBlankLine
(
line
)
and
if
(
IsBlankLine
(
line
)
and
not
nesting_state
.
InNamespaceBody
()
and
not
nesting_state
.
InNamespaceBody
()
and
not
nesting_state
.
InExternC
()):
not
nesting_state
.
InExternC
()):
elided
=
clean_lines
.
elided
elided
=
clean_lines
.
elided
prev_line
=
elided
[
linenum
-
1
]
prev_line
=
elided
[
linenum
-
1
]
...
@@ -3066,12 +3084,12 @@ def CheckSpacing(filename, clean_lines, linenum, nesting_state, error):
...
@@ -3066,12 +3084,12 @@ def CheckSpacing(filename, clean_lines, linenum, nesting_state, error):
if
Match
(
r
' {6}\w'
,
prev_line
):
# Initializer list?
if
Match
(
r
' {6}\w'
,
prev_line
):
# Initializer list?
# We are looking for the opening column of initializer list, which
# We are looking for the opening column of initializer list, which
# should be indented 4 spaces to cause 6 space indentation afterwards.
# should be indented 4 spaces to cause 6 space indentation afterwards.
search_position
=
linenum
-
2
search_position
=
linenum
-
2
while
(
search_position
>=
0
while
(
search_position
>=
0
and
and
Match
(
r
' {6}\w'
,
elided
[
search_position
])):
Match
(
r
' {6}\w'
,
elided
[
search_position
])):
search_position
-=
1
search_position
-=
1
exception
=
(
search_position
>=
0
exception
=
(
search_position
>=
0
and
and
elided
[
search_position
][:
5
]
==
' :'
)
elided
[
search_position
][:
5
]
==
' :'
)
else
:
else
:
# Search for the function arguments or an initializer list. We use a
# Search for the function arguments or an initializer list. We use a
# simple heuristic here: If the line is indented 4 spaces; and we have a
# simple heuristic here: If the line is indented 4 spaces; and we have a
...
@@ -3080,8 +3098,7 @@ def CheckSpacing(filename, clean_lines, linenum, nesting_state, error):
...
@@ -3080,8 +3098,7 @@ def CheckSpacing(filename, clean_lines, linenum, nesting_state, error):
# a function header. If we have a colon indented 4 spaces, it is an
# a function header. If we have a colon indented 4 spaces, it is an
# initializer list.
# initializer list.
exception
=
(
Match
(
r
' {4}\w[^\(]*\)\s*(const\s*)?(\{\s*$|:)'
,
exception
=
(
Match
(
r
' {4}\w[^\(]*\)\s*(const\s*)?(\{\s*$|:)'
,
prev_line
)
prev_line
)
or
Match
(
r
' {4}:'
,
prev_line
))
or
Match
(
r
' {4}:'
,
prev_line
))
if
not
exception
:
if
not
exception
:
error
(
filename
,
linenum
,
'whitespace/blank_line'
,
2
,
error
(
filename
,
linenum
,
'whitespace/blank_line'
,
2
,
...
@@ -3097,9 +3114,8 @@ def CheckSpacing(filename, clean_lines, linenum, nesting_state, error):
...
@@ -3097,9 +3114,8 @@ def CheckSpacing(filename, clean_lines, linenum, nesting_state, error):
# }
# }
if
linenum
+
1
<
clean_lines
.
NumLines
():
if
linenum
+
1
<
clean_lines
.
NumLines
():
next_line
=
raw
[
linenum
+
1
]
next_line
=
raw
[
linenum
+
1
]
if
(
next_line
if
(
next_line
and
Match
(
r
'\s*}'
,
next_line
)
and
and
Match
(
r
'\s*}'
,
next_line
)
next_line
.
find
(
'} else '
)
==
-
1
):
and
next_line
.
find
(
'} else '
)
==
-
1
):
error
(
filename
,
linenum
,
'whitespace/blank_line'
,
3
,
error
(
filename
,
linenum
,
'whitespace/blank_line'
,
3
,
'Redundant blank line at the end of a code block '
'Redundant blank line at the end of a code block '
'should be deleted.'
)
'should be deleted.'
)
...
@@ -3122,8 +3138,7 @@ def CheckSpacing(filename, clean_lines, linenum, nesting_state, error):
...
@@ -3122,8 +3138,7 @@ def CheckSpacing(filename, clean_lines, linenum, nesting_state, error):
# You shouldn't have spaces before your brackets, except maybe after
# You shouldn't have spaces before your brackets, except maybe after
# 'delete []' or 'return []() {};'
# 'delete []' or 'return []() {};'
if
Search
(
r
'\w\s+\['
,
line
)
and
not
Search
(
r
'(?:delete|return)\s+\['
,
line
):
if
Search
(
r
'\w\s+\['
,
line
)
and
not
Search
(
r
'(?:delete|return)\s+\['
,
line
):
error
(
filename
,
linenum
,
'whitespace/braces'
,
5
,
error
(
filename
,
linenum
,
'whitespace/braces'
,
5
,
'Extra space before ['
)
'Extra space before ['
)
# In range-based for, we wanted spaces before and after the colon, but
# In range-based for, we wanted spaces before and after the colon, but
# not around "::" tokens that might appear.
# not around "::" tokens that might appear.
...
@@ -3162,11 +3177,11 @@ def CheckOperatorSpacing(filename, clean_lines, linenum, error):
...
@@ -3162,11 +3177,11 @@ def CheckOperatorSpacing(filename, clean_lines, linenum, error):
# sometimes people put non-spaces on one side when aligning ='s among
# sometimes people put non-spaces on one side when aligning ='s among
# many lines (not that this is behavior that I approve of...)
# many lines (not that this is behavior that I approve of...)
if
((
Search
(
r
'[\w.]='
,
line
)
or
if
((
Search
(
r
'[\w.]='
,
line
)
or
Search
(
r
'=[\w.]'
,
line
))
Search
(
r
'=[\w.]'
,
line
))
and
not
Search
(
r
'\b(if|while|for) '
,
line
)
and
not
Search
(
r
'\b(if|while|for) '
,
line
)
# Operators taken from [lex.operators] in C++11 standard.
# Operators taken from [lex.operators] in C++11 standard.
and
not
Search
(
r
'(>=|<=|==|!=|&=|\^=|\|=|\+=|\*=|\/=|\%=)'
,
line
)
and
and
not
Search
(
r
'operator='
,
line
)):
not
Search
(
r
'(>=|<=|==|!=|&=|\^=|\|=|\+=|\*=|\/=|\%=)'
,
line
)
and
not
Search
(
r
'operator='
,
line
)):
error
(
filename
,
linenum
,
'whitespace/operators'
,
4
,
error
(
filename
,
linenum
,
'whitespace/operators'
,
4
,
'Missing spaces around ='
)
'Missing spaces around ='
)
...
@@ -3196,8 +3211,8 @@ def CheckOperatorSpacing(filename, clean_lines, linenum, error):
...
@@ -3196,8 +3211,8 @@ def CheckOperatorSpacing(filename, clean_lines, linenum, error):
# space. This is done to avoid some false positives with shifts.
# space. This is done to avoid some false positives with shifts.
match
=
Match
(
r
'^(.*[^\s<])<[^\s=<,]'
,
line
)
match
=
Match
(
r
'^(.*[^\s<])<[^\s=<,]'
,
line
)
if
match
:
if
match
:
(
_
,
_
,
end_pos
)
=
CloseExpression
(
(
_
,
_
,
end_pos
)
=
CloseExpression
(
clean_lines
,
linenum
,
clean_lines
,
linenum
,
len
(
match
.
group
(
1
)))
len
(
match
.
group
(
1
)))
if
end_pos
<=
-
1
:
if
end_pos
<=
-
1
:
error
(
filename
,
linenum
,
'whitespace/operators'
,
3
,
error
(
filename
,
linenum
,
'whitespace/operators'
,
3
,
'Missing spaces around <'
)
'Missing spaces around <'
)
...
@@ -3207,8 +3222,8 @@ def CheckOperatorSpacing(filename, clean_lines, linenum, error):
...
@@ -3207,8 +3222,8 @@ def CheckOperatorSpacing(filename, clean_lines, linenum, error):
# false positives with shifts.
# false positives with shifts.
match
=
Match
(
r
'^(.*[^-\s>])>[^\s=>,]'
,
line
)
match
=
Match
(
r
'^(.*[^-\s>])>[^\s=>,]'
,
line
)
if
match
:
if
match
:
(
_
,
_
,
start_pos
)
=
ReverseCloseExpression
(
(
_
,
_
,
start_pos
)
=
ReverseCloseExpression
(
clean_lines
,
linenum
,
clean_lines
,
linenum
,
len
(
match
.
group
(
1
)))
len
(
match
.
group
(
1
)))
if
start_pos
<=
-
1
:
if
start_pos
<=
-
1
:
error
(
filename
,
linenum
,
'whitespace/operators'
,
3
,
error
(
filename
,
linenum
,
'whitespace/operators'
,
3
,
'Missing spaces around >'
)
'Missing spaces around >'
)
...
@@ -3218,8 +3233,10 @@ def CheckOperatorSpacing(filename, clean_lines, linenum, error):
...
@@ -3218,8 +3233,10 @@ def CheckOperatorSpacing(filename, clean_lines, linenum, error):
#
#
# We also allow operators following an opening parenthesis, since
# We also allow operators following an opening parenthesis, since
# those tend to be macros that deal with operators.
# those tend to be macros that deal with operators.
match
=
Search
(
r
'(operator|[^\s(<])(?:L|UL|ULL|l|ul|ull)?<<([^\s,=<])'
,
line
)
match
=
Search
(
r
'(operator|[^\s(<])(?:L|UL|ULL|l|ul|ull)?<<([^\s,=<])'
,
if
(
match
and
not
(
match
.
group
(
1
).
isdigit
()
and
match
.
group
(
2
).
isdigit
())
and
line
)
if
(
match
and
not
(
match
.
group
(
1
).
isdigit
()
and
match
.
group
(
2
).
isdigit
())
and
not
(
match
.
group
(
1
)
==
'operator'
and
match
.
group
(
2
)
==
';'
)):
not
(
match
.
group
(
1
)
==
'operator'
and
match
.
group
(
2
)
==
';'
)):
error
(
filename
,
linenum
,
'whitespace/operators'
,
3
,
error
(
filename
,
linenum
,
'whitespace/operators'
,
3
,
'Missing spaces around <<'
)
'Missing spaces around <<'
)
...
@@ -3271,8 +3288,7 @@ def CheckParenthesisSpacing(filename, clean_lines, linenum, error):
...
@@ -3271,8 +3288,7 @@ def CheckParenthesisSpacing(filename, clean_lines, linenum, error):
# We don't want: "if ( foo)" or "if ( foo )".
# We don't want: "if ( foo)" or "if ( foo )".
# Exception: "for ( ; foo; bar)" and "for (foo; bar; )" are allowed.
# Exception: "for ( ; foo; bar)" and "for (foo; bar; )" are allowed.
match
=
Search
(
r
'\b(if|for|while|switch)\s*'
match
=
Search
(
r
'\b(if|for|while|switch)\s*'
r
'\(([ ]*)(.).*[^ ]+([ ]*)\)\s*{\s*$'
,
r
'\(([ ]*)(.).*[^ ]+([ ]*)\)\s*{\s*$'
,
line
)
line
)
if
match
:
if
match
:
if
len
(
match
.
group
(
2
))
!=
len
(
match
.
group
(
4
)):
if
len
(
match
.
group
(
2
))
!=
len
(
match
.
group
(
4
)):
if
not
(
match
.
group
(
3
)
==
';'
and
if
not
(
match
.
group
(
3
)
==
';'
and
...
@@ -3310,8 +3326,7 @@ def CheckCommaSpacing(filename, clean_lines, linenum, error):
...
@@ -3310,8 +3326,7 @@ def CheckCommaSpacing(filename, clean_lines, linenum, error):
# elided comments.
# elided comments.
if
(
Search
(
r
',[^,\s]'
,
ReplaceAll
(
r
'\boperator\s*,\s*\('
,
'F('
,
line
))
and
if
(
Search
(
r
',[^,\s]'
,
ReplaceAll
(
r
'\boperator\s*,\s*\('
,
'F('
,
line
))
and
Search
(
r
',[^,\s]'
,
raw
[
linenum
])):
Search
(
r
',[^,\s]'
,
raw
[
linenum
])):
error
(
filename
,
linenum
,
'whitespace/comma'
,
3
,
error
(
filename
,
linenum
,
'whitespace/comma'
,
3
,
'Missing space after ,'
)
'Missing space after ,'
)
# You should always have a space after a semicolon
# You should always have a space after a semicolon
# except for few corner cases
# except for few corner cases
...
@@ -3367,8 +3382,8 @@ def CheckBracesSpacing(filename, clean_lines, linenum, error):
...
@@ -3367,8 +3382,8 @@ def CheckBracesSpacing(filename, clean_lines, linenum, error):
# There is a false negative with this approach if people inserted
# There is a false negative with this approach if people inserted
# spurious semicolons, e.g. "if (cond){};", but we will catch the
# spurious semicolons, e.g. "if (cond){};", but we will catch the
# spurious semicolon with a separate check.
# spurious semicolon with a separate check.
(
endline
,
endlinenum
,
endpos
)
=
CloseExpression
(
(
endline
,
endlinenum
,
endpos
)
=
CloseExpression
(
clean_lines
,
linenum
,
clean_lines
,
linenum
,
len
(
match
.
group
(
1
)))
len
(
match
.
group
(
1
)))
trailing_text
=
''
trailing_text
=
''
if
endpos
>
-
1
:
if
endpos
>
-
1
:
trailing_text
=
endline
[
endpos
:]
trailing_text
=
endline
[
endpos
:]
...
@@ -3391,11 +3406,11 @@ def CheckBracesSpacing(filename, clean_lines, linenum, error):
...
@@ -3391,11 +3406,11 @@ def CheckBracesSpacing(filename, clean_lines, linenum, error):
error
(
filename
,
linenum
,
'whitespace/semicolon'
,
5
,
error
(
filename
,
linenum
,
'whitespace/semicolon'
,
5
,
'Semicolon defining empty statement. Use {} instead.'
)
'Semicolon defining empty statement. Use {} instead.'
)
elif
Search
(
r
'^\s*;\s*$'
,
line
):
elif
Search
(
r
'^\s*;\s*$'
,
line
):
error
(
filename
,
linenum
,
'whitespace/semicolon'
,
5
,
error
(
filename
,
linenum
,
'whitespace/semicolon'
,
5
,
'Line contains only semicolon. If this should be an empty statement, '
'Line contains only semicolon. If this should be an empty statement, '
'use {} instead.'
)
'use {} instead.'
)
elif
(
Search
(
r
'\s+;\s*$'
,
line
)
and
elif
(
Search
(
r
'\s+;\s*$'
,
line
)
and
not
Search
(
r
'\bfor\b'
,
line
)):
not
Search
(
r
'\bfor\b'
,
line
)):
error
(
filename
,
linenum
,
'whitespace/semicolon'
,
5
,
error
(
filename
,
linenum
,
'whitespace/semicolon'
,
5
,
'Extra space before last semicolon. If this should be an empty '
'Extra space before last semicolon. If this should be an empty '
'statement, use {} instead.'
)
'statement, use {} instead.'
)
...
@@ -3429,10 +3444,10 @@ def IsTemplateParameterList(clean_lines, linenum, column):
...
@@ -3429,10 +3444,10 @@ def IsTemplateParameterList(clean_lines, linenum, column):
Returns:
Returns:
True if this token is end of a template parameter list, False otherwise.
True if this token is end of a template parameter list, False otherwise.
"""
"""
(
_
,
startline
,
startpos
)
=
ReverseCloseExpression
(
(
_
,
startline
,
startpos
)
=
ReverseCloseExpression
(
clean_lines
,
linenum
,
clean_lines
,
linenum
,
column
)
column
)
if
(
startpos
>
-
1
and
if
(
startpos
>
-
1
and
Search
(
r
'\btemplate\s*$'
,
Search
(
r
'\btemplate\s*$'
,
clean_lines
.
elided
[
startline
][
0
:
startpos
])):
clean_lines
.
elided
[
startline
][
0
:
startpos
])):
return
True
return
True
return
False
return
False
...
@@ -3476,18 +3491,19 @@ def IsRValueType(typenames, clean_lines, nesting_state, linenum, column):
...
@@ -3476,18 +3491,19 @@ def IsRValueType(typenames, clean_lines, nesting_state, linenum, column):
# recognize pointer and reference types:
# recognize pointer and reference types:
# int* Function()
# int* Function()
# int& Function()
# int& Function()
if
(
match
.
group
(
2
)
in
typenames
or
if
(
match
.
group
(
2
)
in
typenames
or
match
.
group
(
2
)
in
[
match
.
group
(
2
)
in
[
'char'
,
'char16_t'
,
'char32_t'
,
'wchar_t'
,
'bool'
,
'char'
,
'char16_t'
,
'char32_t'
,
'wchar_t'
,
'bool'
,
'short'
,
'int'
,
'short'
,
'int'
,
'long'
,
'signed'
,
'unsigned'
,
'long'
,
'signed'
,
'unsigned'
,
'float'
,
'double'
,
'void'
,
'auto'
,
'float'
,
'double'
,
'void'
,
'auto'
,
'>'
,
'*'
,
'&'
]):
'>'
,
'*'
,
'&'
]):
return
True
return
True
# If we see a close parenthesis, look for decltype on the other side.
# If we see a close parenthesis, look for decltype on the other side.
# decltype would unambiguously identify a type, anything else is
# decltype would unambiguously identify a type, anything else is
# probably a parenthesized expression and not a type.
# probably a parenthesized expression and not a type.
if
match
.
group
(
2
)
==
')'
:
if
match
.
group
(
2
)
==
')'
:
return
IsDecltype
(
return
IsDecltype
(
clean_lines
,
linenum
,
clean_lines
,
linenum
,
len
(
match
.
group
(
1
))
+
len
(
match
.
group
(
2
))
-
1
)
len
(
match
.
group
(
1
))
+
len
(
match
.
group
(
2
))
-
1
)
# Check for casts and cv-qualifiers.
# Check for casts and cv-qualifiers.
# match.group(1) remainder
# match.group(1) remainder
...
@@ -3496,8 +3512,7 @@ def IsRValueType(typenames, clean_lines, nesting_state, linenum, column):
...
@@ -3496,8 +3512,7 @@ def IsRValueType(typenames, clean_lines, nesting_state, linenum, column):
# const type&&
# const type&&
# type const&&
# type const&&
if
Search
(
r
'\b(?:const_cast\s*<|static_cast\s*<|dynamic_cast\s*<|'
if
Search
(
r
'\b(?:const_cast\s*<|static_cast\s*<|dynamic_cast\s*<|'
r
'reinterpret_cast\s*<|\w+\s)\s*$'
,
r
'reinterpret_cast\s*<|\w+\s)\s*$'
,
match
.
group
(
1
)):
match
.
group
(
1
)):
return
True
return
True
# Look for a preceding symbol that might help differentiate the context.
# Look for a preceding symbol that might help differentiate the context.
...
@@ -3594,7 +3609,8 @@ def IsRValueType(typenames, clean_lines, nesting_state, linenum, column):
...
@@ -3594,7 +3609,8 @@ def IsRValueType(typenames, clean_lines, nesting_state, linenum, column):
# sizeof(type&&
# sizeof(type&&
# operator=(type&&
# operator=(type&&
#
#
if
Search
(
r
'(?:\]|\bfor|\bsizeof|\boperator\s*\S+\s*)\s*$'
,
before_text
):
if
Search
(
r
'(?:\]|\bfor|\bsizeof|\boperator\s*\S+\s*)\s*$'
,
before_text
):
return
True
return
True
# Patterns that are likely to be expressions:
# Patterns that are likely to be expressions:
...
@@ -3618,9 +3634,10 @@ def IsRValueType(typenames, clean_lines, nesting_state, linenum, column):
...
@@ -3618,9 +3634,10 @@ def IsRValueType(typenames, clean_lines, nesting_state, linenum, column):
# Check for constructors, which don't have return types.
# Check for constructors, which don't have return types.
if
Search
(
r
'\b(?:explicit|inline)$'
,
match_func
.
group
(
1
)):
if
Search
(
r
'\b(?:explicit|inline)$'
,
match_func
.
group
(
1
)):
return
True
return
True
implicit_constructor
=
Match
(
r
'\s*(\w+)\((?:const\s+)?(\w+)'
,
prefix
)
implicit_constructor
=
Match
(
r
'\s*(\w+)\((?:const\s+)?(\w+)'
,
if
(
implicit_constructor
and
prefix
)
implicit_constructor
.
group
(
1
)
==
implicit_constructor
.
group
(
2
)):
if
(
implicit_constructor
and
implicit_constructor
.
group
(
1
)
==
implicit_constructor
.
group
(
2
)):
return
True
return
True
return
IsRValueType
(
typenames
,
clean_lines
,
nesting_state
,
linenum
,
return
IsRValueType
(
typenames
,
clean_lines
,
nesting_state
,
linenum
,
len
(
match_func
.
group
(
1
)))
len
(
match_func
.
group
(
1
)))
...
@@ -3633,8 +3650,8 @@ def IsRValueType(typenames, clean_lines, nesting_state, linenum, column):
...
@@ -3633,8 +3650,8 @@ def IsRValueType(typenames, clean_lines, nesting_state, linenum, column):
if
match_symbol
.
group
(
2
)
==
'>'
:
if
match_symbol
.
group
(
2
)
==
'>'
:
# Possibly a closing bracket, check that what's on the other side
# Possibly a closing bracket, check that what's on the other side
# looks like the start of a template.
# looks like the start of a template.
return
IsTemplateParameterList
(
return
IsTemplateParameterList
(
clean_lines
,
start
,
clean_lines
,
start
,
len
(
match_symbol
.
group
(
1
)))
len
(
match_symbol
.
group
(
1
)))
# Some other symbol, usually something like "a=b&&c". This is most
# Some other symbol, usually something like "a=b&&c". This is most
# likely not a type.
# likely not a type.
...
@@ -3653,8 +3670,8 @@ def IsDeletedOrDefault(clean_lines, linenum):
...
@@ -3653,8 +3670,8 @@ def IsDeletedOrDefault(clean_lines, linenum):
open_paren
=
clean_lines
.
elided
[
linenum
].
find
(
'('
)
open_paren
=
clean_lines
.
elided
[
linenum
].
find
(
'('
)
if
open_paren
<
0
:
if
open_paren
<
0
:
return
False
return
False
(
close_line
,
_
,
close_paren
)
=
CloseExpression
(
(
close_line
,
_
,
close_paren
)
=
CloseExpression
(
clean_lines
,
linenum
,
clean_lines
,
linenum
,
open_paren
)
open_paren
)
if
close_paren
<
0
:
if
close_paren
<
0
:
return
False
return
False
return
Match
(
r
'\s*=\s*(?:delete|default)\b'
,
close_line
[
close_paren
:])
return
Match
(
r
'\s*=\s*(?:delete|default)\b'
,
close_line
[
close_paren
:])
...
@@ -3697,7 +3714,8 @@ def IsRValueAllowed(clean_lines, linenum, typenames):
...
@@ -3697,7 +3714,8 @@ def IsRValueAllowed(clean_lines, linenum, typenames):
previous_line
=
'ReturnType'
previous_line
=
'ReturnType'
if
linenum
>
0
:
if
linenum
>
0
:
previous_line
=
clean_lines
.
elided
[
linenum
-
1
]
previous_line
=
clean_lines
.
elided
[
linenum
-
1
]
if
Match
(
r
'^\s*$'
,
previous_line
)
or
Search
(
r
'[{}:;]\s*$'
,
previous_line
):
if
Match
(
r
'^\s*$'
,
previous_line
)
or
Search
(
r
'[{}:;]\s*$'
,
previous_line
):
return
IsDeletedOrDefault
(
clean_lines
,
linenum
)
return
IsDeletedOrDefault
(
clean_lines
,
linenum
)
# Reject types not mentioned in template-argument-list
# Reject types not mentioned in template-argument-list
...
@@ -3747,7 +3765,8 @@ def GetTemplateArgs(clean_lines, linenum):
...
@@ -3747,7 +3765,8 @@ def GetTemplateArgs(clean_lines, linenum):
if
match
:
if
match
:
# template-argument-list on the same line as function name
# template-argument-list on the same line as function name
start_col
=
len
(
match
.
group
(
1
))
start_col
=
len
(
match
.
group
(
1
))
_
,
end_line
,
end_col
=
CloseExpression
(
clean_lines
,
func_line
,
start_col
)
_
,
end_line
,
end_col
=
CloseExpression
(
clean_lines
,
func_line
,
start_col
)
if
end_col
>
-
1
and
end_line
==
func_line
:
if
end_col
>
-
1
and
end_line
==
func_line
:
start_col
+=
1
# Skip the opening bracket
start_col
+=
1
# Skip the opening bracket
argument_list
=
clean_lines
.
elided
[
func_line
][
start_col
:
end_col
]
argument_list
=
clean_lines
.
elided
[
func_line
][
start_col
:
end_col
]
...
@@ -3765,7 +3784,8 @@ def GetTemplateArgs(clean_lines, linenum):
...
@@ -3765,7 +3784,8 @@ def GetTemplateArgs(clean_lines, linenum):
argument_list
+=
clean_lines
.
elided
[
start_line
][
start_col
:]
argument_list
+=
clean_lines
.
elided
[
start_line
][
start_col
:]
start_col
=
0
start_col
=
0
start_line
+=
1
start_line
+=
1
argument_list
+=
clean_lines
.
elided
[
func_line
-
1
][
start_col
:
end_col
]
argument_list
+=
clean_lines
.
elided
[
func_line
-
1
][
start_col
:
end_col
]
if
not
argument_list
:
if
not
argument_list
:
return
set
()
return
set
()
...
@@ -3801,7 +3821,8 @@ def CheckRValueReference(filename, clean_lines, linenum, nesting_state, error):
...
@@ -3801,7 +3821,8 @@ def CheckRValueReference(filename, clean_lines, linenum, nesting_state, error):
match
=
Match
(
r
'^(.*\S)&&'
,
line
)
match
=
Match
(
r
'^(.*\S)&&'
,
line
)
if
not
match
:
if
not
match
:
match
=
Match
(
r
'(.*)&&\S'
,
line
)
match
=
Match
(
r
'(.*)&&\S'
,
line
)
if
(
not
match
)
or
'(&&)'
in
line
or
Search
(
r
'\boperator\s*$'
,
match
.
group
(
1
)):
if
(
not
match
)
or
'(&&)'
in
line
or
Search
(
r
'\boperator\s*$'
,
match
.
group
(
1
)):
return
return
# Either poorly formed && or an rvalue reference, check the context
# Either poorly formed && or an rvalue reference, check the context
...
@@ -3845,7 +3866,8 @@ def CheckSectionSpacing(filename, clean_lines, class_info, linenum, error):
...
@@ -3845,7 +3866,8 @@ def CheckSectionSpacing(filename, clean_lines, class_info, linenum, error):
linenum
<=
class_info
.
starting_linenum
):
linenum
<=
class_info
.
starting_linenum
):
return
return
matched
=
Match
(
r
'\s*(public|protected|private):'
,
clean_lines
.
lines
[
linenum
])
matched
=
Match
(
r
'\s*(public|protected|private):'
,
clean_lines
.
lines
[
linenum
])
if
matched
:
if
matched
:
# Issue warning if the line before public/protected/private was
# Issue warning if the line before public/protected/private was
# not a blank line, but don't do this if the previous line contains
# not a blank line, but don't do this if the previous line contains
...
@@ -3870,7 +3892,8 @@ def CheckSectionSpacing(filename, clean_lines, class_info, linenum, error):
...
@@ -3870,7 +3892,8 @@ def CheckSectionSpacing(filename, clean_lines, class_info, linenum, error):
break
break
if
end_class_head
<
linenum
-
1
:
if
end_class_head
<
linenum
-
1
:
error
(
filename
,
linenum
,
'whitespace/blank_line'
,
3
,
error
(
filename
,
linenum
,
'whitespace/blank_line'
,
3
,
'"%s:" should be preceded by a blank line'
%
matched
.
group
(
1
))
'"%s:" should be preceded by a blank line'
%
matched
.
group
(
1
))
def
GetPreviousNonBlankLine
(
clean_lines
,
linenum
):
def
GetPreviousNonBlankLine
(
clean_lines
,
linenum
):
...
@@ -3940,8 +3963,10 @@ def CheckBraces(filename, clean_lines, linenum, error):
...
@@ -3940,8 +3963,10 @@ def CheckBraces(filename, clean_lines, linenum, error):
(
endline
,
_
,
endpos
)
=
CloseExpression
(
clean_lines
,
linenum
,
pos
)
(
endline
,
_
,
endpos
)
=
CloseExpression
(
clean_lines
,
linenum
,
pos
)
brace_on_right
=
endline
[
endpos
:].
find
(
'{'
)
!=
-
1
brace_on_right
=
endline
[
endpos
:].
find
(
'{'
)
!=
-
1
if
brace_on_left
!=
brace_on_right
:
# must be brace after if
if
brace_on_left
!=
brace_on_right
:
# must be brace after if
error
(
filename
,
linenum
,
'readability/braces'
,
5
,
error
(
'If an else has a brace on one side, it should have it on both'
)
filename
,
linenum
,
'readability/braces'
,
5
,
'If an else has a brace on one side, it should have it on both'
)
elif
Search
(
r
'}\s*else[^{]*$'
,
line
)
or
Match
(
r
'[^}]*else\s*{'
,
line
):
elif
Search
(
r
'}\s*else[^{]*$'
,
line
)
or
Match
(
r
'[^}]*else\s*{'
,
line
):
error
(
filename
,
linenum
,
'readability/braces'
,
5
,
error
(
filename
,
linenum
,
'readability/braces'
,
5
,
'If an else has a brace on one side, it should have it on both'
)
'If an else has a brace on one side, it should have it on both'
)
...
@@ -3971,15 +3996,16 @@ def CheckBraces(filename, clean_lines, linenum, error):
...
@@ -3971,15 +3996,16 @@ def CheckBraces(filename, clean_lines, linenum, error):
if
if_match
:
if
if_match
:
# This could be a multiline if condition, so find the end first.
# This could be a multiline if condition, so find the end first.
pos
=
if_match
.
end
()
-
1
pos
=
if_match
.
end
()
-
1
(
endline
,
endlinenum
,
endpos
)
=
CloseExpression
(
clean_lines
,
linenum
,
pos
)
(
endline
,
endlinenum
,
endpos
)
=
CloseExpression
(
clean_lines
,
linenum
,
pos
)
# Check for an opening brace, either directly after the if or on the next
# Check for an opening brace, either directly after the if or on the next
# line. If found, this isn't a single-statement conditional.
# line. If found, this isn't a single-statement conditional.
if
(
not
Match
(
r
'\s*{'
,
endline
[
endpos
:])
if
(
not
Match
(
r
'\s*{'
,
endline
[
endpos
:])
and
and
not
(
Match
(
r
'\s*$'
,
endline
[
endpos
:])
not
(
Match
(
r
'\s*$'
,
endline
[
endpos
:])
and
endlinenum
<
and
endlinenum
<
(
len
(
clean_lines
.
elided
)
-
1
)
(
len
(
clean_lines
.
elided
)
-
1
)
and
and
Match
(
r
'\s*{'
,
clean_lines
.
elided
[
endlinenum
+
1
]))):
Match
(
r
'\s*{'
,
clean_lines
.
elided
[
endlinenum
+
1
]))):
while
(
endlinenum
<
len
(
clean_lines
.
elided
)
while
(
endlinenum
<
len
(
clean_lines
.
elided
)
and
and
';'
not
in
clean_lines
.
elided
[
endlinenum
][
endpos
:]):
';'
not
in
clean_lines
.
elided
[
endlinenum
][
endpos
:]):
endlinenum
+=
1
endlinenum
+=
1
endpos
=
0
endpos
=
0
if
endlinenum
<
len
(
clean_lines
.
elided
):
if
endlinenum
<
len
(
clean_lines
.
elided
):
...
@@ -3991,10 +4017,13 @@ def CheckBraces(filename, clean_lines, linenum, error):
...
@@ -3991,10 +4017,13 @@ def CheckBraces(filename, clean_lines, linenum, error):
# Semicolon isn't the last character, there's something trailing.
# Semicolon isn't the last character, there's something trailing.
# Output a warning if the semicolon is not contained inside
# Output a warning if the semicolon is not contained inside
# a lambda expression.
# a lambda expression.
if
not
Match
(
r
'^[^{};]*\[[^\[\]]*\][^{}]*\{[^{}]*\}\s*\)*[;,]\s*$'
,
if
not
Match
(
r
'^[^{};]*\[[^\[\]]*\][^{}]*\{[^{}]*\}\s*\)*[;,]\s*$'
,
endline
):
endline
):
error
(
filename
,
linenum
,
'readability/braces'
,
4
,
error
(
'If/else bodies with multiple statements require braces'
)
filename
,
linenum
,
'readability/braces'
,
4
,
'If/else bodies with multiple statements require braces'
)
elif
endlinenum
<
len
(
clean_lines
.
elided
)
-
1
:
elif
endlinenum
<
len
(
clean_lines
.
elided
)
-
1
:
# Make sure the next line is dedented
# Make sure the next line is dedented
next_line
=
clean_lines
.
elided
[
endlinenum
+
1
]
next_line
=
clean_lines
.
elided
[
endlinenum
+
1
]
...
@@ -4002,14 +4031,17 @@ def CheckBraces(filename, clean_lines, linenum, error):
...
@@ -4002,14 +4031,17 @@ def CheckBraces(filename, clean_lines, linenum, error):
# With ambiguous nested if statements, this will error out on the
# With ambiguous nested if statements, this will error out on the
# if that *doesn't* match the else, regardless of whether it's the
# if that *doesn't* match the else, regardless of whether it's the
# inner one or outer one.
# inner one or outer one.
if
(
if_match
and
Match
(
r
'\s*else\b'
,
next_line
)
if
(
if_match
and
Match
(
r
'\s*else\b'
,
next_line
)
and
and
next_indent
!=
if_indent
):
next_indent
!=
if_indent
):
error
(
filename
,
linenum
,
'readability/braces'
,
4
,
error
(
filename
,
linenum
,
'readability/braces'
,
4
,
'Else clause should be indented at the same level as if. '
'Else clause should be indented at the same level as if. '
'Ambiguous nested if/else chains require braces.'
)
'Ambiguous nested if/else chains require braces.'
)
elif
next_indent
>
if_indent
:
elif
next_indent
>
if_indent
:
error
(
filename
,
linenum
,
'readability/braces'
,
4
,
error
(
'If/else bodies with multiple statements require braces'
)
filename
,
linenum
,
'readability/braces'
,
4
,
'If/else bodies with multiple statements require braces'
)
def
CheckTrailingSemicolon
(
filename
,
clean_lines
,
linenum
,
error
):
def
CheckTrailingSemicolon
(
filename
,
clean_lines
,
linenum
,
error
):
...
@@ -4096,24 +4128,22 @@ def CheckTrailingSemicolon(filename, clean_lines, linenum, error):
...
@@ -4096,24 +4128,22 @@ def CheckTrailingSemicolon(filename, clean_lines, linenum, error):
# - Lambdas
# - Lambdas
# - alignas specifier with anonymous structs:
# - alignas specifier with anonymous structs:
closing_brace_pos
=
match
.
group
(
1
).
rfind
(
')'
)
closing_brace_pos
=
match
.
group
(
1
).
rfind
(
')'
)
opening_parenthesis
=
ReverseCloseExpression
(
opening_parenthesis
=
ReverseCloseExpression
(
clean_lines
,
linenum
,
clean_lines
,
linenum
,
closing_brace_pos
)
closing_brace_pos
)
if
opening_parenthesis
[
2
]
>
-
1
:
if
opening_parenthesis
[
2
]
>
-
1
:
line_prefix
=
opening_parenthesis
[
0
][
0
:
opening_parenthesis
[
2
]]
line_prefix
=
opening_parenthesis
[
0
][
0
:
opening_parenthesis
[
2
]]
macro
=
Search
(
r
'\b([A-Z_]+)\s*$'
,
line_prefix
)
macro
=
Search
(
r
'\b([A-Z_]+)\s*$'
,
line_prefix
)
func
=
Match
(
r
'^(.*\])\s*$'
,
line_prefix
)
func
=
Match
(
r
'^(.*\])\s*$'
,
line_prefix
)
if
((
macro
and
if
((
macro
and
macro
.
group
(
1
)
not
in
macro
.
group
(
1
)
not
in
(
(
'TEST'
,
'TEST_F'
,
'MATCHER'
,
'MATCHER_P'
,
'TYPED_TEST'
,
'TEST'
,
'TEST_F'
,
'MATCHER'
,
'MATCHER_P'
,
'TYPED_TEST'
,
'EXCLUSIVE_LOCKS_REQUIRED'
,
'SHARED_LOCKS_REQUIRED'
,
'EXCLUSIVE_LOCKS_REQUIRED'
,
'SHARED_LOCKS_REQUIRED'
,
'LOCKS_EXCLUDED'
,
'INTERFACE_DEF'
))
or
'LOCKS_EXCLUDED'
,
'INTERFACE_DEF'
))
or
(
func
and
not
Search
(
r
'\boperator\s*\[\s*\]'
,
func
.
group
(
1
)))
or
(
func
and
not
Search
(
r
'\boperator\s*\[\s*\]'
,
func
.
group
(
1
)))
or
Search
(
r
'\b(?:struct|union)\s+alignas\s*$'
,
line_prefix
)
or
Search
(
r
'\b(?:struct|union)\s+alignas\s*$'
,
line_prefix
)
or
Search
(
r
'\s+=\s*$'
,
line_prefix
)):
Search
(
r
'\s+=\s*$'
,
line_prefix
)):
match
=
None
match
=
None
if
(
match
and
if
(
match
and
opening_parenthesis
[
1
]
>
1
and
Search
(
opening_parenthesis
[
1
]
>
1
and
r
'\]\s*$'
,
clean_lines
.
elided
[
opening_parenthesis
[
1
]
-
1
])):
Search
(
r
'\]\s*$'
,
clean_lines
.
elided
[
opening_parenthesis
[
1
]
-
1
])):
# Multi-line lambda-expression
# Multi-line lambda-expression
match
=
None
match
=
None
...
@@ -4135,8 +4165,8 @@ def CheckTrailingSemicolon(filename, clean_lines, linenum, error):
...
@@ -4135,8 +4165,8 @@ def CheckTrailingSemicolon(filename, clean_lines, linenum, error):
# Check matching closing brace
# Check matching closing brace
if
match
:
if
match
:
(
endline
,
endlinenum
,
endpos
)
=
CloseExpression
(
(
endline
,
endlinenum
,
endpos
)
=
CloseExpression
(
clean_lines
,
linenum
,
clean_lines
,
linenum
,
len
(
match
.
group
(
1
)))
len
(
match
.
group
(
1
)))
if
endpos
>
-
1
and
Match
(
r
'^\s*;'
,
endline
[
endpos
:]):
if
endpos
>
-
1
and
Match
(
r
'^\s*;'
,
endline
[
endpos
:]):
# Current {} pair is eligible for semicolon check, and we have found
# Current {} pair is eligible for semicolon check, and we have found
# the redundant semicolon, output warning here.
# the redundant semicolon, output warning here.
...
@@ -4169,15 +4199,16 @@ def CheckEmptyBlockBody(filename, clean_lines, linenum, error):
...
@@ -4169,15 +4199,16 @@ def CheckEmptyBlockBody(filename, clean_lines, linenum, error):
matched
=
Match
(
r
'\s*(for|while|if)\s*\('
,
line
)
matched
=
Match
(
r
'\s*(for|while|if)\s*\('
,
line
)
if
matched
:
if
matched
:
# Find the end of the conditional expression
# Find the end of the conditional expression
(
end_line
,
end_linenum
,
end_pos
)
=
CloseExpression
(
(
end_line
,
end_linenum
,
end_pos
)
=
CloseExpression
(
clean_lines
,
linenum
,
clean_lines
,
linenum
,
line
.
find
(
'('
))
line
.
find
(
'('
))
# Output warning if what follows the condition expression is a semicolon.
# Output warning if what follows the condition expression is a semicolon.
# No warning for all other cases, including whitespace or newline, since we
# No warning for all other cases, including whitespace or newline, since we
# have a separate check for semicolons preceded by whitespace.
# have a separate check for semicolons preceded by whitespace.
if
end_pos
>=
0
and
Match
(
r
';'
,
end_line
[
end_pos
:]):
if
end_pos
>=
0
and
Match
(
r
';'
,
end_line
[
end_pos
:]):
if
matched
.
group
(
1
)
==
'if'
:
if
matched
.
group
(
1
)
==
'if'
:
error
(
filename
,
end_linenum
,
'whitespace/empty_conditional_body'
,
5
,
error
(
filename
,
end_linenum
,
'whitespace/empty_conditional_body'
,
5
,
'Empty conditional bodies should use {}'
)
'Empty conditional bodies should use {}'
)
else
:
else
:
error
(
filename
,
end_linenum
,
'whitespace/empty_loop_body'
,
5
,
error
(
filename
,
end_linenum
,
'whitespace/empty_loop_body'
,
5
,
...
@@ -4224,8 +4255,8 @@ def CheckCheck(filename, clean_lines, linenum, error):
...
@@ -4224,8 +4255,8 @@ def CheckCheck(filename, clean_lines, linenum, error):
return
return
# Find end of the boolean expression by matching parentheses
# Find end of the boolean expression by matching parentheses
(
last_line
,
end_line
,
end_pos
)
=
CloseExpression
(
(
last_line
,
end_line
,
end_pos
)
=
CloseExpression
(
clean_lines
,
linenum
,
clean_lines
,
linenum
,
start_pos
)
start_pos
)
if
end_pos
<
0
:
if
end_pos
<
0
:
return
return
...
@@ -4320,9 +4351,9 @@ def CheckCheck(filename, clean_lines, linenum, error):
...
@@ -4320,9 +4351,9 @@ def CheckCheck(filename, clean_lines, linenum, error):
# We are still keeping the less descriptive message because if lhs
# We are still keeping the less descriptive message because if lhs
# or rhs gets long, the error message might become unreadable.
# or rhs gets long, the error message might become unreadable.
error
(
filename
,
linenum
,
'readability/check'
,
2
,
error
(
filename
,
linenum
,
'readability/check'
,
2
,
'Consider using %s instead of %s(a %s b)'
%
(
'Consider using %s instead of %s(a %s b)'
%
_CHECK_REPLACEMENT
[
check_macro
][
operator
]
,
(
_CHECK_REPLACEMENT
[
check_macro
][
operator
],
check_macro
,
check_macro
,
operator
))
operator
))
def
CheckAltTokens
(
filename
,
clean_lines
,
linenum
,
error
):
def
CheckAltTokens
(
filename
,
clean_lines
,
linenum
,
error
):
...
@@ -4526,8 +4557,8 @@ def _DropCommonSuffixes(filename):
...
@@ -4526,8 +4557,8 @@ def _DropCommonSuffixes(filename):
Returns:
Returns:
The filename with the common suffix removed.
The filename with the common suffix removed.
"""
"""
for
suffix
in
(
'test.cc'
,
'regtest.cc'
,
'unittest.cc
'
,
for
suffix
in
(
'test.cc'
,
'regtest.cc'
,
'unittest.cc'
,
'inl.h'
,
'impl.h
'
,
'inl.h'
,
'impl.h'
,
'internal.h'
):
'internal.h'
):
if
(
filename
.
endswith
(
suffix
)
and
len
(
filename
)
>
len
(
suffix
)
and
if
(
filename
.
endswith
(
suffix
)
and
len
(
filename
)
>
len
(
suffix
)
and
filename
[
-
len
(
suffix
)
-
1
]
in
(
'-'
,
'_'
)):
filename
[
-
len
(
suffix
)
-
1
]
in
(
'-'
,
'_'
)):
return
filename
[:
-
len
(
suffix
)
-
1
]
return
filename
[:
-
len
(
suffix
)
-
1
]
...
@@ -4543,8 +4574,7 @@ def _IsTestFilename(filename):
...
@@ -4543,8 +4574,7 @@ def _IsTestFilename(filename):
Returns:
Returns:
True if 'filename' looks like a test, False otherwise.
True if 'filename' looks like a test, False otherwise.
"""
"""
if
(
filename
.
endswith
(
'_test.cc'
)
or
if
(
filename
.
endswith
(
'_test.cc'
)
or
filename
.
endswith
(
'_unittest.cc'
)
or
filename
.
endswith
(
'_unittest.cc'
)
or
filename
.
endswith
(
'_regtest.cc'
)):
filename
.
endswith
(
'_regtest.cc'
)):
return
True
return
True
else
:
else
:
...
@@ -4610,7 +4640,6 @@ def _ClassifyInclude(fileinfo, include, is_system):
...
@@ -4610,7 +4640,6 @@ def _ClassifyInclude(fileinfo, include, is_system):
return
_OTHER_HEADER
return
_OTHER_HEADER
def
CheckIncludeLine
(
filename
,
clean_lines
,
linenum
,
include_state
,
error
):
def
CheckIncludeLine
(
filename
,
clean_lines
,
linenum
,
include_state
,
error
):
"""Check rules that are applicable to #include lines.
"""Check rules that are applicable to #include lines.
...
@@ -4653,7 +4682,8 @@ def CheckIncludeLine(filename, clean_lines, linenum, include_state, error):
...
@@ -4653,7 +4682,8 @@ def CheckIncludeLine(filename, clean_lines, linenum, include_state, error):
'"%s" already included at %s:%s'
%
'"%s" already included at %s:%s'
%
(
include
,
filename
,
duplicate_line
))
(
include
,
filename
,
duplicate_line
))
elif
(
include
.
endswith
(
'.cc'
)
and
elif
(
include
.
endswith
(
'.cc'
)
and
os
.
path
.
dirname
(
fileinfo
.
RepositoryName
())
!=
os
.
path
.
dirname
(
include
)):
os
.
path
.
dirname
(
fileinfo
.
RepositoryName
())
!=
os
.
path
.
dirname
(
include
)):
error
(
filename
,
linenum
,
'build/include'
,
4
,
error
(
filename
,
linenum
,
'build/include'
,
4
,
'Do not include .cc files from other packages'
)
'Do not include .cc files from other packages'
)
elif
not
_THIRD_PARTY_HEADERS_PATTERN
.
match
(
include
):
elif
not
_THIRD_PARTY_HEADERS_PATTERN
.
match
(
include
):
...
@@ -4676,15 +4706,15 @@ def CheckIncludeLine(filename, clean_lines, linenum, include_state, error):
...
@@ -4676,15 +4706,15 @@ def CheckIncludeLine(filename, clean_lines, linenum, include_state, error):
error
(
filename
,
linenum
,
'build/include_order'
,
4
,
error
(
filename
,
linenum
,
'build/include_order'
,
4
,
'%s. Should be: %s.h, c system, c++ system, other.'
%
'%s. Should be: %s.h, c system, c++ system, other.'
%
(
error_message
,
fileinfo
.
BaseName
()))
(
error_message
,
fileinfo
.
BaseName
()))
canonical_include
=
include_state
.
CanonicalizeAlphabeticalOrder
(
include
)
canonical_include
=
include_state
.
CanonicalizeAlphabeticalOrder
(
if
not
include_state
.
IsInAlphabeticalOrder
(
include
)
clean_lines
,
linenum
,
canonical_include
):
if
not
include_state
.
IsInAlphabeticalOrder
(
clean_lines
,
linenum
,
canonical_include
):
error
(
filename
,
linenum
,
'build/include_alpha'
,
4
,
error
(
filename
,
linenum
,
'build/include_alpha'
,
4
,
'Include "%s" not in alphabetical order'
%
include
)
'Include "%s" not in alphabetical order'
%
include
)
include_state
.
SetLastHeader
(
canonical_include
)
include_state
.
SetLastHeader
(
canonical_include
)
def
_GetTextInside
(
text
,
start_pattern
):
def
_GetTextInside
(
text
,
start_pattern
):
r
"""Retrieves all the text between matching open and close parentheses.
r
"""Retrieves all the text between matching open and close parentheses.
...
@@ -4763,12 +4793,12 @@ _RE_PATTERN_REF_PARAM = re.compile(
...
@@ -4763,12 +4793,12 @@ _RE_PATTERN_REF_PARAM = re.compile(
# A call-by-const-reference parameter either ends with 'const& identifier'
# A call-by-const-reference parameter either ends with 'const& identifier'
# or looks like 'const type& identifier' when 'type' is atomic.
# or looks like 'const type& identifier' when 'type' is atomic.
_RE_PATTERN_CONST_REF_PARAM
=
(
_RE_PATTERN_CONST_REF_PARAM
=
(
r
'(?:.*\s*\bconst\s*&\s*'
+
_RE_PATTERN_IDENT
+
r
'(?:.*\s*\bconst\s*&\s*'
+
_RE_PATTERN_IDENT
+
r
'|const\s+'
+
r
'|const\s+'
+
_RE_PATTERN_TYPE
+
r
'\s*&\s*'
+
_RE_PATTERN_IDENT
+
r
')'
)
_RE_PATTERN_TYPE
+
r
'\s*&\s*'
+
_RE_PATTERN_IDENT
+
r
')'
)
def
CheckLanguage
(
filename
,
clean_lines
,
linenum
,
file_extension
,
def
CheckLanguage
(
filename
,
clean_lines
,
linenum
,
file_extension
,
include_state
,
include_state
,
nesting_state
,
error
):
nesting_state
,
error
):
"""Checks rules from the 'C++ language rules' section of cppguide.html.
"""Checks rules from the 'C++ language rules' section of cppguide.html.
Some of these rules are hard to test (function overloading, using
Some of these rules are hard to test (function overloading, using
...
@@ -4827,7 +4857,8 @@ def CheckLanguage(filename, clean_lines, linenum, file_extension,
...
@@ -4827,7 +4857,8 @@ def CheckLanguage(filename, clean_lines, linenum, file_extension,
match
=
Search
(
r
'\b(short|long(?! +double)|long long)\b'
,
line
)
match
=
Search
(
r
'\b(short|long(?! +double)|long long)\b'
,
line
)
if
match
:
if
match
:
error
(
filename
,
linenum
,
'runtime/int'
,
4
,
error
(
filename
,
linenum
,
'runtime/int'
,
4
,
'Use int16/int64/etc, rather than the C type %s'
%
match
.
group
(
1
))
'Use int16/int64/etc, rather than the C type %s'
%
match
.
group
(
1
))
# Check if some verboten operator overloading is going on
# Check if some verboten operator overloading is going on
# TODO(unknown): catch out-of-line unary operator&:
# TODO(unknown): catch out-of-line unary operator&:
...
@@ -4856,18 +4887,18 @@ def CheckLanguage(filename, clean_lines, linenum, file_extension,
...
@@ -4856,18 +4887,18 @@ def CheckLanguage(filename, clean_lines, linenum, file_extension,
if
printf_args
:
if
printf_args
:
match
=
Match
(
r
'([\w.\->()]+)$'
,
printf_args
)
match
=
Match
(
r
'([\w.\->()]+)$'
,
printf_args
)
if
match
and
match
.
group
(
1
)
!=
'__VA_ARGS__'
:
if
match
and
match
.
group
(
1
)
!=
'__VA_ARGS__'
:
function_name
=
re
.
search
(
r
'\b((?:string)?printf)\s*\('
,
function_name
=
re
.
search
(
r
'\b((?:string)?printf)\s*\('
,
line
,
line
,
re
.
I
).
group
(
1
)
re
.
I
).
group
(
1
)
error
(
filename
,
linenum
,
'runtime/printf'
,
4
,
error
(
filename
,
linenum
,
'runtime/printf'
,
4
,
'Potential format string bug. Do %s("%%s", %s) instead.'
'Potential format string bug. Do %s("%%s", %s) instead.'
%
%
(
function_name
,
match
.
group
(
1
)))
(
function_name
,
match
.
group
(
1
)))
# Check for potential memset bugs like memset(buf, sizeof(buf), 0).
# Check for potential memset bugs like memset(buf, sizeof(buf), 0).
match
=
Search
(
r
'memset\s*\(([^,]*),\s*([^,]*),\s*0\s*\)'
,
line
)
match
=
Search
(
r
'memset\s*\(([^,]*),\s*([^,]*),\s*0\s*\)'
,
line
)
if
match
and
not
Match
(
r
"^''|-?[0-9]+|0x[0-9A-Fa-f]$"
,
match
.
group
(
2
)):
if
match
and
not
Match
(
r
"^''|-?[0-9]+|0x[0-9A-Fa-f]$"
,
match
.
group
(
2
)):
error
(
filename
,
linenum
,
'runtime/memset'
,
4
,
error
(
filename
,
linenum
,
'runtime/memset'
,
4
,
'Did you mean "memset(%s, 0, %s)"?'
'Did you mean "memset(%s, 0, %s)"?'
%
%
(
match
.
group
(
1
),
match
.
group
(
2
)))
(
match
.
group
(
1
),
match
.
group
(
2
)))
if
Search
(
r
'\busing namespace\b'
,
line
):
if
Search
(
r
'\busing namespace\b'
,
line
):
error
(
filename
,
linenum
,
'build/namespaces'
,
5
,
error
(
filename
,
linenum
,
'build/namespaces'
,
5
,
...
@@ -4909,17 +4940,19 @@ def CheckLanguage(filename, clean_lines, linenum, file_extension,
...
@@ -4909,17 +4940,19 @@ def CheckLanguage(filename, clean_lines, linenum, file_extension,
is_const
=
False
is_const
=
False
break
break
if
not
is_const
:
if
not
is_const
:
error
(
filename
,
linenum
,
'runtime/arrays'
,
1
,
error
(
filename
,
linenum
,
'runtime/arrays'
,
1
,
'Do not use variable-length arrays. Use an appropriately named '
'Do not use variable-length arrays. Use an appropriately named '
"('k' followed by CamelCase) compile-time constant for the size."
)
"('k' followed by CamelCase) compile-time constant for the size."
)
# Check for use of unnamed namespaces in header files. Registration
# Check for use of unnamed namespaces in header files. Registration
# macros are typically OK, so we allow use of "namespace {" on lines
# macros are typically OK, so we allow use of "namespace {" on lines
# that end with backslashes.
# that end with backslashes.
if
(
file_extension
==
'h'
if
(
file_extension
==
'h'
and
Search
(
r
'\bnamespace\s*{'
,
line
)
and
and
Search
(
r
'\bnamespace\s*{'
,
line
)
line
[
-
1
]
!=
'
\\
'
):
and
line
[
-
1
]
!=
'
\\
'
):
error
(
error
(
filename
,
linenum
,
'build/namespaces'
,
4
,
filename
,
linenum
,
'build/namespaces'
,
4
,
'Do not use unnamed namespaces in header files. See '
'Do not use unnamed namespaces in header files. See '
'http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namespaces'
'http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namespaces'
' for more information.'
)
' for more information.'
)
...
@@ -4943,8 +4976,7 @@ def CheckGlobalStatic(filename, clean_lines, linenum, error):
...
@@ -4943,8 +4976,7 @@ def CheckGlobalStatic(filename, clean_lines, linenum, error):
# Check for people declaring static/global STL strings at the top level.
# Check for people declaring static/global STL strings at the top level.
# This is dangerous because the C++ language does not guarantee that
# This is dangerous because the C++ language does not guarantee that
# globals with constructors are initialized before the first access.
# globals with constructors are initialized before the first access.
match
=
Match
(
match
=
Match
(
r
'((?:|static +)(?:|const +))string +([a-zA-Z0-9_:]+)\b(.*)'
,
r
'((?:|static +)(?:|const +))string +([a-zA-Z0-9_:]+)\b(.*)'
,
line
)
line
)
# Remove false positives:
# Remove false positives:
...
@@ -4965,12 +4997,12 @@ def CheckGlobalStatic(filename, clean_lines, linenum, error):
...
@@ -4965,12 +4997,12 @@ def CheckGlobalStatic(filename, clean_lines, linenum, error):
# string Class::operator*()
# string Class::operator*()
if
(
match
and
if
(
match
and
not
Search
(
r
'\bstring\b(\s+const)?\s*\*\s*(const\s+)?\w'
,
line
)
and
not
Search
(
r
'\bstring\b(\s+const)?\s*\*\s*(const\s+)?\w'
,
line
)
and
not
Search
(
r
'\boperator\W'
,
line
)
and
not
Search
(
r
'\boperator\W'
,
line
)
and
not
Match
(
not
Match
(
r
'\s*(<.*>)?(::[a-zA-Z0-9_]+)*\s*\(([^"]|$)'
,
match
.
group
(
3
))):
r
'\s*(<.*>)?(::[a-zA-Z0-9_]+)*\s*\(([^"]|$)'
,
match
.
group
(
3
))):
error
(
filename
,
linenum
,
'runtime/string'
,
4
,
error
(
filename
,
linenum
,
'runtime/string'
,
4
,
'For a static/global string constant, use a C style string instead: '
'For a static/global string constant, use a C style string instead: '
'"%schar %s[]".'
%
'"%schar %s[]".'
%
(
match
.
group
(
1
),
match
.
group
(
2
)))
(
match
.
group
(
1
),
match
.
group
(
2
)))
if
Search
(
r
'\b([A-Za-z0-9_]*_)\(\1\)'
,
line
):
if
Search
(
r
'\b([A-Za-z0-9_]*_)\(\1\)'
,
line
):
error
(
filename
,
linenum
,
'runtime/init'
,
4
,
error
(
filename
,
linenum
,
'runtime/init'
,
4
,
...
@@ -5021,8 +5053,8 @@ def IsDerivedFunction(clean_lines, linenum):
...
@@ -5021,8 +5053,8 @@ def IsDerivedFunction(clean_lines, linenum):
match
=
Match
(
r
'^([^()]*\w+)\('
,
clean_lines
.
elided
[
i
])
match
=
Match
(
r
'^([^()]*\w+)\('
,
clean_lines
.
elided
[
i
])
if
match
:
if
match
:
# Look for "override" after the matching closing parenthesis
# Look for "override" after the matching closing parenthesis
line
,
_
,
closing_paren
=
CloseExpression
(
line
,
_
,
closing_paren
=
CloseExpression
(
clean_lines
,
i
,
clean_lines
,
i
,
len
(
match
.
group
(
1
)))
len
(
match
.
group
(
1
)))
return
(
closing_paren
>=
0
and
return
(
closing_paren
>=
0
and
Search
(
r
'\boverride\b'
,
line
[
closing_paren
:]))
Search
(
r
'\boverride\b'
,
line
[
closing_paren
:]))
return
False
return
False
...
@@ -5040,7 +5072,8 @@ def IsOutOfLineMethodDefinition(clean_lines, linenum):
...
@@ -5040,7 +5072,8 @@ def IsOutOfLineMethodDefinition(clean_lines, linenum):
# Scan back a few lines for start of current function
# Scan back a few lines for start of current function
for
i
in
xrange
(
linenum
,
max
(
-
1
,
linenum
-
10
),
-
1
):
for
i
in
xrange
(
linenum
,
max
(
-
1
,
linenum
-
10
),
-
1
):
if
Match
(
r
'^([^()]*\w+)\('
,
clean_lines
.
elided
[
i
]):
if
Match
(
r
'^([^()]*\w+)\('
,
clean_lines
.
elided
[
i
]):
return
Match
(
r
'^[^()]*\w+::\w+\('
,
clean_lines
.
elided
[
i
])
is
not
None
return
Match
(
r
'^[^()]*\w+::\w+\('
,
clean_lines
.
elided
[
i
])
is
not
None
return
False
return
False
...
@@ -5086,8 +5119,8 @@ def IsInitializerList(clean_lines, linenum):
...
@@ -5086,8 +5119,8 @@ def IsInitializerList(clean_lines, linenum):
return
False
return
False
def
CheckForNonConstReference
(
filename
,
clean_lines
,
linenum
,
def
CheckForNonConstReference
(
filename
,
clean_lines
,
linenum
,
nesting_state
,
nesting_state
,
error
):
error
):
"""Check for non-const references.
"""Check for non-const references.
Separate from CheckLanguage since it scans backwards from current
Separate from CheckLanguage since it scans backwards from current
...
@@ -5211,8 +5244,8 @@ def CheckForNonConstReference(filename, clean_lines, linenum,
...
@@ -5211,8 +5244,8 @@ def CheckForNonConstReference(filename, clean_lines, linenum,
# didn't see any function name on this line, so this is likely a
# didn't see any function name on this line, so this is likely a
# multi-line parameter list. Try a bit harder to catch this case.
# multi-line parameter list. Try a bit harder to catch this case.
for
i
in
xrange
(
2
):
for
i
in
xrange
(
2
):
if
(
linenum
>
i
and
if
(
linenum
>
i
and
Search
(
whitelisted_functions
,
Search
(
whitelisted_functions
,
clean_lines
.
elided
[
linenum
-
i
-
1
])):
clean_lines
.
elided
[
linenum
-
i
-
1
])):
return
return
decls
=
ReplaceAll
(
r
'{[^}]*}'
,
' '
,
line
)
# exclude function body
decls
=
ReplaceAll
(
r
'{[^}]*}'
,
' '
,
line
)
# exclude function body
...
@@ -5220,8 +5253,8 @@ def CheckForNonConstReference(filename, clean_lines, linenum,
...
@@ -5220,8 +5253,8 @@ def CheckForNonConstReference(filename, clean_lines, linenum,
if
not
Match
(
_RE_PATTERN_CONST_REF_PARAM
,
parameter
):
if
not
Match
(
_RE_PATTERN_CONST_REF_PARAM
,
parameter
):
error
(
filename
,
linenum
,
'runtime/references'
,
2
,
error
(
filename
,
linenum
,
'runtime/references'
,
2
,
'Is this a non-const reference? '
'Is this a non-const reference? '
'If so, make const or use a pointer: '
+
'If so, make const or use a pointer: '
+
ReplaceAll
(
ReplaceAll
(
' *<'
,
'<'
,
parameter
))
' *<'
,
'<'
,
parameter
))
def
CheckCasts
(
filename
,
clean_lines
,
linenum
,
error
):
def
CheckCasts
(
filename
,
clean_lines
,
linenum
,
error
):
...
@@ -5239,8 +5272,7 @@ def CheckCasts(filename, clean_lines, linenum, error):
...
@@ -5239,8 +5272,7 @@ def CheckCasts(filename, clean_lines, linenum, error):
# I just try to capture the most common basic types, though there are more.
# I just try to capture the most common basic types, though there are more.
# Parameterless conversion functions, such as bool(), are allowed as they are
# Parameterless conversion functions, such as bool(), are allowed as they are
# probably a member operator declaration or default constructor.
# probably a member operator declaration or default constructor.
match
=
Search
(
match
=
Search
(
r
'(\bnew\s+|\S<\s*(?:const\s+)?)?\b'
r
'(\bnew\s+|\S<\s*(?:const\s+)?)?\b'
r
'(int|float|double|bool|char|int32|uint32|int64|uint64)'
r
'(int|float|double|bool|char|int32|uint32|int64|uint64)'
r
'(\([^)].*)'
,
line
)
r
'(\([^)].*)'
,
line
)
expecting_function
=
ExpectingFunctionArgs
(
clean_lines
,
linenum
)
expecting_function
=
ExpectingFunctionArgs
(
clean_lines
,
linenum
)
...
@@ -5272,21 +5304,19 @@ def CheckCasts(filename, clean_lines, linenum, error):
...
@@ -5272,21 +5304,19 @@ def CheckCasts(filename, clean_lines, linenum, error):
# - Placement new
# - Placement new
# - Alias declarations
# - Alias declarations
matched_funcptr
=
match
.
group
(
3
)
matched_funcptr
=
match
.
group
(
3
)
if
(
matched_new_or_template
is
None
and
if
(
matched_new_or_template
is
None
and
not
(
matched_funcptr
and
(
Match
(
not
(
matched_funcptr
and
r
'\((?:[^() ]+::\s*\*\s*)?[^() ]+\)\s*\('
,
(
Match
(
r
'\((?:[^() ]+::\s*\*\s*)?[^() ]+\)\s*\('
,
matched_funcptr
)
or
matched_funcptr
.
startswith
(
'(*)'
)))
and
matched_funcptr
)
or
matched_funcptr
.
startswith
(
'(*)'
)))
and
not
Match
(
r
'\s*using\s+\S+\s*=\s*'
+
matched_type
,
line
)
and
not
Match
(
r
'\s*using\s+\S+\s*=\s*'
+
matched_type
,
line
)
and
not
Search
(
r
'new\(\S+\)\s*'
+
matched_type
,
line
)):
not
Search
(
r
'new\(\S+\)\s*'
+
matched_type
,
line
)):
error
(
filename
,
linenum
,
'readability/casting'
,
4
,
error
(
filename
,
linenum
,
'readability/casting'
,
4
,
'Using deprecated casting style. '
'Using deprecated casting style. '
'Use static_cast<%s>(...) instead'
%
'Use static_cast<%s>(...) instead'
%
matched_type
)
matched_type
)
if
not
expecting_function
:
if
not
expecting_function
:
CheckCStyleCast
(
filename
,
clean_lines
,
linenum
,
'static_cast'
,
CheckCStyleCast
(
filename
,
clean_lines
,
linenum
,
'static_cast'
,
r
'\((int|float|double|bool|char|u?int(16|32|64))\)'
,
error
)
r
'\((int|float|double|bool|char|u?int(16|32|64))\)'
,
error
)
# This doesn't catch all cases. Consider (const char * const)"hello".
# This doesn't catch all cases. Consider (const char * const)"hello".
#
#
...
@@ -5311,17 +5341,18 @@ def CheckCasts(filename, clean_lines, linenum, error):
...
@@ -5311,17 +5341,18 @@ def CheckCasts(filename, clean_lines, linenum, error):
#
#
# This is not a cast:
# This is not a cast:
# reference_type&(int* function_param);
# reference_type&(int* function_param);
match
=
Search
(
match
=
Search
(
r
'(?:[^\w]&\(([^)*][^)]*)\)[\w(])|'
r
'(?:[^\w]&\(([^)*][^)]*)\)[\w(])|'
r
'(?:[^\w]&(static|dynamic|down|reinterpret)_cast\b)'
,
line
)
r
'(?:[^\w]&(static|dynamic|down|reinterpret)_cast\b)'
,
line
)
if
match
:
if
match
:
# Try a better error message when the & is bound to something
# Try a better error message when the & is bound to something
# dereferenced by the casted pointer, as opposed to the casted
# dereferenced by the casted pointer, as opposed to the casted
# pointer itself.
# pointer itself.
parenthesis_error
=
False
parenthesis_error
=
False
match
=
Match
(
r
'^(.*&(?:static|dynamic|down|reinterpret)_cast\b)<'
,
line
)
match
=
Match
(
r
'^(.*&(?:static|dynamic|down|reinterpret)_cast\b)<'
,
line
)
if
match
:
if
match
:
_
,
y1
,
x1
=
CloseExpression
(
clean_lines
,
linenum
,
len
(
match
.
group
(
1
)))
_
,
y1
,
x1
=
CloseExpression
(
clean_lines
,
linenum
,
len
(
match
.
group
(
1
)))
if
x1
>=
0
and
clean_lines
.
elided
[
y1
][
x1
]
==
'('
:
if
x1
>=
0
and
clean_lines
.
elided
[
y1
][
x1
]
==
'('
:
_
,
y2
,
x2
=
CloseExpression
(
clean_lines
,
y1
,
x1
)
_
,
y2
,
x2
=
CloseExpression
(
clean_lines
,
y1
,
x1
)
if
x2
>=
0
:
if
x2
>=
0
:
...
@@ -5470,42 +5501,73 @@ def ExpectingFunctionArgs(clean_lines, linenum):
...
@@ -5470,42 +5501,73 @@ def ExpectingFunctionArgs(clean_lines, linenum):
_HEADERS_CONTAINING_TEMPLATES
=
(
_HEADERS_CONTAINING_TEMPLATES
=
(
(
'<deque>'
,
(
'deque'
,)),
(
'<deque>'
,
(
'deque'
,
)),
(
'<functional>'
,
(
'unary_function'
,
'binary_function'
,
(
'<functional>'
,
(
'plus'
,
'minus'
,
'multiplies'
,
'divides'
,
'modulus'
,
'unary_function'
,
'binary_function'
,
'plus'
,
'minus'
,
'multiplies'
,
'divides'
,
'modulus'
,
'negate'
,
'negate'
,
'equal_to'
,
'not_equal_to'
,
'greater'
,
'less'
,
'equal_to'
,
'greater_equal'
,
'less_equal'
,
'not_equal_to'
,
'logical_and'
,
'logical_or'
,
'logical_not'
,
'greater'
,
'unary_negate'
,
'not1'
,
'binary_negate'
,
'not2'
,
'less'
,
'bind1st'
,
'bind2nd'
,
'greater_equal'
,
'less_equal'
,
'logical_and'
,
'logical_or'
,
'logical_not'
,
'unary_negate'
,
'not1'
,
'binary_negate'
,
'not2'
,
'bind1st'
,
'bind2nd'
,
'pointer_to_unary_function'
,
'pointer_to_unary_function'
,
'pointer_to_binary_function'
,
'pointer_to_binary_function'
,
'ptr_fun'
,
'ptr_fun'
,
'mem_fun_t'
,
'mem_fun'
,
'mem_fun1_t'
,
'mem_fun1_ref_t'
,
'mem_fun_t'
,
'mem_fun'
,
'mem_fun1_t'
,
'mem_fun1_ref_t'
,
'mem_fun_ref_t'
,
'mem_fun_ref_t'
,
'const_mem_fun_t'
,
'const_mem_fun1_t'
,
'const_mem_fun_t'
,
'const_mem_fun_ref_t'
,
'const_mem_fun1_ref_t'
,
'const_mem_fun1_t'
,
'mem_fun_ref'
,
'const_mem_fun_ref_t'
,
)),
'const_mem_fun1_ref_t'
,
(
'<limits>'
,
(
'numeric_limits'
,)),
'mem_fun_ref'
,
)),
(
'<list>'
,
(
'list'
,)),
(
'<limits>'
,
(
'numeric_limits'
,
)),
(
'<map>'
,
(
'map'
,
'multimap'
,)),
(
'<list>'
,
(
'list'
,
)),
(
'<memory>'
,
(
'allocator'
,)),
(
'<map>'
,
(
(
'<queue>'
,
(
'queue'
,
'priority_queue'
,)),
'map'
,
(
'<set>'
,
(
'set'
,
'multiset'
,)),
'multimap'
,
)),
(
'<stack>'
,
(
'stack'
,)),
(
'<memory>'
,
(
'allocator'
,
)),
(
'<string>'
,
(
'char_traits'
,
'basic_string'
,)),
(
'<queue>'
,
(
(
'<tuple>'
,
(
'tuple'
,)),
'queue'
,
(
'<utility>'
,
(
'pair'
,)),
'priority_queue'
,
)),
(
'<vector>'
,
(
'vector'
,)),
(
'<set>'
,
(
'set'
,
'multiset'
,
)),
(
'<stack>'
,
(
'stack'
,
)),
(
'<string>'
,
(
'char_traits'
,
'basic_string'
,
)),
(
'<tuple>'
,
(
'tuple'
,
)),
(
'<utility>'
,
(
'pair'
,
)),
(
'<vector>'
,
(
'vector'
,
)),
# gcc extensions.
# gcc extensions.
# Note: std::hash is their hash, ::hash is our hash
# Note: std::hash is their hash, ::hash is our hash
(
'<hash_map>'
,
(
'hash_map'
,
'hash_multimap'
,)),
(
'<hash_map>'
,
(
(
'<hash_set>'
,
(
'hash_set'
,
'hash_multiset'
,)),
'hash_map'
,
(
'<slist>'
,
(
'slist'
,)),
'hash_multimap'
,
)),
)
(
'<hash_set>'
,
(
'hash_set'
,
'hash_multiset'
,
)),
(
'<slist>'
,
(
'slist'
,
)),
)
_RE_PATTERN_STRING
=
re
.
compile
(
r
'\bstring\b'
)
_RE_PATTERN_STRING
=
re
.
compile
(
r
'\bstring\b'
)
...
@@ -5515,16 +5577,14 @@ for _template in ('copy', 'max', 'min', 'min_element', 'sort', 'swap',
...
@@ -5515,16 +5577,14 @@ for _template in ('copy', 'max', 'min', 'min_element', 'sort', 'swap',
# Match max<type>(..., ...), max(..., ...), but not foo->max, foo.max or
# Match max<type>(..., ...), max(..., ...), but not foo->max, foo.max or
# type::max().
# type::max().
_re_pattern_algorithm_header
.
append
(
_re_pattern_algorithm_header
.
append
(
(
re
.
compile
(
r
'[^>.]\b'
+
_template
+
r
'(<.*?>)?\([^\)]'
),
(
re
.
compile
(
r
'[^>.]\b'
+
_template
+
r
'(<.*?>)?\([^\)]'
),
_template
,
_template
,
'<algorithm>'
))
'<algorithm>'
))
_re_pattern_templates
=
[]
_re_pattern_templates
=
[]
for
_header
,
_templates
in
_HEADERS_CONTAINING_TEMPLATES
:
for
_header
,
_templates
in
_HEADERS_CONTAINING_TEMPLATES
:
for
_template
in
_templates
:
for
_template
in
_templates
:
_re_pattern_templates
.
append
(
_re_pattern_templates
.
append
(
(
re
.
compile
(
r
'(\<|\b)'
+
_template
+
r
'\s*\<'
),
(
re
.
compile
(
r
'(\<|\b)'
+
_template
+
r
'\s*\<'
),
_template
+
'<>'
,
_template
+
'<>'
,
_header
))
_header
))
...
@@ -5610,7 +5670,10 @@ def UpdateIncludeState(filename, include_dict, io=codecs):
...
@@ -5610,7 +5670,10 @@ def UpdateIncludeState(filename, include_dict, io=codecs):
return
True
return
True
def
CheckForIncludeWhatYouUse
(
filename
,
clean_lines
,
include_state
,
error
,
def
CheckForIncludeWhatYouUse
(
filename
,
clean_lines
,
include_state
,
error
,
io
=
codecs
):
io
=
codecs
):
"""Reports for missing stl includes.
"""Reports for missing stl includes.
...
@@ -5660,8 +5723,8 @@ def CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error,
...
@@ -5660,8 +5723,8 @@ def CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error,
# The policy is that if you #include something in foo.h you don't need to
# The policy is that if you #include something in foo.h you don't need to
# include it again in foo.cc. Here, we will look at possible includes.
# include it again in foo.cc. Here, we will look at possible includes.
# Let's flatten the include_state include_list and copy it into a dictionary.
# Let's flatten the include_state include_list and copy it into a dictionary.
include_dict
=
dict
([
item
for
sublist
in
include_state
.
include_list
include_dict
=
dict
(
for
item
in
sublist
])
[
item
for
sublist
in
include_state
.
include_list
for
item
in
sublist
])
# Did we find the header for this file (if any) and successfully load it?
# Did we find the header for this file (if any) and successfully load it?
header_found
=
False
header_found
=
False
...
@@ -5682,7 +5745,8 @@ def CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error,
...
@@ -5682,7 +5745,8 @@ def CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error,
# the keys.
# the keys.
header_keys
=
include_dict
.
keys
()
header_keys
=
include_dict
.
keys
()
for
header
in
header_keys
:
for
header
in
header_keys
:
(
same_module
,
common_path
)
=
FilesBelongToSameModule
(
abs_filename
,
header
)
(
same_module
,
common_path
)
=
FilesBelongToSameModule
(
abs_filename
,
header
)
fullpath
=
common_path
+
header
fullpath
=
common_path
+
header
if
same_module
and
UpdateIncludeState
(
fullpath
,
include_dict
,
io
):
if
same_module
and
UpdateIncludeState
(
fullpath
,
include_dict
,
io
):
header_found
=
True
header_found
=
True
...
@@ -5700,8 +5764,8 @@ def CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error,
...
@@ -5700,8 +5764,8 @@ def CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error,
template
=
required
[
required_header_unstripped
][
1
]
template
=
required
[
required_header_unstripped
][
1
]
if
required_header_unstripped
.
strip
(
'<>"'
)
not
in
include_dict
:
if
required_header_unstripped
.
strip
(
'<>"'
)
not
in
include_dict
:
error
(
filename
,
required
[
required_header_unstripped
][
0
],
error
(
filename
,
required
[
required_header_unstripped
][
0
],
'build/include_what_you_use'
,
4
,
'build/include_what_you_use'
,
4
,
'Add #include '
+
'Add #include '
+
required_header_unstripped
+
' for '
+
template
)
required_header_unstripped
+
' for '
+
template
)
_RE_PATTERN_EXPLICIT_MAKEPAIR
=
re
.
compile
(
r
'\bmake_pair\s*<'
)
_RE_PATTERN_EXPLICIT_MAKEPAIR
=
re
.
compile
(
r
'\bmake_pair\s*<'
)
...
@@ -5722,7 +5786,10 @@ def CheckMakePairUsesDeduction(filename, clean_lines, linenum, error):
...
@@ -5722,7 +5786,10 @@ def CheckMakePairUsesDeduction(filename, clean_lines, linenum, error):
line
=
clean_lines
.
elided
[
linenum
]
line
=
clean_lines
.
elided
[
linenum
]
match
=
_RE_PATTERN_EXPLICIT_MAKEPAIR
.
search
(
line
)
match
=
_RE_PATTERN_EXPLICIT_MAKEPAIR
.
search
(
line
)
if
match
:
if
match
:
error
(
filename
,
linenum
,
'build/explicit_make_pair'
,
error
(
filename
,
linenum
,
'build/explicit_make_pair'
,
4
,
# 4 = high confidence
4
,
# 4 = high confidence
'For C++11-compatibility, omit template arguments from make_pair'
'For C++11-compatibility, omit template arguments from make_pair'
' OR use pair directly OR if appropriate, construct a pair directly'
)
' OR use pair directly OR if appropriate, construct a pair directly'
)
...
@@ -5746,9 +5813,13 @@ def CheckDefaultLambdaCaptures(filename, clean_lines, linenum, error):
...
@@ -5746,9 +5813,13 @@ def CheckDefaultLambdaCaptures(filename, clean_lines, linenum, error):
# Found a potential error, check what comes after the lambda-introducer.
# Found a potential error, check what comes after the lambda-introducer.
# If it's not open parenthesis (for lambda-declarator) or open brace
# If it's not open parenthesis (for lambda-declarator) or open brace
# (for compound-statement), it's not a lambda.
# (for compound-statement), it's not a lambda.
line
,
_
,
pos
=
CloseExpression
(
clean_lines
,
linenum
,
len
(
match
.
group
(
1
)))
line
,
_
,
pos
=
CloseExpression
(
clean_lines
,
linenum
,
len
(
match
.
group
(
1
)))
if
pos
>=
0
and
Match
(
r
'^\s*[{(]'
,
line
[
pos
:]):
if
pos
>=
0
and
Match
(
r
'^\s*[{(]'
,
line
[
pos
:]):
error
(
filename
,
linenum
,
'build/c++11'
,
error
(
filename
,
linenum
,
'build/c++11'
,
4
,
# 4 = high confidence
4
,
# 4 = high confidence
'Default lambda captures are an unapproved C++ feature.'
)
'Default lambda captures are an unapproved C++ feature.'
)
...
@@ -5793,7 +5864,8 @@ def CheckRedundantVirtual(filename, clean_lines, linenum, error):
...
@@ -5793,7 +5864,8 @@ def CheckRedundantVirtual(filename, clean_lines, linenum, error):
if
parameter_list
:
if
parameter_list
:
# Match parentheses to find the end of the parameter list
# Match parentheses to find the end of the parameter list
(
_
,
end_line
,
end_col
)
=
CloseExpression
(
(
_
,
end_line
,
end_col
)
=
CloseExpression
(
clean_lines
,
start_line
,
start_col
+
len
(
parameter_list
.
group
(
1
)))
clean_lines
,
start_line
,
start_col
+
len
(
parameter_list
.
group
(
1
)))
break
break
start_col
=
0
start_col
=
0
...
@@ -5846,8 +5918,6 @@ def CheckRedundantOverrideOrFinal(filename, clean_lines, linenum, error):
...
@@ -5846,8 +5918,6 @@ def CheckRedundantOverrideOrFinal(filename, clean_lines, linenum, error):
'already declared as "final"'
))
'already declared as "final"'
))
# Returns true if we are at a new block, and it is directly
# Returns true if we are at a new block, and it is directly
# inside of a namespace.
# inside of a namespace.
def
IsBlockInNameSpace
(
nesting_state
,
is_forward_declaration
):
def
IsBlockInNameSpace
(
nesting_state
,
is_forward_declaration
):
...
@@ -5912,8 +5982,14 @@ def CheckItemIndentationInNamespace(filename, raw_lines_no_comments, linenum,
...
@@ -5912,8 +5982,14 @@ def CheckItemIndentationInNamespace(filename, raw_lines_no_comments, linenum,
'Do not indent within a namespace'
)
'Do not indent within a namespace'
)
def
ProcessLine
(
filename
,
file_extension
,
clean_lines
,
line
,
def
ProcessLine
(
filename
,
include_state
,
function_state
,
nesting_state
,
error
,
file_extension
,
clean_lines
,
line
,
include_state
,
function_state
,
nesting_state
,
error
,
extra_check_functions
=
[]):
extra_check_functions
=
[]):
"""Processes a single line in the file.
"""Processes a single line in the file.
...
@@ -5941,12 +6017,13 @@ def ProcessLine(filename, file_extension, clean_lines, line,
...
@@ -5941,12 +6017,13 @@ def ProcessLine(filename, file_extension, clean_lines, line,
if
nesting_state
.
InAsmBlock
():
return
if
nesting_state
.
InAsmBlock
():
return
CheckForFunctionLengths
(
filename
,
clean_lines
,
line
,
function_state
,
error
)
CheckForFunctionLengths
(
filename
,
clean_lines
,
line
,
function_state
,
error
)
CheckForMultilineCommentsAndStrings
(
filename
,
clean_lines
,
line
,
error
)
CheckForMultilineCommentsAndStrings
(
filename
,
clean_lines
,
line
,
error
)
CheckStyle
(
filename
,
clean_lines
,
line
,
file_extension
,
nesting_state
,
error
)
CheckStyle
(
filename
,
clean_lines
,
line
,
file_extension
,
nesting_state
,
error
)
CheckLanguage
(
filename
,
clean_lines
,
line
,
file_extension
,
include_state
,
CheckLanguage
(
filename
,
clean_lines
,
line
,
file_extension
,
include_state
,
nesting_state
,
error
)
nesting_state
,
error
)
CheckForNonConstReference
(
filename
,
clean_lines
,
line
,
nesting_state
,
error
)
CheckForNonConstReference
(
filename
,
clean_lines
,
line
,
nesting_state
,
error
)
CheckForNonStandardConstructs
(
filename
,
clean_lines
,
lin
e
,
CheckForNonStandardConstructs
(
filename
,
clean_lines
,
line
,
nesting_stat
e
,
nesting_state
,
error
)
error
)
CheckVlogArguments
(
filename
,
clean_lines
,
line
,
error
)
CheckVlogArguments
(
filename
,
clean_lines
,
line
,
error
)
CheckPosixThreading
(
filename
,
clean_lines
,
line
,
error
)
CheckPosixThreading
(
filename
,
clean_lines
,
line
,
error
)
CheckInvalidIncrement
(
filename
,
clean_lines
,
line
,
error
)
CheckInvalidIncrement
(
filename
,
clean_lines
,
line
,
error
)
...
@@ -5957,6 +6034,7 @@ def ProcessLine(filename, file_extension, clean_lines, line,
...
@@ -5957,6 +6034,7 @@ def ProcessLine(filename, file_extension, clean_lines, line,
for
check_fn
in
extra_check_functions
:
for
check_fn
in
extra_check_functions
:
check_fn
(
filename
,
clean_lines
,
line
,
error
)
check_fn
(
filename
,
clean_lines
,
line
,
error
)
def
FlagCxx11Features
(
filename
,
clean_lines
,
linenum
,
error
):
def
FlagCxx11Features
(
filename
,
clean_lines
,
linenum
,
error
):
"""Flag those c++11 features that we only allow in certain places.
"""Flag those c++11 features that we only allow in certain places.
...
@@ -5970,7 +6048,8 @@ def FlagCxx11Features(filename, clean_lines, linenum, error):
...
@@ -5970,7 +6048,8 @@ def FlagCxx11Features(filename, clean_lines, linenum, error):
# Flag unapproved C++11 headers.
# Flag unapproved C++11 headers.
include
=
Match
(
r
'\s*#\s*include\s+[<"]([^<"]+)[">]'
,
line
)
include
=
Match
(
r
'\s*#\s*include\s+[<"]([^<"]+)[">]'
,
line
)
if
include
and
include
.
group
(
1
)
in
(
'cfenv'
,
if
include
and
include
.
group
(
1
)
in
(
'cfenv'
,
'condition_variable'
,
'condition_variable'
,
'fenv.h'
,
'fenv.h'
,
'future'
,
'future'
,
...
@@ -5979,8 +6058,7 @@ def FlagCxx11Features(filename, clean_lines, linenum, error):
...
@@ -5979,8 +6058,7 @@ def FlagCxx11Features(filename, clean_lines, linenum, error):
'chrono'
,
'chrono'
,
'ratio'
,
'ratio'
,
'regex'
,
'regex'
,
'system_error'
,
'system_error'
,
):
):
error
(
filename
,
linenum
,
'build/c++11'
,
5
,
error
(
filename
,
linenum
,
'build/c++11'
,
5
,
(
'<%s> is an unapproved C++11 header.'
)
%
include
.
group
(
1
))
(
'<%s> is an unapproved C++11 header.'
)
%
include
.
group
(
1
))
...
@@ -5994,16 +6072,18 @@ def FlagCxx11Features(filename, clean_lines, linenum, error):
...
@@ -5994,16 +6072,18 @@ def FlagCxx11Features(filename, clean_lines, linenum, error):
for
top_name
in
(
for
top_name
in
(
# type_traits
# type_traits
'alignment_of'
,
'alignment_of'
,
'aligned_union'
,
'aligned_union'
,
):
):
if
Search
(
r
'\bstd::%s\b'
%
top_name
,
line
):
if
Search
(
r
'\bstd::%s\b'
%
top_name
,
line
):
error
(
filename
,
linenum
,
'build/c++11'
,
5
,
error
(
filename
,
linenum
,
'build/c++11'
,
5
,
(
(
'std::%s is an unapproved C++11 class or function. Send c-style '
'std::%s is an unapproved C++11 class or function. Send c-style '
'an example of where it would make your code more readable, and '
'an example of where it would make your code more readable, and '
'they may let you use it.'
)
%
top_name
)
'they may let you use it.'
)
%
top_name
)
def
ProcessFileData
(
filename
,
file_extension
,
lines
,
error
,
def
ProcessFileData
(
filename
,
file_extension
,
lines
,
error
,
extra_check_functions
=
[]):
extra_check_functions
=
[]):
"""Performs lint checks and reports any errors to the given error function.
"""Performs lint checks and reports any errors to the given error function.
...
@@ -6036,9 +6116,8 @@ def ProcessFileData(filename, file_extension, lines, error,
...
@@ -6036,9 +6116,8 @@ def ProcessFileData(filename, file_extension, lines, error,
CheckForHeaderGuard
(
filename
,
clean_lines
,
error
)
CheckForHeaderGuard
(
filename
,
clean_lines
,
error
)
for
line
in
xrange
(
clean_lines
.
NumLines
()):
for
line
in
xrange
(
clean_lines
.
NumLines
()):
ProcessLine
(
filename
,
file_extension
,
clean_lines
,
line
,
ProcessLine
(
filename
,
file_extension
,
clean_lines
,
line
,
include_state
,
include_state
,
function_state
,
nesting_state
,
error
,
function_state
,
nesting_state
,
error
,
extra_check_functions
)
extra_check_functions
)
FlagCxx11Features
(
filename
,
clean_lines
,
line
,
error
)
FlagCxx11Features
(
filename
,
clean_lines
,
line
,
error
)
nesting_state
.
CheckCompletedBlocks
(
filename
,
error
)
nesting_state
.
CheckCompletedBlocks
(
filename
,
error
)
...
@@ -6054,6 +6133,7 @@ def ProcessFileData(filename, file_extension, lines, error,
...
@@ -6054,6 +6133,7 @@ def ProcessFileData(filename, file_extension, lines, error,
CheckForNewlineAtEOF
(
filename
,
lines
,
error
)
CheckForNewlineAtEOF
(
filename
,
lines
,
error
)
def
ProcessConfigOverrides
(
filename
):
def
ProcessConfigOverrides
(
filename
):
""" Loads the configuration files and processes the config overrides.
""" Loads the configuration files and processes the config overrides.
...
@@ -6101,7 +6181,8 @@ def ProcessConfigOverrides(filename):
...
@@ -6101,7 +6181,8 @@ def ProcessConfigOverrides(filename):
if
base_name
:
if
base_name
:
pattern
=
re
.
compile
(
val
)
pattern
=
re
.
compile
(
val
)
if
pattern
.
match
(
base_name
):
if
pattern
.
match
(
base_name
):
sys
.
stderr
.
write
(
'Ignoring "%s": file excluded by "%s". '
sys
.
stderr
.
write
(
'Ignoring "%s": file excluded by "%s". '
'File path component "%s" matches '
'File path component "%s" matches '
'pattern "%s"
\n
'
%
'pattern "%s"
\n
'
%
(
filename
,
cfg_file
,
base_name
,
val
))
(
filename
,
cfg_file
,
base_name
,
val
))
...
@@ -6119,7 +6200,8 @@ def ProcessConfigOverrides(filename):
...
@@ -6119,7 +6200,8 @@ def ProcessConfigOverrides(filename):
except
IOError
:
except
IOError
:
sys
.
stderr
.
write
(
sys
.
stderr
.
write
(
"Skipping config file '%s': Can't open for reading
\n
"
%
cfg_file
)
"Skipping config file '%s': Can't open for reading
\n
"
%
cfg_file
)
keep_looking
=
False
keep_looking
=
False
# Apply all the accumulated filters in reverse order (top-level directory
# Apply all the accumulated filters in reverse order (top-level directory
...
@@ -6167,7 +6249,8 @@ def ProcessFile(filename, vlevel, extra_check_functions=[]):
...
@@ -6167,7 +6249,8 @@ def ProcessFile(filename, vlevel, extra_check_functions=[]):
codecs
.
getwriter
(
'utf8'
),
codecs
.
getwriter
(
'utf8'
),
'replace'
).
read
().
split
(
'
\n
'
)
'replace'
).
read
().
split
(
'
\n
'
)
else
:
else
:
lines
=
codecs
.
open
(
filename
,
'r'
,
'utf8'
,
'replace'
).
read
().
split
(
'
\n
'
)
lines
=
codecs
.
open
(
filename
,
'r'
,
'utf8'
,
'replace'
).
read
().
split
(
'
\n
'
)
# Remove trailing '\r'.
# Remove trailing '\r'.
# The -1 accounts for the extra trailing blank line we get from split()
# The -1 accounts for the extra trailing blank line we get from split()
...
@@ -6179,8 +6262,8 @@ def ProcessFile(filename, vlevel, extra_check_functions=[]):
...
@@ -6179,8 +6262,8 @@ def ProcessFile(filename, vlevel, extra_check_functions=[]):
lf_lines
.
append
(
linenum
+
1
)
lf_lines
.
append
(
linenum
+
1
)
except
IOError
:
except
IOError
:
sys
.
stderr
.
write
(
sys
.
stderr
.
write
(
"Skipping input '%s': Can't open for reading
\n
"
%
"Skipping input '%s': Can't open for reading
\n
"
%
filename
)
filename
)
_RestoreFilters
()
_RestoreFilters
()
return
return
...
@@ -6252,12 +6335,10 @@ def ParseArguments(args):
...
@@ -6252,12 +6335,10 @@ def ParseArguments(args):
The list of filenames to lint.
The list of filenames to lint.
"""
"""
try
:
try
:
(
opts
,
filenames
)
=
getopt
.
getopt
(
args
,
''
,
[
'help'
,
'output='
,
'verbose='
,
(
opts
,
filenames
)
=
getopt
.
getopt
(
args
,
''
,
[
'counting='
,
'help'
,
'output='
,
'verbose='
,
'counting='
,
'filter='
,
'root='
,
'filter='
,
'linelength='
,
'extensions='
'root='
,
])
'linelength='
,
'extensions='
])
except
getopt
.
GetoptError
:
except
getopt
.
GetoptError
:
PrintUsage
(
'Invalid arguments.'
)
PrintUsage
(
'Invalid arguments.'
)
...
@@ -6271,7 +6352,9 @@ def ParseArguments(args):
...
@@ -6271,7 +6352,9 @@ def ParseArguments(args):
PrintUsage
(
None
)
PrintUsage
(
None
)
elif
opt
==
'--output'
:
elif
opt
==
'--output'
:
if
val
not
in
(
'emacs'
,
'vs7'
,
'eclipse'
):
if
val
not
in
(
'emacs'
,
'vs7'
,
'eclipse'
):
PrintUsage
(
'The only allowed output formats are emacs, vs7 and eclipse.'
)
PrintUsage
(
'The only allowed output formats are emacs, vs7 and eclipse.'
)
output_format
=
val
output_format
=
val
elif
opt
==
'--verbose'
:
elif
opt
==
'--verbose'
:
verbosity
=
int
(
val
)
verbosity
=
int
(
val
)
...
@@ -6281,7 +6364,8 @@ def ParseArguments(args):
...
@@ -6281,7 +6364,8 @@ def ParseArguments(args):
PrintCategories
()
PrintCategories
()
elif
opt
==
'--counting'
:
elif
opt
==
'--counting'
:
if
val
not
in
(
'total'
,
'toplevel'
,
'detailed'
):
if
val
not
in
(
'total'
,
'toplevel'
,
'detailed'
):
PrintUsage
(
'Valid counting options are total, toplevel, and detailed'
)
PrintUsage
(
'Valid counting options are total, toplevel, and detailed'
)
counting_style
=
val
counting_style
=
val
elif
opt
==
'--root'
:
elif
opt
==
'--root'
:
global
_root
global
_root
...
@@ -6317,8 +6401,7 @@ def main():
...
@@ -6317,8 +6401,7 @@ def main():
# if we try to print something containing non-ASCII characters.
# if we try to print something containing non-ASCII characters.
sys
.
stderr
=
codecs
.
StreamReaderWriter
(
sys
.
stderr
,
sys
.
stderr
=
codecs
.
StreamReaderWriter
(
sys
.
stderr
,
codecs
.
getreader
(
'utf8'
),
codecs
.
getreader
(
'utf8'
),
codecs
.
getwriter
(
'utf8'
),
codecs
.
getwriter
(
'utf8'
),
'replace'
)
'replace'
)
_cpplint_state
.
ResetErrorCounts
()
_cpplint_state
.
ResetErrorCounts
()
for
filename
in
filenames
:
for
filename
in
filenames
:
...
...
paddle/scripts/deb/build_scripts/build.sh
浏览文件 @
9115ab1c
...
@@ -33,5 +33,3 @@ cmake .. -DWITH_GPU=ON -DWITH_SWIG_PY=ON -DWITH_AVX=OFF -DCUDNN_ROOT=/usr/
...
@@ -33,5 +33,3 @@ cmake .. -DWITH_GPU=ON -DWITH_SWIG_PY=ON -DWITH_AVX=OFF -DCUDNN_ROOT=/usr/
make
-j
`
nproc
`
make
-j
`
nproc
`
cpack
-D
CPACK_GENERATOR
=
'DEB'
..
cpack
-D
CPACK_GENERATOR
=
'DEB'
..
mv
*
.deb ~/dist/gpu-noavx
mv
*
.deb ~/dist/gpu-noavx
paddle/scripts/docker/generate.sh
浏览文件 @
9115ab1c
...
@@ -58,4 +58,3 @@ m4 -DPADDLE_WITH_GPU=ON -DPADDLE_IS_DEVEL=ON -DPADDLE_WITH_DEMO=ON \
...
@@ -58,4 +58,3 @@ m4 -DPADDLE_WITH_GPU=ON -DPADDLE_IS_DEVEL=ON -DPADDLE_WITH_DEMO=ON \
-DPADDLE_BASE_IMAGE
=
nvidia/cuda:7.5-cudnn5-devel-ubuntu14.04
\
-DPADDLE_BASE_IMAGE
=
nvidia/cuda:7.5-cudnn5-devel-ubuntu14.04
\
-DPADDLE_WITH_AVX
=
OFF
\
-DPADDLE_WITH_AVX
=
OFF
\
Dockerfile.m4
>
Dockerfile.gpu-noavx-demo
Dockerfile.m4
>
Dockerfile.gpu-noavx-demo
paddle/scripts/travis/common.sh
浏览文件 @
9115ab1c
...
@@ -2,4 +2,3 @@
...
@@ -2,4 +2,3 @@
set
-e
set
-e
mkdir
-p
../../../build
mkdir
-p
../../../build
cd
../../../build
cd
../../../build
paddle/trainer/tests/test.txt
浏览文件 @
9115ab1c
...
@@ -998,4 +998,3 @@ from IN B-PP
...
@@ -998,4 +998,3 @@ from IN B-PP
Friday NNP B-NP
Friday NNP B-NP
's POS B-NP
's POS B-NP
Tokyo NNP I-NP
Tokyo NNP I-NP
paddle/trainer/tests/test_gen_dict.txt
浏览文件 @
9115ab1c
paddle/trainer/tests/train.txt
浏览文件 @
9115ab1c
...
@@ -4998,4 +4998,3 @@ However RB B-ADVP
...
@@ -4998,4 +4998,3 @@ However RB B-ADVP
the DT B-NP
the DT B-NP
disclosure NN I-NP
disclosure NN I-NP
of IN B-PP
of IN B-PP
paddle/utils/tests/test_CommandLineParser.cpp
浏览文件 @
9115ab1c
...
@@ -109,4 +109,3 @@ int main(int argc, char** argv) {
...
@@ -109,4 +109,3 @@ int main(int argc, char** argv) {
}
}
#endif
#endif
python/paddle/trainer/config_parser.py
浏览文件 @
9115ab1c
...
@@ -410,8 +410,8 @@ def RecurrentLayerGroupEnd(name):
...
@@ -410,8 +410,8 @@ def RecurrentLayerGroupEnd(name):
"RecurrentLayerGroup not begin"
)
"RecurrentLayerGroup not begin"
)
for
pair
in
g_current_submodel
.
memories
:
#check exist
for
pair
in
g_current_submodel
.
memories
:
#check exist
layer
=
g_layer_map
[
pair
.
layer_name
]
layer
=
g_layer_map
[
pair
.
layer_name
]
config_assert
(
layer
is
not
None
,
"memory declare wrong name:%s"
%
config_assert
(
layer
is
not
None
,
pair
.
layer_name
)
"memory declare wrong name:%s"
%
pair
.
layer_name
)
memory_link
=
g_layer_map
[
pair
.
link_name
]
memory_link
=
g_layer_map
[
pair
.
link_name
]
config_assert
(
layer
.
size
==
memory_link
.
size
,
config_assert
(
layer
.
size
==
memory_link
.
size
,
"memory declare wrong size:%d"
%
memory_link
.
size
)
"memory declare wrong size:%d"
%
memory_link
.
size
)
...
@@ -686,8 +686,8 @@ class ConvProjection(Projection):
...
@@ -686,8 +686,8 @@ class ConvProjection(Projection):
parse_conv
(
conv_conf
,
input_layer_name
,
self
.
proj_conf
.
conv_conf
,
parse_conv
(
conv_conf
,
input_layer_name
,
self
.
proj_conf
.
conv_conf
,
num_filters
)
num_filters
)
# TODO: support rectangle input
# TODO: support rectangle input
self
.
proj_conf
.
output_size
=
(
self
.
proj_conf
.
conv_conf
.
output_x
**
self
.
proj_conf
.
output_size
=
(
self
.
proj_conf
.
conv_conf
.
output_x
2
)
*
num_filters
**
2
)
*
num_filters
def
calc_output_size
(
self
,
input_layer_config
):
def
calc_output_size
(
self
,
input_layer_config
):
return
self
.
proj_conf
.
output_size
return
self
.
proj_conf
.
output_size
...
@@ -2793,8 +2793,8 @@ class ConcatenateLayer2(LayerBase):
...
@@ -2793,8 +2793,8 @@ class ConcatenateLayer2(LayerBase):
@
config_layer
(
'recurrent'
)
@
config_layer
(
'recurrent'
)
class
RecurrentLayer
(
LayerBase
):
class
RecurrentLayer
(
LayerBase
):
def
__init__
(
self
,
name
,
inputs
,
reversed
=
False
,
bias
=
True
,
**
xargs
):
def
__init__
(
self
,
name
,
inputs
,
reversed
=
False
,
bias
=
True
,
**
xargs
):
super
(
RecurrentLayer
,
self
).
__init__
(
name
,
'recurrent'
,
0
,
inputs
,
**
super
(
RecurrentLayer
,
self
).
__init__
(
name
,
'recurrent'
,
0
,
inputs
,
xargs
)
**
xargs
)
config_assert
(
len
(
self
.
inputs
)
==
1
,
'RecurrentLayer must have 1 input'
)
config_assert
(
len
(
self
.
inputs
)
==
1
,
'RecurrentLayer must have 1 input'
)
input_layer
=
self
.
get_input_layer
(
0
)
input_layer
=
self
.
get_input_layer
(
0
)
size
=
input_layer
.
size
size
=
input_layer
.
size
...
@@ -2876,22 +2876,22 @@ class MDLstmLayer(LayerBase):
...
@@ -2876,22 +2876,22 @@ class MDLstmLayer(LayerBase):
active_state_type
=
"sigmoid"
,
active_state_type
=
"sigmoid"
,
bias
=
True
,
bias
=
True
,
**
xargs
):
**
xargs
):
super
(
MDLstmLayer
,
self
).
__init__
(
name
,
'mdlstmemory'
,
0
,
inputs
,
**
super
(
MDLstmLayer
,
self
).
__init__
(
name
,
'mdlstmemory'
,
0
,
inputs
,
xargs
)
**
xargs
)
config_assert
(
len
(
self
.
inputs
)
==
1
,
'MDLstmLayer must have 1 input'
)
config_assert
(
len
(
self
.
inputs
)
==
1
,
'MDLstmLayer must have 1 input'
)
input_layer
=
self
.
get_input_layer
(
0
)
input_layer
=
self
.
get_input_layer
(
0
)
dim_num
=
len
(
directions
)
dim_num
=
len
(
directions
)
#check input_layer.size is divided by (3+dim_num)
#check input_layer.size is divided by (3+dim_num)
config_assert
(
input_layer
.
size
%
config_assert
(
input_layer
.
size
%
(
3
+
dim_num
)
==
0
,
(
3
+
dim_num
)
==
0
,
"size % (dim_num) should be 0!"
)
"size % (dim_num) should be 0!"
)
size
=
input_layer
.
size
/
(
3
+
dim_num
)
size
=
input_layer
.
size
/
(
3
+
dim_num
)
self
.
set_layer_size
(
size
)
self
.
set_layer_size
(
size
)
self
.
config
.
active_gate_type
=
active_gate_type
self
.
config
.
active_gate_type
=
active_gate_type
self
.
config
.
active_state_type
=
active_state_type
self
.
config
.
active_state_type
=
active_state_type
for
i
in
xrange
(
len
(
directions
)):
for
i
in
xrange
(
len
(
directions
)):
self
.
config
.
directions
.
append
(
int
(
directions
[
i
]))
self
.
config
.
directions
.
append
(
int
(
directions
[
i
]))
self
.
create_input_parameter
(
0
,
size
*
size
*
self
.
create_input_parameter
(
0
,
size
*
size
*
(
3
+
dim_num
),
(
3
+
dim_num
),
[
size
,
size
,
3
+
dim_num
])
[
size
,
size
,
3
+
dim_num
])
#bias includes 3 kinds of peephole, 3+dim_num+2+dim_num
#bias includes 3 kinds of peephole, 3+dim_num+2+dim_num
self
.
create_bias_parameter
(
bias
,
size
*
(
5
+
2
*
dim_num
))
self
.
create_bias_parameter
(
bias
,
size
*
(
5
+
2
*
dim_num
))
...
@@ -2929,8 +2929,8 @@ class GruStepLayer(LayerBase):
...
@@ -2929,8 +2929,8 @@ class GruStepLayer(LayerBase):
active_gate_type
=
"sigmoid"
,
active_gate_type
=
"sigmoid"
,
bias
=
True
,
bias
=
True
,
**
xargs
):
**
xargs
):
super
(
GruStepLayer
,
self
).
__init__
(
name
,
'gru_step'
,
size
,
inputs
,
**
super
(
GruStepLayer
,
self
).
__init__
(
name
,
'gru_step'
,
size
,
inputs
,
xargs
)
**
xargs
)
config_assert
(
len
(
self
.
inputs
)
==
2
,
'GruStepLayer must have 2 input'
)
config_assert
(
len
(
self
.
inputs
)
==
2
,
'GruStepLayer must have 2 input'
)
input_layer0
=
self
.
get_input_layer
(
0
)
input_layer0
=
self
.
get_input_layer
(
0
)
input_layer1
=
self
.
get_input_layer
(
1
)
input_layer1
=
self
.
get_input_layer
(
1
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录