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 | } |