1 /***************************************************************************
2 JSPICE3 adaptation of Spice3e2 - Copyright (c) Stephen R. Whiteley 1992
3 Copyright 1990 Regents of the University of California. All rights reserved.
4 Authors: 1987 Wayne A. Christopher
5 1992 Stephen R. Whiteley
6 ****************************************************************************/
7
8 /*
9 * Wordlist manipulation stuff.
10 */
11
12 #include "spice.h"
13 #include "cpstd.h"
14 #include "suffix.h"
15
16 #ifdef __STDC__
17 static int wlcomp(char**,char**);
18 #else
19 static int wlcomp();
20 #endif
21
22 /***************************************************************************/
23 /* Determine the length of a word list. */
24
25 int
wl_length(wlist)26 wl_length(wlist)
27
28 wordlist *wlist;
29 {
30 register int i = 0;
31 register wordlist *wl;
32
33 for (wl = wlist; wl; wl = wl->wl_next)
34 i++;
35 return (i);
36 }
37
38
39 /***************************************************************************/
40 /* Free the storage used by a word list. */
41
42 void
wl_free(wlist)43 wl_free(wlist)
44
45 wordlist *wlist;
46 {
47 wordlist *wl, *nw;
48
49 for (wl = wlist; wl; wl = nw) {
50 nw = wl->wl_next;
51 tfree(wl->wl_word);
52 tfree(wl);
53 }
54 return;
55 }
56
57
58 /***************************************************************************/
59 /* Copy a wordlist and the words. */
60
61 wordlist *
wl_copy(wlist)62 wl_copy(wlist)
63
64 wordlist *wlist;
65 {
66 register wordlist *wl, *nwl = NULL, *w;
67
68 for (wl = wlist; wl; wl = wl->wl_next) {
69 if (nwl == NULL) {
70 nwl = w = alloc(struct wordlist);
71 }
72 else {
73 w->wl_next = alloc(struct wordlist);
74 w->wl_next->wl_prev = w;
75 w = w->wl_next;
76 }
77 w->wl_word = copy(wl->wl_word);
78 }
79 return (nwl);
80 }
81
82
83 /***************************************************************************/
84 /* Substitute a wordlist for one element of a wordlist, and return a pointer
85 * to the last element of the inserted list.
86 */
87
88 wordlist *
wl_splice(elt,list)89 wl_splice(elt, list)
90
91 wordlist *elt, *list;
92 {
93 if (list)
94 list->wl_prev = elt->wl_prev;
95 if (elt->wl_prev)
96 elt->wl_prev->wl_next = list;
97 if (list) {
98 while (list->wl_next)
99 list = list->wl_next;
100 list->wl_next = elt->wl_next;
101 }
102 if (elt->wl_next)
103 elt->wl_next->wl_prev = list;
104 tfree(elt->wl_word);
105 tfree(elt);
106 return (list);
107 }
108
109
110 /***************************************************************************/
111 /* Print a word list. (No \n at the end...) */
112
113 void
wl_print(wlist,fp)114 wl_print(wlist, fp)
115
116 wordlist *wlist;
117 FILE *fp;
118 {
119 wordlist *wl;
120
121 for (wl = wlist; wl; wl = wl->wl_next) {
122 cp_printword(wl->wl_word, fp);
123 if (wl->wl_next)
124 (void) putc(' ', fp);
125 }
126 return;
127 }
128
129
130 /***************************************************************************/
131 /* Turn an array of char *'s into a wordlist. */
132
133 wordlist *
wl_build(v)134 wl_build(v)
135
136 char *v[];
137 {
138 wordlist *wlist, *wl = NULL, *cwl;
139
140 while (*v) {
141 cwl = alloc(struct wordlist);
142 cwl->wl_prev = wl;
143 if (wl)
144 wl->wl_next = cwl;
145 else
146 wlist = cwl;
147 cwl->wl_word = copy(*v);
148 wl = cwl;
149 v++;
150 }
151 return (wlist);
152 }
153
154
155 /***************************************************************************/
156 /* Turn a wordlist into an array of char *'s */
157
158 char **
wl_mkvec(wl)159 wl_mkvec(wl)
160
161 wordlist *wl;
162 {
163 int len, i;
164 char **v;
165
166 len = wl_length(wl);
167 v = (char **) tmalloc((len + 1) * sizeof (char **));
168 for (i = 0; i < len; i++) {
169 v[i] = copy(wl->wl_word);
170 wl = wl->wl_next;
171 }
172 v[i] = NULL;
173 return (v);
174 }
175
176
177 /***************************************************************************/
178 /* Link two wordlists together. */
179
180 wordlist *
wl_append(wlist,nwl)181 wl_append(wlist, nwl)
182
183 wordlist *wlist, *nwl;
184 {
185 wordlist *wl;
186 if (wlist == NULL)
187 return (nwl);
188 if (nwl == NULL)
189 return (wlist);
190 for (wl = wlist; wl->wl_next; wl = wl->wl_next);
191 wl->wl_next = nwl;
192 nwl->wl_prev = wl;
193 return (wlist);
194 }
195
196
197 /***************************************************************************/
198 /* Reverse a word list. */
199
200 wordlist *
wl_reverse(wl)201 wl_reverse(wl)
202
203 wordlist *wl;
204 {
205 wordlist *w, *t;
206
207 for (w = wl; ; w = t) {
208 t = w->wl_next;
209 w->wl_next = w->wl_prev;
210 w->wl_prev = t;
211 if (t == NULL)
212 break;
213 }
214 return (w);
215 }
216
217
218 /***************************************************************************/
219 /* Convert a wordlist into a string. */
220
221 char *
wl_flatten(wl)222 wl_flatten(wl)
223 wordlist *wl;
224 {
225 char *buf;
226 wordlist *tw;
227 int i = 0;
228
229 for (tw = wl; tw; tw = tw->wl_next)
230 i += strlen(tw->wl_word) + 1;
231 buf = tmalloc(i + 1);
232
233 while (wl != NULL) {
234 (void) strcat(buf, wl->wl_word);
235 if (wl->wl_next)
236 (void) strcat(buf, " ");
237 wl = wl->wl_next;
238 }
239 return (buf);
240 }
241
242
243 /***************************************************************************/
244 /* Return the nth element of a wordlist, or the last one if n is too big.
245 * Numbering starts at 0...
246 */
247
248 wordlist *
wl_nthelem(i,wl)249 wl_nthelem(i, wl)
250
251 wordlist *wl;
252 register int i;
253 {
254 register wordlist *ww = wl;
255
256 while ((i-- > 0) && ww->wl_next)
257 ww = ww->wl_next;
258 return (ww);
259 }
260
261
262 /***************************************************************************/
263 /* Sort a wordlist */
264
265 void
wl_sort(wl)266 wl_sort(wl)
267
268 wordlist *wl;
269 {
270 register int i = 0;
271 register wordlist *ww = wl;
272 char **stuff;
273
274 for (i = 0; ww; i++)
275 ww = ww->wl_next;
276 if (i < 2)
277 return;
278 stuff = (char **) tmalloc(i * sizeof (char *));
279 for (i = 0, ww = wl; ww; i++, ww = ww->wl_next)
280 stuff[i] = ww->wl_word;
281 qsort((char *) stuff, i, sizeof (char *),
282 #ifdef __STDC__
283 (int(*)(const void*,const void*))wlcomp);
284 #else
285 wlcomp);
286 #endif
287 for (i = 0, ww = wl; ww; i++, ww = ww->wl_next)
288 ww->wl_word = stuff[i];
289 tfree(stuff);
290 return;
291 }
292
293
294 static int
wlcomp(s,t)295 wlcomp(s, t)
296
297 char **s, **t;
298 {
299 return (strcmp(*s, *t));
300 }
301
302
303 /***************************************************************************/
304 /* Return a range of wordlist elements... */
305
306 wordlist *
wl_range(wl,low,up)307 wl_range(wl, low, up)
308
309 wordlist *wl;
310 int low, up;
311 {
312 int i;
313 wordlist *tt;
314 bool rev = false;
315
316 if (low > up) {
317 i = up;
318 up = low;
319 low = i;
320 rev = true;
321 }
322 up -= low;
323 while (wl && (low > 0)) {
324 tt = wl->wl_next;
325 tfree(wl->wl_word);
326 tfree(wl);
327 wl = tt;
328 if (wl)
329 wl->wl_prev = NULL;
330 low--;
331 }
332 tt = wl;
333 while (tt && (up > 0)) {
334 tt = tt->wl_next;
335 up--;
336 }
337 if (tt && tt->wl_next) {
338 wl_free(tt->wl_next);
339 tt->wl_next = NULL;
340 }
341 if (rev)
342 wl = wl_reverse(wl);
343 return (wl);
344 }
345
346