186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines//===-- sanitizer_flag_parser.h ---------------------------------*- C++ -*-===// 286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// 386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// The LLVM Compiler Infrastructure 486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// 586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// This file is distributed under the University of Illinois Open Source 686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// License. See LICENSE.TXT for details. 786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// 886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines//===----------------------------------------------------------------------===// 986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// 1086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// This file is a part of ThreadSanitizer/AddressSanitizer runtime. 1186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// 1286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines//===----------------------------------------------------------------------===// 1386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 1486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#ifndef SANITIZER_FLAG_REGISTRY_H 1586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define SANITIZER_FLAG_REGISTRY_H 1686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 1786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#include "sanitizer_internal_defs.h" 1886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#include "sanitizer_libc.h" 1986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#include "sanitizer_common.h" 2086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 2186277eb844c4983c81de62d7c050e92fe7155788Stephen Hinesnamespace __sanitizer { 2286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 2386277eb844c4983c81de62d7c050e92fe7155788Stephen Hinesclass FlagHandlerBase { 2486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines public: 2586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines virtual bool Parse(const char *value) { return false; } 2686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines}; 2786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 2886277eb844c4983c81de62d7c050e92fe7155788Stephen Hinestemplate <typename T> 2986277eb844c4983c81de62d7c050e92fe7155788Stephen Hinesclass FlagHandler : public FlagHandlerBase { 3086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines T *t_; 3186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 3286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines public: 3386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines explicit FlagHandler(T *t) : t_(t) {} 3486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines bool Parse(const char *value) final; 3586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines}; 3686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 3786277eb844c4983c81de62d7c050e92fe7155788Stephen Hinestemplate <> 3886277eb844c4983c81de62d7c050e92fe7155788Stephen Hinesinline bool FlagHandler<bool>::Parse(const char *value) { 3986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (internal_strcmp(value, "0") == 0 || 4086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines internal_strcmp(value, "no") == 0 || 4186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines internal_strcmp(value, "false") == 0) { 4286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines *t_ = false; 4386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines return true; 4486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines } 4586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (internal_strcmp(value, "1") == 0 || 4686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines internal_strcmp(value, "yes") == 0 || 4786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines internal_strcmp(value, "true") == 0) { 4886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines *t_ = true; 4986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines return true; 5086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines } 5186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines Printf("ERROR: Invalid value for bool option: '%s'\n", value); 5286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines return false; 5386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines} 5486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 5586277eb844c4983c81de62d7c050e92fe7155788Stephen Hinestemplate <> 5686277eb844c4983c81de62d7c050e92fe7155788Stephen Hinesinline bool FlagHandler<const char *>::Parse(const char *value) { 5786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines *t_ = internal_strdup(value); 5886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines return true; 5986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines} 6086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 6186277eb844c4983c81de62d7c050e92fe7155788Stephen Hinestemplate <> 6286277eb844c4983c81de62d7c050e92fe7155788Stephen Hinesinline bool FlagHandler<int>::Parse(const char *value) { 6386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines char *value_end; 6486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines *t_ = internal_simple_strtoll(value, &value_end, 10); 6586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines bool ok = *value_end == 0; 6686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (!ok) Printf("ERROR: Invalid value for int option: '%s'\n", value); 6786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines return ok; 6886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines} 6986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 7086277eb844c4983c81de62d7c050e92fe7155788Stephen Hinestemplate <> 7186277eb844c4983c81de62d7c050e92fe7155788Stephen Hinesinline bool FlagHandler<uptr>::Parse(const char *value) { 7286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines char *value_end; 7386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines *t_ = internal_simple_strtoll(value, &value_end, 10); 7486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines bool ok = *value_end == 0; 7586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (!ok) Printf("ERROR: Invalid value for uptr option: '%s'\n", value); 7686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines return ok; 7786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines} 7886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 7986277eb844c4983c81de62d7c050e92fe7155788Stephen Hinesclass FlagParser { 8086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines static const int kMaxFlags = 200; 8186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines struct Flag { 8286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines const char *name; 8386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines const char *desc; 8486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines FlagHandlerBase *handler; 8586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines } *flags_; 8686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines int n_flags_; 8786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 8886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines const char *buf_; 8986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines uptr pos_; 9086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 9186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines public: 9286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines FlagParser(); 9386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines void RegisterHandler(const char *name, FlagHandlerBase *handler, 9486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines const char *desc); 9586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines void ParseString(const char *s); 96799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar bool ParseFile(const char *path, bool ignore_missing); 9786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines void PrintFlagDescriptions(); 9886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 9986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines static LowLevelAllocator Alloc; 10086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 10186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines private: 10286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines void fatal_error(const char *err); 10386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines bool is_space(char c); 10486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines void skip_whitespace(); 10586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines void parse_flags(); 10686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines void parse_flag(); 10786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines bool run_handler(const char *name, const char *value); 10886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines char *ll_strndup(const char *s, uptr n); 10986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines}; 11086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 11186277eb844c4983c81de62d7c050e92fe7155788Stephen Hinestemplate <typename T> 11286277eb844c4983c81de62d7c050e92fe7155788Stephen Hinesstatic void RegisterFlag(FlagParser *parser, const char *name, const char *desc, 11386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines T *var) { 11486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines FlagHandler<T> *fh = new (FlagParser::Alloc) FlagHandler<T>(var); // NOLINT 11586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines parser->RegisterHandler(name, fh, desc); 11686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines} 11786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 11886277eb844c4983c81de62d7c050e92fe7155788Stephen Hinesvoid ReportUnrecognizedFlags(); 11986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 12086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines} // namespace __sanitizer 12186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 12286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#endif // SANITIZER_FLAG_REGISTRY_H 123