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