1 /* GNU gettext - internationalization aids
2 Copyright (C) 1995, 1998, 2000-2004, 2006, 2009, 2015 Free Software
5 This file was written by Peter Miller <millerp@canb.auug.org.au>
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
34 /* Initialize an empty list of strings. */
36 string_list_init (string_list_ty *slp)
44 /* Return a fresh, empty list of strings. */
50 slp = XMALLOC (string_list_ty);
59 /* Append a single string to the end of a list of strings. */
61 string_list_append (string_list_ty *slp, const char *s)
64 if (slp->nitems >= slp->nitems_max)
68 slp->nitems_max = slp->nitems_max * 2 + 4;
69 nbytes = slp->nitems_max * sizeof (slp->item[0]);
70 slp->item = (const char **) xrealloc (slp->item, nbytes);
73 /* Add a copy of the string to the end of the list. */
74 slp->item[slp->nitems++] = xstrdup (s);
78 /* Append a single string to the end of a list of strings, unless it is
79 already contained in the list. */
81 string_list_append_unique (string_list_ty *slp, const char *s)
85 /* Do not if the string is already in the list. */
86 for (j = 0; j < slp->nitems; ++j)
87 if (strcmp (slp->item[j], s) == 0)
91 if (slp->nitems >= slp->nitems_max)
93 slp->nitems_max = slp->nitems_max * 2 + 4;
94 slp->item = (const char **) xrealloc (slp->item,
96 * sizeof (slp->item[0]));
99 /* Add a copy of the string to the end of the list. */
100 slp->item[slp->nitems++] = xstrdup (s);
104 /* Destroy a list of strings. */
106 string_list_destroy (string_list_ty *slp)
110 for (j = 0; j < slp->nitems; ++j)
111 free ((char *) slp->item[j]);
112 if (slp->item != NULL)
117 /* Free a list of strings. */
119 string_list_free (string_list_ty *slp)
123 for (j = 0; j < slp->nitems; ++j)
124 free ((char *) slp->item[j]);
125 if (slp->item != NULL)
131 /* Return a freshly allocated string obtained by concatenating all the
132 strings in the list. */
134 string_list_concat (const string_list_ty *slp)
142 for (j = 0; j < slp->nitems; ++j)
143 len += strlen (slp->item[j]);
144 result = XNMALLOC (len, char);
146 for (j = 0; j < slp->nitems; ++j)
148 len = strlen (slp->item[j]);
149 memcpy (result + pos, slp->item[j], len);
157 /* Return a freshly allocated string obtained by concatenating all the
158 strings in the list, and destroy the list. */
160 string_list_concat_destroy (string_list_ty *slp)
164 /* Optimize the most frequent case. */
165 if (slp->nitems == 1)
167 result = (char *) slp->item[0];
172 result = string_list_concat (slp);
173 string_list_destroy (slp);
179 /* Return a freshly allocated string obtained by concatenating all the
180 strings in the list, separated by the separator string, terminated
181 by the terminator character. The terminator character is not added if
182 drop_redundant_terminator is true and the last string already ends with
185 string_list_join (const string_list_ty *slp, const char *separator,
186 char terminator, bool drop_redundant_terminator)
188 size_t separator_len = strlen (separator);
195 for (j = 0; j < slp->nitems; ++j)
198 len += separator_len;
199 len += strlen (slp->item[j]);
203 result = XNMALLOC (len, char);
205 for (j = 0; j < slp->nitems; ++j)
209 memcpy (result + pos, separator, separator_len);
210 pos += separator_len;
212 len = strlen (slp->item[j]);
213 memcpy (result + pos, slp->item[j], len);
217 && !(drop_redundant_terminator
219 && (len = strlen (slp->item[slp->nitems - 1])) > 0
220 && slp->item[slp->nitems - 1][len - 1] == terminator))
221 result[pos++] = terminator;
227 /* Return 1 if s is contained in the list of strings, 0 otherwise. */
229 string_list_member (const string_list_ty *slp, const char *s)
233 for (j = 0; j < slp->nitems; ++j)
234 if (strcmp (slp->item[j], s) == 0)