Make ConfigWriter simpler
- Remove varg WriteLine
- No prefix
- Add WriteVars for writing multiple lines using "="/ "+="
This refactoring is a prep for removing "ResolveVariables()" which is very slow.
Bug: 149020353
Test: atest --test-mapping system/linkerconfig
Change-Id: I6bf2204a9ac0794b0bdf8028999a3543821a26be
diff --git a/modules/configuration.cc b/modules/configuration.cc
index 555ca99..294ed0f 100644
--- a/modules/configuration.cc
+++ b/modules/configuration.cc
@@ -38,8 +38,7 @@
<< " will be ignored.";
} else {
resolved_dirs[resolved_dir] = dir_to_section.second;
- writer.WriteLine(
- "dir.%s = %s", dir_to_section.second.c_str(), resolved_dir.c_str());
+ writer.WriteLine("dir." + dir_to_section.second + " = " + resolved_dir);
}
}
diff --git a/modules/configwriter.cc b/modules/configwriter.cc
index 0b2db69..9c1ae0e 100644
--- a/modules/configwriter.cc
+++ b/modules/configwriter.cc
@@ -16,9 +16,6 @@
#include "linkerconfig/configwriter.h"
-#include <cstdarg>
-#include <cstdio>
-
#include "linkerconfig/log.h"
#include "linkerconfig/variables.h"
@@ -26,45 +23,18 @@
namespace linkerconfig {
namespace modules {
-void ConfigWriter::SetPrefix(const std::string& prefix) {
- prefix_ = prefix;
-}
-
-void ConfigWriter::ResetPrefix() {
- prefix_ = "";
-}
-
-void ConfigWriter::WriteLine(const char* format, ...) {
- va_list args_for_length, args;
-
- va_start(args, format);
- va_copy(args_for_length, args);
-
- int length = vsnprintf(nullptr, 0, format, args_for_length);
- va_end(args_for_length);
-
- if (length < 0) {
- LOG(ERROR) << "Failed to get length of the string with format " << format;
- va_end(args);
- return;
+void ConfigWriter::WriteVars(const std::string& var,
+ const std::vector<std::string>& values) {
+ bool is_first = true;
+ for (const auto& value : values) {
+ WriteLine(var + (is_first ? " = " : " += ") + value);
+ is_first = false;
}
-
- std::unique_ptr<char[]> formatted_string(new char[length + 1]);
-
- int res = vsnprintf(formatted_string.get(), length + 1, format, args);
- va_end(args);
-
- if (res < 0) {
- LOG(ERROR) << "Failed to write a string with format " << format;
- return;
- }
-
- WriteLine(std::string(formatted_string.get()));
}
void ConfigWriter::WriteLine(const std::string& line) {
- auto resolved_line = Variables::ResolveVariables(prefix_ + line);
- content_ << resolved_line << std::endl;
+ auto resolved_line = Variables::ResolveVariables(line);
+ content_ << resolved_line << '\n';
}
std::string ConfigWriter::ToString() {
diff --git a/modules/include/linkerconfig/configwriter.h b/modules/include/linkerconfig/configwriter.h
index 5f93e5f..a3016f7 100644
--- a/modules/include/linkerconfig/configwriter.h
+++ b/modules/include/linkerconfig/configwriter.h
@@ -17,6 +17,7 @@
#include <sstream>
#include <string>
+#include <vector>
namespace android {
namespace linkerconfig {
@@ -24,15 +25,12 @@
class ConfigWriter {
public:
- void SetPrefix(const std::string& prefix);
- void ResetPrefix();
+ void WriteVars(const std::string& var, const std::vector<std::string>& values);
void WriteLine(const std::string& line);
- void WriteLine(const char* format, ...);
std::string ToString();
private:
std::stringstream content_;
- std::string prefix_;
};
} // namespace modules
diff --git a/modules/link.cc b/modules/link.cc
index 4c0e2e9..b22ce22 100644
--- a/modules/link.cc
+++ b/modules/link.cc
@@ -34,23 +34,16 @@
}
void Link::WriteConfig(ConfigWriter& writer) const {
- writer.SetPrefix("namespace." + origin_namespace_ + ".link." +
- target_namespace_);
+ const auto prefix =
+ "namespace." + origin_namespace_ + ".link." + target_namespace_ + ".";
if (allow_all_shared_libs_) {
- writer.WriteLine(".allow_all_shared_libs = true");
+ writer.WriteLine(prefix + "allow_all_shared_libs = true");
} else if (!shared_libs_.empty()) {
- bool is_first = true;
-
- for (auto& lib_name : shared_libs_) {
- writer.WriteLine(
- ".shared_libs %s %s", is_first ? "=" : "+=", lib_name.c_str());
- is_first = false;
- }
+ writer.WriteVars(prefix + "shared_libs", shared_libs_);
} else {
LOG(WARNING) << "Ignored empty shared libs link from " << origin_namespace_
<< " to " << target_namespace_;
}
- writer.ResetPrefix();
}
} // namespace modules
diff --git a/modules/namespace.cc b/modules/namespace.cc
index 81f84b9..b553c46 100644
--- a/modules/namespace.cc
+++ b/modules/namespace.cc
@@ -50,17 +50,6 @@
ns.AddRequires(apex_info.require_libs);
}
-void Namespace::WritePathString(ConfigWriter& writer,
- const std::string& path_type,
- const std::vector<std::string>& path_list) {
- std::string prefix = path_type + ".paths ";
- bool is_first = true;
- for (auto& path : path_list) {
- writer.WriteLine(prefix + (is_first ? "= " : "+= ") + path);
- is_first = false;
- }
-}
-
Link& Namespace::GetLink(const std::string& target_namespace) {
for (auto& link : links_) {
if (link.To() == target_namespace) {
@@ -71,25 +60,19 @@
}
void Namespace::WriteConfig(ConfigWriter& writer) {
- writer.SetPrefix("namespace." + name_ + ".");
+ const auto prefix = "namespace." + name_ + ".";
- writer.WriteLine("isolated = %s", is_isolated_ ? "true" : "false");
+ writer.WriteLine(prefix + "isolated = " + (is_isolated_ ? "true" : "false"));
if (is_visible_) {
- writer.WriteLine("visible = true");
+ writer.WriteLine(prefix + "visible = true");
}
- WritePathString(writer, "search", search_paths_);
- WritePathString(writer, "permitted", permitted_paths_);
- WritePathString(writer, "asan.search", asan_search_paths_);
- WritePathString(writer, "asan.permitted", asan_permitted_paths_);
-
- bool is_first = true;
- for (const auto& whitelisted : whitelisted_) {
- writer.WriteLine(
- "whitelisted %s %s", is_first ? "=" : "+=", whitelisted.c_str());
- is_first = false;
- }
+ writer.WriteVars(prefix + "search.paths", search_paths_);
+ writer.WriteVars(prefix + "permitted.paths", permitted_paths_);
+ writer.WriteVars(prefix + "asan.search.paths", asan_search_paths_);
+ writer.WriteVars(prefix + "asan.permitted.paths", asan_permitted_paths_);
+ writer.WriteVars(prefix + "whitelisted", whitelisted_);
if (!links_.empty()) {
std::vector<std::string> link_list;
@@ -97,14 +80,12 @@
for (const auto& link : links_) {
link_list.push_back(link.To());
}
- writer.WriteLine("links = " + android::base::Join(link_list, ","));
+ writer.WriteLine(prefix + "links = " + android::base::Join(link_list, ","));
for (const auto& link : links_) {
link.WriteConfig(writer);
}
}
-
- writer.ResetPrefix();
}
void Namespace::AddSearchPath(const std::string& path, AsanPath path_from_asan) {
diff --git a/modules/section.cc b/modules/section.cc
index c665d56..325a3d3 100644
--- a/modules/section.cc
+++ b/modules/section.cc
@@ -33,7 +33,7 @@
namespace linkerconfig {
namespace modules {
void Section::WriteConfig(ConfigWriter& writer) {
- writer.WriteLine("[%s]", name_.c_str());
+ writer.WriteLine("[" + name_ + "]");
std::sort(namespaces_.begin(),
namespaces_.end(),
diff --git a/modules/tests/configwriter_test.cc b/modules/tests/configwriter_test.cc
index 4c5c9fa..23c903d 100644
--- a/modules/tests/configwriter_test.cc
+++ b/modules/tests/configwriter_test.cc
@@ -21,12 +21,6 @@
constexpr const char* kSampleContent = "Lorem ipsum dolor sit amet";
-constexpr const char* kExpectedResultWithPrefix =
- R"(Lorem ipsum dolor sit amet
-SAMPLE.TEST.Text : Lorem ipsum dolor sit amet
-end of context
-)";
-
constexpr const char* kExpectedResultWithVariables =
R"(/Value/Test
/Invalid_Value/Path
@@ -41,24 +35,6 @@
ASSERT_EQ(writer.ToString(), "Lorem ipsum dolor sit amet\n");
}
-TEST(linkerconfig_configwriter, write_with_format) {
- android::linkerconfig::modules::ConfigWriter writer;
- writer.WriteLine("Sample text(%d) : %s", 10, kSampleContent);
- ASSERT_EQ(writer.ToString(),
- "Sample text(10) : Lorem ipsum dolor sit amet\n");
-}
-
-TEST(linkerconfig_configwriter, write_with_prefix) {
- android::linkerconfig::modules::ConfigWriter writer;
- writer.WriteLine(kSampleContent);
- writer.SetPrefix("SAMPLE.TEST.");
- writer.WriteLine("Text : %s", kSampleContent);
- writer.ResetPrefix();
- writer.WriteLine("end of context");
-
- ASSERT_EQ(writer.ToString(), kExpectedResultWithPrefix);
-}
-
TEST(linkerconfig_configwriter, replace_variable) {
android::linkerconfig::modules::ConfigWriter writer;
@@ -70,4 +46,18 @@
writer.WriteLine("/@{Invalid_Key:}/Path2");
ASSERT_EQ(writer.ToString(), kExpectedResultWithVariables);
+}
+
+TEST(linkerconfig_configwriter, WriteVars) {
+ android::linkerconfig::modules::ConfigWriter writer;
+
+ writer.WriteVars("var1", {"value1", "value2"});
+ writer.WriteVars("var2", {"value1"});
+ writer.WriteVars("var3", {});
+
+ ASSERT_EQ(
+ "var1 = value1\n"
+ "var1 += value2\n"
+ "var2 = value1\n",
+ writer.ToString());
}
\ No newline at end of file