1 /* PSPP - computes sample statistics.
2 Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
3 Written by Ben Pfaff <blp@gnu.org>.
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.
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.
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
28 #include <libpspp/alloc.h>
29 #include <libpspp/message.h>
30 #include <libpspp/pool.h>
36 /* Reverses the order of NBYTES bytes at address P, thus converting
37 between little- and big-endian byte orders. */
39 buf_reverse (char *p, size_t nbytes)
41 char *h = p, *t = &h[nbytes - 1];
53 /* Finds the last NEEDLE of length NEEDLE_LEN in a HAYSTACK of length
54 HAYSTACK_LEN. Returns a pointer to the needle found. */
56 buf_find_reverse (const char *haystack, size_t haystack_len,
57 const char *needle, size_t needle_len)
60 for (i = haystack_len - needle_len; i >= 0; i--)
61 if (!memcmp (needle, &haystack[i], needle_len))
62 return (char *) &haystack[i];
66 /* Compares the SIZE bytes in A to those in B, disregarding case,
67 and returns a strcmp()-type result. */
69 buf_compare_case (const char *a_, const char *b_, size_t size)
71 const unsigned char *a = (unsigned char *) a_;
72 const unsigned char *b = (unsigned char *) b_;
76 unsigned char ac = toupper (*a++);
77 unsigned char bc = toupper (*b++);
80 return ac > bc ? 1 : -1;
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
90 buf_compare_rpad (const char *a, size_t a_len, const char *b, size_t b_len)
95 min_len = a_len < b_len ? a_len : b_len;
96 result = memcmp (a, b, min_len);
105 for (idx = min_len; idx < b_len; idx++)
107 return ' ' > b[idx] ? 1 : -1;
111 for (idx = min_len; idx < a_len; idx++)
113 return a[idx] > ' ' ? 1 : -1;
119 /* Compares strin A to string B. The shorter string is
120 considered to be padded with spaces to the length of the
123 str_compare_rpad (const char *a, const char *b)
125 return buf_compare_rpad (a, strlen (a), b, strlen (b));
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
132 buf_copy_str_rpad (char *dst, size_t dst_size, const char *src)
134 size_t src_len = strlen (src);
135 if (src_len >= dst_size)
136 memcpy (dst, src, dst_size);
139 memcpy (dst, src, src_len);
140 memset (&dst[src_len], ' ', dst_size - src_len);
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
148 buf_copy_str_lpad (char *dst, size_t dst_size, const char *src)
150 size_t src_len = strlen (src);
151 if (src_len >= dst_size)
152 memcpy (dst, src, dst_size);
155 size_t pad_cnt = dst_size - src_len;
156 memset (&dst[0], ' ', pad_cnt);
157 memcpy (dst + pad_cnt, src, src_len);
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 right with
165 buf_copy_rpad (char *dst, size_t dst_size,
166 const char *src, size_t src_size)
168 if (src_size >= dst_size)
169 memmove (dst, src, dst_size);
172 memmove (dst, src, src_size);
173 memset (&dst[src_size], ' ', dst_size - src_size);
177 /* Copies string SRC to string DST, which is in a buffer DST_SIZE
179 Truncates DST to DST_SIZE - 1 characters or right-pads with
180 spaces to DST_SIZE - 1 characters if necessary. */
182 str_copy_rpad (char *dst, size_t dst_size, const char *src)
184 size_t src_len = strlen (src);
185 if (src_len < dst_size - 1)
187 memcpy (dst, src, src_len);
188 memset (&dst[src_len], ' ', dst_size - 1 - src_len);
191 memcpy (dst, src, dst_size - 1);
192 dst[dst_size - 1] = 0;
195 /* Copies SRC to DST, which is in a buffer DST_SIZE bytes long.
196 Truncates DST to DST_SIZE - 1 characters, if necessary. */
198 str_copy_trunc (char *dst, size_t dst_size, const char *src)
200 size_t src_len = strlen (src);
201 assert (dst_size > 0);
202 if (src_len + 1 < dst_size)
203 memcpy (dst, src, src_len + 1);
206 memcpy (dst, src, dst_size - 1);
207 dst[dst_size - 1] = '\0';
211 /* Copies buffer SRC, of SRC_LEN bytes,
212 to DST, which is in a buffer DST_SIZE bytes long.
213 Truncates DST to DST_SIZE - 1 characters, if necessary. */
215 str_copy_buf_trunc (char *dst, size_t dst_size,
216 const char *src, size_t src_size)
219 assert (dst_size > 0);
221 dst_len = src_size < dst_size ? src_size : dst_size - 1;
222 memcpy (dst, src, dst_len);
226 /* Converts each character in S to uppercase. */
228 str_uppercase (char *s)
230 for (; *s != '\0'; s++)
231 *s = toupper ((unsigned char) *s);
234 /* Converts each character in S to lowercase. */
236 str_lowercase (char *s)
238 for (; *s != '\0'; s++)
239 *s = tolower ((unsigned char) *s);
242 /* Formats FORMAT into DST, as with sprintf(), and returns the
243 address of the terminating null written to DST. */
245 spprintf (char *dst, const char *format, ...)
250 va_start (args, format);
251 count = vsprintf (dst, format, args);
259 /* Returns an empty substring. */
269 /* Returns a substring whose contents are the given C-style
272 ss_cstr (const char *cstr)
274 return ss_buffer (cstr, strlen (cstr));
277 /* Returns a substring whose contents are the CNT characters in
280 ss_buffer (const char *buffer, size_t cnt)
283 ss.string = (char *) buffer;
288 /* Returns a substring whose contents are the CNT characters
289 starting at the (0-based) position START in SS. */
291 ss_substr (struct substring ss, size_t start, size_t cnt)
293 if (start < ss.length)
294 return ss_buffer (ss.string + start, MIN (cnt, ss.length - start));
296 return ss_buffer (ss.string + ss.length, 0);
299 /* Returns a substring whose contents are the first CNT
302 ss_head (struct substring ss, size_t cnt)
304 return ss_buffer (ss.string, MIN (cnt, ss.length));
307 /* Returns a substring whose contents are the last CNT characters
310 ss_tail (struct substring ss, size_t cnt)
313 return ss_buffer (ss.string + (ss.length - cnt), cnt);
318 /* Makes a malloc()'d copy of the contents of OLD
319 and stores it in NEW. */
321 ss_alloc_substring (struct substring *new, struct substring old)
323 new->string = xmalloc (old.length);
324 new->length = old.length;
325 memcpy (new->string, old.string, old.length);
328 /* Allocates room for a CNT-character string in NEW. */
330 ss_alloc_uninit (struct substring *new, size_t cnt)
332 new->string = xmalloc (cnt);
336 /* Frees the string that SS points to. */
338 ss_dealloc (struct substring *ss)
343 /* Truncates SS to at most CNT characters in length. */
345 ss_truncate (struct substring *ss, size_t cnt)
347 if (ss->length > cnt)
351 /* Removes trailing characters in TRIM_SET from SS.
352 Returns number of characters removed. */
354 ss_rtrim (struct substring *ss, struct substring trim_set)
357 while (cnt < ss->length
358 && ss_find_char (trim_set,
359 ss->string[ss->length - cnt - 1]) != SIZE_MAX)
365 /* Removes leading characters in TRIM_SET from SS.
366 Returns number of characters removed. */
368 ss_ltrim (struct substring *ss, struct substring trim_set)
370 size_t cnt = ss_span (*ss, trim_set);
371 ss_advance (ss, cnt);
375 /* Trims leading and trailing characters in TRIM_SET from SS. */
377 ss_trim (struct substring *ss, struct substring trim_set)
379 ss_ltrim (ss, trim_set);
380 ss_rtrim (ss, trim_set);
383 /* If the last character in SS is C, removes it and returns true.
384 Otherwise, returns false without changing the string. */
386 ss_chomp (struct substring *ss, char c)
388 if (ss_last (*ss) == c)
397 /* Divides SS into tokens separated by any of the DELIMITERS.
398 Each call replaces TOKEN by the next token in SS, or by an
399 empty string if no tokens remain. Returns true if a token was
400 obtained, false otherwise.
402 Before the first call, initialize *SAVE_IDX to 0. Do not
403 modify *SAVE_IDX between calls.
405 SS divides into exactly one more tokens than it contains
406 delimiters. That is, a delimiter at the start or end of SS or
407 a pair of adjacent delimiters yields an empty token, and the
408 empty string contains a single token. */
410 ss_separate (struct substring ss, struct substring delimiters,
411 size_t *save_idx, struct substring *token)
413 if (*save_idx <= ss_length (ss))
415 struct substring tmp = ss_substr (ss, *save_idx, SIZE_MAX);
416 size_t length = ss_cspan (tmp, delimiters);
417 *token = ss_head (tmp, length);
418 *save_idx += length + 1;
423 *token = ss_empty ();
428 /* Divides SS into tokens separated by any of the DELIMITERS,
429 merging adjacent delimiters so that the empty string is never
430 produced as a token. Each call replaces TOKEN by the next
431 token in SS, or by an empty string if no tokens remain.
432 Returns true if a token was obtained, false otherwise.
434 Before the first call, initialize *SAVE_IDX to 0. Do not
435 modify *SAVE_IDX between calls. */
437 ss_tokenize (struct substring ss, struct substring delimiters,
438 size_t *save_idx, struct substring *token)
440 ss_advance (&ss, *save_idx);
441 *save_idx += ss_ltrim (&ss, delimiters);
442 *save_idx += ss_get_chars (&ss, ss_cspan (ss, delimiters), token);
443 return ss_length (*token) > 0;
446 /* Removes the first CNT characters from SS. */
448 ss_advance (struct substring *ss, size_t cnt)
450 if (cnt > ss->length)
456 /* If the first character in SS is C, removes it and returns true.
457 Otherwise, returns false without changing the string. */
459 ss_match_char (struct substring *ss, char c)
461 if (ss_first (*ss) == c)
471 /* Removes the first character from SS and returns it.
472 If SS is empty, returns EOF without modifying SS. */
474 ss_get_char (struct substring *ss)
476 int c = ss_first (*ss);
485 /* Stores the prefix of SS up to the first DELIMITER in OUT (if
486 any). Trims those same characters from SS. DELIMITER is
487 removed from SS but not made part of OUT. Returns true if
488 DELIMITER was found (and removed), false otherwise. */
490 ss_get_until (struct substring *ss, char delimiter, struct substring *out)
492 ss_get_chars (ss, ss_cspan (*ss, ss_buffer (&delimiter, 1)), out);
493 return ss_match_char (ss, delimiter);
496 /* Stores the first CNT characters in SS in OUT (or fewer, if SS
497 is shorter than CNT characters). Trims the same characters
498 from the beginning of SS. Returns CNT. */
500 ss_get_chars (struct substring *ss, size_t cnt, struct substring *out)
502 *out = ss_head (*ss, cnt);
503 ss_advance (ss, cnt);
507 /* Returns true if SS is empty (contains no characters),
510 ss_is_empty (struct substring ss)
512 return ss.length == 0;
515 /* Returns the number of characters in SS. */
517 ss_length (struct substring ss)
522 /* Returns a pointer to the characters in SS. */
524 ss_data (struct substring ss)
529 /* Returns a pointer just past the last character in SS. */
531 ss_end (struct substring ss)
533 return ss.string + ss.length;
536 /* Returns the character in position IDX in SS, as a value in the
537 range of unsigned char. Returns EOF if IDX is out of the
538 range of indexes for SS. */
540 ss_at (struct substring ss, size_t idx)
542 return idx < ss.length ? (unsigned char) ss.string[idx] : EOF;
545 /* Returns the first character in SS as a value in the range of
546 unsigned char. Returns EOF if SS is the empty string. */
548 ss_first (struct substring ss)
550 return ss_at (ss, 0);
553 /* Returns the last character in SS as a value in the range of
554 unsigned char. Returns EOF if SS is the empty string. */
556 ss_last (struct substring ss)
558 return ss.length > 0 ? (unsigned char) ss.string[ss.length - 1] : EOF;
561 /* Returns the number of contiguous characters at the beginning
562 of SS that are in SKIP_SET. */
564 ss_span (struct substring ss, struct substring skip_set)
567 for (i = 0; i < ss.length; i++)
568 if (ss_find_char (skip_set, ss.string[i]) == SIZE_MAX)
573 /* Returns the number of contiguous characters at the beginning
574 of SS that are not in SKIP_SET. */
576 ss_cspan (struct substring ss, struct substring stop_set)
579 for (i = 0; i < ss.length; i++)
580 if (ss_find_char (stop_set, ss.string[i]) != SIZE_MAX)
585 /* Returns the offset in SS of the first instance of C,
586 or SIZE_MAX if C does not occur in SS. */
588 ss_find_char (struct substring ss, char c)
590 const char *p = memchr (ss.string, c, ss.length);
591 return p != NULL ? p - ss.string : SIZE_MAX;
594 /* Compares A and B and returns a strcmp()-type comparison
597 ss_compare (struct substring a, struct substring b)
599 int retval = memcmp (a.string, b.string, MIN (a.length, b.length));
601 retval = a.length < b.length ? -1 : a.length > b.length;
605 /* Returns the position in SS that the character at P occupies.
606 P must point within SS or one past its end. */
608 ss_pointer_to_position (struct substring ss, const char *p)
610 size_t pos = p - ss.string;
611 assert (pos <= ss.length);
615 /* Allocates and returns a null-terminated string that contains
618 ss_xstrdup (struct substring ss)
620 char *s = xmalloc (ss.length + 1);
621 memcpy (s, ss.string, ss.length);
626 /* Initializes ST as an empty string. */
628 ds_init_empty (struct string *st)
630 st->ss = ss_empty ();
634 /* Initializes ST with initial contents S. */
636 ds_init_string (struct string *st, const struct string *s)
638 ds_init_substring (st, ds_ss (s));
641 /* Initializes ST with initial contents SS. */
643 ds_init_substring (struct string *st, struct substring ss)
645 st->capacity = MAX (8, ss.length * 2);
646 st->ss.string = xmalloc (st->capacity + 1);
647 memcpy (st->ss.string, ss.string, ss.length);
648 st->ss.length = ss.length;
651 /* Initializes ST with initial contents S. */
653 ds_init_cstr (struct string *st, const char *s)
655 ds_init_substring (st, ss_cstr (s));
660 ds_destroy (struct string *st)
664 ss_dealloc (&st->ss);
665 st->ss.string = NULL;
671 /* Swaps the contents of strings A and B. */
673 ds_swap (struct string *a, struct string *b)
675 struct string tmp = *a;
680 /* Helper function for ds_register_pool. */
682 free_string (void *st_)
684 struct string *st = st_;
688 /* Arranges for ST to be destroyed automatically as part of
691 ds_register_pool (struct string *st, struct pool *pool)
693 pool_register (pool, free_string, st);
696 /* Cancels the arrangement for ST to be destroyed automatically
699 ds_unregister_pool (struct string *st, struct pool *pool)
701 pool_unregister (pool, st);
704 /* Copies SRC into DST.
705 DST and SRC may be the same string. */
707 ds_assign_string (struct string *dst, const struct string *src)
709 ds_assign_substring (dst, ds_ss (src));
712 /* Replaces DST by SS.
713 SS may be a substring of DST. */
715 ds_assign_substring (struct string *dst, struct substring ss)
717 dst->ss.length = ss.length;
718 ds_extend (dst, ss.length);
719 memmove (dst->ss.string, ss.string, ss.length);
722 /* Replaces DST by null-terminated string SRC. SRC may overlap
725 ds_assign_cstr (struct string *dst, const char *src)
727 ds_assign_substring (dst, ss_cstr (src));
730 /* Truncates ST to zero length. */
732 ds_clear (struct string *st)
737 /* Returns a substring that contains ST. */
739 ds_ss (const struct string *st)
744 /* Returns a substring that contains CNT characters from ST
745 starting at position START.
747 If START is greater than or equal to the length of ST, then
748 the substring will be the empty string. If START + CNT
749 exceeds the length of ST, then the substring will only be
750 ds_length(ST) - START characters long. */
752 ds_substr (const struct string *st, size_t start, size_t cnt)
754 return ss_substr (ds_ss (st), start, cnt);
757 /* Returns a substring that contains the first CNT characters in
758 ST. If CNT exceeds the length of ST, then the substring will
759 contain all of ST. */
761 ds_head (const struct string *st, size_t cnt)
763 return ss_head (ds_ss (st), cnt);
766 /* Returns a substring that contains the last CNT characters in
767 ST. If CNT exceeds the length of ST, then the substring will
768 contain all of ST. */
770 ds_tail (const struct string *st, size_t cnt)
772 return ss_tail (ds_ss (st), cnt);
775 /* Ensures that ST can hold at least MIN_CAPACITY characters plus a null
778 ds_extend (struct string *st, size_t min_capacity)
780 if (min_capacity > st->capacity)
783 if (st->capacity < min_capacity)
784 st->capacity = 2 * min_capacity;
786 st->ss.string = xrealloc (st->ss.string, st->capacity + 1);
790 /* Shrink ST to the minimum capacity need to contain its content. */
792 ds_shrink (struct string *st)
794 if (st->capacity != st->ss.length)
796 st->capacity = st->ss.length;
797 st->ss.string = xrealloc (st->ss.string, st->capacity + 1);
801 /* Truncates ST to at most LENGTH characters long. */
803 ds_truncate (struct string *st, size_t length)
805 ss_truncate (&st->ss, length);
808 /* Removes trailing characters in TRIM_SET from ST.
809 Returns number of characters removed. */
811 ds_rtrim (struct string *st, struct substring trim_set)
813 return ss_rtrim (&st->ss, trim_set);
816 /* Removes leading characters in TRIM_SET from ST.
817 Returns number of characters removed. */
819 ds_ltrim (struct string *st, struct substring trim_set)
821 size_t cnt = ds_span (st, trim_set);
823 ds_assign_substring (st, ds_substr (st, cnt, SIZE_MAX));
827 /* Trims leading and trailing characters in TRIM_SET from ST.
828 Returns number of charactesr removed. */
830 ds_trim (struct string *st, struct substring trim_set)
832 size_t cnt = ds_rtrim (st, trim_set);
833 return cnt + ds_ltrim (st, trim_set);
836 /* If the last character in ST is C, removes it and returns true.
837 Otherwise, returns false without modifying ST. */
839 ds_chomp (struct string *st, char c)
841 return ss_chomp (&st->ss, c);
844 /* Divides ST into tokens separated by any of the DELIMITERS.
845 Each call replaces TOKEN by the next token in ST, or by an
846 empty string if no tokens remain. Returns true if a token was
847 obtained, false otherwise.
849 Before the first call, initialize *SAVE_IDX to 0. Do not
850 modify *SAVE_IDX between calls.
852 ST divides into exactly one more tokens than it contains
853 delimiters. That is, a delimiter at the start or end of ST or
854 a pair of adjacent delimiters yields an empty token, and the
855 empty string contains a single token. */
857 ds_separate (const struct string *st, struct substring delimiters,
858 size_t *save_idx, struct substring *token)
860 return ss_separate (ds_ss (st), delimiters, save_idx, token);
863 /* Divides ST into tokens separated by any of the DELIMITERS,
864 merging adjacent delimiters so that the empty string is never
865 produced as a token. Each call replaces TOKEN by the next
866 token in ST, or by an empty string if no tokens remain.
867 Returns true if a token was obtained, false otherwise.
869 Before the first call, initialize *SAVE_IDX to 0. Do not
870 modify *SAVE_IDX between calls. */
872 ds_tokenize (const struct string *st, struct substring delimiters,
873 size_t *save_idx, struct substring *token)
875 return ss_tokenize (ds_ss (st), delimiters, save_idx, token);
878 /* Pad ST on the right with copies of PAD until ST is at least
879 LENGTH characters in size. If ST is initially LENGTH
880 characters or longer, this is a no-op. */
882 ds_rpad (struct string *st, size_t length, char pad)
884 if (length > st->ss.length)
885 ds_put_char_multiple (st, pad, length - st->ss.length);
888 /* Sets the length of ST to exactly NEW_LENGTH,
889 either by truncating characters from the end,
890 or by padding on the right with PAD. */
892 ds_set_length (struct string *st, size_t new_length, char pad)
894 if (st->ss.length < new_length)
895 ds_rpad (st, new_length, pad);
897 st->ss.length = new_length;
900 /* Returns true if ST is empty, false otherwise. */
902 ds_is_empty (const struct string *st)
904 return ss_is_empty (st->ss);
907 /* Returns the length of ST. */
909 ds_length (const struct string *st)
911 return ss_length (ds_ss (st));
914 /* Returns the string data inside ST. */
916 ds_data (const struct string *st)
918 return ss_data (ds_ss (st));
921 /* Returns a pointer to the null terminator ST.
922 This might not be an actual null character unless ds_c_str() has
923 been called since the last modification to ST. */
925 ds_end (const struct string *st)
927 return ss_end (ds_ss (st));
930 /* Returns the character in position IDX in ST, as a value in the
931 range of unsigned char. Returns EOF if IDX is out of the
932 range of indexes for ST. */
934 ds_at (const struct string *st, size_t idx)
936 return ss_at (ds_ss (st), idx);
939 /* Returns the first character in ST as a value in the range of
940 unsigned char. Returns EOF if ST is the empty string. */
942 ds_first (const struct string *st)
944 return ss_first (ds_ss (st));
947 /* Returns the last character in ST as a value in the range of
948 unsigned char. Returns EOF if ST is the empty string. */
950 ds_last (const struct string *st)
952 return ss_last (ds_ss (st));
955 /* Returns the number of consecutive characters at the beginning
956 of ST that are in SKIP_SET. */
958 ds_span (const struct string *st, struct substring skip_set)
960 return ss_span (ds_ss (st), skip_set);
963 /* Returns the number of consecutive characters at the beginning
964 of ST that are not in STOP_SET. */
966 ds_cspan (const struct string *st, struct substring stop_set)
968 return ss_cspan (ds_ss (st), stop_set);
971 /* Returns the position of the first occurrence of character C in
972 ST at or after position OFS, or SIZE_MAX if there is no such
975 ds_find_char (const struct string *st, char c)
977 return ss_find_char (ds_ss (st), c);
980 /* Compares A and B and returns a strcmp()-type comparison
983 ds_compare (const struct string *a, const struct string *b)
985 return ss_compare (ds_ss (a), ds_ss (b));
988 /* Returns the position in ST that the character at P occupies.
989 P must point within ST or one past its end. */
991 ds_pointer_to_position (const struct string *st, const char *p)
993 return ss_pointer_to_position (ds_ss (st), p);
996 /* Allocates and returns a null-terminated string that contains
999 ds_xstrdup (const struct string *st)
1001 return ss_xstrdup (ds_ss (st));
1004 /* Returns the allocation size of ST. */
1006 ds_capacity (const struct string *st)
1008 return st->capacity;
1011 /* Returns the value of ST as a null-terminated string. */
1013 ds_cstr (const struct string *st_)
1015 struct string *st = (struct string *) st_;
1016 if (st->ss.string == NULL)
1018 st->ss.string[st->ss.length] = '\0';
1019 return st->ss.string;
1022 /* Appends to ST a newline-terminated line read from STREAM.
1023 Newline is the last character of ST on return, unless an I/O error
1024 or end of file is encountered after reading some characters.
1025 Returns true if a line is successfully read, false if no characters at
1026 all were read before an I/O error or end of file was
1029 ds_read_line (struct string *st, FILE *stream)
1039 ds_put_char (st, c);
1049 /* Removes a comment introduced by `#' from ST,
1050 ignoring occurrences inside quoted strings. */
1052 remove_comment (struct string *st)
1057 for (cp = ds_data (st); cp < ds_end (st); cp++)
1062 else if (*cp == '\\')
1065 else if (*cp == '\'' || *cp == '"')
1067 else if (*cp == '#')
1069 ds_truncate (st, cp - ds_cstr (st));
1074 /* Reads a line from STREAM into ST, then preprocesses as follows:
1076 - Splices lines terminated with `\'.
1078 - Deletes comments introduced by `#' outside of single or double
1081 - Deletes trailing white space.
1083 Returns true if a line was successfully read, false on
1084 failure. If LINE_NUMBER is non-null, then *LINE_NUMBER is
1085 incremented by the number of lines read. */
1087 ds_read_config_line (struct string *st, int *line_number, FILE *stream)
1092 if (!ds_read_line (st, stream))
1095 ds_rtrim (st, ss_cstr (CC_SPACES));
1097 while (ds_chomp (st, '\\'));
1099 remove_comment (st);
1103 /* Attempts to read SIZE * CNT bytes from STREAM and append them
1105 Returns number of bytes actually read. */
1107 ds_read_stream (struct string *st, size_t size, size_t cnt, FILE *stream)
1111 size_t try_bytes = xtimes (cnt, size);
1112 if (size_in_bounds_p (xsum (ds_length (st), try_bytes)))
1114 char *buffer = ds_put_uninit (st, try_bytes);
1115 size_t got_bytes = fread (buffer, size, cnt, stream);
1116 ds_truncate (st, ds_length (st) - (try_bytes - got_bytes));
1123 /* Concatenates S onto ST. */
1125 ds_put_cstr (struct string *st, const char *s)
1128 ds_put_substring (st, ss_cstr (s));
1131 /* Concatenates SS to ST. */
1133 ds_put_substring (struct string *st, struct substring ss)
1135 memcpy (ds_put_uninit (st, ss_length (ss)), ss_data (ss), ss_length (ss));
1138 /* Returns ds_end(ST) and THEN increases the length by INCR. */
1140 ds_put_uninit (struct string *st, size_t incr)
1143 ds_extend (st, ds_length (st) + incr);
1145 st->ss.length += incr;
1149 /* Formats FORMAT as a printf string and appends the result to ST. */
1151 ds_put_format (struct string *st, const char *format, ...)
1155 va_start (args, format);
1156 ds_put_vformat (st, format, args);
1160 /* Formats FORMAT as a printf string and appends the result to ST. */
1162 ds_put_vformat (struct string *st, const char *format, va_list args_)
1167 va_copy (args, args_);
1168 avail = st->ss.string != NULL ? st->capacity - st->ss.length + 1 : 0;
1169 needed = vsnprintf (st->ss.string + st->ss.length, avail, format, args);
1172 if (needed >= avail)
1174 va_copy (args, args_);
1175 vsprintf (ds_put_uninit (st, needed), format, args);
1180 /* Some old libc's returned -1 when the destination string
1182 while (needed == -1)
1184 ds_extend (st, (st->capacity + 1) * 2);
1185 avail = st->capacity - st->ss.length + 1;
1187 va_copy (args, args_);
1188 needed = vsnprintf (ds_end (st), avail, format, args);
1191 st->ss.length += needed;
1195 /* Appends character CH to ST. */
1197 ds_put_char (struct string *st, int ch)
1199 ds_put_uninit (st, 1)[0] = ch;
1202 /* Appends CNT copies of character CH to ST. */
1204 ds_put_char_multiple (struct string *st, int ch, size_t cnt)
1206 memset (ds_put_uninit (st, cnt), ch, cnt);