Blame SOURCES/0035-ucs2-document-things-a-little-better.patch

4e0e09
From ee7ba570f7c555f93f41badefb63397737ef7810 Mon Sep 17 00:00:00 2001
4e0e09
From: Peter Jones <pjones@redhat.com>
4e0e09
Date: Tue, 18 Jun 2019 13:12:39 -0400
4e0e09
Subject: [PATCH 35/63] ucs2: document things a little better
4e0e09
4e0e09
Signed-off-by: Peter Jones <pjones@redhat.com>
4e0e09
---
4e0e09
 src/ucs2.h | 135 +++++++++++++++++++++++++++++++++++++++--------------
4e0e09
 1 file changed, 100 insertions(+), 35 deletions(-)
4e0e09
4e0e09
diff --git a/src/ucs2.h b/src/ucs2.h
4e0e09
index 478de23b23f..3f8a41d8ccc 100644
4e0e09
--- a/src/ucs2.h
4e0e09
+++ b/src/ucs2.h
4e0e09
@@ -22,11 +22,20 @@
4e0e09
 #define ev_bits(val, mask, shift) \
4e0e09
 	(((val) & ((mask) << (shift))) >> (shift))
4e0e09
 
4e0e09
+/*
4e0e09
+ * ucs2len(): Count the number of characters in a UCS-2 string.
4e0e09
+ * s: a UCS-2 string
4e0e09
+ * limit: the maximum number of uint16_t bytepairs to examine
4e0e09
+ *
4e0e09
+ * returns the number of characters before NUL is found (i.e., excluding
4e0e09
+ * the NUL character).  If limit is non-negative, no character index above
4e0e09
+ * limit will be accessed, and the maximum return value is limit.
4e0e09
+ */
4e0e09
 static inline size_t UNUSED
4e0e09
-ucs2len(const void *vs, ssize_t limit)
4e0e09
+ucs2len(const void *s, ssize_t limit)
4e0e09
 {
4e0e09
 	ssize_t i;
4e0e09
-	const uint8_t *s8 = vs;
4e0e09
+	const uint8_t *s8 = s;
4e0e09
 
4e0e09
 	for (i = 0;
4e0e09
 	     i < (limit >= 0 ? limit : i+1) && !(s8[0] == 0 && s8[1] == 0);
4e0e09
@@ -35,6 +44,15 @@ ucs2len(const void *vs, ssize_t limit)
4e0e09
 	return i;
4e0e09
 }
4e0e09
 
4e0e09
+/*
4e0e09
+ * ucs2size(): count the number of bytes in use by a UCS-2 string.
4e0e09
+ * s: a UCS-2 string
4e0e09
+ * limit: the maximum number of uint16_t bytepairs to examine
4e0e09
+ *
4e0e09
+ * returns the number of bytes, including NUL, in the UCS-2 string s.  If
4e0e09
+ * limit is non-negative, no character index above limit will be accessed,
4e0e09
+ * and the maximum return value is limit.
4e0e09
+ */
4e0e09
 static inline size_t UNUSED
4e0e09
 ucs2size(const void *s, ssize_t limit)
4e0e09
 {
4e0e09
@@ -46,6 +64,18 @@ ucs2size(const void *s, ssize_t limit)
4e0e09
 	return rc;
4e0e09
 }
4e0e09
 
4e0e09
+/*
4e0e09
+ * utf8len(): Count the number of characters in a UTF-8 string.
4e0e09
+ * s: a UTF-8 string
4e0e09
+ * limit: the maximum number of bytes to examine
4e0e09
+ *
4e0e09
+ * returns the number of UTF-8 charters before NUL is found (i.e.,
4e0e09
+ * excluding the NUL character).  If limit is non-negative, no character
4e0e09
+ * index above limit will be accessed, and the maximum return value is
4e0e09
+ * limit.
4e0e09
+ *
4e0e09
+ * Caveat: only good up to 3-byte sequences.
4e0e09
+ */
4e0e09
 static inline size_t UNUSED NONNULL(1)
4e0e09
 utf8len(const unsigned char *s, ssize_t limit)
4e0e09
 {
4e0e09
@@ -63,6 +93,15 @@ utf8len(const unsigned char *s, ssize_t limit)
4e0e09
 	return j;
4e0e09
 }
4e0e09
 
4e0e09
+/*
4e0e09
+ * utf8size(): count the number of bytes in use by a UTF-8 string.
4e0e09
+ * s: a UTF-8 string
4e0e09
+ * limit: the maximum number of bytes to examine
4e0e09
+ *
4e0e09
+ * returns the number of bytes, including NUL, in the UTF-8 string s.
4e0e09
+ * If limit is non-negative, no character index above limit will be
4e0e09
+ * accessed, and the maximum return value is limit.
4e0e09
+ */
4e0e09
 static inline size_t UNUSED NONNULL(1)
4e0e09
 utf8size(const unsigned char *s, ssize_t limit)
4e0e09
 {
4e0e09
@@ -72,68 +111,94 @@ utf8size(const unsigned char *s, ssize_t limit)
4e0e09
 	return ret;
4e0e09
 }
4e0e09
 
4e0e09
+/*
4e0e09
+ * ucs2_to_utf8(): convert UCS-2 to UTF-8
4e0e09
+ * s: the UCS-2 string
4e0e09
+ * limit: the maximum number of characters to copy from s, including the
4e0e09
+ *	  NUL terminator, or -1 for no limit.
4e0e09
+ *
4e0e09
+ * returns an allocated string, into which at most limit - 1 characters of
4e0e09
+ * UTF-8 are translated from UCS-2.  The return value is *always*
4e0e09
+ * NUL-terminated.
4e0e09
+ */
4e0e09
 static inline unsigned char * UNUSED
4e0e09
-ucs2_to_utf8(const void * const voidchars, ssize_t limit)
4e0e09
+ucs2_to_utf8(const void * const s, ssize_t limit)
4e0e09
 {
4e0e09
 	ssize_t i, j;
4e0e09
-	unsigned char *ret;
4e0e09
-	const uint16_t * const chars = voidchars;
4e0e09
+	unsigned char *out, *ret;
4e0e09
+	const uint16_t * const chars = s;
4e0e09
 
4e0e09
 	if (limit < 0)
4e0e09
 		limit = ucs2len(chars, -1);
4e0e09
-	ret = malloc(limit * 6 + 1);
4e0e09
-	if (!ret)
4e0e09
+	out = malloc(limit * 6 + 1);
4e0e09
+	if (!out)
4e0e09
 		return NULL;
4e0e09
-	memset(ret, 0, limit * 6 +1);
4e0e09
+	memset(out, 0, limit * 6 +1);
4e0e09
 
4e0e09
 	for (i=0, j=0; chars[i] && i < (limit >= 0 ? limit : i+1); i++,j++) {
4e0e09
 		if (chars[i] <= 0x7f) {
4e0e09
-			ret[j] = chars[i];
4e0e09
+			out[j] = chars[i];
4e0e09
 		} else if (chars[i] > 0x7f && chars[i] <= 0x7ff) {
4e0e09
-			ret[j++] = 0xc0 | ev_bits(chars[i], 0x1f, 6);
4e0e09
-			ret[j]   = 0x80 | ev_bits(chars[i], 0x3f, 0);
4e0e09
+			out[j++] = 0xc0 | ev_bits(chars[i], 0x1f, 6);
4e0e09
+			out[j]   = 0x80 | ev_bits(chars[i], 0x3f, 0);
4e0e09
 #if 1
4e0e09
 		} else if (chars[i] > 0x7ff) {
4e0e09
-			ret[j++] = 0xe0 | ev_bits(chars[i], 0xf, 12);
4e0e09
-			ret[j++] = 0x80 | ev_bits(chars[i], 0x3f, 6);
4e0e09
-			ret[j]   = 0x80| ev_bits(chars[i], 0x3f, 0);
4e0e09
+			out[j++] = 0xe0 | ev_bits(chars[i], 0xf, 12);
4e0e09
+			out[j++] = 0x80 | ev_bits(chars[i], 0x3f, 6);
4e0e09
+			out[j]   = 0x80| ev_bits(chars[i], 0x3f, 0);
4e0e09
 		}
4e0e09
 #else
4e0e09
 		} else if (chars[i] > 0x7ff && chars[i] < 0x10000) {
4e0e09
-			ret[j++] = 0xe0 | ev_bits(chars[i], 0xf, 12);
4e0e09
-			ret[j++] = 0x80 | ev_bits(chars[i], 0x3f, 6);
4e0e09
-			ret[j]   = 0x80| ev_bits(chars[i], 0x3f, 0);
4e0e09
+			out[j++] = 0xe0 | ev_bits(chars[i], 0xf, 12);
4e0e09
+			out[j++] = 0x80 | ev_bits(chars[i], 0x3f, 6);
4e0e09
+			out[j]   = 0x80| ev_bits(chars[i], 0x3f, 0);
4e0e09
 		} else if (chars[i] > 0xffff && chars[i] < 0x200000) {
4e0e09
-			ret[j++] = 0xf0 | ev_bits(chars[i], 0x7, 18);
4e0e09
-			ret[j++] = 0x80 | ev_bits(chars[i], 0x3f, 12);
4e0e09
-			ret[j++] = 0x80 | ev_bits(chars[i], 0x3f, 6);
4e0e09
-			ret[j]   = 0x80| ev_bits(chars[i], 0x3f, 0);
4e0e09
+			out[j++] = 0xf0 | ev_bits(chars[i], 0x7, 18);
4e0e09
+			out[j++] = 0x80 | ev_bits(chars[i], 0x3f, 12);
4e0e09
+			out[j++] = 0x80 | ev_bits(chars[i], 0x3f, 6);
4e0e09
+			out[j]   = 0x80| ev_bits(chars[i], 0x3f, 0);
4e0e09
 		} else if (chars[i] > 0x1fffff && chars[i] < 0x4000000) {
4e0e09
-			ret[j++] = 0xf8 | ev_bits(chars[i], 0x3, 24);
4e0e09
-			ret[j++] = 0x80 | ev_bits(chars[i], 0x3f, 18);
4e0e09
-			ret[j++] = 0x80 | ev_bits(chars[i], 0x3f, 12);
4e0e09
-			ret[j++] = 0x80 | ev_bits(chars[i], 0x3f, 6);
4e0e09
-			ret[j]   = 0x80 | ev_bits(chars[i], 0x3f, 0);
4e0e09
+			out[j++] = 0xf8 | ev_bits(chars[i], 0x3, 24);
4e0e09
+			out[j++] = 0x80 | ev_bits(chars[i], 0x3f, 18);
4e0e09
+			out[j++] = 0x80 | ev_bits(chars[i], 0x3f, 12);
4e0e09
+			out[j++] = 0x80 | ev_bits(chars[i], 0x3f, 6);
4e0e09
+			out[j]   = 0x80 | ev_bits(chars[i], 0x3f, 0);
4e0e09
 		} else if (chars[i] > 0x3ffffff) {
4e0e09
-			ret[j++] = 0xfc | ev_bits(chars[i], 0x1, 30);
4e0e09
-			ret[j++] = 0x80 | ev_bits(chars[i], 0x3f, 24);
4e0e09
-			ret[j++] = 0x80 | ev_bits(chars[i], 0x3f, 18);
4e0e09
-			ret[j++] = 0x80 | ev_bits(chars[i], 0x3f, 12);
4e0e09
-			ret[j++] = 0x80 | ev_bits(chars[i], 0x3f, 6);
4e0e09
-			ret[j]   = 0x80 | ev_bits(chars[i], 0x3f, 0);
4e0e09
+			out[j++] = 0xfc | ev_bits(chars[i], 0x1, 30);
4e0e09
+			out[j++] = 0x80 | ev_bits(chars[i], 0x3f, 24);
4e0e09
+			out[j++] = 0x80 | ev_bits(chars[i], 0x3f, 18);
4e0e09
+			out[j++] = 0x80 | ev_bits(chars[i], 0x3f, 12);
4e0e09
+			out[j++] = 0x80 | ev_bits(chars[i], 0x3f, 6);
4e0e09
+			out[j]   = 0x80 | ev_bits(chars[i], 0x3f, 0);
4e0e09
 		}
4e0e09
 #endif
4e0e09
 	}
4e0e09
-	ret[j] = '\0';
4e0e09
+	out[j++] = '\0';
4e0e09
+	ret = realloc(out, j);
4e0e09
+	if (!ret) {
4e0e09
+		free(out);
4e0e09
+		return NULL;
4e0e09
+	}
4e0e09
 	return ret;
4e0e09
 }
4e0e09
 
4e0e09
+/*
4e0e09
+ * utf8_to_ucs2(): convert UTF-8 to UCS-2
4e0e09
+ * s: the destination buffer to write to.
4e0e09
+ * size: the size of the allocation to write to
4e0e09
+ * terminate: whether or not to add a terminator to the string
4e0e09
+ * utf8: the utf8 source
4e0e09
+ *
4e0e09
+ * returns the number of characters written to s, including the NUL
4e0e09
+ * terminator if "terminate" is true, or -1 on error.  In the case of an
4e0e09
+ * error, the buffer will not be modified.
4e0e09
+ */
4e0e09
 static inline ssize_t UNUSED NONNULL(4)
4e0e09
-utf8_to_ucs2(void *ucs2void, ssize_t size, int terminate, const unsigned char *utf8)
4e0e09
+utf8_to_ucs2(void *s, ssize_t size, bool terminate, const unsigned char *utf8)
4e0e09
 {
4e0e09
 	ssize_t req;
4e0e09
 	ssize_t i, j;
4e0e09
-	uint16_t *ucs2 = ucs2void;
4e0e09
+	uint16_t *ucs2 = s;
4e0e09
 	uint16_t val16;
4e0e09
 
4e0e09
 	if (!ucs2 && size > 0) {
4e0e09
-- 
4e0e09
2.26.2
4e0e09