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