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.
master
Curtis McEnroe 2018-08-20 18:41:23 -04:00
parent afae851319
commit 4e4eb0de0f
No known key found for this signature in database
GPG Key ID: CEA2F97ADCFCD77C
3 changed files with 40 additions and 10 deletions

3
chat.h
View File

@ -161,8 +161,11 @@ void logFmt(
void spawn(char *const argv[]);
wchar_t *wcsnchr(const wchar_t *wcs, size_t len, wchar_t chr);
wchar_t *wcsnrchr(const wchar_t *wcs, size_t len, wchar_t chr);
wchar_t *ambstowcs(const char *src);
char *awcstombs(const wchar_t *src);
char *awcsntombs(const wchar_t *src, size_t nwc);
int vaswprintf(wchar_t **ret, const wchar_t *format, va_list ap);
// HACK: clang won't check wchar_t *format strings.

15
edit.c
View File

@ -57,15 +57,12 @@ static void right(void) {
static void backWord(void) {
left();
editHead();
wchar_t *word = wcsrchr(line.buf, ' ');
editTail();
wchar_t *word = wcsnrchr(line.buf, line.ptr - line.buf, L' ');
line.ptr = (word ? &word[1] : line.buf);
}
static void foreWord(void) {
right();
editTail();
wchar_t *word = wcschr(line.ptr, ' ');
wchar_t *word = wcsnchr(line.ptr, line.end - line.ptr, L' ');
line.ptr = (word ? word : line.end);
}
@ -108,12 +105,10 @@ static void killForeWord(void) {
static char *prefix;
static void complete(struct Tag tag) {
if (!line.tab) {
editHead();
line.tab = wcsrchr(line.buf, L' ');
line.tab = wcsnrchr(line.buf, line.ptr - line.buf, L' ');
line.tab = (line.tab ? &line.tab[1] : line.buf);
prefix = awcstombs(line.tab);
prefix = awcsntombs(line.tab, line.ptr - line.tab);
if (!prefix) err(EX_DATAERR, "awcstombs");
editTail();
}
const char *next = tabNext(tag, prefix);
@ -161,7 +156,7 @@ static void reject(void) {
static void enter(struct Tag tag) {
if (line.end == line.buf) return;
editTail();
*line.end = L'\0';
char *str = awcstombs(line.buf);
if (!str) err(EX_DATAERR, "awcstombs");
input(tag, str);

32
pls.c
View File

@ -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