1228753Smm/*	$NetBSD: queue.c,v 1.5 2011/08/31 16:24:57 plunky Exp $	*/
2302001Smm
3228753Smm/*-
4228753Smm * SPDX-License-Identifier: BSD-2-Clause
5228753Smm *
6228753Smm * Copyright (c) 1999 James Howard and Dag-Erling Sm��rgrav
7228753Smm * All rights reserved.
8228753Smm * Copyright (c) 2020 Kyle Evans <kevans@FreeBSD.org>
9228753Smm *
10228753Smm * Redistribution and use in source and binary forms, with or without
11228753Smm * modification, are permitted provided that the following conditions
12228753Smm * are met:
13228753Smm * 1. Redistributions of source code must retain the above copyright
14228753Smm *    notice, this list of conditions and the following disclaimer.
15228753Smm * 2. Redistributions in binary form must reproduce the above copyright
16228753Smm *    notice, this list of conditions and the following disclaimer in the
17228753Smm *    documentation and/or other materials provided with the distribution.
18228753Smm *
19228753Smm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20228753Smm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21228753Smm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22228753Smm * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23228753Smm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24228753Smm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25228753Smm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26228753Smm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27228753Smm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28228763Smm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29228753Smm * SUCH DAMAGE.
30228753Smm */
31228753Smm
32228753Smm/*
33232153Smm * A really poor man's queue.  It does only what it has to and gets out of
34232153Smm * Dodge.  It is used in place of <sys/queue.h> to get a better performance.
35232153Smm */
36232153Smm
37232153Smm#include <sys/param.h>
38232153Smm#include <sys/queue.h>
39228753Smm
40228753Smm#include <stdlib.h>
41228753Smm#include <string.h>
42228753Smm
43228753Smm#include "grep.h"
44228753Smm
45232153Smmtypedef struct str		qentry_t;
46232153Smm
47232153Smmstatic long long		filled;
48302001Smmstatic qentry_t			*qend, *qpool;
49302001Smm
50302001Smm/*
51302001Smm * qnext is the next entry to populate.  qlist is where the list actually
52302001Smm * starts, for the purposes of printing.
53302001Smm */
54302001Smmstatic qentry_t		*qlist, *qnext;
55302001Smm
56302001Smmvoid
57302001Smminitqueue(void)
58302001Smm{
59302001Smm
60228753Smm	qlist = qnext = qpool = grep_calloc(Bflag, sizeof(*qpool));
61228753Smm	qend = qpool + (Bflag - 1);
62228753Smm}
63302001Smm
64228753Smmstatic qentry_t *
65228753Smmadvqueue(qentry_t *itemp)
66248616Smm{
67248616Smm
68248616Smm	if (itemp == qend)
69248616Smm		return (qpool);
70302001Smm	return (itemp + 1);
71302001Smm}
72232153Smm
73228753Smm/*
74232153Smm * Enqueue another line; return true if we've dequeued a line as a result
75228753Smm */
76232153Smmbool
77232153Smmenqueue(struct str *x)
78228753Smm{
79228753Smm	qentry_t *item;
80228753Smm	bool rotated;
81228753Smm
82228753Smm	item = qnext;
83228753Smm	qnext = advqueue(qnext);
84228753Smm	rotated = false;
85228753Smm
86228753Smm	if (filled < Bflag) {
87228753Smm		filled++;
88228753Smm	} else if (filled == Bflag) {
89228753Smm		/* We had already filled up coming in; just rotate. */
90228753Smm		qlist = advqueue(qlist);
91228753Smm		rotated = true;
92228753Smm		free(item->dat);
93228753Smm	}
94228753Smm	/* len + 1 for NUL-terminator */
95228753Smm	item->dat = grep_malloc(sizeof(char) * x->len + 1);
96228753Smm	item->len = x->len;
97228753Smm	item->line_no = x->line_no;
98228753Smm	item->boff = x->boff;
99228753Smm	item->off = x->off;
100228753Smm	memcpy(item->dat, x->dat, x->len);
101228753Smm	item->dat[x->len] = '\0';
102228753Smm	item->file = x->file;
103228753Smm
104228753Smm	return (rotated);
105232153Smm}
106228753Smm
107228753Smmvoid
108228753Smmprintqueue(void)
109228753Smm{
110228753Smm	qentry_t *item;
111228753Smm
112228753Smm	item = qlist;
113228753Smm	do {
114228753Smm		/* Buffer must have ended early. */
115228753Smm		if (item->dat == NULL)
116228753Smm			break;
117228753Smm
118228753Smm		grep_printline(item, '-');
119228753Smm		free(item->dat);
120228753Smm		item->dat = NULL;
121228753Smm		item = advqueue(item);
122228753Smm	} while (item != qlist);
123228753Smm
124228753Smm	qlist = qnext = qpool;
125228753Smm	filled = 0;
126228753Smm}
127228753Smm
128228753Smmvoid
129228753Smmclearqueue(void)
130232153Smm{
131228753Smm	qentry_t *item;
132228753Smm
133228753Smm	item = qlist;
134228753Smm	do {
135228753Smm		free(item->dat);
136232153Smm		item->dat = NULL;
137228753Smm		item = advqueue(item);
138228753Smm	} while (item != qlist);
139228753Smm
140228753Smm	qlist = qnext = qpool;
141228753Smm	filled = 0;
142228753Smm}
143328828Smm