common: Minor change of hex2str to allow for embedded nul.
[gnupg.git] / common / strlist.c
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 JNLIB, which is a subsystem of GnuPG.
6  *
7  * JNLIB 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  * JNLIB 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 <http://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 "libjnlib-config.h"
39 #include "strlist.h"
40 #ifdef JNLIB_NEED_UTF8CONV
41 #include "utf8conv.h"
42 #endif
43
44 void
45 free_strlist( strlist_t sl )
46 {
47     strlist_t sl2;
48
49     for(; sl; sl = sl2 ) {
50         sl2 = sl->next;
51         jnlib_free(sl);
52     }
53 }
54
55
56 /* Add STRING to the LIST at the front.  This function terminates the
57    process on memory shortage.  */
58 strlist_t
59 add_to_strlist( strlist_t *list, const char *string )
60 {
61     strlist_t sl;
62
63     sl = jnlib_xmalloc( sizeof *sl + strlen(string));
64     sl->flags = 0;
65     strcpy(sl->d, string);
66     sl->next = *list;
67     *list = sl;
68     return sl;
69 }
70
71
72 /* Add STRING to the LIST at the front.  This function returns NULL
73    and sets ERRNO on memory shortage.  */
74 strlist_t
75 add_to_strlist_try (strlist_t *list, const char *string)
76 {
77   strlist_t sl;
78
79   sl = jnlib_malloc (sizeof *sl + strlen (string));
80   if (sl)
81     {
82       sl->flags = 0;
83       strcpy (sl->d, string);
84       sl->next = *list;
85       *list = sl;
86     }
87   return sl;
88 }
89
90
91 /* Same as add_to_strlist() but if IS_UTF8 is *not* set, a conversion
92    to UTF-8 is done.  This function terminates the process on memory
93    shortage.  */
94 #ifdef JNLIB_NEED_UTF8CONV
95 strlist_t
96 add_to_strlist2( strlist_t *list, const char *string, int is_utf8 )
97 {
98   strlist_t sl;
99
100   if (is_utf8)
101     sl = add_to_strlist( list, string );
102   else
103     {
104       char *p = native_to_utf8( string );
105       sl = add_to_strlist( list, p );
106       jnlib_free ( p );
107     }
108   return sl;
109 }
110 #endif /* JNLIB_NEED_UTF8CONV*/
111
112
113 /* Add STRING to the LIST at the end.  This function terminates the
114    process on memory shortage.  */
115 strlist_t
116 append_to_strlist( strlist_t *list, const char *string )
117 {
118     strlist_t r, sl;
119
120     sl = jnlib_xmalloc( sizeof *sl + strlen(string));
121     sl->flags = 0;
122     strcpy(sl->d, string);
123     sl->next = NULL;
124     if( !*list )
125         *list = sl;
126     else {
127         for( r = *list; r->next; r = r->next )
128             ;
129         r->next = sl;
130     }
131     return sl;
132 }
133
134
135 #ifdef JNLIB_NEED_UTF8CONV
136 strlist_t
137 append_to_strlist2( strlist_t *list, const char *string, int is_utf8 )
138 {
139   strlist_t sl;
140
141   if( is_utf8 )
142     sl = append_to_strlist( list, string );
143   else
144     {
145       char *p = native_to_utf8 (string);
146       sl = append_to_strlist( list, p );
147       jnlib_free( p );
148     }
149   return sl;
150 }
151 #endif /* JNLIB_NEED_UTF8CONV */
152
153
154 /* Return a copy of LIST.  This function terminates the process on
155    memory shortage.*/
156 strlist_t
157 strlist_copy (strlist_t list)
158 {
159   strlist_t newlist = NULL, sl, *last;
160
161   last = &newlist;
162   for (; list; list = list->next)
163     {
164       sl = jnlib_xmalloc (sizeof *sl + strlen (list->d));
165       sl->flags = list->flags;
166       strcpy(sl->d, list->d);
167       sl->next = NULL;
168       *last = sl;
169       last = &sl;
170     }
171   return newlist;
172 }
173
174
175
176 strlist_t
177 strlist_prev( strlist_t head, strlist_t node )
178 {
179     strlist_t n;
180
181     for(n=NULL; head && head != node; head = head->next )
182         n = head;
183     return n;
184 }
185
186 strlist_t
187 strlist_last( strlist_t node )
188 {
189     if( node )
190         for( ; node->next ; node = node->next )
191             ;
192     return node;
193 }
194
195
196 /* Remove the first item from LIST and return its content in an
197    allocated buffer.  This function terminates the process on memory
198    shortage.  */
199 char *
200 strlist_pop (strlist_t *list)
201 {
202   char *str=NULL;
203   strlist_t sl=*list;
204
205   if(sl)
206     {
207       str=jnlib_xmalloc(strlen(sl->d)+1);
208       strcpy(str,sl->d);
209
210       *list=sl->next;
211       jnlib_free(sl);
212     }
213
214   return str;
215 }
216
217 /* Return the first element of the string list HAYSTACK whose string
218    matches NEEDLE.  If no elements match, return NULL.  */
219 strlist_t
220 strlist_find (strlist_t haystack, const char *needle)
221 {
222   for (;
223        haystack;
224        haystack = haystack->next)
225     if (strcmp (haystack->d, needle) == 0)
226       return haystack;
227   return NULL;
228 }