summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJérémie Courrèges-Anglas <jca@wxcvbn.org>2017-09-17 05:11:16 +0200
committerJérémie Courrèges-Anglas <jca@wxcvbn.org>2017-09-17 19:00:07 +0200
commit1b4c4842050368854698402e79f2c021c33dd6d8 (patch)
tree2c13535fc86f7335c235e5a9f193641af3bdea4b
parent8d9df79e6410ff0c56a87049bf736ceaa1986f2d (diff)
downloadratpoison-1b4c4842050368854698402e79f2c021c33dd6d8.zip
Handle UTF-8 in concat_width()
Ensure that we don't truncate UTF-8 characters in %42s-style format strings. Prompted by a similar diff by Will Storey <will@summercat.com>, that made use of the wide char API. I find it simpler to just handle UTF-8.
-rw-r--r--src/format.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/src/format.c b/src/format.c
index caf8781..db903e3 100644
--- a/src/format.c
+++ b/src/format.c
@@ -76,17 +76,26 @@ struct fmt_item fmt_items[] = {
{ 0, NULL }
};
-/* if width >= 0 then limit the width of s to width chars. */
+/* 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)
{
- char *s1 = xsprintf ("%%.%ds", width);
- char *s2 = xsprintf (s1, s);
- sbuf_concat (buf, s2);
- free (s1);
- free (s2);
+ 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);