2 Copyright (C) 2012-2022 Ben Kibbey <bjk@luxsci.net>
4 This file is part of pwmd.
6 Pwmd is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License version 2 as
8 published by the Free Software Foundation.
10 Pwmd is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with Pwmd. If not, see <http://www.gnu.org/licenses/>.
25 #include "util-string.h"
28 #define ALLOC_LARGE 4096
31 string_free (struct string_s
*s
, int with_data
)
43 string_erase (struct string_s
*s
, ssize_t pos
, ssize_t len
)
51 s
->len
= s
->len
- pos
;
57 memmove (&s
->str
[pos
], &s
->str
[pos
+ len
], n
);
63 /* Be careful about allocations since other string_ functions may
64 * realloc the 'str' pointer. */
66 string_new_content (char *str
)
68 struct string_s
*s
= xcalloc (1, sizeof (struct string_s
));
71 s
->len
= strlen (s
->str
);
72 s
->allocated
= s
->len
+ 1;
77 string_large (struct string_s
*str
)
82 return GPG_ERR_INV_ARG
;
84 s
= xrealloc (str
->str
, (str
->len
+ ALLOC_LARGE
) * sizeof (char));
86 return GPG_ERR_ENOMEM
;
94 string_new (const char *str
)
96 struct string_s
*s
= xcalloc (1, sizeof (struct string_s
));
100 s
->str
= str_dup (str
);
107 s
->len
= strlen (s
->str
);
108 s
->allocated
= s
->len
+ 1;
115 string_append (struct string_s
*s
, const char *str
)
117 size_t len
= strlen (str
);
119 if (s
->allocated
< len
+ s
->len
+ 1)
122 size_t size
= len
+ s
->len
+ 1;
124 size
+= s
->large
? ALLOC_LARGE
: 0;
126 p
= xrealloc (s
->str
, size
* sizeof (char));
134 memcpy (&s
->str
[s
->len
], str
, len
);
141 string_truncate (struct string_s
*s
, size_t n
)
155 string_prepend (struct string_s
*s
, const char *str
)
157 size_t len
= strlen (str
);
159 if (s
->allocated
< s
->len
+ len
+ 1)
161 size_t size
= len
+ s
->len
+ 1;
163 size
+= s
->large
? ALLOC_LARGE
: 0;
164 char *p
= xrealloc (s
->str
, size
* sizeof (char));
173 memmove (&s
->str
[len
], s
->str
, s
->len
);
174 memcpy (s
->str
, str
, len
);
181 string_append_printf (struct string_s
*s
, const char *fmt
, ...)
188 len
= str_vasprintf (&buf
, fmt
, ap
);
193 s
= string_append (s
, buf
);
199 string_insert_c (struct string_s
*s
, ssize_t pos
, char c
)
201 size_t len
= s
->len
+ 2;
203 if (pos
>= s
->allocated
)
206 if (s
->allocated
< len
)
208 size_t size
= s
->large
? len
+ ALLOC_LARGE
: len
;
209 char *p
= xrealloc (s
->str
, size
* sizeof (char));
219 memmove (&s
->str
[pos
+ 1], &s
->str
[pos
], s
->len
- pos
);
221 s
->len
= pos
+ 1 == s
->allocated
? pos
+ 1 : s
->len
+ 1;
227 strv_length (char **a
)
237 /* 'str' must already be allocated. */
239 strv_cat (char **a
, char *str
)
241 int len
= a
? strv_length (a
) : 0;
244 dst
= xrealloc (a
, (len
+ 2) * sizeof (char *));
254 strv_printf (char ***array
, const char *fmt
, ...)
262 ret
= str_vasprintf (&buf
, fmt
, ap
);
268 a
= strv_cat (*array
, buf
);
284 for (p
= a
; p
&& *p
; p
++)
291 strv_dup (char **src
)
296 for (p
= src
; p
&& *p
; p
++)
299 char *xp
= str_dup (*p
);
307 tmp
= strv_cat (dst
, xp
);
322 strv_catv (char **dst
, char **src
)
334 for (p
= src
; p
&& *p
; p
++)
337 char *xp
= str_dup (*p
);
345 tmp
= strv_cat (d
, xp
);
369 while (len
&& isspace (str
[--len
]))
372 while (p
&& *p
&& isspace (*p
))
379 str_split_common (const char *src
, const char *delim
, int count
, int ws
)
383 const char *dp
= delim
;
384 char *str
= str_dup (src
);
386 size_t dlen
= strlen (delim
);
387 size_t pos
= 0, lastpos
= 0;
403 size_t len
= pos
- lastpos
- dlen
+ 1;
406 xp
= xmalloc (len
+ 1);
414 memcpy (xp
, &str
[lastpos
], len
);
421 tmp
= strv_cat (dst
, s
);
433 if (count
> 0 && index
+1 == count
&& *(p
+ 1))
435 if (!strv_printf (&dst
, "%s", p
+ 1))
461 if (!strv_printf (&dst
, "%s", p
))
472 /* Like str_split() but trims whitespace between 'delim'. */
474 str_split_ws (const char *str
, const char *delim
, int count
)
476 return str_split_common (str
, delim
, count
, 1);
480 str_split (const char *str
, const char *delim
, int count
)
482 return str_split_common (str
, delim
, count
, 0);
486 strv_join (const char *delim
, char **a
)
490 struct string_s
*s
= string_new ("");
497 for (p
= a
; p
&& *p
; p
++)
501 sp
= string_append_printf (s
, "%s%s", *p
, delim
502 && *(p
+ 1) ? delim
: "");
522 for (p
= str
; *p
; p
++)
532 str_chomp (char *str
)
534 int len
= strlen (str
);
535 char *p
= str
+ len
- 1;
537 while (len
&& isspace (*p
))
550 memmove (str
, p
, len
);
556 str_dup (const char *str
)
563 t
= xmalloc ((len
+ 1) * sizeof (char));
567 for (c
= 0; c
< len
; c
++)
575 str_asprintf (const char *fmt
, ...)
582 len
= str_vasprintf (&result
, fmt
, ap
);
584 return len
== -1 ? NULL
: result
;
588 str_vasprintf (char **result
, const char *fmt
, va_list ap
)
595 len
= vsnprintf (NULL
, 0, fmt
, cp
);
598 buf
= xmalloc (++len
);
603 len2
= vsnprintf (buf
, len
, fmt
, cp
);