]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.bin/grep/queue.c
contrib/tzdata: import tzdata 2022f
[FreeBSD/FreeBSD.git] / usr.bin / grep / queue.c
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-FreeBSD
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 }