void
str_copy_rpad (char *dst, size_t dst_size, const char *src)
{
- size_t src_len = strlen (src);
- if (src_len < dst_size - 1)
+ if (dst_size > 0)
{
- memcpy (dst, src, src_len);
- memset (&dst[src_len], ' ', dst_size - 1 - src_len);
+ size_t src_len = strlen (src);
+ if (src_len < dst_size - 1)
+ {
+ memcpy (dst, src, src_len);
+ memset (&dst[src_len], ' ', dst_size - 1 - src_len);
+ }
+ else
+ memcpy (dst, src, dst_size - 1);
+ dst[dst_size - 1] = 0;
}
- else
- memcpy (dst, src, dst_size - 1);
- dst[dst_size - 1] = 0;
}
/* Copies SRC to DST, which is in a buffer DST_SIZE bytes long.
return false;
}
+/* If the first character in SS is in MATCH, removes it and
+ returns the character that was removed.
+ Otherwise, returns EOF without changing the string. */
+int
+ss_match_char_in (struct substring *ss, struct substring match)
+{
+ int c = EOF;
+ if (ss->length > 0
+ && memchr (match.string, ss->string[0], match.length) != NULL)
+ {
+ c = ss->string[0];
+ ss->string++;
+ ss->length--;
+ }
+ return c;
+}
+
/* If SS begins with TARGET, removes it and returns true.
Otherwise, returns false without changing SS. */
bool
return st->ss.string;
}
-/* Appends to ST a newline-terminated line read from STREAM.
- Newline is the last character of ST on return, unless an I/O error
- or end of file is encountered after reading some characters.
- Returns true if a line is successfully read, false if no characters at
- all were read before an I/O error or end of file was
- encountered. */
+/* Appends to ST a newline-terminated line read from STREAM, but
+ no more than MAX_LENGTH characters.
+ Newline is the last character of ST on return, if encountering
+ a newline was the reason for terminating.
+ Returns true if at least one character was read from STREAM
+ and appended to ST, false if no characters at all were read
+ before an I/O error or end of file was encountered (or
+ MAX_LENGTH was 0). */
bool
-ds_read_line (struct string *st, FILE *stream)
+ds_read_line (struct string *st, FILE *stream, size_t max_length)
{
- int c;
+ if (!st->ss.length && max_length == SIZE_MAX)
+ {
+ size_t capacity = st->capacity ? st->capacity + 1 : 0;
+ ssize_t n = getline (&st->ss.string, &capacity, stream);
+ if (capacity)
+ st->capacity = capacity - 1;
+ if (n > 0)
+ {
+ st->ss.length = n;
+ return true;
+ }
+ else
+ return false;
+ }
+ else
+ {
+ size_t length;
- c = getc (stream);
- if (c == EOF)
- return false;
+ for (length = 0; length < max_length; length++)
+ {
+ int c = getc (stream);
+ if (c == EOF)
+ break;
- for (;;)
- {
- ds_put_char (st, c);
- if (c == '\n')
- return true;
+ ds_put_char (st, c);
+ if (c == '\n')
+ return true;
+ }
- c = getc (stream);
- if (c == EOF)
- return true;
+ return length > 0;
}
}
ds_clear (st);
do
{
- if (!ds_read_line (st, stream))
+ if (!ds_read_line (st, stream, SIZE_MAX))
return false;
(*line_number)++;
ds_rtrim (st, ss_cstr (CC_SPACES));