//===- subzero/src/IceRangeSpec.cpp - Include/exclude specification -------===//
//
//                        The Subzero Code Generator
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Implements a class for specifying sets of names and number ranges to
/// match against.  This is specified as a comma-separated list of clauses.
/// Each clause optionally starts with '-' to indicate exclusion instead of
/// inclusion.  A clause can be a name, or a numeric range X:Y, or a single
/// number X.  The X:Y form indicates a range of numbers greater than or equal
/// to X and strictly less than Y.  A missing "X" is taken to be 0, and a
/// missing "Y" is taken to be infinite.  E.g., "0:" and ":" specify the entire
/// set.
///
/// This is essentially the same implementation as in szbuild.py, except that
/// regular expressions are not used for the names.
///
//===----------------------------------------------------------------------===//

#include "IceRangeSpec.h"
#include "IceStringPool.h"

#include <cctype>
#include <string>
#include <unordered_set>
#include <vector>

namespace Ice {

bool RangeSpec::HasNames = false;

namespace {

/// Helper function to parse "X" or "X:Y" into First and Last.
/// - "X" is treated as "X:X+1".
/// - ":Y" is treated as "0:Y".
/// - "X:" is treated as "X:inf"
///
/// Behavior is undefined if "X" or "Y" is not a proper number (since std::stoul
/// throws an exception).
///
/// If the string doesn't contain 1 or 2 ':' delimiters, or X>=Y,
/// report_fatal_error is called.
void getRange(const std::string &Token, uint32_t *First, uint32_t *Last) {
  bool Error = false;
  auto Tokens = RangeSpec::tokenize(Token, RangeSpec::DELIM_RANGE);
  if (Tokens.size() == 1) {
    *First = std::stoul(Tokens[0]);
    *Last = *First + 1;
  } else if (Tokens.size() == 2) {
    *First = Tokens[0].empty() ? 0 : std::stoul(Tokens[0]);
    *Last = Tokens[1].empty() ? RangeSpec::RangeMax : std::stoul(Tokens[1]);
  } else {
    Error = true;
  }
  if (*First >= *Last) {
    Error = true;
  }
  if (Error) {
    llvm::report_fatal_error("Invalid range " + Token);
  }
}

/// Helper function to add one token to the include or exclude set.  The token
/// is examined and then treated as either a numeric range or a single name.
void record(const std::string &Token, RangeSpec::Desc *D) {
  if (Token.empty())
    return;
  // Mark that an include or exclude was explicitly given.  This affects the
  // default decision when matching a value that wasn't explicitly provided in
  // the include or exclude list.
  D->IsExplicit = true;
  // A range is identified by starting with a digit or a ':'.
  if (Token[0] == RangeSpec::DELIM_RANGE || std::isdigit(Token[0])) {
    uint32_t First, Last;
    getRange(Token, &First, &Last);
    if (Last == RangeSpec::RangeMax) {
      D->AllFrom = std::min(D->AllFrom, First);
    } else {
      if (Last >= D->Numbers.size())
        D->Numbers.resize(Last + 1);
      D->Numbers.set(First, Last);
    }
  } else {
    // Otherwise treat it as a single name.
    D->Names.insert(Token);
  }
}

} // end of anonymous namespace

std::vector<std::string> RangeSpec::tokenize(const std::string &Spec,
                                             char Delimiter) {
  std::vector<std::string> Tokens;
  if (!Spec.empty()) {
    std::string::size_type StartPos = 0;
    std::string::size_type DelimPos = 0;
    while (DelimPos != std::string::npos) {
      DelimPos = Spec.find(Delimiter, StartPos);
      Tokens.emplace_back(Spec.substr(StartPos, DelimPos - StartPos));
      StartPos = DelimPos + 1;
    }
  }
  return Tokens;
}

/// Initialize the RangeSpec with the given string.  Calling init multiple times
/// (e.g. init("A");init("B");) is equivalent to init("A,B"); .
void RangeSpec::init(const std::string &Spec) {
  auto Tokens = tokenize(Spec, DELIM_LIST);
  for (const auto &Token : Tokens) {
    if (Token[0] == '-') {
      exclude(Token.substr(1));
    } else {
      include(Token);
    }
  }
  if (!Includes.Names.empty() || !Excludes.Names.empty())
    HasNames = true;
}

/// Determine whether the given Name/Number combo match the specification given
/// to the init() method.  Explicit excludes take precedence over explicit
/// includes.  If the combo doesn't match any explicit include or exclude:
/// - false if the init() string is empty (no explicit includes or excludes)
/// - true if there is at least one explicit exclude and no explicit includes
/// - false otherwise (at least one explicit include)
bool RangeSpec::match(const std::string &Name, uint32_t Number) const {
  // No match if it is explicitly excluded by name or number.
  if (Excludes.Names.find(Name) != Excludes.Names.end())
    return false;
  if (Number >= Excludes.AllFrom)
    return false;
  if (Number < Excludes.Numbers.size() && Excludes.Numbers[Number])
    return false;

  // Positive match if it is explicitly included by name or number.
  if (Includes.Names.find(Name) != Includes.Names.end())
    return true;
  if (Number >= Includes.AllFrom)
    return true;
  if (Number < Includes.Numbers.size() && Includes.Numbers[Number])
    return true;

  // Otherwise use the default decision.
  return Excludes.IsExplicit && !Includes.IsExplicit;
}

void RangeSpec::include(const std::string &Token) { record(Token, &Includes); }

void RangeSpec::exclude(const std::string &Token) { record(Token, &Excludes); }

} // end of namespace Ice
