From 114ac8d9dc5da558f024aae2b0052f2b41da46e7 Mon Sep 17 00:00:00 2001 From: Gunter Labes Date: Mon, 29 Jun 2009 21:07:15 +0000 Subject: [PATCH] re-apply accidentally reverted commits --- src/serialization/preprocessor.cpp | 126 ++++++++++------------------- 1 file changed, 44 insertions(+), 82 deletions(-) diff --git a/src/serialization/preprocessor.cpp b/src/serialization/preprocessor.cpp index f5820f76e37..043b536300f 100644 --- a/src/serialization/preprocessor.cpp +++ b/src/serialization/preprocessor.cpp @@ -364,6 +364,8 @@ class preprocessor_data: preprocessor std::string directory_; /** Buffer for delayed input processing. */ std::vector< std::string > strings_; + /** Mapping of macro arguments to their content. */ + std::map *local_defines_; /** Stack of nested preprocessing chunks. */ std::vector< token_desc > tokens_; /** @@ -394,7 +396,8 @@ public: std::istream *, std::string const &history, std::string const &name, int line, - std::string const &dir, std::string const &domain); + std::string const &dir, std::string const &domain, + std::map *defines); ~preprocessor_data(); virtual bool get_chunk(); }; @@ -414,7 +417,7 @@ preprocessor_file::preprocessor_file(preprocessor_streambuf &t, std::string cons delete file_stream; } else - new preprocessor_data(t, file_stream, "", name, 1, directory_name(name), t.textdomain_); + new preprocessor_data(t, file_stream, "", name, 1, directory_name(name), t.textdomain_, NULL); } pos_ = files_.begin(); end_ = files_.end(); @@ -442,11 +445,13 @@ bool preprocessor_file::get_chunk() preprocessor_data::preprocessor_data(preprocessor_streambuf &t, std::istream *i, std::string const &history, std::string const &name, int linenum, - std::string const &directory, std::string const &domain) : + std::string const &directory, std::string const &domain, + std::map *defines) : preprocessor(t), in_(i), directory_(directory), strings_(), + local_defines_(defines), tokens_(), slowpath_(0), skipping_(0), @@ -475,6 +480,7 @@ preprocessor_data::preprocessor_data(preprocessor_streambuf &t, preprocessor_data::~preprocessor_data() { + delete local_defines_; } void preprocessor_data::push_token(char t) @@ -777,7 +783,7 @@ bool preprocessor_data::get_chunk() target_.defines_->erase(symbol); LOG_CF << "undefine macro " << symbol << " (location " << target_.location_ << ")\n"; } else - comment = true; + comment = token.type != '{'; skip_eol(); if (comment) put('\n'); @@ -802,7 +808,7 @@ bool preprocessor_data::get_chunk() if (token.type == '{') { if (!strings_.back().empty()) { std::ostringstream error; - std::ostringstream location; + std::ostringstream location; error << "Can't parse new macro parameter with a macro call scope open"; location<::const_iterator arg; + preproc_map::const_iterator macro; // If this is a known pre-processing symbol, then we insert it, // otherwise we assume it's a file name to load. - preproc_map::const_iterator macro = target_.defines_->find(symbol); - if (macro != target_.defines_->end()) + if (local_defines_ && + (arg = local_defines_->find(symbol)) != local_defines_->end()) + { + if (strings_.size() - token.stack_pos != 1) + { + std::ostringstream error; + error << "macro argument '" << symbol + << "' does not expect any argument"; + std::ostringstream location; + location << linenum_ << ' ' << target_.location_; + target_.error(error.str(), location.str()); + } + std::ostringstream v; + v << arg->second << "\376line " << linenum_ << ' ' << target_.location_ + << "\n\376textdomain " << target_.textdomain_ << '\n'; + pop_token(); + put(v.str()); + } + else if ((macro = target_.defines_->find(symbol)) != target_.defines_->end()) { preproc_define const &val = macro->second; size_t nb_arg = strings_.size() - token.stack_pos - 1; - if (nb_arg != val.arguments.size()) { - std::ostringstream error; + if (nb_arg != val.arguments.size()) + { + std::ostringstream error; error << "preprocessor symbol '" << symbol << "' expects " << val.arguments.size() << " arguments, but has " << nb_arg << " arguments"; - std::ostringstream location; - location<write(&*i_bra - 1, i - i_bra + 1); - i_bra = i + 1; - } else if (i_bra == i_end) { - if (c == '#' && !quoting) { - // Keep track of textdomain changes in the body of the - // macro, so they can be restored after each substitution - // of a macro argument. - std::string::const_iterator i_beg = i + 1; - if (i_end - i_beg >= 13 && - std::equal(i_beg, i_beg + 10, "textdomain")) { - i_beg += 10; - i = std::find(i_beg, i_end, '\n'); - if (i_beg != i) - ++i_beg; - macro_textdomain = std::string(i_beg, i); - *buffer << "#textdomain " << macro_textdomain; - ++macro_num; - c = '\n'; - } else if((i_end - i_beg < 6 || (!std::equal(i_beg, i_beg + 6, "define") - && !std::equal(i_beg, i_beg + 6, "ifndef"))) - && (i_end - i_beg < 5 || (!std::equal(i_beg, i_beg + 5, "ifdef") - && !std::equal(i_beg, i_beg + 5, "endif") && !std::equal(i_beg, i_beg + 5, "undef"))) - && (i_end - i_beg < 4 || !std::equal(i_beg, i_beg + 4, "else"))) { - // Check for define, ifdef, ifndef, endif, undef, else. - // Otherwise, this is a comment and should be skipped. - i = std::find(i_beg, i_end, '\n'); - ++macro_num; - c = '\n'; - } - } - buffer->put(c); - } else if (c == '}') { - size_t sz = i - i_bra; - for(size_t n = 0; n < nb_arg; ++n) { - std::string const &arg = val.arguments[n]; - if (arg.size() != sz || - !std::equal(i_bra, i, arg.begin())) - continue; - *buffer << strings_[token.stack_pos + n + 1] - << "\376line " << macro_num - << ' ' << val.location << "\n\376textdomain " - << macro_textdomain << '\n'; - i_bra = i_end; - break; - } - if (i_bra != i_end) { - // The bracketed text was no macro argument - buffer->write(&*i_bra - 1, sz + 2); - i_bra = i_end; - } - } + std::istringstream *buffer = new std::istringstream(val.value); + std::map *defines = + new std::map; + for (size_t i = 0; i < nb_arg; ++i) { + (*defines)[val.arguments[i]] = strings_[token.stack_pos + i + 1]; } - pop_token(); std::string const &dir = directory_name(val.location.substr(0, val.location.find(' '))); if (!slowpath_) { DBG_CF << "substituting macro " << symbol << '\n'; new preprocessor_data(target_, buffer, val.location, "", - val.linenum, dir, val.textdomain); + val.linenum, dir, val.textdomain, defines); } else { DBG_CF << "substituting (slow) macro " << symbol << '\n'; std::ostringstream res; @@ -915,7 +877,7 @@ bool preprocessor_data::get_chunk() new preprocessor_streambuf(target_); { std::istream in(buf); new preprocessor_data(*buf, buffer, val.location, "", - val.linenum, dir, val.textdomain); + val.linenum, dir, val.textdomain, defines); res << in.rdbuf(); } delete buf; strings_.back() += res.str();