about summary refs log tree commit diff
path: root/pls.c
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2018-08-20 18:41:23 -0400
committerJune McEnroe <june@causal.agency>2018-08-20 18:43:16 -0400
commit4e4eb0de0f50517e3a2892cddcadfbd75da7152f (patch)
treecebf2ed9f1cc63b5714e2c9357f8b9ff27f10afc /pls.c
parentSet errno in vaswprintf in case vswprintf does not (diff)
downloadcatgirl-4e4eb0de0f50517e3a2892cddcadfbd75da7152f.tar.gz
catgirl-4e4eb0de0f50517e3a2892cddcadfbd75da7152f.zip
Add wcsnchr, wcsnrchr, awcsntombs
This eliminates calls to editHead and editTail inside edit.c.

Oh god I'm sorry for following libc naming conventions for this stuff.
Diffstat (limited to 'pls.c')
-rw-r--r--pls.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/pls.c b/pls.c
index d768b8f..08309f8 100644
--- a/pls.c
+++ b/pls.c
@@ -22,6 +22,22 @@
 
 #include "chat.h"
 
+wchar_t *wcsnchr(const wchar_t *wcs, size_t len, wchar_t chr) {
+	len = wcsnlen(wcs, len);
+	for (size_t i = 0; i < len; ++i) {
+		if (wcs[i] == chr) return (wchar_t *)&wcs[i];
+	}
+	return NULL;
+}
+
+wchar_t *wcsnrchr(const wchar_t *wcs, size_t len, wchar_t chr) {
+	len = wcsnlen(wcs, len);
+	for (size_t i = len - 1; i < len; --i) {
+		if (wcs[i] == chr) return (wchar_t *)&wcs[i];
+	}
+	return NULL;
+}
+
 wchar_t *ambstowcs(const char *src) {
 	size_t len = mbsrtowcs(NULL, &src, 0, NULL);
 	if (len == (size_t)-1) return NULL;
@@ -54,6 +70,22 @@ char *awcstombs(const wchar_t *src) {
 	return dst;
 }
 
+char *awcsntombs(const wchar_t *src, size_t nwc) {
+	size_t len = wcsnrtombs(NULL, &src, nwc, 0, NULL);
+	if (len == (size_t)-1) return NULL;
+
+	char *dst = malloc(sizeof(*dst) * (1 + len));
+	if (!dst) return NULL;
+
+	len = wcsnrtombs(dst, &src, nwc, 1 + len, NULL);
+	if (len == (size_t)-1) {
+		free(dst);
+		return NULL;
+	}
+
+	return dst;
+}
+
 // From <https://en.cppreference.com/w/c/io/fwprintf#Notes>:
 //
 // While narrow strings provide snprintf, which makes it possible to determine