tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

usage_config.cc (5594B)


      1 //
      2 //  Copyright 2019 The Abseil Authors.
      3 //
      4 // Licensed under the Apache License, Version 2.0 (the "License");
      5 // you may not use this file except in compliance with the License.
      6 // You may obtain a copy of the License at
      7 //
      8 //      https://www.apache.org/licenses/LICENSE-2.0
      9 //
     10 // Unless required by applicable law or agreed to in writing, software
     11 // distributed under the License is distributed on an "AS IS" BASIS,
     12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 // See the License for the specific language governing permissions and
     14 // limitations under the License.
     15 
     16 #include "absl/flags/usage_config.h"
     17 
     18 #include <functional>
     19 #include <iostream>
     20 #include <string>
     21 
     22 #include "absl/base/attributes.h"
     23 #include "absl/base/config.h"
     24 #include "absl/base/const_init.h"
     25 #include "absl/base/no_destructor.h"
     26 #include "absl/base/thread_annotations.h"
     27 #include "absl/flags/internal/path_util.h"
     28 #include "absl/flags/internal/program_name.h"
     29 #include "absl/strings/match.h"
     30 #include "absl/strings/string_view.h"
     31 #include "absl/strings/strip.h"
     32 #include "absl/synchronization/mutex.h"
     33 
     34 extern "C" {
     35 
     36 // Additional report of fatal usage error message before we std::exit. Error is
     37 // fatal if is_fatal argument to ReportUsageError is true.
     38 ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL(
     39    AbslInternalReportFatalUsageError)(absl::string_view) {}
     40 
     41 }  // extern "C"
     42 
     43 namespace absl {
     44 ABSL_NAMESPACE_BEGIN
     45 namespace flags_internal {
     46 
     47 namespace {
     48 
     49 // --------------------------------------------------------------------
     50 // Returns true if flags defined in the filename should be reported with
     51 // -helpshort flag.
     52 
     53 bool ContainsHelpshortFlags(absl::string_view filename) {
     54  // By default we only want flags in binary's main. We expect the main
     55  // routine to reside in <program>.cc or <program>-main.cc or
     56  // <program>_main.cc, where the <program> is the name of the binary
     57  // (without .exe on Windows).
     58  auto suffix = flags_internal::Basename(filename);
     59  auto program_name = flags_internal::ShortProgramInvocationName();
     60  absl::string_view program_name_ref = program_name;
     61 #if defined(_WIN32)
     62  absl::ConsumeSuffix(&program_name_ref, ".exe");
     63 #endif
     64  if (!absl::ConsumePrefix(&suffix, program_name_ref))
     65    return false;
     66  return absl::StartsWith(suffix, ".") || absl::StartsWith(suffix, "-main.") ||
     67         absl::StartsWith(suffix, "_main.");
     68 }
     69 
     70 // --------------------------------------------------------------------
     71 // Returns true if flags defined in the filename should be reported with
     72 // -helppackage flag.
     73 
     74 bool ContainsHelppackageFlags(absl::string_view filename) {
     75  // TODO(rogeeff): implement properly when registry is available.
     76  return ContainsHelpshortFlags(filename);
     77 }
     78 
     79 // --------------------------------------------------------------------
     80 // Generates program version information into supplied output.
     81 
     82 std::string VersionString() {
     83  std::string version_str(flags_internal::ShortProgramInvocationName());
     84 
     85  version_str += "\n";
     86 
     87 #if !defined(NDEBUG)
     88  version_str += "Debug build (NDEBUG not #defined)\n";
     89 #endif
     90 
     91  return version_str;
     92 }
     93 
     94 // --------------------------------------------------------------------
     95 // Normalizes the filename specific to the build system/filesystem used.
     96 
     97 std::string NormalizeFilename(absl::string_view filename) {
     98  // Skip any leading slashes
     99  auto pos = filename.find_first_not_of("\\/");
    100  if (pos == absl::string_view::npos) return "";
    101 
    102  filename.remove_prefix(pos);
    103  return std::string(filename);
    104 }
    105 
    106 // --------------------------------------------------------------------
    107 
    108 absl::Mutex* CustomUsageConfigMutex() {
    109  static absl::NoDestructor<absl::Mutex> mutex;
    110  return mutex.get();
    111 }
    112 ABSL_CONST_INIT FlagsUsageConfig* custom_usage_config
    113    ABSL_GUARDED_BY(CustomUsageConfigMutex())
    114        ABSL_PT_GUARDED_BY(CustomUsageConfigMutex()) = nullptr;
    115 
    116 }  // namespace
    117 
    118 FlagsUsageConfig GetUsageConfig() {
    119  absl::MutexLock l(CustomUsageConfigMutex());
    120 
    121  if (custom_usage_config) return *custom_usage_config;
    122 
    123  FlagsUsageConfig default_config;
    124  default_config.contains_helpshort_flags = &ContainsHelpshortFlags;
    125  default_config.contains_help_flags = &ContainsHelppackageFlags;
    126  default_config.contains_helppackage_flags = &ContainsHelppackageFlags;
    127  default_config.version_string = &VersionString;
    128  default_config.normalize_filename = &NormalizeFilename;
    129 
    130  return default_config;
    131 }
    132 
    133 void ReportUsageError(absl::string_view msg, bool is_fatal) {
    134  std::cerr << "ERROR: " << msg << std::endl;
    135 
    136  if (is_fatal) {
    137    ABSL_INTERNAL_C_SYMBOL(AbslInternalReportFatalUsageError)(msg);
    138  }
    139 }
    140 
    141 }  // namespace flags_internal
    142 
    143 void SetFlagsUsageConfig(FlagsUsageConfig usage_config) {
    144  absl::MutexLock l(flags_internal::CustomUsageConfigMutex());
    145 
    146  if (!usage_config.contains_helpshort_flags)
    147    usage_config.contains_helpshort_flags =
    148        flags_internal::ContainsHelpshortFlags;
    149 
    150  if (!usage_config.contains_help_flags)
    151    usage_config.contains_help_flags = flags_internal::ContainsHelppackageFlags;
    152 
    153  if (!usage_config.contains_helppackage_flags)
    154    usage_config.contains_helppackage_flags =
    155        flags_internal::ContainsHelppackageFlags;
    156 
    157  if (!usage_config.version_string)
    158    usage_config.version_string = flags_internal::VersionString;
    159 
    160  if (!usage_config.normalize_filename)
    161    usage_config.normalize_filename = flags_internal::NormalizeFilename;
    162 
    163  if (flags_internal::custom_usage_config)
    164    *flags_internal::custom_usage_config = usage_config;
    165  else
    166    flags_internal::custom_usage_config = new FlagsUsageConfig(usage_config);
    167 }
    168 
    169 ABSL_NAMESPACE_END
    170 }  // namespace absl