blob: b5c4ae203dadcd0c17495adbc233db58fa7f2def [file] [log] [blame]
/*
* 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