1 /*
2 * Copyright (c) 1999-2002, Darren Hiebert
3 *
4 * This source code is released for free distribution under the terms of the
5 * GNU General Public License version 2 or (at your option) any later version.
6 *
7 * This module contains functions managing resizable string lists.
8 */
9
10 /*
11 * INCLUDE FILES
12 */
13 #include "general.h" /* must always come first */
14
15 #include <string.h>
16 #include <fnmatch.h>
17
18 #include "debug.h"
19 #include "read.h"
20 #include "routines.h"
21 #include "strlist.h"
22
23 /*
24 * FUNCTION DEFINITIONS
25 */
26
stringListNew(void)27 extern stringList *stringListNew (void)
28 {
29 return ptrArrayNew ((ptrArrayDeleteFunc)vStringDelete);
30 }
31
stringListAdd(stringList * const current,vString * string)32 extern void stringListAdd (stringList *const current, vString *string)
33 {
34 ptrArrayAdd (current, string);
35 }
36
stringListRemoveLast(stringList * const current)37 extern void stringListRemoveLast (stringList *const current)
38 {
39 ptrArrayRemoveLast (current);
40 }
41
42 /* Combine list `from' into `current', deleting `from' */
stringListCombine(stringList * const current,stringList * const from)43 extern void stringListCombine (
44 stringList *const current, stringList *const from)
45 {
46 ptrArrayCombine (current, from);
47 }
48
stringListNewFromArgv(const char * const * const argv)49 extern stringList* stringListNewFromArgv (const char* const* const argv)
50 {
51 stringList* const result = stringListNew ();
52 const char *const *p;
53 Assert (argv != NULL);
54 for (p = argv ; *p != NULL ; ++p)
55 stringListAdd (result, vStringNewInit (*p));
56 return result;
57 }
58
stringListNewFromFile(const char * const fileName)59 extern stringList* stringListNewFromFile (const char* const fileName)
60 {
61 stringList* result = NULL;
62 MIO* const mio = mio_new_file (fileName, "r");
63 if (mio != NULL)
64 {
65 result = stringListNew ();
66 while (! mio_eof (mio))
67 {
68 vString* const str = vStringNew ();
69 readLineRaw (str, mio);
70 vStringStripTrailing (str);
71 if (vStringLength (str) > 0)
72 stringListAdd (result, str);
73 else
74 vStringDelete (str);
75 }
76 mio_unref (mio);
77 }
78 return result;
79 }
80
stringListCount(const stringList * const current)81 extern unsigned int stringListCount (const stringList *const current)
82 {
83 return ptrArrayCount (current);
84 }
85
stringListItem(const stringList * const current,const unsigned int indx)86 extern vString* stringListItem (
87 const stringList *const current, const unsigned int indx)
88 {
89 return ptrArrayItem (current, indx);
90 }
91
stringListLast(const stringList * const current)92 extern vString* stringListLast (const stringList *const current)
93 {
94 return ptrArrayLast (current);
95 }
96
stringListClear(stringList * const current)97 extern void stringListClear (stringList *const current)
98 {
99 ptrArrayClear (current);
100 }
101
stringListDelete(stringList * const current)102 extern void stringListDelete (stringList *const current)
103 {
104 ptrArrayDelete (current);
105 }
106
compareString(const char * const string,vString * const itm)107 static bool compareString (
108 const char *const string, vString *const itm)
109 {
110 return (strcmp (string, vStringValue (itm)) == 0);
111 }
112
compareStringInsensitive(const char * const string,vString * const itm)113 static bool compareStringInsensitive (
114 const char *const string, vString *const itm)
115 {
116 return (strcasecmp (string, vStringValue (itm)) == 0);
117 }
118
stringListIndex(const stringList * const current,const char * const string,bool (* test)(const char * s,vString * const vs))119 static int stringListIndex (
120 const stringList *const current,
121 const char *const string,
122 bool (*test)(const char *s, vString *const vs))
123 {
124 int result = -1;
125 unsigned int i;
126 Assert (current != NULL);
127 Assert (string != NULL);
128 Assert (test != NULL);
129 for (i = 0 ; result == -1 && i < ptrArrayCount (current) ; ++i)
130 if ((*test)(string, ptrArrayItem (current, i)))
131 result = i;
132 return result;
133 }
134
stringListHas(const stringList * const current,const char * const string)135 extern bool stringListHas (
136 const stringList *const current, const char *const string)
137 {
138 bool result;
139 Assert (current != NULL);
140 result = stringListIndex (current, string, compareString) != -1;
141 return result;
142 }
143
stringListFinds(const stringList * const current,const char * const string,bool (* test)(const char * s,vString * const vs))144 static vString* stringListFinds (
145 const stringList *const current, const char *const string,
146 bool (*test)(const char *s, vString *const vs))
147 {
148 int i;
149
150 Assert (current != NULL);
151 Assert (string != NULL);
152
153 i = stringListIndex (current, string, test);
154 if (i == -1)
155 return NULL;
156 else
157 return stringListItem(current, i);
158 }
159
stringListHasInsensitive(const stringList * const current,const char * const string)160 extern bool stringListHasInsensitive (
161 const stringList *const current, const char *const string)
162 {
163 bool result;
164 Assert (current != NULL);
165 Assert (string != NULL);
166 result = stringListIndex (current, string, compareStringInsensitive) != -1;
167 return result;
168 }
169
stringListHasTest(const stringList * const current,bool (* test)(const char * s,void * userData),void * userData)170 extern bool stringListHasTest (const stringList *const current,
171 bool (*test)(const char *s, void *userData),
172 void *userData)
173 {
174 bool result = false;
175 unsigned int i;
176 Assert (current != NULL);
177 for (i = 0 ; ! result && i < ptrArrayCount (current) ; ++i)
178 result = (*test)(vStringValue ((vString *)ptrArrayItem (current, i)), userData);
179 return result;
180 }
181
stringListDeleteItemExtension(stringList * const current,const char * const extension)182 extern bool stringListDeleteItemExtension (stringList* const current, const char* const extension)
183 {
184 int where;
185 #ifdef CASE_INSENSITIVE_FILENAMES
186 where = stringListIndex (current, extension, compareStringInsensitive);
187 #else
188 where = stringListIndex (current, extension, compareString);
189 #endif
190 if (where != -1)
191 ptrArrayDeleteItem (current, where);
192 return where != -1;
193 }
194
stringListExtensionMatched(const stringList * const current,const char * const extension)195 extern bool stringListExtensionMatched (
196 const stringList* const current, const char* const extension)
197 {
198 #ifdef CASE_INSENSITIVE_FILENAMES
199 return stringListHasInsensitive (current, extension);
200 #else
201 return stringListHas (current, extension);
202 #endif
203 }
204
stringListExtensionFinds(const stringList * const current,const char * const extension)205 extern vString* stringListExtensionFinds (
206 const stringList* const current, const char* const extension)
207 {
208 #ifdef CASE_INSENSITIVE_FILENAMES
209 return stringListFinds (current, extension, compareStringInsensitive);
210 #else
211 return stringListFinds (current, extension, compareString);
212 #endif
213 }
214
stringListCaseMatched(const stringList * const list,const char * const str)215 extern bool stringListCaseMatched (const stringList* const list, const char* const str)
216 {
217 return stringListCaseFinds(list, str)? true: false;
218 }
219
stringListCaseFinds(const stringList * const list,const char * const str)220 extern vString* stringListCaseFinds (const stringList* const list, const char* const str)
221 {
222 return stringListFinds (list, str, compareStringInsensitive);
223 }
224
fileNameMatched(const vString * const vpattern,const char * const fileName)225 static bool fileNameMatched (
226 const vString* const vpattern, const char* const fileName)
227 {
228 const char* const pattern = vStringValue (vpattern);
229
230 #ifdef CASE_INSENSITIVE_FILENAMES
231 {
232 char* const p = newUpperString (pattern);
233 char* const f = newUpperString (fileName);
234 bool r = (fnmatch (p, f, 0) == 0);
235 eFree (f);
236 eFree (p);
237 return r;
238 }
239 #else
240 return (fnmatch (pattern, fileName, 0) == 0);
241 #endif
242 }
243
stringListFileMatched(const stringList * const current,const char * const fileName)244 extern bool stringListFileMatched (
245 const stringList* const current, const char* const fileName)
246 {
247 return stringListFileFinds (current, fileName)? true: false;
248 }
249
stringListFileFinds(const stringList * const current,const char * const fileName)250 extern vString* stringListFileFinds (
251 const stringList* const current, const char* const fileName)
252 {
253 vString* vstr = NULL;
254 bool matched = false;
255 unsigned int i;
256 const char * normalized = fileName;
257
258 #if defined (WIN32)
259 vString *tmp = vStringNewInit (fileName);
260 vStringTranslate (tmp, PATH_SEPARATOR, OUTPUT_PATH_SEPARATOR);
261 normalized = vStringValue (tmp);
262 #endif
263
264 for (i = 0 ; ! matched && i < stringListCount (current) ; ++i)
265 {
266 vstr = stringListItem (current, i);
267 matched = fileNameMatched (vstr, normalized);
268 }
269
270 #if defined (WIN32)
271 vStringDelete (tmp);
272 #endif
273
274 return matched? vstr: NULL;
275 }
276
stringListPrint(const stringList * const current,FILE * fp)277 extern void stringListPrint (const stringList *const current, FILE *fp)
278 {
279 unsigned int i;
280 Assert (current != NULL);
281 for (i = 0 ; i < ptrArrayCount (current) ; ++i)
282 fprintf (fp, "%s%s", (i > 0) ? ", " : "", vStringValue ((vString *)ptrArrayItem (current, i)));
283 }
284
stringListReverse(const stringList * const current)285 extern void stringListReverse (const stringList *const current)
286 {
287 ptrArrayReverse (current);
288 }
289