diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn index 220e575211..713fb34ef9 100644 --- a/rtc_base/BUILD.gn +++ b/rtc_base/BUILD.gn @@ -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", diff --git a/rtc_base/flags.cc b/rtc_base/flags.cc deleted file mode 100644 index ca32c730e5..0000000000 --- a/rtc_base/flags.cc +++ /dev/null @@ -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 -#include -#include - -#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(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(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 diff --git a/rtc_base/flags.h b/rtc_base/flags.h deleted file mode 100644 index 61a95ffd53..0000000000 --- a/rtc_base/flags.h +++ /dev/null @@ -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(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_