Shinichiro Hamaji | 1d545aa | 2015-06-23 15:29:13 +0900 | [diff] [blame] | 1 | // Copyright 2015 Google Inc. All rights reserved |
| 2 | // |
| 3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | // you may not use this file except in compliance with the License. |
| 5 | // You may obtain a copy of the License at |
| 6 | // |
| 7 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | // |
| 9 | // Unless required by applicable law or agreed to in writing, software |
| 10 | // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | // See the License for the specific language governing permissions and |
| 13 | // limitations under the License. |
| 14 | |
Fumitoshi Ukai | 744bb2b | 2015-06-25 00:10:52 +0900 | [diff] [blame] | 15 | // +build ignore |
| 16 | |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 17 | #include "rule.h" |
| 18 | |
Shinichiro Hamaji | 645cca7 | 2015-09-24 17:04:21 +0900 | [diff] [blame] | 19 | #include "expr.h" |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 20 | #include "log.h" |
Shinichiro Hamaji | 9b16bda | 2015-06-19 14:25:17 +0900 | [diff] [blame] | 21 | #include "parser.h" |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 22 | #include "stringprintf.h" |
| 23 | #include "strutil.h" |
Shinichiro Hamaji | e799275 | 2015-06-29 18:38:35 +0900 | [diff] [blame] | 24 | #include "symtab.h" |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 25 | |
Sasha Smundak | ce812f5 | 2018-08-15 14:49:39 -0700 | [diff] [blame] | 26 | Rule::Rule() : is_double_colon(false), is_suffix_rule(false), cmd_lineno(0) {} |
Shinichiro Hamaji | 9b16bda | 2015-06-19 14:25:17 +0900 | [diff] [blame] | 27 | |
Dan Willemsen | ee57a3f | 2018-11-05 16:18:44 -0800 | [diff] [blame] | 28 | void Rule::ParseInputs(const StringPiece& inputs_str) { |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 29 | bool is_order_only = false; |
Sasha Smundak | ce812f5 | 2018-08-15 14:49:39 -0700 | [diff] [blame] | 30 | for (auto const& input : WordScanner(inputs_str)) { |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 31 | if (input == "|") { |
| 32 | is_order_only = true; |
| 33 | continue; |
| 34 | } |
Shinichiro Hamaji | e799275 | 2015-06-29 18:38:35 +0900 | [diff] [blame] | 35 | Symbol input_sym = Intern(TrimLeadingCurdir(input)); |
Sasha Smundak | ce812f5 | 2018-08-15 14:49:39 -0700 | [diff] [blame] | 36 | (is_order_only ? order_only_inputs : inputs).push_back(input_sym); |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 37 | } |
| 38 | } |
| 39 | |
Sasha Smundak | ce812f5 | 2018-08-15 14:49:39 -0700 | [diff] [blame] | 40 | void Rule::ParsePrerequisites(const StringPiece& line, |
| 41 | size_t separator_pos, |
Dan Willemsen | ee57a3f | 2018-11-05 16:18:44 -0800 | [diff] [blame] | 42 | const RuleStmt* rule_stmt) { |
Sasha Smundak | ce812f5 | 2018-08-15 14:49:39 -0700 | [diff] [blame] | 43 | // line is either |
| 44 | // prerequisites [ ; command ] |
| 45 | // or |
| 46 | // target-prerequisites : prereq-patterns [ ; command ] |
| 47 | // First, separate command. At this point separator_pos should point to ';' |
| 48 | // unless null. |
| 49 | StringPiece prereq_string = line; |
Dan Willemsen | ee57a3f | 2018-11-05 16:18:44 -0800 | [diff] [blame] | 50 | if (separator_pos != string::npos && |
| 51 | rule_stmt->sep != RuleStmt::SEP_SEMICOLON) { |
Sasha Smundak | ce812f5 | 2018-08-15 14:49:39 -0700 | [diff] [blame] | 52 | CHECK(line[separator_pos] == ';'); |
Shinichiro Hamaji | 2928f46 | 2015-06-23 20:24:53 +0900 | [diff] [blame] | 53 | // TODO: Maybe better to avoid Intern here? |
Sasha Smundak | ae1d58c | 2018-08-22 09:39:42 -0700 | [diff] [blame] | 54 | cmds.push_back(Value::NewLiteral( |
Sasha Smundak | ce812f5 | 2018-08-15 14:49:39 -0700 | [diff] [blame] | 55 | Intern(TrimLeftSpace(line.substr(separator_pos + 1))).str())); |
| 56 | prereq_string = line.substr(0, separator_pos); |
Shinichiro Hamaji | 2928f46 | 2015-06-23 20:24:53 +0900 | [diff] [blame] | 57 | } |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 58 | |
Sasha Smundak | ce812f5 | 2018-08-15 14:49:39 -0700 | [diff] [blame] | 59 | if ((separator_pos = prereq_string.find(':')) == string::npos) { |
| 60 | // Simple prerequisites |
| 61 | ParseInputs(prereq_string); |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 62 | return; |
| 63 | } |
Shinichiro Hamaji | 9b16bda | 2015-06-19 14:25:17 +0900 | [diff] [blame] | 64 | |
Sasha Smundak | ce812f5 | 2018-08-15 14:49:39 -0700 | [diff] [blame] | 65 | // Static pattern rule. |
| 66 | if (!output_patterns.empty()) { |
Dan Willemsen | e41c755 | 2017-02-22 14:31:16 -0800 | [diff] [blame] | 67 | ERROR_LOC(loc, "*** mixed implicit and normal rules: deprecated syntax"); |
Shinichiro Hamaji | 9b16bda | 2015-06-19 14:25:17 +0900 | [diff] [blame] | 68 | } |
| 69 | |
Sasha Smundak | ce812f5 | 2018-08-15 14:49:39 -0700 | [diff] [blame] | 70 | // Empty static patterns should not produce rules, but need to eat the |
| 71 | // commands So return a rule with no outputs nor output_patterns |
| 72 | if (outputs.empty()) { |
Dan Willemsen | eeee13a | 2018-06-16 10:23:33 -0700 | [diff] [blame] | 73 | return; |
| 74 | } |
| 75 | |
Sasha Smundak | ce812f5 | 2018-08-15 14:49:39 -0700 | [diff] [blame] | 76 | StringPiece target_prereq = prereq_string.substr(0, separator_pos); |
| 77 | StringPiece prereq_patterns = prereq_string.substr(separator_pos + 1); |
Shinichiro Hamaji | 9b16bda | 2015-06-19 14:25:17 +0900 | [diff] [blame] | 78 | |
Sasha Smundak | ce812f5 | 2018-08-15 14:49:39 -0700 | [diff] [blame] | 79 | for (StringPiece target_pattern : WordScanner(target_prereq)) { |
| 80 | target_pattern = TrimLeadingCurdir(target_pattern); |
| 81 | for (Symbol target : outputs) { |
| 82 | if (!Pattern(target_pattern).Match(target.str())) { |
Dan Willemsen | e41c755 | 2017-02-22 14:31:16 -0800 | [diff] [blame] | 83 | WARN_LOC(loc, "target `%s' doesn't match the target pattern", |
Sasha Smundak | ce812f5 | 2018-08-15 14:49:39 -0700 | [diff] [blame] | 84 | target.c_str()); |
Shinichiro Hamaji | 138c4d8 | 2015-09-28 13:53:46 +0900 | [diff] [blame] | 85 | } |
| 86 | } |
Sasha Smundak | ce812f5 | 2018-08-15 14:49:39 -0700 | [diff] [blame] | 87 | output_patterns.push_back(Intern(target_pattern)); |
Shinichiro Hamaji | 9b16bda | 2015-06-19 14:25:17 +0900 | [diff] [blame] | 88 | } |
| 89 | |
Sasha Smundak | ce812f5 | 2018-08-15 14:49:39 -0700 | [diff] [blame] | 90 | if (output_patterns.empty()) { |
Dan Willemsen | e41c755 | 2017-02-22 14:31:16 -0800 | [diff] [blame] | 91 | ERROR_LOC(loc, "*** missing target pattern."); |
Shinichiro Hamaji | 9b16bda | 2015-06-19 14:25:17 +0900 | [diff] [blame] | 92 | } |
Sasha Smundak | ce812f5 | 2018-08-15 14:49:39 -0700 | [diff] [blame] | 93 | if (output_patterns.size() > 1) { |
Dan Willemsen | e41c755 | 2017-02-22 14:31:16 -0800 | [diff] [blame] | 94 | ERROR_LOC(loc, "*** multiple target patterns."); |
Shinichiro Hamaji | 9b16bda | 2015-06-19 14:25:17 +0900 | [diff] [blame] | 95 | } |
Sasha Smundak | ce812f5 | 2018-08-15 14:49:39 -0700 | [diff] [blame] | 96 | if (!IsPatternRule(output_patterns[0].str())) { |
Dan Willemsen | e41c755 | 2017-02-22 14:31:16 -0800 | [diff] [blame] | 97 | ERROR_LOC(loc, "*** target pattern contains no '%%'."); |
Shinichiro Hamaji | 9b16bda | 2015-06-19 14:25:17 +0900 | [diff] [blame] | 98 | } |
Sasha Smundak | ce812f5 | 2018-08-15 14:49:39 -0700 | [diff] [blame] | 99 | ParseInputs(prereq_patterns); |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 100 | } |
| 101 | |
| 102 | string Rule::DebugString() const { |
| 103 | vector<string> v; |
Shinichiro Hamaji | e799275 | 2015-06-29 18:38:35 +0900 | [diff] [blame] | 104 | v.push_back(StringPrintf("outputs=[%s]", JoinSymbols(outputs, ",").c_str())); |
| 105 | v.push_back(StringPrintf("inputs=[%s]", JoinSymbols(inputs, ",").c_str())); |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 106 | if (!order_only_inputs.empty()) { |
| 107 | v.push_back(StringPrintf("order_only_inputs=[%s]", |
Shinichiro Hamaji | e799275 | 2015-06-29 18:38:35 +0900 | [diff] [blame] | 108 | JoinSymbols(order_only_inputs, ",").c_str())); |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 109 | } |
Shinichiro Hamaji | 2e23e4a | 2015-06-26 07:33:16 +0900 | [diff] [blame] | 110 | if (!output_patterns.empty()) { |
| 111 | v.push_back(StringPrintf("output_patterns=[%s]", |
Shinichiro Hamaji | e799275 | 2015-06-29 18:38:35 +0900 | [diff] [blame] | 112 | JoinSymbols(output_patterns, ",").c_str())); |
Shinichiro Hamaji | 2e23e4a | 2015-06-26 07:33:16 +0900 | [diff] [blame] | 113 | } |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 114 | if (is_double_colon) |
| 115 | v.push_back("is_double_colon"); |
| 116 | if (is_suffix_rule) |
| 117 | v.push_back("is_suffix_rule"); |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 118 | if (!cmds.empty()) { |
| 119 | v.push_back(StringPrintf("cmds=[%s]", JoinValues(cmds, ",").c_str())); |
| 120 | } |
| 121 | return JoinStrings(v, " "); |
| 122 | } |