1//===-- sanitizer_flags.cc ------------------------------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file is a part of ThreadSanitizer/AddressSanitizer runtime. 11// 12//===----------------------------------------------------------------------===// 13 14#include "sanitizer_flags.h" 15 16#include "sanitizer_common.h" 17#include "sanitizer_libc.h" 18 19namespace __sanitizer { 20 21static bool GetFlagValue(const char *env, const char *name, 22 const char **value, int *value_length) { 23 if (env == 0) 24 return false; 25 const char *pos = internal_strstr(env, name); 26 const char *end; 27 if (pos == 0) 28 return false; 29 pos += internal_strlen(name); 30 if (pos[0] != '=') { 31 end = pos; 32 } else { 33 pos += 1; 34 if (pos[0] == '"') { 35 pos += 1; 36 end = internal_strchr(pos, '"'); 37 } else if (pos[0] == '\'') { 38 pos += 1; 39 end = internal_strchr(pos, '\''); 40 } else { 41 end = internal_strchr(pos, ' '); 42 } 43 if (end == 0) 44 end = pos + internal_strlen(pos); 45 } 46 *value = pos; 47 *value_length = end - pos; 48 return true; 49} 50 51static bool StartsWith(const char *flag, int flag_length, const char *value) { 52 if (!flag || !value) 53 return false; 54 int value_length = internal_strlen(value); 55 return (flag_length >= value_length) && 56 (0 == internal_strncmp(flag, value, value_length)); 57} 58 59void ParseFlag(const char *env, bool *flag, const char *name) { 60 const char *value; 61 int value_length; 62 if (!GetFlagValue(env, name, &value, &value_length)) 63 return; 64 if (StartsWith(value, value_length, "0") || 65 StartsWith(value, value_length, "no") || 66 StartsWith(value, value_length, "false")) 67 *flag = false; 68 if (StartsWith(value, value_length, "1") || 69 StartsWith(value, value_length, "yes") || 70 StartsWith(value, value_length, "true")) 71 *flag = true; 72} 73 74void ParseFlag(const char *env, int *flag, const char *name) { 75 const char *value; 76 int value_length; 77 if (!GetFlagValue(env, name, &value, &value_length)) 78 return; 79 *flag = internal_atoll(value); 80} 81 82static LowLevelAllocator allocator_for_flags; 83 84void ParseFlag(const char *env, const char **flag, const char *name) { 85 const char *value; 86 int value_length; 87 if (!GetFlagValue(env, name, &value, &value_length)) 88 return; 89 // Copy the flag value. Don't use locks here, as flags are parsed at 90 // tool startup. 91 char *value_copy = (char*)(allocator_for_flags.Allocate(value_length + 1)); 92 internal_memcpy(value_copy, value, value_length); 93 value_copy[value_length] = '\0'; 94 *flag = value_copy; 95} 96 97} // namespace __sanitizer 98