1f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov//===-- sanitizer_flags.cc ------------------------------------------------===//
2f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov//
3f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov//                     The LLVM Compiler Infrastructure
4f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov//
5f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov// This file is distributed under the University of Illinois Open Source
6f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov// License. See LICENSE.TXT for details.
7f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov//
8f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov//===----------------------------------------------------------------------===//
9f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov//
10f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov// This file is a part of ThreadSanitizer/AddressSanitizer runtime.
11f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov//
12f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov//===----------------------------------------------------------------------===//
13f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov
14f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov#include "sanitizer_flags.h"
15f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov
16f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov#include "sanitizer_common.h"
17f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov#include "sanitizer_libc.h"
18f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov
19f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonovnamespace __sanitizer {
20f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov
21947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonovstatic bool GetFlagValue(const char *env, const char *name,
22947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov                         const char **value, int *value_length) {
23f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov  if (env == 0)
24947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov    return false;
25f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov  const char *pos = internal_strstr(env, name);
26f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov  const char *end;
27f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov  if (pos == 0)
28947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov    return false;
29f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov  pos += internal_strlen(name);
30f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov  if (pos[0] != '=') {
31f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov    end = pos;
32f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov  } else {
33f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov    pos += 1;
34f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov    if (pos[0] == '"') {
35f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov      pos += 1;
36f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov      end = internal_strchr(pos, '"');
37f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov    } else if (pos[0] == '\'') {
38f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov      pos += 1;
39f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov      end = internal_strchr(pos, '\'');
40f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov    } else {
41f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov      end = internal_strchr(pos, ' ');
42f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov    }
43f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov    if (end == 0)
44f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov      end = pos + internal_strlen(pos);
45f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov  }
46947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov  *value = pos;
47947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov  *value_length = end - pos;
48947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov  return true;
49947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov}
50947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov
51947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonovstatic bool StartsWith(const char *flag, int flag_length, const char *value) {
52947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov  if (!flag || !value)
53947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov    return false;
54947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov  int value_length = internal_strlen(value);
55947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov  return (flag_length >= value_length) &&
56947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov         (0 == internal_strncmp(flag, value, value_length));
57f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov}
58f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov
59f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonovvoid ParseFlag(const char *env, bool *flag, const char *name) {
60947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov  const char *value;
61947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov  int value_length;
62947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov  if (!GetFlagValue(env, name, &value, &value_length))
63f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov    return;
64947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov  if (StartsWith(value, value_length, "0") ||
65947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov      StartsWith(value, value_length, "no") ||
66947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov      StartsWith(value, value_length, "false"))
67f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov    *flag = false;
68947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov  if (StartsWith(value, value_length, "1") ||
69947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov      StartsWith(value, value_length, "yes") ||
70947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov      StartsWith(value, value_length, "true"))
71f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov    *flag = true;
72f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov}
73f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov
74f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonovvoid ParseFlag(const char *env, int *flag, const char *name) {
75947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov  const char *value;
76947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov  int value_length;
77947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov  if (!GetFlagValue(env, name, &value, &value_length))
78f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov    return;
79947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov  *flag = internal_atoll(value);
80f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov}
81f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov
82947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonovstatic LowLevelAllocator allocator_for_flags;
83947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov
84f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonovvoid ParseFlag(const char *env, const char **flag, const char *name) {
85947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov  const char *value;
86947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov  int value_length;
87947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov  if (!GetFlagValue(env, name, &value, &value_length))
88f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov    return;
89d883c8007ea8b5ffad10d82a66b1bb262e109705Alexey Samsonov  // Copy the flag value. Don't use locks here, as flags are parsed at
90d883c8007ea8b5ffad10d82a66b1bb262e109705Alexey Samsonov  // tool startup.
91947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov  char *value_copy = (char*)(allocator_for_flags.Allocate(value_length + 1));
92947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov  internal_memcpy(value_copy, value, value_length);
93947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov  value_copy[value_length] = '\0';
94947fbd1a073fcd38988c1ec131452e99bb0313f8Alexey Samsonov  *flag = value_copy;
95f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov}
96f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov
97f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov}  // namespace __sanitizer
98