source: icGREP/icgrep-devel/icgrep/icgrep.cpp @ 5990

Last change on this file since 5990 was 5990, checked in by cameron, 11 months ago

Bug fix for binary detection/abort

File size: 5.9 KB
Line 
1/*
2 *  Copyright (c) 2014-8 International Characters.
3 *  This software is licensed to the public under the Open Software License 3.0.
4 *  icgrep is a trademark of International Characters.
5 */
6
7#include <cstdio>
8#include <vector>
9#include <llvm/Support/CommandLine.h>
10#include <llvm/Support/ErrorHandling.h>
11#include <llvm/Support/PrettyStackTrace.h>
12#include <llvm/Support/Signals.h>
13#include <llvm/Support/ManagedStatic.h>
14#include <llvm/Support/raw_ostream.h>
15#include <re/re_alt.h>
16#include <re/re_seq.h>
17#include <re/re_start.h>
18#include <re/re_end.h>
19#include <re/parsers/parser.h>
20#include <re/re_utility.h>
21#include <grep/grep_engine.h>
22#include <grep_interface.h>
23#include <fstream>
24#include <string>
25#include <toolchain/toolchain.h>
26#include <re/re_toolchain.h>
27#include <pablo/pablo_toolchain.h>
28#include <boost/filesystem.hpp>
29#include <util/file_select.h>
30#include <sys/stat.h>
31#include <fcntl.h>
32
33using namespace llvm;
34
35static cl::list<std::string> inputFiles(cl::Positional, cl::desc("<regex> <input file ...>"), cl::OneOrMore);
36
37static cl::opt<bool> ByteMode("enable-byte-mode", cl::desc("Process regular expressions in byte mode"));
38
39static cl::opt<int> REsPerGroup("re-num", cl::desc("Number of regular expressions processed by each kernel."), cl::init(0));
40
41static re::ModeFlagSet globalFlags = re::MULTILINE_MODE_FLAG;
42
43std::vector<re::RE *> readExpressions() {
44 
45    if (argv::FileFlag != "") {
46        std::ifstream regexFile(argv::FileFlag.c_str());
47        std::string r;
48        if (regexFile.is_open()) {
49            while (std::getline(regexFile, r)) {
50                argv::RegexpVector.push_back(r);
51            }
52            regexFile.close();
53        }
54    }
55   
56    // if there are no regexes specified through -e or -f, the first positional argument
57    // must be a regex, not an input file.
58   
59    if (argv::RegexpVector.size() == 0) {
60        argv::RegexpVector.push_back(inputFiles[0]);
61        inputFiles.erase(inputFiles.begin());
62    }
63    if (argv::IgnoreCaseFlag) {
64        globalFlags |= re::CASE_INSENSITIVE_MODE_FLAG;
65    }
66
67    std::vector<re::RE *> REs;
68    for (unsigned i = 0; i < argv::RegexpVector.size(); i++) {
69        re::RE * re_ast = re::RE_Parser::parse(argv::RegexpVector[i], globalFlags, argv::RegexpSyntax, ByteMode);
70        REs.push_back(re_ast);
71    }
72
73   
74    // If there are multiple REs, combine them into groups.
75    // A separate kernel will be created for each group.
76    if (REs.size() > 1) {
77        codegen::SegmentPipelineParallel = true;
78        if (REsPerGroup == 0) {
79            // If no grouping factor is specified, we use a default formula.
80            REsPerGroup = (REs.size() + codegen::ThreadNum) / (codegen::ThreadNum + 1);
81        }
82        std::vector<re::RE *> groups;
83        auto start = REs.begin();
84        auto end = start + REsPerGroup;
85        while (end < REs.end()) {
86            groups.push_back(re::makeAlt(start, end));
87            start = end;
88            end += REsPerGroup;
89        }
90        if ((REs.end() - start) > 1) {
91            groups.push_back(re::makeAlt(start, REs.end()));
92        } else {
93            groups.push_back(*start);
94        }
95    REs.swap(groups);
96    }
97    for (re::RE *& re_ast : REs) {
98        assert (re_ast);
99        if (argv::WordRegexpFlag) {
100            re_ast = re::makeSeq({re::makeWordBoundary(), re_ast, re::makeWordBoundary()});
101        }
102        if (argv::LineRegexpFlag) {
103            re_ast = re::makeSeq({re::makeStart(), re_ast, re::makeEnd()});
104        }
105    }
106
107    return REs;
108}
109
110namespace fs = boost::filesystem;
111
112int main(int argc, char *argv[]) {
113    sys::PrintStackTraceOnErrorSignal(argv[0]);
114    llvm::PrettyStackTraceProgram X(argc, argv);
115    llvm_shutdown_obj shutdown;
116
117    argv::InitializeCommandLineInterface(argc, argv);
118   
119    auto REs = readExpressions();
120
121    std::vector<fs::path> allFiles = argv::getFullFileList(inputFiles);
122    if (inputFiles.empty()) {
123        argv::UseStdIn = true;
124    }
125    else if ((allFiles.size() > 1) && !argv::NoFilenameFlag) {
126        argv::WithFilenameFlag = true;
127    }
128
129    grep::GrepEngine * grepEngine = nullptr;
130   
131    switch (argv::Mode) {
132        case argv::NormalMode:
133            grepEngine = new grep::EmitMatchesEngine();
134            if (argv::MaxCountFlag) grepEngine->setMaxCount(argv::MaxCountFlag);
135            if (argv::WithFilenameFlag) grepEngine->showFileNames();
136            if (argv::LineNumberFlag) grepEngine->showLineNumbers();
137            if (argv::InitialTabFlag) grepEngine->setInitialTab();
138           break;
139        case argv::CountOnly:
140            grepEngine = new grep::CountOnlyEngine();
141            if (argv::WithFilenameFlag) grepEngine->showFileNames();
142            if (argv::MaxCountFlag) grepEngine->setMaxCount(argv::MaxCountFlag);
143           break;
144        case argv::FilesWithMatch:
145        case argv::FilesWithoutMatch:
146            grepEngine = new grep::MatchOnlyEngine(argv::Mode == argv::FilesWithMatch, argv::NullFlag);
147            break;
148        case argv::QuietMode:
149            grepEngine = new grep::QuietModeEngine(); break;
150        default: llvm_unreachable("Invalid grep mode!");
151    }
152    if (argv::IgnoreCaseFlag) grepEngine->setCaseInsensitive();
153    if (argv::InvertMatchFlag) grepEngine->setInvertMatches();
154    if (argv::UnicodeLinesFlag) {
155        grepEngine->setRecordBreak(grep::GrepRecordBreakKind::Unicode);
156    } else if (argv::NullDataFlag) {
157        grepEngine->setRecordBreak(grep::GrepRecordBreakKind::Null);
158    } else {
159        grepEngine->setRecordBreak(grep::GrepRecordBreakKind::LF);
160    }
161    grepEngine->setStdinLabel(argv::LabelFlag);
162    if (argv::UseStdIn) grepEngine->setGrepStdIn();
163    if (argv::NoMessagesFlag) grepEngine->suppressFileMessages();
164    if (argv::MmapFlag) grepEngine->setPreferMMap();
165    grepEngine->initREs(REs);
166    grepEngine->grepCodeGen();
167    grepEngine->initFileResult(allFiles);
168    bool matchFound = grepEngine->searchAllFiles();
169    delete(grepEngine);
170   
171    return matchFound ? argv::MatchFoundExitCode : argv::MatchNotFoundExitCode;
172}
Note: See TracBrowser for help on using the repository browser.