| //===-- sanitizer_flags.cc ------------------------------------------------===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file is a part of ThreadSanitizer/AddressSanitizer runtime. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "sanitizer_flags.h" |
| |
| #include "sanitizer_common.h" |
| #include "sanitizer_libc.h" |
| |
| namespace __sanitizer { |
| |
| static bool GetFlagValue(const char *env, const char *name, |
| const char **value, int *value_length) { |
| if (env == 0) |
| return false; |
| const char *pos = internal_strstr(env, name); |
| const char *end; |
| if (pos == 0) |
| return false; |
| pos += internal_strlen(name); |
| if (pos[0] != '=') { |
| end = pos; |
| } else { |
| pos += 1; |
| if (pos[0] == '"') { |
| pos += 1; |
| end = internal_strchr(pos, '"'); |
| } else if (pos[0] == '\'') { |
| pos += 1; |
| end = internal_strchr(pos, '\''); |
| } else { |
| // Read until the next space or colon. |
| end = pos + internal_strcspn(pos, " :"); |
| } |
| if (end == 0) |
| end = pos + internal_strlen(pos); |
| } |
| *value = pos; |
| *value_length = end - pos; |
| return true; |
| } |
| |
| static bool StartsWith(const char *flag, int flag_length, const char *value) { |
| if (!flag || !value) |
| return false; |
| int value_length = internal_strlen(value); |
| return (flag_length >= value_length) && |
| (0 == internal_strncmp(flag, value, value_length)); |
| } |
| |
| void ParseFlag(const char *env, bool *flag, const char *name) { |
| const char *value; |
| int value_length; |
| if (!GetFlagValue(env, name, &value, &value_length)) |
| return; |
| if (StartsWith(value, value_length, "0") || |
| StartsWith(value, value_length, "no") || |
| StartsWith(value, value_length, "false")) |
| *flag = false; |
| if (StartsWith(value, value_length, "1") || |
| StartsWith(value, value_length, "yes") || |
| StartsWith(value, value_length, "true")) |
| *flag = true; |
| } |
| |
| void ParseFlag(const char *env, int *flag, const char *name) { |
| const char *value; |
| int value_length; |
| if (!GetFlagValue(env, name, &value, &value_length)) |
| return; |
| *flag = internal_atoll(value); |
| } |
| |
| static LowLevelAllocator allocator_for_flags; |
| |
| void ParseFlag(const char *env, const char **flag, const char *name) { |
| const char *value; |
| int value_length; |
| if (!GetFlagValue(env, name, &value, &value_length)) |
| return; |
| // Copy the flag value. Don't use locks here, as flags are parsed at |
| // tool startup. |
| char *value_copy = (char*)(allocator_for_flags.Allocate(value_length + 1)); |
| internal_memcpy(value_copy, value, value_length); |
| value_copy[value_length] = '\0'; |
| *flag = value_copy; |
| } |
| |
| } // namespace __sanitizer |