aboutsummaryrefslogtreecommitdiffstats
path: root/ninja.cc
diff options
context:
space:
mode:
authorColin Cross <ccross@android.com>2015-07-15 18:33:37 -0700
committerColin Cross <ccross@android.com>2015-07-15 18:45:33 -0700
commit2e032ba8df8f8c5f8178ecbdfcaf5391778212f6 (patch)
tree164e4feb1acdab8e6dd25aa161f770a4710b82eb /ninja.cc
parent6b1167f7d91d2be83e1b187ca307b6e1d6bba19d (diff)
downloadplatform_build_kati-2e032ba8df8f8c5f8178ecbdfcaf5391778212f6.tar.gz
platform_build_kati-2e032ba8df8f8c5f8178ecbdfcaf5391778212f6.tar.bz2
platform_build_kati-2e032ba8df8f8c5f8178ecbdfcaf5391778212f6.zip
[C++] Convert initial echo command into ninja description
If the first command for a rule is an echo with no redirections, strip any outer quotes and use the result as the ninja rule description. This makes Android builds much more readable by preventing every successful rule from writing a single line, allowing ninja to reuse the current line for its status.
Diffstat (limited to 'ninja.cc')
-rw-r--r--ninja.cc61
1 files changed, 60 insertions, 1 deletions
diff --git a/ninja.cc b/ninja.cc
index 7ef2bd6..747d959 100644
--- a/ninja.cc
+++ b/ninja.cc
@@ -245,6 +245,60 @@ class NinjaGenerator {
cmd_buf_.size() - orig_size);
}
+ bool GetDescriptionFromCommand(StringPiece cmd, string *out) {
+ cmd = TrimSpace(cmd);
+
+ if (!HasPrefix(cmd, "echo ")) {
+ return false;
+ }
+ cmd = cmd.substr(5, cmd.size());
+
+ cmd_buf_.clear();
+ cmd = TranslateCommand(cmd.as_string().c_str());
+
+ bool prev_backslash = false;
+ char quote = 0;
+ string out_buf;
+
+ // Strip outer quotes, and fail if it is not a single echo command
+ for (StringPiece::iterator in = cmd.begin(); in != cmd.end(); in++) {
+ if (prev_backslash) {
+ prev_backslash = false;
+ out_buf += *in;
+ } else if (*in == '\\') {
+ prev_backslash = true;
+ out_buf += *in;
+ } else if (quote) {
+ if (*in == quote) {
+ quote = 0;
+ } else {
+ out_buf += *in;
+ }
+ } else {
+ switch (*in) {
+ case '\'':
+ case '"':
+ case '`':
+ quote = *in;
+ break;
+
+ case '<':
+ case '>':
+ case '&':
+ case '|':
+ case ';':
+ return false;
+
+ default:
+ out_buf += *in;
+ }
+ }
+ }
+
+ *out = out_buf;
+ return true;
+ }
+
bool GenShellScript(const vector<Command*>& commands) {
bool use_gomacc = false;
bool should_ignore_error = false;
@@ -331,7 +385,12 @@ class NinjaGenerator {
if (!commands.empty()) {
rule_name = GenRuleName();
fprintf(fp_, "rule %s\n", rule_name.c_str());
- fprintf(fp_, " description = build $out\n");
+
+ string description = "build $out";
+ if (GetDescriptionFromCommand(*(commands[0]->cmd), &description)) {
+ commands[0]->cmd->assign("true");
+ }
+ fprintf(fp_, " description = %s\n", description.c_str());
use_local_pool |= GenShellScript(commands);
EmitDepfile();