bool LightgrepController::addScanner(PatternScanner& scanner) { LG_Error* lgErr = 0; unsigned int patBegin = numeric_limits<unsigned int>::max(), patEnd = 0; int idx = -1; for (vector<const Handler*>::const_iterator h(scanner.handlers().begin()); h != scanner.handlers().end(); ++h) { bool good = false; if (lg_parse_pattern(ParsedPattern, (*h)->RE.c_str(), &(*h)->Options, &lgErr)) { for (vector<string>::const_iterator enc((*h)->Encodings.begin()); enc != (*h)->Encodings.end(); ++enc) { idx = lg_add_pattern(Fsm, PatternInfo, ParsedPattern, enc->c_str(), &lgErr); if (idx >= 0) { lg_pattern_info(PatternInfo, idx)->UserData = const_cast<void*>(static_cast<const void*>(&((*h)->Callback))); patBegin = std::min(patBegin, static_cast<unsigned int>(idx)); good = true; } } } if (!good) { if (scanner.handleParseError(**h, lgErr)) { lg_free_error(lgErr); lgErr = 0; } else { return false; } } } patEnd = lg_pattern_map_size(PatternInfo); scanner.patternRange() = make_pair(patBegin, patEnd); Scanners.push_back(&scanner); return true; }
bool LightgrepController::addUserPatterns(PatternScanner& scanner, CallbackFnType* callbackPtr, const FindOptsStruct& user) { unsigned int patBegin = lg_pattern_map_size(PatternInfo), patEnd = 0; LG_KeyOptions opts; opts.FixedString = 0; opts.CaseInsensitive = 0; LG_Error *err = 0; for (vector<string>::const_iterator itr(user.Files.begin()); itr != user.Files.end(); ++itr) { ifstream file(itr->c_str(), ios::in); if (!file.is_open()) { cerr << "Could not open pattern file '" << *itr << "'." << endl; return false; } string contents = string(istreambuf_iterator<char>(file), istreambuf_iterator<char>()); const char* contentsCStr = contents.c_str(); if (lg_add_pattern_list(Fsm, PatternInfo, contentsCStr, DefaultEncodingsCStrings, 2, &opts, &err) < 0) { vector<string> lines; istringstream input(contents); string line; while (input) { getline(input, line); lines.push_back(line); } LG_Error* cur(err); while (cur) { cerr << "Error in " << *itr << ", line " << cur->Index+1 << ", pattern '" << lines[cur->Index] << "': " << cur->Message << endl; cur = cur->Next; } lg_free_error(err); return false; } } for (vector<string>::const_iterator itr(user.Patterns.begin()); itr != user.Patterns.end(); ++itr) { bool good = false; if (lg_parse_pattern(ParsedPattern, itr->c_str(), &opts, &err)) { for (unsigned int i = 0; i < NumDefaultEncodings; ++i) { if (lg_add_pattern(Fsm, PatternInfo, ParsedPattern, DefaultEncodingsCStrings[i], &err) >= 0) { good = true; } } } if (!good) { cerr << "Error on '" << *itr << "': " << err->Message << endl; lg_free_error(err); return false; } } patEnd = lg_pattern_map_size(PatternInfo); for (unsigned int i = patBegin; i < patEnd; ++i) { lg_pattern_info(PatternInfo, i)->UserData = const_cast<void*>(static_cast<const void*>(callbackPtr)); } scanner.patternRange() = make_pair(patBegin, patEnd); Scanners.push_back(&scanner); return true; }
void LightgrepController::processHit(const vector<PatternScanner*>& sTbl, const LG_SearchHit& hit, const scanner_params& sp, const recursion_control_block& rcb) { // lookup the handler's callback functor, then invoke it CallbackFnType* cbPtr(static_cast<CallbackFnType*>(lg_pattern_info(PatternInfo, hit.KeywordIndex)->UserData)); ((*sTbl[hit.KeywordIndex]).*(*cbPtr))(hit, sp, rcb); // ...yep... }
void STest::init(const std::vector<Pattern>& pats) { std::unique_ptr<PatternHandle,void(*)(PatternHandle*)> pat( lg_create_pattern(), lg_destroy_pattern ); PMap = std::unique_ptr<PatternMapHandle,void(*)(PatternMapHandle*)>( lg_create_pattern_map(pats.size()), lg_destroy_pattern_map ); std::unique_ptr<FSMHandle,void(*)(FSMHandle*)> fsm( lg_create_fsm(0), lg_destroy_fsm ); LG_KeyOptions keyOpts; size_t i = 0, numErrors = 0; for (const Pattern& p : pats) { LG_Error* err = nullptr; keyOpts.CaseInsensitive = p.CaseInsensitive; keyOpts.FixedString = p.FixedString; lg_parse_pattern(pat.get(), p.Expression.c_str(), &keyOpts, &err); if (!err) { lg_add_pattern( fsm.get(), PMap.get(), pat.get(), p.Encoding.c_str(), &err ); if (!err) { // pack the user pattern number into the void*, oh the horror LG_PatternInfo* pinfo = lg_pattern_info(PMap.get(), i - numErrors); pinfo->UserData = reinterpret_cast<void*>(i); } } if (err) { lg_free_error(err); ++numErrors; } ++i; } LG_ProgramOptions progOpts{1}; Prog = std::unique_ptr<ProgramHandle,void(*)(ProgramHandle*)>( lg_create_program(fsm.get(), &progOpts), lg_destroy_program ); if (Prog) { LG_ContextOptions ctxOpts; Ctx = std::unique_ptr<ContextHandle,void(*)(ContextHandle*)>( lg_create_context(Prog.get(), &ctxOpts), lg_destroy_context ); } }