Я хочу найти библиотеку для предварительной обработки файлов 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, но с поддержкой виртуальной файловой системы? Или mayby boost :: wave это как-то поддерживает?
От документов до Boost Wave:
Тип политики ввода может быть указан в качестве параметра шаблона для объекта 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;
};
};
} } }
Ниже приведен пример загрузки файла в 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;
//...
}