From 997bb3428312779a6f5af0264fa772407184ec17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Courr=C3=A8ges-Anglas?= Date: Sun, 17 Sep 2017 06:17:04 +0200 Subject: Rename concat_width to sbuf_utf8_nconcat, and move it to sbuf.c This function appends n UTF-8 characters to its sbuf parameter. Falls back to bytes in a non-UTF-8 locale. If width = -1, it appends the whole input string. --- src/format.c | 55 +++++++++++++++---------------------------------------- src/sbuf.c | 27 +++++++++++++++++++++++++++ src/sbuf.h | 1 + 3 files changed, 43 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/format.c b/src/format.c index f9d0ed4..ed1f571 100644 --- a/src/format.c +++ b/src/format.c @@ -76,31 +76,6 @@ struct fmt_item fmt_items[] = { { 0, NULL } }; -/* if width >= 0 then limit the width of s to width UTF-8 chars. */ -static void -concat_width (struct sbuf *buf, char *s, int width) -{ - if (width >= 0) - { - int len, nchars; - - len = nchars = 0; - while (s[len] != '\0' && nchars < width) - { - if (RP_IS_UTF8_START (s[len])) - do - len++; - while (RP_IS_UTF8_CONT (s[len])); - else - len++; - nchars++; - } - sbuf_printf_concat (buf, "%.*s", len, s); - } - else - sbuf_concat (buf, s); -} - void format_string (char *fmt, rp_window_elem *win_elem, struct sbuf *buffer) { @@ -147,7 +122,7 @@ format_string (char *fmt, rp_window_elem *win_elem, struct sbuf *buffer) { sbuf_clear (retbuf); fmt_items[fip].fmt_fn(win_elem, retbuf); - concat_width (buffer, sbuf_get (retbuf), width); + sbuf_utf8_nconcat (buffer, sbuf_get (retbuf), width); found = 1; break; } @@ -327,7 +302,7 @@ fmt_pid (rp_window_elem *elem, struct sbuf *buf) #include #include -void rtp_test_concat_width(void); +void test_sbuf_utf8_nconcat(void); int main(void) { @@ -335,48 +310,48 @@ int main(void) correctly. */ setlocale(LC_ALL, ""); - rtp_test_concat_width(); + test_sbuf_utf8_nconcat(); return 0; } -void rtp_test_concat_width(void) +void test_sbuf_utf8_nconcat(void) { struct sbuf *buf = NULL; /* Zero length string, no limit. */ buf = sbuf_new(0); - concat_width(buf, "", -1); + sbuf_utf8_nconcat(buf, "", -1); assert(strcmp(sbuf_get(buf), "") == 0); sbuf_free(buf); /* Zero length string, non-zero limit. */ buf = sbuf_new(0); - concat_width(buf, "", 5); + sbuf_utf8_nconcat(buf, "", 5); assert(strcmp(sbuf_get(buf), "") == 0); sbuf_free(buf); /* ASCII string, no limit. */ buf = sbuf_new(0); - concat_width(buf, "hi there", -1); + sbuf_utf8_nconcat(buf, "hi there", -1); assert(strcmp(sbuf_get(buf), "hi there") == 0); - concat_width(buf, " you", -1); + sbuf_utf8_nconcat(buf, " you", -1); assert(strcmp(sbuf_get(buf), "hi there you") == 0); sbuf_free(buf); /* ASCII string, non-zero limit, truncated. */ buf = sbuf_new(0); - concat_width(buf, "hi there", 4); + sbuf_utf8_nconcat(buf, "hi there", 4); assert(strcmp(sbuf_get(buf), "hi t") == 0); sbuf_free(buf); /* ASCII string, non-zero limit, not truncated. */ buf = sbuf_new(0); - concat_width(buf, "hi", 4); + sbuf_utf8_nconcat(buf, "hi", 4); assert(strcmp(sbuf_get(buf), "hi") == 0); sbuf_free(buf); @@ -384,7 +359,7 @@ void rtp_test_concat_width(void) buf = sbuf_new(0); /* 0xe2 0x84 0xa2 is U+2122, the trademark symbol. */ - concat_width(buf, "hi \xe2\x84\xa2 there", -1); + sbuf_utf8_nconcat(buf, "hi \xe2\x84\xa2 there", -1); assert(strcmp(sbuf_get(buf), "hi \xe2\x84\xa2 there") == 0); sbuf_free(buf); @@ -392,7 +367,7 @@ void rtp_test_concat_width(void) by bytes or by characters. */ buf = sbuf_new(0); - concat_width(buf, "hi \xe2\x84\xa2 there you", 11); + sbuf_utf8_nconcat(buf, "hi \xe2\x84\xa2 there you", 11); assert(strcmp(sbuf_get(buf), "hi \xe2\x84\xa2 there ") == 0); sbuf_free(buf); @@ -400,14 +375,14 @@ void rtp_test_concat_width(void) bytes that we would cut in the middle of a character. */ buf = sbuf_new(0); - concat_width(buf, "hi \xe2\x84\xa2 there you", 5); + sbuf_utf8_nconcat(buf, "hi \xe2\x84\xa2 there you", 5); assert(strcmp(sbuf_get(buf), "hi \xe2\x84\xa2 ") == 0); sbuf_free(buf); /* UTF-8 string, non-zero limit, not truncated. */ buf = sbuf_new(0); - concat_width(buf, "hi \xe2\x84\xa2 there you", 20); + sbuf_utf8_nconcat(buf, "hi \xe2\x84\xa2 there you", 20); assert(strcmp(sbuf_get(buf), "hi \xe2\x84\xa2 there you") == 0); sbuf_free(buf); @@ -415,7 +390,7 @@ void rtp_test_concat_width(void) buf = sbuf_new(0); /* This is an invalid UTF-8 sequence. It's missing 0xa2. */ - concat_width(buf, "hi \xe2\x84 there you", 20); + sbuf_utf8_nconcat(buf, "hi \xe2\x84 there you", 20); assert(strcmp(sbuf_get(buf), "hi ") == 0); sbuf_free(buf); } diff --git a/src/sbuf.c b/src/sbuf.c index 661ec83..ceac839 100644 --- a/src/sbuf.c +++ b/src/sbuf.c @@ -145,6 +145,33 @@ sbuf_printf_concat (struct sbuf *b, char *fmt, ...) return b->data; } +/* if width >= 0 then limit the width of s to width chars. */ +char * +sbuf_utf8_nconcat (struct sbuf *b, const char *s, int width) +{ + if (width >= 0) + { + int len, nchars; + + len = nchars = 0; + while (s[len] != '\0' && nchars < width) + { + if (RP_IS_UTF8_START (s[len])) + do + len++; + while (RP_IS_UTF8_CONT (s[len])); + else + len++; + nchars++; + } + sbuf_printf_concat (b, "%.*s", len, s); + } + else + sbuf_concat (b, s); + + return b->data; +} + void sbuf_chop (struct sbuf *b) { diff --git a/src/sbuf.h b/src/sbuf.h index e565efc..820d564 100644 --- a/src/sbuf.h +++ b/src/sbuf.h @@ -39,6 +39,7 @@ void sbuf_free (struct sbuf *b); char *sbuf_free_struct (struct sbuf *b); char *sbuf_concat (struct sbuf *b, const char *str); char *sbuf_nconcat (struct sbuf *b, const char *str, int len); +char *sbuf_utf8_nconcat (struct sbuf *b, const char *s, int width); char *sbuf_copy (struct sbuf *b, const char *str); char *sbuf_clear (struct sbuf *b); char *sbuf_get (struct sbuf *b); -- cgit v1.2.3