• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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