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[]); 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); wchar_t *ambstowcs(const char *src);
char *awcstombs(const wchar_t *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); int vaswprintf(wchar_t **ret, const wchar_t *format, va_list ap);
// HACK: clang won't check wchar_t *format strings. // 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) { static void backWord(void) {
left(); left();
editHead(); wchar_t *word = wcsnrchr(line.buf, line.ptr - line.buf, L' ');
wchar_t *word = wcsrchr(line.buf, ' ');
editTail();
line.ptr = (word ? &word[1] : line.buf); line.ptr = (word ? &word[1] : line.buf);
} }
static void foreWord(void) { static void foreWord(void) {
right(); right();
editTail(); wchar_t *word = wcsnchr(line.ptr, line.end - line.ptr, L' ');
wchar_t *word = wcschr(line.ptr, ' ');
line.ptr = (word ? word : line.end); line.ptr = (word ? word : line.end);
} }
@ -108,12 +105,10 @@ static void killForeWord(void) {
static char *prefix; static char *prefix;
static void complete(struct Tag tag) { static void complete(struct Tag tag) {
if (!line.tab) { if (!line.tab) {
editHead(); line.tab = wcsnrchr(line.buf, line.ptr - line.buf, L' ');
line.tab = wcsrchr(line.buf, L' ');
line.tab = (line.tab ? &line.tab[1] : line.buf); 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"); if (!prefix) err(EX_DATAERR, "awcstombs");
editTail();
} }
const char *next = tabNext(tag, prefix); const char *next = tabNext(tag, prefix);
@ -161,7 +156,7 @@ static void reject(void) {
static void enter(struct Tag tag) { static void enter(struct Tag tag) {
if (line.end == line.buf) return; if (line.end == line.buf) return;
editTail(); *line.end = L'\0';
char *str = awcstombs(line.buf); char *str = awcstombs(line.buf);
if (!str) err(EX_DATAERR, "awcstombs"); if (!str) err(EX_DATAERR, "awcstombs");
input(tag, str); input(tag, str);

32
pls.c
View File

@ -22,6 +22,22 @@
#include "chat.h" #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) { wchar_t *ambstowcs(const char *src) {
size_t len = mbsrtowcs(NULL, &src, 0, NULL); size_t len = mbsrtowcs(NULL, &src, 0, NULL);
if (len == (size_t)-1) return NULL; if (len == (size_t)-1) return NULL;
@ -54,6 +70,22 @@ char *awcstombs(const wchar_t *src) {
return dst; 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>: // From <https://en.cppreference.com/w/c/io/fwprintf#Notes>:
// //
// While narrow strings provide snprintf, which makes it possible to determine // While narrow strings provide snprintf, which makes it possible to determine