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