From 226d2b38d9f118a3529741b30578bdcb82154701 Mon Sep 17 00:00:00 2001 From: Philip Top Date: Tue, 26 Nov 2019 11:29:43 -0800 Subject: [PATCH 1/3] fix some warnings generated from klocwork static analyzer --- include/CLI/App.hpp | 5 +++-- include/CLI/TypeTools.hpp | 29 +++++++++++++++-------------- include/CLI/Validators.hpp | 23 +++++++++++------------ 3 files changed, 29 insertions(+), 28 deletions(-) diff --git a/include/CLI/App.hpp b/include/CLI/App.hpp index 8a58e4223..704cd5947 100644 --- a/include/CLI/App.hpp +++ b/include/CLI/App.hpp @@ -751,10 +751,11 @@ class App { std::string flag_description = "") { CLI::callback_t fun = [function](const CLI::results_t &res) { - bool trigger; + bool trigger{false}; auto result = CLI::detail::lexical_cast(res[0], trigger); - if(trigger) + if(result && trigger) { function(); + } return result; }; return _add_flag_internal(flag_name, std::move(fun), std::move(flag_description)); diff --git a/include/CLI/TypeTools.hpp b/include/CLI/TypeTools.hpp index 29e86957c..d7af24f10 100644 --- a/include/CLI/TypeTools.hpp +++ b/include/CLI/TypeTools.hpp @@ -758,7 +758,7 @@ bool lexical_conversion(const std::vector &strings, T &output) { typename std::tuple_element<1, XC>::type v2; bool retval = lexical_assign(strings[0], v1); if(strings.size() > 1) { - retval &= lexical_assign(strings[1], v2); + retval = retval && lexical_assign(strings[1], v2); } if(retval) { output = T{v1, v2}; @@ -773,15 +773,17 @@ template ::value == expected_max_vector_size && type_count::value == 1, detail::enabler> = detail::dummy> bool lexical_conversion(const std::vector &strings, T &output) { - bool retval = true; output.clear(); output.reserve(strings.size()); for(const auto &elem : strings) { output.emplace_back(); - retval &= lexical_assign(elem, output.back()); + bool retval = lexical_assign(elem, output.back()); + if(!retval) { + return false; + } } - return (!output.empty()) && retval; + return (!output.empty()); } /// Lexical conversion of a vector types with type size of two @@ -791,15 +793,14 @@ template ::value == expected_max_vector_size && type_count::value == 2, detail::enabler> = detail::dummy> bool lexical_conversion(const std::vector &strings, T &output) { - bool retval = true; output.clear(); for(size_t ii = 0; ii < strings.size(); ii += 2) { typename std::tuple_element<0, typename XC::value_type>::type v1; typename std::tuple_element<1, typename XC::value_type>::type v2; - retval = lexical_assign(strings[ii], v1); + bool retval = lexical_assign(strings[ii], v1); if(strings.size() > ii + 1) { - retval &= lexical_assign(strings[ii + 1], v2); + retval = retval && lexical_assign(strings[ii + 1], v2); } if(retval) { output.emplace_back(v1, v2); @@ -807,7 +808,7 @@ bool lexical_conversion(const std::vector &strings, T &output) { return false; } } - return (!output.empty()) && retval; + return (!output.empty()); } /// Conversion to a vector type using a particular single type as the conversion type @@ -823,7 +824,7 @@ bool lexical_conversion(const std::vector &strings, T &output) { for(const auto &elem : strings) { output.emplace_back(); - retval &= lexical_assign(elem, output.back()); + retval = retval && lexical_assign(elem, output.back()); } return (!output.empty()) && retval; } @@ -857,12 +858,12 @@ template I::value, bool>::type tuple_conversion(const std::vector &strings, T &output) { bool retval = true; if(strings.size() > I) { - retval &= lexical_assign< - typename std::tuple_element::type, - typename std::conditional::value, typename std::tuple_element::type, XC>::type>( - strings[I], std::get(output)); + retval = retval && lexical_assign::type, + typename std::conditional::value, + typename std::tuple_element::type, + XC>::type>(strings[I], std::get(output)); } - retval &= tuple_conversion(strings, output); + retval = retval && tuple_conversion(strings, output); return retval; } diff --git a/include/CLI/Validators.hpp b/include/CLI/Validators.hpp index 23936b510..39b05b0a4 100644 --- a/include/CLI/Validators.hpp +++ b/include/CLI/Validators.hpp @@ -373,17 +373,16 @@ class IPV4Validator : public Validator { func_ = [](std::string &ip_addr) { auto result = CLI::detail::split(ip_addr, '.'); if(result.size() != 4) { - return "Invalid IPV4 address must have four parts (" + ip_addr + ')'; + return std::string("Invalid IPV4 address must have four parts (") + ip_addr + ')'; } int num; - bool retval = true; for(const auto &var : result) { - retval &= detail::lexical_cast(var, num); + bool retval = detail::lexical_cast(var, num); if(!retval) { - return "Failed parsing number (" + var + ')'; + return std::string( "Failed parsing number (") + var + ')'; } if(num < 0 || num > 255) { - return "Each IP number must be between 0 and 255 " + var; + return std::string("Each IP number must be between 0 and 255 ") + var; } } return std::string(); @@ -398,10 +397,10 @@ class PositiveNumber : public Validator { func_ = [](std::string &number_str) { double number; if(!detail::lexical_cast(number_str, number)) { - return "Failed parsing number: (" + number_str + ')'; + return std::string("Failed parsing number: (") + number_str + ')'; } if(number <= 0) { - return "Number less or equal to 0: (" + number_str + ')'; + return std::string("Number less or equal to 0: (") + number_str + ')'; } return std::string(); }; @@ -414,10 +413,10 @@ class NonNegativeNumber : public Validator { func_ = [](std::string &number_str) { double number; if(!detail::lexical_cast(number_str, number)) { - return "Failed parsing number: (" + number_str + ')'; + return std::string("Failed parsing number: (") + number_str + ')'; } if(number < 0) { - return "Number less than 0: (" + number_str + ')'; + return std::string("Number less than 0: (") + number_str + ')'; } return std::string(); }; @@ -431,7 +430,7 @@ class Number : public Validator { func_ = [](std::string &number_str) { double number; if(!detail::lexical_cast(number_str, number)) { - return "Failed parsing as a number (" + number_str + ')'; + return std::string("Failed parsing as a number (") + number_str + ')'; } return std::string(); }; @@ -482,7 +481,7 @@ class Range : public Validator { T val; bool converted = detail::lexical_cast(input, val); if((!converted) || (val < min || val > max)) - return "Value " + input + " not in range " + std::to_string(min) + " to " + std::to_string(max); + return std::string("Value ") + input + " not in range " + std::to_string(min) + " to " + std::to_string(max); return std::string(); }; @@ -508,7 +507,7 @@ class Bound : public Validator { T val; bool converted = detail::lexical_cast(input, val); if(!converted) { - return "Value " + input + " could not be converted"; + return std::string("Value ") + input + " could not be converted"; } if(val < min) input = detail::to_string(min); From 3673b0737775c9d7b5b5918096d4d91310bab864 Mon Sep 17 00:00:00 2001 From: Philip Top Date: Tue, 26 Nov 2019 20:54:31 -0800 Subject: [PATCH 2/3] Some more visual studio static analyzer and clang-tidy fixes --- include/CLI/Option.hpp | 2 +- include/CLI/TypeTools.hpp | 121 ++++++++++++++++++++++--------------- include/CLI/Validators.hpp | 11 ++-- tests/AppTest.cpp | 23 +++---- tests/CreationTest.cpp | 5 +- tests/HelpersTest.cpp | 12 ++-- 6 files changed, 101 insertions(+), 73 deletions(-) diff --git a/include/CLI/Option.hpp b/include/CLI/Option.hpp index 4a3871b82..d1aae7470 100644 --- a/include/CLI/Option.hpp +++ b/include/CLI/Option.hpp @@ -715,7 +715,7 @@ class Option : public OptionBase