/* This needs to be a power of 2 */
#define WB_HISTORY_SIZE 32
struct match_workbuf {
- unsigned int count;
unsigned int pos;
unsigned int len;
- unsigned int size; /* power of 2, same as history size */
- unsigned int history[WB_HISTORY_SIZE];
+ aa_state_t history[WB_HISTORY_SIZE];
};
#define DEFINE_MATCH_WB(N) \
struct match_workbuf N = { \
- .count = 0, \
.pos = 0, \
.len = 0, \
}
return state;
}
-#define inc_wb_pos(wb) \
-do { \
+#define inc_wb_pos(wb) \
+do { \
BUILD_BUG_ON_NOT_POWER_OF_2(WB_HISTORY_SIZE); \
wb->pos = (wb->pos + 1) & (WB_HISTORY_SIZE - 1); \
- wb->len = (wb->len + 1) & (WB_HISTORY_SIZE - 1); \
+ wb->len = (wb->len + 1) > WB_HISTORY_SIZE ? WB_HISTORY_SIZE : \
+ wb->len + 1; \
} while (0)
/* For DFAs that don't support extended tagging of states */
+/* adjust is only set if is_loop returns true */
static bool is_loop(struct match_workbuf *wb, aa_state_t state,
unsigned int *adjust)
{
- aa_state_t pos = wb->pos;
- aa_state_t i;
+ int pos = wb->pos;
+ int i;
if (wb->history[pos] < state)
return false;
- for (i = 0; i <= wb->len; i++) {
+ for (i = 0; i < wb->len; i++) {
if (wb->history[pos] == state) {
*adjust = i;
return true;
}
- if (pos == 0)
- pos = WB_HISTORY_SIZE;
- pos--;
+ /* -1 wraps to WB_HISTORY_SIZE - 1 */
+ pos = (pos - 1) & (WB_HISTORY_SIZE - 1);
}
- *adjust = i;
- return true;
+ return false;
}
static aa_state_t leftmatch_fb(struct aa_dfa *dfa, aa_state_t start,