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

Last change on this file since 6141 was 5992, checked in by cameron, 16 months ago

Setting BinaryFilesMode? to Text (temporary); conversion to unique_ptr progress

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