mirror of
https://github.com/wesnoth/wesnoth
synced 2025-05-08 17:26:24 +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_;
|
std::string directory_;
|
||||||
/** Buffer for delayed input processing. */
|
/** Buffer for delayed input processing. */
|
||||||
std::vector< std::string > strings_;
|
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. */
|
/** Stack of nested preprocessing chunks. */
|
||||||
std::vector< token_desc > tokens_;
|
std::vector< token_desc > tokens_;
|
||||||
/**
|
/**
|
||||||
@ -394,7 +396,8 @@ public:
|
|||||||
std::istream *,
|
std::istream *,
|
||||||
std::string const &history,
|
std::string const &history,
|
||||||
std::string const &name, int line,
|
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();
|
~preprocessor_data();
|
||||||
virtual bool get_chunk();
|
virtual bool get_chunk();
|
||||||
};
|
};
|
||||||
@ -414,7 +417,7 @@ preprocessor_file::preprocessor_file(preprocessor_streambuf &t, std::string cons
|
|||||||
delete file_stream;
|
delete file_stream;
|
||||||
}
|
}
|
||||||
else
|
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();
|
pos_ = files_.begin();
|
||||||
end_ = files_.end();
|
end_ = files_.end();
|
||||||
@ -442,11 +445,13 @@ bool preprocessor_file::get_chunk()
|
|||||||
|
|
||||||
preprocessor_data::preprocessor_data(preprocessor_streambuf &t,
|
preprocessor_data::preprocessor_data(preprocessor_streambuf &t,
|
||||||
std::istream *i, std::string const &history, std::string const &name, int linenum,
|
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),
|
preprocessor(t),
|
||||||
in_(i),
|
in_(i),
|
||||||
directory_(directory),
|
directory_(directory),
|
||||||
strings_(),
|
strings_(),
|
||||||
|
local_defines_(defines),
|
||||||
tokens_(),
|
tokens_(),
|
||||||
slowpath_(0),
|
slowpath_(0),
|
||||||
skipping_(0),
|
skipping_(0),
|
||||||
@ -475,6 +480,7 @@ preprocessor_data::preprocessor_data(preprocessor_streambuf &t,
|
|||||||
|
|
||||||
preprocessor_data::~preprocessor_data()
|
preprocessor_data::~preprocessor_data()
|
||||||
{
|
{
|
||||||
|
delete local_defines_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void preprocessor_data::push_token(char t)
|
void preprocessor_data::push_token(char t)
|
||||||
@ -777,7 +783,7 @@ bool preprocessor_data::get_chunk()
|
|||||||
target_.defines_->erase(symbol);
|
target_.defines_->erase(symbol);
|
||||||
LOG_CF << "undefine macro " << symbol << " (location " << target_.location_ << ")\n";
|
LOG_CF << "undefine macro " << symbol << " (location " << target_.location_ << ")\n";
|
||||||
} else
|
} else
|
||||||
comment = true;
|
comment = token.type != '{';
|
||||||
skip_eol();
|
skip_eol();
|
||||||
if (comment)
|
if (comment)
|
||||||
put('\n');
|
put('\n');
|
||||||
@ -816,98 +822,54 @@ bool preprocessor_data::get_chunk()
|
|||||||
std::string::iterator b = symbol.begin(); // invalidated at each iteration
|
std::string::iterator b = symbol.begin(); // invalidated at each iteration
|
||||||
symbol.erase(b + pos, b + symbol.find('\n', pos + 1) + 1);
|
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,
|
// If this is a known pre-processing symbol, then we insert it,
|
||||||
// otherwise we assume it's a file name to load.
|
// otherwise we assume it's a file name to load.
|
||||||
preproc_map::const_iterator macro = target_.defines_->find(symbol);
|
if (local_defines_ &&
|
||||||
if (macro != target_.defines_->end())
|
(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;
|
preproc_define const &val = macro->second;
|
||||||
size_t nb_arg = strings_.size() - token.stack_pos - 1;
|
size_t nb_arg = strings_.size() - token.stack_pos - 1;
|
||||||
if (nb_arg != val.arguments.size()) {
|
if (nb_arg != val.arguments.size())
|
||||||
|
{
|
||||||
std::ostringstream error;
|
std::ostringstream error;
|
||||||
error << "preprocessor symbol '" << symbol << "' expects "
|
error << "preprocessor symbol '" << symbol << "' expects "
|
||||||
<< val.arguments.size() << " arguments, but has "
|
<< val.arguments.size() << " arguments, but has "
|
||||||
<< nb_arg << " arguments";
|
<< nb_arg << " arguments";
|
||||||
std::ostringstream location;
|
std::ostringstream location;
|
||||||
location<<linenum_<<' '<<target_.location_;
|
location << linenum_ << ' ' << target_.location_;
|
||||||
target_.error(error.str(), location.str());
|
target_.error(error.str(), location.str());
|
||||||
}
|
}
|
||||||
|
std::istringstream *buffer = new std::istringstream(val.value);
|
||||||
std::stringstream *buffer = new std::stringstream;
|
std::map<std::string, std::string> *defines =
|
||||||
std::string::const_iterator i_bra = val.value.end();
|
new std::map<std::string, std::string>;
|
||||||
int macro_num = val.linenum;
|
for (size_t i = 0; i < nb_arg; ++i) {
|
||||||
std::string macro_textdomain = val.textdomain;
|
(*defines)[val.arguments[i]] = strings_[token.stack_pos + i + 1];
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pop_token();
|
pop_token();
|
||||||
std::string const &dir = directory_name(val.location.substr(0, val.location.find(' ')));
|
std::string const &dir = directory_name(val.location.substr(0, val.location.find(' ')));
|
||||||
if (!slowpath_) {
|
if (!slowpath_) {
|
||||||
DBG_CF << "substituting macro " << symbol << '\n';
|
DBG_CF << "substituting macro " << symbol << '\n';
|
||||||
new preprocessor_data(target_, buffer, val.location, "",
|
new preprocessor_data(target_, buffer, val.location, "",
|
||||||
val.linenum, dir, val.textdomain);
|
val.linenum, dir, val.textdomain, defines);
|
||||||
} else {
|
} else {
|
||||||
DBG_CF << "substituting (slow) macro " << symbol << '\n';
|
DBG_CF << "substituting (slow) macro " << symbol << '\n';
|
||||||
std::ostringstream res;
|
std::ostringstream res;
|
||||||
@ -915,7 +877,7 @@ bool preprocessor_data::get_chunk()
|
|||||||
new preprocessor_streambuf(target_);
|
new preprocessor_streambuf(target_);
|
||||||
{ std::istream in(buf);
|
{ std::istream in(buf);
|
||||||
new preprocessor_data(*buf, buffer, val.location, "",
|
new preprocessor_data(*buf, buffer, val.location, "",
|
||||||
val.linenum, dir, val.textdomain);
|
val.linenum, dir, val.textdomain, defines);
|
||||||
res << in.rdbuf(); }
|
res << in.rdbuf(); }
|
||||||
delete buf;
|
delete buf;
|
||||||
strings_.back() += res.str();
|
strings_.back() += res.str();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user