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...
}
Example #4
0
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
    );
  }
}