Remove rtc::Flag.
WebRTC has been migrated to Abseil Flags. Bug: webrtc:10616 Change-Id: Id4a363429ccd2dd55c0dff00c9490c15124fdccc Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/144631 Reviewed-by: Steve Anton <steveanton@webrtc.org> Commit-Queue: Mirko Bonadei <mbonadei@webrtc.org> Cr-Commit-Position: refs/heads/master@{#28620}
This commit is contained in:
committed by
Commit Bot
parent
5693c26ad3
commit
836ab13f1c
@ -80,8 +80,6 @@ rtc_source_set("rtc_base_approved") {
|
||||
"copy_on_write_buffer.h",
|
||||
"event_tracer.cc",
|
||||
"event_tracer.h",
|
||||
"flags.cc",
|
||||
"flags.h",
|
||||
"function_view.h",
|
||||
"ignore_wundef.h",
|
||||
"location.cc",
|
||||
|
||||
@ -1,282 +0,0 @@
|
||||
/*
|
||||
* Copyright 2006 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 "rtc_base/flags.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
namespace {
|
||||
bool FlagEq(const char* arg, const char* flag) {
|
||||
// Compare two flags for equality.
|
||||
// 'arg' is the name of a flag passed via the command line and 'flag' is the
|
||||
// name of a flag defined with the DEFINE_* macros.
|
||||
// We compare the flags for equality, considering hyphens (-) and
|
||||
// underscores (_) to be equivalent, so that --flag-name and --flag_name both
|
||||
// match with --flag_name.
|
||||
while (*arg != '\0' && (*arg == *flag || (*arg == '-' && *flag == '_'))) {
|
||||
++arg;
|
||||
++flag;
|
||||
}
|
||||
return *arg == '\0' && *flag == '\0';
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace rtc {
|
||||
// -----------------------------------------------------------------------------
|
||||
// Implementation of Flag
|
||||
|
||||
Flag::Flag(const char* file,
|
||||
const char* name,
|
||||
const char* comment,
|
||||
Type type,
|
||||
void* variable,
|
||||
FlagValue default__)
|
||||
: file_(file),
|
||||
name_(name),
|
||||
comment_(comment),
|
||||
type_(type),
|
||||
variable_(reinterpret_cast<FlagValue*>(variable)),
|
||||
default_(default__) {
|
||||
FlagList::Register(this);
|
||||
}
|
||||
|
||||
void Flag::SetToDefault() {
|
||||
// Note that we cannot simply do '*variable_ = default_;' since
|
||||
// flag variables are not really of type FlagValue and thus may
|
||||
// be smaller! The FlagValue union is simply 'overlayed' on top
|
||||
// of a flag variable for convenient access. Since union members
|
||||
// are guarantee to be aligned at the beginning, this works.
|
||||
switch (type_) {
|
||||
case Flag::BOOL:
|
||||
variable_->b = default_.b;
|
||||
return;
|
||||
case Flag::INT:
|
||||
variable_->i = default_.i;
|
||||
return;
|
||||
case Flag::FLOAT:
|
||||
variable_->f = default_.f;
|
||||
return;
|
||||
case Flag::STRING:
|
||||
variable_->s = default_.s;
|
||||
return;
|
||||
}
|
||||
FATAL() << "unreachable code";
|
||||
}
|
||||
|
||||
static const char* Type2String(Flag::Type type) {
|
||||
switch (type) {
|
||||
case Flag::BOOL:
|
||||
return "bool";
|
||||
case Flag::INT:
|
||||
return "int";
|
||||
case Flag::FLOAT:
|
||||
return "float";
|
||||
case Flag::STRING:
|
||||
return "string";
|
||||
}
|
||||
FATAL() << "unreachable code";
|
||||
}
|
||||
|
||||
static void PrintFlagValue(Flag::Type type, FlagValue* p) {
|
||||
switch (type) {
|
||||
case Flag::BOOL:
|
||||
printf("%s", (p->b ? "true" : "false"));
|
||||
return;
|
||||
case Flag::INT:
|
||||
printf("%d", p->i);
|
||||
return;
|
||||
case Flag::FLOAT:
|
||||
printf("%f", p->f);
|
||||
return;
|
||||
case Flag::STRING:
|
||||
printf("%s", p->s);
|
||||
return;
|
||||
}
|
||||
FATAL() << "unreachable code";
|
||||
}
|
||||
|
||||
void Flag::Print(bool print_current_value) {
|
||||
printf(" --%s (%s) type: %s default: ", name_, comment_,
|
||||
Type2String(type_));
|
||||
PrintFlagValue(type_, &default_);
|
||||
if (print_current_value) {
|
||||
printf(" current value: ");
|
||||
PrintFlagValue(type_, variable_);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Implementation of FlagList
|
||||
|
||||
Flag* FlagList::list_ = nullptr;
|
||||
|
||||
FlagList::FlagList() {
|
||||
list_ = nullptr;
|
||||
}
|
||||
|
||||
void FlagList::Print(const char* file, bool print_current_value) {
|
||||
// Since flag registration is likely by file (= C++ file),
|
||||
// we don't need to sort by file and still get grouped output.
|
||||
const char* current = nullptr;
|
||||
for (Flag* f = list_; f != nullptr; f = f->next()) {
|
||||
if (file == nullptr || file == f->file()) {
|
||||
if (current != f->file()) {
|
||||
printf("Flags from %s:\n", f->file());
|
||||
current = f->file();
|
||||
}
|
||||
f->Print(print_current_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Flag* FlagList::Lookup(const char* name) {
|
||||
Flag* f = list_;
|
||||
while (f != nullptr && !FlagEq(name, f->name()))
|
||||
f = f->next();
|
||||
return f;
|
||||
}
|
||||
|
||||
void FlagList::SplitArgument(const char* arg,
|
||||
char* buffer,
|
||||
int buffer_size,
|
||||
const char** name,
|
||||
const char** value,
|
||||
bool* is_bool) {
|
||||
*name = nullptr;
|
||||
*value = nullptr;
|
||||
*is_bool = false;
|
||||
|
||||
if (*arg == '-') {
|
||||
// find the begin of the flag name
|
||||
arg++; // remove 1st '-'
|
||||
if (*arg == '-')
|
||||
arg++; // remove 2nd '-'
|
||||
if (arg[0] == 'n' && arg[1] == 'o' && Lookup(arg + 2)) {
|
||||
arg += 2; // remove "no"
|
||||
*is_bool = true;
|
||||
}
|
||||
*name = arg;
|
||||
|
||||
// find the end of the flag name
|
||||
while (*arg != '\0' && *arg != '=')
|
||||
arg++;
|
||||
|
||||
// get the value if any
|
||||
if (*arg == '=') {
|
||||
// make a copy so we can NUL-terminate flag name
|
||||
int n = static_cast<int>(arg - *name);
|
||||
RTC_CHECK_LT(n, buffer_size);
|
||||
memcpy(buffer, *name, n * sizeof(char));
|
||||
buffer[n] = '\0';
|
||||
*name = buffer;
|
||||
// get the value
|
||||
*value = arg + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int FlagList::SetFlagsFromCommandLine(int* argc,
|
||||
const char** argv,
|
||||
bool remove_flags) {
|
||||
// parse arguments
|
||||
for (int i = 1; i < *argc; /* see below */) {
|
||||
int j = i; // j > 0
|
||||
const char* arg = argv[i++];
|
||||
|
||||
// split arg into flag components
|
||||
char buffer[1024];
|
||||
const char* name;
|
||||
const char* value;
|
||||
bool is_bool;
|
||||
SplitArgument(arg, buffer, sizeof buffer, &name, &value, &is_bool);
|
||||
|
||||
if (name != nullptr) {
|
||||
// lookup the flag
|
||||
Flag* flag = Lookup(name);
|
||||
if (flag == nullptr) {
|
||||
fprintf(stderr, "Error: unrecognized flag %s\n", arg);
|
||||
return j;
|
||||
}
|
||||
|
||||
// if we still need a flag value, use the next argument if available
|
||||
if (flag->type() != Flag::BOOL && value == nullptr) {
|
||||
if (i < *argc) {
|
||||
value = argv[i++];
|
||||
} else {
|
||||
fprintf(stderr, "Error: missing value for flag %s of type %s\n", arg,
|
||||
Type2String(flag->type()));
|
||||
return j;
|
||||
}
|
||||
}
|
||||
|
||||
// set the flag
|
||||
char empty[] = {'\0'};
|
||||
char* endp = empty;
|
||||
switch (flag->type()) {
|
||||
case Flag::BOOL:
|
||||
*flag->bool_variable() = !is_bool;
|
||||
break;
|
||||
case Flag::INT:
|
||||
*flag->int_variable() = strtol(value, &endp, 10);
|
||||
break;
|
||||
case Flag::FLOAT:
|
||||
*flag->float_variable() = strtod(value, &endp);
|
||||
break;
|
||||
case Flag::STRING:
|
||||
*flag->string_variable() = value;
|
||||
break;
|
||||
}
|
||||
|
||||
// handle errors
|
||||
if ((flag->type() == Flag::BOOL && value != nullptr) ||
|
||||
(flag->type() != Flag::BOOL && is_bool) || *endp != '\0') {
|
||||
fprintf(stderr, "Error: illegal value for flag %s of type %s\n", arg,
|
||||
Type2String(flag->type()));
|
||||
return j;
|
||||
}
|
||||
|
||||
// remove the flag & value from the command
|
||||
if (remove_flags)
|
||||
while (j < i)
|
||||
argv[j++] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// shrink the argument list
|
||||
if (remove_flags) {
|
||||
int j = 1;
|
||||
for (int i = 1; i < *argc; i++) {
|
||||
if (argv[i] != nullptr)
|
||||
argv[j++] = argv[i];
|
||||
}
|
||||
*argc = j;
|
||||
}
|
||||
|
||||
// parsed all flags successfully
|
||||
return 0;
|
||||
}
|
||||
|
||||
void FlagList::Register(Flag* flag) {
|
||||
RTC_DCHECK(flag);
|
||||
RTC_DCHECK_GT(strlen(flag->name()), 0);
|
||||
// NOTE: Don't call Lookup() within Register because it accesses the name_
|
||||
// of other flags in list_, and if the flags are coming from two different
|
||||
// compilation units, the initialization order between them is undefined, and
|
||||
// this will trigger an asan initialization-order-fiasco error.
|
||||
flag->next_ = list_;
|
||||
list_ = flag;
|
||||
}
|
||||
|
||||
} // namespace rtc
|
||||
244
rtc_base/flags.h
244
rtc_base/flags.h
@ -1,244 +0,0 @@
|
||||
/*
|
||||
* Copyright 2006 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.
|
||||
*/
|
||||
|
||||
// Originally comes from shared/commandlineflags/flags.h
|
||||
|
||||
// Flags are defined and declared using DEFINE_xxx and DECLARE_xxx macros,
|
||||
// where xxx is the flag type. Flags are referred to via FLAG_yyy,
|
||||
// where yyy is the flag name. For intialization and iteration of flags,
|
||||
// see the FlagList class. For full programmatic access to any
|
||||
// flag, see the Flag class.
|
||||
//
|
||||
// The implementation only relies and basic C++ functionality
|
||||
// and needs no special library or STL support.
|
||||
|
||||
#ifndef RTC_BASE_FLAGS_H_
|
||||
#define RTC_BASE_FLAGS_H_
|
||||
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
// Internal use only.
|
||||
union FlagValue {
|
||||
// Note: Because in C++ non-bool values are silently converted into
|
||||
// bool values ('bool b = "false";' results in b == true!), we pass
|
||||
// and int argument to New_BOOL as this appears to be safer - sigh.
|
||||
// In particular, it prevents the (not uncommon!) bug where a bool
|
||||
// flag is defined via: WEBRTC_DEFINE_bool(flag, "false", "some comment");.
|
||||
static FlagValue New_BOOL(int b) {
|
||||
FlagValue v;
|
||||
v.b = (b != 0);
|
||||
return v;
|
||||
}
|
||||
|
||||
static FlagValue New_INT(int i) {
|
||||
FlagValue v;
|
||||
v.i = i;
|
||||
return v;
|
||||
}
|
||||
|
||||
static FlagValue New_FLOAT(float f) {
|
||||
FlagValue v;
|
||||
v.f = f;
|
||||
return v;
|
||||
}
|
||||
|
||||
static FlagValue New_STRING(const char* s) {
|
||||
FlagValue v;
|
||||
v.s = s;
|
||||
return v;
|
||||
}
|
||||
|
||||
bool b;
|
||||
int i;
|
||||
double f;
|
||||
const char* s;
|
||||
};
|
||||
|
||||
// Each flag can be accessed programmatically via a Flag object.
|
||||
class Flag {
|
||||
public:
|
||||
enum Type { BOOL, INT, FLOAT, STRING };
|
||||
|
||||
// Internal use only.
|
||||
Flag(const char* file,
|
||||
const char* name,
|
||||
const char* comment,
|
||||
Type type,
|
||||
void* variable,
|
||||
FlagValue default_);
|
||||
|
||||
// General flag information
|
||||
const char* file() const { return file_; }
|
||||
const char* name() const { return name_; }
|
||||
const char* comment() const { return comment_; }
|
||||
|
||||
// Flag type
|
||||
Type type() const { return type_; }
|
||||
|
||||
// Flag variables
|
||||
bool* bool_variable() const {
|
||||
RTC_DCHECK_EQ(BOOL, type_);
|
||||
return &variable_->b;
|
||||
}
|
||||
|
||||
int* int_variable() const {
|
||||
RTC_DCHECK_EQ(INT, type_);
|
||||
return &variable_->i;
|
||||
}
|
||||
|
||||
double* float_variable() const {
|
||||
RTC_DCHECK_EQ(FLOAT, type_);
|
||||
return &variable_->f;
|
||||
}
|
||||
|
||||
const char** string_variable() const {
|
||||
RTC_DCHECK_EQ(STRING, type_);
|
||||
return &variable_->s;
|
||||
}
|
||||
|
||||
// Default values
|
||||
bool bool_default() const {
|
||||
RTC_DCHECK_EQ(BOOL, type_);
|
||||
return default_.b;
|
||||
}
|
||||
|
||||
int int_default() const {
|
||||
RTC_DCHECK_EQ(INT, type_);
|
||||
return default_.i;
|
||||
}
|
||||
|
||||
double float_default() const {
|
||||
RTC_DCHECK_EQ(FLOAT, type_);
|
||||
return default_.f;
|
||||
}
|
||||
|
||||
const char* string_default() const {
|
||||
RTC_DCHECK_EQ(STRING, type_);
|
||||
return default_.s;
|
||||
}
|
||||
|
||||
// Resets a flag to its default value
|
||||
void SetToDefault();
|
||||
|
||||
// Iteration support
|
||||
Flag* next() const { return next_; }
|
||||
|
||||
// Prints flag information. The current flag value is only printed
|
||||
// if print_current_value is set.
|
||||
void Print(bool print_current_value);
|
||||
|
||||
private:
|
||||
const char* file_;
|
||||
const char* name_;
|
||||
const char* comment_;
|
||||
|
||||
Type type_;
|
||||
FlagValue* variable_;
|
||||
FlagValue default_;
|
||||
|
||||
Flag* next_;
|
||||
|
||||
friend class FlagList; // accesses next_
|
||||
};
|
||||
|
||||
// Internal use only.
|
||||
#define WEBRTC_DEFINE_FLAG(type, c_type, name, default, comment) \
|
||||
/* define and initialize the flag */ \
|
||||
c_type FLAG_##name = (default); \
|
||||
/* register the flag */ \
|
||||
static rtc::Flag Flag_##name(__FILE__, #name, (comment), rtc::Flag::type, \
|
||||
&FLAG_##name, \
|
||||
rtc::FlagValue::New_##type(default))
|
||||
|
||||
// Internal use only.
|
||||
#define WEBRTC_DECLARE_FLAG(c_type, name) \
|
||||
/* declare the external flag */ \
|
||||
extern c_type FLAG_##name
|
||||
|
||||
// Use the following macros to define a new flag:
|
||||
#define WEBRTC_DEFINE_bool(name, default, comment) \
|
||||
WEBRTC_DEFINE_FLAG(BOOL, bool, name, default, comment)
|
||||
#define WEBRTC_DEFINE_int(name, default, comment) \
|
||||
WEBRTC_DEFINE_FLAG(INT, int, name, default, comment)
|
||||
#define WEBRTC_DEFINE_float(name, default, comment) \
|
||||
WEBRTC_DEFINE_FLAG(FLOAT, double, name, default, comment)
|
||||
#define WEBRTC_DEFINE_string(name, default, comment) \
|
||||
WEBRTC_DEFINE_FLAG(STRING, const char*, name, default, comment)
|
||||
|
||||
// Use the following macros to declare a flag defined elsewhere:
|
||||
#define WEBRTC_DECLARE_bool(name) WEBRTC_DECLARE_FLAG(bool, name)
|
||||
#define WEBRTC_DECLARE_int(name) WEBRTC_DECLARE_FLAG(int, name)
|
||||
#define WEBRTC_DECLARE_float(name) WEBRTC_DECLARE_FLAG(double, name)
|
||||
#define WEBRTC_DECLARE_string(name) WEBRTC_DECLARE_FLAG(const char*, name)
|
||||
|
||||
// The global list of all flags.
|
||||
class FlagList {
|
||||
public:
|
||||
FlagList();
|
||||
|
||||
// The null-terminated list of all flags. Traverse with Flag::next().
|
||||
static Flag* list() { return list_; }
|
||||
|
||||
// If file != nullptr, prints information for all flags defined in file;
|
||||
// otherwise prints information for all flags in all files. The current flag
|
||||
// value is only printed if print_current_value is set.
|
||||
static void Print(const char* file, bool print_current_value);
|
||||
|
||||
// Lookup a flag by name. Returns the matching flag or null.
|
||||
static Flag* Lookup(const char* name);
|
||||
|
||||
// Helper function to parse flags: Takes an argument arg and splits it into
|
||||
// a flag name and flag value (or null if they are missing). is_bool is set
|
||||
// if the arg started with "-no" or "--no". The buffer may be used to NUL-
|
||||
// terminate the name, it must be large enough to hold any possible name.
|
||||
static void SplitArgument(const char* arg,
|
||||
char* buffer,
|
||||
int buffer_size,
|
||||
const char** name,
|
||||
const char** value,
|
||||
bool* is_bool);
|
||||
|
||||
// Set the flag values by parsing the command line. If remove_flags
|
||||
// is set, the flags and associated values are removed from (argc,
|
||||
// argv). Returns 0 if no error occurred. Otherwise, returns the
|
||||
// argv index > 0 for the argument where an error occurred. In that
|
||||
// case, (argc, argv) will remain unchanged indepdendent of the
|
||||
// remove_flags value, and no assumptions about flag settings should
|
||||
// be made.
|
||||
//
|
||||
// The following syntax for flags is accepted (both '-' and '--' are ok):
|
||||
//
|
||||
// --flag (bool flags only)
|
||||
// --noflag (bool flags only)
|
||||
// --flag=value (non-bool flags only, no spaces around '=')
|
||||
// --flag value (non-bool flags only)
|
||||
static int SetFlagsFromCommandLine(int* argc,
|
||||
const char** argv,
|
||||
bool remove_flags);
|
||||
static inline int SetFlagsFromCommandLine(int* argc,
|
||||
char** argv,
|
||||
bool remove_flags) {
|
||||
return SetFlagsFromCommandLine(argc, const_cast<const char**>(argv),
|
||||
remove_flags);
|
||||
}
|
||||
|
||||
// Registers a new flag. Called during program initialization. Not
|
||||
// thread-safe.
|
||||
static void Register(Flag* flag);
|
||||
|
||||
private:
|
||||
static Flag* list_;
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif // SHARED_COMMANDLINEFLAGS_FLAGS_H_
|
||||
Reference in New Issue
Block a user