1 /*============================================================================= 2 Boost.Wave: A Standard compliant C++ preprocessor library 3 http://www.boost.org/ 4 5 Copyright (c) 2001-2010 Hartmut Kaiser. 6 Copyrigth (c) 2020 Jeff Trull. Distributed under the Boost 7 Software License, Version 1.0. (See accompanying file 8 LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 9 =============================================================================*/ 10 11 #if !defined(BOOST_WAVE_CHECK_MACRO_NAMING_INCLUDED) 12 #define BOOST_WAVE_CHECK_MACRO_NAMING_INCLUDED 13 14 #include <boost/wave/token_ids.hpp> 15 #include <boost/wave/preprocessing_hooks.hpp> 16 #include <boost/regex.hpp> 17 18 #include <string> 19 #include <set> 20 21 /////////////////////////////////////////////////////////////////////////////// 22 // 23 // The macroname_preprocessing_hooks policy class is used to record the 24 // use of macros within a header file. 25 // 26 // This policy type is used as a template parameter to the 27 // boost::wave::context<> object. 28 // 29 /////////////////////////////////////////////////////////////////////////////// 30 class macroname_preprocessing_hooks 31 : public boost::wave::context_policies::default_preprocessing_hooks 32 { 33 public: macroname_preprocessing_hooks(boost::regex const & macro_regex,std::set<std::string> & bad_macros,std::string & include_guard)34 macroname_preprocessing_hooks(boost::regex const & macro_regex, 35 std::set<std::string>& bad_macros, 36 std::string& include_guard) 37 : macro_regex_(macro_regex), 38 bad_macros_(bad_macros), 39 include_guard_(include_guard), 40 suppress_includes_(false) 41 {} 42 43 /////////////////////////////////////////////////////////////////////////// 44 // 45 // Monitor macro definitions to verify they follow the required convention 46 // by overriding the defined_macro hook 47 // 48 /////////////////////////////////////////////////////////////////////////// 49 50 template <typename ContextT, typename TokenT, 51 typename ParametersT, typename DefinitionT> defined_macro(ContextT const &,TokenT const & name,bool,ParametersT const &,DefinitionT const &,bool is_predefined)52 void defined_macro(ContextT const & /* ctx */, TokenT const &name, 53 bool /* is_functionlike */, ParametersT const & /* parameters */, 54 DefinitionT const & /* definition */, bool is_predefined) 55 { 56 using namespace boost::wave; 57 if (!is_predefined && 58 !regex_match(name.get_value().c_str(), macro_regex_)) 59 bad_macros_.insert(name.get_value().c_str()); 60 } 61 62 // Wave only reports include guards in files that were actually included 63 // as a result we have to mock up the inclusion process. This means 64 // constructing a fake "includer" file in memory, and only permitting one 65 // level of includes (as we only want to analyze the header itself) 66 67 /////////////////////////////////////////////////////////////////////////// 68 // 69 // Suppress includes of files other than the one we are analyzing 70 // using found_include_directive 71 // 72 /////////////////////////////////////////////////////////////////////////// 73 74 template <typename ContextT> found_include_directive(ContextT const &,std::string const & filename,bool)75 bool found_include_directive(ContextT const& /* ctx */, 76 std::string const & filename, 77 bool /* include_next */) 78 { 79 return suppress_includes_; 80 } 81 82 /////////////////////////////////////////////////////////////////////////// 83 // 84 // Suppress includes beyond the first level by setting our flag 85 // from opened_include_file 86 // 87 /////////////////////////////////////////////////////////////////////////// 88 89 template <typename ContextT> opened_include_file(ContextT const &,std::string const &,std::string const &,bool)90 void opened_include_file(ContextT const& /* ctx */, 91 std::string const & /* rel_filename */, 92 std::string const & /* abs_filename */, 93 bool /* is_system_include */) 94 { 95 suppress_includes_ = true; 96 } 97 98 // we only study one file, so no need to restore the ability to include 99 100 /////////////////////////////////////////////////////////////////////////// 101 // 102 // Record detected include guard macros 103 // 104 /////////////////////////////////////////////////////////////////////////// 105 106 template <typename ContextT> detected_include_guard(ContextT const &,std::string filename,std::string const & include_guard)107 void detected_include_guard(ContextT const& /* ctx */, 108 std::string filename, 109 std::string const& include_guard) 110 { 111 include_guard_ = include_guard; 112 } 113 114 115 private: 116 boost::regex const & macro_regex_; 117 std::set<std::string>& bad_macros_; 118 std::string& include_guard_; 119 bool suppress_includes_; 120 }; 121 122 #endif // !defined(BOOST_WAVE_CHECK_MACRO_NAMING_INCLUDED) 123