Line data Source code
1 : /* strlist.c - string helpers
2 : * Copyright (C) 1998, 2000, 2001, 2006 Free Software Foundation, Inc.
3 : * Copyright (C) 2015 g10 Code GmbH
4 : *
5 : * This file is part of GnuPG.
6 : *
7 : * GnuPG is free software; you can redistribute it and/or modify it
8 : * under the terms of either
9 : *
10 : * - the GNU Lesser General Public License as published by the Free
11 : * Software Foundation; either version 3 of the License, or (at
12 : * your option) any later version.
13 : *
14 : * or
15 : *
16 : * - the GNU General Public License as published by the Free
17 : * Software Foundation; either version 2 of the License, or (at
18 : * your option) any later version.
19 : *
20 : * or both in parallel, as here.
21 : *
22 : * GnuPG is distributed in the hope that it will be useful, but
23 : * WITHOUT ANY WARRANTY; without even the implied warranty of
24 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 : * General Public License for more details.
26 : *
27 : * You should have received a copies of the GNU General Public License
28 : * and the GNU Lesser General Public License along with this program;
29 : * if not, see <https://www.gnu.org/licenses/>.
30 : */
31 :
32 : #include <config.h>
33 : #include <stdlib.h>
34 : #include <string.h>
35 : #include <stdarg.h>
36 : #include <ctype.h>
37 :
38 : #include "util.h"
39 : #include "common-defs.h"
40 : #include "strlist.h"
41 : #include "utf8conv.h"
42 : #include "mischelp.h"
43 :
44 : void
45 7563 : free_strlist( strlist_t sl )
46 : {
47 : strlist_t sl2;
48 :
49 10126 : for(; sl; sl = sl2 ) {
50 2563 : sl2 = sl->next;
51 2563 : xfree(sl);
52 : }
53 7563 : }
54 :
55 :
56 : void
57 44 : free_strlist_wipe (strlist_t sl)
58 : {
59 : strlist_t sl2;
60 :
61 140 : for(; sl; sl = sl2 ) {
62 96 : sl2 = sl->next;
63 96 : wipememory (sl, sizeof *sl + strlen (sl->d));
64 96 : xfree(sl);
65 : }
66 44 : }
67 :
68 :
69 : /* Add STRING to the LIST at the front. This function terminates the
70 : process on memory shortage. */
71 : strlist_t
72 2428 : add_to_strlist( strlist_t *list, const char *string )
73 : {
74 : strlist_t sl;
75 :
76 2428 : sl = xmalloc( sizeof *sl + strlen(string));
77 2428 : sl->flags = 0;
78 2428 : strcpy(sl->d, string);
79 2428 : sl->next = *list;
80 2428 : *list = sl;
81 2428 : return sl;
82 : }
83 :
84 :
85 : /* Add STRING to the LIST at the front. This function returns NULL
86 : and sets ERRNO on memory shortage. */
87 : strlist_t
88 0 : add_to_strlist_try (strlist_t *list, const char *string)
89 : {
90 : strlist_t sl;
91 :
92 0 : sl = xtrymalloc (sizeof *sl + strlen (string));
93 0 : if (sl)
94 : {
95 0 : sl->flags = 0;
96 0 : strcpy (sl->d, string);
97 0 : sl->next = *list;
98 0 : *list = sl;
99 : }
100 0 : return sl;
101 : }
102 :
103 :
104 : /* Same as add_to_strlist() but if IS_UTF8 is *not* set, a conversion
105 : to UTF-8 is done. This function terminates the process on memory
106 : shortage. */
107 : strlist_t
108 541 : add_to_strlist2( strlist_t *list, const char *string, int is_utf8 )
109 : {
110 : strlist_t sl;
111 :
112 541 : if (is_utf8)
113 3 : sl = add_to_strlist( list, string );
114 : else
115 : {
116 538 : char *p = native_to_utf8( string );
117 538 : sl = add_to_strlist( list, p );
118 538 : xfree ( p );
119 : }
120 541 : return sl;
121 : }
122 :
123 :
124 : /* Add STRING to the LIST at the end. This function terminates the
125 : process on memory shortage. */
126 : strlist_t
127 73 : append_to_strlist( strlist_t *list, const char *string )
128 : {
129 : strlist_t sl;
130 73 : sl = append_to_strlist_try (list, string);
131 73 : if (!sl)
132 0 : xoutofcore ();
133 73 : return sl;
134 : }
135 :
136 :
137 : /* Add STRING to the LIST at the end. */
138 : strlist_t
139 227 : append_to_strlist_try (strlist_t *list, const char *string)
140 : {
141 : strlist_t r, sl;
142 :
143 227 : sl = xtrymalloc( sizeof *sl + strlen(string));
144 227 : if (sl == NULL)
145 0 : return NULL;
146 :
147 227 : sl->flags = 0;
148 227 : strcpy(sl->d, string);
149 227 : sl->next = NULL;
150 227 : if( !*list )
151 123 : *list = sl;
152 : else {
153 104 : for( r = *list; r->next; r = r->next )
154 : ;
155 104 : r->next = sl;
156 : }
157 227 : return sl;
158 : }
159 :
160 :
161 : strlist_t
162 6 : append_to_strlist2( strlist_t *list, const char *string, int is_utf8 )
163 : {
164 : strlist_t sl;
165 :
166 6 : if( is_utf8 )
167 0 : sl = append_to_strlist( list, string );
168 : else
169 : {
170 6 : char *p = native_to_utf8 (string);
171 6 : sl = append_to_strlist( list, p );
172 6 : xfree( p );
173 : }
174 6 : return sl;
175 : }
176 :
177 :
178 : /* Return a copy of LIST. This function terminates the process on
179 : memory shortage.*/
180 : strlist_t
181 0 : strlist_copy (strlist_t list)
182 : {
183 0 : strlist_t newlist = NULL, sl, *last;
184 :
185 0 : last = &newlist;
186 0 : for (; list; list = list->next)
187 : {
188 0 : sl = xmalloc (sizeof *sl + strlen (list->d));
189 0 : sl->flags = list->flags;
190 0 : strcpy(sl->d, list->d);
191 0 : sl->next = NULL;
192 0 : *last = sl;
193 0 : last = &sl;
194 : }
195 0 : return newlist;
196 : }
197 :
198 :
199 :
200 : strlist_t
201 14 : strlist_prev( strlist_t head, strlist_t node )
202 : {
203 : strlist_t n;
204 :
205 56 : for(n=NULL; head && head != node; head = head->next )
206 42 : n = head;
207 14 : return n;
208 : }
209 :
210 : strlist_t
211 12 : strlist_last( strlist_t node )
212 : {
213 12 : if( node )
214 12 : for( ; node->next ; node = node->next )
215 : ;
216 12 : return node;
217 : }
218 :
219 :
220 : /* Remove the first item from LIST and return its content in an
221 : allocated buffer. This function terminates the process on memory
222 : shortage. */
223 : char *
224 0 : strlist_pop (strlist_t *list)
225 : {
226 0 : char *str=NULL;
227 0 : strlist_t sl=*list;
228 :
229 0 : if(sl)
230 : {
231 0 : str = xmalloc(strlen(sl->d)+1);
232 0 : strcpy(str,sl->d);
233 :
234 0 : *list=sl->next;
235 0 : xfree(sl);
236 : }
237 :
238 0 : return str;
239 : }
240 :
241 : /* Return the first element of the string list HAYSTACK whose string
242 : matches NEEDLE. If no elements match, return NULL. */
243 : strlist_t
244 0 : strlist_find (strlist_t haystack, const char *needle)
245 : {
246 0 : for (;
247 : haystack;
248 0 : haystack = haystack->next)
249 0 : if (strcmp (haystack->d, needle) == 0)
250 0 : return haystack;
251 0 : return NULL;
252 : }
253 :
254 : int
255 663 : strlist_length (strlist_t list)
256 : {
257 : int i;
258 2480 : for (i = 0; list; list = list->next)
259 1817 : i ++;
260 :
261 663 : return i;
262 : }
263 :
264 : /* Reverse the list *LIST in place. */
265 : strlist_t
266 183 : strlist_rev (strlist_t *list)
267 : {
268 183 : strlist_t l = *list;
269 183 : strlist_t lrev = NULL;
270 :
271 558 : while (l)
272 : {
273 192 : strlist_t tail = l->next;
274 192 : l->next = lrev;
275 192 : lrev = l;
276 192 : l = tail;
277 : }
278 :
279 183 : *list = lrev;
280 183 : return lrev;
281 : }
|