Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #library("test_options_parser"); | 5 #library("test_options_parser"); |
| 6 | 6 |
| 7 List<String> defaultTestSelectors = | 7 List<String> defaultTestSelectors = |
| 8 const ['dartc', 'samples', 'standalone', 'corelib', 'co19', 'language', | 8 const ['dartc', 'samples', 'standalone', 'corelib', 'co19', 'language', |
| 9 'isolate', 'stub-generator', 'vm', 'client']; | 9 'isolate', 'stub-generator', 'vm', 'client']; |
| 10 | 10 |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 164 * Parse a list of strings as test options. | 164 * Parse a list of strings as test options. |
| 165 * | 165 * |
| 166 * Returns a list of configurations in which to run the | 166 * Returns a list of configurations in which to run the |
| 167 * tests. Configurations are maps mapping from option keys to | 167 * tests. Configurations are maps mapping from option keys to |
| 168 * values. When encountering the first non-option string, the rest | 168 * values. When encountering the first non-option string, the rest |
| 169 * of the arguments are stored in the returned Map under the 'rest' | 169 * of the arguments are stored in the returned Map under the 'rest' |
| 170 * key. | 170 * key. |
| 171 */ | 171 */ |
| 172 List<Map> parse(List<String> arguments) { | 172 List<Map> parse(List<String> arguments) { |
| 173 var configuration = new Map(); | 173 var configuration = new Map(); |
| 174 // Build configuration of default values. | 174 // Fill in configuration with arguments passed to the test script. |
| 175 for (var option in _options) { | |
| 176 configuration[option.name] = option.defaultValue; | |
| 177 } | |
| 178 // Overwrite with the arguments passed to the test script. | |
| 179 var numArguments = arguments.length; | 175 var numArguments = arguments.length; |
| 180 for (var i = 0; i < numArguments; i++) { | 176 for (var i = 0; i < numArguments; i++) { |
| 181 // Extract name and value for options. | 177 // Extract name and value for options. |
| 182 var arg = arguments[i]; | 178 String arg = arguments[i]; |
| 183 var name = ''; | 179 String name = ''; |
| 184 var value = ''; | 180 String value = ''; |
| 181 _TestOptionSpecification spec; | |
| 185 if (arg.startsWith('--')) { | 182 if (arg.startsWith('--')) { |
| 186 if (arg == '--help') { | 183 if (arg == '--help') { |
| 187 _printHelp(); | 184 _printHelp(); |
| 188 return null; | 185 return null; |
| 189 } | 186 } |
| 190 var split = arg.indexOf('='); | 187 var split = arg.indexOf('='); |
| 191 if (split == -1) { | 188 if (split == -1) { |
| 192 name = arg; | 189 name = arg; |
| 190 spec = _getSpecification(name); | |
| 193 // Boolean options do not have a value. | 191 // Boolean options do not have a value. |
| 194 if (_getSpecification(name).type != 'bool') { | 192 if (spec.type != 'bool') { |
| 195 if ((i + 1) >= arguments.length) { | 193 if ((i + 1) >= arguments.length) { |
| 196 print('No value supplied for option $name'); | 194 print('No value supplied for option $name'); |
| 197 return null; | 195 return null; |
| 198 } | 196 } |
| 199 value = arguments[++i]; | 197 value = arguments[++i]; |
| 200 } | 198 } |
| 201 } else { | 199 } else { |
| 202 name = arg.substring(0, split); | 200 name = arg.substring(0, split); |
| 201 spec = _getSpecification(name); | |
| 203 value = arg.substring(split + 1, arg.length); | 202 value = arg.substring(split + 1, arg.length); |
| 204 } | 203 } |
| 205 } else if (arg.startsWith('-')) { | 204 } else if (arg.startsWith('-')) { |
| 206 if (arg == '-h') { | 205 if (arg == '-h') { |
| 207 _printHelp(); | 206 _printHelp(); |
| 208 return null; | 207 return null; |
| 209 } | 208 } |
| 210 if (arg.length > 2) { | 209 if (arg.length > 2) { |
| 211 name = arg.substring(0, 2); | 210 name = arg.substring(0, 2); |
| 211 spec = _getSpecification(name); | |
| 212 value = arg.substring(2, arg.length); | 212 value = arg.substring(2, arg.length); |
| 213 } else { | 213 } else { |
| 214 name = arg; | 214 name = arg; |
| 215 spec = _getSpecification(name); | |
| 215 // Boolean options do not have a value. | 216 // Boolean options do not have a value. |
| 216 if (_getSpecification(name).type != 'bool') { | 217 if (spec.type != 'bool') { |
| 217 if ((i + 1) >= arguments.length) { | 218 if ((i + 1) >= arguments.length) { |
| 218 print('No value supplied for option $name'); | 219 print('No value supplied for option $name'); |
| 219 return null; | 220 return null; |
| 220 } | 221 } |
| 221 value = arguments[++i]; | 222 value = arguments[++i]; |
| 222 } | 223 } |
| 223 } | 224 } |
| 224 } else { | 225 } else { |
| 225 // The argument does not start with '-' or '--' and is | 226 // The argument does not start with '-' or '--' and is |
| 226 // therefore not an option. We use it as a test selection | 227 // therefore not an option. We use it as a test selection |
| 227 // pattern. | 228 // pattern. |
| 228 configuration.putIfAbsent('selectors', () => []); | 229 configuration.putIfAbsent('selectors', () => []); |
| 229 var patterns = configuration['selectors']; | 230 var patterns = configuration['selectors']; |
| 230 patterns.add(arg); | 231 patterns.add(arg); |
| 231 continue; | 232 continue; |
| 232 } | 233 } |
| 233 // Find the option specification for the name. | 234 |
| 234 var spec = _getSpecification(name); | 235 |
| 235 if (spec == null) { | 236 // Multiple uses of a flag are an error, because there is no |
| 236 print('Unknown test option $name'); | 237 // naturally correct way to handle conflicting options. |
| 238 if (configuration.containsKey(spec.name)) { | |
| 239 print('Multiple "--${spec.name}" flags on command line'); | |
|
Emily Fortuna
2012/01/10 23:24:00
Slightly more informative error message:
print ('E
| |
| 237 exit(1); | 240 exit(1); |
| 238 } | 241 } |
| 239 // Parse the value for the option. | 242 // Parse the value for the option. |
| 240 if (spec.type == 'bool') { | 243 if (spec.type == 'bool') { |
| 241 if (!value.isEmpty()) { | 244 if (!value.isEmpty()) { |
| 242 print('No value expected for bool option $name'); | 245 print('No value expected for bool option $name'); |
| 243 exit(1); | 246 exit(1); |
| 244 } | 247 } |
| 245 configuration[spec.name] = true; | 248 configuration[spec.name] = true; |
| 246 } else if (spec.type == 'int') { | 249 } else if (spec.type == 'int') { |
| 247 try { | 250 try { |
| 248 configuration[spec.name] = Math.parseInt(value); | 251 configuration[spec.name] = Math.parseInt(value); |
| 249 } catch (var e) { | 252 } catch (var e) { |
| 250 print('Integer value expected for int option $name'); | 253 print('Integer value expected for int option $name'); |
| 251 exit(1); | 254 exit(1); |
| 252 } | 255 } |
| 253 } else { | 256 } else { |
| 254 assert(spec.type == 'string'); | 257 assert(spec.type == 'string'); |
| 255 if (!spec.values.isEmpty()) { | 258 if (!spec.values.isEmpty()) { |
| 256 for (var v in value.split(',')) { | 259 for (var v in value.split(',')) { |
| 257 if (spec.values.lastIndexOf(v) == -1) { | 260 if (spec.values.lastIndexOf(v) == -1) { |
| 258 print('Unknown value ($v) for option $name'); | 261 print('Unknown value ($v) for option $name'); |
| 259 exit(1); | 262 exit(1); |
| 260 } | 263 } |
| 261 } | 264 } |
| 262 } | 265 } |
| 263 configuration[spec.name] = value; | 266 configuration[spec.name] = value; |
| 264 } | 267 } |
| 265 } | 268 } |
| 266 | 269 |
| 270 // Apply default values for unspecified options. | |
| 271 for (var option in _options) { | |
| 272 if (!configuration.containsKey(option.name)) { | |
| 273 configuration[option.name] = option.defaultValue; | |
| 274 } | |
| 275 } | |
| 276 | |
| 267 return _expandConfigurations(configuration); | 277 return _expandConfigurations(configuration); |
| 268 } | 278 } |
| 269 | 279 |
| 270 | 280 |
| 271 /** | 281 /** |
| 272 * Recursively expand a configuration with multiple values per key | 282 * Recursively expand a configuration with multiple values per key |
| 273 * into a list of configurations with exactly one value per key. | 283 * into a list of configurations with exactly one value per key. |
| 274 */ | 284 */ |
| 275 List<Map> _expandConfigurations(Map configuration) { | 285 List<Map> _expandConfigurations(Map configuration) { |
| 276 | 286 |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 442 | 452 |
| 443 /** | 453 /** |
| 444 * Find the test option specification for a given option key. | 454 * Find the test option specification for a given option key. |
| 445 */ | 455 */ |
| 446 _TestOptionSpecification _getSpecification(String name) { | 456 _TestOptionSpecification _getSpecification(String name) { |
| 447 for (var option in _options) { | 457 for (var option in _options) { |
| 448 if (option.keys.some((key) => key == name)) { | 458 if (option.keys.some((key) => key == name)) { |
| 449 return option; | 459 return option; |
| 450 } | 460 } |
| 451 } | 461 } |
| 452 return null; | 462 print('Unknown test option $name'); |
| 463 exit(1); | |
| 453 } | 464 } |
| 454 | 465 |
| 455 | 466 |
| 456 List<_TestOptionSpecification> _options; | 467 List<_TestOptionSpecification> _options; |
| 457 } | 468 } |
| OLD | NEW |