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[]);
|
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
15
edit.c
|
@ -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
32
pls.c
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue