e851bac1f3f7cef17b35e134434be77f8a84570d
[pspp] / src / libpspp / str.c
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 1997-9, 2000, 2006, 2009, 2010, 2011, 2012, 2014,
3    2020 Free Software Foundation, Inc.
4
5    This program is free software: you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation, either version 3 of the License, or
8    (at your option) any later version.
9
10    This program 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.
14
15    You should have received a copy of the GNU General Public License
16    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
17
18 #include <config.h>
19
20 #include "str.h"
21
22 #include <ctype.h>
23 #include <errno.h>
24 #include <stdint.h>
25 #include <stdlib.h>
26 #include <unistr.h>
27
28 #include "libpspp/cast.h"
29 #include "libpspp/i18n.h"
30 #include "libpspp/message.h"
31 #include "libpspp/pool.h"
32
33 #include "gl/c-ctype.h"
34 #include "gl/c-vasnprintf.h"
35 #include "gl/relocatable.h"
36 #include "gl/minmax.h"
37 #include "gl/xalloc.h"
38 #include "gl/xmemdup0.h"
39 #include "gl/xsize.h"
40 \f
41 /* Reverses the order of NBYTES bytes at address P, thus converting
42    between little- and big-endian byte orders.  */
43 void
44 buf_reverse (char *p, size_t nbytes)
45 {
46   char *h = p, *t = &h[nbytes - 1];
47   char temp;
48
49   nbytes /= 2;
50   while (nbytes--)
51     {
52       temp = *h;
53       *h++ = *t;
54       *t-- = temp;
55     }
56 }
57
58 /* Compares the SIZE bytes in A to those in B, disregarding case,
59    and returns a strcmp()-type result. */
60 int
61 buf_compare_case (const char *a_, const char *b_, size_t size)
62 {
63   const unsigned char *a = (unsigned char *) a_;
64   const unsigned char *b = (unsigned char *) b_;
65
66   while (size-- > 0)
67     {
68       unsigned char ac = toupper (*a++);
69       unsigned char bc = toupper (*b++);
70
71       if (ac != bc)
72         return ac > bc ? 1 : -1;
73     }
74
75   return 0;
76 }
77
78 /* Compares A of length A_LEN to B of length B_LEN.  The shorter
79    string is considered to be padded with spaces to the length of
80    the longer. */
81 int
82 buf_compare_rpad (const char *a, size_t a_len, const char *b, size_t b_len)
83 {
84   size_t min_len;
85   int result;
86
87   min_len = a_len < b_len ? a_len : b_len;
88   result = memcmp (a, b, min_len);
89   if (result != 0)
90     return result;
91   else
92     {
93       size_t idx;
94
95       if (a_len < b_len)
96         {
97           for (idx = min_len; idx < b_len; idx++)
98             if (' ' != b[idx])
99               return ' ' > b[idx] ? 1 : -1;
100         }
101       else
102         {
103           for (idx = min_len; idx < a_len; idx++)
104             if (a[idx] != ' ')
105               return a[idx] > ' ' ? 1 : -1;
106         }
107       return 0;
108     }
109 }
110
111 /* Compares strin A to string B.  The shorter string is
112    considered to be padded with spaces to the length of the
113    longer. */
114 int
115 str_compare_rpad (const char *a, const char *b)
116 {
117   return buf_compare_rpad (a, strlen (a), b, strlen (b));
118 }
119
120 /* Copies string SRC to buffer DST, of size DST_SIZE bytes.
121    DST is truncated to DST_SIZE bytes or padded on the right with
122    copies of PAD as needed. */
123 void
124 buf_copy_str_rpad (char *dst, size_t dst_size, const char *src, char pad)
125 {
126   size_t src_len = strlen (src);
127   if (src_len >= dst_size)
128     memcpy (dst, src, dst_size);
129   else
130     {
131       memcpy (dst, src, src_len);
132       memset (&dst[src_len], pad, dst_size - src_len);
133     }
134 }
135
136 /* Copies string SRC to buffer DST, of size DST_SIZE bytes.
137    DST is truncated to DST_SIZE bytes or padded on the left with
138    copies of PAD as needed. */
139 void
140 buf_copy_str_lpad (char *dst, size_t dst_size, const char *src, char pad)
141 {
142   size_t src_len = strlen (src);
143   if (src_len >= dst_size)
144     memcpy (dst, src, dst_size);
145   else
146     {
147       size_t n_pad = dst_size - src_len;
148       memset (&dst[0], pad, n_pad);
149       memcpy (dst + n_pad, src, src_len);
150     }
151 }
152
153 /* Copies buffer SRC, of SRC_SIZE bytes, to DST, of DST_SIZE bytes.
154    DST is truncated to DST_SIZE bytes or padded on the left with
155    copies of PAD as needed. */
156 void
157 buf_copy_lpad (char *dst, size_t dst_size,
158                const char *src, size_t src_size,
159                char pad)
160 {
161   if (src_size >= dst_size)
162     memmove (dst, src, dst_size);
163   else
164     {
165       memset (dst, pad, dst_size - src_size);
166       memmove (&dst[dst_size - src_size], src, src_size);
167     }
168 }
169
170 /* Copies buffer SRC, of SRC_SIZE bytes, to DST, of DST_SIZE bytes.
171    DST is truncated to DST_SIZE bytes or padded on the right with
172    copies of PAD as needed. */
173 void
174 buf_copy_rpad (char *dst, size_t dst_size,
175                const char *src, size_t src_size,
176                char pad)
177 {
178   if (src_size >= dst_size)
179     memmove (dst, src, dst_size);
180   else
181     {
182       memmove (dst, src, src_size);
183       memset (&dst[src_size], pad, dst_size - src_size);
184     }
185 }
186
187 /* Copies string SRC to string DST, which is in a buffer DST_SIZE
188    bytes long.
189    Truncates DST to DST_SIZE - 1 bytes or right-pads with
190    spaces to DST_SIZE - 1 bytes if necessary. */
191 void
192 str_copy_rpad (char *dst, size_t dst_size, const char *src)
193 {
194   if (dst_size > 0)
195     {
196       size_t src_len = strlen (src);
197       if (src_len < dst_size - 1)
198         {
199           memcpy (dst, src, src_len);
200           memset (&dst[src_len], ' ', dst_size - 1 - src_len);
201         }
202       else
203         memcpy (dst, src, dst_size - 1);
204       dst[dst_size - 1] = 0;
205     }
206 }
207
208 /* Copies SRC to DST, which is in a buffer DST_SIZE bytes long.
209    Truncates DST to DST_SIZE - 1 bytes, if necessary. */
210 void
211 str_copy_trunc (char *dst, size_t dst_size, const char *src)
212 {
213   size_t src_len = strlen (src);
214   assert (dst_size > 0);
215   if (src_len + 1 < dst_size)
216     memcpy (dst, src, src_len + 1);
217   else
218     {
219       memcpy (dst, src, dst_size - 1);
220       dst[dst_size - 1] = '\0';
221     }
222 }
223
224 /* Copies buffer SRC, of SRC_LEN bytes,
225    to DST, which is in a buffer DST_SIZE bytes long.
226    Truncates DST to DST_SIZE - 1 bytes, if necessary. */
227 void
228 str_copy_buf_trunc (char *dst, size_t dst_size,
229                     const char *src, size_t src_size)
230 {
231   size_t dst_len;
232   assert (dst_size > 0);
233
234   dst_len = src_size < dst_size ? src_size : dst_size - 1;
235   memcpy (dst, src, dst_len);
236   dst[dst_len] = '\0';
237 }
238
239 /* Converts each byte in S to uppercase.
240
241    This is suitable only for ASCII strings.  Use utf8_to_upper() for UTF-8
242    strings.*/
243 void
244 str_uppercase (char *s)
245 {
246   for (; *s != '\0'; s++)
247     *s = c_toupper ((unsigned char) *s);
248 }
249
250 /* Converts each byte in S to lowercase.
251
252    This is suitable only for ASCII strings.  Use utf8_to_lower() for UTF-8
253    strings.*/
254 void
255 str_lowercase (char *s)
256 {
257   for (; *s != '\0'; s++)
258     *s = c_tolower ((unsigned char) *s);
259 }
260
261 /* Converts NUMBER into a string in 26-adic notation in BUFFER,
262    which has room for SIZE bytes.  Uses uppercase if UPPERCASE is
263    true, otherwise lowercase, Returns true if successful, false
264    if NUMBER, plus a trailing null, is too large to fit in the
265    available space.
266
267    26-adic notation is "spreadsheet column numbering": 1 = A, 2 =
268    B, 3 = C, ... 26 = Z, 27 = AA, 28 = AB, 29 = AC, ...
269
270    26-adic notation is the special case of a k-adic numeration
271    system (aka bijective base-k numeration) with k=26.  In k-adic
272    numeration, the digits are {1, 2, 3, ..., k} (there is no
273    digit 0), and integer 0 is represented by the empty string.
274    For more information, see
275    http://en.wikipedia.org/wiki/Bijective_numeration. */
276 bool
277 str_format_26adic (unsigned long int number, bool uppercase,
278                    char buffer[], size_t size)
279 {
280   const char *alphabet
281     = uppercase ? "ABCDEFGHIJKLMNOPQRSTUVWXYZ" : "abcdefghijklmnopqrstuvwxyz";
282   size_t length = 0;
283
284   while (number-- > 0)
285     {
286       if (length >= size)
287         goto overflow;
288       buffer[length++] = alphabet[number % 26];
289       number /= 26;
290     }
291
292   if (length >= size)
293     goto overflow;
294   buffer[length] = '\0';
295
296   buf_reverse (buffer, length);
297   return true;
298
299 overflow:
300   if (length > 0)
301     buffer[0] = '\0';
302   return false;
303 }
304
305 /* Copies IN to buffer OUT with size OUT_SIZE, appending a null terminator.  If
306    IN is too long for OUT, or if IN contains a new-line, replaces the tail with
307    "...".
308
309    OUT_SIZE must be at least 16. */
310 void
311 str_ellipsize (struct substring in, char *out, size_t out_size)
312 {
313   assert (out_size >= 16);
314
315   size_t out_maxlen = out_size - 1;
316   if (in.length > out_maxlen - 3)
317     out_maxlen -= 3;
318
319   size_t out_len = 0;
320   while (out_len < in.length
321          && in.string[out_len] != '\n'
322          && in.string[out_len] != '\0'
323          && (in.string[out_len] != '\r'
324              || out_len + 1 >= in.length
325              || in.string[out_len + 1] != '\n'))
326     {
327       int mblen = u8_mblen (CHAR_CAST (const uint8_t *, in.string + out_len),
328                             in.length - out_len);
329       if (mblen < 0 || out_len + mblen > out_maxlen)
330         break;
331       out_len += mblen;
332     }
333
334   memcpy (out, in.string, out_len);
335   strcpy (&out[out_len], out_len < in.length ? "..." : "");
336 }
337
338 /* Sets the SIZE bytes starting at BLOCK to C,
339    and returns the byte following BLOCK. */
340 void *
341 mempset (void *block, int c, size_t size)
342 {
343   memset (block, c, size);
344   return (char *) block + size;
345 }
346 \f
347 /* Substrings. */
348
349 /* Returns a substring whose contents are the N bytes
350    starting at the (0-based) position START in SS. */
351 struct substring
352 ss_substr (struct substring ss, size_t start, size_t n)
353 {
354   if (start < ss.length)
355     return ss_buffer (ss.string + start, MIN (n, ss.length - start));
356   else
357     return ss_buffer (ss.string + ss.length, 0);
358 }
359
360 /* Returns a substring whose contents are the first N
361    bytes in SS. */
362 struct substring
363 ss_head (struct substring ss, size_t n)
364 {
365   return ss_buffer (ss.string, MIN (n, ss.length));
366 }
367
368 /* Returns a substring whose contents are the last N bytes
369    in SS. */
370 struct substring
371 ss_tail (struct substring ss, size_t n)
372 {
373   if (n < ss.length)
374     return ss_buffer (ss.string + (ss.length - n), n);
375   else
376     return ss;
377 }
378
379 /* Returns a malloc()'d, null-terminated copy of the contents of OLD.  The
380   caller owns the returned string and must eventually free it. */
381 struct substring
382 ss_clone (struct substring old)
383 {
384   return (struct substring) {
385     .string = xmemdup0 (old.string, old.length),
386     .length = old.length,
387   };
388 }
389
390 /* Allocates room for a N-byte string in NEW. */
391 void
392 ss_alloc_uninit (struct substring *new, size_t n)
393 {
394   new->string = xmalloc (n);
395   new->length = n;
396 }
397
398 void
399 ss_realloc (struct substring *ss, size_t size)
400 {
401   ss->string = xrealloc (ss->string, size);
402 }
403
404 /* Returns a pool_alloc_unaligned()'d, null-terminated copy of the contents of
405   OLD in POOL.  The pool owns the returned string. */
406 struct substring
407 ss_clone_pool (struct substring old, struct pool *pool)
408 {
409   return (struct substring) {
410     .string = pool_memdup0 (pool, old.string, old.length),
411     .length = old.length
412   };
413 }
414
415 /* Allocates room for a N-byte string in NEW in POOL. */
416 void
417 ss_alloc_uninit_pool (struct substring *new, size_t n, struct pool *pool)
418 {
419   new->string = pool_alloc_unaligned (pool, n);
420   new->length = n;
421 }
422
423 /* Frees the string that SS points to. */
424 void
425 ss_dealloc (struct substring *ss)
426 {
427   free (ss->string);
428 }
429
430 /* Exchanges the contents of A and B. */
431 void
432 ss_swap (struct substring *a, struct substring *b)
433 {
434   struct substring tmp = *a;
435   *a = *b;
436   *b = tmp;
437 }
438
439 /* Truncates SS to at most N bytes in length. */
440 void
441 ss_truncate (struct substring *ss, size_t n)
442 {
443   if (ss->length > n)
444     ss->length = n;
445 }
446
447 /* Removes trailing bytes in TRIM_SET from SS.
448    Returns number of bytes removed. */
449 size_t
450 ss_rtrim (struct substring *ss, struct substring trim_set)
451 {
452   size_t n = 0;
453   while (n < ss->length
454          && ss_find_byte (trim_set,
455                           ss->string[ss->length - n - 1]) != SIZE_MAX)
456     n++;
457   ss->length -= n;
458   return n;
459 }
460
461 /* Removes leading bytes in TRIM_SET from SS.
462    Returns number of bytes removed. */
463 size_t
464 ss_ltrim (struct substring *ss, struct substring trim_set)
465 {
466   size_t n = ss_span (*ss, trim_set);
467   ss_advance (ss, n);
468   return n;
469 }
470
471 /* Trims leading and trailing bytes in TRIM_SET from SS. */
472 void
473 ss_trim (struct substring *ss, struct substring trim_set)
474 {
475   ss_ltrim (ss, trim_set);
476   ss_rtrim (ss, trim_set);
477 }
478
479 /* If the last byte in SS is C, removes it and returns true.
480    Otherwise, returns false without changing the string. */
481 bool
482 ss_chomp_byte (struct substring *ss, char c)
483 {
484   if (ss_last (*ss) == c)
485     {
486       ss->length--;
487       return true;
488     }
489   else
490     return false;
491 }
492
493 /* If SS ends with SUFFIX, removes it and returns true.
494    Otherwise, returns false without changing the string. */
495 bool
496 ss_chomp (struct substring *ss, struct substring suffix)
497 {
498   if (ss_ends_with (*ss, suffix))
499     {
500       ss->length -= suffix.length;
501       return true;
502     }
503   else
504     return false;
505 }
506
507 /* Divides SS into tokens separated by any of the DELIMITERS.
508    Each call replaces TOKEN by the next token in SS, or by an
509    empty string if no tokens remain.  Returns true if a token was
510    obtained, false otherwise.
511
512    Before the first call, initialize *SAVE_IDX to 0.  Do not
513    modify *SAVE_IDX between calls.
514
515    SS divides into exactly one more tokens than it contains
516    delimiters.  That is, a delimiter at the start or end of SS or
517    a pair of adjacent delimiters yields an empty token, and the
518    empty string contains a single token. */
519 bool
520 ss_separate (struct substring ss, struct substring delimiters,
521              size_t *save_idx, struct substring *token)
522 {
523   if (*save_idx <= ss_length (ss))
524     {
525       struct substring tmp = ss_substr (ss, *save_idx, SIZE_MAX);
526       size_t length = ss_cspan (tmp, delimiters);
527       *token = ss_head (tmp, length);
528       *save_idx += length + 1;
529       return true;
530     }
531   else
532     {
533       *token = ss_empty ();
534       return false;
535     }
536 }
537
538 /* Divides SS into tokens separated by any of the DELIMITERS,
539    merging adjacent delimiters so that the empty string is never
540    produced as a token.  Each call replaces TOKEN by the next
541    token in SS, or by an empty string if no tokens remain, and
542    then skips past the first delimiter following the token.
543    Returns true if a token was obtained, false otherwise.
544
545    Before the first call, initialize *SAVE_IDX to 0.  Do not
546    modify *SAVE_IDX between calls. */
547 bool
548 ss_tokenize (struct substring ss, struct substring delimiters,
549              size_t *save_idx, struct substring *token)
550 {
551   bool found_token;
552
553   ss_advance (&ss, *save_idx);
554   *save_idx += ss_ltrim (&ss, delimiters);
555   ss_get_bytes (&ss, ss_cspan (ss, delimiters), token);
556
557   found_token = ss_length (*token) > 0;
558   *save_idx += ss_length (*token) + (found_token?1:0);
559   return found_token;
560 }
561
562 /* Removes the first N bytes from SS. */
563 void
564 ss_advance (struct substring *ss, size_t n)
565 {
566   if (n > ss->length)
567     n = ss->length;
568   ss->string += n;
569   ss->length -= n;
570 }
571
572 /* If the first byte in SS is C, removes it and returns true.
573    Otherwise, returns false without changing the string. */
574 bool
575 ss_match_byte (struct substring *ss, char c)
576 {
577   if (ss_first (*ss) == c)
578     {
579       ss->string++;
580       ss->length--;
581       return true;
582     }
583   else
584     return false;
585 }
586
587 /* If the first byte in SS is in MATCH, removes it and
588    returns the byte that was removed.
589    Otherwise, returns EOF without changing the string. */
590 int
591 ss_match_byte_in (struct substring *ss, struct substring match)
592 {
593   int c = EOF;
594   if (ss->length > 0
595       && memchr (match.string, ss->string[0], match.length) != NULL)
596     {
597       c = ss->string[0];
598       ss->string++;
599       ss->length--;
600     }
601   return c;
602 }
603
604 /* If SS begins with TARGET, removes it and returns true.
605    Otherwise, returns false without changing SS. */
606 bool
607 ss_match_string (struct substring *ss, const struct substring target)
608 {
609   size_t length = ss_length (target);
610   if (ss_equals (ss_head (*ss, length), target))
611     {
612       ss_advance (ss, length);
613       return true;
614     }
615   else
616     return false;
617 }
618
619 /* If SS begins with TARGET, except possibly for case differences, removes it
620    and returns true.  Otherwise, returns false without changing SS. */
621 bool
622 ss_match_string_case (struct substring *ss, const struct substring target)
623 {
624   size_t length = ss_length (target);
625   if (ss_equals_case (ss_head (*ss, length), target))
626     {
627       ss_advance (ss, length);
628       return true;
629     }
630   else
631     return false;
632 }
633
634 /* Removes the first byte from SS and returns it.
635    If SS is empty, returns EOF without modifying SS. */
636 int
637 ss_get_byte (struct substring *ss)
638 {
639   int c = ss_first (*ss);
640   if (c != EOF)
641     {
642       ss->string++;
643       ss->length--;
644     }
645   return c;
646 }
647
648 /* Stores the prefix of SS up to the first DELIMITER in OUT (if
649    any).  Trims those same bytes from SS.  DELIMITER is
650    removed from SS but not made part of OUT.  Returns true if
651    DELIMITER was found (and removed), false otherwise. */
652 bool
653 ss_get_until (struct substring *ss, char delimiter, struct substring *out)
654 {
655   ss_get_bytes (ss, ss_cspan (*ss, ss_buffer (&delimiter, 1)), out);
656   return ss_match_byte (ss, delimiter);
657 }
658
659 /* Stores the first N bytes in SS in OUT (or fewer, if SS
660    is shorter than N bytes).  Trims the same bytes
661    from the beginning of SS.  Returns N. */
662 size_t
663 ss_get_bytes (struct substring *ss, size_t n, struct substring *out)
664 {
665   *out = ss_head (*ss, n);
666   ss_advance (ss, n);
667   return n;
668 }
669
670 /* Parses and removes an optionally signed decimal integer from
671    the beginning of SS.  Returns 0 if an error occurred,
672    otherwise the number of bytes removed from SS.  Stores
673    the integer's value into *VALUE. */
674 size_t
675 ss_get_long (struct substring *ss, long *value)
676 {
677   char tmp[64];
678   size_t length;
679
680   length = ss_span (*ss, ss_cstr ("+-"));
681   length += ss_span (ss_substr (*ss, length, SIZE_MAX), ss_cstr (CC_DIGITS));
682   if (length > 0 && length < sizeof tmp)
683     {
684       char *tail;
685
686       memcpy (tmp, ss_data (*ss), length);
687       tmp[length] = '\0';
688
689       *value = strtol (tmp, &tail, 10);
690       if (tail - tmp == length)
691         {
692           ss_advance (ss, length);
693           return length;
694         }
695     }
696   *value = 0;
697   return 0;
698 }
699
700 /* Returns true if SS is empty (has length 0 bytes),
701    false otherwise. */
702 bool
703 ss_is_empty (struct substring ss)
704 {
705   return ss.length == 0;
706 }
707
708 /* Returns the number of bytes in SS. */
709 size_t
710 ss_length (struct substring ss)
711 {
712   return ss.length;
713 }
714
715 /* Returns a pointer to the bytes in SS. */
716 char *
717 ss_data (struct substring ss)
718 {
719   return ss.string;
720 }
721
722 /* Returns a pointer just past the last byte in SS. */
723 char *
724 ss_end (struct substring ss)
725 {
726   return ss.string + ss.length;
727 }
728
729 /* Returns the byte in position IDX in SS, as a value in the
730    range of unsigned char.  Returns EOF if IDX is out of the
731    range of indexes for SS. */
732 int
733 ss_at (struct substring ss, size_t idx)
734 {
735   return idx < ss.length ? (unsigned char) ss.string[idx] : EOF;
736 }
737
738 /* Returns the first byte in SS as a value in the range of
739    unsigned char.  Returns EOF if SS is the empty string. */
740 int
741 ss_first (struct substring ss)
742 {
743   return ss_at (ss, 0);
744 }
745
746 /* Returns the last byte in SS as a value in the range of
747    unsigned char.  Returns EOF if SS is the empty string. */
748 int
749 ss_last (struct substring ss)
750 {
751   return ss.length > 0 ? (unsigned char) ss.string[ss.length - 1] : EOF;
752 }
753
754 /* Returns true if SS starts with PREFIX, false otherwise. */
755 bool
756 ss_starts_with (struct substring ss, struct substring prefix)
757 {
758   return (ss.length >= prefix.length
759           && !memcmp (ss.string, prefix.string, prefix.length));
760 }
761
762 /* Returns true if SS starts with PREFIX in any case, false otherwise. */
763 bool
764 ss_starts_with_case (struct substring ss, struct substring prefix)
765 {
766   return (ss.length >= prefix.length
767           && !memcasecmp (ss.string, prefix.string, prefix.length));
768 }
769
770 /* Returns true if SS ends with SUFFIX, false otherwise. */
771 bool
772 ss_ends_with (struct substring ss, struct substring suffix)
773 {
774   return (ss.length >= suffix.length
775           && !memcmp (&ss.string[ss.length - suffix.length], suffix.string,
776                       suffix.length));
777 }
778
779 /* Returns true if SS ends with SUFFIX in any case, false otherwise. */
780 bool
781 ss_ends_with_case (struct substring ss, struct substring suffix)
782 {
783   return (ss.length >= suffix.length
784           && !memcasecmp (&ss.string[ss.length - suffix.length], suffix.string,
785                           suffix.length));
786 }
787
788 /* Returns the number of contiguous bytes at the beginning
789    of SS that are in SKIP_SET. */
790 size_t
791 ss_span (struct substring ss, struct substring skip_set)
792 {
793   size_t i;
794   for (i = 0; i < ss.length; i++)
795     if (ss_find_byte (skip_set, ss.string[i]) == SIZE_MAX)
796       break;
797   return i;
798 }
799
800 /* Returns the number of contiguous bytes at the beginning
801    of SS that are not in SKIP_SET. */
802 size_t
803 ss_cspan (struct substring ss, struct substring stop_set)
804 {
805   size_t i;
806   for (i = 0; i < ss.length; i++)
807     if (ss_find_byte (stop_set, ss.string[i]) != SIZE_MAX)
808       break;
809   return i;
810 }
811
812 /* Returns the offset in SS of the first instance of C,
813    or SIZE_MAX if C does not occur in SS. */
814 size_t
815 ss_find_byte (struct substring ss, char c)
816 {
817   const char *p = memchr (ss.string, (int) c, ss.length);
818   return p != NULL ? p - ss.string : SIZE_MAX;
819 }
820
821 /* Returns the offset in HAYSTACK of the first instance of NEEDLE,
822    or SIZE_MAX if NEEDLE does not occur in HAYSTACK. */
823 size_t
824 ss_find_substring (struct substring haystack, struct substring needle)
825 {
826   const char *p = memmem (haystack.string, haystack.length,
827                           needle.string, needle.length);
828   return p != NULL ? p - haystack.string : SIZE_MAX;
829 }
830
831 /* Compares A and B and returns a strcmp()-type comparison
832    result. */
833 int
834 ss_compare (struct substring a, struct substring b)
835 {
836   int retval = memcmp (a.string, b.string, MIN (a.length, b.length));
837   if (retval == 0)
838     retval = a.length < b.length ? -1 : a.length > b.length;
839   return retval;
840 }
841
842 /* Compares A and B case-insensitively and returns a
843    strcmp()-type comparison result. */
844 int
845 ss_compare_case (struct substring a, struct substring b)
846 {
847   int retval = memcasecmp (a.string, b.string, MIN (a.length, b.length));
848   if (retval == 0)
849     retval = a.length < b.length ? -1 : a.length > b.length;
850   return retval;
851 }
852
853 /* Compares A and B and returns true if their contents are
854    identical, false otherwise. */
855 int
856 ss_equals (struct substring a, struct substring b)
857 {
858   return a.length == b.length && !memcmp (a.string, b.string, a.length);
859 }
860
861 /* Compares A and B and returns true if their contents are
862    identical except possibly for case differences, false
863    otherwise. */
864 int
865 ss_equals_case (struct substring a, struct substring b)
866 {
867   return a.length == b.length && !memcasecmp (a.string, b.string, a.length);
868 }
869
870 /* Returns the position in SS that the byte at P occupies.
871    P must point within SS or one past its end. */
872 size_t
873 ss_pointer_to_position (struct substring ss, const char *p)
874 {
875   size_t pos = p - ss.string;
876   assert (pos <= ss.length);
877   return pos;
878 }
879
880 /* Allocates and returns a null-terminated string that contains
881    SS. */
882 char *
883 ss_xstrdup (struct substring ss)
884 {
885   char *s = xmalloc (ss.length + 1);
886   memcpy (s, ss.string, ss.length);
887   s[ss.length] = '\0';
888   return s;
889 }
890 /* UTF-8. */
891
892 /* Returns the character represented by the UTF-8 sequence at the start of S.
893    The return value is either a Unicode code point in the range 0 to 0x10ffff,
894    or UINT32_MAX if S is empty. */
895 ucs4_t
896 ss_first_mb (struct substring s)
897 {
898   return ss_at_mb (s, 0);
899 }
900
901 /* Returns the number of bytes in the UTF-8 character at the beginning of S.
902
903    The return value is 0 if S is empty, otherwise between 1 and 4. */
904 int
905 ss_first_mblen (struct substring s)
906 {
907   return ss_at_mblen (s, 0);
908 }
909
910 /* Advances S past the UTF-8 character at its beginning.  Returns the Unicode
911    code point that was skipped (in the range 0 to 0x10ffff), or UINT32_MAX if S
912    was not modified because it was initially empty. */
913 ucs4_t
914 ss_get_mb (struct substring *s)
915 {
916   if (s->length > 0)
917     {
918       ucs4_t uc;
919       int n;
920
921       n = u8_mbtouc (&uc, CHAR_CAST (const uint8_t *, s->string), s->length);
922       s->string += n;
923       s->length -= n;
924       return uc;
925     }
926   else
927     return UINT32_MAX;
928 }
929
930 /* Returns the character represented by the UTF-8 sequence starting OFS bytes
931    into S.  The return value is either a Unicode code point in the range 0 to
932    0x10ffff, or UINT32_MAX if OFS is past the last byte in S.
933
934    (Returns 0xfffd if OFS points into the middle, not the beginning, of a UTF-8
935    sequence.)  */
936 ucs4_t
937 ss_at_mb (struct substring s, size_t ofs)
938 {
939   if (s.length > ofs)
940     {
941       ucs4_t uc;
942       u8_mbtouc (&uc, CHAR_CAST (const uint8_t *, s.string + ofs),
943                  s.length - ofs);
944       return uc;
945     }
946   else
947     return UINT32_MAX;
948 }
949
950 /* Returns the number of bytes represented by the UTF-8 sequence starting OFS
951    bytes into S.  The return value is 0 if OFS is past the last byte in S,
952    otherwise between 1 and 4. */
953 int
954 ss_at_mblen (struct substring s, size_t ofs)
955 {
956   if (s.length > ofs)
957     {
958       ucs4_t uc;
959       return u8_mbtouc (&uc, CHAR_CAST (const uint8_t *, s.string + ofs),
960                         s.length - ofs);
961     }
962   else
963     return 0;
964 }
965
966 size_t
967 ss_utf8_count_columns (struct substring s)
968 {
969   return utf8_count_columns (s.string, s.length);
970 }
971
972 /* Returns a substring of S starting at 0-based display column START and
973    running for N display columns. */
974 struct substring
975 ss_utf8_columns (struct substring s, size_t start, size_t n)
976 {
977   ss_advance (&s, utf8_columns_to_bytes (s.string, s.length, start));
978   s.length = utf8_columns_to_bytes (s.string, s.length, n);
979   return s;
980 }
981 \f
982 /* Initializes ST as an empty string. */
983 void
984 ds_init_empty (struct string *st)
985 {
986   st->ss = ss_empty ();
987   st->capacity = 0;
988 }
989
990 /* Initializes ST with initial contents S. */
991 void
992 ds_init_string (struct string *st, const struct string *s)
993 {
994   ds_init_substring (st, ds_ss (s));
995 }
996
997 /* Initializes ST with initial contents SS. */
998 void
999 ds_init_substring (struct string *st, struct substring ss)
1000 {
1001   st->capacity = MAX (8, ss.length * 2);
1002   st->ss.string = xmalloc (st->capacity + 1);
1003   memcpy (st->ss.string, ss.string, ss.length);
1004   st->ss.length = ss.length;
1005 }
1006
1007 /* Initializes ST with initial contents S. */
1008 void
1009 ds_init_cstr (struct string *st, const char *s)
1010 {
1011   ds_init_substring (st, ss_cstr (s));
1012 }
1013
1014 /* Frees ST. */
1015 void
1016 ds_destroy (struct string *st)
1017 {
1018   if (st != NULL)
1019     {
1020       ss_dealloc (&st->ss);
1021       st->ss.string = NULL;
1022       st->ss.length = 0;
1023       st->capacity = 0;
1024     }
1025 }
1026
1027 /* Swaps the contents of strings A and B. */
1028 void
1029 ds_swap (struct string *a, struct string *b)
1030 {
1031   struct string tmp = *a;
1032   *a = *b;
1033   *b = tmp;
1034 }
1035
1036 /* Helper function for ds_register_pool. */
1037 static void
1038 free_string (void *st_)
1039 {
1040   struct string *st = st_;
1041   ds_destroy (st);
1042 }
1043
1044 /* Arranges for ST to be destroyed automatically as part of
1045    POOL. */
1046 void
1047 ds_register_pool (struct string *st, struct pool *pool)
1048 {
1049   pool_register (pool, free_string, st);
1050 }
1051
1052 /* Cancels the arrangement for ST to be destroyed automatically
1053    as part of POOL. */
1054 void
1055 ds_unregister_pool (struct string *st, struct pool *pool)
1056 {
1057   pool_unregister (pool, st);
1058 }
1059
1060 /* Copies SRC into DST.
1061    DST and SRC may be the same string. */
1062 void
1063 ds_assign_string (struct string *dst, const struct string *src)
1064 {
1065   ds_assign_substring (dst, ds_ss (src));
1066 }
1067
1068 /* Replaces DST by SS.
1069    SS may be a substring of DST. */
1070 void
1071 ds_assign_substring (struct string *dst, struct substring ss)
1072 {
1073   dst->ss.length = ss.length;
1074   ds_extend (dst, ss.length);
1075   memmove (dst->ss.string, ss.string, ss.length);
1076 }
1077
1078 /* Replaces DST by null-terminated string SRC.  SRC may overlap
1079    with DST. */
1080 void
1081 ds_assign_cstr (struct string *dst, const char *src)
1082 {
1083   ds_assign_substring (dst, ss_cstr (src));
1084 }
1085
1086 /* Truncates ST to zero length. */
1087 void
1088 ds_clear (struct string *st)
1089 {
1090   st->ss.length = 0;
1091 }
1092
1093 /* Returns a substring that contains ST. */
1094 struct substring
1095 ds_ss (const struct string *st)
1096 {
1097   return st->ss;
1098 }
1099
1100 /* Returns a substring that contains N bytes from ST
1101    starting at position START.
1102
1103    If START is greater than or equal to the length of ST, then
1104    the substring will be the empty string.  If START + N
1105    exceeds the length of ST, then the substring will only be
1106    ds_length(ST) - START bytes long. */
1107 struct substring
1108 ds_substr (const struct string *st, size_t start, size_t n)
1109 {
1110   return ss_substr (ds_ss (st), start, n);
1111 }
1112
1113 /* Returns a substring that contains the first N bytes in
1114    ST.  If N exceeds the length of ST, then the substring will
1115    contain all of ST. */
1116 struct substring
1117 ds_head (const struct string *st, size_t n)
1118 {
1119   return ss_head (ds_ss (st), n);
1120 }
1121
1122 /* Returns a substring that contains the last N bytes in
1123    ST.  If N exceeds the length of ST, then the substring will
1124    contain all of ST. */
1125 struct substring
1126 ds_tail (const struct string *st, size_t n)
1127 {
1128   return ss_tail (ds_ss (st), n);
1129 }
1130
1131 /* Ensures that ST can hold at least MIN_CAPACITY bytes plus a null
1132    terminator. */
1133 void
1134 ds_extend (struct string *st, size_t min_capacity)
1135 {
1136   if (min_capacity > st->capacity)
1137     {
1138       st->capacity *= 2;
1139       if (st->capacity < min_capacity)
1140         st->capacity = 2 * min_capacity;
1141
1142       st->ss.string = xrealloc (st->ss.string, st->capacity + 1);
1143     }
1144 }
1145
1146 /* Shrink ST to the minimum capacity need to contain its content. */
1147 void
1148 ds_shrink (struct string *st)
1149 {
1150   if (st->capacity != st->ss.length)
1151     {
1152       st->capacity = st->ss.length;
1153       st->ss.string = xrealloc (st->ss.string, st->capacity + 1);
1154     }
1155 }
1156
1157 /* Truncates ST to at most LENGTH bytes long. */
1158 void
1159 ds_truncate (struct string *st, size_t length)
1160 {
1161   ss_truncate (&st->ss, length);
1162 }
1163
1164 /* Removes trailing bytes in TRIM_SET from ST.
1165    Returns number of bytes removed. */
1166 size_t
1167 ds_rtrim (struct string *st, struct substring trim_set)
1168 {
1169   return ss_rtrim (&st->ss, trim_set);
1170 }
1171
1172 /* Removes leading bytes in TRIM_SET from ST.
1173    Returns number of bytes removed. */
1174 size_t
1175 ds_ltrim (struct string *st, struct substring trim_set)
1176 {
1177   size_t n = ds_span (st, trim_set);
1178   if (n > 0)
1179     ds_assign_substring (st, ds_substr (st, n, SIZE_MAX));
1180   return n;
1181 }
1182
1183 /* Trims leading and trailing bytes in TRIM_SET from ST.
1184    Returns number of bytes removed. */
1185 size_t
1186 ds_trim (struct string *st, struct substring trim_set)
1187 {
1188   size_t n = ds_rtrim (st, trim_set);
1189   return n + ds_ltrim (st, trim_set);
1190 }
1191
1192 /* If the last byte in ST is C, removes it and returns true.
1193    Otherwise, returns false without modifying ST. */
1194 bool
1195 ds_chomp_byte (struct string *st, char c)
1196 {
1197   return ss_chomp_byte (&st->ss, c);
1198 }
1199
1200 /* If ST ends with SUFFIX, removes it and returns true.
1201    Otherwise, returns false without modifying ST. */
1202 bool
1203 ds_chomp (struct string *st, struct substring suffix)
1204 {
1205   return ss_chomp (&st->ss, suffix);
1206 }
1207
1208 /* Divides ST into tokens separated by any of the DELIMITERS.
1209    Each call replaces TOKEN by the next token in ST, or by an
1210    empty string if no tokens remain.  Returns true if a token was
1211    obtained, false otherwise.
1212
1213    Before the first call, initialize *SAVE_IDX to 0.  Do not
1214    modify *SAVE_IDX between calls.
1215
1216    ST divides into exactly one more tokens than it contains
1217    delimiters.  That is, a delimiter at the start or end of ST or
1218    a pair of adjacent delimiters yields an empty token, and the
1219    empty string contains a single token. */
1220 bool
1221 ds_separate (const struct string *st, struct substring delimiters,
1222              size_t *save_idx, struct substring *token)
1223 {
1224   return ss_separate (ds_ss (st), delimiters, save_idx, token);
1225 }
1226
1227 /* Divides ST into tokens separated by any of the DELIMITERS,
1228    merging adjacent delimiters so that the empty string is never
1229    produced as a token.  Each call replaces TOKEN by the next
1230    token in ST, or by an empty string if no tokens remain.
1231    Returns true if a token was obtained, false otherwise.
1232
1233    Before the first call, initialize *SAVE_IDX to 0.  Do not
1234    modify *SAVE_IDX between calls. */
1235 bool
1236 ds_tokenize (const struct string *st, struct substring delimiters,
1237              size_t *save_idx, struct substring *token)
1238 {
1239   return ss_tokenize (ds_ss (st), delimiters, save_idx, token);
1240 }
1241
1242 /* Pad ST on the right with copies of PAD until ST is at least
1243    LENGTH bytes in size.  If ST is initially LENGTH
1244    bytes or longer, this is a no-op. */
1245 void
1246 ds_rpad (struct string *st, size_t length, char pad)
1247 {
1248   if (length > st->ss.length)
1249     ds_put_byte_multiple (st, pad, length - st->ss.length);
1250 }
1251
1252 /* Sets the length of ST to exactly NEW_LENGTH,
1253    either by truncating bytes from the end,
1254    or by padding on the right with PAD. */
1255 void
1256 ds_set_length (struct string *st, size_t new_length, char pad)
1257 {
1258   if (st->ss.length < new_length)
1259     ds_rpad (st, new_length, pad);
1260   else
1261     st->ss.length = new_length;
1262 }
1263
1264 /* Removes N bytes from ST starting at offset START. */
1265 void
1266 ds_remove (struct string *st, size_t start, size_t n)
1267 {
1268   if (n > 0 && start < st->ss.length)
1269     {
1270       if (st->ss.length - start <= n)
1271         {
1272           /* All bytes at or beyond START are deleted. */
1273           st->ss.length = start;
1274         }
1275       else
1276         {
1277           /* Some bytes remain and must be shifted into
1278              position. */
1279           memmove (st->ss.string + st->ss.length,
1280                    st->ss.string + st->ss.length + n,
1281                    st->ss.length - start - n);
1282           st->ss.length -= n;
1283         }
1284     }
1285   else
1286     {
1287       /* There are no bytes to delete or no bytes at or
1288          beyond START, hence deletion is a no-op. */
1289     }
1290 }
1291
1292 /* Returns true if ST is empty, false otherwise. */
1293 bool
1294 ds_is_empty (const struct string *st)
1295 {
1296   return ss_is_empty (st->ss);
1297 }
1298
1299 /* Returns the length of ST. */
1300 size_t
1301 ds_length (const struct string *st)
1302 {
1303   return ss_length (ds_ss (st));
1304 }
1305
1306 /* Returns the string data inside ST. */
1307 char *
1308 ds_data (const struct string *st)
1309 {
1310   return ss_data (ds_ss (st));
1311 }
1312
1313 /* Returns a pointer to the null terminator ST.
1314    This might not be an actual null byte unless ds_c_str() has
1315    been called since the last modification to ST. */
1316 char *
1317 ds_end (const struct string *st)
1318 {
1319   return ss_end (ds_ss (st));
1320 }
1321
1322 /* Returns the byte in position IDX in ST, as a value in the
1323    range of unsigned char.  Returns EOF if IDX is out of the
1324    range of indexes for ST. */
1325 int
1326 ds_at (const struct string *st, size_t idx)
1327 {
1328   return ss_at (ds_ss (st), idx);
1329 }
1330
1331 /* Returns the first byte in ST as a value in the range of
1332    unsigned char.  Returns EOF if ST is the empty string. */
1333 int
1334 ds_first (const struct string *st)
1335 {
1336   return ss_first (ds_ss (st));
1337 }
1338
1339 /* Returns the last byte in ST as a value in the range of
1340    unsigned char.  Returns EOF if ST is the empty string. */
1341 int
1342 ds_last (const struct string *st)
1343 {
1344   return ss_last (ds_ss (st));
1345 }
1346
1347 /* Returns true if ST ends with SUFFIX, false otherwise. */
1348 bool
1349 ds_ends_with (const struct string *st, struct substring suffix)
1350 {
1351   return ss_ends_with (st->ss, suffix);
1352 }
1353
1354 /* Returns the number of consecutive bytes at the beginning
1355    of ST that are in SKIP_SET. */
1356 size_t
1357 ds_span (const struct string *st, struct substring skip_set)
1358 {
1359   return ss_span (ds_ss (st), skip_set);
1360 }
1361
1362 /* Returns the number of consecutive bytes at the beginning
1363    of ST that are not in STOP_SET.  */
1364 size_t
1365 ds_cspan (const struct string *st, struct substring stop_set)
1366 {
1367   return ss_cspan (ds_ss (st), stop_set);
1368 }
1369
1370 /* Returns the position of the first occurrence of byte C in
1371    ST at or after position OFS, or SIZE_MAX if there is no such
1372    occurrence. */
1373 size_t
1374 ds_find_byte (const struct string *st, char c)
1375 {
1376   return ss_find_byte (ds_ss (st), c);
1377 }
1378
1379 /* Compares A and B and returns a strcmp()-type comparison
1380    result. */
1381 int
1382 ds_compare (const struct string *a, const struct string *b)
1383 {
1384   return ss_compare (ds_ss (a), ds_ss (b));
1385 }
1386
1387 /* Returns the position in ST that the byte at P occupies.
1388    P must point within ST or one past its end. */
1389 size_t
1390 ds_pointer_to_position (const struct string *st, const char *p)
1391 {
1392   return ss_pointer_to_position (ds_ss (st), p);
1393 }
1394
1395 /* Allocates and returns a null-terminated string that contains
1396    ST. */
1397 char *
1398 ds_xstrdup (const struct string *st)
1399 {
1400   return ss_xstrdup (ds_ss (st));
1401 }
1402
1403 /* Returns the allocation size of ST. */
1404 size_t
1405 ds_capacity (const struct string *st)
1406 {
1407   return st->capacity;
1408 }
1409
1410 /* Returns the value of ST as a null-terminated string. */
1411 char *
1412 ds_cstr (const struct string *st_)
1413 {
1414   struct string *st = CONST_CAST (struct string *, st_);
1415   if (st->ss.string == NULL)
1416     ds_extend (st, 1);
1417   st->ss.string[st->ss.length] = '\0';
1418   return st->ss.string;
1419 }
1420
1421 /* Returns the value of ST as a null-terminated string and then
1422    reinitialized ST as an empty string.  The caller must free the
1423    returned string with free(). */
1424 char *
1425 ds_steal_cstr (struct string *st)
1426 {
1427   char *s = ds_cstr (st);
1428   ds_init_empty (st);
1429   return s;
1430 }
1431
1432 /* Reads bytes from STREAM and appends them to ST, stopping
1433    after MAX_LENGTH bytes, after appending a newline, or
1434    after an I/O error or end of file was encountered, whichever
1435    comes first.  Returns true if at least one byte was added
1436    to ST, false if no bytes were read before an I/O error or
1437    end of file (or if MAX_LENGTH was 0).
1438
1439    This function treats LF and CR LF sequences as new-line,
1440    translating each of them to a single '\n' in ST. */
1441 bool
1442 ds_read_line (struct string *st, FILE *stream, size_t max_length)
1443 {
1444   size_t length;
1445
1446   for (length = 0; length < max_length; length++)
1447     {
1448       int c = getc (stream);
1449       switch (c)
1450         {
1451         case EOF:
1452           return length > 0;
1453
1454         case '\n':
1455           ds_put_byte (st, c);
1456           return true;
1457
1458         case '\r':
1459           c = getc (stream);
1460           if (c == '\n')
1461             {
1462               /* CR followed by LF is special: translate to \n. */
1463               ds_put_byte (st, '\n');
1464               return true;
1465             }
1466           else
1467             {
1468               /* CR followed by anything else is just CR. */
1469               ds_put_byte (st, '\r');
1470               if (c == EOF)
1471                 return true;
1472               ungetc (c, stream);
1473             }
1474           break;
1475
1476         default:
1477           ds_put_byte (st, c);
1478         }
1479     }
1480
1481   return length > 0;
1482 }
1483
1484 /* Removes a comment introduced by `#' from ST,
1485    ignoring occurrences inside quoted strings. */
1486 static void
1487 remove_comment (struct string *st)
1488 {
1489   char *cp;
1490   int quote = 0;
1491
1492   for (cp = ds_data (st); cp < ds_end (st); cp++)
1493     if (quote)
1494       {
1495         if (*cp == quote)
1496           quote = 0;
1497         else if (*cp == '\\')
1498           cp++;
1499       }
1500     else if (*cp == '\'' || *cp == '"')
1501       quote = *cp;
1502     else if (*cp == '#')
1503       {
1504         ds_truncate (st, cp - ds_cstr (st));
1505         break;
1506       }
1507 }
1508
1509 /* Reads a line from STREAM into ST, then preprocesses as follows:
1510
1511    - Splices lines terminated with `\'.
1512
1513    - Deletes comments introduced by `#' outside of single or double
1514      quotes.
1515
1516    - Deletes trailing white space.
1517
1518    Returns true if a line was successfully read, false on
1519    failure.  If LINE_NUMBER is non-null, then *LINE_NUMBER is
1520    incremented by the number of lines read. */
1521 bool
1522 ds_read_config_line (struct string *st, int *line_number, FILE *stream)
1523 {
1524   ds_clear (st);
1525   do
1526     {
1527       if (!ds_read_line (st, stream, SIZE_MAX))
1528         return false;
1529       (*line_number)++;
1530       ds_rtrim (st, ss_cstr (CC_SPACES));
1531     }
1532   while (ds_chomp_byte (st, '\\'));
1533
1534   remove_comment (st);
1535   return true;
1536 }
1537
1538 /* Attempts to read SIZE * N bytes from STREAM and append them
1539    to ST.
1540    Returns true if all the requested data was read, false otherwise. */
1541 bool
1542 ds_read_stream (struct string *st, size_t size, size_t n, FILE *stream)
1543 {
1544   if (size != 0)
1545     {
1546       size_t try_bytes = xtimes (n, size);
1547       if (size_in_bounds_p (xsum (ds_length (st), try_bytes)))
1548         {
1549           char *buffer = ds_put_uninit (st, try_bytes);
1550           size_t got_bytes = fread (buffer, 1, try_bytes, stream);
1551           ds_truncate (st, ds_length (st) - (try_bytes - got_bytes));
1552           return got_bytes == try_bytes;
1553         }
1554       else
1555         {
1556           errno = ENOMEM;
1557           return false;
1558         }
1559     }
1560   else
1561     return true;
1562 }
1563
1564 /* Concatenates S onto ST. */
1565 void
1566 ds_put_cstr (struct string *st, const char *s)
1567 {
1568   if (s != NULL)
1569     ds_put_substring (st, ss_cstr (s));
1570 }
1571
1572 /* Concatenates SS to ST. */
1573 void
1574 ds_put_substring (struct string *st, struct substring ss)
1575 {
1576   if (ss.length)
1577     memcpy (ds_put_uninit (st, ss_length (ss)), ss_data (ss), ss_length (ss));
1578 }
1579
1580 /* Returns ds_end(ST) and THEN increases the length by INCR. */
1581 char *
1582 ds_put_uninit (struct string *st, size_t incr)
1583 {
1584   char *end;
1585   ds_extend (st, ds_length (st) + incr);
1586   end = ds_end (st);
1587   st->ss.length += incr;
1588   return end;
1589 }
1590
1591 /* Moves the bytes in ST following offset OFS + OLD_LEN in ST to offset OFS +
1592    NEW_LEN and returns the byte at offset OFS.  The first min(OLD_LEN, NEW_LEN)
1593    bytes at the returned position are unchanged; if NEW_LEN > OLD_LEN then the
1594    following NEW_LEN - OLD_LEN bytes are initially indeterminate.
1595
1596    The intention is that the caller should write NEW_LEN bytes at the returned
1597    position, to effectively replace the OLD_LEN bytes previously at that
1598    position. */
1599 char *
1600 ds_splice_uninit (struct string *st,
1601                   size_t ofs, size_t old_len, size_t new_len)
1602 {
1603   if (new_len != old_len)
1604     {
1605       if (new_len > old_len)
1606         ds_extend (st, ds_length (st) + (new_len - old_len));
1607
1608       assert (ds_length (st) >= ofs + old_len);
1609
1610       memmove (ds_data (st) + (ofs + new_len),
1611                ds_data (st) + (ofs + old_len),
1612                ds_length (st) - (ofs + old_len));
1613       st->ss.length += new_len - old_len;
1614     }
1615   return ds_data (st) + ofs;
1616 }
1617
1618 /* Formats FORMAT as a printf string and appends the result to ST. */
1619 void
1620 ds_put_format (struct string *st, const char *format, ...)
1621 {
1622   va_list args;
1623
1624   va_start (args, format);
1625   ds_put_vformat (st, format, args);
1626   va_end (args);
1627 }
1628
1629 /* Formats FORMAT as a printf string as if in the C locale and appends the result to ST. */
1630 void
1631 ds_put_c_format (struct string *st, const char *format, ...)
1632 {
1633   va_list args;
1634
1635   va_start (args, format);
1636   ds_put_c_vformat (st, format, args);
1637   va_end (args);
1638 }
1639
1640 /* Formats FORMAT as a printf string and appends the result to ST. */
1641 void
1642 ds_put_vformat (struct string *st, const char *format, va_list args_)
1643 {
1644   int avail, needed;
1645   va_list args;
1646
1647   va_copy (args, args_);
1648   avail = st->ss.string != NULL ? st->capacity - st->ss.length + 1 : 0;
1649   needed = vsnprintf (st->ss.string + st->ss.length, avail, format, args);
1650   va_end (args);
1651
1652   if (needed >= avail)
1653     {
1654       va_copy (args, args_);
1655       vsnprintf (ds_put_uninit (st, needed), needed + 1, format, args);
1656       va_end (args);
1657     }
1658   else
1659     {
1660       /* Some old libc's returned -1 when the destination string
1661          was too short. */
1662       while (needed == -1)
1663         {
1664           ds_extend (st, (st->capacity + 1) * 2);
1665           avail = st->capacity - st->ss.length + 1;
1666
1667           va_copy (args, args_);
1668           needed = vsnprintf (ds_end (st), avail, format, args);
1669           va_end (args);
1670         }
1671       st->ss.length += needed;
1672     }
1673 }
1674
1675 /* Formats FORMAT as a printf string, as if in the C locale,
1676    and appends the result to ST. */
1677 void
1678 ds_put_c_vformat (struct string *st, const char *format, va_list args)
1679 {
1680   char buf[128];
1681   size_t len = sizeof buf;
1682   char *output = c_vasnprintf (buf, &len, format, args);
1683   if (output)
1684     {
1685       ds_put_cstr (st, output);
1686       if (output != buf)
1687         free (output);
1688     }
1689 }
1690
1691 /* Appends byte CH to ST. */
1692 void
1693 ds_put_byte (struct string *st, int ch)
1694 {
1695   ds_put_uninit (st, 1)[0] = ch;
1696 }
1697
1698 /* Appends N copies of byte CH to ST. */
1699 void
1700 ds_put_byte_multiple (struct string *st, int ch, size_t n)
1701 {
1702   memset (ds_put_uninit (st, n), ch, n);
1703 }
1704
1705 /* Appends Unicode code point UC to ST in UTF-8 encoding. */
1706 void
1707 ds_put_unichar (struct string *st, ucs4_t uc)
1708 {
1709   ds_extend (st, ds_length (st) + 6);
1710   st->ss.length += u8_uctomb (CHAR_CAST (uint8_t *, ds_end (st)), uc, 6);
1711 }
1712
1713 /* Appends N copies of S to ST. */
1714 void
1715 ds_put_substring_multiple (struct string *dst, struct substring src, size_t n)
1716 {
1717   char *p = ds_put_uninit (dst, n * src.length);
1718   for (size_t i = 0; i < n; i++)
1719     {
1720       memcpy (p, src.string, src.length);
1721       p += src.length;
1722     }
1723 }
1724
1725 /* If relocation has been enabled, replace ST,
1726    with its relocated version */
1727 void
1728 ds_relocate (struct string *st)
1729 {
1730   const char *orig = ds_cstr (st);
1731   const char *rel = relocate (orig);
1732
1733   if (orig != rel)
1734     {
1735       ds_clear (st);
1736       ds_put_cstr (st, rel);
1737       /* The documentation for relocate says that casting away const
1738         and then freeing is appropriate ... */
1739       free (CONST_CAST (char *, rel));
1740     }
1741 }
1742
1743
1744 \f
1745
1746 /* Operations on uint8_t "strings" */
1747
1748 /* Copies buffer SRC, of SRC_SIZE bytes, to DST, of DST_SIZE bytes.
1749    DST is truncated to DST_SIZE bytes or padded on the right with
1750    copies of PAD as needed. */
1751 void
1752 u8_buf_copy_rpad (uint8_t *dst, size_t dst_size,
1753                   const uint8_t *src, size_t src_size,
1754                   char pad)
1755 {
1756   if (src_size >= dst_size)
1757     memmove (dst, src, dst_size);
1758   else
1759     {
1760       memmove (dst, src, src_size);
1761       memset (&dst[src_size], pad, dst_size - src_size);
1762     }
1763 }