【问题标题】:c preprocessor with virtual file system带有虚拟文件系统的 c 预处理器
【发布时间】:2014-01-06 10:04:18
【问题描述】:

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

  1. 流程定义
  2. 过程包括

我想要的小例子:

输入

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 非常适合它。 但是我想要更多:包含文件的虚拟文件系统。 所以预处理器将从内存中的虚拟文件系统中获取包含文件,而不是从硬盘中获取。当我必须用许多不同的定义预处理同一个文件时,我需要它来进行更快的预处理。

所以问题是:是否存在像 boost::wave 这样的库,但支持虚拟文件系统?或者也许 boost::wave 以某种方式支持它?

【问题讨论】:

  • 这不是你的问题的答案,但是创建一个 RAM 磁盘并在那里复制头文件呢?
  • 我认为您可能会在一些编译器代码中找到一些有用的东西。叮当声可能会有所帮助。
  • 我认为完成 boost::wave 可能并不难。一方面,查找标头的方式是实现定义的(无论如何都未由 C++ 标准指定)。因此,为了通用,预处理器已经不会假设这些事情了。

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


【解决方案1】:

从文档到 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;
        };
    };

} } }

【讨论】:

  • 不幸的是,这不起作用。我用 hardcoded_header_policy 创建了一个简单的例子。然而 boost::wave 仅在搜索包含文件后才调用 init_iterators。因此代码因 boost::wave::cpp_exception 而失败,代码为 bad_include_file。
  • 对于 boost 1.53,改变上下文对象的 HooksT 模板参数就可以了。我将 default_preprocessing_hooks 子类化为覆盖 locate_include_file 函数。
  • @RomanSilakov 您可能希望将此作为答案包含在内,以便人们能够发现它已解决
【解决方案2】:

这里是为在 boost::wave (version 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;
   //...
}

【讨论】:

    猜你喜欢
    • 2010-11-24
    • 2013-04-28
    • 2016-09-28
    • 1970-01-01
    • 2015-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多