xref: /Universal-ctags/main/strlist.c (revision 3956588487124ab9933aeace4e3b212c3b28785b)
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