Question

I want to find a library for preprocessing c files with following features:

  1. process defines
  2. process includes

Small example of what I want:

input

some_file.h

some_code

main.c

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

output (with SOME_DEFINE = TRUE) main.c

some_code
...

It seems that boost::wave fits perfectly for it. However I want something more: virtual file system for include files. So preprocessor will get include files from virtual file system in memory, and not from hdd. I need this to have faster preprocessing in situation when I have to preprocess same file with a lot of different defines.

So the question: does there exist a library like boost::wave, but with support for virtual file system? Or mayby boost::wave supports it somehow?

Was it helpful?

Solution 2

Here is snipped for hooking file loading in 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;
   //...
}

OTHER TIPS

From the docs to Boost Wave:

The Input Policy

The input policy type may be specified as a template parameter to the wave::context object and is used for customizing the way, how an included file is to be represented by a pair of iterators pointing to the beginning and the end of the resulting input sequence. If this template parameter is not given while instantiating the context object, it defaults to the iteration_context_policies::load_file_to_string type.

So the input_policy would appear to be your extension point. You could test it by just returning the iterators to a hard-coded text for demonstration purposes:

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;
        };
    };

} } }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top