TEST(ng_charreach, set) { CharReach cr; ASSERT_EQ(0U, cr.count()); ASSERT_TRUE(cr.none()); ASSERT_FALSE(cr.all()); cr.set('q'); ASSERT_EQ(1U, cr.count()); cr.setall(); ASSERT_EQ(cr.size(), cr.count()); ASSERT_TRUE(cr.all()); }
TEST(ng_charreach, alpha) { CharReach cr; ASSERT_EQ(0U, cr.count()); ASSERT_FALSE(cr.isAlpha()); cr.set('a'); ASSERT_FALSE(0 == cr.count()); ASSERT_TRUE(cr.isAlpha()); cr.set('A'); cr.set('b'); cr.set('z'); ASSERT_TRUE(cr.isAlpha()); cr.set(1); ASSERT_FALSE(cr.isAlpha()); }
TEST(ng_charreach, dot) { CharReach dot = CharReach::dot(); ASSERT_EQ(256, dot.count()); ASSERT_TRUE(dot.all()); for (size_t i = 0; i < 256; i++) { ASSERT_TRUE(dot.test(i)); } }
TEST(ng_charreach, init) { CharReach cr; ASSERT_EQ(0U, cr.count()); ASSERT_TRUE(cr.none()); ASSERT_FALSE(cr.all()); ASSERT_EQ(256U, cr.size()); }
TEST(ng_charreach, flip) { CharReach cr; ASSERT_EQ(0U, cr.count()); ASSERT_TRUE(cr.none()); cr.flip(); ASSERT_EQ(cr.size(), cr.count()); ASSERT_TRUE(cr.all()); cr.flip(); ASSERT_EQ(0U, cr.count()); ASSERT_TRUE(cr.none()); cr.flip(25); ASSERT_FALSE(cr.none()); ASSERT_FALSE(cr.all()); ASSERT_EQ(1U, cr.count()); cr.flip(); ASSERT_EQ(cr.size() - 1, cr.count()); }
TEST(ng_charreach, copy) { CharReach cr; cr.set('a'); cr.set('z'); CharReach cr2(cr); ASSERT_EQ(cr.count(), cr2.count()); ASSERT_TRUE(cr == cr2); }
TEST(ng_charreach, assignment) { CharReach cr; cr.set('f'); cr.set('l'); cr.set('y'); CharReach cr2; cr2 = cr; ASSERT_EQ(cr.count(), cr2.count()); ASSERT_TRUE(cr == cr2); }
TEST(ng_charreach, clear) { CharReach cr; ASSERT_EQ(0U, cr.count()); ASSERT_TRUE(cr.none()); ASSERT_FALSE(cr.all()); cr.set('q'); cr.set('u'); cr.set('a'); cr.set('r'); cr.set('k'); ASSERT_EQ(5U, cr.count()); cr.clear('r'); ASSERT_EQ(4U, cr.count()); ASSERT_FALSE(cr.test('r')); cr.setall(); ASSERT_EQ(cr.size(), cr.count()); ASSERT_TRUE(cr.all()); cr.clear(0xff); ASSERT_FALSE(cr.all()); }
TEST(ng_charreach, setRange) { // Exhaustive test: every possible contiguous range. for (unsigned range = 0; range < 256; range++) { for (unsigned from = 0; from < 256 - range; from++) { unsigned to = from + range; CharReach cr; cr.setRange(from, to); ASSERT_EQ(from, cr.find_first()); ASSERT_EQ(to, cr.find_last()); ASSERT_EQ(range + 1, cr.count()); } } }
static bool is_accel(const raw_dfa &raw, dstate_id_t sds_or_proxy, dstate_id_t this_idx) { if (!this_idx /* dead state is not accelerable */) { return false; } /* Note on report acceleration states: While we can't accelerate while we * are spamming out callbacks, the QR code paths don't raise reports * during scanning so they can accelerate report states. */ if (generates_callbacks(raw.kind) && !raw.states[this_idx].reports.empty()) { return false; } size_t single_limit = this_idx == sds_or_proxy ? ACCEL_MAX_FLOATING_STOP_CHAR : ACCEL_MAX_STOP_CHAR; DEBUG_PRINTF("inspecting %hu/%hu: %zu\n", this_idx, sds_or_proxy, single_limit); CharReach out; for (u32 i = 0; i < N_CHARS; i++) { if (raw.states[this_idx].next[raw.alpha_remap[i]] != this_idx) { out.set(i); } } if (out.count() <= single_limit) { DEBUG_PRINTF("state %hu should be accelerable %zu\n", this_idx, out.count()); return true; } DEBUG_PRINTF("state %hu is not accelerable has %zu\n", this_idx, out.count()); return false; }
void nfaExecLbrTruf_dump(const NFA *nfa, const string &base) { assert(nfa); assert(nfa->type == LBR_NFA_TRUF); StdioFile f(base + ".txt", "w"); const lbr_truf *lt = (const lbr_truf *)getImplNfa(nfa); lbrDumpCommon(<->common, f); CharReach cr = truffle2cr((const u8 *)<->mask1, (const u8 *)<->mask2); fprintf(f, "TRUFFLE model, scanning for: %s (%zu chars)\n", describeClass(cr, 20, CC_OUT_TEXT).c_str(), cr.count()); fprintf(f, "\n"); dumpTextReverse(nfa, f); }
void nfaExecLbrShuf_dump(const NFA *nfa, const string &base) { assert(nfa); assert(nfa->type == LBR_NFA_SHUF); StdioFile f(base + ".txt", "w"); const lbr_shuf *ls = (const lbr_shuf *)getImplNfa(nfa); lbrDumpCommon(&ls->common, f); CharReach cr = shufti2cr((const u8 *)&ls->mask_lo, (const u8 *)&ls->mask_hi); fprintf(f, "SHUF model, scanning for: %s (%zu chars)\n", describeClass(cr, 20, CC_OUT_TEXT).c_str(), cr.count()); fprintf(f, "\n"); dumpTextReverse(nfa, f); }
u32 mcclellanStartReachSize(const raw_dfa *raw) { if (raw->states.size() < 2) { return 0; } const dstate &ds = raw->states[raw->start_anchored]; CharReach out; for (unsigned i = 0; i < N_CHARS; i++) { if (ds.next[raw->alpha_remap[i]] != DEAD_STATE) { out.set(i); } } return out.count(); }
TEST(ng_charreach, count) { CharReach cr; cr.set(1); cr.set(2); cr.set('a'); cr.set('Z'); cr.set('m'); cr.set('~'); cr.set(210); size_t n = cr.find_first(); ASSERT_FALSE(n == CharReach::npos); unsigned int i = 0; while (n != CharReach::npos) { i++; n = cr.find_next(n); } ASSERT_EQ(i, cr.count()); }
static aligned_unique_ptr<NFA> constructLBR(const CharReach &cr, const depth &repeatMin, const depth &repeatMax, u32 minPeriod, bool is_reset, ReportID report) { DEBUG_PRINTF("bounds={%s,%s}, cr=%s (count %zu), report=%u\n", repeatMin.str().c_str(), repeatMax.str().c_str(), describeClass(cr, 20, CC_OUT_TEXT).c_str(), cr.count(), report); assert(repeatMin <= repeatMax); assert(repeatMax.is_reachable()); aligned_unique_ptr<NFA> nfa = buildLbrDot(cr, repeatMin, repeatMax, minPeriod, is_reset, report); if (!nfa) { nfa = buildLbrVerm(cr, repeatMin, repeatMax, minPeriod, is_reset, report); } if (!nfa) { nfa = buildLbrNVerm(cr, repeatMin, repeatMax, minPeriod, is_reset, report); } if (!nfa) { nfa = buildLbrShuf(cr, repeatMin, repeatMax, minPeriod, is_reset, report); } if (!nfa) { nfa = buildLbrTruf(cr, repeatMin, repeatMax, minPeriod, is_reset, report); } if (!nfa) { assert(0); return nullptr; } return nfa; }
static aligned_unique_ptr<NFA> buildLbrVerm(const CharReach &cr, const depth &repeatMin, const depth &repeatMax, u32 minPeriod, bool is_reset, ReportID report) { const CharReach escapes(~cr); if (escapes.count() != 1) { return nullptr; } enum RepeatType rtype = chooseRepeatType(repeatMin, repeatMax, minPeriod, is_reset); aligned_unique_ptr<NFA> nfa = makeLbrNfa<lbr_verm>(LBR_NFA_Verm, rtype, repeatMax); struct lbr_verm *lv = (struct lbr_verm *)getMutableImplNfa(nfa.get()); lv->c = escapes.find_first(); fillNfa<lbr_verm>(nfa.get(), &lv->common, report, repeatMin, repeatMax, minPeriod, rtype); DEBUG_PRINTF("built verm lbr\n"); return nfa; }