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