}
// Aligned loops from here on in
- if (nocase) {
- return dvermSearchAlignedNocase(chars1, chars2, c1, c2, buf, buf_end);
- } else {
- return dvermSearchAligned(chars1, chars2, c1, c2, buf, buf_end);
+ const u8 *ptr = nocase ? dvermSearchAlignedNocase(chars1, chars2, c1, c2,
+ buf, buf_end)
+ : dvermSearchAligned(chars1, chars2, c1, c2, buf,
+ buf_end);
+ if (ptr) {
+ return ptr;
}
+
+ // Tidy up the mess at the end
+ ptr = nocase ? dvermPreconditionNocase(chars1, chars2,
+ buf_end - VERM_BOUNDARY)
+ : dvermPrecondition(chars1, chars2, buf_end - VERM_BOUNDARY);
+ /* buf_end - 1 to be conservative in case last byte is a partial match */
+ return ptr ? ptr : buf_end - 1;
+
}
static really_inline
}
// Aligned loops from here on in
- return dvermSearchAlignedMasked(chars1, chars2, mask1, mask2, c1, c2, m1, m2,
- buf, buf_end);
+ const u8 *ptr = dvermSearchAlignedMasked(chars1, chars2, mask1, mask2, c1,
+ c2, m1, m2, buf, buf_end);
+ if (ptr) {
+ return ptr;
+ }
+
+ // Tidy up the mess at the end
+ ptr = dvermPreconditionMasked(chars1, chars2, mask1, mask2,
+ buf_end - VERM_BOUNDARY);
+ /* buf_end - 1 to be conservative in case last byte is a partial match */
+ return ptr ? ptr : buf_end - 1;
+
}
// Reverse vermicelli scan. Provides exact semantics and returns (buf - 1) if
#include "gtest/gtest.h"
#include "nfa/vermicelli.h"
-#define BOUND (~(VERM_BOUNDARY - 1))
-
TEST(Vermicelli, ExecNoMatch1) {
char t1[] = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
const u8 *rv = vermicelliDoubleExec('a', 'b', 0, (u8 *)t1 + i,
(u8 *)t1 + strlen(t1) - j);
- ASSERT_EQ(((size_t)t1 + strlen(t1) - j - 1) & BOUND, (size_t)rv);
+ ASSERT_EQ(((size_t)t1 + strlen(t1) - j - 1), (size_t)rv);
rv = vermicelliDoubleExec('B', 'b', 0, (u8 *)t1 + i,
(u8 *)t1 + strlen(t1) - j);
- ASSERT_EQ(((size_t)t1 + strlen(t1) - j - 1) & BOUND, (size_t)rv);
+ ASSERT_EQ(((size_t)t1 + strlen(t1) - j - 1), (size_t)rv);
rv = vermicelliDoubleExec('A', 'B', 1, (u8 *)t1 + i,
(u8 *)t1 + strlen(t1) - j);
- ASSERT_EQ(((size_t)t1 + strlen(t1) - j - 1) & BOUND, (size_t)rv);
+ ASSERT_EQ(((size_t)t1 + strlen(t1) - j - 1), (size_t)rv);
rv = vermicelliDoubleExec('b', 'B', 0, (u8 *)t1 + i,
(u8 *)t1 + strlen(t1) - j);
- ASSERT_EQ(((size_t)t1 + strlen(t1) - j - 1) & BOUND, (size_t)rv);
+ ASSERT_EQ(((size_t)t1 + strlen(t1) - j - 1), (size_t)rv);
rv = vermicelliDoubleExec('B', 'A', 1, (u8 *)t1 + i,
(u8 *)t1 + strlen(t1) - j);
- ASSERT_EQ(((size_t)t1 + strlen(t1) - j - 1) & BOUND, (size_t)rv);
+ ASSERT_EQ(((size_t)t1 + strlen(t1) - j - 1), (size_t)rv);
}
}
}
t1_raw + i,
t1_raw + t1.length() - i - j);
- ASSERT_EQ(((size_t)t1_raw + t1.length() - i - j - 1) & BOUND, (size_t)rv);
-
+ ASSERT_EQ(((size_t)t1_raw + t1.length() - i - j - 1), (size_t)rv);
rv = vermicelliDoubleMaskedExec('B', 'b', 0xff, CASE_CLEAR,
t1_raw + i,
t1_raw + t1.length() - i - j);
- ASSERT_EQ(((size_t)t1_raw + t1.length() - i - j - 1) & BOUND, (size_t)rv);
+ ASSERT_EQ(((size_t)t1_raw + t1.length() - i - j - 1), (size_t)rv);
rv = vermicelliDoubleMaskedExec('A', 'B', CASE_CLEAR, CASE_CLEAR,
t1_raw + i,
t1_raw + t1.length() -i - j);
- ASSERT_EQ(((size_t)t1_raw + t1.length() - i - j - 1) & BOUND, (size_t)rv);
+ ASSERT_EQ(((size_t)t1_raw + t1.length() - i - j - 1), (size_t)rv);
rv = vermicelliDoubleMaskedExec('b', 'B', CASE_CLEAR, 0xff,
t1_raw + i,
t1_raw + t1.length() - i - j);
- ASSERT_EQ(((size_t)t1_raw + t1.length() - i - j - 1) & BOUND, (size_t)rv);
+ ASSERT_EQ(((size_t)t1_raw + t1.length() - i - j - 1), (size_t)rv);
rv = vermicelliDoubleMaskedExec('B', 'A', 0xff, 0xff,
t1_raw + i,
t1_raw + t1.length() - i - j);
- ASSERT_EQ(((size_t)t1_raw + t1.length() - i - j - 1) & BOUND, (size_t)rv);
+ ASSERT_EQ(((size_t)t1_raw + t1.length() - i - j - 1), (size_t)rv);
}
}
}