xref: /freebsd/usr.bin/grep/queue.c (revision 535af610)
1 /*	$NetBSD: queue.c,v 1.5 2011/08/31 16:24:57 plunky Exp $	*/
2 /*	$FreeBSD$	*/
3 
4 /*-
5  * SPDX-License-Identifier: BSD-2-Clause
6  *
7  * Copyright (c) 1999 James Howard and Dag-Erling Coïdan Smørgrav
8  * All rights reserved.
9  * Copyright (c) 2020 Kyle Evans <kevans@FreeBSD.org>
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  */
32 
33 /*
34  * A really poor man's queue.  It does only what it has to and gets out of
35  * Dodge.  It is used in place of <sys/queue.h> to get a better performance.
36  */
37 
38 #include <sys/cdefs.h>
39 __FBSDID("$FreeBSD$");
40 
41 #include <sys/param.h>
42 #include <sys/queue.h>
43 
44 #include <stdlib.h>
45 #include <string.h>
46 
47 #include "grep.h"
48 
49 typedef struct str		qentry_t;
50 
51 static long long		filled;
52 static qentry_t			*qend, *qpool;
53 
54 /*
55  * qnext is the next entry to populate.  qlist is where the list actually
56  * starts, for the purposes of printing.
57  */
58 static qentry_t		*qlist, *qnext;
59 
60 void
61 initqueue(void)
62 {
63 
64 	qlist = qnext = qpool = grep_calloc(Bflag, sizeof(*qpool));
65 	qend = qpool + (Bflag - 1);
66 }
67 
68 static qentry_t *
69 advqueue(qentry_t *itemp)
70 {
71 
72 	if (itemp == qend)
73 		return (qpool);
74 	return (itemp + 1);
75 }
76 
77 /*
78  * Enqueue another line; return true if we've dequeued a line as a result
79  */
80 bool
81 enqueue(struct str *x)
82 {
83 	qentry_t *item;
84 	bool rotated;
85 
86 	item = qnext;
87 	qnext = advqueue(qnext);
88 	rotated = false;
89 
90 	if (filled < Bflag) {
91 		filled++;
92 	} else if (filled == Bflag) {
93 		/* We had already filled up coming in; just rotate. */
94 		qlist = advqueue(qlist);
95 		rotated = true;
96 		free(item->dat);
97 	}
98 	/* len + 1 for NUL-terminator */
99 	item->dat = grep_malloc(sizeof(char) * x->len + 1);
100 	item->len = x->len;
101 	item->line_no = x->line_no;
102 	item->boff = x->boff;
103 	item->off = x->off;
104 	memcpy(item->dat, x->dat, x->len);
105 	item->dat[x->len] = '\0';
106 	item->file = x->file;
107 
108 	return (rotated);
109 }
110 
111 void
112 printqueue(void)
113 {
114 	qentry_t *item;
115 
116 	item = qlist;
117 	do {
118 		/* Buffer must have ended early. */
119 		if (item->dat == NULL)
120 			break;
121 
122 		grep_printline(item, '-');
123 		free(item->dat);
124 		item->dat = NULL;
125 		item = advqueue(item);
126 	} while (item != qlist);
127 
128 	qlist = qnext = qpool;
129 	filled = 0;
130 }
131 
132 void
133 clearqueue(void)
134 {
135 	qentry_t *item;
136 
137 	item = qlist;
138 	do {
139 		free(item->dat);
140 		item->dat = NULL;
141 		item = advqueue(item);
142 	} while (item != qlist);
143 
144 	qlist = qnext = qpool;
145 	filled = 0;
146 }
147