1 /* $NetBSD: bm.c,v 1.12 2012/06/25 22:32:46 abs Exp $ */
5 * The Regents of the University of California. All rights reserved.
7 * This code is derived from software contributed to Berkeley by
8 * Andrew Hume of AT&T Bell Laboratories.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 #include <sys/cdefs.h>
36 #if defined(LIBC_SCCS) && !defined(lint)
38 static char sccsid
[] = "@(#)bm.c 8.7 (Berkeley) 6/21/94";
40 __RCSID("$NetBSD: bm.c,v 1.12 2012/06/25 22:32:46 abs Exp $");
42 #endif /* LIBC_SCCS && not lint */
44 #include "namespace.h"
45 #include <sys/types.h>
54 __weak_alias(bm_comp
,_bm_comp
)
55 __weak_alias(bm_exec
,_bm_exec
)
56 __weak_alias(bm_free
,_bm_free
)
61 * The default frequency table starts at 99 and counts down. The default
62 * table should probably be oriented toward text, and will necessarily be
63 * locale specific. This one is for English. It was derived from the
64 * OSF/1 and 4.4BSD formatted and unformatted manual pages, and about 100Mb
65 * of email and random text. Change it if you can find something better.
67 static u_char
const freq_def
[256] = {
68 0, 0, 0, 0, 0, 0, 0, 0,
69 0, 77, 90, 0, 0, 0, 0, 0,
70 0, 0, 0, 0, 0, 0, 0, 0,
71 0, 0, 0, 0, 0, 0, 0, 0,
72 99, 28, 42, 27, 16, 14, 20, 51,
73 66, 65, 59, 24, 75, 76, 84, 56,
74 72, 74, 64, 55, 54, 47, 41, 37,
75 44, 61, 70, 43, 23, 53, 49, 22,
76 33, 58, 40, 46, 45, 57, 60, 26,
77 30, 63, 21, 12, 32, 50, 38, 39,
78 34, 11, 48, 67, 62, 35, 15, 29,
79 71, 18, 9, 17, 25, 13, 10, 52,
80 36, 95, 78, 86, 87, 98, 82, 80,
81 88, 94, 19, 68, 89, 83, 93, 96,
82 81, 7, 91, 92, 97, 85, 69, 73,
83 31, 79, 8, 5, 4, 6, 3, 0,
84 0, 0, 0, 0, 0, 0, 0, 0,
85 0, 0, 0, 0, 0, 0, 0, 0,
86 0, 0, 0, 0, 0, 0, 0, 0,
87 0, 0, 0, 0, 0, 0, 0, 0,
88 0, 0, 0, 0, 0, 0, 0, 0,
89 0, 0, 0, 0, 0, 0, 0, 0,
90 0, 0, 0, 0, 0, 0, 0, 0,
91 0, 0, 0, 0, 0, 0, 0, 0,
92 0, 0, 0, 0, 0, 0, 0, 0,
93 0, 0, 0, 0, 0, 0, 0, 0,
94 0, 0, 0, 0, 0, 0, 0, 0,
95 0, 0, 0, 0, 0, 0, 0, 0,
96 0, 0, 0, 0, 0, 0, 0, 0,
97 0, 0, 0, 0, 0, 0, 0, 0,
98 0, 0, 0, 0, 0, 0, 0, 0,
99 0, 0, 0, 0, 0, 0, 0, 0,
103 bm_comp(u_char
const *pb
, size_t len
, u_char
const *freq
)
105 u_char
const *pe
, *p
;
111 _DIAGASSERT(pb
!= NULL
);
112 /* freq may be NULL */
118 if ((pat
= malloc(sizeof(*pat
))) == NULL
)
123 pat
->patlen
= len
; /* copy pattern */
124 if ((pat
->pat
= malloc(pat
->patlen
)) == NULL
)
126 memcpy(pat
->pat
, pb
, pat
->patlen
);
128 if ((pat
->delta
= malloc(256 * sizeof(*d
))) == NULL
)
130 for (j
= 0, d
= pat
->delta
; j
< 256; j
++)
132 for (pe
= pb
+ pat
->patlen
- 1; pb
<= pe
; pb
++)
135 if (freq
== NULL
) /* default freq table */
137 r
= 0; /* get guard */
138 for (pb
= pat
->pat
, pe
= pb
+ pat
->patlen
- 1; pb
< pe
; pb
++)
139 if (freq
[*pb
] < freq
[pat
->pat
[r
]])
141 pat
->rarec
= pat
->pat
[r
];
142 pat
->rareoff
= r
- (pat
->patlen
- 1);
145 for (pe
= pat
->pat
+ pat
->patlen
- 1, p
= pe
- 1; p
>= pat
->pat
; p
--)
149 /* *p is first leftward reoccurrence of *pe */
153 mem
: sv_errno
= errno
;
163 _DIAGASSERT(pat
!= NULL
);
165 if (pat
->pat
!= NULL
)
167 if (pat
->delta
!= NULL
)
173 bm_exec(bm_pat
*pat
, u_char
*base
, size_t n
)
175 u_char
*e
, *ep
, *p
, *q
, *s
;
176 size_t *d0
, k
, md2
, n1
, ro
;
179 _DIAGASSERT(pat
!= NULL
);
180 _DIAGASSERT(base
!= NULL
);
186 n1
= pat
->patlen
- 1;
190 ep
= pat
->pat
+ pat
->patlen
- 1;
191 s
= base
+ (pat
->patlen
- 1);
193 /* fast loop up to n - 3 * patlen */
194 e
= base
+ n
- 3 * pat
->patlen
;
196 k
= d0
[*s
]; /* ufast skip loop */
203 if (s
[ro
] != rc
) /* guard test */
206 for (p
= pat
->pat
, q
= s
- n1
; p
< ep
;)
211 mismatch1
: s
+= md2
; /* md2 shift */
214 /* slow loop up to end */
217 s
+= d0
[*s
]; /* step */
220 if (s
[ro
] != rc
) /* guard test */
223 for (p
= pat
->pat
, q
= s
- n1
; p
<= ep
;)
228 mismatch2
: s
+= md2
; /* md2 shift */