Introductory parseThat commit. - - - - - - - - - - - - - - - - - - - - -
[dyninst.git] / parseThat / src / strlist.C
1 #include <stdlib.h>
2 #include <string.h>
3 #include <ctype.h>
4
5 #include "strlist.h"
6 #include "utils.h"
7
8 strlist *strlist_alloc()
9 {
10     strlist *result = (strlist *)malloc(sizeof(strlist));
11     if (result) memset(result, 0, sizeof(strlist));
12     return result;
13 }
14
15 bool strlist_insert(strlist *list, const char *data)
16 {
17     int result = -1;
18     strlist_elm *prev = NULL;
19     strlist_elm *curr = list->head;
20     strlist_elm *elem;
21
22     while (curr && result < 0) {
23         result = strncmp(curr->data, data, strlen(curr->data));
24         if (result == 0) return true;
25
26         prev = curr;
27         curr = curr->next;
28     }
29
30     elem = (strlist_elm *)malloc(sizeof(strlist_elm));
31     if (!elem) return false;
32
33     elem->data = strdup(data);
34     if (!elem->data) {
35         free(elem);
36         return false;
37     }
38
39     if (!prev) {
40         elem->next = list->head;
41         list->head = elem;
42
43     } else {
44         elem->next = curr;
45         prev->next = elem;
46     }
47
48     if (!curr)
49         list->tail = elem;
50
51     ++list->count;
52     return true;
53 }
54
55 bool strlist_push_front(strlist *list, const char *data)
56 {
57     strlist_elm *elem = (strlist_elm *)malloc(sizeof(strlist_elm));
58     if (!elem) return false;
59
60     elem->data = strdup(data);
61     if (!elem->data) {
62         free(elem);
63         return false;
64     }
65
66     if (!list->head)
67         list->tail = elem;
68
69     elem->next = list->head;
70     list->head = elem;
71
72     ++list->count;
73     return true;
74 }
75
76 bool strlist_pop_front(strlist *list)
77 {
78     strlist_elm *elem = list->head;
79
80     if (!elem) return false;
81
82     list->head = list->head->next;
83     if (list->tail == elem)
84         list->tail = NULL;
85     --list->count;
86
87     free(elem->data);
88     free(elem);
89     return true;
90 }
91
92 bool strlist_push_back(strlist *list, const char *data)
93 {
94     strlist_elm *elem = (strlist_elm *)malloc(sizeof(strlist_elm));
95     if (!elem) return false;
96
97     elem->data = strdup(data);
98     elem->next = NULL;
99     if (!elem->data) {
100         free(elem);
101         return false;
102     }
103
104     if (list->tail) {
105         list->tail->next = elem;
106     } else {
107         list->head = elem;
108     }
109     list->tail = elem;
110
111     ++list->count;
112     return true;
113 }
114
115 bool strlist_pop_back(strlist *list)
116 {
117     strlist_elm *prev = NULL;
118     strlist_elm *curr = list->head;
119
120     while (curr) {
121         prev = curr;
122         curr = curr->next;
123     }
124
125     if (!prev) {
126         list->head = NULL;
127         list->tail = NULL;
128
129     } else {
130         list->tail = prev;
131         prev->next = NULL;
132     }
133     --list->count;
134
135     free(curr->data);
136     free(curr);
137     return true;
138 }
139
140 char *strlist_get(strlist *list, unsigned i)
141 {
142     strlist_elm *curr = list->head;
143     if (i >= list->count) return NULL;
144
145     while (curr && i != 0) {
146         curr = curr->next;
147         --i;
148     }
149     return (curr ? curr->data : NULL);
150 }
151
152 void strlist_clear(strlist *list)
153 {
154     strlist_elm *prev = NULL;
155     strlist_elm *curr = list->head;
156
157     while (curr) {
158         prev = curr;
159         curr = curr->next;
160
161         free(prev->data);
162         free(prev);
163     }
164     memset(list, 0, sizeof(strlist));
165 }
166
167 #include <stdio.h>
168 bool strlist_cmp(strlist *a, strlist *b)
169 {
170     if (a->count != b->count) return false;
171
172     for (unsigned i = 0; i < a->count; ++i)
173         if (0 != strcmp(strlist_get(a, i), strlist_get(b, i)))
174             return false;
175     return true;
176 }
177
178 /* --------------------------------------------------------
179  * Helper functions for file storage of strlists.  Strings
180  * separated by ((char)255).
181  */
182 #define ARG_SEPARATOR ((char)255)
183 strlist char2strlist(char *buf)
184 {
185     char *data = NULL;
186     char *curr = buf;
187     char *next = NULL;
188
189     strlist result = STRLIST_INITIALIZER;
190     while (curr && *curr) {
191         while (isspace(*curr)) ++curr;
192
193         data = decodeStr(curr, &next);
194         if (!strlist_push_back(&result, data)) {
195             strlist_clear(&result);
196             break;
197         }
198         curr = next;
199     }
200     return result;
201 }
202
203 char *strlist2char(strlist *list, char *buf)
204 {
205     char *data = strlist_get(list, 0);
206
207     strcpy(buf, encodeStr(data));
208     for (unsigned i = 1; i < list->count; ++i) {
209         strcat(buf, " ");
210         data = strlist_get(list, i);
211         strcat(buf, encodeStr(data));
212     }
213     return buf;
214 }