📄 testwave_app.cpp
字号:
<< std::endl;
}
ctx.add_sysinclude_path((*cit).c_str());
}
}
// add include directories to the user include search paths
if (vm.count("include")) {
cmd_line_utils::include_paths const &ip =
variables_map_as(vm["include"], (cmd_line_utils::include_paths*)NULL);
std::vector<std::string>::const_iterator end = ip.paths.end();
for (std::vector<std::string>::const_iterator cit = ip.paths.begin();
cit != end; ++cit)
{
if (9 == debuglevel) {
std::cerr << "initialise_options: option: -I" << *cit
<< std::endl;
}
ctx.add_include_path((*cit).c_str());
}
// if on the command line was given -I- , this has to be propagated
if (ip.seen_separator) {
if (9 == debuglevel) {
std::cerr << "initialise_options: option: -I-" << std::endl;
}
ctx.set_sysinclude_delimiter();
}
// add system include directories to the include path
std::vector<std::string>::const_iterator sysend = ip.syspaths.end();
for (std::vector<std::string>::const_iterator syscit = ip.syspaths.begin();
syscit != sysend; ++syscit)
{
if (9 == debuglevel) {
std::cerr << "initialise_options: option: -S" << *syscit
<< std::endl;
}
ctx.add_sysinclude_path((*syscit).c_str());
}
}
// add additional defined macros
if (vm.count("define")) {
std::vector<std::string> const ¯os =
variables_map_as(vm["define"], (std::vector<std::string>*)NULL);
std::vector<std::string>::const_iterator end = macros.end();
for (std::vector<std::string>::const_iterator cit = macros.begin();
cit != end; ++cit)
{
if (9 == debuglevel) {
std::cerr << "initialise_options: option: -D" << *cit
<< std::endl;
}
ctx.add_macro_definition(*cit);
}
}
// add additional predefined macros
if (vm.count("predefine")) {
std::vector<std::string> const &predefmacros =
variables_map_as(vm["predefine"], (std::vector<std::string>*)NULL);
std::vector<std::string>::const_iterator end = predefmacros.end();
for (std::vector<std::string>::const_iterator cit = predefmacros.begin();
cit != end; ++cit)
{
if (9 == debuglevel) {
std::cerr << "initialise_options: option: -P" << *cit
<< std::endl;
}
ctx.add_macro_definition(*cit);
}
}
// undefine specified macros
if (vm.count("undefine")) {
std::vector<std::string> const &undefmacros =
variables_map_as(vm["undefine"], (std::vector<std::string>*)NULL);
std::vector<std::string>::const_iterator end = undefmacros.end();
for (std::vector<std::string>::const_iterator cit = undefmacros.begin();
cit != end; ++cit)
{
if (9 == debuglevel) {
std::cerr << "initialise_options: option: -U" << *cit
<< std::endl;
}
ctx.remove_macro_definition((*cit).c_str());
}
}
// maximal include nesting depth
if (vm.count("nesting")) {
int max_depth = variables_map_as(vm["nesting"], (int*)NULL);
if (max_depth < 1 || max_depth > 100000) {
std::cerr << "testwave: bogus maximal include nesting depth: "
<< max_depth << std::endl;
return false;
}
else if (9 == debuglevel) {
std::cerr << "initialise_options: option: -n" << max_depth
<< std::endl;
}
ctx.set_max_include_nesting_depth(max_depth);
}
if (9 == debuglevel) {
std::cerr << "initialise_options: succeeded to initialise options"
<< std::endl;
}
return true;
}
///////////////////////////////////////////////////////////////////////////////
#ifdef BOOST_NO_STRINGSTREAM
#include <strstream>
#define BOOST_WAVETEST_OSSTREAM std::ostrstream
std::string BOOST_WAVETEST_GETSTRING(std::ostrstream& ss)
{
ss << ends;
std::string rval = ss.str();
ss.freeze(false);
return rval;
}
#else
#include <sstream>
#define BOOST_WAVETEST_GETSTRING(ss) ss.str()
#define BOOST_WAVETEST_OSSTREAM std::ostringstream
#endif
// construct a SIZEOF macro definition string and predefine this macro
template <typename Context>
inline bool
testwave_app::add_sizeof_definition(Context& ctx, char const *name, int value)
{
BOOST_WAVETEST_OSSTREAM strm;
strm << "__TESTWAVE_SIZEOF_" << name << "__=" << value;
std::string macro(BOOST_WAVETEST_GETSTRING(strm));
if (!ctx.add_macro_definition(macro)) {
std::cerr << "testwave: failed to predefine macro: " << macro
<< std::endl;
return false;
}
else if (9 == debuglevel) {
std::cerr << "add_sizeof_definition: predefined macro: " << macro
<< std::endl;
}
return true;
}
// construct a MIN macro definition string and predefine this macro
template <typename T, typename Context>
inline bool
testwave_app::add_min_definition(Context& ctx, char const *name)
{
BOOST_WAVETEST_OSSTREAM strm;
if (!std::numeric_limits<T>::is_signed) {
strm << "__TESTWAVE_" << name << "_MIN__="
<< "0x" << std::hex
<< (std::numeric_limits<T>::min)() << "U";
}
else {
strm << "__TESTWAVE_" << name << "_MIN__=( "
<< (std::numeric_limits<T>::min)()+1 << "-1)";
}
std::string macro(BOOST_WAVETEST_GETSTRING(strm));
if (!ctx.add_macro_definition(macro)) {
std::cerr << "testwave: failed to predefine macro: " << macro
<< std::endl;
return false;
}
else if (9 == debuglevel) {
std::cerr << "add_min_definition: predefined macro: " << macro
<< std::endl;
}
return true;
}
// construct a MAX macro definition string and predefine this macro
template <typename T, typename Context>
inline bool
testwave_app::add_max_definition(Context& ctx, char const *name)
{
BOOST_WAVETEST_OSSTREAM strm;
if (!std::numeric_limits<T>::is_signed) {
strm << "__TESTWAVE_" << name << "_MAX__="
<< "0x" << std::hex
<< (std::numeric_limits<T>::max)() << "U";
}
else {
strm << "__TESTWAVE_" << name << "_MAX__="
<< (std::numeric_limits<T>::max)();
}
std::string macro(BOOST_WAVETEST_GETSTRING(strm));
if (!ctx.add_macro_definition(macro)) {
std::cerr << "testwave: failed to predefine macro: " << macro
<< std::endl;
return false;
}
else if (9 == debuglevel) {
std::cerr << "add_max_definition: predefined macro: " << macro
<< std::endl;
}
return true;
}
#undef BOOST_WAVETEST_GETSTRING
#undef BOOST_WAVETEST_OSSTREAM
///////////////////////////////////////////////////////////////////////////////
//
// Add special predefined macros to the context object.
//
// This adds a lot of macros to the test environment, which allows to adjust
// the testcases for different platforms.
//
///////////////////////////////////////////////////////////////////////////////
template <typename Context>
bool
testwave_app::add_predefined_macros(Context& ctx)
{
// add the __TESTWAVE_SIZEOF_<type>__ macros
if (!add_sizeof_definition(ctx, "CHAR", sizeof(char)) ||
!add_sizeof_definition(ctx, "SHORT", sizeof(short)) ||
!add_sizeof_definition(ctx, "INT", sizeof(int)) ||
#if defined(BOOST_HAS_LONG_LONG)
!add_sizeof_definition(ctx, "LONGLONG", sizeof(boost::long_long_type)) ||
#endif
!add_sizeof_definition(ctx, "LONG", sizeof(long)))
{
std::cerr << "testwave: failed to add a predefined macro (SIZEOF)."
<< std::endl;
return false;
}
// add the __TESTWAVE_<type>_MIN__ macros
if (/*!add_min_definition<char>(ctx, "CHAR") ||*/
/*!add_min_definition<unsigned char>(ctx, "UCHAR") ||*/
!add_min_definition<short>(ctx, "SHORT") ||
!add_min_definition<unsigned short>(ctx, "USHORT") ||
!add_min_definition<int>(ctx, "INT") ||
!add_min_definition<unsigned int>(ctx, "UINT") ||
#if defined(BOOST_HAS_LONG_LONG)
!add_min_definition<boost::long_long_type>(ctx, "LONGLONG") ||
!add_min_definition<boost::ulong_long_type>(ctx, "ULONGLONG") ||
#endif
!add_min_definition<long>(ctx, "LONG") ||
!add_min_definition<unsigned long>(ctx, "ULONG"))
{
std::cerr << "testwave: failed to add a predefined macro (MIN)."
<< std::endl;
}
// add the __TESTWAVE_<type>_MAX__ macros
if (/*!add_max_definition<char>(ctx, "CHAR") ||*/
/*!add_max_definition<unsigned char>(ctx, "UCHAR") ||*/
!add_max_definition<short>(ctx, "SHORT") ||
!add_max_definition<unsigned short>(ctx, "USHORT") ||
!add_max_definition<int>(ctx, "INT") ||
!add_max_definition<unsigned int>(ctx, "UINT") ||
#if defined(BOOST_HAS_LONG_LONG)
!add_max_definition<boost::long_long_type>(ctx, "LONGLONG") ||
!add_max_definition<boost::ulong_long_type>(ctx, "ULONGLONG") ||
#endif
!add_max_definition<long>(ctx, "LONG") ||
!add_max_definition<unsigned long>(ctx, "ULONG"))
{
std::cerr << "testwave: failed to add a predefined macro (MAX)."
<< std::endl;
}
return true;
}
///////////////////////////////////////////////////////////////////////////////
//
// Preprocess the given input data and return the generated output through
// the parameter 'result'.
//
///////////////////////////////////////////////////////////////////////////////
bool
testwave_app::preprocess_file(std::string filename, std::string const& instr,
std::string& result, std::string& error)
{
// create the wave::context object and initialise it from the file to
// preprocess (may contain options inside of special comments)
typedef boost::wave::cpplexer::lex_token<> token_type;
typedef boost::wave::cpplexer::lex_iterator<token_type> lexer_type;
typedef boost::wave::context<std::string::const_iterator, lexer_type>
context_type;
if (9 == debuglevel) {
std::cerr << "preprocess_file: preprocessing input file: " << filename
<< std::endl;
}
try {
// create preprocesing context
context_type ctx(instr.begin(), instr.end(), filename.c_str());
// initialise the context from the options given on the command line
if (!initialise_options(ctx, global_vm))
return false;
// extract the options from the input data and initialise the context
if (!extract_options(filename, instr, ctx))
return false;
// add special predefined macros
if (!add_predefined_macros(ctx))
return false;
// preprocess the input, loop over all generated tokens collecting the
// generated text
context_type::iterator_type end = ctx.end();
for (context_type::iterator_type it = ctx.begin(); it != end; ++it)
{
using namespace boost::wave;
if (T_PP_LINE == token_id(*it)) {
// special handling of the whole #line directive is required to
// allow correct file name matching
if (!handle_line_directive(it, end, result))
return false; // unexpected eof
}
else {
// add the value of the current token
result = result + (*it).get_value().c_str();
}
}
error.clear();
}
catch (boost::wave::cpplexer::lexing_exception const& e) {
// some lexer error
TESTWAVE_OSSTREAM strm;
std::string filename = e.file_name();
strm
<< handle_filepath(filename) << "(" << e.line_no() << "): "
<< e.description() << std::endl;
error = TESTWAVE_GETSTRING(strm);
return false;
}
catch (boost::wave::cpp_exception const& e) {
// some preprocessing error
TESTWAVE_OSSTREAM strm;
std::string filename = e.file_name();
strm
<< handle_filepath(filename) << "(" << e.line_no() << "): "
<< e.description() << std::endl;
error = TESTWAVE_GETSTRING(strm);
return false;
}
if (9 == debuglevel) {
std::cerr << "preprocess_file: succeeded to preprocess input file: "
<< filename << std::endl;
}
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -