Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "tools/gn/input_conversion.h" | 5 #include "tools/gn/input_conversion.h" |
| 6 | 6 |
| 7 #include "base/strings/string_split.h" | 7 #include "base/strings/string_split.h" |
| 8 #include "base/strings/string_util.h" | 8 #include "base/strings/string_util.h" |
| 9 #include "tools/gn/build_settings.h" | 9 #include "tools/gn/build_settings.h" |
| 10 #include "tools/gn/err.h" | 10 #include "tools/gn/err.h" |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 98 return result; | 98 return result; |
| 99 } | 99 } |
| 100 | 100 |
| 101 Value ParseList(const std::string& input, | 101 Value ParseList(const std::string& input, |
| 102 const ParseNode* origin, | 102 const ParseNode* origin, |
| 103 Err* err) { | 103 Err* err) { |
| 104 Value ret(origin, Value::LIST); | 104 Value ret(origin, Value::LIST); |
| 105 std::vector<std::string> as_lines; | 105 std::vector<std::string> as_lines; |
| 106 base::SplitString(input, '\n', &as_lines); | 106 base::SplitString(input, '\n', &as_lines); |
| 107 | 107 |
| 108 // Trim empty lines from the end. | 108 // Trim one empty line from the end since the last line might end in a |
| 109 // Do we want to make this configurable? | 109 // newline. If the user wants more trimming, they'll specify "trim" in the |
| 110 while (!as_lines.empty() && as_lines[as_lines.size() - 1].empty()) | 110 // input conversion options. |
| 111 if (!as_lines.empty() && as_lines[as_lines.size() - 1].empty()) | |
| 111 as_lines.resize(as_lines.size() - 1); | 112 as_lines.resize(as_lines.size() - 1); |
| 112 | 113 |
| 113 ret.list_value().reserve(as_lines.size()); | 114 ret.list_value().reserve(as_lines.size()); |
| 114 for (size_t i = 0; i < as_lines.size(); i++) | 115 for (size_t i = 0; i < as_lines.size(); i++) |
| 115 ret.list_value().push_back(Value(origin, as_lines[i])); | 116 ret.list_value().push_back(Value(origin, as_lines[i])); |
| 116 return ret; | 117 return ret; |
| 117 } | 118 } |
| 118 | 119 |
| 120 // Backend for ConvertInputToValue, this takes the extracted string for the | |
| 121 // input conversion so we can recursively call ourselves to handle the optional | |
| 122 // "trim" prefix. This original value is also kept for the purposes of throwing | |
| 123 // errors. | |
| 124 Value DoConvertInputToValue(const std::string& input, | |
| 125 const ParseNode* origin, | |
| 126 const Value& input_conversion_value, | |
| 127 const std::string& input_conversion, | |
| 128 Err* err) { | |
| 129 if (input_conversion.empty()) | |
| 130 return Value(); // Empty string means discard the result. | |
| 131 | |
| 132 const char kTrimPrefix[] = "trim "; | |
| 133 if (StartsWithASCII(input_conversion, kTrimPrefix, true)) { | |
| 134 std::string trimmed; | |
| 135 TrimWhitespaceASCII(input, TRIM_ALL, &trimmed); | |
| 136 | |
| 137 // Remove "trim" prefix from the input conversion and re-run. | |
| 138 return DoConvertInputToValue( | |
| 139 trimmed, origin, input_conversion_value, | |
| 140 input_conversion.substr(arraysize(kTrimPrefix) - 1), err); | |
| 141 } | |
| 142 | |
| 143 if (input_conversion == "value") | |
| 144 return ParseString(input, origin, err); | |
| 145 if (input_conversion == "string") | |
| 146 return Value(origin, input); | |
| 147 if (input_conversion == "list lines") | |
| 148 return ParseList(input, origin, err); | |
| 149 | |
| 150 *err = Err(input_conversion_value, "Not a valid input conversion.", | |
|
bbudge
2014/01/08 23:22:32
Shouldn't this be 'input_conversion'?
The comment
| |
| 151 "Have you considered a career in retail?"); | |
| 152 return Value(); | |
| 153 } | |
| 154 | |
| 119 } // namespace | 155 } // namespace |
| 120 | 156 |
| 121 extern const char kInputConversion_Help[] = | 157 extern const char kInputConversion_Help[] = |
| 122 "input_conversion: Specifies how to transform input to a variable.\n" | 158 "input_conversion: Specifies how to transform input to a variable.\n" |
| 123 "\n" | 159 "\n" |
| 124 " input_conversion is an argument to read_file and exec_script that\n" | 160 " input_conversion is an argument to read_file and exec_script that\n" |
| 125 " specifies how the result of the read operation should be converted\n" | 161 " specifies how the result of the read operation should be converted\n" |
| 126 " into a variable.\n" | 162 " into a variable.\n" |
| 127 "\n" | 163 "\n" |
| 164 " \"\" (the default)\n" | |
| 165 " Discard the result and return None.\n" | |
| 166 "\n" | |
| 128 " \"list lines\"\n" | 167 " \"list lines\"\n" |
| 129 " Return the file contents as a list, with a string for each line.\n" | 168 " Return the file contents as a list, with a string for each line.\n" |
| 130 " The newlines will not be present in the result. Empty newlines\n" | 169 " The newlines will not be present in the result. The last line may\n" |
| 131 " will be trimmed from the trailing end of the returned list.\n" | 170 " or may not end in a newline.\n" |
| 171 "\n" | |
| 172 " After splitting, each individual line will be trimmed of\n" | |
| 173 " whitespace on both ends.\n" | |
| 132 "\n" | 174 "\n" |
| 133 " \"value\"\n" | 175 " \"value\"\n" |
| 134 " Parse the input as if it was a literal rvalue in a buildfile.\n" | 176 " Parse the input as if it was a literal rvalue in a buildfile.\n" |
| 135 " Examples of typical program output using this mode:\n" | 177 " Examples of typical program output using this mode:\n" |
| 136 " [ \"foo\", \"bar\" ] (result will be a list)\n" | 178 " [ \"foo\", \"bar\" ] (result will be a list)\n" |
| 137 " or\n" | 179 " or\n" |
| 138 " \"foo bar\" (result will be a string)\n" | 180 " \"foo bar\" (result will be a string)\n" |
| 139 " or\n" | 181 " or\n" |
| 140 " 5 (result will be an integer)\n" | 182 " 5 (result will be an integer)\n" |
| 141 "\n" | 183 "\n" |
| 142 " Note that if the input is empty, the result will be a null value\n" | 184 " Note that if the input is empty, the result will be a null value\n" |
| 143 " which will produce an error if assigned to a variable.\n" | 185 " which will produce an error if assigned to a variable.\n" |
| 144 "\n" | 186 "\n" |
| 145 " \"string\"\n" | 187 " \"string\"\n" |
| 146 " Return the file contents into a single string.\n"; | 188 " Return the file contents into a single string.\n" |
| 189 "\n" | |
| 190 " \"trim ...\"\n" | |
| 191 " Prefixing any of the other transformations with the word \"trim\"\n" | |
| 192 " will result in whitespace being trimmed from the beginning and end\n" | |
| 193 " of the result before processing.\n" | |
| 194 "\n" | |
| 195 " Examples: \"trim string\" or \"trim list lines\"\n" | |
| 196 "\n" | |
| 197 " Note that \"trim value\" is useless because the value parser skips\n" | |
| 198 " whitespace anyway.\n"; | |
| 147 | 199 |
| 148 Value ConvertInputToValue(const std::string& input, | 200 Value ConvertInputToValue(const std::string& input, |
| 149 const ParseNode* origin, | 201 const ParseNode* origin, |
| 150 const Value& input_conversion_value, | 202 const Value& input_conversion_value, |
| 151 Err* err) { | 203 Err* err) { |
| 204 if (input_conversion_value.type() == Value::NONE) | |
| 205 return Value(); // Allow null inputs to mean discard the result. | |
| 152 if (!input_conversion_value.VerifyTypeIs(Value::STRING, err)) | 206 if (!input_conversion_value.VerifyTypeIs(Value::STRING, err)) |
| 153 return Value(); | 207 return Value(); |
| 154 const std::string& input_conversion = input_conversion_value.string_value(); | 208 return DoConvertInputToValue(input, origin, input_conversion_value, |
| 155 | 209 input_conversion_value.string_value(), err); |
| 156 if (input_conversion == "value") | |
| 157 return ParseString(input, origin, err); | |
| 158 if (input_conversion == "string") | |
| 159 return Value(origin, input); | |
| 160 if (input_conversion == "list lines") | |
| 161 return ParseList(input, origin, err); | |
| 162 | |
| 163 *err = Err(input_conversion_value, "Not a valid read file mode.", | |
| 164 "Have you considered a career in retail?"); | |
| 165 return Value(); | |
| 166 } | 210 } |
| OLD | NEW |