• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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