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 19 namespace __sanitizer { 20 21 static 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 // Read until the next space or colon. 42 end = pos + internal_strcspn(pos, " :"); 43 } 44 if (end == 0) 45 end = pos + internal_strlen(pos); 46 } 47 *value = pos; 48 *value_length = end - pos; 49 return true; 50 } 51 52 static bool StartsWith(const char *flag, int flag_length, const char *value) { 53 if (!flag || !value) 54 return false; 55 int value_length = internal_strlen(value); 56 return (flag_length >= value_length) && 57 (0 == internal_strncmp(flag, value, value_length)); 58 } 59 60 void ParseFlag(const char *env, bool *flag, const char *name) { 61 const char *value; 62 int value_length; 63 if (!GetFlagValue(env, name, &value, &value_length)) 64 return; 65 if (StartsWith(value, value_length, "0") || 66 StartsWith(value, value_length, "no") || 67 StartsWith(value, value_length, "false")) 68 *flag = false; 69 if (StartsWith(value, value_length, "1") || 70 StartsWith(value, value_length, "yes") || 71 StartsWith(value, value_length, "true")) 72 *flag = true; 73 } 74 75 void ParseFlag(const char *env, int *flag, const char *name) { 76 const char *value; 77 int value_length; 78 if (!GetFlagValue(env, name, &value, &value_length)) 79 return; 80 *flag = internal_atoll(value); 81 } 82 83 static LowLevelAllocator allocator_for_flags; 84 85 void ParseFlag(const char *env, const char **flag, const char *name) { 86 const char *value; 87 int value_length; 88 if (!GetFlagValue(env, name, &value, &value_length)) 89 return; 90 // Copy the flag value. Don't use locks here, as flags are parsed at 91 // tool startup. 92 char *value_copy = (char*)(allocator_for_flags.Allocate(value_length + 1)); 93 internal_memcpy(value_copy, value, value_length); 94 value_copy[value_length] = '\0'; 95 *flag = value_copy; 96 } 97 98 } // namespace __sanitizer 99