forked from csutils/csdiff
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdefqueue.cc
161 lines (139 loc) · 4.33 KB
/
defqueue.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/*
* Copyright (C) 2011 - 2012 Red Hat, Inc.
*
* This file is part of csdiff.
*
* csdiff is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* csdiff is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with csdiff. If not, see <http://www.gnu.org/licenses/>.
*/
#include "defqueue.hh"
#include "csfilter.hh"
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/lexical_cast.hpp>
#define DEBUG_DEF_MATCH 0
#define DEBUG_LOOKUP_OFFSET 0
// /////////////////////////////////////////////////////////////////////////////
// implementation of DefQueue
DefQueue::DefQueue():
filt_(MsgFilter::inst())
{
}
void DefQueue::hashDefect(const Defect &def)
{
TDefByFile &row = stor_[def.checker];
const std::string &fileName = def.events[def.keyEventIdx].fileName;
TDefList &col = row[filt_->filterPath(fileName)];
col.push_back(def);
}
bool DefQueue::lookup(
Defect &dst,
const std::string &checker,
const std::string &fileName)
{
// look for the given defect class
TDefByChecker::iterator iRow = stor_.find(checker);
if (stor_.end() == iRow) {
#if DEBUG_DEF_MATCH
std::cerr << checker << ": not found\n";
#endif
return false;
}
TDefByFile &row = iRow->second;
if (row.empty()) {
#if DEBUG_DEF_MATCH
std::cerr << checker << ": row empty\n";
#endif
return false;
}
// look for the given file name
std::string path = filt_->filterPath(fileName);
TDefByFile::iterator iCol = row.find(path);
if (row.end() == iCol) {
#if DEBUG_DEF_MATCH
std::cerr << checker << ": " << path << ": not found\n";
#endif
return false;
}
TDefList &col = iCol->second;
if (col.empty()) {
#if DEBUG_DEF_MATCH
std::cerr << checker << ": " << path << ": list empty\n";
#endif
return false;
}
// remove the first defect in the list...
dst = col.front();
col.pop_front();
if (col.empty()) {
// ... and subsequently the list itself once it becomes empty
row.erase(iCol);
#if DEBUG_LOOKUP_OFFSET
std::cerr << checker << ": " << path
<< ": list removed, row.size() = " << row.size() << "\n";
#endif
if (row.empty()) {
// ... and eventually also the row where the list belongs to
stor_.erase(iRow);
#if DEBUG_LOOKUP_OFFSET
std::cerr << checker << ": row removed, stor_.size() = "
<< stor_.size() << "\n";
#endif
}
}
// TODO: What else should we (and are we able to) check? fnc names?
return true;
}
// /////////////////////////////////////////////////////////////////////////////
// implementation of DefQueryParser
bool DefQueryParser::parse(DefQueryParser::QRow &dst) {
// read one line from stdin
std::string line;
if (!std::getline(input_, line))
return false;
// increment the line counter
++lineno_;
// tokenize the line
std::vector<std::string> tokens;
boost::split(tokens, line, boost::algorithm::is_any_of(","));
if (tokens.size() < 3) {
std::cerr << fName_ << ":" << lineno_
<< ": error: not enough ',' at the line\n";
return false;
}
// parse cid
try {
dst.cid = boost::lexical_cast<int>(tokens[/* cid */ 0]);
}
catch(boost::bad_lexical_cast &) {
std::cerr << fName_ << ":" << lineno_ << ": error: failed to parse CID\n";
return false;
}
// all OK
dst.checker = tokens[/* checker */ 1];
dst.fileName = tokens[/* fileName */ 2];
if (3 < tokens.size())
dst.fnc = tokens[/* fnc */ 3];
return true;
}
bool DefQueryParser::getNext(DefQueryParser::QRow &dst) {
// error recovery loop
while (input_) {
if (this->parse(dst))
return true;
else
hasError_ = true;
}
// EOF
return false;
}