/** * aa_dfa_match - traverse @dfa to find state @str stops at * @dfa: the dfa to match @str against (NOT NULL) * @start: the state of the dfa to start matching in * @str: the null terminated string of bytes to match against the dfa (NOT NULL) * * aa_dfa_match will match @str against the dfa and return the state it * finished matching in. The final state can be used to look up the accepting * label, or as the start state of a continuing match. * * Returns: final state reached after input is consumed */ unsigned int aa_dfa_match(struct aa_dfa *dfa, unsigned int start, const char *str) { u16 *def = DEFAULT_TABLE(dfa); u32 *base = BASE_TABLE(dfa); u16 *next = NEXT_TABLE(dfa); u16 *check = CHECK_TABLE(dfa); unsigned int state = start; if (state == 0) return 0; /* current state is <state>, matching character *str */ if (dfa->tables[YYTD_ID_EC]) { /* Equivalence class table defined */ u8 *equiv = EQUIV_TABLE(dfa); /* default is direct to next state */ while (*str) match_char(state, def, base, next, check, equiv[(u8) *str++]); } else { /* default is direct to next state */ while (*str) match_char(state, def, base, next, check, (u8) *str++); } return state; }
unsigned int aa_dfa_next(struct aa_dfa *dfa, unsigned int state, const char c) { u16 *def = DEFAULT_TABLE(dfa); u32 *base = BASE_TABLE(dfa); u16 *next = NEXT_TABLE(dfa); u16 *check = CHECK_TABLE(dfa); unsigned int pos; if (dfa->tables[YYTD_ID_EC]) { u8 *equiv = EQUIV_TABLE(dfa); pos = base[state] + equiv[(u8) c]; if (check[pos] == state) state = next[pos]; else state = def[state]; } else { pos = base[state] + (u8) c; if (check[pos] == state) state = next[pos]; else state = def[state]; } return state; }
/** * aa_dfa_next - step one character to the next state in the dfa * @dfa: the dfa to tranverse (NOT NULL) * @state: the state to start in * @c: the input character to transition on * * aa_dfa_match will step through the dfa by one input character @c * * Returns: state reach after input @c */ unsigned int aa_dfa_next(struct aa_dfa *dfa, unsigned int state, const char c) { u16 *def = DEFAULT_TABLE(dfa); u32 *base = BASE_TABLE(dfa); u16 *next = NEXT_TABLE(dfa); u16 *check = CHECK_TABLE(dfa); unsigned int pos; /* current state is <state>, matching character *str */ if (dfa->tables[YYTD_ID_EC]) { /* Equivalence class table defined */ u8 *equiv = EQUIV_TABLE(dfa); /* default is direct to next state */ pos = base_idx(base[state]) + equiv[(u8) c]; if (check[pos] == state) state = next[pos]; else state = def[state]; } else { /* default is direct to next state */ pos = base_idx(base[state]) + (u8) c; if (check[pos] == state) state = next[pos]; else state = def[state]; } return state; }
/** * aa_dfa_next_state - traverse @dfa to find state @str stops at * @dfa: the dfa to match @str against * @start: the state of the dfa to start matching in * @str: the string to match against the dfa * * aa_dfa_next_state will match @str against the dfa and return the state it * finished matching in. The final state can be used to look up the accepting * label, or as the start state of a continuing match. */ unsigned int aa_dfa_next_state(struct aa_dfa *dfa, unsigned int start, const char *str) { u16 *def = DEFAULT_TABLE(dfa); u32 *base = BASE_TABLE(dfa); u16 *next = NEXT_TABLE(dfa); u16 *check = CHECK_TABLE(dfa); unsigned int state = start, pos; if (state == 0) return 0; /* current state is <state>, matching character *str */ if (dfa->tables[YYTD_ID_EC - 1]) { u8 *equiv = EQUIV_TABLE(dfa); while (*str) { pos = base[state] + equiv[(u8)*str++]; if (check[pos] == state) state = next[pos]; else state = def[state]; } } else { while (*str) { pos = base[state] + (u8)*str++; if (check[pos] == state) state = next[pos]; else state = def[state]; } } return state; }
/** * aa_dfa_next - step one character to the next state in the dfa * @dfa: the dfa to tranverse (NOT NULL) * @state: the state to start in * @c: the input character to transition on * * aa_dfa_match will step through the dfa by one input character @c * * Returns: state reach after input @c */ unsigned int aa_dfa_next(struct aa_dfa *dfa, unsigned int state, const char c) { u16 *def = DEFAULT_TABLE(dfa); u32 *base = BASE_TABLE(dfa); u16 *next = NEXT_TABLE(dfa); u16 *check = CHECK_TABLE(dfa); /* current state is <state>, matching character *str */ if (dfa->tables[YYTD_ID_EC]) { /* Equivalence class table defined */ u8 *equiv = EQUIV_TABLE(dfa); match_char(state, def, base, next, check, equiv[(u8) c]); } else match_char(state, def, base, next, check, (u8) c); return state; }
/** * aa_dfa_matchn_until - traverse @dfa until accept or @n bytes consumed * @dfa: the dfa to match @str against (NOT NULL) * @start: the state of the dfa to start matching in * @str: the string of bytes to match against the dfa (NOT NULL) * @n: length of the string of bytes to match * @retpos: first character in str after match OR str + n * * aa_dfa_match_len will match @str against the dfa and return the state it * finished matching in. The final state can be used to look up the accepting * label, or as the start state of a continuing match. * * This function will happily match again the 0 byte and only finishes * when @n input is consumed. * * Returns: final state reached after input is consumed */ unsigned int aa_dfa_matchn_until(struct aa_dfa *dfa, unsigned int start, const char *str, int n, const char **retpos) { u16 *def = DEFAULT_TABLE(dfa); u32 *base = BASE_TABLE(dfa); u16 *next = NEXT_TABLE(dfa); u16 *check = CHECK_TABLE(dfa); u32 *accept = ACCEPT_TABLE(dfa); unsigned int state = start, pos; *retpos = NULL; if (state == 0) return 0; /* current state is <state>, matching character *str */ if (dfa->tables[YYTD_ID_EC]) { /* Equivalence class table defined */ u8 *equiv = EQUIV_TABLE(dfa); /* default is direct to next state */ for (; n; n--) { pos = base_idx(base[state]) + equiv[(u8) *str++]; if (check[pos] == state) state = next[pos]; else state = def[state]; if (accept[state]) break; } } else { /* default is direct to next state */ for (; n; n--) { pos = base_idx(base[state]) + (u8) *str++; if (check[pos] == state) state = next[pos]; else state = def[state]; if (accept[state]) break; } } *retpos = str; return state; }
unsigned int aa_dfa_match_len(struct aa_dfa *dfa, unsigned int start, const char *str, int len) { u16 *def = DEFAULT_TABLE(dfa); u32 *base = BASE_TABLE(dfa); u16 *next = NEXT_TABLE(dfa); u16 *check = CHECK_TABLE(dfa); unsigned int state = start, pos; if (state == 0) return 0; if (dfa->tables[YYTD_ID_EC]) { u8 *equiv = EQUIV_TABLE(dfa); for (; len; len--) { pos = base[state] + equiv[(u8) *str++]; if (check[pos] == state) state = next[pos]; else state = def[state]; } } else { for (; len; len--) { pos = base[state] + (u8) *str++; if (check[pos] == state) state = next[pos]; else state = def[state]; } } return state; }
/** * aa_dfa_match_len - traverse @dfa to find state @str stops at * @dfa: the dfa to match @str against (NOT NULL) * @start: the state of the dfa to start matching in * @str: the string of bytes to match against the dfa (NOT NULL) * @len: length of the string of bytes to match * * aa_dfa_match_len will match @str against the dfa and return the state it * finished matching in. The final state can be used to look up the accepting * label, or as the start state of a continuing match. * * This function will happily match again the 0 byte and only finishes * when @len input is consumed. * * Returns: final state reached after input is consumed */ unsigned int aa_dfa_match_len(struct aa_dfa *dfa, unsigned int start, const char *str, int len) { u16 *def = DEFAULT_TABLE(dfa); u32 *base = BASE_TABLE(dfa); u16 *next = NEXT_TABLE(dfa); u16 *check = CHECK_TABLE(dfa); unsigned int state = start, pos; if (state == 0) return 0; /* current state is <state>, matching character *str */ if (dfa->tables[YYTD_ID_EC]) { /* Equivalence class table defined */ u8 *equiv = EQUIV_TABLE(dfa); /* default is direct to next state */ for (; len; len--) { pos = base[state] + equiv[(u8) *str++]; if (check[pos] == state) state = next[pos]; else state = def[state]; } } else { /* default is direct to next state */ for (; len; len--) { pos = base[state] + (u8) *str++; if (check[pos] == state) state = next[pos]; else state = def[state]; } } return state; }
static unsigned int leftmatch_fb(struct aa_dfa *dfa, unsigned int start, const char *str, struct match_workbuf *wb, unsigned int *count) { u16 *def = DEFAULT_TABLE(dfa); u32 *base = BASE_TABLE(dfa); u16 *next = NEXT_TABLE(dfa); u16 *check = CHECK_TABLE(dfa); unsigned int state = start, pos; AA_BUG(!dfa); AA_BUG(!str); AA_BUG(!wb); AA_BUG(!count); *count = 0; if (state == 0) return 0; /* current state is <state>, matching character *str */ if (dfa->tables[YYTD_ID_EC]) { /* Equivalence class table defined */ u8 *equiv = EQUIV_TABLE(dfa); /* default is direct to next state */ while (*str) { unsigned int adjust; wb->history[wb->pos] = state; pos = base_idx(base[state]) + equiv[(u8) *str++]; if (check[pos] == state) state = next[pos]; else state = def[state]; if (is_loop(wb, state, &adjust)) { state = aa_dfa_match(dfa, state, str); *count -= adjust; goto out; } inc_wb_pos(wb); (*count)++; } } else { /* default is direct to next state */ while (*str) { unsigned int adjust; wb->history[wb->pos] = state; pos = base_idx(base[state]) + (u8) *str++; if (check[pos] == state) state = next[pos]; else state = def[state]; if (is_loop(wb, state, &adjust)) { state = aa_dfa_match(dfa, state, str); *count -= adjust; goto out; } inc_wb_pos(wb); (*count)++; } } out: if (!state) *count = 0; return state; }