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
parent
afae851319
commit
4e4eb0de0f
3
chat.h
3
chat.h
|
@ -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
15
edit.c
|
@ -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
32
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
|
||||
|
|
Loading…
Reference in New Issue