X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/52391b538640f320acb25a66b673042c51567f61..865cc1bd7e146d8a3fe44ede30d834f7ab0c195c:/sbr/charstring.c?ds=inline diff --git a/sbr/charstring.c b/sbr/charstring.c index 2119be97..8f8b5ea5 100644 --- a/sbr/charstring.c +++ b/sbr/charstring.c @@ -1,5 +1,4 @@ -/* - * 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 @@ -7,8 +6,8 @@ * complete copyright information. */ -#include -#include +#include "h/mh.h" +#include "h/utils.h" #ifdef MULTIBYTE_SUPPORT # define NMH_MAX_CHARWIDTH MB_CUR_MAX @@ -27,7 +26,8 @@ struct charstring { 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) { @@ -41,9 +41,11 @@ charstring_reserve (charstring_t s, size_t need) { * 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; @@ -52,10 +54,12 @@ charstring_create (size_t max) { } 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); @@ -69,7 +73,8 @@ charstring_copy (const charstring_t src) { * 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); @@ -77,7 +82,8 @@ charstring_free (charstring_t 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; @@ -89,7 +95,8 @@ charstring_push_back (charstring_t s, const char c) { */ 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); @@ -98,11 +105,12 @@ charstring_push_back_chars (charstring_t s, const char c[], size_t 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; @@ -110,7 +118,21 @@ charstring_append (charstring_t dest, const charstring_t src) { } 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; } @@ -120,7 +142,8 @@ charstring_clear (charstring_t s) { * 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. */ @@ -133,43 +156,46 @@ charstring_buffer (const charstring_t s) { } 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; }