Update copyright to LGPL on all files
[dyninst.git] / parseThat / src / strlist.C
1 /*
2  * Copyright (c) 1996-2009 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * By your use of Paradyn, you understand and agree that we (or any
12  * other person or entity with proprietary rights in Paradyn) are
13  * under no obligation to provide either maintenance services,
14  * update services, notices of latent defects, or correction of
15  * defects for Paradyn.
16  * 
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  * 
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30  */
31 #include <stdlib.h>
32 #include <string.h>
33 #include <ctype.h>
34
35 #include "strlist.h"
36 #include "utils.h"
37
38 strlist *strlist_alloc()
39 {
40     strlist *result = (strlist *)malloc(sizeof(strlist));
41     if (result) memset(result, 0, sizeof(strlist));
42     return result;
43 }
44
45 bool strlist_insert(strlist *list, const char *data)
46 {
47     int result = -1;
48     strlist_elm *prev = NULL;
49     strlist_elm *curr = list->head;
50     strlist_elm *elem;
51
52     while (curr && result < 0) {
53         result = strncmp(curr->data, data, strlen(curr->data));
54         if (result == 0) return true;
55
56         prev = curr;
57         curr = curr->next;
58     }
59
60     elem = (strlist_elm *)malloc(sizeof(strlist_elm));
61     if (!elem) return false;
62
63     elem->data = strdup(data);
64     if (!elem->data) {
65         free(elem);
66         return false;
67     }
68
69     if (!prev) {
70         elem->next = list->head;
71         list->head = elem;
72
73     } else {
74         elem->next = curr;
75         prev->next = elem;
76     }
77
78     if (!curr)
79         list->tail = elem;
80
81     ++list->count;
82     return true;
83 }
84
85 bool strlist_push_front(strlist *list, const char *data)
86 {
87     strlist_elm *elem = (strlist_elm *)malloc(sizeof(strlist_elm));
88     if (!elem) return false;
89
90     elem->data = strdup(data);
91     if (!elem->data) {
92         free(elem);
93         return false;
94     }
95
96     if (!list->head)
97         list->tail = elem;
98
99     elem->next = list->head;
100     list->head = elem;
101
102     ++list->count;
103     return true;
104 }
105
106 bool strlist_pop_front(strlist *list)
107 {
108     strlist_elm *elem = list->head;
109
110     if (!elem) return false;
111
112     list->head = list->head->next;
113     if (list->tail == elem)
114         list->tail = NULL;
115     --list->count;
116
117     free(elem->data);
118     free(elem);
119     return true;
120 }
121
122 bool strlist_push_back(strlist *list, const char *data)
123 {
124     strlist_elm *elem = (strlist_elm *)malloc(sizeof(strlist_elm));
125     if (!elem) return false;
126
127     elem->data = strdup(data);
128     elem->next = NULL;
129     if (!elem->data) {
130         free(elem);
131         return false;
132     }
133
134     if (list->tail) {
135         list->tail->next = elem;
136     } else {
137         list->head = elem;
138     }
139     list->tail = elem;
140
141     ++list->count;
142     return true;
143 }
144
145 bool strlist_pop_back(strlist *list)
146 {
147     strlist_elm *prev = NULL;
148     strlist_elm *curr = list->head;
149
150     while (curr) {
151         prev = curr;
152         curr = curr->next;
153     }
154
155     if (!prev) {
156         list->head = NULL;
157         list->tail = NULL;
158
159     } else {
160         list->tail = prev;
161         prev->next = NULL;
162     }
163     --list->count;
164
165     free(curr->data);
166     free(curr);
167     return true;
168 }
169
170 char *strlist_get(strlist *list, unsigned i)
171 {
172     strlist_elm *curr = list->head;
173     if (i >= list->count) return NULL;
174
175     while (curr && i != 0) {
176         curr = curr->next;
177         --i;
178     }
179     return (curr ? curr->data : NULL);
180 }
181
182 void strlist_clear(strlist *list)
183 {
184     strlist_elm *prev = NULL;
185     strlist_elm *curr = list->head;
186
187     while (curr) {
188         prev = curr;
189         curr = curr->next;
190
191         free(prev->data);
192         free(prev);
193     }
194     memset(list, 0, sizeof(strlist));
195 }
196
197 #include <stdio.h>
198 bool strlist_cmp(strlist *a, strlist *b)
199 {
200     if (a->count != b->count) return false;
201
202     for (unsigned i = 0; i < a->count; ++i)
203         if (0 != strcmp(strlist_get(a, i), strlist_get(b, i)))
204             return false;
205     return true;
206 }
207
208 /* --------------------------------------------------------
209  * Helper functions for file storage of strlists.  Strings
210  * separated by ((char)255).
211  */
212 #define ARG_SEPARATOR ((char)255)
213 strlist char2strlist(char *buf)
214 {
215     char *data = NULL;
216     char *curr = buf;
217     char *next = NULL;
218
219     strlist result = STRLIST_INITIALIZER;
220     while (curr && *curr) {
221         while (isspace(*curr)) ++curr;
222
223         data = decodeStr(curr, &next);
224         if (!strlist_push_back(&result, data)) {
225             strlist_clear(&result);
226             break;
227         }
228         curr = next;
229     }
230     return result;
231 }
232
233 char *strlist2char(strlist *list)
234 {
235     char *data = strlist_get(list, 0);
236
237     data = strcat_static(encodeStr(data), const_cast<char *>(""));
238     for (unsigned i = 1; i < list->count; ++i) {
239       data = strcat_static(data, const_cast<char *>(" "));
240         data = strcat_static(data, encodeStr(strlist_get(list, i)));
241     }
242     return data;
243 }