c预处理器与虚拟文件系统

时间:2014-01-06 10:04:18

标签: c++ c boost c-preprocessor wave

我想找到一个用于预处理具有以下功能的c文件的库:

  1. 流程定义
  2. 流程包括
  3. 我想要的小例子:

    输入

    some_file.h

    some_code
    

    main.c

    #if SOME_DEFINE == TRUE
       #inlcude "some_file.h"
    #else
    #endif
    ...
    

    输出(SOME_DEFINE = TRUE) main.c中

    some_code
    ...
    

    似乎boost :: wave非常适合它。 但是我想要更多:包含文件的虚拟文件系统。 因此预处理器将从内存中的虚拟文件系统获取包含文件,而不是从hdd获取。当我必须使用许多不同的定义预处理相同的文件时,我需要这个以便更快地进行预处理。

    所以问题是:是否存在类似boost :: wave的库,但支持虚拟文件系统?或者mayby boost :: wave以某种方式支持它?

2 个答案:

答案 0 :(得分:2)

从文档到Boost Wave:

  

<强> The Input Policy

     

可以将输入策略类型指定为wave :: context对象的模板参数,并用于自定义方式,如何通过一对指向开头和结尾的迭代器来表示包含的文件。结果输入序列。如果在实例化上下文对象时未给出此模板参数,则默认为iteration_context_policies :: load_file_to_string类型。

因此input_policy似乎是您的扩展点。您可以通过将迭代器返回到硬编码文本来进行测试,以便进行演示:

namespace boost { namespace wave { namespace iteration_context_policies {

    struct hardcoded_header_policy {

        template <typename IterContext>
        class inner {

        public:
            // expose the begin and end iterators for the included file
            template <typename Position>
            static void init_iterators(IterContext &iter_ctx, Position const &act_pos)
            {
                typedef typename IterContext::iterator_type iterator_type;

                iter_ctx.hard_coded_contents = "// header file '" << iter_ctx.filename << "' intentionally left blank\n";

                iter_ctx.first = iterator_type(iter_ctx.hard_coded_contents.begin(), iter_ctx.hard_coded_contents.end(), PositionT(iter_ctx.filename));
                iter_ctx.last  = iterator_type();
            }

        private:
            std::string hard_coded_contents;
        };
    };

} } }

答案 1 :(得分:1)

这是剪辑用于在boost :: wave(版本1.53)

中挂钩文件加载
class custom_directives_hooks
   : public boost::wave::context_policies::default_preprocessing_hooks
{
public:
#if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0
   void found_include_directive(std::string const& filename, bool include_next)
   {}
#else
   template <typename ContextT>
   bool found_include_directive(ContextT const& ctx, std::string const& filename, bool include_next)
   {
      return false; // ok to include this file
   }
#endif

   template <typename ContextT>
   bool locate_include_file(ContextT& ctx, std::string &file_path,
      bool is_system, char const *current_name, std::string &dir_path,
      std::string &native_name)
   {
      //write code here to locate file
      return true; //or false if file is not found
   }
}

void main()
{
   //...
   //typedef for boost::wave context with hooks for file loading
   typedef boost::wave::cpplexer::lex_iterator< boost::wave::cpplexer::lex_token<> >
      lex_iterator_type;
   typedef boost::wave::context<
      std::string::iterator, lex_iterator_type,
      boost::wave::iteration_context_policies::load_file_to_string,
      custom_directives_hooks>
     context_type;
   //...
}