diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/textsearch.c | 14 | ||||
| -rw-r--r-- | lib/ts_bm.c | 26 | ||||
| -rw-r--r-- | lib/ts_fsm.c | 6 | ||||
| -rw-r--r-- | lib/ts_kmp.c | 29 |
4 files changed, 54 insertions, 21 deletions
diff --git a/lib/textsearch.c b/lib/textsearch.c index a3e500ad51d7..4b7c6075256f 100644 --- a/lib/textsearch.c +++ b/lib/textsearch.c | |||
| @@ -54,10 +54,13 @@ | |||
| 54 | * USAGE | 54 | * USAGE |
| 55 | * | 55 | * |
| 56 | * Before a search can be performed, a configuration must be created | 56 | * Before a search can be performed, a configuration must be created |
| 57 | * by calling textsearch_prepare() specyfing the searching algorithm and | 57 | * by calling textsearch_prepare() specifying the searching algorithm, |
| 58 | * the pattern to look for. The returned configuration may then be used | 58 | * the pattern to look for and flags. As a flag, you can set TS_IGNORECASE |
| 59 | * for an arbitary amount of times and even in parallel as long as a | 59 | * to perform case insensitive matching. But it might slow down |
| 60 | * separate struct ts_state variable is provided to every instance. | 60 | * performance of algorithm, so you should use it at own your risk. |
| 61 | * The returned configuration may then be used for an arbitary | ||
| 62 | * amount of times and even in parallel as long as a separate struct | ||
| 63 | * ts_state variable is provided to every instance. | ||
| 61 | * | 64 | * |
| 62 | * The actual search is performed by either calling textsearch_find_- | 65 | * The actual search is performed by either calling textsearch_find_- |
| 63 | * continuous() for linear data or by providing an own get_next_block() | 66 | * continuous() for linear data or by providing an own get_next_block() |
| @@ -89,7 +92,6 @@ | |||
| 89 | * panic("Oh my god, dancing chickens at %d\n", pos); | 92 | * panic("Oh my god, dancing chickens at %d\n", pos); |
| 90 | * | 93 | * |
| 91 | * textsearch_destroy(conf); | 94 | * textsearch_destroy(conf); |
| 92 | * | ||
| 93 | * ========================================================================== | 95 | * ========================================================================== |
| 94 | */ | 96 | */ |
| 95 | 97 | ||
| @@ -280,7 +282,7 @@ struct ts_config *textsearch_prepare(const char *algo, const void *pattern, | |||
| 280 | if (ops == NULL) | 282 | if (ops == NULL) |
| 281 | goto errout; | 283 | goto errout; |
| 282 | 284 | ||
| 283 | conf = ops->init(pattern, len, gfp_mask); | 285 | conf = ops->init(pattern, len, gfp_mask, flags); |
| 284 | if (IS_ERR(conf)) { | 286 | if (IS_ERR(conf)) { |
| 285 | err = PTR_ERR(conf); | 287 | err = PTR_ERR(conf); |
| 286 | goto errout; | 288 | goto errout; |
diff --git a/lib/ts_bm.c b/lib/ts_bm.c index 4a7fce72898e..9e66ee4020e9 100644 --- a/lib/ts_bm.c +++ b/lib/ts_bm.c | |||
| @@ -39,6 +39,7 @@ | |||
| 39 | #include <linux/module.h> | 39 | #include <linux/module.h> |
| 40 | #include <linux/types.h> | 40 | #include <linux/types.h> |
| 41 | #include <linux/string.h> | 41 | #include <linux/string.h> |
| 42 | #include <linux/ctype.h> | ||
| 42 | #include <linux/textsearch.h> | 43 | #include <linux/textsearch.h> |
| 43 | 44 | ||
| 44 | /* Alphabet size, use ASCII */ | 45 | /* Alphabet size, use ASCII */ |
| @@ -64,6 +65,7 @@ static unsigned int bm_find(struct ts_config *conf, struct ts_state *state) | |||
| 64 | unsigned int i, text_len, consumed = state->offset; | 65 | unsigned int i, text_len, consumed = state->offset; |
| 65 | const u8 *text; | 66 | const u8 *text; |
| 66 | int shift = bm->patlen - 1, bs; | 67 | int shift = bm->patlen - 1, bs; |
| 68 | const u8 icase = conf->flags & TS_IGNORECASE; | ||
| 67 | 69 | ||
| 68 | for (;;) { | 70 | for (;;) { |
| 69 | text_len = conf->get_next_block(consumed, &text, conf, state); | 71 | text_len = conf->get_next_block(consumed, &text, conf, state); |
| @@ -75,7 +77,9 @@ static unsigned int bm_find(struct ts_config *conf, struct ts_state *state) | |||
| 75 | DEBUGP("Searching in position %d (%c)\n", | 77 | DEBUGP("Searching in position %d (%c)\n", |
| 76 | shift, text[shift]); | 78 | shift, text[shift]); |
| 77 | for (i = 0; i < bm->patlen; i++) | 79 | for (i = 0; i < bm->patlen; i++) |
| 78 | if (text[shift-i] != bm->pattern[bm->patlen-1-i]) | 80 | if ((icase ? toupper(text[shift-i]) |
| 81 | : text[shift-i]) | ||
| 82 | != bm->pattern[bm->patlen-1-i]) | ||
| 79 | goto next; | 83 | goto next; |
| 80 | 84 | ||
| 81 | /* London calling... */ | 85 | /* London calling... */ |
| @@ -111,14 +115,18 @@ static int subpattern(u8 *pattern, int i, int j, int g) | |||
| 111 | return ret; | 115 | return ret; |
| 112 | } | 116 | } |
| 113 | 117 | ||
| 114 | static void compute_prefix_tbl(struct ts_bm *bm) | 118 | static void compute_prefix_tbl(struct ts_bm *bm, int flags) |
| 115 | { | 119 | { |
| 116 | int i, j, g; | 120 | int i, j, g; |
| 117 | 121 | ||
| 118 | for (i = 0; i < ASIZE; i++) | 122 | for (i = 0; i < ASIZE; i++) |
| 119 | bm->bad_shift[i] = bm->patlen; | 123 | bm->bad_shift[i] = bm->patlen; |
| 120 | for (i = 0; i < bm->patlen - 1; i++) | 124 | for (i = 0; i < bm->patlen - 1; i++) { |
| 121 | bm->bad_shift[bm->pattern[i]] = bm->patlen - 1 - i; | 125 | bm->bad_shift[bm->pattern[i]] = bm->patlen - 1 - i; |
| 126 | if (flags & TS_IGNORECASE) | ||
| 127 | bm->bad_shift[tolower(bm->pattern[i])] | ||
| 128 | = bm->patlen - 1 - i; | ||
| 129 | } | ||
| 122 | 130 | ||
| 123 | /* Compute the good shift array, used to match reocurrences | 131 | /* Compute the good shift array, used to match reocurrences |
| 124 | * of a subpattern */ | 132 | * of a subpattern */ |
| @@ -135,10 +143,11 @@ static void compute_prefix_tbl(struct ts_bm *bm) | |||
| 135 | } | 143 | } |
| 136 | 144 | ||
| 137 | static struct ts_config *bm_init(const void *pattern, unsigned int len, | 145 | static struct ts_config *bm_init(const void *pattern, unsigned int len, |
| 138 | gfp_t gfp_mask) | 146 | gfp_t gfp_mask, int flags) |
| 139 | { | 147 | { |
| 140 | struct ts_config *conf; | 148 | struct ts_config *conf; |
| 141 | struct ts_bm *bm; | 149 | struct ts_bm *bm; |
| 150 | int i; | ||
| 142 | unsigned int prefix_tbl_len = len * sizeof(unsigned int); | 151 | unsigned int prefix_tbl_len = len * sizeof(unsigned int); |
| 143 | size_t priv_size = sizeof(*bm) + len + prefix_tbl_len; | 152 | size_t priv_size = sizeof(*bm) + len + prefix_tbl_len; |
| 144 | 153 | ||
| @@ -146,11 +155,16 @@ static struct ts_config *bm_init(const void *pattern, unsigned int len, | |||
| 146 | if (IS_ERR(conf)) | 155 | if (IS_ERR(conf)) |
| 147 | return conf; | 156 | return conf; |
| 148 | 157 | ||
| 158 | conf->flags = flags; | ||
| 149 | bm = ts_config_priv(conf); | 159 | bm = ts_config_priv(conf); |
| 150 | bm->patlen = len; | 160 | bm->patlen = len; |
| 151 | bm->pattern = (u8 *) bm->good_shift + prefix_tbl_len; | 161 | bm->pattern = (u8 *) bm->good_shift + prefix_tbl_len; |
| 152 | memcpy(bm->pattern, pattern, len); | 162 | if (flags & TS_IGNORECASE) |
| 153 | compute_prefix_tbl(bm); | 163 | for (i = 0; i < len; i++) |
| 164 | bm->pattern[i] = toupper(((u8 *)pattern)[i]); | ||
| 165 | else | ||
| 166 | memcpy(bm->pattern, pattern, len); | ||
| 167 | compute_prefix_tbl(bm, flags); | ||
| 154 | 168 | ||
| 155 | return conf; | 169 | return conf; |
| 156 | } | 170 | } |
diff --git a/lib/ts_fsm.c b/lib/ts_fsm.c index af575b61526b..5696a35184e4 100644 --- a/lib/ts_fsm.c +++ b/lib/ts_fsm.c | |||
| @@ -257,7 +257,7 @@ found_match: | |||
| 257 | } | 257 | } |
| 258 | 258 | ||
| 259 | static struct ts_config *fsm_init(const void *pattern, unsigned int len, | 259 | static struct ts_config *fsm_init(const void *pattern, unsigned int len, |
| 260 | gfp_t gfp_mask) | 260 | gfp_t gfp_mask, int flags) |
| 261 | { | 261 | { |
| 262 | int i, err = -EINVAL; | 262 | int i, err = -EINVAL; |
| 263 | struct ts_config *conf; | 263 | struct ts_config *conf; |
| @@ -269,6 +269,9 @@ static struct ts_config *fsm_init(const void *pattern, unsigned int len, | |||
| 269 | if (len % sizeof(struct ts_fsm_token) || ntokens < 1) | 269 | if (len % sizeof(struct ts_fsm_token) || ntokens < 1) |
| 270 | goto errout; | 270 | goto errout; |
| 271 | 271 | ||
| 272 | if (flags & TS_IGNORECASE) | ||
| 273 | goto errout; | ||
| 274 | |||
| 272 | for (i = 0; i < ntokens; i++) { | 275 | for (i = 0; i < ntokens; i++) { |
| 273 | struct ts_fsm_token *t = &tokens[i]; | 276 | struct ts_fsm_token *t = &tokens[i]; |
| 274 | 277 | ||
| @@ -284,6 +287,7 @@ static struct ts_config *fsm_init(const void *pattern, unsigned int len, | |||
| 284 | if (IS_ERR(conf)) | 287 | if (IS_ERR(conf)) |
| 285 | return conf; | 288 | return conf; |
| 286 | 289 | ||
| 290 | conf->flags = flags; | ||
| 287 | fsm = ts_config_priv(conf); | 291 | fsm = ts_config_priv(conf); |
| 288 | fsm->ntokens = ntokens; | 292 | fsm->ntokens = ntokens; |
| 289 | memcpy(fsm->tokens, pattern, len); | 293 | memcpy(fsm->tokens, pattern, len); |
diff --git a/lib/ts_kmp.c b/lib/ts_kmp.c index 3ced628cab4b..632f783e65f1 100644 --- a/lib/ts_kmp.c +++ b/lib/ts_kmp.c | |||
| @@ -33,6 +33,7 @@ | |||
| 33 | #include <linux/module.h> | 33 | #include <linux/module.h> |
| 34 | #include <linux/types.h> | 34 | #include <linux/types.h> |
| 35 | #include <linux/string.h> | 35 | #include <linux/string.h> |
| 36 | #include <linux/ctype.h> | ||
| 36 | #include <linux/textsearch.h> | 37 | #include <linux/textsearch.h> |
| 37 | 38 | ||
| 38 | struct ts_kmp | 39 | struct ts_kmp |
| @@ -47,6 +48,7 @@ static unsigned int kmp_find(struct ts_config *conf, struct ts_state *state) | |||
| 47 | struct ts_kmp *kmp = ts_config_priv(conf); | 48 | struct ts_kmp *kmp = ts_config_priv(conf); |
| 48 | unsigned int i, q = 0, text_len, consumed = state->offset; | 49 | unsigned int i, q = 0, text_len, consumed = state->offset; |
| 49 | const u8 *text; | 50 | const u8 *text; |
| 51 | const int icase = conf->flags & TS_IGNORECASE; | ||
| 50 | 52 | ||
| 51 | for (;;) { | 53 | for (;;) { |
| 52 | text_len = conf->get_next_block(consumed, &text, conf, state); | 54 | text_len = conf->get_next_block(consumed, &text, conf, state); |
| @@ -55,9 +57,11 @@ static unsigned int kmp_find(struct ts_config *conf, struct ts_state *state) | |||
| 55 | break; | 57 | break; |
| 56 | 58 | ||
| 57 | for (i = 0; i < text_len; i++) { | 59 | for (i = 0; i < text_len; i++) { |
| 58 | while (q > 0 && kmp->pattern[q] != text[i]) | 60 | while (q > 0 && kmp->pattern[q] |
| 61 | != (icase ? toupper(text[i]) : text[i])) | ||
| 59 | q = kmp->prefix_tbl[q - 1]; | 62 | q = kmp->prefix_tbl[q - 1]; |
| 60 | if (kmp->pattern[q] == text[i]) | 63 | if (kmp->pattern[q] |
| 64 | == (icase ? toupper(text[i]) : text[i])) | ||
| 61 | q++; | 65 | q++; |
| 62 | if (unlikely(q == kmp->pattern_len)) { | 66 | if (unlikely(q == kmp->pattern_len)) { |
| 63 | state->offset = consumed + i + 1; | 67 | state->offset = consumed + i + 1; |
| @@ -72,24 +76,28 @@ static unsigned int kmp_find(struct ts_config *conf, struct ts_state *state) | |||
| 72 | } | 76 | } |
| 73 | 77 | ||
| 74 | static inline void compute_prefix_tbl(const u8 *pattern, unsigned int len, | 78 | static inline void compute_prefix_tbl(const u8 *pattern, unsigned int len, |
| 75 | unsigned int *prefix_tbl) | 79 | unsigned int *prefix_tbl, int flags) |
| 76 | { | 80 | { |
| 77 | unsigned int k, q; | 81 | unsigned int k, q; |
| 82 | const u8 icase = flags & TS_IGNORECASE; | ||
| 78 | 83 | ||
| 79 | for (k = 0, q = 1; q < len; q++) { | 84 | for (k = 0, q = 1; q < len; q++) { |
| 80 | while (k > 0 && pattern[k] != pattern[q]) | 85 | while (k > 0 && (icase ? toupper(pattern[k]) : pattern[k]) |
| 86 | != (icase ? toupper(pattern[q]) : pattern[q])) | ||
| 81 | k = prefix_tbl[k-1]; | 87 | k = prefix_tbl[k-1]; |
| 82 | if (pattern[k] == pattern[q]) | 88 | if ((icase ? toupper(pattern[k]) : pattern[k]) |
| 89 | == (icase ? toupper(pattern[q]) : pattern[q])) | ||
| 83 | k++; | 90 | k++; |
| 84 | prefix_tbl[q] = k; | 91 | prefix_tbl[q] = k; |
| 85 | } | 92 | } |
| 86 | } | 93 | } |
| 87 | 94 | ||
| 88 | static struct ts_config *kmp_init(const void *pattern, unsigned int len, | 95 | static struct ts_config *kmp_init(const void *pattern, unsigned int len, |
| 89 | gfp_t gfp_mask) | 96 | gfp_t gfp_mask, int flags) |
| 90 | { | 97 | { |
| 91 | struct ts_config *conf; | 98 | struct ts_config *conf; |
| 92 | struct ts_kmp *kmp; | 99 | struct ts_kmp *kmp; |
| 100 | int i; | ||
| 93 | unsigned int prefix_tbl_len = len * sizeof(unsigned int); | 101 | unsigned int prefix_tbl_len = len * sizeof(unsigned int); |
| 94 | size_t priv_size = sizeof(*kmp) + len + prefix_tbl_len; | 102 | size_t priv_size = sizeof(*kmp) + len + prefix_tbl_len; |
| 95 | 103 | ||
| @@ -97,11 +105,16 @@ static struct ts_config *kmp_init(const void *pattern, unsigned int len, | |||
| 97 | if (IS_ERR(conf)) | 105 | if (IS_ERR(conf)) |
| 98 | return conf; | 106 | return conf; |
| 99 | 107 | ||
| 108 | conf->flags = flags; | ||
| 100 | kmp = ts_config_priv(conf); | 109 | kmp = ts_config_priv(conf); |
| 101 | kmp->pattern_len = len; | 110 | kmp->pattern_len = len; |
| 102 | compute_prefix_tbl(pattern, len, kmp->prefix_tbl); | 111 | compute_prefix_tbl(pattern, len, kmp->prefix_tbl, flags); |
| 103 | kmp->pattern = (u8 *) kmp->prefix_tbl + prefix_tbl_len; | 112 | kmp->pattern = (u8 *) kmp->prefix_tbl + prefix_tbl_len; |
| 104 | memcpy(kmp->pattern, pattern, len); | 113 | if (flags & TS_IGNORECASE) |
| 114 | for (i = 0; i < len; i++) | ||
| 115 | kmp->pattern[i] = toupper(((u8 *)pattern)[i]); | ||
| 116 | else | ||
| 117 | memcpy(kmp->pattern, pattern, len); | ||
| 105 | 118 | ||
| 106 | return conf; | 119 | return conf; |
| 107 | } | 120 | } |
