brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.7 KiB · dccdee4 Raw
203 lines · c
1//===-- sanitizer_flag_parser.h ---------------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file is a part of ThreadSanitizer/AddressSanitizer runtime.10//11//===----------------------------------------------------------------------===//12 13#ifndef SANITIZER_FLAG_REGISTRY_H14#define SANITIZER_FLAG_REGISTRY_H15 16#include "sanitizer_common.h"17#include "sanitizer_internal_defs.h"18#include "sanitizer_libc.h"19 20namespace __sanitizer {21 22class FlagHandlerBase {23 public:24  virtual bool Parse(const char *value) { return false; }25  // Write the C string representation of the current value (truncated to fit)26  // into the buffer of size `size`. Returns false if truncation occurred and27  // returns true otherwise.28  virtual bool Format(char *buffer, uptr size) {29    if (size > 0)30      buffer[0] = '\0';31    return false;32  }33 34 protected:35  ~FlagHandlerBase() {}36 37  inline bool FormatString(char *buffer, uptr size, const char *str_to_use) {38    uptr num_symbols_should_write =39        internal_snprintf(buffer, size, "%s", str_to_use);40    return num_symbols_should_write < size;41  }42};43 44template <typename T>45class FlagHandler final : public FlagHandlerBase {46  T *t_;47 48 public:49  explicit FlagHandler(T *t) : t_(t) {}50  bool Parse(const char *value) final;51  bool Format(char *buffer, uptr size) final;52};53 54inline bool ParseBool(const char *value, bool *b) {55  if (internal_strcmp(value, "0") == 0 ||56      internal_strcmp(value, "no") == 0 ||57      internal_strcmp(value, "false") == 0) {58    *b = false;59    return true;60  }61  if (internal_strcmp(value, "1") == 0 ||62      internal_strcmp(value, "yes") == 0 ||63      internal_strcmp(value, "true") == 0) {64    *b = true;65    return true;66  }67  return false;68}69 70template <>71inline bool FlagHandler<bool>::Parse(const char *value) {72  if (ParseBool(value, t_)) return true;73  Printf("ERROR: Invalid value for bool option: '%s'\n", value);74  return false;75}76 77template <>78inline bool FlagHandler<bool>::Format(char *buffer, uptr size) {79  return FormatString(buffer, size, *t_ ? "true" : "false");80}81 82template <>83inline bool FlagHandler<HandleSignalMode>::Parse(const char *value) {84  bool b;85  if (ParseBool(value, &b)) {86    *t_ = b ? kHandleSignalYes : kHandleSignalNo;87    return true;88  }89  if (internal_strcmp(value, "2") == 0 ||90      internal_strcmp(value, "exclusive") == 0) {91    *t_ = kHandleSignalExclusive;92    return true;93  }94  Printf("ERROR: Invalid value for signal handler option: '%s'\n", value);95  return false;96}97 98template <>99inline bool FlagHandler<HandleSignalMode>::Format(char *buffer, uptr size) {100  uptr num_symbols_should_write = internal_snprintf(buffer, size, "%d", *t_);101  return num_symbols_should_write < size;102}103 104template <>105inline bool FlagHandler<const char *>::Parse(const char *value) {106  *t_ = value;107  return true;108}109 110template <>111inline bool FlagHandler<const char *>::Format(char *buffer, uptr size) {112  return FormatString(buffer, size, *t_);113}114 115template <>116inline bool FlagHandler<int>::Parse(const char *value) {117  const char *value_end;118  *t_ = internal_simple_strtoll(value, &value_end, 10);119  bool ok = *value_end == 0;120  if (!ok) Printf("ERROR: Invalid value for int option: '%s'\n", value);121  return ok;122}123 124template <>125inline bool FlagHandler<int>::Format(char *buffer, uptr size) {126  uptr num_symbols_should_write = internal_snprintf(buffer, size, "%d", *t_);127  return num_symbols_should_write < size;128}129 130template <>131inline bool FlagHandler<uptr>::Parse(const char *value) {132  const char *value_end;133  *t_ = internal_simple_strtoll(value, &value_end, 10);134  bool ok = *value_end == 0;135  if (!ok) Printf("ERROR: Invalid value for uptr option: '%s'\n", value);136  return ok;137}138 139template <>140inline bool FlagHandler<uptr>::Format(char *buffer, uptr size) {141  uptr num_symbols_should_write = internal_snprintf(buffer, size, "0x%zx", *t_);142  return num_symbols_should_write < size;143}144 145template <>146inline bool FlagHandler<s64>::Parse(const char *value) {147  const char *value_end;148  *t_ = internal_simple_strtoll(value, &value_end, 10);149  bool ok = *value_end == 0;150  if (!ok) Printf("ERROR: Invalid value for s64 option: '%s'\n", value);151  return ok;152}153 154template <>155inline bool FlagHandler<s64>::Format(char *buffer, uptr size) {156  uptr num_symbols_should_write = internal_snprintf(buffer, size, "%lld", *t_);157  return num_symbols_should_write < size;158}159 160class FlagParser {161  static const int kMaxFlags = 200;162  struct Flag {163    const char *name;164    const char *desc;165    FlagHandlerBase *handler;166  } *flags_;167  int n_flags_;168 169  const char *buf_;170  uptr pos_;171 172 public:173  FlagParser();174  void RegisterHandler(const char *name, FlagHandlerBase *handler,175                       const char *desc);176  void ParseString(const char *s, const char *env_name = 0);177  void ParseStringFromEnv(const char *env_name);178  bool ParseFile(const char *path, bool ignore_missing);179  void PrintFlagDescriptions();180 181 private:182  void fatal_error(const char *err);183  bool is_space(char c);184  void skip_whitespace();185  void parse_flags(const char *env_option_name);186  void parse_flag(const char *env_option_name);187  bool run_handler(const char *name, const char *value);188  char *ll_strndup(const char *s, uptr n);189};190 191template <typename T>192static void RegisterFlag(FlagParser *parser, const char *name, const char *desc,193                         T *var) {194  FlagHandler<T> *fh = new (GetGlobalLowLevelAllocator()) FlagHandler<T>(var);195  parser->RegisterHandler(name, fh, desc);196}197 198void ReportUnrecognizedFlags();199 200}  // namespace __sanitizer201 202#endif  // SANITIZER_FLAG_REGISTRY_H203