mirror of
https://github.com/wesnoth/wesnoth
synced 2025-05-07 07:54:04 +00:00
re-apply accidentally reverted commits
This commit is contained in:
parent
db81f3e343
commit
114ac8d9dc
@ -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<std::string, std::string> *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<std::string, std::string> *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<std::string, std::string> *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<<linenum_<<' '<<target_.location_;
|
||||
target_.error(error.str(), location.str());
|
||||
@ -816,98 +822,54 @@ bool preprocessor_data::get_chunk()
|
||||
std::string::iterator b = symbol.begin(); // invalidated at each iteration
|
||||
symbol.erase(b + pos, b + symbol.find('\n', pos + 1) + 1);
|
||||
}
|
||||
std::map<std::string, std::string>::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<<linenum_<<' '<<target_.location_;
|
||||
std::ostringstream location;
|
||||
location << linenum_ << ' ' << target_.location_;
|
||||
target_.error(error.str(), location.str());
|
||||
}
|
||||
|
||||
std::stringstream *buffer = new std::stringstream;
|
||||
std::string::const_iterator i_bra = val.value.end();
|
||||
int macro_num = val.linenum;
|
||||
std::string macro_textdomain = val.textdomain;
|
||||
bool quoting = false;
|
||||
for(std::string::const_iterator i = val.value.begin(),
|
||||
i_end = val.value.end(); i != i_end; ++i) {
|
||||
char c = *i;
|
||||
if (c == '\n') {
|
||||
++macro_num;
|
||||
} else if (c == '"') {
|
||||
quoting = !quoting;
|
||||
}
|
||||
|
||||
if (c == '{') {
|
||||
if (i_bra != i_end)
|
||||
buffer->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<std::string, std::string> *defines =
|
||||
new std::map<std::string, std::string>;
|
||||
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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user