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