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
GetFlagValue(const char * env,const char * name,const char ** value,int * value_length)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 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
StartsWith(const char * flag,int flag_length,const char * value)51 static 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
ParseFlag(const char * env,bool * flag,const char * name)59 void 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
ParseFlag(const char * env,int * flag,const char * name)74 void 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
82 static LowLevelAllocator allocator_for_flags;
83
ParseFlag(const char * env,const char ** flag,const char * name)84 void 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