1bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov#include "common_util.h"
2bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov
3bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov#include "ignore.h"
4bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov
5bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy StepanovIgnoreLists *g_ignore_lists;
6bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanovvector<string>* g_ignore_obj;
7bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy StepanovIgnoreLists *g_white_lists;
8bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov
9bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanovstatic void SplitStringIntoLinesAndRemoveBlanksAndComments(
10bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    const string &str, vector<string> *lines) {
11bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  string cur_line;
12bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  bool in_comment = false;
13bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  for (size_t pos = 0; pos < str.size(); pos++) {
14bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    char ch = str[pos];
15bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    if (ch == '\n') {
16bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov      if (!cur_line.empty()) {
17bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov        // Printf("++ %s\n", cur_line.c_str());
18bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov        lines->push_back(cur_line);
19bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov      }
20bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov      cur_line.clear();
21bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov      in_comment = false;
22bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov      continue;
23bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    }
24bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    if (ch == ' ' || ch == '\t') continue;
25bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    if (ch == '#') {
26bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov      in_comment = true;
27bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov      continue;
28bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    }
29bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    if (!in_comment) {
30bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov      cur_line += ch;
31bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    }
32bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  }
33bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov}
34bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov
35bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanovstatic bool CutStringPrefixIfPresent(const string &input, const string &prefix,
36bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov                     /* OUT */ string *output) {
37bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  if (input.find(prefix) == 0) {
38bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    *output = input.substr(prefix.size());
39bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    return true;
40bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  } else {
41bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    return false;
42bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  }
43bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov}
44bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov
45bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanovstatic bool ReadIgnoreLine(string input_line, IgnoreLists *ignore_lists) {
46bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  string tail;
47bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  if (CutStringPrefixIfPresent(input_line, "obj:", &tail)) {
48bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    ignore_lists->ignores.push_back(IgnoreObj(tail));
49bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  } else if (CutStringPrefixIfPresent(input_line, "src:", &tail)) {
50bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    ignore_lists->ignores.push_back(IgnoreFile(tail));
51bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  } else if (CutStringPrefixIfPresent(input_line, "fun:", &tail)) {
52bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    ignore_lists->ignores.push_back(IgnoreFun(tail));
53bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  } else if (CutStringPrefixIfPresent(input_line, "fun_r:", &tail)) {
54bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    ignore_lists->ignores_r.push_back(IgnoreFun(tail));
55bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  } else if (CutStringPrefixIfPresent(input_line, "fun_hist:", &tail)) {
56bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    ignore_lists->ignores_hist.push_back(IgnoreFun(tail));
57bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  } else {
58bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    return false;
59bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  }
60bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  return true;
61bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov}
62bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov
63db2b85ac6df2716e3ae85cccc29eefafa6b5d047Evgeniy Stepanovvoid ReadIgnoresFromString(const string& ignoreString, IgnoreLists *ignore_lists) {
64bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  vector<string> lines;
65bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  SplitStringIntoLinesAndRemoveBlanksAndComments(ignoreString, &lines);
66bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  for (size_t j = 0; j < lines.size(); j++) {
67bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    string &line = lines[j];
68bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    bool line_parsed = ReadIgnoreLine(line, ignore_lists);
69bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    if (!line_parsed) {
70bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov      Printf("Error reading ignore file line:\n%s\n", line.c_str());
71bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov      CHECK(0);
72bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    }
73bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  }
74bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov}
75bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov
76bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov// True iff there exists a triple each of which components is either empty
77bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov// or matches the corresponding string.
78bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanovbool TripleVectorMatchKnown(const vector<IgnoreTriple>& v,
79bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov                       const string& fun,
80bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov                       const string& obj,
81bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov                       const string& file) {
82bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  for (size_t i = 0; i < v.size(); i++) {
83bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    if ((fun.size() == 0 || StringMatch(v[i].fun, fun)) &&
84bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov        (obj.size() == 0 || StringMatch(v[i].obj, obj)) &&
85bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov        (file.size() == 0 || StringMatch(v[i].file, file))) {
86bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov      if ((fun.size() == 0 || v[i].fun == "*") &&
87bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov          (obj.size() == 0 || v[i].obj == "*") &&
88bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov          (file.size() == 0 || v[i].file == "*")) {
89bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov        // At least one of the matched features should be either non-empty
90bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov        // or match a non-trivial pattern.
91bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov        // For example, a <*, *, filename.ext> triple should NOT match
92bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov        // fun="fun", obj="obj.o", file="".
93bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov        continue;
94bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov      } else {
95bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov        return true;
96bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov      }
97bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    }
98bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  }
99bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  return false;
100bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov}
101bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov
102bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanovbool StringVectorMatch(const vector<string>& v, const string& obj) {
103bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  for (size_t i = 0; i < v.size(); i++)
104bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    if (StringMatch(v[i], obj))
105bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov      return true;
106bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  return false;
107bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov}
108