/* Copyright (c) 2008-2010, Google Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

// This file is part of ThreadSanitizer, a dynamic data race detector.
// Author: Evgeniy Stepanov.

// This file contains the parser for valgrind-compatible suppressions.

#include "common_util.h"
#include "ts_util.h"

#include "suppressions.h"

// TODO(eugenis): convert checks to warning messages.
// TODO(eugenis): write tests for incorrect syntax.

enum LocationType {
  LT_STAR,  // ...
  LT_OBJ,  // obj:
  LT_FUN,  // fun:
};

struct Location {
  LocationType type;
  string name;
};

struct StackTraceTemplate {
  vector<Location> locations;
};

struct Suppression {
  string name;
  set<string> tools;
  string warning_name;
  // Extra information available for some suppression types.
  // ex.: Memcheck:Param
  string extra;
  vector<StackTraceTemplate> templates;
};

class Parser {
 public:
  explicit Parser(const string &str)
      : buffer_(str), next_(buffer_.c_str()),
        end_(buffer_.c_str() + buffer_.size()), line_no_(0), error_(false) {}

  bool NextSuppression(Suppression* suppression);
  bool GetError();
  string GetErrorString();
  int GetLineNo();

 private:
  bool Eof() { return next_ >= end_; }
  string NextLine();
  string NextLineSkipComments();
  void PutBackSkipComments(string line);
  bool ParseSuppressionToolsLine(Suppression* supp, string line);
  bool IsExtraLine(string line);
  bool ParseStackTraceLine(StackTraceTemplate* trace, string line);
  bool NextStackTraceTemplate(StackTraceTemplate* trace, bool* last);

  void SetError(string desc);

  const string& buffer_;
  const char* next_;
  const char* end_;
  stack<string> put_back_stack_;

  int line_no_;
  bool error_;
  string error_string_;
};

#define PARSER_CHECK(cond, desc) do {\
    if (!(cond)) {\
      SetError(desc);\
      return false;\
    }} while (0)

void Parser::SetError(string desc) {
  error_ = true;
  error_string_ = desc;
}

bool Parser::GetError() {
  return error_;
}

string Parser::GetErrorString() {
  return error_string_;
}

int Parser::GetLineNo() {
  return line_no_;
}

string Parser::NextLine() {
  const char* first = next_;
  while (!Eof() && *next_ != '\n') {
    ++next_;
  }
  string line(first, next_ - first);
  if (*next_ == '\n') {
    ++next_;
  }
  ++line_no_;
  return line;
}

string Parser::NextLineSkipComments() {
  string line;
  if (!put_back_stack_.empty()) {
    line = put_back_stack_.top();
    put_back_stack_.pop();
    return line;
  }
  while (!Eof()) {
    line = NextLine();
    // Skip empty lines.
    if (line.empty())
      continue;
    // Skip comments.
    if (line[0] == '#')
      continue;
    const char* p = line.c_str();
    const char* e = p + line.size();
    // Strip whitespace.
    while (p < e && (*p == ' ' || *p == '\t'))
      ++p;
    if (p >= e)
      continue;
    const char* last = e - 1;
    while (last > p && (*last == ' ' || *last == '\t'))
      --last;
    return string(p, last - p + 1);
  }
  return "";
}

void Parser::PutBackSkipComments(string line) {
  put_back_stack_.push(line);
}

bool Parser::ParseSuppressionToolsLine(Suppression* supp, string line) {
  size_t idx = line.find(':');
  PARSER_CHECK(idx != string::npos, "expected ':' in tools line");
  string s1 = line.substr(0, idx);
  string s2 = line.substr(idx + 1);
  PARSER_CHECK(!s1.empty(), "expected non-empty tool(s) name");
  PARSER_CHECK(!s2.empty(), "expected non-empty warning name");
  size_t idx2;
  while ((idx2 = s1.find(',')) != string::npos) {
    supp->tools.insert(s1.substr(0, idx2));
    s1.erase(0, idx2 + 1);
  }
  supp->tools.insert(s1);
  supp->warning_name = s2;
  return true;
}

bool Parser::ParseStackTraceLine(StackTraceTemplate* trace, string line) {
  if (line == "...") {
    Location location = {LT_STAR, ""};
    trace->locations.push_back(location);
    return true;
  } else {
    size_t idx = line.find(':');
    PARSER_CHECK(idx != string::npos, "expected ':' in stack trace line");
    string s1 = line.substr(0, idx);
    string s2 = line.substr(idx + 1);
    if (s1 == "obj") {
      Location location = {LT_OBJ, s2};
      trace->locations.push_back(location);
      return true;
    } else if (s1 == "fun") {
      Location location = {LT_FUN, s2};
      trace->locations.push_back(location);
      return true;
    } else {
      SetError("bad stack trace line");
      return false;
    }
  }
}

// Checks if this line can not be parsed by Parser::NextStackTraceTemplate
// and, therefore, is an extra information for the suppression.
bool Parser::IsExtraLine(string line) {
  if (line == "..." || line == "{" || line == "}")
    return false;
  if (line.size() < 4)
    return true;
  string prefix = line.substr(0, 4);
  return !(prefix == "obj:" || prefix == "fun:");
}

bool Parser::NextStackTraceTemplate(StackTraceTemplate* trace,
    bool* last_stack_trace) {
  string line = NextLineSkipComments();
  if (line == "}") {  // No more stack traces in multi-trace syntax
    *last_stack_trace = true;
    return false;
  }

  if (line == "{") {  // A multi-trace syntax
    line = NextLineSkipComments();
  } else {
    *last_stack_trace = true;
  }

  while (true) {
    if (!ParseStackTraceLine(trace, line))
      return false;
    line = NextLineSkipComments();
    if (line == "}")
      break;
  }
  return true;
}

bool Parser::NextSuppression(Suppression* supp) {
  string line;
  line = NextLineSkipComments();
  if (line.empty())
    return false;
  // Opening {
  PARSER_CHECK(line == "{", "expected '{'");
  // Suppression name.
  line = NextLineSkipComments();
  PARSER_CHECK(!line.empty(), "expected suppression name");
  supp->name = line;
  // tool[,tool]:warning_name.
  line = NextLineSkipComments();
  PARSER_CHECK(!line.empty(), "expected tool[, tool]:warning_name line");
  if (!ParseSuppressionToolsLine(supp, line))
    return false;
  if (0) {  // Not used currently. May still be needed later.
    // A possible extra line.
    line = NextLineSkipComments();
    if (IsExtraLine(line))
      supp->extra = line;
    else
      PutBackSkipComments(line);
  }
  // Everything else.
  bool done = false;
  while (!done) {
    StackTraceTemplate trace;
    if (NextStackTraceTemplate(&trace, &done))
      supp->templates.push_back(trace);
    if (error_)
      return false;
  }
  // TODO(eugenis): Do we need to check for empty traces?
  return true;
}

struct Suppressions::SuppressionsRep {
  vector<Suppression> suppressions;
  string error_string_;
  int error_line_no_;
};

Suppressions::Suppressions() : rep_(new SuppressionsRep) {}

Suppressions::~Suppressions() {
  delete rep_;
}

int Suppressions::ReadFromString(const string &str) {
  int sizeBefore = rep_->suppressions.size();
  Parser parser(str);
  Suppression supp;
  while (parser.NextSuppression(&supp)) {
    rep_->suppressions.push_back(supp);
  }
  if (parser.GetError()) {
    rep_->error_string_ = parser.GetErrorString();
    rep_->error_line_no_ = parser.GetLineNo();
    return -1;
  }
  return rep_->suppressions.size() - sizeBefore;
}

string Suppressions::GetErrorString() {
  return rep_->error_string_;
}

int Suppressions::GetErrorLineNo() {
  return rep_->error_line_no_;
}

struct MatcherContext {
  MatcherContext(
      const vector<string>& function_names_mangled_,
      const vector<string>& function_names_demangled_,
      const vector<string>& object_names_) :
      function_names_mangled(function_names_mangled_),
      function_names_demangled(function_names_demangled_),
      object_names(object_names_),
      tmpl(NULL)
  {}

  const vector<string>& function_names_mangled;
  const vector<string>& function_names_demangled;
  const vector<string>& object_names;
  StackTraceTemplate* tmpl;
};

static bool MatchStackTraceRecursive(MatcherContext ctx, int trace_index,
    int tmpl_index) {
  const int trace_size = ctx.function_names_mangled.size();
  const int tmpl_size = ctx.tmpl->locations.size();
  while (trace_index < trace_size && tmpl_index < tmpl_size) {
    Location& location = ctx.tmpl->locations[tmpl_index];
    if (location.type == LT_STAR) {
      ++tmpl_index;
      while (trace_index < trace_size) {
        if (MatchStackTraceRecursive(ctx, trace_index++, tmpl_index))
          return true;
      }
      return false;
    } else {
      bool match = false;
      if (location.type == LT_OBJ) {
        match = StringMatch(location.name, ctx.object_names[trace_index]);
      } else {
        CHECK(location.type == LT_FUN);
        match =
          StringMatch(location.name, ctx.function_names_mangled[trace_index]) ||
          StringMatch(location.name, ctx.function_names_demangled[trace_index]);
      }
      if (match) {
        ++trace_index;
        ++tmpl_index;
      } else {
        return false;
      }
    }
  }
  return tmpl_index == tmpl_size;
}

bool Suppressions::StackTraceSuppressed(string tool_name, string warning_name,
    const vector<string>& function_names_mangled,
    const vector<string>& function_names_demangled,
    const vector<string>& object_names,
    string *name_of_suppression) {
  MatcherContext ctx(function_names_mangled, function_names_demangled,
      object_names);
  for (vector<Suppression>::iterator it = rep_->suppressions.begin();
       it != rep_->suppressions.end(); ++it) {
    if (it->warning_name != warning_name ||
        it->tools.find(tool_name) == it->tools.end())
      continue;
    for (vector<StackTraceTemplate>::iterator it2 = it->templates.begin();
         it2 != it->templates.end(); ++it2) {
      ctx.tmpl = &*it2;
      bool result = MatchStackTraceRecursive(ctx, 0, 0);
      if (result) {
        *name_of_suppression = it->name;
        return true;
      }
    }
  }
  return false;
}
