commit - ff991362a03e8c97d86863feb04f24f2fd2ff9e0
commit + 8d2a714bb6ebca6ba521846939ac1c7973bf04ad
blob - d38723107e71c74c6e1129fbecfeccf9f66eef7b
blob + 0860a0ee86bc7e87451725acb7f828415606fb03
--- rover.c
+++ rover.c
#include <stdlib.h>
#include <stdint.h>
#include <ctype.h>
+#include <wchar.h>
+#include <wctype.h>
#include <string.h>
#include <sys/types.h> /* pid_t, ... */
#include <stdio.h>
#include <limits.h> /* PATH_MAX */
#include <locale.h> /* setlocale(), LC_ALL */
-#include <wchar.h>
#include <unistd.h> /* chdir(), getcwd(), read(), close(), ... */
#include <dirent.h> /* DIR, struct dirent, opendir(), ... */
#include <sys/stat.h>
/* Line editing state. */
typedef struct Edit {
- char buffer[INPUTSZ-1];
+ wchar_t buffer[INPUTSZ+1];
int left, right;
} Edit;
while ((ch = getch()) == ERR)
sync_signals();
return ch;
+}
+
+/* This function must be used in place of get_wch().
+ It handles signals while waiting for user input. */
+static wint_t
+rover_get_wch()
+{
+ wint_t wch;
+
+ while (get_wch(&wch) == ERR)
+ sync_signals();
+ return wch;
}
/* Do a fork-exec to external program (e.g. $EDITOR). */
{
curs_set(TRUE);
strncpy(INPUT, init_input, INPUTSZ);
- strncpy(rover.edit.buffer, init_input, INPUTSZ);
- rover.edit.left = strlen(init_input);
+ rover.edit.left = mbstowcs(rover.edit.buffer, init_input, INPUTSZ);
rover.edit.right = INPUTSZ - 1;
+ rover.edit.buffer[INPUTSZ] = L'\0';
rover.edit_scroll = 0;
}
static EditStat
get_line_edit()
{
- int ch = rover_getch();
- if (ch == '\r' || ch == '\n' || ch == KEY_ENTER) {
+ wchar_t eraser, killer;
+ int length;
+ wint_t wch = rover_get_wch();
+
+ erasewchar(&eraser);
+ killwchar(&killer);
+ if (wch == L'\r' || wch == L'\n' || wch == KEY_ENTER) {
curs_set(FALSE);
return CONFIRM;
- } else if (ch == '\t') {
+ } else if (wch == L'\t') {
curs_set(FALSE);
return CANCEL;
- } else if (EDIT_CAN_LEFT(rover.edit) && ch == KEY_LEFT) {
- EDIT_LEFT(rover.edit);
- } else if (EDIT_CAN_RIGHT(rover.edit) && ch == KEY_RIGHT) {
- EDIT_RIGHT(rover.edit);
- } else if (ch == KEY_UP) {
+ } else if (wch == KEY_LEFT) {
+ if (EDIT_CAN_LEFT(rover.edit)) EDIT_LEFT(rover.edit);
+ } else if (wch == KEY_RIGHT) {
+ if (EDIT_CAN_RIGHT(rover.edit)) EDIT_RIGHT(rover.edit);
+ } else if (wch == KEY_UP) {
while (EDIT_CAN_LEFT(rover.edit)) EDIT_LEFT(rover.edit);
- } else if (ch == KEY_DOWN) {
+ } else if (wch == KEY_DOWN) {
while (EDIT_CAN_RIGHT(rover.edit)) EDIT_RIGHT(rover.edit);
- } else if (ch == erasechar() || ch == KEY_BACKSPACE) {
+ } else if (wch == eraser || wch == KEY_BACKSPACE) {
if (EDIT_CAN_LEFT(rover.edit)) EDIT_BACKSPACE(rover.edit);
- } else if (ch == KEY_DC) {
+ } else if (wch == KEY_DC) {
if (EDIT_CAN_RIGHT(rover.edit)) EDIT_DELETE(rover.edit);
- } else if (ch == killchar()) {
+ } else if (wch == killer) {
EDIT_CLEAR(rover.edit);
clear_message();
- } else if (!EDIT_FULL(rover.edit) && isprint(ch)) {
- EDIT_INSERT(rover.edit, ch);
+ } else if (iswprint(wch)) {
+ if (!EDIT_FULL(rover.edit)) EDIT_INSERT(rover.edit, wch);
}
- /* Copy edit contents to INPUT and append null character. */
- strncpy(INPUT, rover.edit.buffer, rover.edit.left);
- strncpy(&INPUT[rover.edit.left], &rover.edit.buffer[rover.edit.right+1],
- INPUTSZ-rover.edit.left-1);
- INPUT[rover.edit.left+INPUTSZ-rover.edit.right-1] = '\0';
+ /* Encode edit contents in INPUT. */
+ rover.edit.buffer[rover.edit.left] = L'\0';
+ length = wcstombs(INPUT, rover.edit.buffer, INPUTSZ);
+ wcstombs(&INPUT[length], &rover.edit.buffer[rover.edit.right+1],
+ INPUTSZ-length);
return CONTINUE;
}
int plen, ilen, maxlen;
plen = strlen(prompt);
- ilen = strlen(INPUT);
+ ilen = mbstowcs(NULL, INPUT, 0);
maxlen = STATUSPOS - plen - 2;
if (ilen - rover.edit_scroll < maxlen)
rover.edit_scroll = MAX(ilen - maxlen, 0);