xref: /freebsd/contrib/nvi/common/seq.c (revision 110d525ec6188f3c9dc4f54c4bc1cced2f7184cd)
1b8ba871bSPeter Wemm /*-
2b8ba871bSPeter Wemm  * Copyright (c) 1992, 1993, 1994
3b8ba871bSPeter Wemm  *	The Regents of the University of California.  All rights reserved.
4b8ba871bSPeter Wemm  * Copyright (c) 1992, 1993, 1994, 1995, 1996
5b8ba871bSPeter Wemm  *	Keith Bostic.  All rights reserved.
6b8ba871bSPeter Wemm  *
7b8ba871bSPeter Wemm  * See the LICENSE file for redistribution information.
8b8ba871bSPeter Wemm  */
9b8ba871bSPeter Wemm 
10b8ba871bSPeter Wemm #include "config.h"
11b8ba871bSPeter Wemm 
12b8ba871bSPeter Wemm #include <sys/types.h>
13b8ba871bSPeter Wemm #include <sys/queue.h>
14f0957ccaSPeter Wemm #include <sys/time.h>
15b8ba871bSPeter Wemm 
16b8ba871bSPeter Wemm #include <bitstring.h>
17b8ba871bSPeter Wemm #include <ctype.h>
18b8ba871bSPeter Wemm #include <errno.h>
19b8ba871bSPeter Wemm #include <limits.h>
20b8ba871bSPeter Wemm #include <stdio.h>
21b8ba871bSPeter Wemm #include <stdlib.h>
22b8ba871bSPeter Wemm #include <string.h>
23b8ba871bSPeter Wemm 
24b8ba871bSPeter Wemm #include "common.h"
25b8ba871bSPeter Wemm 
26b8ba871bSPeter Wemm /*
27b8ba871bSPeter Wemm  * seq_set --
28b8ba871bSPeter Wemm  *	Internal version to enter a sequence.
29b8ba871bSPeter Wemm  *
30c271fa92SBaptiste Daroussin  * PUBLIC: int seq_set(SCR *, CHAR_T *,
31c271fa92SBaptiste Daroussin  * PUBLIC:    size_t, CHAR_T *, size_t, CHAR_T *, size_t, seq_t, int);
32b8ba871bSPeter Wemm  */
33b8ba871bSPeter Wemm int
seq_set(SCR * sp,CHAR_T * name,size_t nlen,CHAR_T * input,size_t ilen,CHAR_T * output,size_t olen,seq_t stype,int flags)34*110d525eSBaptiste Daroussin seq_set(SCR *sp, CHAR_T *name, size_t nlen, CHAR_T *input, size_t ilen,
35*110d525eSBaptiste Daroussin     CHAR_T *output, size_t olen, seq_t stype, int flags)
36b8ba871bSPeter Wemm {
37b8ba871bSPeter Wemm 	CHAR_T *p;
38b8ba871bSPeter Wemm 	SEQ *lastqp, *qp;
39b8ba871bSPeter Wemm 	int sv_errno;
40b8ba871bSPeter Wemm 
41b8ba871bSPeter Wemm 	/*
42b8ba871bSPeter Wemm 	 * An input string must always be present.  The output string
43b8ba871bSPeter Wemm 	 * can be NULL, when set internally, that's how we throw away
44b8ba871bSPeter Wemm 	 * input.
45b8ba871bSPeter Wemm 	 *
46b8ba871bSPeter Wemm 	 * Just replace the output field if the string already set.
47b8ba871bSPeter Wemm 	 */
48b8ba871bSPeter Wemm 	if ((qp =
49b8ba871bSPeter Wemm 	    seq_find(sp, &lastqp, NULL, input, ilen, stype, NULL)) != NULL) {
50b8ba871bSPeter Wemm 		if (LF_ISSET(SEQ_NOOVERWRITE))
51b8ba871bSPeter Wemm 			return (0);
52b8ba871bSPeter Wemm 		if (output == NULL || olen == 0) {
53b8ba871bSPeter Wemm 			p = NULL;
54b8ba871bSPeter Wemm 			olen = 0;
55f0957ccaSPeter Wemm 		} else if ((p = v_wstrdup(sp, output, olen)) == NULL) {
56b8ba871bSPeter Wemm 			sv_errno = errno;
57b8ba871bSPeter Wemm 			goto mem1;
58b8ba871bSPeter Wemm 		}
59b8ba871bSPeter Wemm 		free(qp->output);
60b8ba871bSPeter Wemm 		qp->olen = olen;
61b8ba871bSPeter Wemm 		qp->output = p;
62b8ba871bSPeter Wemm 		return (0);
63b8ba871bSPeter Wemm 	}
64b8ba871bSPeter Wemm 
65b8ba871bSPeter Wemm 	/* Allocate and initialize SEQ structure. */
66*110d525eSBaptiste Daroussin 	CALLOC(sp, qp, 1, sizeof(SEQ));
67b8ba871bSPeter Wemm 	if (qp == NULL) {
68b8ba871bSPeter Wemm 		sv_errno = errno;
69b8ba871bSPeter Wemm 		goto mem1;
70b8ba871bSPeter Wemm 	}
71b8ba871bSPeter Wemm 
72b8ba871bSPeter Wemm 	/* Name. */
73b8ba871bSPeter Wemm 	if (name == NULL || nlen == 0)
74b8ba871bSPeter Wemm 		qp->name = NULL;
75f0957ccaSPeter Wemm 	else if ((qp->name = v_wstrdup(sp, name, nlen)) == NULL) {
76b8ba871bSPeter Wemm 		sv_errno = errno;
77b8ba871bSPeter Wemm 		goto mem2;
78b8ba871bSPeter Wemm 	}
79b8ba871bSPeter Wemm 	qp->nlen = nlen;
80b8ba871bSPeter Wemm 
81b8ba871bSPeter Wemm 	/* Input. */
82f0957ccaSPeter Wemm 	if ((qp->input = v_wstrdup(sp, input, ilen)) == NULL) {
83b8ba871bSPeter Wemm 		sv_errno = errno;
84b8ba871bSPeter Wemm 		goto mem3;
85b8ba871bSPeter Wemm 	}
86b8ba871bSPeter Wemm 	qp->ilen = ilen;
87b8ba871bSPeter Wemm 
88b8ba871bSPeter Wemm 	/* Output. */
89b8ba871bSPeter Wemm 	if (output == NULL) {
90b8ba871bSPeter Wemm 		qp->output = NULL;
91b8ba871bSPeter Wemm 		olen = 0;
92f0957ccaSPeter Wemm 	} else if ((qp->output = v_wstrdup(sp, output, olen)) == NULL) {
93b8ba871bSPeter Wemm 		sv_errno = errno;
94b8ba871bSPeter Wemm 		free(qp->input);
95*110d525eSBaptiste Daroussin mem3:		free(qp->name);
96b8ba871bSPeter Wemm mem2:		free(qp);
97b8ba871bSPeter Wemm mem1:		errno = sv_errno;
98b8ba871bSPeter Wemm 		msgq(sp, M_SYSERR, NULL);
99b8ba871bSPeter Wemm 		return (1);
100b8ba871bSPeter Wemm 	}
101b8ba871bSPeter Wemm 	qp->olen = olen;
102b8ba871bSPeter Wemm 
103b8ba871bSPeter Wemm 	/* Type, flags. */
104b8ba871bSPeter Wemm 	qp->stype = stype;
105b8ba871bSPeter Wemm 	qp->flags = flags;
106b8ba871bSPeter Wemm 
107b8ba871bSPeter Wemm 	/* Link into the chain. */
108b8ba871bSPeter Wemm 	if (lastqp == NULL) {
109f0957ccaSPeter Wemm 		SLIST_INSERT_HEAD(sp->gp->seqq, qp, q);
110b8ba871bSPeter Wemm 	} else {
111f0957ccaSPeter Wemm 		SLIST_INSERT_AFTER(lastqp, qp, q);
112b8ba871bSPeter Wemm 	}
113b8ba871bSPeter Wemm 
114b8ba871bSPeter Wemm 	/* Set the fast lookup bit. */
115f0957ccaSPeter Wemm 	if ((qp->input[0] & ~MAX_BIT_SEQ) == 0)
116b8ba871bSPeter Wemm 		bit_set(sp->gp->seqb, qp->input[0]);
117b8ba871bSPeter Wemm 
118b8ba871bSPeter Wemm 	return (0);
119b8ba871bSPeter Wemm }
120b8ba871bSPeter Wemm 
121b8ba871bSPeter Wemm /*
122b8ba871bSPeter Wemm  * seq_delete --
123b8ba871bSPeter Wemm  *	Delete a sequence.
124b8ba871bSPeter Wemm  *
125c271fa92SBaptiste Daroussin  * PUBLIC: int seq_delete(SCR *, CHAR_T *, size_t, seq_t);
126b8ba871bSPeter Wemm  */
127b8ba871bSPeter Wemm int
seq_delete(SCR * sp,CHAR_T * input,size_t ilen,seq_t stype)128*110d525eSBaptiste Daroussin seq_delete(SCR *sp, CHAR_T *input, size_t ilen, seq_t stype)
129b8ba871bSPeter Wemm {
130f0957ccaSPeter Wemm 	SEQ *qp, *pre_qp = NULL;
131f0957ccaSPeter Wemm 	int diff;
132b8ba871bSPeter Wemm 
133f0957ccaSPeter Wemm 	SLIST_FOREACH(qp, sp->gp->seqq, q) {
134f0957ccaSPeter Wemm 		if (qp->stype == stype && qp->ilen == ilen) {
135f0957ccaSPeter Wemm 			diff = MEMCMP(qp->input, input, ilen);
136f0957ccaSPeter Wemm 			if (!diff) {
137f0957ccaSPeter Wemm 				if (F_ISSET(qp, SEQ_FUNCMAP))
138f0957ccaSPeter Wemm 					break;
139f0957ccaSPeter Wemm 				if (qp == SLIST_FIRST(sp->gp->seqq))
140f0957ccaSPeter Wemm 					SLIST_REMOVE_HEAD(sp->gp->seqq, q);
141f0957ccaSPeter Wemm 				else
142f0957ccaSPeter Wemm 					SLIST_REMOVE_AFTER(pre_qp, q);
143f0957ccaSPeter Wemm 				return (seq_free(qp));
144f0957ccaSPeter Wemm 			}
145f0957ccaSPeter Wemm 			if (diff > 0)
146f0957ccaSPeter Wemm 				break;
147f0957ccaSPeter Wemm 		}
148f0957ccaSPeter Wemm 		pre_qp = qp;
149f0957ccaSPeter Wemm 	}
150b8ba871bSPeter Wemm 	return (1);
151b8ba871bSPeter Wemm }
152b8ba871bSPeter Wemm 
153b8ba871bSPeter Wemm /*
154f0957ccaSPeter Wemm  * seq_free --
155f0957ccaSPeter Wemm  *	Free a map entry.
156b8ba871bSPeter Wemm  *
157c271fa92SBaptiste Daroussin  * PUBLIC: int seq_free(SEQ *);
158b8ba871bSPeter Wemm  */
159b8ba871bSPeter Wemm int
seq_free(SEQ * qp)160f0957ccaSPeter Wemm seq_free(SEQ *qp)
161b8ba871bSPeter Wemm {
162b8ba871bSPeter Wemm 	free(qp->name);
163b8ba871bSPeter Wemm 	free(qp->input);
164b8ba871bSPeter Wemm 	free(qp->output);
165b8ba871bSPeter Wemm 	free(qp);
166b8ba871bSPeter Wemm 	return (0);
167b8ba871bSPeter Wemm }
168b8ba871bSPeter Wemm 
169b8ba871bSPeter Wemm /*
170b8ba871bSPeter Wemm  * seq_find --
171b8ba871bSPeter Wemm  *	Search the sequence list for a match to a buffer, if ispartial
172b8ba871bSPeter Wemm  *	isn't NULL, partial matches count.
173b8ba871bSPeter Wemm  *
174b8ba871bSPeter Wemm  * PUBLIC: SEQ *seq_find
175c271fa92SBaptiste Daroussin  * PUBLIC:   (SCR *, SEQ **, EVENT *, CHAR_T *, size_t, seq_t, int *);
176b8ba871bSPeter Wemm  */
177b8ba871bSPeter Wemm SEQ *
seq_find(SCR * sp,SEQ ** lastqp,EVENT * e_input,CHAR_T * c_input,size_t ilen,seq_t stype,int * ispartialp)178*110d525eSBaptiste Daroussin seq_find(SCR *sp, SEQ **lastqp, EVENT *e_input, CHAR_T *c_input, size_t ilen,
179*110d525eSBaptiste Daroussin     seq_t stype, int *ispartialp)
180b8ba871bSPeter Wemm {
181f0957ccaSPeter Wemm 	SEQ *lqp = NULL, *qp;
182b8ba871bSPeter Wemm 	int diff;
183b8ba871bSPeter Wemm 
184b8ba871bSPeter Wemm 	/*
185b8ba871bSPeter Wemm 	 * Ispartialp is a location where we return if there was a
186b8ba871bSPeter Wemm 	 * partial match, i.e. if the string were extended it might
187b8ba871bSPeter Wemm 	 * match something.
188b8ba871bSPeter Wemm 	 *
189b8ba871bSPeter Wemm 	 * XXX
190b8ba871bSPeter Wemm 	 * Overload the meaning of ispartialp; only the terminal key
191b8ba871bSPeter Wemm 	 * search doesn't want the search limited to complete matches,
192b8ba871bSPeter Wemm 	 * i.e. ilen may be longer than the match.
193b8ba871bSPeter Wemm 	 */
194b8ba871bSPeter Wemm 	if (ispartialp != NULL)
195b8ba871bSPeter Wemm 		*ispartialp = 0;
196f0957ccaSPeter Wemm 	for (qp = SLIST_FIRST(sp->gp->seqq); qp != NULL;
197f0957ccaSPeter Wemm 	    lqp = qp, qp = SLIST_NEXT(qp, q)) {
198b8ba871bSPeter Wemm 		/*
199b8ba871bSPeter Wemm 		 * Fast checks on the first character and type, and then
200b8ba871bSPeter Wemm 		 * a real comparison.
201b8ba871bSPeter Wemm 		 */
202b8ba871bSPeter Wemm 		if (e_input == NULL) {
203b8ba871bSPeter Wemm 			if (qp->input[0] > c_input[0])
204b8ba871bSPeter Wemm 				break;
205b8ba871bSPeter Wemm 			if (qp->input[0] < c_input[0] ||
206b8ba871bSPeter Wemm 			    qp->stype != stype || F_ISSET(qp, SEQ_FUNCMAP))
207b8ba871bSPeter Wemm 				continue;
208f0957ccaSPeter Wemm 			diff = MEMCMP(qp->input, c_input, MIN(qp->ilen, ilen));
209b8ba871bSPeter Wemm 		} else {
210b8ba871bSPeter Wemm 			if (qp->input[0] > e_input->e_c)
211b8ba871bSPeter Wemm 				break;
212b8ba871bSPeter Wemm 			if (qp->input[0] < e_input->e_c ||
213b8ba871bSPeter Wemm 			    qp->stype != stype || F_ISSET(qp, SEQ_FUNCMAP))
214b8ba871bSPeter Wemm 				continue;
215b8ba871bSPeter Wemm 			diff =
216b8ba871bSPeter Wemm 			    e_memcmp(qp->input, e_input, MIN(qp->ilen, ilen));
217b8ba871bSPeter Wemm 		}
218b8ba871bSPeter Wemm 		if (diff > 0)
219b8ba871bSPeter Wemm 			break;
220b8ba871bSPeter Wemm 		if (diff < 0)
221b8ba871bSPeter Wemm 			continue;
222b8ba871bSPeter Wemm 		/*
223b8ba871bSPeter Wemm 		 * If the entry is the same length as the string, return a
224b8ba871bSPeter Wemm 		 * match.  If the entry is shorter than the string, return a
225b8ba871bSPeter Wemm 		 * match if called from the terminal key routine.  Otherwise,
226b8ba871bSPeter Wemm 		 * keep searching for a complete match.
227b8ba871bSPeter Wemm 		 */
228b8ba871bSPeter Wemm 		if (qp->ilen <= ilen) {
229b8ba871bSPeter Wemm 			if (qp->ilen == ilen || ispartialp != NULL) {
230b8ba871bSPeter Wemm 				if (lastqp != NULL)
231b8ba871bSPeter Wemm 					*lastqp = lqp;
232b8ba871bSPeter Wemm 				return (qp);
233b8ba871bSPeter Wemm 			}
234b8ba871bSPeter Wemm 			continue;
235b8ba871bSPeter Wemm 		}
236b8ba871bSPeter Wemm 		/*
237b8ba871bSPeter Wemm 		 * If the entry longer than the string, return partial match
238b8ba871bSPeter Wemm 		 * if called from the terminal key routine.  Otherwise, no
239b8ba871bSPeter Wemm 		 * match.
240b8ba871bSPeter Wemm 		 */
241b8ba871bSPeter Wemm 		if (ispartialp != NULL)
242b8ba871bSPeter Wemm 			*ispartialp = 1;
243b8ba871bSPeter Wemm 		break;
244b8ba871bSPeter Wemm 	}
245b8ba871bSPeter Wemm 	if (lastqp != NULL)
246b8ba871bSPeter Wemm 		*lastqp = lqp;
247b8ba871bSPeter Wemm 	return (NULL);
248b8ba871bSPeter Wemm }
249b8ba871bSPeter Wemm 
250b8ba871bSPeter Wemm /*
251b8ba871bSPeter Wemm  * seq_close --
252b8ba871bSPeter Wemm  *	Discard all sequences.
253b8ba871bSPeter Wemm  *
254c271fa92SBaptiste Daroussin  * PUBLIC: void seq_close(GS *);
255b8ba871bSPeter Wemm  */
256b8ba871bSPeter Wemm void
seq_close(GS * gp)257f0957ccaSPeter Wemm seq_close(GS *gp)
258b8ba871bSPeter Wemm {
259b8ba871bSPeter Wemm 	SEQ *qp;
260b8ba871bSPeter Wemm 
261f0957ccaSPeter Wemm 	while ((qp = SLIST_FIRST(gp->seqq)) != NULL) {
262f0957ccaSPeter Wemm 		SLIST_REMOVE_HEAD(gp->seqq, q);
263f0957ccaSPeter Wemm 		(void)seq_free(qp);
264b8ba871bSPeter Wemm 	}
265b8ba871bSPeter Wemm }
266b8ba871bSPeter Wemm 
267b8ba871bSPeter Wemm /*
268b8ba871bSPeter Wemm  * seq_dump --
269b8ba871bSPeter Wemm  *	Display the sequence entries of a specified type.
270b8ba871bSPeter Wemm  *
271c271fa92SBaptiste Daroussin  * PUBLIC: int seq_dump(SCR *, seq_t, int);
272b8ba871bSPeter Wemm  */
273b8ba871bSPeter Wemm int
seq_dump(SCR * sp,seq_t stype,int isname)274*110d525eSBaptiste Daroussin seq_dump(SCR *sp, seq_t stype, int isname)
275b8ba871bSPeter Wemm {
276b8ba871bSPeter Wemm 	CHAR_T *p;
277b8ba871bSPeter Wemm 	GS *gp;
278b8ba871bSPeter Wemm 	SEQ *qp;
279b8ba871bSPeter Wemm 	int cnt, len, olen;
280b8ba871bSPeter Wemm 
281b8ba871bSPeter Wemm 	cnt = 0;
282b8ba871bSPeter Wemm 	gp = sp->gp;
283f0957ccaSPeter Wemm 	SLIST_FOREACH(qp, sp->gp->seqq, q) {
284b8ba871bSPeter Wemm 		if (stype != qp->stype || F_ISSET(qp, SEQ_FUNCMAP))
285b8ba871bSPeter Wemm 			continue;
286b8ba871bSPeter Wemm 		++cnt;
287b8ba871bSPeter Wemm 		for (p = qp->input,
288b8ba871bSPeter Wemm 		    olen = qp->ilen, len = 0; olen > 0; --olen, ++p)
289b8ba871bSPeter Wemm 			len += ex_puts(sp, KEY_NAME(sp, *p));
290b8ba871bSPeter Wemm 		for (len = STANDARD_TAB - len % STANDARD_TAB; len > 0;)
291b8ba871bSPeter Wemm 			len -= ex_puts(sp, " ");
292b8ba871bSPeter Wemm 
293b8ba871bSPeter Wemm 		if (qp->output != NULL)
294b8ba871bSPeter Wemm 			for (p = qp->output,
295b8ba871bSPeter Wemm 			    olen = qp->olen, len = 0; olen > 0; --olen, ++p)
296b8ba871bSPeter Wemm 				len += ex_puts(sp, KEY_NAME(sp, *p));
297b8ba871bSPeter Wemm 		else
298b8ba871bSPeter Wemm 			len = 0;
299b8ba871bSPeter Wemm 
300b8ba871bSPeter Wemm 		if (isname && qp->name != NULL) {
301b8ba871bSPeter Wemm 			for (len = STANDARD_TAB - len % STANDARD_TAB; len > 0;)
302b8ba871bSPeter Wemm 				len -= ex_puts(sp, " ");
303b8ba871bSPeter Wemm 			for (p = qp->name,
304b8ba871bSPeter Wemm 			    olen = qp->nlen; olen > 0; --olen, ++p)
305b8ba871bSPeter Wemm 				(void)ex_puts(sp, KEY_NAME(sp, *p));
306b8ba871bSPeter Wemm 		}
307b8ba871bSPeter Wemm 		(void)ex_puts(sp, "\n");
308b8ba871bSPeter Wemm 	}
309b8ba871bSPeter Wemm 	return (cnt);
310b8ba871bSPeter Wemm }
311b8ba871bSPeter Wemm 
312b8ba871bSPeter Wemm /*
313b8ba871bSPeter Wemm  * seq_save --
314b8ba871bSPeter Wemm  *	Save the sequence entries to a file.
315b8ba871bSPeter Wemm  *
316c271fa92SBaptiste Daroussin  * PUBLIC: int seq_save(SCR *, FILE *, char *, seq_t);
317b8ba871bSPeter Wemm  */
318b8ba871bSPeter Wemm int
seq_save(SCR * sp,FILE * fp,char * prefix,seq_t stype)319*110d525eSBaptiste Daroussin seq_save(SCR *sp, FILE *fp, char *prefix, seq_t stype)
320b8ba871bSPeter Wemm {
321b8ba871bSPeter Wemm 	CHAR_T *p;
322b8ba871bSPeter Wemm 	SEQ *qp;
323b8ba871bSPeter Wemm 	size_t olen;
324b8ba871bSPeter Wemm 	int ch;
325b8ba871bSPeter Wemm 
326b8ba871bSPeter Wemm 	/* Write a sequence command for all keys the user defined. */
327f0957ccaSPeter Wemm 	SLIST_FOREACH(qp, sp->gp->seqq, q) {
328b8ba871bSPeter Wemm 		if (stype != qp->stype || !F_ISSET(qp, SEQ_USERDEF))
329b8ba871bSPeter Wemm 			continue;
330b8ba871bSPeter Wemm 		if (prefix)
331b8ba871bSPeter Wemm 			(void)fprintf(fp, "%s", prefix);
332b8ba871bSPeter Wemm 		for (p = qp->input, olen = qp->ilen; olen > 0; --olen) {
333b8ba871bSPeter Wemm 			ch = *p++;
334b8ba871bSPeter Wemm 			if (ch == CH_LITERAL || ch == '|' ||
335f0957ccaSPeter Wemm 			    cmdskip(ch) || KEY_VAL(sp, ch) == K_NL)
336b8ba871bSPeter Wemm 				(void)putc(CH_LITERAL, fp);
337b8ba871bSPeter Wemm 			(void)putc(ch, fp);
338b8ba871bSPeter Wemm 		}
339b8ba871bSPeter Wemm 		(void)putc(' ', fp);
340b8ba871bSPeter Wemm 		if (qp->output != NULL)
341b8ba871bSPeter Wemm 			for (p = qp->output,
342b8ba871bSPeter Wemm 			    olen = qp->olen; olen > 0; --olen) {
343b8ba871bSPeter Wemm 				ch = *p++;
344b8ba871bSPeter Wemm 				if (ch == CH_LITERAL || ch == '|' ||
345b8ba871bSPeter Wemm 				    KEY_VAL(sp, ch) == K_NL)
346b8ba871bSPeter Wemm 					(void)putc(CH_LITERAL, fp);
347b8ba871bSPeter Wemm 				(void)putc(ch, fp);
348b8ba871bSPeter Wemm 			}
349b8ba871bSPeter Wemm 		(void)putc('\n', fp);
350b8ba871bSPeter Wemm 	}
351b8ba871bSPeter Wemm 	return (0);
352b8ba871bSPeter Wemm }
353b8ba871bSPeter Wemm 
354b8ba871bSPeter Wemm /*
355b8ba871bSPeter Wemm  * e_memcmp --
356b8ba871bSPeter Wemm  *	Compare a string of EVENT's to a string of CHAR_T's.
357b8ba871bSPeter Wemm  *
358c271fa92SBaptiste Daroussin  * PUBLIC: int e_memcmp(CHAR_T *, EVENT *, size_t);
359b8ba871bSPeter Wemm  */
360b8ba871bSPeter Wemm int
e_memcmp(CHAR_T * p1,EVENT * ep,size_t n)361*110d525eSBaptiste Daroussin e_memcmp(CHAR_T *p1, EVENT *ep, size_t n)
362b8ba871bSPeter Wemm {
363b8ba871bSPeter Wemm 	if (n != 0) {
364b8ba871bSPeter Wemm 		do {
365b8ba871bSPeter Wemm 			if (*p1++ != ep->e_c)
366b8ba871bSPeter Wemm 				return (*--p1 - ep->e_c);
367b8ba871bSPeter Wemm 			++ep;
368b8ba871bSPeter Wemm 		} while (--n != 0);
369b8ba871bSPeter Wemm 	}
370b8ba871bSPeter Wemm 	return (0);
371b8ba871bSPeter Wemm }
372