in tools/worker/swift_runner.cc [214:264]
bool SwiftRunner::ProcessPossibleResponseFile(
const std::string &arg, std::function<void(const std::string &)> consumer) {
auto path = arg.substr(1);
std::ifstream original_file(path);
ArgsFile args_file(original_file);
// If we couldn't open it, maybe it's not a file; maybe it's just some other
// argument that starts with "@" such as "@loader_path/..."
if (!original_file.good()) {
consumer(arg);
return false;
}
// Read the file to a vector to prevent double I/O
auto args = ParseArguments(args_file);
// If we're forcing response files, process and send the arguments from this
// file directly to the consumer; they'll all get written to the same response
// file at the end of processing all the arguments.
if (force_response_file_) {
for (auto it = args.begin(); it != args.end(); ++it) {
// Arguments in response files might be quoted/escaped, so we need to
// unescape them ourselves.
ProcessArgument(it, Unescape(*it), consumer);
}
return true;
}
// Otherwise, open the file, process the arguments, and rewrite it if any of
// them have changed.
bool changed = false;
std::string arg_from_file;
std::vector<std::string> new_args;
for (auto it = args.begin(); it != args.end(); ++it) {
changed |= ProcessArgument(it, *it, [&](const std::string &processed_arg) {
new_args.push_back(processed_arg);
});
}
if (changed) {
auto new_file = WriteResponseFile(new_args);
consumer("@" + new_file->GetPath());
temp_files_.push_back(std::move(new_file));
} else {
// If none of the arguments changed, just keep the original response file
// argument.
consumer(arg);
}
return changed;
}