1 /*-
2  * Copyright (c) 2002 Jordan DeLong
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the author nor the names of contributors may be
14  *    used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29 #include "vhighlight.h"
30 
31 /*
32  * anchors not in use are placed on the free list for reuse to
33  * prevent the need to constantly allocate them.  anchors are
34  * never deallocated, just moved to this list.
35  */
36 static anchorlist_t anchor_freelist = TAILQ_HEAD_INITIALIZER(anchor_freelist);
37 
anchor_get()38 static __inline anchor_t *anchor_get() {
39 	anchor_t *anchor;
40 
41 	anchor = TAILQ_FIRST(&anchor_freelist);
42 	if (!anchor)
43 		return ckmalloc(sizeof(anchor_t));
44 	TAILQ_REMOVE(&anchor_freelist, anchor, a_list);
45 
46 	return anchor;
47 }
48 
anchor_shutdown()49 void anchor_shutdown() {
50 	anchor_t *anchor;
51 
52 	while (!TAILQ_EMPTY(&anchor_freelist)) {
53 		anchor = TAILQ_FIRST(&anchor_freelist);
54 		TAILQ_REMOVE(&anchor_freelist, anchor, a_list);
55 		free(anchor);
56 	}
57 }
58 
anchor_add(anchorlist_t * list,line_t * line,int linenum,synitem_t * state)59 anchor_t *anchor_add(anchorlist_t *list, line_t *line,
60 		int linenum, synitem_t *state) {
61 	anchor_t *anchor;
62 
63 	anchor = anchor_get();
64 	anchor->line = line;
65 	anchor->linenum = linenum;
66 	anchor->state = state;
67 	TAILQ_INSERT_TAIL(list, anchor, a_list);
68 
69 	return anchor;
70 }
71 
72 /* move an anchor to the freelist */
anchor_remove(anchorlist_t * list,anchor_t * anchor)73 void anchor_remove(anchorlist_t *list, anchor_t *anchor) {
74 	TAILQ_REMOVE(list, anchor, a_list);
75 	TAILQ_INSERT_HEAD(&anchor_freelist, anchor, a_list);
76 }
77 
78 /*
79  * find the last anchor before linenum, and remove all the
80  * ones after it (they aren't valid anymore).
81  */
anchor_findlast(anchorlist_t * list,int linenum)82 anchor_t *anchor_findlast(anchorlist_t *list, int linenum) {
83 	anchor_t *anchor;
84 
85 	while (!TAILQ_EMPTY(list)) {
86 		anchor = TAILQ_LAST(list, anchorlist);
87 		if (anchor->linenum <= linenum)
88 			return anchor;
89 		anchor_remove(list, anchor);
90 	}
91 
92 	return NULL;
93 }
94