• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500-V1.0.1.40_1.0.68/ap/gpl/timemachine/gettext-0.17/gettext-tools/src/
1/* GNU gettext - internationalization aids
2   Copyright (C) 1995, 1998, 2000-2004, 2006 Free Software Foundation, Inc.
3
4   This file was written by Peter Miller <millerp@canb.auug.org.au>
5
6   This program is free software: you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 3 of the License, or
9   (at your option) any later version.
10
11   This program is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
18
19#ifdef HAVE_CONFIG_H
20# include "config.h"
21#endif
22
23/* Specification.  */
24#include "str-list.h"
25
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29
30#include "xalloc.h"
31
32
33/* Initialize an empty list of strings.  */
34void
35string_list_init (string_list_ty *slp)
36{
37  slp->item = NULL;
38  slp->nitems = 0;
39  slp->nitems_max = 0;
40}
41
42
43/* Return a fresh, empty list of strings.  */
44string_list_ty *
45string_list_alloc ()
46{
47  string_list_ty *slp;
48
49  slp = XMALLOC (string_list_ty);
50  slp->item = NULL;
51  slp->nitems = 0;
52  slp->nitems_max = 0;
53
54  return slp;
55}
56
57
58/* Append a single string to the end of a list of strings.  */
59void
60string_list_append (string_list_ty *slp, const char *s)
61{
62  /* Grow the list.  */
63  if (slp->nitems >= slp->nitems_max)
64    {
65      size_t nbytes;
66
67      slp->nitems_max = slp->nitems_max * 2 + 4;
68      nbytes = slp->nitems_max * sizeof (slp->item[0]);
69      slp->item = (const char **) xrealloc (slp->item, nbytes);
70    }
71
72  /* Add a copy of the string to the end of the list.  */
73  slp->item[slp->nitems++] = xstrdup (s);
74}
75
76
77/* Append a single string to the end of a list of strings, unless it is
78   already contained in the list.  */
79void
80string_list_append_unique (string_list_ty *slp, const char *s)
81{
82  size_t j;
83
84  /* Do not if the string is already in the list.  */
85  for (j = 0; j < slp->nitems; ++j)
86    if (strcmp (slp->item[j], s) == 0)
87      return;
88
89  /* Grow the list.  */
90  if (slp->nitems >= slp->nitems_max)
91    {
92      slp->nitems_max = slp->nitems_max * 2 + 4;
93      slp->item = (const char **) xrealloc (slp->item,
94					    slp->nitems_max
95					    * sizeof (slp->item[0]));
96    }
97
98  /* Add a copy of the string to the end of the list.  */
99  slp->item[slp->nitems++] = xstrdup (s);
100}
101
102
103/* Destroy a list of strings.  */
104void
105string_list_destroy (string_list_ty *slp)
106{
107  size_t j;
108
109  for (j = 0; j < slp->nitems; ++j)
110    free ((char *) slp->item[j]);
111  if (slp->item != NULL)
112    free (slp->item);
113}
114
115
116/* Free a list of strings.  */
117void
118string_list_free (string_list_ty *slp)
119{
120  size_t j;
121
122  for (j = 0; j < slp->nitems; ++j)
123    free ((char *) slp->item[j]);
124  if (slp->item != NULL)
125    free (slp->item);
126  free (slp);
127}
128
129
130/* Return a freshly allocated string obtained by concatenating all the
131   strings in the list.  */
132char *
133string_list_concat (const string_list_ty *slp)
134{
135  size_t len;
136  size_t j;
137  char *result;
138  size_t pos;
139
140  len = 1;
141  for (j = 0; j < slp->nitems; ++j)
142    len += strlen (slp->item[j]);
143  result = XNMALLOC (len, char);
144  pos = 0;
145  for (j = 0; j < slp->nitems; ++j)
146    {
147      len = strlen (slp->item[j]);
148      memcpy (result + pos, slp->item[j], len);
149      pos += len;
150    }
151  result[pos] = '\0';
152  return result;
153}
154
155
156/* Return a freshly allocated string obtained by concatenating all the
157   strings in the list, and destroy the list.  */
158char *
159string_list_concat_destroy (string_list_ty *slp)
160{
161  char *result;
162
163  /* Optimize the most frequent case.  */
164  if (slp->nitems == 1)
165    {
166      result = (char *) slp->item[0];
167      free (slp->item);
168    }
169  else
170    {
171      result = string_list_concat (slp);
172      string_list_destroy (slp);
173    }
174  return result;
175}
176
177
178/* Return a freshly allocated string obtained by concatenating all the
179   strings in the list, separated by the separator character, terminated
180   by the terminator character.  The terminator character is not added if
181   drop_redundant_terminator is true and the last string already ends with
182   the terminator. */
183char *
184string_list_join (const string_list_ty *slp, char separator,
185		  char terminator, bool drop_redundant_terminator)
186{
187  size_t len;
188  size_t j;
189  char *result;
190  size_t pos;
191
192  len = 1;
193  for (j = 0; j < slp->nitems; ++j)
194    {
195      if (separator && j > 0)
196	++len;
197      len += strlen (slp->item[j]);
198    }
199  if (terminator)
200    ++len;
201  result = XNMALLOC (len, char);
202  pos = 0;
203  for (j = 0; j < slp->nitems; ++j)
204    {
205      if (separator && j > 0)
206	result[pos++] = separator;
207      len = strlen (slp->item[j]);
208      memcpy (result + pos, slp->item[j], len);
209      pos += len;
210    }
211  if (terminator
212      && !(drop_redundant_terminator
213	   && slp->nitems > 0
214	   && (len = strlen (slp->item[slp->nitems - 1])) > 0
215	   && slp->item[slp->nitems - 1][len - 1] == terminator))
216    result[pos++] = terminator;
217  result[pos] = '\0';
218  return result;
219}
220
221
222/* Return 1 if s is contained in the list of strings, 0 otherwise.  */
223bool
224string_list_member (const string_list_ty *slp, const char *s)
225{
226  size_t j;
227
228  for (j = 0; j < slp->nitems; ++j)
229    if (strcmp (slp->item[j], s) == 0)
230      return true;
231  return false;
232}
233