Add a chain style to formatter.
It is now valid to do, for example:
out.sIf("condition", [&] {
out << "statement1;" << "\n"
<< "statement2;" << "\n";
}).endl();
Test: compiles
Test: hidl_test
Change-Id: Iab104644a005ac8386813a0f249a87ebd0284837
diff --git a/generateCpp.cpp b/generateCpp.cpp
index 0ef61e1..ec79059 100644
--- a/generateCpp.cpp
+++ b/generateCpp.cpp
@@ -840,16 +840,12 @@
// static
void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
- out << "if (" << nonNull << " == nullptr) {\n";
- out.indent();
- out << "return ::android::hardware::Status::fromExceptionCode(\n";
- out.indent();
- out.indent();
- out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
- out.unindent();
- out.unindent();
- out.unindent();
- out << "}\n\n";
+ out.sIf(nonNull + " == nullptr", [&] {
+ out << "return ::android::hardware::Status::fromExceptionCode(\n";
+ out.indent(2, [&] {
+ out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
+ });
+ }).endl().endl();
}
status_t AST::generateTypeSource(
@@ -1229,18 +1225,13 @@
out.unindent();
out << "}\n\n";
- out << "if (_hidl_err == ::android::UNEXPECTED_NULL) {\n";
- out.indent();
- out << "_hidl_err = ::android::hardware::writeToParcel(\n";
- out.indent();
- out.indent();
- out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
- out << "_hidl_reply);\n";
- out.unindent();
- out.unindent();
-
- out.unindent();
- out << "}\n\n";
+ out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
+ out << "_hidl_err = ::android::hardware::writeToParcel(\n";
+ out.indent(2, [&] {
+ out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
+ out << "_hidl_reply);\n";
+ });
+ });
out << "return _hidl_err;\n";
diff --git a/utils/Formatter.cpp b/utils/Formatter.cpp
index 404c0c6..6709785 100644
--- a/utils/Formatter.cpp
+++ b/utils/Formatter.cpp
@@ -42,14 +42,21 @@
mIndentDepth -= level;
}
-void Formatter::indent(size_t level, std::function<void(void)> func) {
+Formatter &Formatter::indent(size_t level, std::function<void(void)> func) {
this->indent(level);
func();
this->unindent(level);
+ return *this;
}
-void Formatter::indent(std::function<void(void)> func) {
- this->indent(1, func);
+Formatter &Formatter::indent(std::function<void(void)> func) {
+ return this->indent(1, func);
+}
+
+Formatter &Formatter::block(std::function<void(void)> func) {
+ (*this) << "{\n";
+ this->indent(func);
+ return (*this) << "}";
}
void Formatter::setLinePrefix(const std::string &prefix) {
@@ -60,6 +67,26 @@
mLinePrefix = "";
}
+Formatter &Formatter::endl() {
+ return (*this) << "\n";
+}
+
+Formatter &Formatter::sIf(const std::string &cond, std::function<void(void)> block) {
+ (*this) << "if (" << cond << ") ";
+ return this->block(block);
+}
+
+Formatter &Formatter::sElseIf(const std::string &cond, std::function<void(void)> block) {
+ (*this) << " else if (" << cond << ") ";
+ return this->block(block);
+}
+
+Formatter &Formatter::sElse(std::function<void(void)> block) {
+ (*this) << " else ";
+ return this->block(block);
+}
+
+
Formatter &Formatter::operator<<(const std::string &out) {
const size_t len = out.length();
size_t start = 0;
diff --git a/utils/include/hidl-util/Formatter.h b/utils/include/hidl-util/Formatter.h
index 6264159..7a27287 100644
--- a/utils/include/hidl-util/Formatter.h
+++ b/utils/include/hidl-util/Formatter.h
@@ -24,7 +24,13 @@
namespace android {
+// Two styles to use a Formatter.
+// One is with .indent() calls and operator<<.
+// out << "if (good) {\n"; out.indent(); out << "blah\nblah\n"; out.unindent(); out << "}\n";
+// The other is with chain calls and lambda functions
+// out.sIf("good", [&] { out("blah").endl()("blah").endl(); }).endl();
struct Formatter {
+
// Assumes ownership of file. Directed to stdout if file == NULL.
Formatter(FILE *file = NULL);
~Formatter();
@@ -32,14 +38,46 @@
void indent(size_t level = 1);
void unindent(size_t level = 1);
+ // Note that The last \n after the last line is NOT added automatically.
// out.indent(2, [&] {
// out << "Meow\n";
// });
- void indent(size_t level, std::function<void(void)> func);
+ Formatter &indent(size_t level, std::function<void(void)> func);
+
+ // Note that The last \n after the last line is NOT added automatically.
// out.indent([&] {
// out << "Meow\n";
// });
- void indent(std::function<void(void)> func);
+ Formatter &indent(std::function<void(void)> func);
+
+ // A block inside braces.
+ // * No space will be added before the opening brace.
+ // * The last \n before the closing brace is added automatically.
+ // * There will NOT be a \n after the closing brace.
+ // out.block([&] {
+ // out << "one();\n"
+ // << "two();\n";
+ // });
+ // is equivalent to
+ // out << "{\n"
+ // << "one();\ntwo();\n" // func()
+ // << "}";
+ Formatter &block(std::function<void(void)> func);
+
+ // A synonym to (*this) << "\n";
+ Formatter &endl();
+
+ // out.sIf("z == 1", [&] {
+ // out << "doGoodStuff();\n";
+ // }).sElseIf("z == 2", [&] {
+ // out << "doBadStuff();\n";
+ // }).sElse([&] {
+ // out << "logFatal();\n";
+ // }).endl();
+ // note that there will be a space before the "else"-s.
+ Formatter &sIf(const std::string &cond, std::function<void(void)> block);
+ Formatter &sElseIf(const std::string &cond, std::function<void(void)> block);
+ Formatter &sElse(std::function<void(void)> block);
Formatter &operator<<(const std::string &out);
Formatter &operator<<(size_t n);