-/*
- * charstring -- dynamically-sized char array that can report size
+/* charstring.c -- dynamically-sized char array that can report size
* in both characters and bytes
*
* This code is Copyright (c) 2014, by the authors of nmh. See the
* complete copyright information.
*/
-#include <h/mh.h>
-#include <h/utils.h>
+#include "h/mh.h"
+#include "h/utils.h"
#ifdef MULTIBYTE_SUPPORT
# define NMH_MAX_CHARWIDTH MB_CUR_MAX
static void
-charstring_reserve (charstring_t s, size_t need) {
+charstring_reserve (charstring_t s, size_t need)
+{
const size_t cur = s->cur - s->buffer;
while (need >= s->max - cur) {
* max is in characters
*/
charstring_t
-charstring_create (size_t max) {
- charstring_t s = mh_xmalloc (sizeof *s);
+charstring_create (size_t max)
+{
+ charstring_t s;
+ NEW(s);
s->max = NMH_MAX_CHARWIDTH * (max ? max : CHARSTRING_DEFAULT_SIZE);
s->cur = s->buffer = mh_xmalloc (s->max);
s->chars = 0;
}
charstring_t
-charstring_copy (const charstring_t src) {
+charstring_copy (const charstring_t src)
+{
const size_t num = src->cur - src->buffer;
- charstring_t s = mh_xmalloc (sizeof *s);
+ charstring_t s;
+ NEW(s);
s->max = src->max;
s->buffer = mh_xmalloc (s->max);
memcpy (s->buffer, src->buffer, num);
* OK to call charstring_free with a NULL argument.
*/
void
-charstring_free (charstring_t s) {
+charstring_free (charstring_t s)
+{
if (s) {
free (s->buffer);
free (s);
}
void
-charstring_push_back (charstring_t s, const char c) {
+charstring_push_back (charstring_t s, const char c)
+{
charstring_reserve (s, s->cur - s->buffer + 1);
*s->cur++ = c;
++s->chars;
*/
void
charstring_push_back_chars (charstring_t s, const char c[], size_t num,
- size_t width) {
+ size_t width)
+{
size_t i;
charstring_reserve (s, s->cur - s->buffer + num);
}
void
-charstring_append (charstring_t dest, const charstring_t src) {
+charstring_append (charstring_t dest, const charstring_t src)
+{
const size_t num = src->cur - src->buffer;
if (num > 0) {
- charstring_reserve (dest, num + (dest->cur - dest->buffer));
+ charstring_reserve (dest, dest->cur - dest->buffer + num);
memcpy (dest->cur, src->buffer, num);
dest->cur += num;
dest->chars += src->chars;
}
void
-charstring_clear (charstring_t s) {
+charstring_append_cstring (charstring_t dest, const char src[])
+{
+ const size_t num = strlen (src);
+
+ if (num > 0) {
+ charstring_reserve (dest, dest->cur - dest->buffer + num);
+ memcpy (dest->cur, src, num); /* Exclude src's trailing newline. */
+ dest->cur += num;
+ dest->chars += num;
+ }
+}
+
+void
+charstring_clear (charstring_t s)
+{
s->cur = s->buffer;
s->chars = 0;
}
* intervening push_back's; use charstring_buffer_copy() instead.
*/
const char *
-charstring_buffer (const charstring_t s) {
+charstring_buffer (const charstring_t s)
+{
charstring_reserve (s, s->cur - s->buffer + 1);
/* This is the only place that we null-terminate the buffer. */
}
char *
-charstring_buffer_copy (const charstring_t s) {
- char *copy = strdup (charstring_buffer (s));
-
- if (copy) {
- return copy;
- } else {
- advise ("strdup", "unable to copy charstring buffer");
- return NULL;
- }
+charstring_buffer_copy (const charstring_t s)
+{
+ char *copy = mh_xmalloc (s->cur - s->buffer + 1);
+
+ /* Use charstring_buffer() to null terminate the buffer. */
+ memcpy (copy, charstring_buffer (s), s->cur - s->buffer + 1);
+
+ return copy;
}
size_t
-charstring_bytes (const charstring_t s) {
+charstring_bytes (const charstring_t s)
+{
return s->cur - s->buffer;
}
size_t
-charstring_chars (const charstring_t s) {
+charstring_chars (const charstring_t s)
+{
return s->chars;
}
int
-charstring_last_char_len (const charstring_t s) {
+charstring_last_char_len (const charstring_t s)
+{
int len = 0;
#ifdef MULTIBYTE_SUPPORT
const char *sp = charstring_buffer (s);
size_t remaining = charstring_bytes (s);
- (void) mbtowc (NULL, NULL, 0); /* reset shift state */
+ if (mbtowc (NULL, NULL, 0)) {} /* reset shift state */
while (*sp && remaining > 0) {
wchar_t wide_char;
- len = mbtowc (&wide_char, sp,
- (size_t) MB_CUR_MAX < remaining ? MB_CUR_MAX : remaining);
- sp += len > 0 ? len : 1;
- remaining -= len > 0 ? len : 1;
+ len = mbtowc (&wide_char, sp, (size_t) MB_CUR_MAX < remaining
+ ? (size_t) MB_CUR_MAX
+ : remaining);
+ sp += max(len, 1);
+ remaining -= max(len, 1);
}
#else /* ! MULTIBYTE_SUPPORT */
if (charstring_bytes (s) > 0) { len = 1; }