list.c revision b6f2c9cc
1/*
2  Copyright (c) 2002-2003 by Juliusz Chroboczek
3
4  Permission is hereby granted, free of charge, to any person obtaining a copy
5  of this software and associated documentation files (the "Software"), to deal
6  in the Software without restriction, including without limitation the rights
7  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  copies of the Software, and to permit persons to whom the Software is
9  furnished to do so, subject to the following conditions:
10
11  The above copyright notice and this permission notice shall be included in
12  all copies or substantial portions of the Software.
13
14  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20  THE SOFTWARE.
21*/
22
23#include <stdlib.h>
24#include <stdio.h>
25#include <stdarg.h>
26#include <string.h>
27#include "list.h"
28
29#ifdef NEED_SNPRINTF
30#undef SCOPE
31#define SCOPE static
32#include "snprintf.c"
33#endif
34
35int
36listMember(char *elt, ListPtr list)
37{
38    while(list != NULL) {
39        if(strcmp(elt, list->value) == 0)
40            return 1;
41        list = list->next;
42    }
43    return 0;
44}
45
46ListPtr
47listCons(char *car, ListPtr cdr)
48{
49    ListPtr lcar = malloc(sizeof(ListRec));
50    if(!lcar)
51        return NULL;
52    lcar -> value = car;
53    lcar -> next = cdr;
54    return lcar;
55}
56
57ListPtr
58listAdjoin(char *car, ListPtr cdr)
59{
60    if(listMember(car, cdr)) {
61        free(car);
62        return cdr;
63    }
64    return listCons(car, cdr);
65}
66
67char *
68dsprintf(char *f, ...)
69{
70    va_list args;
71    char *string;
72    {
73	int n, size = 20;
74	while(1) {
75	    if(size > 4096)
76		return NULL;
77	    string = malloc(size);
78	    if(!string)
79		return NULL;
80	    va_start(args, f);
81	    n = vsnprintf(string, size, f, args);
82	    va_end(args);
83	    if(n >= 0 && n < size)
84                return string;
85	    else if(n >= size)
86		size = n + 1;
87	    else
88		size = size * 3 / 2 + 1;
89	    free(string);
90	}
91    }
92}
93
94
95ListPtr
96listConsF(ListPtr cdr, char *f, ...)
97{
98    va_list args;
99    char *string;
100    {
101	int n, size = 20;
102	while(1) {
103	    if(size > 4096)
104		return NULL;
105	    string = malloc(size);
106	    if(!string)
107		return NULL;
108	    va_start(args, f);
109	    n = vsnprintf(string, size, f, args);
110	    va_end(args);
111	    if(n >= 0 && n < size)
112		return listCons(string, cdr);
113	    else if(n >= size)
114		size = n + 1;
115	    else
116		size = size * 3 / 2 + 1;
117	    free(string);
118	}
119    }
120}
121
122ListPtr
123listAdjoinF(ListPtr cdr, char *f, ...)
124{
125    va_list args;
126    char *string;
127    {
128	int n, size = 20;
129	while(1) {
130	    if(size > 4096)
131		return NULL;
132	    string = malloc(size);
133	    if(!string)
134		return NULL;
135	    va_start(args, f);
136	    n = vsnprintf(string, size, f, args);
137	    va_end(args);
138	    if(n >= 0 && n < size)
139		return listAdjoin(string, cdr);
140	    else if(n >= size)
141		size = n + 1;
142	    else
143		size = size * 3 / 2 + 1;
144	    free(string);
145	}
146    }
147}
148
149int
150listLength(ListPtr list)
151{
152    int n = 0;
153    while(list) {
154        n++;
155        list = list->next;
156    }
157    return n;
158}
159
160ListPtr
161appendList(ListPtr first, ListPtr second)
162{
163    ListPtr current;
164
165    if(second == NULL)
166        return first;
167
168    if(first == NULL)
169        return second;
170
171    for(current = first; current->next; current = current->next)
172        ;
173
174    current->next = second;
175    return first;
176}
177
178ListPtr
179makeList(char **a, int n, ListPtr old, int begin)
180{
181    ListPtr first, current, next;
182    int i;
183
184    if(n == 0)
185        return old;
186
187    first = malloc(sizeof(ListRec));
188    if(!first)
189        return NULL;
190
191    first->value = a[0];
192    first->next = NULL;
193
194    current = first;
195    for(i = 1; i < n; i++) {
196        next = malloc(sizeof(ListRec));
197        if(!next)
198            return NULL;
199        next->value = a[i];
200        next->next = NULL;
201
202        current->next = next;
203        current = next;
204    }
205    if(begin) {
206        current->next = old;
207        return first;
208    } else {
209        return appendList(old, first);
210    }
211}
212
213ListPtr
214reverseList(ListPtr old)
215{
216    ListPtr new = NULL, current;
217    while(old) {
218        current = old;
219        old = old->next;
220        current->next = new;
221        new = current;
222    }
223    return new;
224}
225
226void
227destroyList(ListPtr old)
228{
229    ListPtr next;
230    if(!old)
231        return;
232    while(old) {
233        next = old->next;
234        free(old);
235        old = next;
236    }
237}
238
239void
240deepDestroyList(ListPtr old)
241{
242    ListPtr next;
243    if(!old)
244        return;
245    while(old) {
246        next = old->next;
247        free(old->value);
248        free(old);
249        old = next;
250    }
251}
252