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