Skip to content

Commit ca420d1

Browse files
committed
csgrep: --record-input-locations for json
If --record-input-locations option is used, DefEvents output as json will have "input_line" and "input_file" fields that reference the location of the event in the compilation log. Signed-off-by: Jan Matufka <jmatufka@redhat.com>
1 parent 9ea9212 commit ca420d1

21 files changed

+354
-18
lines changed

src/csgrep.cc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,7 @@ int main(int argc, char *argv[])
619619
("file-glob", "expand glob patterns in the names of input files")
620620
("ignore-case,i", "ignore case when matching regular expressions")
621621
("ignore-parser-warnings", "if enabled, parser warnings about the input files do not affect exit code")
622+
("record-input-locations", "if enabled, events in json will contain input_line and input_file fields referencing the original location of input file/stream")
622623
("invert-match,v", "select defects that do not match the selected criteria")
623624
("invert-regex,n", "invert regular expressions in all predicates")
624625
("filter-file,f", po::value<TStringList>(), "read custom filtering rules from a file in JSON format");
@@ -639,7 +640,7 @@ int main(int argc, char *argv[])
639640
p.add("input-file", -1);
640641

641642
po::store(po::parse_command_line(argc, argv, desc), vm);
642-
po::notify(vm);
643+
po::notify(vm);
643644

644645
po::options_description opts;
645646
opts.add(desc).add(hidden);
@@ -735,6 +736,9 @@ int main(int argc, char *argv[])
735736
if (vm.count("ignore-parser-warnings"))
736737
eng->setIgnoreParserWarnings(true);
737738

739+
if (vm.count("record-input-locations"))
740+
eng->setRecordInputLocations(true);
741+
738742
bool hasError = false;
739743

740744
// if no input file is given, read from stdin

src/lib/defect.hh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ struct DefEvent {
4949
std::string fileName;
5050
int line = 0;
5151
int column = 0;
52+
int inputLine = 0;
53+
std::string inputFile;
5254
std::string event;
5355
std::string msg;
5456

src/lib/instream.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@
1919

2020
#include "instream.hh"
2121

22-
InStream::InStream(const std::string &fileName, const bool silent):
22+
InStream::InStream(const std::string &fileName, const bool silent, const bool recordInputLocations):
2323
fileName_(fileName),
2424
silent_(silent),
25+
recordInputLocations_(recordInputLocations),
2526
str_((fileName_ == "-")
2627
? std::cin
2728
: fileStr_)

src/lib/instream.hh

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,20 +38,23 @@ struct InFileException {
3838

3939
class InStream {
4040
public:
41-
InStream(const std::string &fileName, bool silent = false);
41+
InStream(const std::string &fileName, bool silent = false,
42+
bool recordInputLocations = false);
4243
InStream(std::istringstream &str, bool silent = false);
4344
~InStream() = default;
4445

45-
const std::string& fileName() const { return fileName_; }
46-
std::istream& str() const { return str_; }
47-
bool silent() const { return silent_; }
48-
bool anyError() const { return anyError_; }
46+
const std::string& fileName() const { return fileName_; }
47+
std::istream& str() const { return str_; }
48+
bool silent() const { return silent_; }
49+
bool recordInputLocations() const { return recordInputLocations_; }
50+
bool anyError() const { return anyError_; }
4951

5052
void handleError(const std::string &msg = "", unsigned long line = 0UL);
5153

5254
private:
5355
const std::string fileName_;
5456
const bool silent_;
57+
const bool recordInputLocations_ = false;
5558
bool anyError_ = false;
5659
std::ifstream fileStr_;
5760
std::istream &str_;

src/lib/parser-cov.cc

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,10 @@ std::ostream& operator<<(std::ostream &str, EToken code)
114114

115115
class ErrFileLexer {
116116
public:
117-
ErrFileLexer(std::istream &input):
118-
lineReader_(input),
117+
ErrFileLexer(InStream &input):
118+
lineReader_(input.str()),
119+
fileName_(input.fileName()),
120+
recordInputLocations_(input.recordInputLocations()),
119121
hasError_(false)
120122
{
121123
}
@@ -140,6 +142,8 @@ class ErrFileLexer {
140142

141143
private:
142144
LineReader lineReader_;
145+
std::string fileName_;
146+
bool recordInputLocations_;
143147
bool hasError_;
144148
Defect def_;
145149
DefEvent evt_;
@@ -181,6 +185,10 @@ EToken ErrFileLexer::readNext()
181185
evt_ = DefEvent();
182186
evt_.event = sm[/* # */ 1];
183187
evt_.msg = sm[/* msg */ 2];
188+
if (recordInputLocations_) {
189+
evt_.inputLine = lineReader_.lineNo();
190+
evt_.inputFile = fileName_;
191+
}
184192
return T_COMMENT;
185193
}
186194

@@ -202,6 +210,11 @@ EToken ErrFileLexer::readNext()
202210
evt_.event = sm[/* event */ 4];
203211
evt_.msg = sm[/* msg */ 5];
204212

213+
if (recordInputLocations_) {
214+
evt_.inputLine = lineReader_.lineNo();
215+
evt_.inputFile = fileName_;
216+
}
217+
205218
return T_EVENT;
206219
}
207220

@@ -523,7 +536,7 @@ struct CovParser::Private {
523536
ImpliedAttrDigger digger;
524537

525538
Private(InStream &input_):
526-
lexer(input_.str()),
539+
lexer(input_),
527540
fileName(input_.fileName()),
528541
silent(input_.silent()),
529542
hasError(false),

src/lib/parser-gcc.cc

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,11 @@ class AbstractTokenFilter: public ITokenizer {
6868

6969
class Tokenizer: public ITokenizer {
7070
public:
71-
Tokenizer(std::istream &input):
72-
input_(input),
73-
lineNo_(0)
71+
Tokenizer(InStream &input):
72+
input_(input.str()),
73+
lineNo_(0),
74+
fileName_(input.fileName()),
75+
recordInputLocations_(input.recordInputLocations())
7476
{
7577
}
7678

@@ -83,6 +85,8 @@ class Tokenizer: public ITokenizer {
8385
private:
8486
std::istream &input_;
8587
int lineNo_;
88+
std::string fileName_;
89+
bool recordInputLocations_;
8690

8791
const RE reSideBar_ =
8892
RE("^ *((([0-9]+)? \\| )|(\\+\\+\\+ \\|\\+)).*$");
@@ -131,6 +135,11 @@ EToken Tokenizer::readNext(DefEvent *pEvt)
131135
*pEvt = DefEvent();
132136
pEvt->msg = line;
133137

138+
if (recordInputLocations_) {
139+
pEvt->inputLine = lineNo_;
140+
pEvt->inputFile = fileName_;
141+
}
142+
134143
// check for line markers produced by gcc-9.2.1 (a.k.a. sidebar)
135144
if (boost::regex_match(pEvt->msg, reSideBar_))
136145
// xxx.c:2:1: note: include '<stdlib.h>' or provide a declaration...
@@ -387,7 +396,7 @@ EToken MultilineConcatenator::readNext(DefEvent *pEvt)
387396
class BasicGccParser {
388397
public:
389398
BasicGccParser(InStream &input):
390-
rawTokenizer_(input.str()),
399+
rawTokenizer_(input),
391400
noiseFilter_(&rawTokenizer_),
392401
markerConverter_(&noiseFilter_),
393402
tokenizer_(&markerConverter_),
@@ -535,6 +544,7 @@ bool BasicGccParser::getNext(Defect *pDef)
535544
DefEvent evt;
536545

537546
const EToken tok = tokenizer_.readNext(&evt);
547+
538548
switch (tok) {
539549
case T_NULL:
540550
if (!hasKeyEvent_ && !defCurrent_.events.empty())
@@ -828,7 +838,7 @@ bool GccParser::getNext(Defect *pDef)
828838
while (d->core.getNext(&d->lastDef) && d->tryMerge(pDef))
829839
;
830840

831-
// initialize verbosityLevel
841+
// initialize verbosityLevel
832842
// FIXME: similar code to KeyEventDigger::initVerbosity()
833843
TEvtList &evtList = pDef->events;
834844
const unsigned evtCount = evtList.size();

src/lib/parser-json-simple.cc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ SimpleTreeDecoder::Private::Private(InStream &input):
7373
"event",
7474
"file_name",
7575
"h_size",
76+
"input_file",
77+
"input_line",
7678
"line",
7779
"message",
7880
"v_size",
@@ -148,6 +150,8 @@ bool SimpleTreeDecoder::readNode(Defect *def)
148150
evt.column = valueOf<int >(evtNode, "column");
149151
evt.hSize = valueOf<TNumDiff >(evtNode, "h_size");
150152
evt.vSize = valueOf<TNumDiff >(evtNode, "v_size");
153+
evt.inputFile = valueOf<std::string >(evtNode, "input_file");
154+
evt.inputLine = valueOf<int >(evtNode, "input_line");
151155
evt.event = valueOf<std::string >(evtNode, "event");
152156
evt.msg = valueOf<std::string >(evtNode, "message");
153157
evt.verbosityLevel = valueOf<int>(evtNode, "verbosity_level", -1);
@@ -189,4 +193,3 @@ bool SimpleTreeDecoder::readNode(Defect *def)
189193

190194
return true;
191195
}
192-

src/lib/writer-json-simple.cc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ static array simpleEncodeEvents(const TEvtList &events)
4040
for (const DefEvent &evt : events) {
4141
object evtNode;
4242

43-
// describe the location
43+
// describe the location from the source code
4444
evtNode["file_name"] = evt.fileName;
4545
evtNode["line"] = evt.line;
4646
if (0 < evt.column)
@@ -50,6 +50,12 @@ static array simpleEncodeEvents(const TEvtList &events)
5050
if (0 < evt.vSize)
5151
evtNode["v_size"] = evt.vSize;
5252

53+
// describe the location from the compilation error log/input
54+
if (!evt.inputFile.empty())
55+
evtNode["input_file"] = evt.inputFile;
56+
if (0 < evt.inputLine)
57+
evtNode["input_line"] = evt.inputLine;
58+
5359
// describe the event
5460
evtNode["event"] = evt.event;
5561
evtNode["message"] = sanitizeUTF8(evt.msg);

src/lib/writer.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ bool AbstractWriter::handleFile(InStream &input)
5656
bool AbstractWriter::handleFile(const std::string &fileName, bool silent)
5757
{
5858
try {
59-
InStream str(fileName, silent);
59+
InStream str(fileName, silent, recordInputLocations_);
6060
return this->handleFile(str);
6161
}
6262
catch (const InFileException &e) {

src/lib/writer.hh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,15 @@ class AbstractWriter {
6262
ignoreParserWarnings_ = val;
6363
}
6464

65+
void setRecordInputLocations(const bool val) {
66+
recordInputLocations_ = val;
67+
}
6568

6669
private:
6770
EFileFormat inputFormat_ = FF_INVALID;
6871
const TScanProps emptyProps_{};
6972
bool ignoreParserWarnings_ = false;
73+
bool recordInputLocations_ = false;
7074
};
7175

7276
using TWriterPtr = std::unique_ptr<AbstractWriter>;

0 commit comments

Comments
 (0)