diff options
| author | Shinichiro Hamaji <shinichiro.hamaji@gmail.com> | 2015-07-28 17:07:57 +0900 |
|---|---|---|
| committer | Shinichiro Hamaji <shinichiro.hamaji@gmail.com> | 2015-07-29 12:54:07 +0900 |
| commit | fc14d5f97d00b51aae88cb193e749ed7804d82b3 (patch) | |
| tree | 1e7eda9459663cfad0e6121c76499ad5dd7f90e1 /func.cc | |
| parent | 865597be2b052f225f0abb2acb5fc1d541cc4c06 (diff) | |
[C++] Fix comment_in_command.mk
Diffstat (limited to 'func.cc')
| -rw-r--r-- | func.cc | 56 |
1 files changed, 55 insertions, 1 deletions
@@ -40,6 +40,60 @@ namespace { +// TODO: This code is very similar to +// NinjaGenerator::TranslateCommand. Factor them out. +shared_ptr<string> StripShellComment(shared_ptr<string> cmd) { + if (cmd->find('#') == string::npos) + return cmd; + + shared_ptr<string> res = make_shared<string>(); + bool prev_backslash = false; + // Set space as an initial value so the leading comment will be + // stripped out. + char prev_char = ' '; + char quote = 0; + bool done = false; + const char* in = cmd->c_str(); + for (; *in && !done; in++) { + switch (*in) { + case '#': + if (quote == 0 && isspace(prev_char)) { + while (*in && *in != '\n') + in++; + break; + } + + case '\'': + case '"': + case '`': + if (quote) { + if (quote == *in) + quote = 0; + } else if (!prev_backslash) { + quote = *in; + } + *res += *in; + break; + + case '\\': + *res += '\\'; + break; + + default: + *res += *in; + } + + if (*in == '\\') { + prev_backslash = !prev_backslash; + } else { + prev_backslash = false; + } + + prev_char = *in; + } + return res; +} + void PatsubstFunc(const vector<Value*>& args, Evaluator* ev, string* s) { shared_ptr<string> pat_str = args[0]->Eval(ev); shared_ptr<string> repl = args[1]->Eval(ev); @@ -437,7 +491,7 @@ void ShellFunc(const vector<Value*>& args, Evaluator* ev, string* s) { shared_ptr<string> cmd = args[0]->Eval(ev); if (ev->avoid_io() && !HasNoIoInShellScript(*cmd)) { *s += "$("; - *s += *cmd; + *s += *StripShellComment(cmd); *s += ")"; return; } |
