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