1 // deprecated_name_check implementation -----------------------------------// 2 3 // Copyright Beman Dawes 2002. 4 // Copyright Gennaro Prota 2006. 5 // Copyright Hartmut Kaiser 2016. 6 // 7 // Distributed under the Boost Software License, Version 1.0. 8 // (See accompanying file LICENSE_1_0.txt or copy at 9 // http://www.boost.org/LICENSE_1_0.txt) 10 11 #include <hpx/config/defines.hpp> 12 13 #include <algorithm> 14 15 #include "deprecated_name_check.hpp" 16 #include "boost/regex.hpp" 17 #include "boost/lexical_cast.hpp" 18 #include "function_hyper.hpp" 19 20 #include <set> 21 #include <string> 22 #include <vector> 23 24 namespace boost 25 { 26 namespace inspect 27 { 28 deprecated_names const names[] = 29 { 30 // boost::xyz 31 { "(\\bboost\\s*::\\s*move\\b)", "std::move" }, 32 { "(\\bboost\\s*::\\s*forward\\b)", "std::forward" }, 33 { "(\\bboost\\s*::\\s*noncopyable\\b)", "HPX_NON_COPYABLE" }, 34 { "(\\bboost\\s*::\\s*result_of\\b)", "std::result_of" }, 35 { "(\\bboost\\s*::\\s*decay\\b)", "std::decay" }, 36 { "(\\bboost\\s*::\\s*enable_if\\b)", "std::enable_if" }, 37 { "(\\bboost\\s*::\\s*disable_if\\b)", "std::enable_if" }, 38 { "(\\bboost\\s*::\\s*enable_if_c\\b)", "std::enable_if" }, 39 { "(\\bboost\\s*::\\s*disable_if_c\\b)", "std::enable_if" }, 40 { "(\\bboost\\s*::\\s*lazy_enable_if\\b)", "hpx::util::lazy_enable_if" }, 41 { "(\\bboost\\s*::\\s*lazy_disable_if\\b)", "hpx::util::lazy_enable_if" }, 42 { "(\\bboost\\s*::\\s*lazy_enable_if_c\\b)", "hpx::util::lazy_enable_if" }, 43 { "(\\bboost\\s*::\\s*lazy_disable_if_c\\b)", "hpx::util::lazy_enable_if" }, 44 { "(\\bboost\\s*::\\s*mpl\\b)", "no specific replacement" }, 45 { "(\\bboost\\s*::\\s*(is_[^\\s]*?\\b))", "std::\\2" }, 46 { "(\\bboost\\s*::\\s*(add_[^\\s]*?\\b))", "std::\\2" }, 47 { "(\\bboost\\s*::\\s*(remove_[^\\s]*?\\b))", "std::\\2" }, 48 { "(\\bboost\\s*::\\s*(((false)|(true))_type\\b))", "std::\\2" }, 49 { "(\\bboost\\s*::\\s*lock_guard\\b)", "std::lock_guard" }, 50 { "(\\bboost\\s*::\\s*unordered_map\\b)", "std::unordered_map" }, 51 { "(\\bboost\\s*::\\s*unordered_multimap\\b)", "std::unordered_multimap" }, 52 { "(\\bboost\\s*::\\s*unordered_set\\b)", "std::unordered_set" }, 53 { "(\\bboost\\s*::\\s*unordered_multiset\\b)", "std::unordered_multiset" }, 54 { "(\\bboost\\s*::\\s*detail\\s*::\\s*atomic_count\\b)", 55 "hpx::util::atomic_count" }, 56 { "(\\bboost\\s*::\\s*function\\b)", "hpx::util::function_nonser" }, 57 { "(\\bboost\\s*::\\s*shared_ptr\\b)", "std::shared_ptr" }, 58 { "(\\bboost\\s*::\\s*make_shared\\b)", "std::make_shared" }, 59 { "(\\bboost\\s*::\\s*enable_shared_from_this\\b)", 60 "std::enable_shared_from_this" }, 61 { "(\\bboost\\s*::\\s*bind\\b)", "hpx::util::bind" }, 62 { "(\\bboost\\s*::\\s*unique_lock\\b)", "std::unique_lock" }, 63 { "(\\bboost\\s*::\\s*chrono\\b)", "std::chrono" }, 64 { "(\\bboost\\s*::\\s*reference_wrapper\\b)", "std::reference_wrapper" }, 65 { "(\\bboost\\s*::\\s*(c?ref)\\b)", "std::\\2" }, 66 { "(\\bboost\\s*::\\s*(u?int[0-9]+_t)\\b)", "std::\\2" }, 67 { "(\\bboost\\s*::\\s*thread\\b)", "hpx::compat::thread" }, 68 { "(\\bboost\\s*::\\s*this_thread::\\s*get_id\\b)", "hpx::compat::this_thread::get_id" }, 69 { "(\\bboost\\s*::\\s*this_thread::\\s*yield\\b)", "hpx::compat::this_thread::yield" }, 70 { "(\\bboost\\s*::\\s*this_thread::\\s*sleep_until\\b)", "hpx::compat::this_thread::sleep_until" }, 71 { "(\\bboost\\s*::\\s*this_thread::\\s*sleep_for\\b)", "hpx::compat::this_thread::sleep_for" }, 72 { "(\\bboost\\s*::\\s*mutex\\b)", "hpx::compat::mutex" }, 73 { "(\\bboost\\s*::\\s*recursive_mutex\\b)", "hpx::compat::recursive_mutex" }, 74 { "(\\bboost\\s*::\\s*once_flag\\b)", "hpx::compat::once_flag" }, 75 { "(\\bboost\\s*::\\s*call_once\\b)", "hpx::compat::call_once" }, 76 { "(\\bboost\\s*::\\s*cv_status\\b)", "hpx::compat::cv_status" }, 77 { "(\\bboost\\s*::\\s*condition_variable\\b)", "hpx::compat::condition_variable" }, 78 { "(\\bboost\\s*::\\s*barrier\\b)", "hpx::compat::barrier" }, 79 { "(\\bboost\\s*::\\s*exception_ptr\\b)", "std::exception_ptr" }, 80 { "(\\bboost\\s*::\\s*copy_exception\\b)", "std::make_exception_ptr" }, 81 { "(\\bboost\\s*::\\s*current_exception\\b)", "std::current_exception" }, 82 { "(\\bboost\\s*::\\s*rethrow_exception\\b)", "std::rethrow_exception" }, 83 { "(\\bboost\\s*::\\s*enable_error_info\\b)", "hpx::throw_with_info" }, 84 { "(\\bboost\\s*::\\s*iterator_range\\b)", "hpx::util::iterator_range" }, 85 { "(\\bboost\\s*::\\s*make_iterator_range\\b)", "hpx::util::make_iterator_range" }, 86 { "(\\bboost\\s*::\\s*atomic_flag\\b)", "std::atomic_flag" }, 87 { "(\\bboost\\s*::\\s*atomic\\b)", "std::atomic" }, 88 { "(\\bboost\\s*::\\s*memory_order_((relaxed)|(acquire)|(release)|" 89 "(acq_rel)|(seq_cst))\\b)", "std::memory_order_\\2" }, 90 { "(\\bboost\\s*::\\s*random\\s*::\\s*([^\\s]*)\\b)", "std::\\2" }, 91 { "(\\bboost\\s*::\\s*format\\b)", "hpx::util::format[_to]" }, 92 ///////////////////////////////////////////////////////////////////////// 93 { "((\\bhpx::\\b)?\\btraits\\s*::\\bis_callable\\b)", "\\2traits::is_invocable[_r]" }, 94 { "((\\bhpx::\\b)?\\butil\\s*::\\bresult_of\\b)", "\\2util::invoke_result" }, 95 { "(\\bNULL\\b)", "nullptr" }, 96 // Boost preprocessor macros 97 { "\\b(BOOST_PP_CAT)\\b", "HPX_PP_CAT" }, 98 { "\\b(BOOST_PP_STRINGIZE)\\b", "HPX_PP_STRINGIZE" }, 99 { "\\b(BOOST_STRINGIZE)\\b", "HPX_PP_STRINGIZE(HPX_PP_EXPAND())" }, 100 { "\\b(BOOST_ASSERT)\\b", "HPX_ASSERT" }, 101 { nullptr, nullptr } 102 }; 103 104 // deprecated_name_check constructor --------------------------------- // 105 deprecated_name_check()106 deprecated_name_check::deprecated_name_check() 107 : m_errors(0) 108 { 109 // C/C++ source code... 110 register_signature( ".c" ); 111 register_signature( ".cpp" ); 112 register_signature( ".cxx" ); 113 register_signature( ".h" ); 114 register_signature( ".hpp" ); 115 register_signature( ".hxx" ); 116 register_signature( ".inc" ); 117 register_signature( ".ipp" ); 118 119 for (deprecated_names const* names_it = &names[0]; 120 names_it->name_regex != nullptr; 121 ++names_it) 122 { 123 std::string rx(names_it->name_regex); 124 rx += 125 "|" // or (ignored) 126 "(" 127 "//[^\\n]*" // single line comments (//) 128 "|" 129 "/\\*.*?\\*/" // multi line comments (/**/) 130 "|" 131 "\"([^\"\\\\]|\\\\.)*\"" // string literals 132 ")"; 133 regex_data.push_back(deprecated_names_regex_data(names_it, rx)); 134 } 135 } 136 137 // inspect ( C++ source files ) ---------------------------------------// 138 inspect(const string & library_name,const path & full_path,const string & contents)139 void deprecated_name_check::inspect( 140 const string & library_name, 141 const path & full_path, // example: c:/foo/boost/filesystem/path.hpp 142 const string & contents) // contents of file to be inspected 143 { 144 std::string::size_type p = contents.find( "hpxinspect:" "nodeprecatedname" ); 145 if (p != string::npos) 146 { 147 // ignore this directive here (it is handled below) if it is followed 148 // by a ':' 149 if (p == contents.size() - 27 || 150 (contents.size() > p + 27 && contents[p + 27] != ':')) 151 { 152 return; 153 } 154 } 155 156 std::set<std::string> found_names; 157 158 // for all given names, check whether any is used 159 for (deprecated_names_regex_data const& d : regex_data) 160 { 161 boost::sregex_iterator cur(contents.begin(), contents.end(), d.pattern), end; 162 for(/**/; cur != end; ++cur) 163 { 164 auto m = *cur; 165 if (m[1].matched) 166 { 167 // avoid errors to be reported twice 168 std::string found_name(m[1].first, m[1].second); 169 170 if (found_names.find(found_name) == found_names.end()) 171 { 172 std::string tag("hpxinspect:" "nodeprecatedname:" + found_name); 173 if (contents.find(tag) != string::npos) 174 continue; 175 176 // name was found 177 found_names.insert(found_name); 178 179 auto it = contents.begin(); 180 auto match_it = m[1].first; 181 auto line_start = it; 182 183 string::size_type line_number = 1; 184 for (/**/; it != match_it; ++it) 185 { 186 if (string::traits_type::eq(*it, '\n')) 187 { 188 ++line_number; 189 line_start = it + 1; // could be end() 190 } 191 } 192 193 ++m_errors; 194 error(library_name, full_path, string(name()) 195 + " deprecated name (" 196 + found_name 197 + ") on line " 198 + linelink(full_path, boost::lexical_cast<string>(line_number)) 199 + ", use " + m.format(d.data->use_instead) 200 + " instead"); 201 } 202 } 203 } 204 } 205 } 206 207 } // namespace inspect 208 } // namespace boost 209 210