//===-- sanitizer_flag_parser.cpp -----------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file is a part of ThreadSanitizer/AddressSanitizer runtime.
//
//===----------------------------------------------------------------------===//

#include "sanitizer_flag_parser.h"

#include "sanitizer_common.h"
#include "sanitizer_libc.h"
#include "sanitizer_flags.h"
#include "sanitizer_flag_parser.h"

namespace __sanitizer {

LowLevelAllocator FlagParser::Alloc;

class UnknownFlags {
  static const int kMaxUnknownFlags = 20;
  const char *unknown_flags_[kMaxUnknownFlags];
  int n_unknown_flags_;

 public:
  void Add(const char *name) {
    CHECK_LT(n_unknown_flags_, kMaxUnknownFlags);
    unknown_flags_[n_unknown_flags_++] = name;
  }

  void Report() {
    if (!n_unknown_flags_) return;
    Printf("WARNING: found %d unrecognized flag(s):\n", n_unknown_flags_);
    for (int i = 0; i < n_unknown_flags_; ++i)
      Printf("    %s\n", unknown_flags_[i]);
    n_unknown_flags_ = 0;
  }
};

UnknownFlags unknown_flags;

void ReportUnrecognizedFlags() {
  unknown_flags.Report();
}

char *FlagParser::ll_strndup(const char *s, uptr n) {
  uptr len = internal_strnlen(s, n);
  char *s2 = (char*)Alloc.Allocate(len + 1);
  internal_memcpy(s2, s, len);
  s2[len] = 0;
  return s2;
}

void FlagParser::PrintFlagDescriptions() {
  Printf("Available flags for %s:\n", SanitizerToolName);
  for (int i = 0; i < n_flags_; ++i)
    Printf("\t%s\n\t\t- %s\n", flags_[i].name, flags_[i].desc);
}

void FlagParser::fatal_error(const char *err) {
  Printf("%s: ERROR: %s\n", SanitizerToolName, err);
  Die();
}

bool FlagParser::is_space(char c) {
  return c == ' ' || c == ',' || c == ':' || c == '\n' || c == '\t' ||
         c == '\r';
}

void FlagParser::skip_whitespace() {
  while (is_space(buf_[pos_])) ++pos_;
}

void FlagParser::parse_flag(const char *env_option_name) {
  uptr name_start = pos_;
  while (buf_[pos_] != 0 && buf_[pos_] != '=' && !is_space(buf_[pos_])) ++pos_;
  if (buf_[pos_] != '=') {
    if (env_option_name) {
      Printf("%s: ERROR: expected '=' in %s\n", SanitizerToolName,
             env_option_name);
      Die();
    } else {
      fatal_error("expected '='");
    }
  }
  char *name = ll_strndup(buf_ + name_start, pos_ - name_start);

  uptr value_start = ++pos_;
  char *value;
  if (buf_[pos_] == '\'' || buf_[pos_] == '"') {
    char quote = buf_[pos_++];
    while (buf_[pos_] != 0 && buf_[pos_] != quote) ++pos_;
    if (buf_[pos_] == 0) fatal_error("unterminated string");
    value = ll_strndup(buf_ + value_start + 1, pos_ - value_start - 1);
    ++pos_; // consume the closing quote
  } else {
    while (buf_[pos_] != 0 && !is_space(buf_[pos_])) ++pos_;
    if (buf_[pos_] != 0 && !is_space(buf_[pos_]))
      fatal_error("expected separator or eol");
    value = ll_strndup(buf_ + value_start, pos_ - value_start);
  }

  bool res = run_handler(name, value);
  if (!res) fatal_error("Flag parsing failed.");
}

void FlagParser::parse_flags(const char *env_option_name) {
  while (true) {
    skip_whitespace();
    if (buf_[pos_] == 0) break;
    parse_flag(env_option_name);
  }

  // Do a sanity check for certain flags.
  if (common_flags_dont_use.malloc_context_size < 1)
    common_flags_dont_use.malloc_context_size = 1;
}

void FlagParser::ParseStringFromEnv(const char *env_name) {
  const char *env = GetEnv(env_name);
  VPrintf(1, "%s: %s\n", env_name, env ? env : "<empty>");
  ParseString(env, env_name);
}

void FlagParser::ParseString(const char *s, const char *env_option_name) {
  if (!s) return;
  // Backup current parser state to allow nested ParseString() calls.
  const char *old_buf_ = buf_;
  uptr old_pos_ = pos_;
  buf_ = s;
  pos_ = 0;

  parse_flags(env_option_name);

  buf_ = old_buf_;
  pos_ = old_pos_;
}

bool FlagParser::ParseFile(const char *path, bool ignore_missing) {
  static const uptr kMaxIncludeSize = 1 << 15;
  char *data;
  uptr data_mapped_size;
  error_t err;
  uptr len;
  if (!ReadFileToBuffer(path, &data, &data_mapped_size, &len,
                        Max(kMaxIncludeSize, GetPageSizeCached()), &err)) {
    if (ignore_missing)
      return true;
    Printf("Failed to read options from '%s': error %d\n", path, err);
    return false;
  }
  ParseString(data, path);
  UnmapOrDie(data, data_mapped_size);
  return true;
}

bool FlagParser::run_handler(const char *name, const char *value) {
  for (int i = 0; i < n_flags_; ++i) {
    if (internal_strcmp(name, flags_[i].name) == 0)
      return flags_[i].handler->Parse(value);
  }
  // Unrecognized flag. This is not a fatal error, we may print a warning later.
  unknown_flags.Add(name);
  return true;
}

void FlagParser::RegisterHandler(const char *name, FlagHandlerBase *handler,
                                 const char *desc) {
  CHECK_LT(n_flags_, kMaxFlags);
  flags_[n_flags_].name = name;
  flags_[n_flags_].desc = desc;
  flags_[n_flags_].handler = handler;
  ++n_flags_;
}

FlagParser::FlagParser() : n_flags_(0), buf_(nullptr), pos_(0) {
  flags_ = (Flag *)Alloc.Allocate(sizeof(Flag) * kMaxFlags);
}

}  // namespace __sanitizer
