| /* |
| * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
| * |
| * Use of this source code is governed by a BSD-style license |
| * that can be found in the LICENSE file in the root of the source |
| * tree. An additional intellectual property rights grant can be found |
| * in the file PATENTS. All contributing project authors may |
| * be found in the AUTHORS file in the root of the source tree. |
| */ |
| |
| #include "webrtc/video_engine/test/auto_test/primitives/input_helpers.h" |
| |
| #include <assert.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| |
| #include <algorithm> |
| |
| #include "gflags/gflags.h" |
| |
| namespace webrtc { |
| |
| DEFINE_string(override, "", |
| "Makes it possible to override choices or inputs. All choices and " |
| "inputs will use their default values unless you override them in this " |
| "flag's argument. There can be several comma-separated overrides specified:" |
| " Overrides are specified as \"title=option text\" for choices and " |
| "\"title=value\" for regular inputs. Note that the program will stop if " |
| "you provide input not accepted by the input's validator through this flag." |
| "\n\nExample: --override \"Enter destination IP=192.168.0.1, " |
| "Select a codec=VP8\""); |
| |
| class AcceptAllNonEmptyValidator : public InputValidator { |
| public: |
| bool InputOk(const std::string& value) const { |
| return value.length() > 0; |
| } |
| }; |
| |
| InputBuilder::InputBuilder(const std::string& title, |
| const InputValidator* input_validator, |
| const OverrideRegistry& override_registry) |
| : input_source_(stdin), input_validator_(input_validator), |
| override_registry_(override_registry), default_value_(""), title_(title) { |
| } |
| |
| InputBuilder::~InputBuilder() { |
| delete input_validator_; |
| } |
| |
| std::string InputBuilder::AskForInput() const { |
| if (override_registry_.HasOverrideFor(title_)) |
| return GetOverride(); |
| if (!FLAGS_override.empty() && !default_value_.empty()) |
| return default_value_; |
| |
| // We don't know the answer already, so ask the user. |
| return ActuallyAskUser(); |
| } |
| |
| std::string InputBuilder::ActuallyAskUser() const { |
| printf("\n%s%s\n", title_.c_str(), additional_info_.c_str()); |
| |
| if (!default_value_.empty()) |
| printf("Hit enter for default (%s):\n", default_value_.c_str()); |
| |
| printf("# "); |
| char raw_input[128]; |
| if (!fgets(raw_input, 128, input_source_)) { |
| // If we get here the user probably hit CTRL+D. |
| exit(1); |
| } |
| |
| std::string input = raw_input; |
| input = input.substr(0, input.size() - 1); // Strip last \n. |
| |
| if (input.empty() && !default_value_.empty()) |
| return default_value_; |
| |
| if (!input_validator_->InputOk(input)) { |
| printf("Invalid input. Please try again.\n"); |
| return ActuallyAskUser(); |
| } |
| return input; |
| } |
| |
| InputBuilder& InputBuilder::WithInputSource(FILE* input_source) { |
| input_source_ = input_source; |
| return *this; |
| } |
| |
| InputBuilder& InputBuilder::WithInputValidator( |
| const InputValidator* input_validator) { |
| // If there's a default value, it must be accepted by the input validator. |
| assert(default_value_.empty() || input_validator->InputOk(default_value_)); |
| delete input_validator_; |
| input_validator_ = input_validator; |
| return *this; |
| } |
| |
| InputBuilder& InputBuilder::WithDefault(const std::string& default_value) { |
| assert(input_validator_->InputOk(default_value)); |
| default_value_ = default_value; |
| return *this; |
| } |
| |
| InputBuilder& InputBuilder::WithAdditionalInfo(const std::string& info) { |
| additional_info_ = info; |
| return *this; |
| } |
| |
| const std::string& InputBuilder::GetOverride() const { |
| const std::string& override = override_registry_.GetOverrideFor(title_); |
| if (!input_validator_->InputOk(override)) { |
| printf("Fatal: Input validator for \"%s\" does not accept override %s.\n", |
| title_.c_str(), override.c_str()); |
| exit(1); |
| } |
| return override; |
| } |
| |
| OverrideRegistry::OverrideRegistry(const std::string& overrides) { |
| std::vector<std::string> all_overrides = Split(overrides, ","); |
| std::vector<std::string>::const_iterator override = all_overrides.begin(); |
| for (; override != all_overrides.end(); ++override) { |
| std::vector<std::string> key_value = Split(*override, "="); |
| if (key_value.size() != 2) { |
| printf("Fatal: Override %s is malformed.", (*override).c_str()); |
| exit(1); |
| } |
| std::string key = key_value[0]; |
| std::string value = key_value[1]; |
| overrides_[key] = value; |
| } |
| } |
| |
| bool OverrideRegistry::HasOverrideFor(const std::string& title) const { |
| return overrides_.find(title) != overrides_.end(); |
| } |
| |
| const std::string& OverrideRegistry::GetOverrideFor( |
| const std::string& title) const { |
| assert(HasOverrideFor(title)); |
| return (*overrides_.find(title)).second; |
| } |
| |
| InputBuilder TypedInput(const std::string& title) { |
| static OverrideRegistry override_registry_(FLAGS_override); |
| return InputBuilder( |
| title, new AcceptAllNonEmptyValidator(), override_registry_); |
| } |
| |
| std::vector<std::string> Split(const std::string& to_split, |
| const std::string& delimiter) { |
| std::vector<std::string> result; |
| size_t current_pos = 0; |
| size_t next_delimiter = 0; |
| while ((next_delimiter = to_split.find(delimiter, current_pos)) != |
| std::string::npos) { |
| std::string part = to_split.substr( |
| current_pos, next_delimiter - current_pos); |
| result.push_back(part); |
| current_pos = next_delimiter + 1; |
| } |
| std::string last_part = to_split.substr(current_pos); |
| if (!last_part.empty()) |
| result.push_back(last_part); |
| |
| return result; |
| } |
| |
| } // namespace webrtc |