带有虚拟文件系统的 c 预处理器
Posted
技术标签:
【中文标题】带有虚拟文件系统的 c 预处理器【英文标题】:c preprocessor with virtual file system 【发布时间】:2014-01-06 10:04:18 【问题描述】:我想找一个具有以下功能的用于预处理 c 文件的库:
-
流程定义
过程包括
我想要的小例子:
输入
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++ 标准指定)。因此,为了通用,预处理器已经不会假设这些事情了。 【参考方案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;
//...
【讨论】:
以上是关于带有虚拟文件系统的 c 预处理器的主要内容,如果未能解决你的问题,请参考以下文章