[wave] resetting input stream during the lifetime of a wave::context

Hi there, I'm using boost::wave to implement a C/C++ preprocessor for the Synopsis (http://synopsis.fresco.org/) project. I have just been asked for support of the '-include' command line option, which, for typical compilers, means to preload an include file before parsing the actual input. I wonder how to implement that with wave. The wave::context<> constructor expects two input iterators (begin and end) which it will use during parsing. Relying only on this would mean I have to write my own iterators (or wrapper container) that is able to switch from one input source (the one specified by '-include') to the next (the actual input file). However, I believe there is a lot of value in wave::context<> being able to do that internally (either, by allowing to reassign a new pair of iterators, or by providing a copy constructor for the context that creates a new context from a new pair of iterators, but inherits the state of an existing context). Does anything like this exist ? Are there plans to support such use cases ? Many thanks, Stefan -- ...ich hab' noch einen Koffer in Berlin...

Stefan,
I'm using boost::wave to implement a C/C++ preprocessor for the Synopsis (http://synopsis.fresco.org/) project. I have just been asked for support of the '-include' command line option, which, for typical compilers, means to preload an include file before parsing the actual input.
I wonder how to implement that with wave. The wave::context<> constructor expects two input iterators (begin and end) which it will use during parsing. Relying only on this would mean I have to write my own iterators (or wrapper container) that is able to switch from one input source (the one specified by '-include') to the next (the actual input file).
However, I believe there is a lot of value in wave::context<> being able to do that internally (either, by allowing to reassign a new pair of iterators, or by providing a copy constructor for the context that creates a new context from a new pair of iterators, but inherits the state of an existing context).
Does anything like this exist ? Are there plans to support such use cases ?
Wave does already support that! The iterator returned from the context has a member function force_include(): context_type::iterator_type it = ctx.begin(); for (each of the files to be pre-included) it.force_include(filename, last_name); Note, you have to call force_include() in reverse order if compared to the sequence of files to pre-include, i.e. the file to be pre-included first has to be supplied to force_include() last. The additional flag (second parameter) has to be true when calling force_include() for the last time (for the 'first' file). Obviously you need to call force_include() _before_ you dereference the iterator for the first time. BTW, if you would like to see an example how to implement this, the wave driver applet has a command line option --forceinclude/-F allowing to specify one or several files to be pre-included before the actual preprocessing begins: vector<string>::const_reverse_iterator rend = force.rend(); for (vector<string>::const_reverse_iterator cit = force.rbegin(); cit != rend; /**/) { string filename(*cit); first.force_include(filename.c_str(), ++cit == rend); } where 'force' is a vector containing the filenames to pre-include and 'first' is the iterator returned from ctx.begin(). HTH Regards Hartmut

Hartmut Kaiser wrote:
Stefan,
Does anything like this exist ? Are there plans to support such use cases ?
Wave does already support that! The iterator returned from the context has a member function force_include():
context_type::iterator_type it = ctx.begin(); for (each of the files to be pre-included) it.force_include(filename, last_name);
Excellent ! Unfortunately it seems the context::iterator_type isn't documented anywhere, at least I couldn't find this feature in http://boost.org/libs/wave/doc/class_reference_context.html. Also, I believe the implementation contains a bug (though to be really sure I'd need to see the specification): It appears the force-included header is searched as if included by means of #include "file", i.e. starting in the directory containing the main input. In contrast, the gcc documentation explains that the search should disregard that main input's directory, and start searching in the current working directory instead (http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Preprocessor-Options.html#Prepro...). (Please bear with me for using gcc as the authoritative input ;-) ) Thanks a lot ! Stefan -- ...ich hab' noch einen Koffer in Berlin...

Stefan,
Does anything like this exist ? Are there plans to support such use cases ?
Wave does already support that! The iterator returned from the context has a member function force_include():
context_type::iterator_type it = ctx.begin(); for (each of the files to be pre-included) it.force_include(filename, last_name);
Excellent ! Unfortunately it seems the context::iterator_type isn't documented anywhere, at least I couldn't find this feature in http://boost.org/libs/wave/doc/class_reference_context.html.
You're right. It's not documented anywhere, I'll have to add this info.
Also, I believe the implementation contains a bug (though to be really sure I'd need to see the specification):
It appears the force-included header is searched as if included by means of #include "file", i.e. starting in the directory containing the main input.
In contrast, the gcc documentation explains that the search should disregard that main input's directory, and start searching in the current working directory instead (http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Preprocessor-Opti ons.html#Preprocessor-Options).
(Please bear with me for using gcc as the authoritative input ;-) )
You're right again. The filename is interpreted as if it has been specified by a #include "file" directive. Frankly, I didn't even look at the gcc behavior wrt this. I'm not sure about the rationale of gcc's behavior either, I chose Wave's behavior as to allow for (force-)include files in the directory containing the main file. Do you think we should change that behavior? Regards Hartmut
Thanks a lot !
Stefan
--
...ich hab' noch einen Koffer in Berlin... _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Hartmut Kaiser wrote:
You're right again. The filename is interpreted as if it has been specified by a #include "file" directive. Frankly, I didn't even look at the gcc behavior wrt this. I'm not sure about the rationale of gcc's behavior either, I chose Wave's behavior as to allow for (force-)include files in the directory containing the main file.
Do you think we should change that behavior?
For the rationale: I believe this is simply because, if the force-included file is indeed included before the main file is seen, the processor can't possibly know where to start searching, other than the current working directory. Yes, I'd much appreciate if the behavior was synchronized with gcc (if there is no real reason not to), as that avoids potential clashes. (As you know, Synopsis is used like a compiler, i.e. users are expected to pass the same arguments from the build system that are used in a compilation command. Thus it's important that the semantics are the same, too.) Thanks ! Stefan -- ...ich hab' noch einen Koffer in Berlin...

Stefan,
Yes, I'd much appreciate if the behavior was synchronized with gcc (if there is no real reason not to), as that avoids potential clashes. (As you know, Synopsis is used like a compiler, i.e. users are expected to pass the same arguments from the build system that are used in a compilation command. Thus it's important that the semantics are the same, too.)
I committed a fix to Boost CVS::HEAD. Try it out please. Regards Hartmut

Hartmut Kaiser wrote:
Stefan,
Yes, I'd much appreciate if the behavior was synchronized with gcc (if there is no real reason not to), as that avoids potential clashes. (As you know, Synopsis is used like a compiler, i.e. users are expected to pass the same arguments from the build system that are used in a compilation command. Thus it's important that the semantics are the same, too.)
I committed a fix to Boost CVS::HEAD. Try it out please.
The current version of wave doesn't compile for me (gcc-4.1.1): ./boost/wave/util/flex_string.hpp:1982: error: ‘copy_n’ is not a member of ‘boost::wave::util::flex_string_details’ (That appears to be a recent change as of three days ago.) Any idea what's wrong with that ? It doesn't look compiler-specific... Thanks, Stefan -- ...ich hab' noch einen Koffer in Berlin...

Stefan Seefeld wrote:
Yes, I'd much appreciate if the behavior was synchronized with gcc (if there is no real reason not to), as that avoids potential clashes. (As you know, Synopsis is used like a compiler, i.e. users are expected to pass the same arguments from the build system that are used in a compilation command. Thus it's important that the semantics are the same, too.)
I committed a fix to Boost CVS::HEAD. Try it out please.
The current version of wave doesn't compile for me (gcc-4.1.1):
./boost/wave/util/flex_string.hpp:1982: error: 'copy_n' is not a member of 'boost::wave::util::flex_string_details'
(That appears to be a recent change as of three days ago.)
Any idea what's wrong with that ? It doesn't look compiler-specific...
Doh! Sorry for that. Should be fixed now. Regards Hartmut
participants (2)
-
Hartmut Kaiser
-
Stefan Seefeld