1 /* $Id: textlist.c,v 1.6 2003/04/07 16:27:11 ukai Exp $ */
2 #include "textlist.h"
3 #include "indep.h"
4 #include "Str.h"
5 #include <gc.h>
6 
7 /* General doubly linked list */
8 
9 ListItem *
newListItem(void * s,ListItem * n,ListItem * p)10 newListItem(void *s, ListItem *n, ListItem *p)
11 {
12     ListItem *it;
13     it = New(ListItem);
14     it->ptr = s;
15     it->next = n;
16     it->prev = p;
17     return it;
18 }
19 
20 GeneralList *
newGeneralList()21 newGeneralList()
22 {
23     GeneralList *tl = New(GeneralList);
24     tl->first = tl->last = NULL;
25     tl->nitem = 0;
26     return tl;
27 }
28 
29 void
pushValue(GeneralList * tl,void * s)30 pushValue(GeneralList *tl, void *s)
31 {
32     ListItem *it;
33     if (s == NULL || tl == NULL || tl->nitem >= GENERAL_LIST_MAX)
34 	return;
35     it = newListItem(s, NULL, tl->last);
36     if (tl->first == NULL) {
37 	tl->first = it;
38 	tl->last = it;
39 	tl->nitem = 1;
40     }
41     else {
42 	tl->last->next = it;
43 	tl->last = it;
44 	tl->nitem++;
45     }
46 }
47 
48 void *
popValue(GeneralList * tl)49 popValue(GeneralList *tl)
50 {
51     ListItem *f;
52 
53     if (tl == NULL || tl->first == NULL)
54 	return NULL;
55     f = tl->first;
56     tl->first = f->next;
57     if (tl->first)
58 	tl->first->prev = NULL;
59     else
60 	tl->last = NULL;
61     tl->nitem--;
62     return f->ptr;
63 }
64 
65 void *
rpopValue(GeneralList * tl)66 rpopValue(GeneralList *tl)
67 {
68     ListItem *f;
69 
70     if (tl == NULL || tl->last == NULL)
71 	return NULL;
72     f = tl->last;
73     tl->last = f->prev;
74     if (tl->last)
75 	tl->last->next = NULL;
76     else
77 	tl->first = NULL;
78     tl->nitem--;
79     return f->ptr;
80 }
81 
82 void
delValue(GeneralList * tl,ListItem * it)83 delValue(GeneralList *tl, ListItem *it)
84 {
85     if (it->prev)
86 	it->prev->next = it->next;
87     else
88 	tl->first = it->next;
89     if (it->next)
90 	it->next->prev = it->prev;
91     else
92 	tl->last = it->prev;
93     tl->nitem--;
94 }
95 
96 GeneralList *
appendGeneralList(GeneralList * tl,GeneralList * tl2)97 appendGeneralList(GeneralList *tl, GeneralList *tl2)
98 {
99     if (tl && tl2) {
100 	if (tl2->first) {
101 	    if (tl->last) {
102 		if (tl->nitem + tl2->nitem > GENERAL_LIST_MAX) {
103 		    return tl;
104 		}
105 		tl->last->next = tl2->first;
106 		tl2->first->prev = tl->last;
107 		tl->last = tl2->last;
108 		tl->nitem += tl2->nitem;
109 	    }
110 	    else {
111 		tl->first = tl2->first;
112 		tl->last = tl2->last;
113 		tl->nitem = tl2->nitem;
114 	    }
115 	}
116 	tl2->first = tl2->last = NULL;
117 	tl2->nitem = 0;
118     }
119 
120     return tl;
121 }
122 
123 
124 /* Line text list */
125 
126 TextLine *
newTextLine(Str line,int pos)127 newTextLine(Str line, int pos)
128 {
129     TextLine *lbuf = New(TextLine);
130     if (line)
131 	lbuf->line = line;
132     else
133 	lbuf->line = Strnew();
134     lbuf->pos = pos;
135     return lbuf;
136 }
137 
138 void
appendTextLine(TextLineList * tl,Str line,int pos)139 appendTextLine(TextLineList *tl, Str line, int pos)
140 {
141     TextLine *lbuf;
142 
143     if (tl->last == NULL) {
144 	pushTextLine(tl, newTextLine(Strdup(line), pos));
145     }
146     else {
147 	lbuf = tl->last->ptr;
148 	if (lbuf->line)
149 	    Strcat(lbuf->line, line);
150 	else
151 	    lbuf->line = line;
152 	lbuf->pos += pos;
153     }
154 }
155