Daily bump.
[official-gcc.git] / libsanitizer / sanitizer_common / sanitizer_flags.cc
blob90bb57dff98049a9732ad873cb97022a2afeba99
1 //===-- sanitizer_flags.cc ------------------------------------------------===//
2 //
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
5 //
6 //===----------------------------------------------------------------------===//
7 //
8 // This file is a part of ThreadSanitizer/AddressSanitizer runtime.
9 //
10 //===----------------------------------------------------------------------===//
12 #include "sanitizer_flags.h"
14 #include "sanitizer_common.h"
15 #include "sanitizer_libc.h"
17 namespace __sanitizer {
19 void SetCommonFlagsDefaults(CommonFlags *f) {
20 f->symbolize = true;
21 f->external_symbolizer_path = 0;
22 f->strip_path_prefix = "";
23 f->fast_unwind_on_fatal = false;
24 f->fast_unwind_on_malloc = true;
25 f->handle_ioctl = false;
26 f->malloc_context_size = 1;
27 f->log_path = "stderr";
28 f->verbosity = 0;
29 f->detect_leaks = false;
30 f->leak_check_at_exit = true;
31 f->allocator_may_return_null = false;
32 f->print_summary = true;
35 void ParseCommonFlagsFromString(CommonFlags *f, const char *str) {
36 ParseFlag(str, &f->symbolize, "symbolize");
37 ParseFlag(str, &f->external_symbolizer_path, "external_symbolizer_path");
38 ParseFlag(str, &f->strip_path_prefix, "strip_path_prefix");
39 ParseFlag(str, &f->fast_unwind_on_fatal, "fast_unwind_on_fatal");
40 ParseFlag(str, &f->fast_unwind_on_malloc, "fast_unwind_on_malloc");
41 ParseFlag(str, &f->handle_ioctl, "handle_ioctl");
42 ParseFlag(str, &f->malloc_context_size, "malloc_context_size");
43 ParseFlag(str, &f->log_path, "log_path");
44 ParseFlag(str, &f->verbosity, "verbosity");
45 ParseFlag(str, &f->detect_leaks, "detect_leaks");
46 ParseFlag(str, &f->leak_check_at_exit, "leak_check_at_exit");
47 ParseFlag(str, &f->allocator_may_return_null, "allocator_may_return_null");
48 ParseFlag(str, &f->print_summary, "print_summary");
50 // Do a sanity check for certain flags.
51 if (f->malloc_context_size < 1)
52 f->malloc_context_size = 1;
55 static bool GetFlagValue(const char *env, const char *name,
56 const char **value, int *value_length) {
57 if (env == 0)
58 return false;
59 const char *pos = 0;
60 for (;;) {
61 pos = internal_strstr(env, name);
62 if (pos == 0)
63 return false;
64 if (pos != env && ((pos[-1] >= 'a' && pos[-1] <= 'z') || pos[-1] == '_')) {
65 // Seems to be middle of another flag name or value.
66 env = pos + 1;
67 continue;
69 break;
71 pos += internal_strlen(name);
72 const char *end;
73 if (pos[0] != '=') {
74 end = pos;
75 } else {
76 pos += 1;
77 if (pos[0] == '"') {
78 pos += 1;
79 end = internal_strchr(pos, '"');
80 } else if (pos[0] == '\'') {
81 pos += 1;
82 end = internal_strchr(pos, '\'');
83 } else {
84 // Read until the next space or colon.
85 end = pos + internal_strcspn(pos, " :");
87 if (end == 0)
88 end = pos + internal_strlen(pos);
90 *value = pos;
91 *value_length = end - pos;
92 return true;
95 static bool StartsWith(const char *flag, int flag_length, const char *value) {
96 if (!flag || !value)
97 return false;
98 int value_length = internal_strlen(value);
99 return (flag_length >= value_length) &&
100 (0 == internal_strncmp(flag, value, value_length));
103 void ParseFlag(const char *env, bool *flag, const char *name) {
104 const char *value;
105 int value_length;
106 if (!GetFlagValue(env, name, &value, &value_length))
107 return;
108 if (StartsWith(value, value_length, "0") ||
109 StartsWith(value, value_length, "no") ||
110 StartsWith(value, value_length, "false"))
111 *flag = false;
112 if (StartsWith(value, value_length, "1") ||
113 StartsWith(value, value_length, "yes") ||
114 StartsWith(value, value_length, "true"))
115 *flag = true;
118 void ParseFlag(const char *env, int *flag, const char *name) {
119 const char *value;
120 int value_length;
121 if (!GetFlagValue(env, name, &value, &value_length))
122 return;
123 *flag = static_cast<int>(internal_atoll(value));
126 static LowLevelAllocator allocator_for_flags;
128 void ParseFlag(const char *env, const char **flag, const char *name) {
129 const char *value;
130 int value_length;
131 if (!GetFlagValue(env, name, &value, &value_length))
132 return;
133 // Copy the flag value. Don't use locks here, as flags are parsed at
134 // tool startup.
135 char *value_copy = (char*)(allocator_for_flags.Allocate(value_length + 1));
136 internal_memcpy(value_copy, value, value_length);
137 value_copy[value_length] = '\0';
138 *flag = value_copy;
141 } // namespace __sanitizer