Store RcFile pointers, rather than inline objects.
Since RcFile hands out pointers to its string members, modifying
vector<RcFile> may cause reallocation, which invalidates handed out
pointers.
Fixes #205.
--
Change-Id: Id4eb0a4e8a52373130140f1de5697f4e4f4a6f95
Reviewed-on: https://bazel-review.googlesource.com/#/c/1360/
MOS_MIGRATED_REVID=94276823
diff --git a/src/main/cpp/option_processor.cc b/src/main/cpp/option_processor.cc
index 9500cf4..9a14484 100644
--- a/src/main/cpp/option_processor.cc
+++ b/src/main/cpp/option_processor.cc
@@ -47,7 +47,7 @@
}
blaze_exit_code::ExitCode OptionProcessor::RcFile::Parse(
- vector<RcFile>* rcfiles,
+ vector<RcFile*>* rcfiles,
map<string, vector<RcOption> >* rcoptions,
string* error) {
list<string> initial_import_stack;
@@ -57,12 +57,13 @@
}
blaze_exit_code::ExitCode OptionProcessor::RcFile::Parse(
- const string& filename,
+ const string& filename_ref,
const int index,
- vector<RcFile>* rcfiles,
+ vector<RcFile*>* rcfiles,
map<string, vector<RcOption> >* rcoptions,
list<string>* import_stack,
string* error) {
+ string filename(filename_ref); // file
string contents;
if (!ReadFile(filename, &contents)) {
// We checked for file readability before, so this is unexpected.
@@ -121,10 +122,10 @@
return blaze_exit_code::BAD_ARGV;
}
- rcfiles->push_back(RcFile(words[1], rcfiles->size()));
+ rcfiles->push_back(new RcFile(words[1], rcfiles->size()));
import_stack->push_back(words[1]);
- blaze_exit_code::ExitCode parse_exit_code = RcFile::Parse(
- rcfiles->back().Filename(), rcfiles->back().Index(),
+ blaze_exit_code::ExitCode parse_exit_code =
+ RcFile::Parse(rcfiles->back()->Filename(), rcfiles->back()->Index(),
rcfiles, rcoptions, import_stack, error);
if (parse_exit_code != blaze_exit_code::SUCCESS) {
return parse_exit_code;
@@ -260,18 +261,19 @@
if (use_master_blazerc) {
string depot_blazerc_path = FindDepotBlazerc(workspace);
if (!depot_blazerc_path.empty()) {
- blazercs_.push_back(RcFile(depot_blazerc_path, blazercs_.size()));
+ blazercs_.push_back(new RcFile(depot_blazerc_path, blazercs_.size()));
blaze_exit_code::ExitCode parse_exit_code =
- blazercs_.back().Parse(&blazercs_, &rcoptions_, error);
+ blazercs_.back()->Parse(&blazercs_, &rcoptions_, error);
if (parse_exit_code != blaze_exit_code::SUCCESS) {
return parse_exit_code;
}
}
string alongside_binary_blazerc = FindAlongsideBinaryBlazerc(cwd, args[0]);
if (!alongside_binary_blazerc.empty()) {
- blazercs_.push_back(RcFile(alongside_binary_blazerc, blazercs_.size()));
+ blazercs_.push_back(new RcFile(alongside_binary_blazerc,
+ blazercs_.size()));
blaze_exit_code::ExitCode parse_exit_code =
- blazercs_.back().Parse(&blazercs_, &rcoptions_, error);
+ blazercs_.back()->Parse(&blazercs_, &rcoptions_, error);
if (parse_exit_code != blaze_exit_code::SUCCESS) {
return parse_exit_code;
}
@@ -286,9 +288,9 @@
return find_blazerc_exit_code;
}
if (!user_blazerc_path.empty()) {
- blazercs_.push_back(RcFile(user_blazerc_path, blazercs_.size()));
+ blazercs_.push_back(new RcFile(user_blazerc_path, blazercs_.size()));
blaze_exit_code::ExitCode parse_exit_code =
- blazercs_.back().Parse(&blazercs_, &rcoptions_, error);
+ blazercs_.back()->Parse(&blazercs_, &rcoptions_, error);
if (parse_exit_code != blaze_exit_code::SUCCESS) {
return parse_exit_code;
}
@@ -347,7 +349,7 @@
// Process all elements except the last one.
for (; i < startup_options.size() - 1; i++) {
const RcOption& option = startup_options[i];
- const string& blazerc = blazercs_[option.rcfile_index()].Filename();
+ const string& blazerc = blazercs_[option.rcfile_index()]->Filename();
process_arg_exit_code = parsed_startup_options_->ProcessArg(
option.option(), startup_options[i + 1].option(), blazerc,
&is_space_separated, error);
@@ -362,7 +364,7 @@
if (i < startup_options.size()) {
const RcOption& option = startup_options[i];
if (IsArg(option.option())) {
- const string& blazerc = blazercs_[option.rcfile_index()].Filename();
+ const string& blazerc = blazercs_[option.rcfile_index()]->Filename();
process_arg_exit_code = parsed_startup_options_->ProcessArg(
option.option(), "", blazerc, &is_space_separated, error);
if (process_arg_exit_code != blaze_exit_code::SUCCESS) {
@@ -407,8 +409,8 @@
void OptionProcessor::AddRcfileArgsAndOptions(bool batch, const string& cwd) {
// Push the options mapping .blazerc numbers to filenames.
for (int i_blazerc = 0; i_blazerc < blazercs_.size(); i_blazerc++) {
- const RcFile& blazerc = blazercs_[i_blazerc];
- command_arguments_.push_back("--rc_source=" + blazerc.Filename());
+ const RcFile* blazerc = blazercs_[i_blazerc];
+ command_arguments_.push_back("--rc_source=" + blazerc->Filename());
}
// Push the option defaults
@@ -462,4 +464,11 @@
const BlazeStartupOptions& OptionProcessor::GetParsedStartupOptions() const {
return *parsed_startup_options_.get();
}
+
+OptionProcessor::~OptionProcessor() {
+ for (auto it : blazercs_) {
+ delete it;
+ }
+}
+
} // namespace blaze
diff --git a/src/main/cpp/option_processor.h b/src/main/cpp/option_processor.h
index 15724e8..5b12bcd 100644
--- a/src/main/cpp/option_processor.h
+++ b/src/main/cpp/option_processor.h
@@ -35,7 +35,7 @@
public:
OptionProcessor();
- virtual ~OptionProcessor() {}
+ virtual ~OptionProcessor();
// Parse a command line and the appropriate blazerc files. This should be
// invoked only once per OptionProcessor object.
@@ -87,7 +87,7 @@
public:
RcFile(const string& filename, int index);
blaze_exit_code::ExitCode Parse(
- std::vector<RcFile>* rcfiles,
+ std::vector<RcFile*>* rcfiles,
std::map<string, std::vector<RcOption> >* rcoptions,
string* error);
const string& Filename() const { return filename_; }
@@ -96,7 +96,7 @@
private:
static blaze_exit_code::ExitCode Parse(const string& filename,
const int index,
- std::vector<RcFile>* rcfiles,
+ std::vector<RcFile*>* rcfiles,
std::map<string,
std::vector<RcOption> >* rcoptions,
std::list<string>* import_stack,
@@ -109,7 +109,7 @@
void AddRcfileArgsAndOptions(bool batch, const string& cwd);
blaze_exit_code::ExitCode ParseStartupOptions(string *error);
- std::vector<RcFile> blazercs_;
+ std::vector<RcFile*> blazercs_;
std::map<string, std::vector<RcOption> > rcoptions_;
std::vector<string> args_;
unsigned int startup_args_;