Synchronize libedit with NetBSD and activate UTF-8 support [1]

Differences with NetBSD
Reapply our local patches on top of it
Fix Unicode environement detection
Fix reading a line in unicode environment.
It allows /bin/sh to works in UTF-8 envs

Differential Revision:	https://reviews.freebsd.org/D1455
Reviewed by:	jilles, pfg
Obtained from:	NetBSD [1]
MFC after:	1 month
Relnotes:	yes
This commit is contained in:
Baptiste Daroussin 2015-01-09 07:40:56 +00:00
parent ec680ff8a8
commit c1a66a97f9
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=276881
48 changed files with 5153 additions and 3124 deletions

View File

@ -7,8 +7,8 @@ SHLIB_MAJOR= 7
SHLIBDIR?= /lib
OSRCS= chared.c common.c el.c emacs.c fcns.c filecomplete.c help.c \
hist.c key.c map.c \
parse.c prompt.c read.c refresh.c search.c sig.c term.c tty.c vi.c
hist.c keymacro.c map.c chartype.c \
parse.c prompt.c read.c refresh.c search.c sig.c terminal.c tty.c vi.c
LIBADD= ncursesw
@ -34,7 +34,10 @@ CLEANFILES+= common.h editline.c emacs.h fcns.c fcns.h help.c help.h vi.h
INCS= histedit.h
CFLAGS+= -I. -I${.CURDIR} -I${.CURDIR}/edit
OSRCS+= eln.c
SRCS+= tokenizern.c historyn.c
CLEANFILES+= tokenizern.c historyn.c
CFLAGS+= -I. -I${.CURDIR} -I${.CURDIR}/edit -DWIDECHAR
CFLAGS+= #-DDEBUG_TTY -DDEBUG_KEY -DDEBUG_READ -DDEBUG -DDEBUG_REFRESH
CFLAGS+= #-DDEBUG_PASTE -DDEBUG_EDIT
@ -65,6 +68,12 @@ help.h: ${ASRC} makelist
editline.c: ${OSRCS}
sh ${.CURDIR}/makelist -e ${.ALLSRC:T} > ${.TARGET}
tokenizern.c: makelist Makefile
sh ${.CURDIR}/makelist -n tokenizer.c > ${.TARGET}
historyn.c: makelist Makefile
sh ${.CURDIR}/makelist -n history.c > ${.TARGET}
# minimal dependency to make "make depend" optional
editline.o editline.po editline.So editline.ln: \
common.h emacs.h fcns.c fcns.h help.c help.h vi.h

53
lib/libedit/TEST/rl1.c Normal file
View File

@ -0,0 +1,53 @@
/* $NetBSD: rl1.c,v 1.1 2010/09/16 20:08:51 christos Exp $ */
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Christos Zoulas.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if !defined(lint)
__RCSID("$NetBSD: rl1.c,v 1.1 2010/09/16 20:08:51 christos Exp $");
#endif /* not lint */
__FBSDID("$FreeBSD$");
/*
* test.c: A little test program
*/
#include <stdio.h>
#include <readline/readline.h>
int
main(int argc, char *argv[])
{
char *p;
while ((p = readline("hi$")) != NULL) {
add_history(p);
printf("%d %s\n", history_length, p);
}
return 0;
}

View File

@ -1,3 +1,5 @@
/* $NetBSD: tc1.c,v 1.6 2014/06/18 20:12:15 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
@ -30,22 +32,24 @@
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include "config.h"
#ifndef lint
__COPYRIGHT("@(#) Copyright (c) 1992, 1993\n\
The Regents of the University of California. All rights reserved.\n");
#endif /* not lint */
#if !defined(lint) && !defined(SCCSID)
#if 0
static char sccsid[] = "@(#)test.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: tc1.c,v 1.6 2014/06/18 20:12:15 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
__RCSID("$NetBSD: test.c,v 1.3 2009/07/17 12:25:52 christos Exp $");
__FBSDID("$FreeBSD$");
/*
* test.c: A little test program
*/
#include "sys.h"
#include <stdio.h>
#include <string.h>
#include <signal.h>
@ -54,6 +58,7 @@ __FBSDID("$FreeBSD$");
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <locale.h>
#include "histedit.h"
@ -68,7 +73,7 @@ static void sig(int);
static char *
prompt(EditLine *el)
{
static char a[] = "\1\e[7m\1Edit$\1\e[0m\1 ";
static char a[] = "\1\033[7m\1Edit$\1\033[0m\1 ";
static char b[] = "Edit> ";
return (continuation ? b : a);
@ -88,6 +93,7 @@ complete(EditLine *el, int ch)
const char* ptr;
const LineInfo *lf = el_line(el);
int len;
int res = CC_ERROR;
/*
* Find the last word
@ -101,16 +107,16 @@ complete(EditLine *el, int ch)
if (len > strlen(dp->d_name))
continue;
if (strncmp(dp->d_name, ptr, len) == 0) {
closedir(dd);
if (el_insertstr(el, &dp->d_name[len]) == -1)
return (CC_ERROR);
res = CC_ERROR;
else
return (CC_REFRESH);
res = CC_REFRESH;
break;
}
}
closedir(dd);
return (CC_ERROR);
return res;
}
int
@ -127,6 +133,7 @@ main(int argc, char *argv[])
History *hist;
HistEvent ev;
(void) setlocale(LC_CTYPE, "");
(void) signal(SIGINT, sig);
(void) signal(SIGQUIT, sig);
(void) signal(SIGHUP, sig);

281
lib/libedit/TEST/wtc1.c Normal file
View File

@ -0,0 +1,281 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <sys/wait.h>
#include <err.h>
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <limits.h>
#include <locale.h>
#include "../histedit.h"
static int continuation;
volatile sig_atomic_t gotsig;
static const char hfile[] = ".whistory";
static wchar_t *
prompt(EditLine *el)
{
static wchar_t a[] = L"\1\033[7m\1Edit$\1\033[0m\1 ";
static wchar_t b[] = L"Edit> ";
return continuation ? b : a;
}
static void
sig(int i)
{
gotsig = i;
}
const char *
my_wcstombs(const wchar_t *wstr)
{
static struct {
char *str;
int len;
} buf;
int needed = wcstombs(0, wstr, 0) + 1;
if (needed > buf.len) {
buf.str = malloc(needed);
buf.len = needed;
}
wcstombs(buf.str, wstr, needed);
buf.str[needed - 1] = 0;
return buf.str;
}
static unsigned char
complete(EditLine *el, int ch)
{
DIR *dd = opendir(".");
struct dirent *dp;
const wchar_t *ptr;
char *buf, *bptr;
const LineInfoW *lf = el_wline(el);
int len, mblen, i;
unsigned char res = 0;
wchar_t dir[1024];
/* Find the last word */
for (ptr = lf->cursor -1; !iswspace(*ptr) && ptr > lf->buffer; --ptr)
continue;
len = lf->cursor - ++ptr;
/* Convert last word to multibyte encoding, so we can compare to it */
wctomb(NULL, 0); /* Reset shift state */
mblen = MB_LEN_MAX * len + 1;
buf = bptr = malloc(mblen);
if (buf == NULL)
err(1, "malloc");
for (i = 0; i < len; ++i) {
/* Note: really should test for -1 return from wctomb */
bptr += wctomb(bptr, ptr[i]);
}
*bptr = 0; /* Terminate multibyte string */
mblen = bptr - buf;
/* Scan directory for matching name */
for (dp = readdir(dd); dp != NULL; dp = readdir(dd)) {
if (mblen > strlen(dp->d_name))
continue;
if (strncmp(dp->d_name, buf, mblen) == 0) {
mbstowcs(dir, &dp->d_name[mblen],
sizeof(dir) / sizeof(*dir));
if (el_winsertstr(el, dir) == -1)
res = CC_ERROR;
else
res = CC_REFRESH;
break;
}
}
closedir(dd);
free(buf);
return res;
}
int
main(int argc, char *argv[])
{
EditLine *el = NULL;
int numc, ncontinuation;
const wchar_t *line;
TokenizerW *tok;
HistoryW *hist;
HistEventW ev;
#ifdef DEBUG
int i;
#endif
setlocale(LC_ALL, "");
(void)signal(SIGINT, sig);
(void)signal(SIGQUIT, sig);
(void)signal(SIGHUP, sig);
(void)signal(SIGTERM, sig);
hist = history_winit(); /* Init built-in history */
history_w(hist, &ev, H_SETSIZE, 100); /* Remember 100 events */
history_w(hist, &ev, H_LOAD, hfile);
tok = tok_winit(NULL); /* Init the tokenizer */
el = el_init(argv[0], stdin, stdout, stderr);
el_wset(el, EL_EDITOR, L"vi"); /* Default editor is vi */
el_wset(el, EL_SIGNAL, 1); /* Handle signals gracefully */
el_wset(el, EL_PROMPT_ESC, prompt, '\1'); /* Set the prompt function */
el_wset(el, EL_HIST, history_w, hist); /* FIXME - history_w? */
/* Add a user-defined function */
el_wset(el, EL_ADDFN, L"ed-complete", L"Complete argument", complete);
/* Bind <tab> to it */
el_wset(el, EL_BIND, L"^I", L"ed-complete", NULL);
/*
* Bind j, k in vi command mode to previous and next line, instead
* of previous and next history.
*/
el_wset(el, EL_BIND, L"-a", L"k", L"ed-prev-line", NULL);
el_wset(el, EL_BIND, L"-a", L"j", L"ed-next-line", NULL);
/* Source the user's defaults file. */
el_source(el, NULL);
while((line = el_wgets(el, &numc)) != NULL && numc != 0) {
int ac, cc, co, rc;
const wchar_t **av;
const LineInfoW *li;
li = el_wline(el);
#ifdef DEBUG
(void)fwprintf(stderr, L"==> got %d %ls", numc, line);
(void)fwprintf(stderr, L" > li `%.*ls_%.*ls'\n",
(li->cursor - li->buffer), li->buffer,
(li->lastchar - 1 - li->cursor),
(li->cursor >= li->lastchar) ? L"" : li->cursor);
#endif
if (gotsig) {
(void)fprintf(stderr, "Got signal %d.\n", (int)gotsig);
gotsig = 0;
el_reset(el);
}
if(!continuation && numc == 1)
continue; /* Only got a linefeed */
ac = cc = co = 0;
ncontinuation = tok_wline(tok, li, &ac, &av, &cc, &co);
if (ncontinuation < 0) {
(void) fprintf(stderr, "Internal error\n");
continuation = 0;
continue;
}
#ifdef DEBUG
(void)fprintf(stderr, " > nc %d ac %d cc %d co %d\n",
ncontinuation, ac, cc, co);
#endif
history_w(hist, &ev, continuation ? H_APPEND : H_ENTER, line);
continuation = ncontinuation;
ncontinuation = 0;
if(continuation)
continue;
#ifdef DEBUG
for (i = 0; i < ac; ++i) {
(void)fwprintf(stderr, L" > arg# %2d ", i);
if (i != cc)
(void)fwprintf(stderr, L"`%ls'\n", av[i]);
else
(void)fwprintf(stderr, L"`%.*ls_%ls'\n",
co, av[i], av[i] + co);
}
#endif
if (wcscmp (av[0], L"history") == 0) {
switch(ac) {
case 1:
for(rc = history_w(hist, &ev, H_LAST);
rc != -1;
rc = history_w(hist, &ev, H_PREV))
(void)fwprintf(stdout, L"%4d %ls",
ev.num, ev.str);
break;
case 2:
if (wcscmp(av[1], L"clear") == 0)
history_w(hist, &ev, H_CLEAR);
else
goto badhist;
break;
case 3:
if (wcscmp(av[1], L"load") == 0)
history_w(hist, &ev, H_LOAD,
my_wcstombs(av[2]));
else if (wcscmp(av[1], L"save") == 0)
history_w(hist, &ev, H_SAVE,
my_wcstombs(av[2]));
else
goto badhist;
break;
badhist:
default:
(void)fprintf(stderr,
"Bad history arguments\n");
break;
}
} else if (el_wparse(el, ac, av) == -1) {
switch (fork()) {
case 0: {
Tokenizer *ntok = tok_init(NULL);
int nargc;
const char **nav;
tok_str(ntok, my_wcstombs(line), &nargc, &nav);
execvp(nav[0],(char **)nav);
perror(nav[0]);
_exit(1);
/* NOTREACHED */
break;
}
case -1:
perror("fork");
break;
default:
if (wait(&rc) == -1)
perror("wait");
(void)fprintf(stderr, "Exit %x\n", rc);
break;
}
}
tok_wreset(tok);
}
el_end(el);
tok_wend(tok);
history_w(hist, &ev, H_SAVE, hfile);
history_wend(hist);
fprintf(stdout, "\n");
return 0;
}

View File

@ -1,3 +1,5 @@
/* $NetBSD: chared.c,v 1.40 2014/06/18 18:12:28 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
@ -28,12 +30,15 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $NetBSD: chared.c,v 1.27 2009/02/15 21:55:23 christos Exp $
*/
#include "config.h"
#if !defined(lint) && !defined(SCCSID)
#if 0
static char sccsid[] = "@(#)chared.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: chared.c,v 1.40 2014/06/18 18:12:28 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@ -41,12 +46,10 @@ __FBSDID("$FreeBSD$");
/*
* chared.c: Character editor utilities
*/
#include "sys.h"
#include <stdlib.h>
#include "el.h"
private void ch__clearmacro(EditLine *);
private void ch__clearmacro (EditLine *);
/* value to leave unused in line buffer */
#define EL_LEAVE 2
@ -62,10 +65,10 @@ cv_undo(EditLine *el)
size_t size;
/* Save entire line for undo */
size = el->el_line.lastchar - el->el_line.buffer;
vu->len = size;
size = (size_t)(el->el_line.lastchar - el->el_line.buffer);
vu->len = (ssize_t)size;
vu->cursor = (int)(el->el_line.cursor - el->el_line.buffer);
memcpy(vu->buf, el->el_line.buffer, size);
(void)memcpy(vu->buf, el->el_line.buffer, size * sizeof(*vu->buf));
/* save command info for redo */
r->count = el->el_state.doingarg ? el->el_state.argument : 0;
@ -79,11 +82,11 @@ cv_undo(EditLine *el)
* Save yank/delete data for paste
*/
protected void
cv_yank(EditLine *el, const char *ptr, int size)
cv_yank(EditLine *el, const Char *ptr, int size)
{
c_kill_t *k = &el->el_chared.c_kill;
memcpy(k->buf, ptr, (size_t)size);
(void)memcpy(k->buf, ptr, (size_t)size * sizeof(*k->buf));
k->last = k->buf + size;
}
@ -94,7 +97,7 @@ cv_yank(EditLine *el, const char *ptr, int size)
protected void
c_insert(EditLine *el, int num)
{
char *cp;
Char *cp;
if (el->el_line.lastchar + num >= el->el_line.limit) {
if (!ch_enlargebufs(el, (size_t)num))
@ -126,7 +129,7 @@ c_delafter(EditLine *el, int num)
}
if (num > 0) {
char *cp;
Char *cp;
for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++)
*cp = cp[num];
@ -142,7 +145,7 @@ c_delafter(EditLine *el, int num)
protected void
c_delafter1(EditLine *el)
{
char *cp;
Char *cp;
for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++)
*cp = cp[1];
@ -167,7 +170,7 @@ c_delbefore(EditLine *el, int num)
}
if (num > 0) {
char *cp;
Char *cp;
for (cp = el->el_line.cursor - num;
cp <= el->el_line.lastchar;
@ -185,7 +188,7 @@ c_delbefore(EditLine *el, int num)
protected void
c_delbefore1(EditLine *el)
{
char *cp;
Char *cp;
for (cp = el->el_line.cursor - 1; cp <= el->el_line.lastchar; cp++)
*cp = cp[1];
@ -198,9 +201,9 @@ c_delbefore1(EditLine *el)
* Return if p is part of a word according to emacs
*/
protected int
ce__isword(int p)
ce__isword(Int p)
{
return (isalnum(p) || strchr("*?_-.[]~=", p) != NULL);
return Isalnum(p) || Strchr(STR("*?_-.[]~="), p) != NULL;
}
@ -208,11 +211,11 @@ ce__isword(int p)
* Return if p is part of a word according to vi
*/
protected int
cv__isword(int p)
cv__isword(Int p)
{
if (isalnum(p) || p == '_')
if (Isalnum(p) || p == '_')
return 1;
if (isgraph(p))
if (Isgraph(p))
return 2;
return 0;
}
@ -222,24 +225,24 @@ cv__isword(int p)
* Return if p is part of a big word according to vi
*/
protected int
cv__isWord(int p)
cv__isWord(Int p)
{
return (!isspace(p));
return !Isspace(p);
}
/* c__prev_word():
* Find the previous word
*/
protected char *
c__prev_word(char *p, char *low, int n, int (*wtest)(int))
protected Char *
c__prev_word(Char *p, Char *low, int n, int (*wtest)(Int))
{
p--;
while (n--) {
while ((p >= low) && !(*wtest)((unsigned char) *p))
while ((p >= low) && !(*wtest)(*p))
p--;
while ((p >= low) && (*wtest)((unsigned char) *p))
while ((p >= low) && (*wtest)(*p))
p--;
}
@ -248,117 +251,83 @@ c__prev_word(char *p, char *low, int n, int (*wtest)(int))
if (p < low)
p = low;
/* cp now points where we want it */
return (p);
return p;
}
/* c__next_word():
* Find the next word
*/
protected char *
c__next_word(char *p, char *high, int n, int (*wtest)(int))
protected Char *
c__next_word(Char *p, Char *high, int n, int (*wtest)(Int))
{
while (n--) {
while ((p < high) && !(*wtest)((unsigned char) *p))
while ((p < high) && !(*wtest)(*p))
p++;
while ((p < high) && (*wtest)((unsigned char) *p))
while ((p < high) && (*wtest)(*p))
p++;
}
if (p > high)
p = high;
/* p now points where we want it */
return (p);
return p;
}
/* cv_next_word():
* Find the next word vi style
*/
protected char *
cv_next_word(EditLine *el, char *p, char *high, int n, int (*wtest)(int))
protected Char *
cv_next_word(EditLine *el, Char *p, Char *high, int n, int (*wtest)(Int))
{
int test;
while (n--) {
test = (*wtest)((unsigned char) *p);
while ((p < high) && (*wtest)((unsigned char) *p) == test)
test = (*wtest)(*p);
while ((p < high) && (*wtest)(*p) == test)
p++;
/*
* vi historically deletes with cw only the word preserving the
* trailing whitespace! This is not what 'w' does..
*/
if (n || el->el_chared.c_vcmd.action != (DELETE|INSERT))
while ((p < high) && isspace((unsigned char) *p))
while ((p < high) && Isspace(*p))
p++;
}
/* p now points where we want it */
if (p > high)
return (high);
return high;
else
return (p);
return p;
}
/* cv_prev_word():
* Find the previous word vi style
*/
protected char *
cv_prev_word(char *p, char *low, int n, int (*wtest)(int))
protected Char *
cv_prev_word(Char *p, Char *low, int n, int (*wtest)(Int))
{
int test;
p--;
while (n--) {
while ((p > low) && isspace((unsigned char) *p))
while ((p > low) && Isspace(*p))
p--;
test = (*wtest)((unsigned char) *p);
while ((p >= low) && (*wtest)((unsigned char) *p) == test)
test = (*wtest)(*p);
while ((p >= low) && (*wtest)(*p) == test)
p--;
}
p++;
/* p now points where we want it */
if (p < low)
return (low);
return low;
else
return (p);
return p;
}
#ifdef notdef
/* c__number():
* Ignore character p points to, return number appearing after that.
* A '$' by itself means a big number; "$-" is for negative; '^' means 1.
* Return p pointing to last char used.
*/
protected char *
c__number(
char *p, /* character position */
int *num, /* Return value */
int dval) /* dval is the number to subtract from like $-3 */
{
int i;
int sign = 1;
if (*++p == '^') {
*num = 1;
return (p);
}
if (*p == '$') {
if (*++p != '-') {
*num = 0x7fffffff; /* Handle $ */
return (--p);
}
sign = -1; /* Handle $- */
++p;
}
for (i = 0; isdigit((unsigned char) *p); i = 10 * i + *p++ - '0')
continue;
*num = (sign < 0 ? dval - i : i);
return (--p);
}
#endif
/* cv_delfini():
* Finish vi delete action
*/
@ -397,48 +366,26 @@ cv_delfini(EditLine *el)
}
#ifdef notdef
/* ce__endword():
* Go to the end of this word according to emacs
*/
protected char *
ce__endword(char *p, char *high, int n)
{
p++;
while (n--) {
while ((p < high) && isspace((unsigned char) *p))
p++;
while ((p < high) && !isspace((unsigned char) *p))
p++;
}
p--;
return (p);
}
#endif
/* cv__endword():
* Go to the end of this word according to vi
*/
protected char *
cv__endword(char *p, char *high, int n, int (*wtest)(int))
protected Char *
cv__endword(Char *p, Char *high, int n, int (*wtest)(Int))
{
int test;
p++;
while (n--) {
while ((p < high) && isspace((unsigned char) *p))
while ((p < high) && Isspace(*p))
p++;
test = (*wtest)((unsigned char) *p);
while ((p < high) && (*wtest)((unsigned char) *p) == test)
test = (*wtest)(*p);
while ((p < high) && (*wtest)(*p) == test)
p++;
}
p--;
return (p);
return p;
}
/* ch_init():
@ -449,24 +396,29 @@ ch_init(EditLine *el)
{
c_macro_t *ma = &el->el_chared.c_macro;
el->el_line.buffer = (char *) el_malloc(EL_BUFSIZ);
el->el_line.buffer = el_malloc(EL_BUFSIZ *
sizeof(*el->el_line.buffer));
if (el->el_line.buffer == NULL)
return (-1);
return -1;
(void) memset(el->el_line.buffer, 0, EL_BUFSIZ);
(void) memset(el->el_line.buffer, 0, EL_BUFSIZ *
sizeof(*el->el_line.buffer));
el->el_line.cursor = el->el_line.buffer;
el->el_line.lastchar = el->el_line.buffer;
el->el_line.limit = &el->el_line.buffer[EL_BUFSIZ - EL_LEAVE];
el->el_chared.c_undo.buf = (char *) el_malloc(EL_BUFSIZ);
el->el_chared.c_undo.buf = el_malloc(EL_BUFSIZ *
sizeof(*el->el_chared.c_undo.buf));
if (el->el_chared.c_undo.buf == NULL)
return (-1);
(void) memset(el->el_chared.c_undo.buf, 0, EL_BUFSIZ);
return -1;
(void) memset(el->el_chared.c_undo.buf, 0, EL_BUFSIZ *
sizeof(*el->el_chared.c_undo.buf));
el->el_chared.c_undo.len = -1;
el->el_chared.c_undo.cursor = 0;
el->el_chared.c_redo.buf = (char *) el_malloc(EL_BUFSIZ);
el->el_chared.c_redo.buf = el_malloc(EL_BUFSIZ *
sizeof(*el->el_chared.c_redo.buf));
if (el->el_chared.c_redo.buf == NULL)
return (-1);
return -1;
el->el_chared.c_redo.pos = el->el_chared.c_redo.buf;
el->el_chared.c_redo.lim = el->el_chared.c_redo.buf + EL_BUFSIZ;
el->el_chared.c_redo.cmd = ED_UNASSIGNED;
@ -474,12 +426,18 @@ ch_init(EditLine *el)
el->el_chared.c_vcmd.action = NOP;
el->el_chared.c_vcmd.pos = el->el_line.buffer;
el->el_chared.c_kill.buf = (char *) el_malloc(EL_BUFSIZ);
el->el_chared.c_kill.buf = el_malloc(EL_BUFSIZ *
sizeof(*el->el_chared.c_kill.buf));
if (el->el_chared.c_kill.buf == NULL)
return (-1);
(void) memset(el->el_chared.c_kill.buf, 0, EL_BUFSIZ);
return -1;
(void) memset(el->el_chared.c_kill.buf, 0, EL_BUFSIZ *
sizeof(*el->el_chared.c_kill.buf));
el->el_chared.c_kill.mark = el->el_line.buffer;
el->el_chared.c_kill.last = el->el_chared.c_kill.buf;
el->el_chared.c_resizefun = NULL;
el->el_chared.c_resizearg = NULL;
el->el_chared.c_aliasfun = NULL;
el->el_chared.c_aliasarg = NULL;
el->el_map.current = el->el_map.key;
@ -491,10 +449,10 @@ ch_init(EditLine *el)
ma->level = -1;
ma->offset = 0;
ma->macro = (char **) el_malloc(EL_MAXMACRO * sizeof(char *));
ma->macro = el_malloc(EL_MAXMACRO * sizeof(*ma->macro));
if (ma->macro == NULL)
return (-1);
return (0);
return -1;
return 0;
}
/* ch_reset():
@ -533,7 +491,7 @@ ch__clearmacro(EditLine *el)
{
c_macro_t *ma = &el->el_chared.c_macro;
while (ma->level >= 0)
el_free((ptr_t)ma->macro[ma->level--]);
el_free(ma->macro[ma->level--]);
}
/* ch_enlargebufs():
@ -544,9 +502,9 @@ protected int
ch_enlargebufs(EditLine *el, size_t addlen)
{
size_t sz, newsz;
char *newbuffer, *oldbuf, *oldkbuf;
Char *newbuffer, *oldbuf, *oldkbuf;
sz = el->el_line.limit - el->el_line.buffer + EL_LEAVE;
sz = (size_t)(el->el_line.limit - el->el_line.buffer + EL_LEAVE);
newsz = sz * 2;
/*
* If newly required length is longer than current buffer, we need
@ -560,12 +518,12 @@ ch_enlargebufs(EditLine *el, size_t addlen)
/*
* Reallocate line buffer.
*/
newbuffer = el_realloc(el->el_line.buffer, newsz);
newbuffer = el_realloc(el->el_line.buffer, newsz * sizeof(*newbuffer));
if (!newbuffer)
return 0;
/* zero the newly added memory, leave old data in */
(void) memset(&newbuffer[sz], 0, newsz - sz);
(void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer));
oldbuf = el->el_line.buffer;
@ -578,12 +536,13 @@ ch_enlargebufs(EditLine *el, size_t addlen)
/*
* Reallocate kill buffer.
*/
newbuffer = el_realloc(el->el_chared.c_kill.buf, newsz);
newbuffer = el_realloc(el->el_chared.c_kill.buf, newsz *
sizeof(*newbuffer));
if (!newbuffer)
return 0;
/* zero the newly added memory, leave old data in */
(void) memset(&newbuffer[sz], 0, newsz - sz);
(void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer));
oldkbuf = el->el_chared.c_kill.buf;
@ -596,15 +555,17 @@ ch_enlargebufs(EditLine *el, size_t addlen)
/*
* Reallocate undo buffer.
*/
newbuffer = el_realloc(el->el_chared.c_undo.buf, newsz);
newbuffer = el_realloc(el->el_chared.c_undo.buf,
newsz * sizeof(*newbuffer));
if (!newbuffer)
return 0;
/* zero the newly added memory, leave old data in */
(void) memset(&newbuffer[sz], 0, newsz - sz);
(void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer));
el->el_chared.c_undo.buf = newbuffer;
newbuffer = el_realloc(el->el_chared.c_redo.buf, newsz);
newbuffer = el_realloc(el->el_chared.c_redo.buf,
newsz * sizeof(*newbuffer));
if (!newbuffer)
return 0;
el->el_chared.c_redo.pos = newbuffer +
@ -618,6 +579,8 @@ ch_enlargebufs(EditLine *el, size_t addlen)
/* Safe to set enlarged buffer size */
el->el_line.limit = &el->el_line.buffer[newsz - EL_LEAVE];
if (el->el_chared.c_resizefun)
(*el->el_chared.c_resizefun)(el, el->el_chared.c_resizearg);
return 1;
}
@ -627,20 +590,20 @@ ch_enlargebufs(EditLine *el, size_t addlen)
protected void
ch_end(EditLine *el)
{
el_free((ptr_t) el->el_line.buffer);
el_free(el->el_line.buffer);
el->el_line.buffer = NULL;
el->el_line.limit = NULL;
el_free((ptr_t) el->el_chared.c_undo.buf);
el_free(el->el_chared.c_undo.buf);
el->el_chared.c_undo.buf = NULL;
el_free((ptr_t) el->el_chared.c_redo.buf);
el_free(el->el_chared.c_redo.buf);
el->el_chared.c_redo.buf = NULL;
el->el_chared.c_redo.pos = NULL;
el->el_chared.c_redo.lim = NULL;
el->el_chared.c_redo.cmd = ED_UNASSIGNED;
el_free((ptr_t) el->el_chared.c_kill.buf);
el_free(el->el_chared.c_kill.buf);
el->el_chared.c_kill.buf = NULL;
ch_reset(el, 1);
el_free((ptr_t) el->el_chared.c_macro.macro);
el_free(el->el_chared.c_macro.macro);
el->el_chared.c_macro.macro = NULL;
}
@ -649,21 +612,21 @@ ch_end(EditLine *el)
* Insert string at cursorI
*/
public int
el_insertstr(EditLine *el, const char *s)
FUN(el,insertstr)(EditLine *el, const Char *s)
{
size_t len;
if ((len = strlen(s)) == 0)
return (-1);
if (s == NULL || (len = Strlen(s)) == 0)
return -1;
if (el->el_line.lastchar + len >= el->el_line.limit) {
if (!ch_enlargebufs(el, len))
return (-1);
return -1;
}
c_insert(el, (int)len);
while (*s)
*el->el_line.cursor++ = *s++;
return (0);
return 0;
}
@ -685,19 +648,38 @@ el_deletestr(EditLine *el, int n)
el->el_line.cursor = el->el_line.buffer;
}
/* el_cursor():
* Move the cursor to the left or the right of the current position
*/
public int
el_cursor(EditLine *el, int n)
{
if (n == 0)
goto out;
el->el_line.cursor += n;
if (el->el_line.cursor < el->el_line.buffer)
el->el_line.cursor = el->el_line.buffer;
if (el->el_line.cursor > el->el_line.lastchar)
el->el_line.cursor = el->el_line.lastchar;
out:
return (int)(el->el_line.cursor - el->el_line.buffer);
}
/* c_gets():
* Get a string
*/
protected int
c_gets(EditLine *el, char *buf, const char *prompt)
c_gets(EditLine *el, Char *buf, const Char *prompt)
{
char ch;
Char ch;
ssize_t len;
char *cp = el->el_line.buffer;
Char *cp = el->el_line.buffer;
if (prompt) {
len = strlen(prompt);
memcpy(cp, prompt, (size_t)len);
len = (ssize_t)Strlen(prompt);
(void)memcpy(cp, prompt, (size_t)len * sizeof(*cp));
cp += len;
}
len = 0;
@ -708,7 +690,7 @@ c_gets(EditLine *el, char *buf, const char *prompt)
el->el_line.lastchar = cp + 1;
re_refresh(el);
if (el_getc(el, &ch) != 1) {
if (FUN(el,getc)(el, &ch) != 1) {
ed_end_of_file(el, 0);
len = -1;
break;
@ -716,8 +698,8 @@ c_gets(EditLine *el, char *buf, const char *prompt)
switch (ch) {
case '\010': /* Delete and backspace */
case '\177':
case 0010: /* Delete and backspace */
case 0177:
if (len == 0) {
len = -1;
break;
@ -725,15 +707,15 @@ c_gets(EditLine *el, char *buf, const char *prompt)
cp--;
continue;
case '\033': /* ESC */
case 0033: /* ESC */
case '\r': /* Newline */
case '\n':
buf[len] = ch;
break;
default:
if (len >= EL_BUFSIZ - 16)
term_beep(el);
if (len >= (ssize_t)(EL_BUFSIZ - 16))
terminal_beep(el);
else {
buf[len++] = ch;
*cp++ = ch;
@ -756,13 +738,13 @@ c_gets(EditLine *el, char *buf, const char *prompt)
protected int
c_hpos(EditLine *el)
{
char *ptr;
Char *ptr;
/*
* Find how many characters till the beginning of this line.
*/
if (el->el_line.cursor == el->el_line.buffer)
return (0);
return 0;
else {
for (ptr = el->el_line.cursor - 1;
ptr >= el->el_line.buffer && *ptr != '\n';
@ -771,3 +753,19 @@ c_hpos(EditLine *el)
return (int)(el->el_line.cursor - ptr - 1);
}
}
protected int
ch_resizefun(EditLine *el, el_zfunc_t f, void *a)
{
el->el_chared.c_resizefun = f;
el->el_chared.c_resizearg = a;
return 0;
}
protected int
ch_aliasfun(EditLine *el, el_afunc_t f, void *a)
{
el->el_chared.c_aliasfun = f;
el->el_chared.c_aliasarg = a;
return 0;
}

View File

@ -1,3 +1,5 @@
/* $NetBSD: chared.h,v 1.22 2014/06/18 18:12:28 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
@ -30,7 +32,6 @@
* SUCH DAMAGE.
*
* @(#)chared.h 8.1 (Berkeley) 6/4/93
* $NetBSD: chared.h,v 1.18 2009/02/15 21:55:23 christos Exp $
* $FreeBSD$
*/
@ -63,7 +64,7 @@
typedef struct c_macro_t {
int level;
int offset;
char **macro;
Char **macro;
} c_macro_t;
/*
@ -72,16 +73,16 @@ typedef struct c_macro_t {
typedef struct c_undo_t {
ssize_t len; /* length of saved line */
int cursor; /* position of saved cursor */
char *buf; /* full saved text */
Char *buf; /* full saved text */
} c_undo_t;
/* redo for vi */
typedef struct c_redo_t {
char *buf; /* redo insert key sequence */
char *pos;
char *lim;
Char *buf; /* redo insert key sequence */
Char *pos;
Char *lim;
el_action_t cmd; /* command to redo */
char ch; /* char that invoked it */
Char ch; /* char that invoked it */
int count;
int action; /* from cv_action() */
} c_redo_t;
@ -91,18 +92,21 @@ typedef struct c_redo_t {
*/
typedef struct c_vcmd_t {
int action;
char *pos;
Char *pos;
} c_vcmd_t;
/*
* Kill buffer for emacs
*/
typedef struct c_kill_t {
char *buf;
char *last;
char *mark;
Char *buf;
Char *last;
Char *mark;
} c_kill_t;
typedef void (*el_zfunc_t)(EditLine *, void *);
typedef const char *(*el_afunc_t)(void *, const char *);
/*
* Note that we use both data structures because the user can bind
* commands from both editors!
@ -113,13 +117,16 @@ typedef struct el_chared_t {
c_redo_t c_redo;
c_vcmd_t c_vcmd;
c_macro_t c_macro;
el_zfunc_t c_resizefun;
el_afunc_t c_aliasfun;
void * c_resizearg;
void * c_aliasarg;
} el_chared_t;
#define STRQQ "\"\""
#define isglob(a) (strchr("*[]?", (a)) != NULL)
#define isword(a) (isprint(a))
#define NOP 0x00
#define DELETE 0x01
@ -140,27 +147,29 @@ typedef struct el_chared_t {
#include "fcns.h"
protected int cv__isword(int);
protected int cv__isWord(int);
protected int cv__isword(Int);
protected int cv__isWord(Int);
protected void cv_delfini(EditLine *);
protected char *cv__endword(char *, char *, int, int (*)(int));
protected int ce__isword(int);
protected Char *cv__endword(Char *, Char *, int, int (*)(Int));
protected int ce__isword(Int);
protected void cv_undo(EditLine *);
protected void cv_yank(EditLine *, const char *, int);
protected char *cv_next_word(EditLine*, char *, char *, int, int (*)(int));
protected char *cv_prev_word(char *, char *, int, int (*)(int));
protected char *c__next_word(char *, char *, int, int (*)(int));
protected char *c__prev_word(char *, char *, int, int (*)(int));
protected void cv_yank(EditLine *, const Char *, int);
protected Char *cv_next_word(EditLine*, Char *, Char *, int, int (*)(Int));
protected Char *cv_prev_word(Char *, Char *, int, int (*)(Int));
protected Char *c__next_word(Char *, Char *, int, int (*)(Int));
protected Char *c__prev_word(Char *, Char *, int, int (*)(Int));
protected void c_insert(EditLine *, int);
protected void c_delbefore(EditLine *, int);
protected void c_delbefore1(EditLine *);
protected void c_delafter(EditLine *, int);
protected void c_delafter1(EditLine *);
protected int c_gets(EditLine *, char *, const char *);
protected int c_gets(EditLine *, Char *, const Char *);
protected int c_hpos(EditLine *);
protected int ch_init(EditLine *);
protected void ch_reset(EditLine *, int);
protected int ch_resizefun(EditLine *, el_zfunc_t, void *);
protected int ch_aliasfun(EditLine *, el_afunc_t, void *);
protected int ch_enlargebufs(EditLine *, size_t);
protected void ch_end(EditLine *);

352
lib/libedit/chartype.c Normal file
View File

@ -0,0 +1,352 @@
/* $NetBSD: chartype.c,v 1.10 2011/08/16 16:25:15 christos Exp $ */
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* chartype.c: character classification and meta information
*/
#include "config.h"
#if !defined(lint) && !defined(SCCSID)
__RCSID("$NetBSD: chartype.c,v 1.10 2011/08/16 16:25:15 christos Exp $");
#endif /* not lint && not SCCSID */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "el.h"
#include <stdlib.h>
#define CT_BUFSIZ ((size_t)1024)
#ifdef WIDECHAR
protected void
ct_conv_buff_resize(ct_buffer_t *conv, size_t mincsize, size_t minwsize)
{
void *p;
if (mincsize > conv->csize) {
conv->csize = mincsize;
p = el_realloc(conv->cbuff, conv->csize * sizeof(*conv->cbuff));
if (p == NULL) {
conv->csize = 0;
el_free(conv->cbuff);
conv->cbuff = NULL;
} else
conv->cbuff = p;
}
if (minwsize > conv->wsize) {
conv->wsize = minwsize;
p = el_realloc(conv->wbuff, conv->wsize * sizeof(*conv->wbuff));
if (p == NULL) {
conv->wsize = 0;
el_free(conv->wbuff);
conv->wbuff = NULL;
} else
conv->wbuff = p;
}
}
public char *
ct_encode_string(const Char *s, ct_buffer_t *conv)
{
char *dst;
ssize_t used = 0;
if (!s)
return NULL;
if (!conv->cbuff)
ct_conv_buff_resize(conv, CT_BUFSIZ, (size_t)0);
if (!conv->cbuff)
return NULL;
dst = conv->cbuff;
while (*s) {
used = (ssize_t)(conv->csize - (size_t)(dst - conv->cbuff));
if (used < 5) {
used = dst - conv->cbuff;
ct_conv_buff_resize(conv, conv->csize + CT_BUFSIZ,
(size_t)0);
if (!conv->cbuff)
return NULL;
dst = conv->cbuff + used;
}
used = ct_encode_char(dst, (size_t)5, *s);
if (used == -1) /* failed to encode, need more buffer space */
abort();
++s;
dst += used;
}
*dst = '\0';
return conv->cbuff;
}
public Char *
ct_decode_string(const char *s, ct_buffer_t *conv)
{
size_t len = 0;
if (!s)
return NULL;
if (!conv->wbuff)
ct_conv_buff_resize(conv, (size_t)0, CT_BUFSIZ);
if (!conv->wbuff)
return NULL;
len = ct_mbstowcs(NULL, s, (size_t)0);
if (len == (size_t)-1)
return NULL;
if (len > conv->wsize)
ct_conv_buff_resize(conv, (size_t)0, len + 1);
if (!conv->wbuff)
return NULL;
ct_mbstowcs(conv->wbuff, s, conv->wsize);
return conv->wbuff;
}
protected Char **
ct_decode_argv(int argc, const char *argv[], ct_buffer_t *conv)
{
size_t bufspace;
int i;
Char *p;
Char **wargv;
ssize_t bytes;
/* Make sure we have enough space in the conversion buffer to store all
* the argv strings. */
for (i = 0, bufspace = 0; i < argc; ++i)
bufspace += argv[i] ? strlen(argv[i]) + 1 : 0;
ct_conv_buff_resize(conv, (size_t)0, bufspace);
if (!conv->wsize)
return NULL;
wargv = el_malloc((size_t)argc * sizeof(*wargv));
for (i = 0, p = conv->wbuff; i < argc; ++i) {
if (!argv[i]) { /* don't pass null pointers to mbstowcs */
wargv[i] = NULL;
continue;
} else {
wargv[i] = p;
bytes = (ssize_t)mbstowcs(p, argv[i], bufspace);
}
if (bytes == -1) {
el_free(wargv);
return NULL;
} else
bytes++; /* include '\0' in the count */
bufspace -= (size_t)bytes;
p += bytes;
}
return wargv;
}
protected size_t
ct_enc_width(Char c)
{
/* UTF-8 encoding specific values */
if (c < 0x80)
return 1;
else if (c < 0x0800)
return 2;
else if (c < 0x10000)
return 3;
else if (c < 0x110000)
return 4;
else
return 0; /* not a valid codepoint */
}
protected ssize_t
ct_encode_char(char *dst, size_t len, Char c)
{
ssize_t l = 0;
if (len < ct_enc_width(c))
return -1;
l = ct_wctomb(dst, c);
if (l < 0) {
ct_wctomb_reset;
l = 0;
}
return l;
}
#endif
protected const Char *
ct_visual_string(const Char *s)
{
static Char *buff = NULL;
static size_t buffsize = 0;
void *p;
Char *dst;
ssize_t used = 0;
if (!s)
return NULL;
if (!buff) {
buffsize = CT_BUFSIZ;
buff = el_malloc(buffsize * sizeof(*buff));
}
dst = buff;
while (*s) {
used = ct_visual_char(dst, buffsize - (size_t)(dst - buff), *s);
if (used == -1) { /* failed to encode, need more buffer space */
used = dst - buff;
buffsize += CT_BUFSIZ;
p = el_realloc(buff, buffsize * sizeof(*buff));
if (p == NULL)
goto out;
buff = p;
dst = buff + used;
/* don't increment s here - we want to retry it! */
}
else
++s;
dst += used;
}
if (dst >= (buff + buffsize)) { /* sigh */
buffsize += 1;
p = el_realloc(buff, buffsize * sizeof(*buff));
if (p == NULL)
goto out;
buff = p;
dst = buff + buffsize - 1;
}
*dst = 0;
return buff;
out:
el_free(buff);
buffsize = 0;
return NULL;
}
protected int
ct_visual_width(Char c)
{
int t = ct_chr_class(c);
switch (t) {
case CHTYPE_ASCIICTL:
return 2; /* ^@ ^? etc. */
case CHTYPE_TAB:
return 1; /* Hmm, this really need to be handled outside! */
case CHTYPE_NL:
return 0; /* Should this be 1 instead? */
#ifdef WIDECHAR
case CHTYPE_PRINT:
return wcwidth(c);
case CHTYPE_NONPRINT:
if (c > 0xffff) /* prefer standard 4-byte display over 5-byte */
return 8; /* \U+12345 */
else
return 7; /* \U+1234 */
#else
case CHTYPE_PRINT:
return 1;
case CHTYPE_NONPRINT:
return 4; /* \123 */
#endif
default:
return 0; /* should not happen */
}
}
protected ssize_t
ct_visual_char(Char *dst, size_t len, Char c)
{
int t = ct_chr_class(c);
switch (t) {
case CHTYPE_TAB:
case CHTYPE_NL:
case CHTYPE_ASCIICTL:
if (len < 2)
return -1; /* insufficient space */
*dst++ = '^';
if (c == '\177')
*dst = '?'; /* DEL -> ^? */
else
*dst = c | 0100; /* uncontrolify it */
return 2;
case CHTYPE_PRINT:
if (len < 1)
return -1; /* insufficient space */
*dst = c;
return 1;
case CHTYPE_NONPRINT:
/* we only use single-width glyphs for display,
* so this is right */
if ((ssize_t)len < ct_visual_width(c))
return -1; /* insufficient space */
#ifdef WIDECHAR
*dst++ = '\\';
*dst++ = 'U';
*dst++ = '+';
#define tohexdigit(v) "0123456789ABCDEF"[v]
if (c > 0xffff) /* prefer standard 4-byte display over 5-byte */
*dst++ = tohexdigit(((unsigned int) c >> 16) & 0xf);
*dst++ = tohexdigit(((unsigned int) c >> 12) & 0xf);
*dst++ = tohexdigit(((unsigned int) c >> 8) & 0xf);
*dst++ = tohexdigit(((unsigned int) c >> 4) & 0xf);
*dst = tohexdigit(((unsigned int) c ) & 0xf);
return c > 0xffff ? 8 : 7;
#else
*dst++ = '\\';
#define tooctaldigit(v) ((v) + '0')
*dst++ = tooctaldigit(((unsigned int) c >> 6) & 0x7);
*dst++ = tooctaldigit(((unsigned int) c >> 3) & 0x7);
*dst++ = tooctaldigit(((unsigned int) c ) & 0x7);
#endif
/*FALLTHROUGH*/
/* these two should be handled outside this function */
default: /* we should never hit the default */
return 0;
}
}
protected int
ct_chr_class(Char c)
{
if (c == '\t')
return CHTYPE_TAB;
else if (c == '\n')
return CHTYPE_NL;
else if (IsASCII(c) && Iscntrl(c))
return CHTYPE_ASCIICTL;
else if (Isprint(c))
return CHTYPE_PRINT;
else
return CHTYPE_NONPRINT;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: chartype.h,v 1.6 2010/04/20 02:01:13 christos Exp $ */
/* $NetBSD: chartype.h,v 1.10 2011/11/16 01:45:10 christos Exp $ */
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
@ -39,7 +39,7 @@
* supports non-BMP code points without requiring UTF-16, but nothing
* seems to actually advertise this properly, despite Unicode 3.1 having
* been around since 2001... */
#if !defined(__NetBSD__) && !defined(__sun) && !(defined(__APPLE__) && defined(__MACH__))
#if !defined(__NetBSD__) && !defined(__sun) && !(defined(__APPLE__) && defined(__MACH__)) && !defined(__FreeBSD__)
#ifndef __STDC_ISO_10646__
/* In many places it is assumed that the first 127 code points are ASCII
* compatible, so ensure wchar_t indeed does ISO 10646 and not some other
@ -56,7 +56,7 @@
#endif
#define ct_mbtowc mbtowc
#define ct_mbtowc_reset mbtowc(0,0,0)
#define ct_mbtowc_reset mbtowc(0,0,(size_t)0)
#define ct_wctomb wctomb
#define ct_wctomb_reset wctomb(0,0)
#define ct_wcstombs wcstombs
@ -100,7 +100,12 @@
#define Strtol(p,e,b) wcstol(p,e,b)
#define Width(c) wcwidth(c)
static inline int
Width(wchar_t c)
{
int w = wcwidth(c);
return w < 0 ? 0 : w;
}
#else /* NARROW */
@ -167,11 +172,11 @@ typedef struct ct_buffer_t {
} ct_buffer_t;
#define ct_encode_string __ct_encode_string
/* Encode a wide character string and return the UTF-8 encoded result. */
/* Encode a wide-character string and return the UTF-8 encoded result. */
public char *ct_encode_string(const Char *, ct_buffer_t *);
#define ct_decode_string __ct_decode_string
/* Decode a (multi)?byte string and return the wide character string result. */
/* Decode a (multi)?byte string and return the wide-character string result. */
public Char *ct_decode_string(const char *, ct_buffer_t *);
/* Decode a (multi)?byte argv string array.
@ -201,7 +206,7 @@ protected size_t ct_enc_width(Char);
/* The maximum buffer size to hold the most unwieldly visual representation,
* in this case \U+nnnnn. */
#define VISUAL_WIDTH_MAX 8
#define VISUAL_WIDTH_MAX ((size_t)8)
/* The terminal is thought of in terms of X columns by Y lines. In the cases
* where a wide character takes up more than one column, the adjacent

View File

@ -1,3 +1,5 @@
/* $NetBSD: common.c,v 1.29 2012/03/24 20:08:43 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
@ -28,12 +30,15 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $NetBSD: common.c,v 1.23 2009/02/27 04:18:45 msaitoh Exp $
*/
#include "config.h"
#if !defined(lint) && !defined(SCCSID)
#if 0
static char sccsid[] = "@(#)common.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: common.c,v 1.29 2012/03/24 20:08:43 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@ -41,7 +46,6 @@ __FBSDID("$FreeBSD$");
/*
* common.c: Common Editor functions
*/
#include "sys.h"
#include "el.h"
/* ed_end_of_file():
@ -50,12 +54,12 @@ __FBSDID("$FreeBSD$");
*/
protected el_action_t
/*ARGSUSED*/
ed_end_of_file(EditLine *el, int c __unused)
ed_end_of_file(EditLine *el, Int c __attribute__((__unused__)))
{
re_goto_bottom(el);
*el->el_line.lastchar = '\0';
return (CC_EOF);
return CC_EOF;
}
@ -64,12 +68,12 @@ ed_end_of_file(EditLine *el, int c __unused)
* Insert a character [bound to all insert keys]
*/
protected el_action_t
ed_insert(EditLine *el, int c)
ed_insert(EditLine *el, Int c)
{
int count = el->el_state.argument;
if (c == '\0')
return (CC_ERROR);
return CC_ERROR;
if (el->el_line.lastchar + el->el_state.argument >=
el->el_line.limit) {
@ -97,7 +101,7 @@ ed_insert(EditLine *el, int c)
if (el->el_state.inputmode == MODE_REPLACE_1)
return vi_command_mode(el, 0);
return (CC_NORM);
return CC_NORM;
}
@ -107,12 +111,12 @@ ed_insert(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
ed_delete_prev_word(EditLine *el, int c __unused)
ed_delete_prev_word(EditLine *el, Int c __attribute__((__unused__)))
{
char *cp, *p, *kp;
Char *cp, *p, *kp;
if (el->el_line.cursor == el->el_line.buffer)
return (CC_ERROR);
return CC_ERROR;
cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
el->el_state.argument, ce__isword);
@ -125,7 +129,7 @@ ed_delete_prev_word(EditLine *el, int c __unused)
el->el_line.cursor = cp;
if (el->el_line.cursor < el->el_line.buffer)
el->el_line.cursor = el->el_line.buffer; /* bounds check */
return (CC_REFRESH);
return CC_REFRESH;
}
@ -135,9 +139,9 @@ ed_delete_prev_word(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
ed_delete_next_char(EditLine *el, int c)
ed_delete_next_char(EditLine *el, Int c __attribute__((__unused__)))
{
#ifdef notdef /* XXX */
#ifdef DEBUG_EDIT
#define EL el->el_line
(void) fprintf(el->el_errlfile,
"\nD(b: %x(%s) c: %x(%s) last: %x(%s) limit: %x(%s)\n",
@ -150,21 +154,21 @@ ed_delete_next_char(EditLine *el, int c)
if (el->el_line.cursor == el->el_line.buffer) {
/* if I'm also at the beginning */
#ifdef KSHVI
return (CC_ERROR);
return CC_ERROR;
#else
/* then do an EOF */
term_writechar(el, c);
return (CC_EOF);
terminal_writec(el, c);
return CC_EOF;
#endif
} else {
#ifdef KSHVI
el->el_line.cursor--;
#else
return (CC_ERROR);
return CC_ERROR;
#endif
}
} else
return (CC_ERROR);
return CC_ERROR;
}
c_delafter(el, el->el_state.argument); /* delete after dot */
if (el->el_map.type == MAP_VI &&
@ -172,7 +176,7 @@ ed_delete_next_char(EditLine *el, int c)
el->el_line.cursor > el->el_line.buffer)
/* bounds check */
el->el_line.cursor = el->el_line.lastchar - 1;
return (CC_REFRESH);
return CC_REFRESH;
}
@ -182,9 +186,9 @@ ed_delete_next_char(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
ed_kill_line(EditLine *el, int c __unused)
ed_kill_line(EditLine *el, Int c __attribute__((__unused__)))
{
char *kp, *cp;
Char *kp, *cp;
cp = el->el_line.cursor;
kp = el->el_chared.c_kill.buf;
@ -193,7 +197,7 @@ ed_kill_line(EditLine *el, int c __unused)
el->el_chared.c_kill.last = kp;
/* zap! -- delete to end */
el->el_line.lastchar = el->el_line.cursor;
return (CC_REFRESH);
return CC_REFRESH;
}
@ -203,17 +207,20 @@ ed_kill_line(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
ed_move_to_end(EditLine *el, int c __unused)
ed_move_to_end(EditLine *el, Int c __attribute__((__unused__)))
{
el->el_line.cursor = el->el_line.lastchar;
if (el->el_map.type == MAP_VI) {
if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el);
return (CC_REFRESH);
return CC_REFRESH;
}
#ifdef VI_MOVE
el->el_line.cursor--;
#endif
}
return (CC_CURSOR);
return CC_CURSOR;
}
@ -223,21 +230,21 @@ ed_move_to_end(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
ed_move_to_beg(EditLine *el, int c __unused)
ed_move_to_beg(EditLine *el, Int c __attribute__((__unused__)))
{
el->el_line.cursor = el->el_line.buffer;
if (el->el_map.type == MAP_VI) {
/* We want FIRST non space character */
while (isspace((unsigned char) *el->el_line.cursor))
while (Isspace(*el->el_line.cursor))
el->el_line.cursor++;
if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el);
return (CC_REFRESH);
return CC_REFRESH;
}
}
return (CC_CURSOR);
return CC_CURSOR;
}
@ -246,12 +253,12 @@ ed_move_to_beg(EditLine *el, int c __unused)
* [^T] [^T]
*/
protected el_action_t
ed_transpose_chars(EditLine *el, int c)
ed_transpose_chars(EditLine *el, Int c)
{
if (el->el_line.cursor < el->el_line.lastchar) {
if (el->el_line.lastchar <= &el->el_line.buffer[1])
return (CC_ERROR);
return CC_ERROR;
else
el->el_line.cursor++;
}
@ -260,9 +267,9 @@ ed_transpose_chars(EditLine *el, int c)
c = el->el_line.cursor[-2];
el->el_line.cursor[-2] = el->el_line.cursor[-1];
el->el_line.cursor[-1] = c;
return (CC_REFRESH);
return CC_REFRESH;
} else
return (CC_ERROR);
return CC_ERROR;
}
@ -272,15 +279,15 @@ ed_transpose_chars(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
ed_next_char(EditLine *el, int c __unused)
ed_next_char(EditLine *el, Int c __attribute__((__unused__)))
{
char *lim = el->el_line.lastchar;
Char *lim = el->el_line.lastchar;
if (el->el_line.cursor >= lim ||
(el->el_line.cursor == lim - 1 &&
el->el_map.type == MAP_VI &&
el->el_chared.c_vcmd.action == NOP))
return (CC_ERROR);
return CC_ERROR;
el->el_line.cursor += el->el_state.argument;
if (el->el_line.cursor > lim)
@ -289,9 +296,9 @@ ed_next_char(EditLine *el, int c __unused)
if (el->el_map.type == MAP_VI)
if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el);
return (CC_REFRESH);
return CC_REFRESH;
}
return (CC_CURSOR);
return CC_CURSOR;
}
@ -301,11 +308,11 @@ ed_next_char(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
ed_prev_word(EditLine *el, int c __unused)
ed_prev_word(EditLine *el, Int c __attribute__((__unused__)))
{
if (el->el_line.cursor == el->el_line.buffer)
return (CC_ERROR);
return CC_ERROR;
el->el_line.cursor = c__prev_word(el->el_line.cursor,
el->el_line.buffer,
@ -315,9 +322,9 @@ ed_prev_word(EditLine *el, int c __unused)
if (el->el_map.type == MAP_VI)
if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el);
return (CC_REFRESH);
return CC_REFRESH;
}
return (CC_CURSOR);
return CC_CURSOR;
}
@ -327,7 +334,7 @@ ed_prev_word(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
ed_prev_char(EditLine *el, int c __unused)
ed_prev_char(EditLine *el, Int c __attribute__((__unused__)))
{
if (el->el_line.cursor > el->el_line.buffer) {
@ -338,11 +345,11 @@ ed_prev_char(EditLine *el, int c __unused)
if (el->el_map.type == MAP_VI)
if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el);
return (CC_REFRESH);
return CC_REFRESH;
}
return (CC_CURSOR);
return CC_CURSOR;
} else
return (CC_ERROR);
return CC_ERROR;
}
@ -351,19 +358,19 @@ ed_prev_char(EditLine *el, int c __unused)
* [^V] [^V]
*/
protected el_action_t
ed_quoted_insert(EditLine *el, int c)
ed_quoted_insert(EditLine *el, Int c)
{
int num;
char tc;
Char tc;
tty_quotemode(el);
num = el_getc(el, &tc);
c = (unsigned char) tc;
num = FUN(el,getc)(el, &tc);
c = tc;
tty_noquotemode(el);
if (num == 1)
return (ed_insert(el, c));
return ed_insert(el, c);
else
return (ed_end_of_file(el, 0));
return ed_end_of_file(el, 0);
}
@ -371,11 +378,11 @@ ed_quoted_insert(EditLine *el, int c)
* Adds to argument or enters a digit
*/
protected el_action_t
ed_digit(EditLine *el, int c)
ed_digit(EditLine *el, Int c)
{
if (!isdigit((unsigned char) c))
return (CC_ERROR);
if (!Isdigit(c))
return CC_ERROR;
if (el->el_state.doingarg) {
/* if doing an arg, add this in... */
@ -383,11 +390,11 @@ ed_digit(EditLine *el, int c)
el->el_state.argument = c - '0';
else {
if (el->el_state.argument > 1000000)
return (CC_ERROR);
return CC_ERROR;
el->el_state.argument =
(el->el_state.argument * 10) + (c - '0');
}
return (CC_ARGHACK);
return CC_ARGHACK;
}
return ed_insert(el, c);
@ -399,22 +406,22 @@ ed_digit(EditLine *el, int c)
* For ESC-n
*/
protected el_action_t
ed_argument_digit(EditLine *el, int c)
ed_argument_digit(EditLine *el, Int c)
{
if (!isdigit((unsigned char) c))
return (CC_ERROR);
if (!Isdigit(c))
return CC_ERROR;
if (el->el_state.doingarg) {
if (el->el_state.argument > 1000000)
return (CC_ERROR);
return CC_ERROR;
el->el_state.argument = (el->el_state.argument * 10) +
(c - '0');
} else { /* else starting an argument */
el->el_state.argument = c - '0';
el->el_state.doingarg = 1;
}
return (CC_ARGHACK);
return CC_ARGHACK;
}
@ -424,10 +431,11 @@ ed_argument_digit(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
ed_unassigned(EditLine *el, int c __unused)
ed_unassigned(EditLine *el __attribute__((__unused__)),
Int c __attribute__((__unused__)))
{
return (CC_ERROR);
return CC_ERROR;
}
@ -441,11 +449,11 @@ ed_unassigned(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
ed_tty_sigint(EditLine *el __unused,
int c __unused)
ed_tty_sigint(EditLine *el __attribute__((__unused__)),
Int c __attribute__((__unused__)))
{
return (CC_NORM);
return CC_NORM;
}
@ -455,11 +463,11 @@ ed_tty_sigint(EditLine *el __unused,
*/
protected el_action_t
/*ARGSUSED*/
ed_tty_dsusp(EditLine *el __unused,
int c __unused)
ed_tty_dsusp(EditLine *el __attribute__((__unused__)),
Int c __attribute__((__unused__)))
{
return (CC_NORM);
return CC_NORM;
}
@ -469,11 +477,11 @@ ed_tty_dsusp(EditLine *el __unused,
*/
protected el_action_t
/*ARGSUSED*/
ed_tty_flush_output(EditLine *el __unused,
int c __unused)
ed_tty_flush_output(EditLine *el __attribute__((__unused__)),
Int c __attribute__((__unused__)))
{
return (CC_NORM);
return CC_NORM;
}
@ -483,11 +491,11 @@ ed_tty_flush_output(EditLine *el __unused,
*/
protected el_action_t
/*ARGSUSED*/
ed_tty_sigquit(EditLine *el __unused,
int c __unused)
ed_tty_sigquit(EditLine *el __attribute__((__unused__)),
Int c __attribute__((__unused__)))
{
return (CC_NORM);
return CC_NORM;
}
@ -497,11 +505,11 @@ ed_tty_sigquit(EditLine *el __unused,
*/
protected el_action_t
/*ARGSUSED*/
ed_tty_sigtstp(EditLine *el __unused,
int c __unused)
ed_tty_sigtstp(EditLine *el __attribute__((__unused__)),
Int c __attribute__((__unused__)))
{
return (CC_NORM);
return CC_NORM;
}
@ -511,11 +519,11 @@ ed_tty_sigtstp(EditLine *el __unused,
*/
protected el_action_t
/*ARGSUSED*/
ed_tty_stop_output(EditLine *el __unused,
int c __unused)
ed_tty_stop_output(EditLine *el __attribute__((__unused__)),
Int c __attribute__((__unused__)))
{
return (CC_NORM);
return CC_NORM;
}
@ -525,11 +533,11 @@ ed_tty_stop_output(EditLine *el __unused,
*/
protected el_action_t
/*ARGSUSED*/
ed_tty_start_output(EditLine *el __unused,
int c __unused)
ed_tty_start_output(EditLine *el __attribute__((__unused__)),
Int c __attribute__((__unused__)))
{
return (CC_NORM);
return CC_NORM;
}
@ -539,13 +547,13 @@ ed_tty_start_output(EditLine *el __unused,
*/
protected el_action_t
/*ARGSUSED*/
ed_newline(EditLine *el, int c __unused)
ed_newline(EditLine *el, Int c __attribute__((__unused__)))
{
re_goto_bottom(el);
*el->el_line.lastchar++ = '\n';
*el->el_line.lastchar = '\0';
return (CC_NEWLINE);
return CC_NEWLINE;
}
@ -555,17 +563,17 @@ ed_newline(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
ed_delete_prev_char(EditLine *el, int c __unused)
ed_delete_prev_char(EditLine *el, Int c __attribute__((__unused__)))
{
if (el->el_line.cursor <= el->el_line.buffer)
return (CC_ERROR);
return CC_ERROR;
c_delbefore(el, el->el_state.argument);
el->el_line.cursor -= el->el_state.argument;
if (el->el_line.cursor < el->el_line.buffer)
el->el_line.cursor = el->el_line.buffer;
return (CC_REFRESH);
return CC_REFRESH;
}
@ -575,12 +583,12 @@ ed_delete_prev_char(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
ed_clear_screen(EditLine *el, int c __unused)
ed_clear_screen(EditLine *el, Int c __attribute__((__unused__)))
{
term_clear_screen(el); /* clear the whole real screen */
terminal_clear_screen(el); /* clear the whole real screen */
re_clear_display(el); /* reset everything */
return (CC_REFRESH);
return CC_REFRESH;
}
@ -590,11 +598,11 @@ ed_clear_screen(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
ed_redisplay(EditLine *el __unused,
int c __unused)
ed_redisplay(EditLine *el __attribute__((__unused__)),
Int c __attribute__((__unused__)))
{
return (CC_REDISPLAY);
return CC_REDISPLAY;
}
@ -604,11 +612,11 @@ ed_redisplay(EditLine *el __unused,
*/
protected el_action_t
/*ARGSUSED*/
ed_start_over(EditLine *el, int c __unused)
ed_start_over(EditLine *el, Int c __attribute__((__unused__)))
{
ch_reset(el, 0);
return (CC_REFRESH);
return CC_REFRESH;
}
@ -618,11 +626,11 @@ ed_start_over(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
ed_sequence_lead_in(EditLine *el __unused,
int c __unused)
ed_sequence_lead_in(EditLine *el __attribute__((__unused__)),
Int c __attribute__((__unused__)))
{
return (CC_NORM);
return CC_NORM;
}
@ -632,7 +640,7 @@ ed_sequence_lead_in(EditLine *el __unused,
*/
protected el_action_t
/*ARGSUSED*/
ed_prev_history(EditLine *el, int c __unused)
ed_prev_history(EditLine *el, Int c __attribute__((__unused__)))
{
char beep = 0;
int sv_event = el->el_history.eventno;
@ -642,7 +650,7 @@ ed_prev_history(EditLine *el, int c __unused)
if (el->el_history.eventno == 0) { /* save the current buffer
* away */
(void) strncpy(el->el_history.buf, el->el_line.buffer,
(void) Strncpy(el->el_history.buf, el->el_line.buffer,
EL_BUFSIZ);
el->el_history.last = el->el_history.buf +
(el->el_line.lastchar - el->el_line.buffer);
@ -652,7 +660,7 @@ ed_prev_history(EditLine *el, int c __unused)
if (hist_get(el) == CC_ERROR) {
if (el->el_map.type == MAP_VI) {
el->el_history.eventno = sv_event;
return CC_ERROR;
}
beep = 1;
/* el->el_history.eventno was fixed by first call */
@ -670,7 +678,7 @@ ed_prev_history(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
ed_next_history(EditLine *el, int c __unused)
ed_next_history(EditLine *el, Int c __attribute__((__unused__)))
{
el_action_t beep = CC_REFRESH, rval;
@ -697,9 +705,9 @@ ed_next_history(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
ed_search_prev_history(EditLine *el, int c __unused)
ed_search_prev_history(EditLine *el, Int c __attribute__((__unused__)))
{
const char *hp;
const Char *hp;
int h;
bool_t found = 0;
@ -712,20 +720,20 @@ ed_search_prev_history(EditLine *el, int c __unused)
"e_prev_search_hist(): eventno < 0;\n");
#endif
el->el_history.eventno = 0;
return (CC_ERROR);
return CC_ERROR;
}
if (el->el_history.eventno == 0) {
(void) strncpy(el->el_history.buf, el->el_line.buffer,
(void) Strncpy(el->el_history.buf, el->el_line.buffer,
EL_BUFSIZ);
el->el_history.last = el->el_history.buf +
(el->el_line.lastchar - el->el_line.buffer);
}
if (el->el_history.ref == NULL)
return (CC_ERROR);
return CC_ERROR;
hp = HIST_FIRST(el);
if (hp == NULL)
return (CC_ERROR);
return CC_ERROR;
c_setpat(el); /* Set search pattern !! */
@ -736,7 +744,7 @@ ed_search_prev_history(EditLine *el, int c __unused)
#ifdef SDEBUG
(void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp);
#endif
if ((strncmp(hp, el->el_line.buffer, (size_t)
if ((Strncmp(hp, el->el_line.buffer, (size_t)
(el->el_line.lastchar - el->el_line.buffer)) ||
hp[el->el_line.lastchar - el->el_line.buffer]) &&
c_hmatch(el, hp)) {
@ -751,11 +759,11 @@ ed_search_prev_history(EditLine *el, int c __unused)
#ifdef SDEBUG
(void) fprintf(el->el_errfile, "not found\n");
#endif
return (CC_ERROR);
return CC_ERROR;
}
el->el_history.eventno = h;
return (hist_get(el));
return hist_get(el);
}
@ -765,9 +773,9 @@ ed_search_prev_history(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
ed_search_next_history(EditLine *el, int c __unused)
ed_search_next_history(EditLine *el, Int c __attribute__((__unused__)))
{
const char *hp;
const Char *hp;
int h;
bool_t found = 0;
@ -776,14 +784,14 @@ ed_search_next_history(EditLine *el, int c __unused)
*el->el_line.lastchar = '\0'; /* just in case */
if (el->el_history.eventno == 0)
return (CC_ERROR);
return CC_ERROR;
if (el->el_history.ref == NULL)
return (CC_ERROR);
return CC_ERROR;
hp = HIST_FIRST(el);
if (hp == NULL)
return (CC_ERROR);
return CC_ERROR;
c_setpat(el); /* Set search pattern !! */
@ -791,7 +799,7 @@ ed_search_next_history(EditLine *el, int c __unused)
#ifdef SDEBUG
(void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp);
#endif
if ((strncmp(hp, el->el_line.buffer, (size_t)
if ((Strncmp(hp, el->el_line.buffer, (size_t)
(el->el_line.lastchar - el->el_line.buffer)) ||
hp[el->el_line.lastchar - el->el_line.buffer]) &&
c_hmatch(el, hp))
@ -804,12 +812,12 @@ ed_search_next_history(EditLine *el, int c __unused)
#ifdef SDEBUG
(void) fprintf(el->el_errfile, "not found\n");
#endif
return (CC_ERROR);
return CC_ERROR;
}
}
el->el_history.eventno = found;
return (hist_get(el));
return hist_get(el);
}
@ -819,9 +827,9 @@ ed_search_next_history(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
ed_prev_line(EditLine *el, int c __unused)
ed_prev_line(EditLine *el, Int c __attribute__((__unused__)))
{
char *ptr;
Char *ptr;
int nchars = c_hpos(el);
/*
@ -835,7 +843,7 @@ ed_prev_line(EditLine *el, int c __unused)
break;
if (el->el_state.argument > 0)
return (CC_ERROR);
return CC_ERROR;
/*
* Move to the beginning of the line
@ -852,7 +860,7 @@ ed_prev_line(EditLine *el, int c __unused)
continue;
el->el_line.cursor = ptr;
return (CC_CURSOR);
return CC_CURSOR;
}
@ -862,9 +870,9 @@ ed_prev_line(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
ed_next_line(EditLine *el, int c __unused)
ed_next_line(EditLine *el, Int c __attribute__((__unused__)))
{
char *ptr;
Char *ptr;
int nchars = c_hpos(el);
/*
@ -875,7 +883,7 @@ ed_next_line(EditLine *el, int c __unused)
break;
if (el->el_state.argument > 0)
return (CC_ERROR);
return CC_ERROR;
/*
* Move to the character requested
@ -886,7 +894,7 @@ ed_next_line(EditLine *el, int c __unused)
continue;
el->el_line.cursor = ptr;
return (CC_CURSOR);
return CC_CURSOR;
}
@ -896,16 +904,16 @@ ed_next_line(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
ed_command(EditLine *el, int c __unused)
ed_command(EditLine *el, Int c __attribute__((__unused__)))
{
char tmpbuf[EL_BUFSIZ];
Char tmpbuf[EL_BUFSIZ];
int tmplen;
tmplen = c_gets(el, tmpbuf, "\n: ");
term__putc(el, '\n');
tmplen = c_gets(el, tmpbuf, STR("\n: "));
terminal__putc(el, '\n');
if (tmplen < 0 || (tmpbuf[tmplen] = 0, parse_line(el, tmpbuf)) == -1)
term_beep(el);
terminal_beep(el);
el->el_map.current = el->el_map.key;
re_clear_display(el);

290
lib/libedit/config.h Normal file
View File

@ -0,0 +1,290 @@
/* $FreeBSD$ */
/* config.h. Generated from config.h.in by configure. */
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if the `closedir' function returns void instead of `int'. */
/* #undef CLOSEDIR_VOID */
/* Define to 1 if you have the <curses.h> header file. */
#define HAVE_CURSES_H 1
/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
*/
#define HAVE_DIRENT_H 1
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
/* Define to 1 if you have the `endpwent' function. */
#define HAVE_ENDPWENT 1
/* Define to 1 if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1
/* Define to 1 if you have the `fgetln' function. */
#define HAVE_FGETLN 1
/* Define to 1 if you have the `fork' function. */
#define HAVE_FORK 1
/* Define to 1 if you have getpwnam_r and getpwuid_r that are draft POSIX.1
versions. */
/* #undef HAVE_GETPW_R_DRAFT */
/* Define to 1 if you have getpwnam_r and getpwuid_r that are POSIX.1
compatible. */
#define HAVE_GETPW_R_POSIX 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the `isascii' function. */
#define HAVE_ISASCII 1
/* Define to 1 if you have the `issetugid' function. */
#define HAVE_ISSETUGID 1
/* Define to 1 if you have the `curses' library (-lcurses). */
/* #undef HAVE_LIBCURSES */
/* Define to 1 if you have the `ncurses' library (-lncurses). */
#define HAVE_LIBNCURSES 1
/* Define to 1 if you have the `termcap' library (-ltermcap). */
/* #undef HAVE_LIBTERMCAP */
/* Define to 1 if you have the `terminfo' library (-lterminfo). */
/* #undef HAVE_LIBTERMINFO */
/* Define to 1 if you have the `termlib' library (-ltermlib). */
/* #undef HAVE_LIBTERMLIB */
/* Define to 1 if you have the <limits.h> header file. */
#define HAVE_LIMITS_H 1
/* Define to 1 if you have the <malloc.h> header file. */
#define HAVE_MALLOC_H 1
/* Define to 1 if you have the `memchr' function. */
#define HAVE_MEMCHR 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the `memset' function. */
#define HAVE_MEMSET 1
/* Define to 1 if you have the <ncurses.h> header file. */
#define HAVE_NCURSES_H 1
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
/* #undef HAVE_NDIR_H */
/* Define to 1 if you have the `regcomp' function. */
#define HAVE_REGCOMP 1
/* Define to 1 if you have the `re_comp' function. */
/* #undef HAVE_RE_COMP */
/* Define to 1 if `stat' has the bug that it succeeds when given the
zero-length file name argument. */
/* #undef HAVE_STAT_EMPTY_STRING_BUG */
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the `strcasecmp' function. */
#define HAVE_STRCASECMP 1
/* Define to 1 if you have the `strchr' function. */
#define HAVE_STRCHR 1
/* Define to 1 if you have the `strcspn' function. */
#define HAVE_STRCSPN 1
/* Define to 1 if you have the `strdup' function. */
#define HAVE_STRDUP 1
/* Define to 1 if you have the `strerror' function. */
#define HAVE_STRERROR 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the `strlcat' function. */
#define HAVE_STRLCAT 1
/* Define to 1 if you have the `strlcpy' function. */
#define HAVE_STRLCPY 1
/* Define to 1 if you have the `strrchr' function. */
#define HAVE_STRRCHR 1
/* Define to 1 if you have the `strstr' function. */
#define HAVE_STRSTR 1
/* Define to 1 if you have the `strtol' function. */
#define HAVE_STRTOL 1
/* Define to 1 if struct dirent has member d_namlen */
#define HAVE_STRUCT_DIRENT_D_NAMLEN 1
/* Define to 1 if you have the `strunvis' function. */
#define HAVE_STRUNVIS 1
/* Define to 1 if you have the `strvis' function. */
#define HAVE_STRVIS 1
/* Define to 1 if you have the <sys/cdefs.h> header file. */
#define HAVE_SYS_CDEFS_H 1
/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
*/
/* #undef HAVE_SYS_DIR_H */
/* Define to 1 if you have the <sys/ioctl.h> header file. */
#define HAVE_SYS_IOCTL_H 1
/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
*/
/* #undef HAVE_SYS_NDIR_H */
/* Define to 1 if you have the <sys/param.h> header file. */
#define HAVE_SYS_PARAM_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
#define HAVE_SYS_WAIT_H 1
/* Define to 1 if you have the <termcap.h> header file. */
#define HAVE_TERMCAP_H 1
/* Define to 1 if you have the <term.h> header file. */
#define HAVE_TERM_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to 1 if the system has the type `u_int32_t'. */
#define HAVE_U_INT32_T 1
/* Define to 1 if you have the `vfork' function. */
#define HAVE_VFORK 1
/* Define to 1 if you have the <vfork.h> header file. */
/* #undef HAVE_VFORK_H */
/* Define to 1 if you have the `vis' function. */
#define HAVE_VIS 1
/* Define to 1 if you have the `wcsdup' function. */
#define HAVE_WCSDUP 1
/* Define to 1 if `fork' works. */
#define HAVE_WORKING_FORK 1
/* Define to 1 if `vfork' works. */
#define HAVE_WORKING_VFORK 1
/* Define to 1 if `lstat' dereferences a symlink specified with a trailing
slash. */
#define LSTAT_FOLLOWS_SLASHED_SYMLINK 1
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#define LT_OBJDIR ".libs/"
/* Name of package */
#define PACKAGE "libedit-20110729"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT ""
/* Define to the full name of this package. */
#define PACKAGE_NAME "libedit"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "libedit 3.0"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "libedit-20110729"
/* Define to the home page for this package. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "3.0"
/* Define as the return type of signal handlers (`int' or `void'). */
#define RETSIGTYPE void
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Enable extensions on AIX 3, Interix. */
#ifndef _ALL_SOURCE
# define _ALL_SOURCE 1
#endif
/* Enable GNU extensions on systems that have them. */
#ifndef _GNU_SOURCE
# define _GNU_SOURCE 1
#endif
/* Enable threading extensions on Solaris. */
#ifndef _POSIX_PTHREAD_SEMANTICS
# define _POSIX_PTHREAD_SEMANTICS 1
#endif
/* Enable extensions on HP NonStop. */
#ifndef _TANDEM_SOURCE
# define _TANDEM_SOURCE 1
#endif
/* Enable general extensions on Solaris. */
#ifndef __EXTENSIONS__
# define __EXTENSIONS__ 1
#endif
/* Version number of package */
#define VERSION "3.0"
/* Define to 1 if you want wide-character code */
/* #undef WIDECHAR */
/* Define to 1 if on MINIX. */
/* #undef _MINIX */
/* Define to 2 if the system does not provide POSIX.1 features except with
this defined. */
/* #undef _POSIX_1_SOURCE */
/* Define to 1 if you need to in order for `stat' and other things to work. */
/* #undef _POSIX_SOURCE */
/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */
/* Define to `int' if <sys/types.h> does not define. */
/* #undef pid_t */
/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */
/* Define as `fork' if `vfork' does not work. */
/* #undef vfork */
#include "sys.h"
#undef SCCSID
#undef LIBC_SCCS
#undef lint
#undef SIZE_T_MAX

View File

@ -111,6 +111,7 @@ extern char *rl_basic_word_break_characters;
extern char *rl_completer_word_break_characters;
extern char *rl_completer_quote_characters;
extern Function *rl_completion_entry_function;
extern char *(*rl_completion_word_break_hook)(void);
extern CPPFunction *rl_attempted_completion_function;
extern int rl_attempted_completion_over;
extern int rl_completion_type;
@ -126,6 +127,8 @@ extern char *rl_prompt;
/*
* The following is not implemented
*/
extern int rl_catch_signals;
extern int rl_catch_sigwinch;
extern KEYMAP_ENTRY_ARRAY emacs_standard_keymap,
emacs_meta_keymap,
emacs_ctlx_keymap;
@ -153,7 +156,6 @@ int where_history(void);
HIST_ENTRY *current_history(void);
HIST_ENTRY *history_get(int);
HIST_ENTRY *remove_history(int);
/*###152 [lint] syntax error 'histdata_t' [249]%%%*/
HIST_ENTRY *replace_history_entry(int, const char *, histdata_t);
int history_total_bytes(void);
int history_set_pos(int);
@ -200,6 +202,7 @@ void rl_get_screen_size(int *, int *);
void rl_set_screen_size(int, int);
char *rl_filename_completion_function (const char *, int);
int _rl_abort_internal(void);
int _rl_qsort_string_compare(char **, char **);
char **rl_completion_matches(const char *, rl_compentry_func_t *);
void rl_forced_update_display(void);
int rl_set_prompt(const char *);

View File

@ -1,6 +1,6 @@
.\" $NetBSD: editline.3,v 1.70 2009/07/05 21:55:24 perry Exp $
.\" $NetBSD: editline.3,v 1.84 2014/12/25 13:39:41 wiz Exp $
.\"
.\" Copyright (c) 1997-2003 The NetBSD Foundation, Inc.
.\" Copyright (c) 1997-2014 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
.\" This file was contributed to The NetBSD Foundation by Luke Mewburn.
@ -28,33 +28,52 @@
.\"
.\" $FreeBSD$
.\"
.Dd July 5, 2009
.Dd December 25, 2014
.Dt EDITLINE 3
.Os
.Sh NAME
.Nm editline ,
.Nm el_init ,
.Nm el_init_fd ,
.Nm el_end ,
.Nm el_reset ,
.Nm el_gets ,
.Nm el_wgets ,
.Nm el_getc ,
.Nm el_wgetc ,
.Nm el_push ,
.Nm el_wpush ,
.Nm el_parse ,
.Nm el_wparse ,
.Nm el_set ,
.Nm el_wset ,
.Nm el_get ,
.Nm el_wget ,
.Nm el_source ,
.Nm el_resize ,
.Nm el_cursor ,
.Nm el_line ,
.Nm el_wline ,
.Nm el_insertstr ,
.Nm el_winsertstr ,
.Nm el_deletestr ,
.Nm el_wdeletestr ,
.Nm history_init ,
.Nm history_winit ,
.Nm history_end ,
.Nm history_wend ,
.Nm history ,
.Nm history_w ,
.Nm tok_init ,
.Nm tok_winit ,
.Nm tok_end ,
.Nm tok_wend ,
.Nm tok_reset ,
.Nm tok_wreset ,
.Nm tok_line ,
.Nm tok_wline ,
.Nm tok_str
.Nm tok_wstr
.Nd line editor, history and tokenization functions
.Sh LIBRARY
.Lb libedit
@ -62,51 +81,86 @@
.In histedit.h
.Ft EditLine *
.Fn el_init "const char *prog" "FILE *fin" "FILE *fout" "FILE *ferr"
.Ft EditLine *
.Fn el_init_fd "const char *prog" "FILE *fin" "FILE *fout" "FILE *ferr" "int fdin" "int fdout" "int fderr"
.Ft void
.Fn el_end "EditLine *e"
.Ft void
.Fn el_reset "EditLine *e"
.Ft const char *
.Fn el_gets "EditLine *e" "int *count"
.Ft const wchar_t *
.Fn el_wgets "EditLine *e" "int *count"
.Ft int
.Fn el_getc "EditLine *e" "char *ch"
.Ft int
.Fn el_wgetc "EditLine *e" "wchar_t *ch"
.Ft void
.Fn el_push "EditLine *e" "char *str"
.Fn el_push "EditLine *e" "const char *str"
.Ft void
.Fn el_wpush "EditLine *e" "const wchar_t *str"
.Ft int
.Fn el_parse "EditLine *e" "int argc" "const char *argv[]"
.Ft int
.Fn el_wparse "EditLine *e" "int argc" "const wchar_t *argv[]"
.Ft int
.Fn el_set "EditLine *e" "int op" "..."
.Ft int
.Fn el_wset "EditLine *e" "int op" "..."
.Ft int
.Fn el_get "EditLine *e" "int op" "..."
.Ft int
.Fn el_wget "EditLine *e" "int op" "..."
.Ft int
.Fn el_source "EditLine *e" "const char *file"
.Ft void
.Fn el_resize "EditLine *e"
.Fn int
.Fn el_cursor "EditLine *e" "int count"
.Ft const LineInfo *
.Fn el_line "EditLine *e"
.Ft const LineInfoW *
.Fn el_wline "EditLine *e"
.Ft int
.Fn el_insertstr "EditLine *e" "const char *str"
.Ft int
.Fn el_winsertstr "EditLine *e" "const wchar_t *str"
.Ft void
.Fn el_deletestr "EditLine *e" "int count"
.Ft void
.Fn el_wdeletestr "EditLine *e" "int count"
.Ft History *
.Fn history_init
.Ft HistoryW *
.Fn history_winit
.Ft void
.Fn history_end "History *h"
.Ft void
.Fn history_wend "HistoryW *h"
.Ft int
.Fn history "History *h" "HistEvent *ev" "int op" "..."
.Ft int
.Fn history_w "HistoryW *h" "HistEventW *ev" "int op" "..."
.Ft Tokenizer *
.Fn tok_init "const char *IFS"
.Ft TokenizerW *
.Fn tok_winit "const wchar_t *IFS"
.Ft void
.Fn tok_end "Tokenizer *t"
.Ft void
.Fn tok_wend "TokenizerW *t"
.Ft void
.Fn tok_reset "Tokenizer *t"
.Ft void
.Fn tok_wreset "TokenizerW *t"
.Ft int
.Fo tok_line
.Fa "Tokenizer *t" "const LineInfo *li" "int *argc" "const char **argv[]"
.Fa "int *cursorc" "int *cursoro"
.Fc
.Fn tok_line "Tokenizer *t" "const LineInfo *li" "int *argc" "const char **argv[]" "int *cursorc" "int *cursoro"
.Ft int
.Fn tok_wline "TokenizerW *t" "const LineInfoW *li" "int *argc" "const wchar_t **argv[]" "int *cursorc" "int *cursoro"
.Ft int
.Fn tok_str "Tokenizer *t" "const char *str" "int *argc" "const char **argv[]"
.Ft int
.Fn tok_wstr "TokenizerW *t" "const wchar_t *str" "int *argc" "const wchar_t **argv[]"
.Sh DESCRIPTION
The
.Nm
@ -126,14 +180,21 @@ The line editing functions use a common data structure,
.Fa EditLine ,
which is created by
.Fn el_init
or
.Fn el_init_fd
and freed by
.Fn el_end .
.Pp
The wide-character functions behave the same way as their narrow
counterparts.
.Pp
The following functions are available:
.Bl -tag -width 4n
.It Fn el_init
Initialise the line editor, and return a data structure
to be used by all other line editing functions.
to be used by all other line editing functions, or
.Dv NULL
on failure.
.Fa prog
is the name of the invoking program, used when reading the
.Xr editrc 5
@ -146,11 +207,20 @@ are the input, output, and error streams (respectively) to use.
In this documentation, references to
.Dq the tty
are actually to this input/output stream combination.
.It Fn el_init_fd
Like
.Fn el_init
but allows specifying file descriptors for the
.Xr stdio 3
corresponding streams, in case those were created with
.Xr funopen 3 .
.It Fn el_end
Clean up and finish with
.Fa e ,
assumed to have been created with
.Fn el_init .
.Fn el_init
or
.Fn el_init_fd .
.It Fn el_reset
Reset the tty and the parser.
This should be called after an error which may have upset the tty's
@ -174,7 +244,10 @@ and must be copied if the data is to be retained.
Read a character from the tty.
.Fa ch
is modified to contain the character read.
Returns the number of characters read if successful, \-1 otherwise.
Returns the number of characters read if successful, \-1 otherwise,
in which case
.Dv errno
can be inspected for the cause.
.It Fn el_push
Pushes
.Fa str
@ -196,7 +269,7 @@ to execute builtin
.Nm
commands.
If the command is prefixed with
.Dq prog:
.Dq prog :
then
.Fn el_parse
will only execute the command if
@ -209,7 +282,7 @@ The return value is
\-1 if the command is unknown,
0 if there was no error or
.Dq prog
did not match, or
didn't match, or
1 if the command returned an error.
Refer to
.Xr editrc 5
@ -221,6 +294,7 @@ parameters.
.Fa op
determines which parameter to set, and each operation has its
own parameter list.
Returns 0 on success, \-1 on failure.
.Pp
The following values for
.Fa op
@ -385,6 +459,14 @@ check this
(using
.Fn el_get )
to determine if editing should be enabled or not.
.It Dv EL_UNBUFFERED , Fa "int flag"
If
.Fa flag
is zero,
unbuffered mode is disabled (the default).
In unbuffered mode,
.Fn el_gets
will return immediately after processing a single character.
.It Dv EL_GETCFN , Fa "int (*f)(EditLine *, char *c)"
Define the character reading function as
.Fa f ,
@ -396,7 +478,7 @@ and
.Fn el_getc .
The builtin function can be set or restored with the special function
name
.Dv EL_BUILTIN_GETCFN .
.Dq Dv EL_BUILTIN_GETCFN .
.It Dv EL_CLIENTDATA , Fa "void *data"
Register
.Fa data
@ -454,7 +536,7 @@ If
is not
.Dv NULL ,
return the start/stop literal prompt character in it.
.It Dv EL_EDITOR , Fa "const char *"
.It Dv EL_EDITOR , Fa "const char **"
Return the name of the editor, which will be one of
.Dq emacs
or
@ -478,7 +560,7 @@ above).
Return non-zero if editing is enabled.
.It Dv EL_GETCFN , Fa "int (**f)(EditLine *, char *)"
Return a pointer to the function that read characters, which is equal to
.Dv EL_BUILTIN_GETCFN
.Dq Dv EL_BUILTIN_GETCFN
in the case of the default builtin function.
.It Dv EL_CLIENTDATA , Fa "void **data"
Retrieve
@ -487,10 +569,7 @@ previously registered with the corresponding
.Fn el_set
call.
.It Dv EL_UNBUFFERED , Fa "int"
Sets or clears unbuffered mode.
In this mode,
.Fn el_gets
will return immediately after processing a single character.
Return non-zero if unbuffered mode is enabled.
.It Dv EL_PREP_TERM , Fa "int"
Sets or clears terminal editing mode.
.It Dv EL_GETFP , Fa "int fd", Fa "FILE **fp"
@ -531,6 +610,8 @@ Refer to
.Xr editrc 5
for details on the format of
.Fa file .
.Fn el_source
returns 0 on success and \-1 on error.
.It Fn el_resize
Must be called if the terminal size changes.
If
@ -538,9 +619,14 @@ If
has been set with
.Fn el_set ,
then this is done automatically.
Otherwise, it is the responsibility of the application to call
Otherwise, it's the responsibility of the application to call
.Fn el_resize
on the appropriate occasions.
.It Fn el_cursor
Move the cursor to the right (if positive) or to the left (if negative)
.Fa count
characters.
Returns the resulting offset of the cursor from the beginning of the line.
.It Fn el_line
Return the editing information for the current line in a
.Fa LineInfo
@ -568,7 +654,7 @@ Insert
into the line at the cursor.
Returns \-1 if
.Fa str
is empty or will not fit, and 0 otherwise.
is empty or won't fit, and 0 otherwise.
.It Fn el_deletestr
Delete
.Fa count
@ -586,7 +672,9 @@ The following functions are available:
.Bl -tag -width 4n
.It Fn history_init
Initialise the history list, and return a data structure
to be used by all other history list functions.
to be used by all other history list functions, or
.Dv NULL
on failure.
.It Fn history_end
Clean up and finish with
.Fa h ,
@ -623,7 +711,7 @@ Fa "history_sfun_t set" , Fa "history_vfun_t clear" , \
Fa "history_efun_t enter" , Fa "history_efun_t add"
Define functions to perform various history operations.
.Fa ptr
is the argument given to a function when it is invoked.
is the argument given to a function when it's invoked.
.It Dv H_FIRST
Return the first element in the history.
.It Dv H_LAST
@ -655,12 +743,12 @@ as a new element to the history, and, if necessary,
removing the oldest entry to keep the list to the created size.
If
.Dv H_SETUNIQUE
was has been called with a non-zero arguments, the element
has been called with a non-zero argument, the element
will not be entered into the history if its contents match
the ones of the current history element.
If the element is entered
.Fn history
returns 1, if it is ignored as a duplicate returns 0.
returns 1; if it is ignored as a duplicate returns 0.
Finally
.Fn history
returns \-1 if an error occurred.
@ -682,9 +770,11 @@ Load the history list stored in
.It Dv H_SAVE , Fa "const char *file"
Save the history list to
.Fa file .
.It Dv H_SAVE_FP , Fa "FILE*"
.It Dv H_SAVE_FP , Fa "FILE *fp"
Save the history list to the opened
.Fa FILE* .
.Ft FILE
pointer
.Fa fp .
.It Dv H_SETUNIQUE , Fa "int unique"
Set flag that adjacent identical event strings should not be entered
into the history.
@ -701,9 +791,8 @@ The caller is responsible for free'ing the string in the returned
.Fa HistEvent .
.El
.Pp
The
.Fn history
function returns \*[Ge] 0 if the operation
returns \*[Gt]= 0 if the operation
.Fa op
succeeds.
Otherwise, \-1 is returned and
@ -747,7 +836,7 @@ and before a new line is to be tokenized.
.It Fn tok_line
Tokenize
.Fa li ,
if successful, modify
If successful, modify:
.Fa argv
to contain the words,
.Fa argc
@ -774,12 +863,14 @@ and
.Aq newline .
A positive exit code indicates that another line should be read
and tokenization attempted again.
.
.It Fn tok_str
A simpler form of
.Fn tok_line ;
.Fa str
is a NUL terminated string to tokenize.
.El
.
.\"XXX.Sh EXAMPLES
.\"XXX: provide some examples
.Sh SEE ALSO
@ -796,10 +887,9 @@ library first appeared in
.Dv CC_REDISPLAY
appeared in
.Nx 1.3 .
.Dv CC_REFRESH_BEEP
and
.Dv CC_REFRESH_BEEP ,
.Dv EL_EDITMODE
appeared in
and the readline emulation appeared in
.Nx 1.4 .
.Dv EL_RPROMPT
appeared in
@ -817,6 +907,10 @@ wrote this manual and implemented
.Dv EL_EDITMODE ,
and
.Dv EL_RPROMPT .
.An Jaromir Dolecek
implemented the readline emulation.
.An Johny Mattsson
implemented wide-character support.
.Sh BUGS
At this time, it is the responsibility of the caller to
check the result of the

View File

@ -1,4 +1,4 @@
.\" $NetBSD: editrc.5,v 1.24 2009/04/11 22:17:52 wiz Exp $
.\" $NetBSD: editrc.5,v 1.29 2014/12/25 13:39:41 wiz Exp $
.\"
.\" Copyright (c) 1997-2000 The NetBSD Foundation, Inc.
.\" All rights reserved.
@ -28,7 +28,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd October 18, 2003
.Dd December 25, 2014
.Dt EDITRC 5
.Os
.Sh NAME
@ -44,7 +44,8 @@ file defines various settings to be used by the
library.
.Pp
The format of each line is:
.Dl [prog:]command [arg [...]]
.Pp
.Dl [prog:]command [arg ...]
.Pp
.Ar command
is one of the
@ -105,16 +106,12 @@ to
.Ar key .
Options include:
.Bl -tag -width 4n
.It Fl e
Bind all keys to the standard GNU Emacs-like bindings.
.It Fl v
Bind all keys to the standard
.Xr vi 1 Ns -like
bindings.
.It Fl a
List or change key bindings in the
.Xr vi 1
mode alternate (command mode) key map.
.It Fl e
Bind all keys to the standard GNU Emacs-like bindings.
.It Fl k
.Ar key
is interpreted as a symbolic arrow key name, which may be one of
@ -136,6 +133,10 @@ Bound keys in
.Ar command
are themselves reinterpreted, and this continues for ten levels of
interpretation.
.It Fl v
Bind all keys to the standard
.Xr vi 1 Ns -like
bindings.
.El
.Pp
.Ar command
@ -150,8 +151,10 @@ can contain control characters of the form
.Sm off
.Sq No ^ Ar character
.Sm on
(e.g.\&
.Sq ^A ) ,
.Po
e.g.\&
.Sq ^A
.Pc ,
and the following backslashed escape sequences:
.Pp
.Bl -tag -compact -offset indent -width 4n
@ -186,7 +189,7 @@ and
.Sq ^ .
.It Ic echotc Oo Fl sv Oc Ar arg Ar ...
Exercise terminal capabilities given in
.Ar arg Ar ... .
.Ar arg ... .
If
.Ar arg
is
@ -194,7 +197,8 @@ is
.Sq cols ,
.Sq lines ,
.Sq rows ,
.Sq meta or
.Sq meta ,
or
.Sq tabs ,
the value of that capability is printed, with
.Dq yes
@ -207,7 +211,7 @@ returns an empty string for non-existent capabilities, rather than
causing an error.
.Fl v
causes messages to be verbose.
.It Ic edit Op Cm on | off
.It Ic edit Op Li on | Li off
Enable or disable the
.Nm editline
functionality in a program.
@ -229,9 +233,6 @@ is non zero, only keep unique history entries.
If
.Dv n
is zero, then keep all entries (the default).
.It Ic telltc
List the values of all the terminal capabilities (see
.Xr termcap 5 ) .
.It Ic settc Ar cap Ar val
Set the terminal capability
.Ar cap
@ -262,9 +263,13 @@ set of tty modes respectively; defaulting to
Without other arguments,
.Ic setty
lists the modes in the chosen set which are fixed on
.Pq Sq +mode
.Po
.Sq +mode
.Pc
or off
.Pq Sq -mode .
.Po
.Sq -mode
.Pc .
.Fl a
lists all tty modes in the chosen set regardless of the setting.
With
@ -286,6 +291,9 @@ If
is empty
then the character is set to
.Dv _POSIX_VDISABLE .
.It Ic telltc
List the values of all the terminal capabilities (see
.Xr termcap 5 ) .
.El
.Sh EDITOR COMMANDS
The following editor commands are available for use in key bindings:
@ -295,11 +303,11 @@ The following editor commands are available for use in key bindings:
Vi paste previous deletion to the right of the cursor.
.It Ic vi-paste-prev
Vi paste previous deletion to the left of the cursor.
.It Ic vi-prev-space-word
.It Ic vi-prev-big-word
Vi move to the previous space delimited word.
.It Ic vi-prev-word
Vi move to the previous word.
.It Ic vi-next-space-word
.It Ic vi-next-big-word
Vi move to the next space delimited word.
.It Ic vi-next-word
Vi move to the next word.
@ -327,9 +335,9 @@ Vi enter insert mode after the cursor.
Vi enter insert mode at end of line.
.It Ic vi-delete-meta
Vi delete prefix command.
.It Ic vi-end-word
.It Ic vi-end-big-word
Vi move to the end of the current space delimited word.
.It Ic vi-to-end-word
.It Ic vi-end-word
Vi move to the end of the current word.
.It Ic vi-undo
Vi undo last change.
@ -363,6 +371,28 @@ Vi move up to the character specified previous.
Vi repeat current character search in the same search direction.
.It Ic vi-repeat-prev-char
Vi repeat current character search in the opposite search direction.
.It Ic vi-match
Vi go to matching () {} or [].
.It Ic vi-undo-line
Vi undo all changes to line.
.It Ic vi-to-column
Vi go to specified column.
.It Ic vi-yank-end
Vi yank to end of line.
.It Ic vi-yank
Vi yank.
.It Ic vi-comment-out
Vi comment out current command.
.It Ic vi-alias
Vi include shell alias.
.It Ic vi-to-history-line
Vi go to specified history file line..
.It Ic vi-histedit
Vi edit history line with vi.
.It Ic vi-history-word
Vi append word from previous input line.
.It Ic vi-redo
Vi redo last non-motion command.
.It Ic em-delete-or-list
Delete character under cursor or list completions if at end of line.
.It Ic em-delete-next-word

View File

@ -1,3 +1,5 @@
/* $NetBSD: el.c,v 1.73 2014/06/18 18:12:28 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
@ -28,12 +30,15 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $NetBSD: el.c,v 1.55 2009/07/25 21:19:23 christos Exp $
*/
#include "config.h"
#if !defined(lint) && !defined(SCCSID)
#if 0
static char sccsid[] = "@(#)el.c 8.2 (Berkeley) 1/3/94";
#else
__RCSID("$NetBSD: el.c,v 1.73 2014/06/18 18:12:28 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@ -41,29 +46,34 @@ __FBSDID("$FreeBSD$");
/*
* el.c: EditLine interface functions
*/
#include "sys.h"
#include <sys/types.h>
#include <sys/param.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <ctype.h>
#include <locale.h>
#include <langinfo.h>
#include "el.h"
#define HAVE_ISSETUGID
/* el_init():
* Initialize editline and set default parameters.
*/
public EditLine *
el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr)
{
return el_init_fd(prog, fin, fout, ferr, fileno(fin), fileno(fout),
fileno(ferr));
}
EditLine *el = (EditLine *) el_malloc(sizeof(EditLine));
public EditLine *
el_init_fd(const char *prog, FILE *fin, FILE *fout, FILE *ferr,
int fdin, int fdout, int fderr)
{
EditLine *el = el_malloc(sizeof(*el));
if (el == NULL)
return (NULL);
return NULL;
memset(el, 0, sizeof(EditLine));
@ -71,9 +81,12 @@ el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr)
el->el_outfile = fout;
el->el_errfile = ferr;
el->el_infd = fileno(fin);
el->el_infd = fdin;
el->el_outfd = fdout;
el->el_errfd = fderr;
if ((el->el_prog = el_strdup(prog)) == NULL) {
el->el_prog = Strdup(ct_decode_string(prog, &el->el_scratch));
if (el->el_prog == NULL) {
el_free(el);
return NULL;
}
@ -82,13 +95,19 @@ el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr)
* Initialize all the modules. Order is important!!!
*/
el->el_flags = 0;
#ifdef WIDECHAR
if (setlocale(LC_CTYPE, "") != NULL) {
if (strcmp(nl_langinfo(CODESET), "UTF-8") == 0)
el->el_flags |= CHARSET_IS_UTF8;
}
#endif
if (term_init(el) == -1) {
if (terminal_init(el) == -1) {
el_free(el->el_prog);
el_free(el);
return NULL;
}
(void) key_init(el);
(void) keymacro_init(el);
(void) map_init(el);
if (tty_init(el) == -1)
el->el_flags |= NO_TTY;
@ -99,7 +118,7 @@ el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr)
(void) sig_init(el);
(void) read_init(el);
return (el);
return el;
}
@ -115,8 +134,8 @@ el_end(EditLine *el)
el_reset(el);
term_end(el);
key_end(el);
terminal_end(el);
keymacro_end(el);
map_end(el);
tty_end(el);
ch_end(el);
@ -125,8 +144,14 @@ el_end(EditLine *el)
prompt_end(el);
sig_end(el);
el_free((ptr_t) el->el_prog);
el_free((ptr_t) el);
el_free(el->el_prog);
#ifdef WIDECHAR
el_free(el->el_scratch.cbuff);
el_free(el->el_scratch.wbuff);
el_free(el->el_lgcyconv.cbuff);
el_free(el->el_lgcyconv.wbuff);
#endif
el_free(el);
}
@ -146,13 +171,13 @@ el_reset(EditLine *el)
* set the editline parameters
*/
public int
el_set(EditLine *el, int op, ...)
FUN(el,set)(EditLine *el, int op, ...)
{
va_list ap;
int rv = 0;
if (el == NULL)
return (-1);
return -1;
va_start(ap, op);
switch (op) {
@ -160,25 +185,39 @@ el_set(EditLine *el, int op, ...)
case EL_RPROMPT: {
el_pfunc_t p = va_arg(ap, el_pfunc_t);
rv = prompt_set(el, p, 0, op);
rv = prompt_set(el, p, 0, op, 1);
break;
}
case EL_RESIZE: {
el_zfunc_t p = va_arg(ap, el_zfunc_t);
void *arg = va_arg(ap, void *);
rv = ch_resizefun(el, p, arg);
break;
}
case EL_ALIAS_TEXT: {
el_afunc_t p = va_arg(ap, el_afunc_t);
void *arg = va_arg(ap, void *);
rv = ch_aliasfun(el, p, arg);
break;
}
case EL_PROMPT_ESC:
case EL_RPROMPT_ESC: {
el_pfunc_t p = va_arg(ap, el_pfunc_t);
char c = va_arg(ap, int);
int c = va_arg(ap, int);
rv = prompt_set(el, p, c, op);
rv = prompt_set(el, p, c, op, 1);
break;
}
case EL_TERMINAL:
rv = term_set(el, va_arg(ap, char *));
rv = terminal_set(el, va_arg(ap, char *));
break;
case EL_EDITOR:
rv = map_set_editor(el, va_arg(ap, char *));
rv = map_set_editor(el, va_arg(ap, Char *));
break;
case EL_SIGNAL:
@ -191,40 +230,39 @@ el_set(EditLine *el, int op, ...)
case EL_BIND:
case EL_TELLTC:
case EL_SETTC:
case EL_GETTC:
case EL_ECHOTC:
case EL_SETTY:
{
const char *argv[20];
const Char *argv[20];
int i;
for (i = 1; i < 20; i++)
if ((argv[i] = va_arg(ap, char *)) == NULL)
for (i = 1; i < (int)__arraycount(argv); i++)
if ((argv[i] = va_arg(ap, Char *)) == NULL)
break;
switch (op) {
case EL_BIND:
argv[0] = "bind";
argv[0] = STR("bind");
rv = map_bind(el, i, argv);
break;
case EL_TELLTC:
argv[0] = "telltc";
rv = term_telltc(el, i, argv);
argv[0] = STR("telltc");
rv = terminal_telltc(el, i, argv);
break;
case EL_SETTC:
argv[0] = "settc";
rv = term_settc(el, i, argv);
argv[0] = STR("settc");
rv = terminal_settc(el, i, argv);
break;
case EL_ECHOTC:
argv[0] = "echotc";
rv = term_echotc(el, i, argv);
argv[0] = STR("echotc");
rv = terminal_echotc(el, i, argv);
break;
case EL_SETTY:
argv[0] = "setty";
argv[0] = STR("setty");
rv = tty_stty(el, i, argv);
break;
@ -238,8 +276,8 @@ el_set(EditLine *el, int op, ...)
case EL_ADDFN:
{
char *name = va_arg(ap, char *);
char *help = va_arg(ap, char *);
Char *name = va_arg(ap, Char *);
Char *help = va_arg(ap, Char *);
el_func_t func = va_arg(ap, el_func_t);
rv = map_addfunc(el, name, help, func);
@ -249,9 +287,11 @@ el_set(EditLine *el, int op, ...)
case EL_HIST:
{
hist_fun_t func = va_arg(ap, hist_fun_t);
ptr_t ptr = va_arg(ap, char *);
void *ptr = va_arg(ap, void *);
rv = hist_set(el, func, ptr);
if (!(el->el_flags & CHARSET_IS_UTF8))
el->el_flags &= ~NARROW_HISTORY;
break;
}
@ -267,6 +307,7 @@ el_set(EditLine *el, int op, ...)
{
el_rfunc_t rc = va_arg(ap, el_rfunc_t);
rv = el_read_setfn(el, rc);
el->el_flags &= ~NARROW_READ;
break;
}
@ -311,9 +352,11 @@ el_set(EditLine *el, int op, ...)
break;
case 1:
el->el_outfile = fp;
el->el_outfd = fileno(fp);
break;
case 2:
el->el_errfile = fp;
el->el_errfd = fileno(fp);
break;
default:
rv = -1;
@ -325,7 +368,7 @@ el_set(EditLine *el, int op, ...)
case EL_REFRESH:
re_clear_display(el);
re_refresh(el);
term__flush(el);
terminal__flush(el);
break;
default:
@ -334,7 +377,7 @@ el_set(EditLine *el, int op, ...)
}
va_end(ap);
return (rv);
return rv;
}
@ -342,7 +385,7 @@ el_set(EditLine *el, int op, ...)
* retrieve the editline parameters
*/
public int
el_get(EditLine *el, int op, ...)
FUN(el,get)(EditLine *el, int op, ...)
{
va_list ap;
int rv;
@ -356,14 +399,20 @@ el_get(EditLine *el, int op, ...)
case EL_PROMPT:
case EL_RPROMPT: {
el_pfunc_t *p = va_arg(ap, el_pfunc_t *);
char *c = va_arg(ap, char *);
rv = prompt_get(el, p, 0, op);
break;
}
case EL_PROMPT_ESC:
case EL_RPROMPT_ESC: {
el_pfunc_t *p = va_arg(ap, el_pfunc_t *);
Char *c = va_arg(ap, Char *);
rv = prompt_get(el, p, c, op);
break;
}
case EL_EDITOR:
rv = map_get_editor(el, va_arg(ap, const char **));
rv = map_get_editor(el, va_arg(ap, const Char **));
break;
case EL_SIGNAL:
@ -377,7 +426,7 @@ el_get(EditLine *el, int op, ...)
break;
case EL_TERMINAL:
term_get(el, va_arg(ap, const char **));
terminal_get(el, va_arg(ap, const char **));
rv = 0;
break;
@ -387,44 +436,15 @@ el_get(EditLine *el, int op, ...)
char *argv[20];
int i;
for (i = 1; i < (int)(sizeof(argv) / sizeof(argv[0])); i++)
for (i = 1; i < (int)__arraycount(argv); i++)
if ((argv[i] = va_arg(ap, char *)) == NULL)
break;
switch (op) {
case EL_GETTC:
argv[0] = name;
rv = term_gettc(el, i, argv);
break;
default:
rv = -1;
EL_ABORT((el->el_errfile, "Bad op %d\n", op));
break;
}
argv[0] = name;
rv = terminal_gettc(el, i, argv);
break;
}
#if 0 /* XXX */
case EL_ADDFN:
{
char *name = va_arg(ap, char *);
char *help = va_arg(ap, char *);
el_func_t func = va_arg(ap, el_func_t);
rv = map_addfunc(el, name, help, func);
break;
}
case EL_HIST:
{
hist_fun_t func = va_arg(ap, hist_fun_t);
ptr_t ptr = va_arg(ap, char *);
rv = hist_set(el, func, ptr);
}
break;
#endif /* XXX */
case EL_GETCFN:
*va_arg(ap, el_rfunc_t *) = el_read_getfn(el);
rv = 0;
@ -436,7 +456,7 @@ el_get(EditLine *el, int op, ...)
break;
case EL_UNBUFFERED:
*va_arg(ap, int *) = (!(el->el_flags & UNBUFFERED));
*va_arg(ap, int *) = (el->el_flags & UNBUFFERED) != 0;
rv = 0;
break;
@ -470,18 +490,18 @@ el_get(EditLine *el, int op, ...)
}
va_end(ap);
return (rv);
return rv;
}
/* el_line():
* Return editing info
*/
public const LineInfo *
el_line(EditLine *el)
public const TYPE(LineInfo) *
FUN(el,line)(EditLine *el)
{
return (const LineInfo *) (void *) &el->el_line;
return (const TYPE(LineInfo) *)(void *)&el->el_line;
}
@ -494,23 +514,24 @@ el_source(EditLine *el, const char *fname)
FILE *fp;
size_t len;
char *ptr;
#ifdef HAVE_ISSETUGID
char path[MAXPATHLEN];
#endif
char *path = NULL;
const Char *dptr;
int error = 0;
fp = NULL;
if (fname == NULL) {
#ifdef HAVE_ISSETUGID
static const char elpath[] = "/.editrc";
size_t plen = sizeof(elpath);
if (issetugid())
return (-1);
return -1;
if ((ptr = getenv("HOME")) == NULL)
return (-1);
if (strlcpy(path, ptr, sizeof(path)) >= sizeof(path))
return (-1);
if (strlcat(path, elpath, sizeof(path)) >= sizeof(path))
return (-1);
return -1;
plen += strlen(ptr);
if ((path = el_malloc(plen * sizeof(*path))) == NULL)
return -1;
(void)snprintf(path, plen, "%s%s", ptr, elpath);
fname = path;
#else
/*
@ -518,33 +539,37 @@ el_source(EditLine *el, const char *fname)
* to keep from inadvertently opening up the user to a security
* hole.
*/
return (-1);
return -1;
#endif
}
if (fp == NULL)
fp = fopen(fname, "r");
if (fp == NULL)
return (-1);
while ((ptr = fgetln(fp, &len)) != NULL) {
if (len > 0 && ptr[len - 1] == '\n')
--len;
ptr[len] = '\0';
/* loop until first non-space char or EOL */
while (*ptr != '\0' && isspace((unsigned char)*ptr))
ptr++;
if (*ptr == '#')
continue; /* ignore, this is a comment line */
if (parse_line(el, ptr) == -1) {
(void) fclose(fp);
return (-1);
}
if (fp == NULL) {
el_free(path);
return -1;
}
while ((ptr = fgetln(fp, &len)) != NULL) {
if (*ptr == '\n')
continue; /* Empty line. */
dptr = ct_decode_string(ptr, &el->el_scratch);
if (!dptr)
continue;
if (len > 0 && dptr[len - 1] == '\n')
--len;
/* loop until first non-space char or EOL */
while (*dptr != '\0' && Isspace(*dptr))
dptr++;
if (*dptr == '#')
continue; /* ignore, this is a comment line */
if ((error = parse_line(el, dptr)) == -1)
break;
}
el_free(path);
(void) fclose(fp);
return (0);
return error;
}
@ -562,8 +587,8 @@ el_resize(EditLine *el)
(void) sigprocmask(SIG_BLOCK, &nset, &oset);
/* get the correct window size */
if (term_get_size(el, &lins, &cols))
term_change_size(el, lins, cols);
if (terminal_get_size(el, &lins, &cols))
terminal_change_size(el, lins, cols);
(void) sigprocmask(SIG_SETMASK, &oset, NULL);
}
@ -576,7 +601,7 @@ public void
el_beep(EditLine *el)
{
term_beep(el);
terminal_beep(el);
}
@ -585,24 +610,25 @@ el_beep(EditLine *el)
*/
protected int
/*ARGSUSED*/
el_editmode(EditLine *el, int argc, const char **argv)
el_editmode(EditLine *el, int argc, const Char **argv)
{
const char *how;
const Char *how;
if (argv == NULL || argc != 2 || argv[1] == NULL)
return (-1);
return -1;
how = argv[1];
if (strcmp(how, "on") == 0) {
if (Strcmp(how, STR("on")) == 0) {
el->el_flags &= ~EDIT_DISABLED;
tty_rawmode(el);
} else if (strcmp(how, "off") == 0) {
} else if (Strcmp(how, STR("off")) == 0) {
tty_cookedmode(el);
el->el_flags |= EDIT_DISABLED;
}
else {
(void) fprintf(el->el_errfile, "edit: Bad value `%s'.\n", how);
return (-1);
(void) fprintf(el->el_errfile, "edit: Bad value `" FSTR "'.\n",
how);
return -1;
}
return (0);
return 0;
}

View File

@ -1,3 +1,5 @@
/* $NetBSD: el.h,v 1.25 2011/07/29 23:44:44 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
@ -30,7 +32,6 @@
* SUCH DAMAGE.
*
* @(#)el.h 8.1 (Berkeley) 6/4/93
* $NetBSD: el.h,v 1.17 2006/12/15 22:13:33 christos Exp $
* $FreeBSD$
*/
@ -46,15 +47,21 @@
#define VIDEFAULT
#define ANCHOR
#include "histedit.h"
#include "chartype.h"
#include <stdio.h>
#include <sys/types.h>
#define EL_BUFSIZ 1024 /* Maximum line size */
#define EL_BUFSIZ ((size_t)1024) /* Maximum line size */
#define HANDLE_SIGNALS 0x01
#define NO_TTY 0x02
#define EDIT_DISABLED 0x04
#define UNBUFFERED 0x08
#define CHARSET_IS_UTF8 0x10
#define IGNORE_EXTCHARS 0x20 /* Ignore characters read > 0xff */
#define NARROW_HISTORY 0x40
#define NARROW_READ 0x80
typedef int bool_t; /* True or not */
@ -66,10 +73,10 @@ typedef struct coord_t { /* Position on the screen */
} coord_t;
typedef struct el_line_t {
char *buffer; /* Input line */
char *cursor; /* Cursor position */
char *lastchar; /* Last character */
const char *limit; /* Max position */
Char *buffer; /* Input line */
Char *cursor; /* Cursor position */
Char *lastchar; /* Last character */
const Char *limit; /* Max position */
} el_line_t;
/*
@ -82,21 +89,20 @@ typedef struct el_state_t {
int metanext; /* Is the next char a meta char */
el_action_t lastcmd; /* Previous command */
el_action_t thiscmd; /* this command */
char thisch; /* char that generated it */
Char thisch; /* char that generated it */
} el_state_t;
/*
* Until we come up with something better...
*/
#define el_strdup(a) strdup(a)
#define el_malloc(a) malloc(a)
#define el_realloc(a,b) realloc(a, b)
#define el_free(a) free(a)
#include "tty.h"
#include "prompt.h"
#include "key.h"
#include "term.h"
#include "keymacro.h"
#include "terminal.h"
#include "refresh.h"
#include "chared.h"
#include "common.h"
@ -109,34 +115,41 @@ typedef struct el_state_t {
#include "read.h"
struct editline {
char *el_prog; /* the program name */
Char *el_prog; /* the program name */
FILE *el_infile; /* Stdio stuff */
FILE *el_outfile; /* Stdio stuff */
FILE *el_errfile; /* Stdio stuff */
int el_infd; /* Input file descriptor */
int el_outfd; /* Output file descriptor */
int el_errfd; /* Error file descriptor */
int el_flags; /* Various flags. */
int el_errno; /* Local copy of errno */
coord_t el_cursor; /* Cursor location */
char **el_display; /* Real screen image = what is there */
char **el_vdisplay; /* Virtual screen image = what we see */
Char **el_display; /* Real screen image = what is there */
Char **el_vdisplay; /* Virtual screen image = what we see */
void *el_data; /* Client data */
el_line_t el_line; /* The current line information */
el_state_t el_state; /* Current editor state */
el_term_t el_term; /* Terminal dependent stuff */
el_terminal_t el_terminal; /* Terminal dependent stuff */
el_tty_t el_tty; /* Tty dependent stuff */
el_refresh_t el_refresh; /* Refresh stuff */
el_prompt_t el_prompt; /* Prompt stuff */
el_prompt_t el_rprompt; /* Prompt stuff */
el_chared_t el_chared; /* Characted editor stuff */
el_map_t el_map; /* Key mapping stuff */
el_key_t el_key; /* Key binding stuff */
el_keymacro_t el_keymacro; /* Key binding stuff */
el_history_t el_history; /* History stuff */
el_search_t el_search; /* Search stuff */
el_signal_t el_signal; /* Signal handling stuff */
el_read_t el_read; /* Character reading stuff */
#ifdef WIDECHAR
ct_buffer_t el_scratch; /* Scratch conversion buffer */
ct_buffer_t el_lgcyconv; /* Buffer for legacy wrappers */
LineInfo el_lgcylinfo; /* Legacy LineInfo buffer */
#endif
};
protected int el_editmode(EditLine *, int, const char **);
protected int el_editmode(EditLine *, int, const Char **);
#ifdef DEBUG
#define EL_ABORT(a) do { \

402
lib/libedit/eln.c Normal file
View File

@ -0,0 +1,402 @@
/* $NetBSD: eln.c,v 1.17 2014/06/18 18:12:28 christos Exp $ */
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#if !defined(lint) && !defined(SCCSID)
__RCSID("$NetBSD: eln.c,v 1.17 2014/06/18 18:12:28 christos Exp $");
#endif /* not lint && not SCCSID */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "histedit.h"
#include "el.h"
#include "read.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
public int
el_getc(EditLine *el, char *cp)
{
int num_read;
wchar_t wc = 0;
if (!(el->el_flags & CHARSET_IS_UTF8))
el->el_flags |= IGNORE_EXTCHARS;
num_read = el_wgetc (el, &wc);
if (!(el->el_flags & CHARSET_IS_UTF8))
el->el_flags &= ~IGNORE_EXTCHARS;
if (num_read > 0)
*cp = (char)wc;
return num_read;
}
public void
el_push(EditLine *el, const char *str)
{
/* Using multibyte->wide string decoding works fine under single-byte
* character sets too, and Does The Right Thing. */
el_wpush(el, ct_decode_string(str, &el->el_lgcyconv));
}
public const char *
el_gets(EditLine *el, int *nread)
{
const wchar_t *tmp;
const char *ret;
int nwread;
*nread = 0;
if (!(el->el_flags & CHARSET_IS_UTF8))
el->el_flags |= IGNORE_EXTCHARS;
tmp = el_wgets(el, &nwread);
if (!(el->el_flags & CHARSET_IS_UTF8))
el->el_flags &= ~IGNORE_EXTCHARS;
for (int i = 0; i < nwread; i++)
*nread += ct_enc_width(tmp[i]);
return ct_encode_string(tmp, &el->el_lgcyconv);
}
public int
el_parse(EditLine *el, int argc, const char *argv[])
{
int ret;
const wchar_t **wargv;
wargv = (const wchar_t **)
ct_decode_argv(argc, argv, &el->el_lgcyconv);
if (!wargv)
return -1;
ret = el_wparse(el, argc, wargv);
ct_free_argv(wargv);
return ret;
}
public int
el_set(EditLine *el, int op, ...)
{
va_list ap;
int ret;
if (!el)
return -1;
va_start(ap, op);
switch (op) {
case EL_PROMPT: /* el_pfunc_t */
case EL_RPROMPT: {
el_pfunc_t p = va_arg(ap, el_pfunc_t);
ret = prompt_set(el, p, 0, op, 0);
break;
}
case EL_RESIZE: {
el_zfunc_t p = va_arg(ap, el_zfunc_t);
void *arg = va_arg(ap, void *);
ret = ch_resizefun(el, p, arg);
break;
}
case EL_ALIAS_TEXT: {
el_afunc_t p = va_arg(ap, el_afunc_t);
void *arg = va_arg(ap, void *);
ret = ch_aliasfun(el, p, arg);
break;
}
case EL_PROMPT_ESC:
case EL_RPROMPT_ESC: {
el_pfunc_t p = va_arg(ap, el_pfunc_t);
int c = va_arg(ap, int);
ret = prompt_set(el, p, c, op, 0);
break;
}
case EL_TERMINAL: /* const char * */
ret = el_wset(el, op, va_arg(ap, char *));
break;
case EL_EDITOR: /* const wchar_t * */
ret = el_wset(el, op, ct_decode_string(va_arg(ap, char *),
&el->el_lgcyconv));
break;
case EL_SIGNAL: /* int */
case EL_EDITMODE:
case EL_UNBUFFERED:
case EL_PREP_TERM:
ret = el_wset(el, op, va_arg(ap, int));
break;
case EL_BIND: /* const char * list -> const wchar_t * list */
case EL_TELLTC:
case EL_SETTC:
case EL_ECHOTC:
case EL_SETTY: {
const char *argv[20];
int i;
const wchar_t **wargv;
for (i = 1; i < (int)__arraycount(argv) - 1; ++i)
if ((argv[i] = va_arg(ap, const char *)) == NULL)
break;
argv[0] = argv[i] = NULL;
wargv = (const wchar_t **)
ct_decode_argv(i + 1, argv, &el->el_lgcyconv);
if (!wargv) {
ret = -1;
goto out;
}
/*
* AFAIK we can't portably pass through our new wargv to
* el_wset(), so we have to reimplement the body of
* el_wset() for these ops.
*/
switch (op) {
case EL_BIND:
wargv[0] = STR("bind");
ret = map_bind(el, i, wargv);
break;
case EL_TELLTC:
wargv[0] = STR("telltc");
ret = terminal_telltc(el, i, wargv);
break;
case EL_SETTC:
wargv[0] = STR("settc");
ret = terminal_settc(el, i, wargv);
break;
case EL_ECHOTC:
wargv[0] = STR("echotc");
ret = terminal_echotc(el, i, wargv);
break;
case EL_SETTY:
wargv[0] = STR("setty");
ret = tty_stty(el, i, wargv);
break;
default:
ret = -1;
}
ct_free_argv(wargv);
break;
}
/* XXX: do we need to change el_func_t too? */
case EL_ADDFN: { /* const char *, const char *, el_func_t */
const char *args[2];
el_func_t func;
wchar_t **wargv;
args[0] = va_arg(ap, const char *);
args[1] = va_arg(ap, const char *);
func = va_arg(ap, el_func_t);
wargv = ct_decode_argv(2, args, &el->el_lgcyconv);
if (!wargv) {
ret = -1;
goto out;
}
// XXX: The two strdup's leak
ret = map_addfunc(el, Strdup(wargv[0]), Strdup(wargv[1]),
func);
ct_free_argv(wargv);
break;
}
case EL_HIST: { /* hist_fun_t, const char * */
hist_fun_t fun = va_arg(ap, hist_fun_t);
void *ptr = va_arg(ap, void *);
ret = hist_set(el, fun, ptr);
el->el_flags |= NARROW_HISTORY;
break;
}
/* XXX: do we need to change el_rfunc_t? */
case EL_GETCFN: /* el_rfunc_t */
ret = el_wset(el, op, va_arg(ap, el_rfunc_t));
el->el_flags |= NARROW_READ;
break;
case EL_CLIENTDATA: /* void * */
ret = el_wset(el, op, va_arg(ap, void *));
break;
case EL_SETFP: { /* int, FILE * */
int what = va_arg(ap, int);
FILE *fp = va_arg(ap, FILE *);
ret = el_wset(el, op, what, fp);
break;
}
case EL_REFRESH:
re_clear_display(el);
re_refresh(el);
terminal__flush(el);
ret = 0;
break;
default:
ret = -1;
break;
}
out:
va_end(ap);
return ret;
}
public int
el_get(EditLine *el, int op, ...)
{
va_list ap;
int ret;
if (!el)
return -1;
va_start(ap, op);
switch (op) {
case EL_PROMPT: /* el_pfunc_t * */
case EL_RPROMPT: {
el_pfunc_t *p = va_arg(ap, el_pfunc_t *);
ret = prompt_get(el, p, 0, op);
break;
}
case EL_PROMPT_ESC: /* el_pfunc_t *, char **/
case EL_RPROMPT_ESC: {
el_pfunc_t *p = va_arg(ap, el_pfunc_t *);
char *c = va_arg(ap, char *);
wchar_t wc = 0;
ret = prompt_get(el, p, &wc, op);
*c = (char)wc;
break;
}
case EL_EDITOR: {
const char **p = va_arg(ap, const char **);
const wchar_t *pw;
ret = el_wget(el, op, &pw);
*p = ct_encode_string(pw, &el->el_lgcyconv);
if (!el->el_lgcyconv.csize)
ret = -1;
break;
}
case EL_TERMINAL: /* const char ** */
ret = el_wget(el, op, va_arg(ap, const char **));
break;
case EL_SIGNAL: /* int * */
case EL_EDITMODE:
case EL_UNBUFFERED:
case EL_PREP_TERM:
ret = el_wget(el, op, va_arg(ap, int *));
break;
case EL_GETTC: {
char *argv[20];
static char gettc[] = "gettc";
int i;
for (i = 1; i < (int)__arraycount(argv); ++i)
if ((argv[i] = va_arg(ap, char *)) == NULL)
break;
argv[0] = gettc;
ret = terminal_gettc(el, i, argv);
break;
}
/* XXX: do we need to change el_rfunc_t? */
case EL_GETCFN: /* el_rfunc_t */
ret = el_wget(el, op, va_arg(ap, el_rfunc_t *));
break;
case EL_CLIENTDATA: /* void ** */
ret = el_wget(el, op, va_arg(ap, void **));
break;
case EL_GETFP: { /* int, FILE ** */
int what = va_arg(ap, int);
FILE **fpp = va_arg(ap, FILE **);
ret = el_wget(el, op, what, fpp);
break;
}
default:
ret = -1;
break;
}
va_end(ap);
return ret;
}
const LineInfo *
el_line(EditLine *el)
{
const LineInfoW *winfo = el_wline(el);
LineInfo *info = &el->el_lgcylinfo;
size_t offset;
const Char *p;
info->buffer = ct_encode_string(winfo->buffer, &el->el_lgcyconv);
offset = 0;
for (p = winfo->buffer; p < winfo->cursor; p++)
offset += ct_enc_width(*p);
info->cursor = info->buffer + offset;
offset = 0;
for (p = winfo->buffer; p < winfo->lastchar; p++)
offset += ct_enc_width(*p);
info->lastchar = info->buffer + offset;
return info;
}
int
el_insertstr(EditLine *el, const char *str)
{
return el_winsertstr(el, ct_decode_string(str, &el->el_lgcyconv));
}

View File

@ -1,3 +1,5 @@
/* $NetBSD: emacs.c,v 1.25 2011/07/29 15:16:33 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
@ -28,12 +30,15 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $NetBSD: emacs.c,v 1.22 2009/02/15 21:55:23 christos Exp $
*/
#include "config.h"
#if !defined(lint) && !defined(SCCSID)
#if 0
static char sccsid[] = "@(#)emacs.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: emacs.c,v 1.25 2011/07/29 15:16:33 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@ -41,7 +46,6 @@ __FBSDID("$FreeBSD$");
/*
* emacs.c: Emacs functions
*/
#include "sys.h"
#include "el.h"
/* em_delete_or_list():
@ -50,22 +54,22 @@ __FBSDID("$FreeBSD$");
*/
protected el_action_t
/*ARGSUSED*/
em_delete_or_list(EditLine *el, int c)
em_delete_or_list(EditLine *el, Int c)
{
if (el->el_line.cursor == el->el_line.lastchar) {
/* if I'm at the end */
if (el->el_line.cursor == el->el_line.buffer) {
/* and the beginning */
term_writec(el, c); /* then do an EOF */
return (CC_EOF);
terminal_writec(el, c); /* then do an EOF */
return CC_EOF;
} else {
/*
* Here we could list completions, but it is an
* error right now
*/
term_beep(el);
return (CC_ERROR);
terminal_beep(el);
return CC_ERROR;
}
} else {
if (el->el_state.doingarg)
@ -75,7 +79,7 @@ em_delete_or_list(EditLine *el, int c)
if (el->el_line.cursor > el->el_line.lastchar)
el->el_line.cursor = el->el_line.lastchar;
/* bounds check */
return (CC_REFRESH);
return CC_REFRESH;
}
}
@ -86,12 +90,12 @@ em_delete_or_list(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
em_delete_next_word(EditLine *el, int c __unused)
em_delete_next_word(EditLine *el, Int c __attribute__((__unused__)))
{
char *cp, *p, *kp;
Char *cp, *p, *kp;
if (el->el_line.cursor == el->el_line.lastchar)
return (CC_ERROR);
return CC_ERROR;
cp = c__next_word(el->el_line.cursor, el->el_line.lastchar,
el->el_state.argument, ce__isword);
@ -105,7 +109,7 @@ em_delete_next_word(EditLine *el, int c __unused)
if (el->el_line.cursor > el->el_line.lastchar)
el->el_line.cursor = el->el_line.lastchar;
/* bounds check */
return (CC_REFRESH);
return CC_REFRESH;
}
@ -115,17 +119,17 @@ em_delete_next_word(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
em_yank(EditLine *el, int c __unused)
em_yank(EditLine *el, Int c __attribute__((__unused__)))
{
char *kp, *cp;
Char *kp, *cp;
if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf)
return (CC_NORM);
return CC_NORM;
if (el->el_line.lastchar +
(el->el_chared.c_kill.last - el->el_chared.c_kill.buf) >=
el->el_line.limit)
return (CC_ERROR);
return CC_ERROR;
el->el_chared.c_kill.mark = el->el_line.cursor;
cp = el->el_line.cursor;
@ -141,7 +145,7 @@ em_yank(EditLine *el, int c __unused)
if (el->el_state.argument == 1)
el->el_line.cursor = cp;
return (CC_REFRESH);
return CC_REFRESH;
}
@ -151,9 +155,9 @@ em_yank(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
em_kill_line(EditLine *el, int c __unused)
em_kill_line(EditLine *el, Int c __attribute__((__unused__)))
{
char *kp, *cp;
Char *kp, *cp;
cp = el->el_line.buffer;
kp = el->el_chared.c_kill.buf;
@ -163,7 +167,7 @@ em_kill_line(EditLine *el, int c __unused)
/* zap! -- delete all of it */
el->el_line.lastchar = el->el_line.buffer;
el->el_line.cursor = el->el_line.buffer;
return (CC_REFRESH);
return CC_REFRESH;
}
@ -173,12 +177,12 @@ em_kill_line(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
em_kill_region(EditLine *el, int c __unused)
em_kill_region(EditLine *el, Int c __attribute__((__unused__)))
{
char *kp, *cp;
Char *kp, *cp;
if (!el->el_chared.c_kill.mark)
return (CC_ERROR);
return CC_ERROR;
if (el->el_chared.c_kill.mark > el->el_line.cursor) {
cp = el->el_line.cursor;
@ -196,7 +200,7 @@ em_kill_region(EditLine *el, int c __unused)
c_delbefore(el, (int)(cp - el->el_chared.c_kill.mark));
el->el_line.cursor = el->el_chared.c_kill.mark;
}
return (CC_REFRESH);
return CC_REFRESH;
}
@ -206,12 +210,12 @@ em_kill_region(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
em_copy_region(EditLine *el, int c __unused)
em_copy_region(EditLine *el, Int c __attribute__((__unused__)))
{
char *kp, *cp;
Char *kp, *cp;
if (!el->el_chared.c_kill.mark)
return (CC_ERROR);
return CC_ERROR;
if (el->el_chared.c_kill.mark > el->el_line.cursor) {
cp = el->el_line.cursor;
@ -226,7 +230,7 @@ em_copy_region(EditLine *el, int c __unused)
*kp++ = *cp++; /* copy it */
el->el_chared.c_kill.last = kp;
}
return (CC_NORM);
return CC_NORM;
}
@ -235,7 +239,7 @@ em_copy_region(EditLine *el, int c __unused)
* Gosling emacs transpose chars [^T]
*/
protected el_action_t
em_gosmacs_transpose(EditLine *el, int c)
em_gosmacs_transpose(EditLine *el, Int c)
{
if (el->el_line.cursor > &el->el_line.buffer[1]) {
@ -243,9 +247,9 @@ em_gosmacs_transpose(EditLine *el, int c)
c = el->el_line.cursor[-2];
el->el_line.cursor[-2] = el->el_line.cursor[-1];
el->el_line.cursor[-1] = c;
return (CC_REFRESH);
return CC_REFRESH;
} else
return (CC_ERROR);
return CC_ERROR;
}
@ -255,10 +259,10 @@ em_gosmacs_transpose(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
em_next_word(EditLine *el, int c __unused)
em_next_word(EditLine *el, Int c __attribute__((__unused__)))
{
if (el->el_line.cursor == el->el_line.lastchar)
return (CC_ERROR);
return CC_ERROR;
el->el_line.cursor = c__next_word(el->el_line.cursor,
el->el_line.lastchar,
@ -268,9 +272,9 @@ em_next_word(EditLine *el, int c __unused)
if (el->el_map.type == MAP_VI)
if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el);
return (CC_REFRESH);
return CC_REFRESH;
}
return (CC_CURSOR);
return CC_CURSOR;
}
@ -280,21 +284,21 @@ em_next_word(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
em_upper_case(EditLine *el, int c __unused)
em_upper_case(EditLine *el, Int c __attribute__((__unused__)))
{
char *cp, *ep;
Char *cp, *ep;
ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
el->el_state.argument, ce__isword);
for (cp = el->el_line.cursor; cp < ep; cp++)
if (islower((unsigned char)*cp))
*cp = toupper((unsigned char)*cp);
if (Islower(*cp))
*cp = Toupper(*cp);
el->el_line.cursor = ep;
if (el->el_line.cursor > el->el_line.lastchar)
el->el_line.cursor = el->el_line.lastchar;
return (CC_REFRESH);
return CC_REFRESH;
}
@ -304,29 +308,29 @@ em_upper_case(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
em_capitol_case(EditLine *el, int c __unused)
em_capitol_case(EditLine *el, Int c __attribute__((__unused__)))
{
char *cp, *ep;
Char *cp, *ep;
ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
el->el_state.argument, ce__isword);
for (cp = el->el_line.cursor; cp < ep; cp++) {
if (isalpha((unsigned char)*cp)) {
if (islower((unsigned char)*cp))
*cp = toupper((unsigned char)*cp);
if (Isalpha(*cp)) {
if (Islower(*cp))
*cp = Toupper(*cp);
cp++;
break;
}
}
for (; cp < ep; cp++)
if (isupper((unsigned char)*cp))
*cp = tolower((unsigned char)*cp);
if (Isupper(*cp))
*cp = Tolower(*cp);
el->el_line.cursor = ep;
if (el->el_line.cursor > el->el_line.lastchar)
el->el_line.cursor = el->el_line.lastchar;
return (CC_REFRESH);
return CC_REFRESH;
}
@ -336,21 +340,21 @@ em_capitol_case(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
em_lower_case(EditLine *el, int c __unused)
em_lower_case(EditLine *el, Int c __attribute__((__unused__)))
{
char *cp, *ep;
Char *cp, *ep;
ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
el->el_state.argument, ce__isword);
for (cp = el->el_line.cursor; cp < ep; cp++)
if (isupper((unsigned char)*cp))
*cp = tolower((unsigned char)*cp);
if (Isupper(*cp))
*cp = Tolower(*cp);
el->el_line.cursor = ep;
if (el->el_line.cursor > el->el_line.lastchar)
el->el_line.cursor = el->el_line.lastchar;
return (CC_REFRESH);
return CC_REFRESH;
}
@ -360,11 +364,11 @@ em_lower_case(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
em_set_mark(EditLine *el, int c __unused)
em_set_mark(EditLine *el, Int c __attribute__((__unused__)))
{
el->el_chared.c_kill.mark = el->el_line.cursor;
return (CC_NORM);
return CC_NORM;
}
@ -374,14 +378,14 @@ em_set_mark(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
em_exchange_mark(EditLine *el, int c __unused)
em_exchange_mark(EditLine *el, Int c __attribute__((__unused__)))
{
char *cp;
Char *cp;
cp = el->el_line.cursor;
el->el_line.cursor = el->el_chared.c_kill.mark;
el->el_chared.c_kill.mark = cp;
return (CC_CURSOR);
return CC_CURSOR;
}
@ -391,14 +395,14 @@ em_exchange_mark(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
em_universal_argument(EditLine *el, int c __unused)
em_universal_argument(EditLine *el, Int c __attribute__((__unused__)))
{ /* multiply current argument by 4 */
if (el->el_state.argument > 1000000)
return (CC_ERROR);
return CC_ERROR;
el->el_state.doingarg = 1;
el->el_state.argument *= 4;
return (CC_ARGHACK);
return CC_ARGHACK;
}
@ -408,11 +412,11 @@ em_universal_argument(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
em_meta_next(EditLine *el, int c __unused)
em_meta_next(EditLine *el, Int c __attribute__((__unused__)))
{
el->el_state.metanext = 1;
return (CC_ARGHACK);
return CC_ARGHACK;
}
@ -421,12 +425,12 @@ em_meta_next(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
em_toggle_overwrite(EditLine *el, int c __unused)
em_toggle_overwrite(EditLine *el, Int c __attribute__((__unused__)))
{
el->el_state.inputmode = (el->el_state.inputmode == MODE_INSERT) ?
MODE_REPLACE : MODE_INSERT;
return (CC_NORM);
return CC_NORM;
}
@ -435,12 +439,12 @@ em_toggle_overwrite(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
em_copy_prev_word(EditLine *el, int c __unused)
em_copy_prev_word(EditLine *el, Int c __attribute__((__unused__)))
{
char *cp, *oldc, *dp;
Char *cp, *oldc, *dp;
if (el->el_line.cursor == el->el_line.buffer)
return (CC_ERROR);
return CC_ERROR;
oldc = el->el_line.cursor;
/* does a bounds check */
@ -453,7 +457,7 @@ em_copy_prev_word(EditLine *el, int c __unused)
el->el_line.cursor = dp;/* put cursor at end */
return (CC_REFRESH);
return CC_REFRESH;
}
@ -462,11 +466,11 @@ em_copy_prev_word(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
em_inc_search_next(EditLine *el, int c __unused)
em_inc_search_next(EditLine *el, Int c __attribute__((__unused__)))
{
el->el_search.patlen = 0;
return (ce_inc_search(el, ED_SEARCH_NEXT_HISTORY));
return ce_inc_search(el, ED_SEARCH_NEXT_HISTORY);
}
@ -475,11 +479,11 @@ em_inc_search_next(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
em_inc_search_prev(EditLine *el, int c __unused)
em_inc_search_prev(EditLine *el, Int c __attribute__((__unused__)))
{
el->el_search.patlen = 0;
return (ce_inc_search(el, ED_SEARCH_PREV_HISTORY));
return ce_inc_search(el, ED_SEARCH_PREV_HISTORY);
}
@ -489,11 +493,11 @@ em_inc_search_prev(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
em_delete_prev_char(EditLine *el, int c __unused)
em_delete_prev_char(EditLine *el, Int c __attribute__((__unused__)))
{
if (el->el_line.cursor <= el->el_line.buffer)
return (CC_ERROR);
return CC_ERROR;
if (el->el_state.doingarg)
c_delbefore(el, el->el_state.argument);
@ -502,5 +506,5 @@ em_delete_prev_char(EditLine *el, int c __unused)
el->el_line.cursor -= el->el_state.argument;
if (el->el_line.cursor < el->el_line.buffer)
el->el_line.cursor = el->el_line.buffer;
return (CC_REFRESH);
return CC_REFRESH;
}

View File

@ -1,3 +1,5 @@
/* $NetBSD: filecomplete.c,v 1.34 2014/10/18 15:07:02 riz Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
* All rights reserved.
@ -25,10 +27,12 @@
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* $NetBSD: filecomplete.c,v 1.19 2010/06/01 18:20:26 christos Exp $
*/
#include "config.h"
#if !defined(lint) && !defined(SCCSID)
__RCSID("$NetBSD: filecomplete.c,v 1.34 2014/10/18 15:07:02 riz Exp $");
#endif /* not lint && not SCCSID */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@ -44,16 +48,16 @@ __FBSDID("$FreeBSD$");
#include <limits.h>
#include <errno.h>
#include <fcntl.h>
#include <vis.h>
#include "el.h"
#include "fcns.h" /* for EL_NUM_FCNS */
#include "histedit.h"
#include "filecomplete.h"
static char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`',
'>', '<', '=', ';', '|', '&', '{', '(', '\0' };
static const Char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@',
'$', '>', '<', '=', ';', '|', '&', '{', '(', '\0' };
/* Tilde is deliberately omitted here, we treat it specially. */
static char extra_quote_chars[] = { ')', '}', '*', '?', '[', '$', '\0' };
static const Char extra_quote_chars[] = { ')', '}', '*', '?', '[', '$', '\0' };
/********************************/
@ -64,18 +68,21 @@ static char extra_quote_chars[] = { ')', '}', '*', '?', '[', '$', '\0' };
* if ``user'' isn't valid user name or ``txt'' doesn't start
* w/ '~', returns pointer to strdup()ed copy of ``txt''
*
* it's callers's responsibility to free() returned string
* it's the caller's responsibility to free() the returned string
*/
char *
fn_tilde_expand(const char *txt)
{
struct passwd pwres, *pass;
#if defined(HAVE_GETPW_R_POSIX) || defined(HAVE_GETPW_R_DRAFT)
struct passwd pwres;
char pwbuf[1024];
#endif
struct passwd *pass;
char *temp;
size_t len = 0;
char pwbuf[1024];
if (txt[0] != '~')
return (strdup(txt));
return strdup(txt);
temp = strchr(txt + 1, '/');
if (temp == NULL) {
@ -83,34 +90,49 @@ fn_tilde_expand(const char *txt)
if (temp == NULL)
return NULL;
} else {
len = temp - txt + 1; /* text until string after slash */
temp = malloc(len);
/* text until string after slash */
len = (size_t)(temp - txt + 1);
temp = el_malloc(len * sizeof(*temp));
if (temp == NULL)
return NULL;
(void)strncpy(temp, txt + 1, len - 2);
temp[len - 2] = '\0';
}
if (temp[0] == 0) {
if (getpwuid_r(getuid(), &pwres, pwbuf, sizeof(pwbuf), &pass) != 0)
pass = NULL;
#ifdef HAVE_GETPW_R_POSIX
if (getpwuid_r(getuid(), &pwres, pwbuf, sizeof(pwbuf),
&pass) != 0)
pass = NULL;
#elif HAVE_GETPW_R_DRAFT
pass = getpwuid_r(getuid(), &pwres, pwbuf, sizeof(pwbuf));
#else
pass = getpwuid(getuid());
#endif
} else {
#ifdef HAVE_GETPW_R_POSIX
if (getpwnam_r(temp, &pwres, pwbuf, sizeof(pwbuf), &pass) != 0)
pass = NULL;
#elif HAVE_GETPW_R_DRAFT
pass = getpwnam_r(temp, &pwres, pwbuf, sizeof(pwbuf));
#else
pass = getpwnam(temp);
#endif
}
free(temp); /* value no more needed */
el_free(temp); /* value no more needed */
if (pass == NULL)
return (strdup(txt));
return strdup(txt);
/* update pointer txt to point at string immediately following */
/* update pointer txt to point at string immedially following */
/* first slash */
txt += len;
temp = malloc(strlen(pass->pw_dir) + 1 + strlen(txt) + 1);
len = strlen(pass->pw_dir) + 1 + strlen(txt) + 1;
temp = el_malloc(len * sizeof(*temp));
if (temp == NULL)
return NULL;
(void)sprintf(temp, "%s/%s", pass->pw_dir, txt);
(void)snprintf(temp, len, "%s/%s", pass->pw_dir, txt);
return (temp);
return temp;
}
@ -119,7 +141,7 @@ fn_tilde_expand(const char *txt)
* such file can be found
* value of ``state'' is ignored
*
* it's caller's responsibility to free returned string
* it's the caller's responsibility to free the returned string
*/
char *
fn_filename_completion_function(const char *text, int state)
@ -136,19 +158,21 @@ fn_filename_completion_function(const char *text, int state)
if (temp) {
char *nptr;
temp++;
nptr = realloc(filename, strlen(temp) + 1);
nptr = el_realloc(filename, (strlen(temp) + 1) *
sizeof(*nptr));
if (nptr == NULL) {
free(filename);
el_free(filename);
filename = NULL;
return NULL;
}
filename = nptr;
(void)strcpy(filename, temp);
len = temp - text; /* including last slash */
len = (size_t)(temp - text); /* including last slash */
nptr = realloc(dirname, len + 1);
nptr = el_realloc(dirname, (len + 1) *
sizeof(*nptr));
if (nptr == NULL) {
free(dirname);
el_free(dirname);
dirname = NULL;
return NULL;
}
@ -156,7 +180,7 @@ fn_filename_completion_function(const char *text, int state)
(void)strncpy(dirname, text, len);
dirname[len] = '\0';
} else {
free(filename);
el_free(filename);
if (*text == 0)
filename = NULL;
else {
@ -164,7 +188,7 @@ fn_filename_completion_function(const char *text, int state)
if (filename == NULL)
return NULL;
}
free(dirname);
el_free(dirname);
dirname = NULL;
}
@ -175,7 +199,7 @@ fn_filename_completion_function(const char *text, int state)
/* support for ``~user'' syntax */
free(dirpath);
el_free(dirpath);
dirpath = NULL;
if (dirname == NULL) {
if ((dirname = strdup("")) == NULL)
@ -191,7 +215,7 @@ fn_filename_completion_function(const char *text, int state)
dir = opendir(dirpath);
if (!dir)
return (NULL); /* cannot open the directory */
return NULL; /* cannot open the directory */
/* will be used in cycle */
filename_len = filename ? strlen(filename) : 0;
@ -208,26 +232,36 @@ fn_filename_completion_function(const char *text, int state)
/* otherwise, get first entry where first */
/* filename_len characters are equal */
if (entry->d_name[0] == filename[0]
#if HAVE_STRUCT_DIRENT_D_NAMLEN
&& entry->d_namlen >= filename_len
#else
&& strlen(entry->d_name) >= filename_len
#endif
&& strncmp(entry->d_name, filename,
filename_len) == 0)
break;
}
if (entry) { /* match found */
len = entry->d_namlen;
temp = malloc(strlen(dirname) + len + 1);
#if HAVE_STRUCT_DIRENT_D_NAMLEN
len = entry->d_namlen;
#else
len = strlen(entry->d_name);
#endif
len = strlen(dirname) + len + 1;
temp = el_malloc(len * sizeof(*temp));
if (temp == NULL)
return NULL;
(void)sprintf(temp, "%s%s", dirname, entry->d_name);
(void)snprintf(temp, len, "%s%s", dirname, entry->d_name);
} else {
(void)closedir(dir);
dir = NULL;
temp = NULL;
}
return (temp);
return temp;
}
@ -244,11 +278,9 @@ append_char_function(const char *name)
rs = "/";
out:
if (expname)
free(expname);
el_free(expname);
return rs;
}
/*
* returns list of completions for text given
* non-static for readline.
@ -269,10 +301,10 @@ completion_matches(const char *text, char *(*genfunc)(const char *, int))
char **nmatch_list;
while (matches + 3 >= match_list_len)
match_list_len <<= 1;
nmatch_list = realloc(match_list,
match_list_len * sizeof(char *));
nmatch_list = el_realloc(match_list,
match_list_len * sizeof(*nmatch_list));
if (nmatch_list == NULL) {
free(match_list);
el_free(match_list);
return NULL;
}
match_list = nmatch_list;
@ -295,9 +327,9 @@ completion_matches(const char *text, char *(*genfunc)(const char *, int))
max_equal = i;
}
retstr = malloc(max_equal + 1);
retstr = el_malloc((max_equal + 1) * sizeof(*retstr));
if (retstr == NULL) {
free(match_list);
el_free(match_list);
return NULL;
}
(void)strncpy(retstr, match_list[1], max_equal);
@ -305,12 +337,11 @@ completion_matches(const char *text, char *(*genfunc)(const char *, int))
match_list[0] = retstr;
/* add NULL as last pointer to the array */
match_list[matches + 1] = (char *) NULL;
match_list[matches + 1] = NULL;
return (match_list);
return match_list;
}
/*
* Sort function for qsort(). Just wrapper around strcasecmp().
*/
@ -323,47 +354,53 @@ _fn_qsort_string_compare(const void *i1, const void *i2)
return strcasecmp(s1, s2);
}
/*
* Display list of strings in columnar format on readline's output stream.
* 'matches' is list of strings, 'len' is number of strings in 'matches',
* 'max' is maximum length of string in 'matches'.
* 'matches' is list of strings, 'num' is number of strings in 'matches',
* 'width' is maximum length of string in 'matches'.
*
* matches[0] is not one of the match strings, but it is counted in
* num, so the strings are matches[1] *through* matches[num-1].
*/
void
fn_display_match_list(EditLine *el, char **matches, size_t len, size_t max)
fn_display_match_list (EditLine *el, char **matches, size_t num, size_t width)
{
size_t i, idx, limit, count;
int screenwidth = el->el_term.t_size.h;
size_t line, lines, col, cols, thisguy;
int screenwidth = el->el_terminal.t_size.h;
/* Ignore matches[0]. Avoid 1-based array logic below. */
matches++;
num--;
/*
* Find out how many entries can be put on one line, count
* with two spaces between strings.
* Find out how many entries can be put on one line; count
* with one space between strings the same way it's printed.
*/
limit = screenwidth / (max + 2);
if (limit == 0)
limit = 1;
cols = (size_t)screenwidth / (width + 1);
if (cols == 0)
cols = 1;
/* how many lines of output */
count = len / limit;
if (count * limit < len)
count++;
/* how many lines of output, rounded up */
lines = (num + cols - 1) / cols;
/* Sort the items if they are not already sorted. */
qsort(&matches[1], len, sizeof(char *), _fn_qsort_string_compare);
/* Sort the items. */
qsort(matches, num, sizeof(char *), _fn_qsort_string_compare);
idx = 1;
for(; count > 0; count--) {
int more = limit > 0 && matches[0];
for(i = 0; more; idx++) {
more = ++i < limit && matches[idx + 1];
(void)fprintf(el->el_outfile, "%-*s%s", (int)max,
matches[idx], more ? " " : "");
/*
* On the ith line print elements i, i+lines, i+lines*2, etc.
*/
for (line = 0; line < lines; line++) {
for (col = 0; col < cols; col++) {
thisguy = line + col * lines;
if (thisguy >= num)
break;
(void)fprintf(el->el_outfile, "%s%-*s",
col == 0 ? "" : " ", (int)width, matches[thisguy]);
}
(void)fprintf(el->el_outfile, "\n");
}
}
/*
* Complete the word at or before point,
* 'what_to_do' says what to do with the completion.
@ -380,18 +417,18 @@ int
fn_complete(EditLine *el,
char *(*complet_func)(const char *, int),
char **(*attempted_completion_function)(const char *, int, int),
const char *word_break, const char *special_prefixes,
const Char *word_break, const Char *special_prefixes,
const char *(*app_func)(const char *), size_t query_items,
int *completion_type, int *over, int *point, int *end,
const char *(*find_word_start_func)(const char *, const char *),
char *(*dequoting_func)(const char *),
const Char *(*find_word_start_func)(const Char *, const Char *),
Char *(*dequoting_func)(const Char *),
char *(*quoting_func)(const char *))
{
const LineInfo *li;
char *temp;
char *dequoted_temp;
char **matches;
const char *ctemp;
const TYPE(LineInfo) *li;
Char *temp;
Char *dequoted_temp;
char **matches;
const Char *ctemp;
size_t len;
int what_to_do = '\t';
int retval = CC_NORM;
@ -409,26 +446,20 @@ fn_complete(EditLine *el,
app_func = append_char_function;
/* We now look backwards for the start of a filename/variable word */
li = el_line(el);
li = FUN(el,line)(el);
if (find_word_start_func)
ctemp = find_word_start_func(li->buffer, li->cursor);
else {
ctemp = li->cursor;
while (ctemp > li->buffer
&& !strchr(word_break, ctemp[-1])
&& (!special_prefixes || !strchr(special_prefixes, ctemp[-1]) ) )
&& !Strchr(word_break, ctemp[-1])
&& (!special_prefixes || !Strchr(special_prefixes, ctemp[-1]) ) )
ctemp--;
}
len = li->cursor - ctemp;
#if defined(__SSP__) || defined(__SSP_ALL__)
temp = malloc(sizeof(*temp) * (len + 1));
if (temp == NULL)
return retval;
#else
temp = alloca(sizeof(*temp) * (len + 1));
#endif
(void)strncpy(temp, ctemp, len);
len = (size_t)(li->cursor - ctemp);
temp = el_malloc((len + 1) * sizeof(*temp));
(void)Strncpy(temp, ctemp, len);
temp[len] = '\0';
if (dequoting_func) {
@ -447,13 +478,17 @@ fn_complete(EditLine *el,
if (attempted_completion_function) {
int cur_off = (int)(li->cursor - li->buffer);
matches = (*attempted_completion_function) (dequoted_temp ? dequoted_temp : temp,
(int)(cur_off - len), cur_off);
matches = (*attempted_completion_function)(
ct_encode_string(dequoted_temp ? dequoted_temp : temp,
&el->el_scratch),
cur_off - (int)len, cur_off);
} else
matches = 0;
if (!attempted_completion_function ||
(over != NULL && !*over && !matches))
matches = completion_matches(dequoted_temp ? dequoted_temp : temp, complet_func);
matches = completion_matches(
ct_encode_string(dequoted_temp ? dequoted_temp : temp,
&el->el_scratch), complet_func);
if (over != NULL)
*over = 0;
@ -475,23 +510,25 @@ fn_complete(EditLine *el,
goto free_matches;
} else
quoted_match = NULL;
el_deletestr(el, (int) len);
el_insertstr(el, quoted_match ? quoted_match : matches[0]);
free(quoted_match);
FUN(el,insertstr)(el,
ct_decode_string(quoted_match ? quoted_match :
matches[0] , &el->el_scratch));
}
if (what_to_do == '?')
goto display_matches;
if (matches[2] == NULL && strcmp(matches[0], matches[1]) == 0) {
if (matches[2] == NULL &&
(matches[1] == NULL || strcmp(matches[0], matches[1]) == 0)) {
/*
* We found exact match. Add a space after
* it, unless we do filename completion and the
* object is a directory.
*/
el_insertstr(el, (*app_func)(matches[0]));
FUN(el,insertstr)(el,
ct_decode_string((*app_func)(matches[0]),
&el->el_scratch));
} else if (what_to_do == '!') {
display_matches:
/*
@ -504,7 +541,8 @@ fn_complete(EditLine *el,
if (match_len > maxlen)
maxlen = match_len;
}
matches_num = i - 1;
/* matches[1] through matches[i-1] are available */
matches_num = (size_t)(i - 1);
/* newline to get on next line from command line */
(void)fprintf(el->el_outfile, "\n");
@ -523,9 +561,17 @@ fn_complete(EditLine *el,
(void)fprintf(el->el_outfile, "\n");
}
if (match_display)
fn_display_match_list(el, matches, matches_num,
maxlen);
if (match_display) {
/*
* Interface of this function requires the
* strings be matches[1..num-1] for compat.
* We have matches_num strings not counting
* the prefix in matches[0], so we need to
* add 1 to matches_num for the call.
*/
fn_display_match_list(el, matches,
matches_num+1, maxlen);
}
retval = CC_REDISPLAY;
} else if (matches[0][0]) {
/*
@ -544,18 +590,15 @@ fn_complete(EditLine *el,
free_matches:
/* free elements of array and the array itself */
for (i = 0; matches[i]; i++)
free(matches[i]);
free(matches);
el_free(matches[i]);
el_free(matches);
matches = NULL;
}
free(dequoted_temp);
#if defined(__SSP__) || defined(__SSP_ALL__)
free(temp);
#endif
el_free(temp);
return retval;
}
/*
* el-compatible wrapper around rl_complete; needed for key binding
*/
@ -564,30 +607,26 @@ unsigned char
_el_fn_complete(EditLine *el, int ch __attribute__((__unused__)))
{
return (unsigned char)fn_complete(el, NULL, NULL,
break_chars, NULL, NULL, 100,
break_chars, NULL, NULL, (size_t)100,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL);
}
static const char *
sh_find_word_start(const char *buffer, const char *cursor)
static const Char *
sh_find_word_start(const Char *buffer, const Char *cursor)
{
const char *word_start = buffer;
const Char *word_start = buffer;
while (buffer < cursor) {
if (*buffer == '\\')
buffer++;
else if (strchr(break_chars, *buffer))
else if (Strchr(break_chars, *buffer))
word_start = buffer + 1;
buffer++;
}
return word_start;
}
static char *
sh_quote(const char *str)
{
@ -595,24 +634,20 @@ sh_quote(const char *str)
int extra_len = 0;
char *quoted_str, *dst;
if (*str == '-' || *str == '+')
extra_len += 2;
for (src = str; *src != '\0'; src++)
if (strchr(break_chars, *src) ||
strchr(extra_quote_chars, *src))
for (src = str; *src != '\0'; src++)
if (Strchr(break_chars, *src) ||
Strchr(extra_quote_chars, *src))
extra_len++;
quoted_str = malloc(sizeof(*quoted_str) *
(strlen(str) + extra_len + 1));
(strlen(str) + extra_len + 1));
if (quoted_str == NULL)
return NULL;
dst = quoted_str;
if (*str == '-' || *str == '+')
*dst++ = '.', *dst++ = '/';
for (src = str; *src != '\0'; src++) {
if (strchr(break_chars, *src) ||
strchr(extra_quote_chars, *src))
if (Strchr(break_chars, *src) ||
Strchr(extra_quote_chars, *src))
*dst++ = '\\';
*dst++ = *src;
}
@ -621,14 +656,13 @@ sh_quote(const char *str)
return quoted_str;
}
static char *
sh_dequote(const char *str)
static Char *
sh_dequote(const Char *str)
{
char *dequoted_str, *dst;
Char *dequoted_str, *dst;
/* save extra space to replace \~ with ./~ */
dequoted_str = malloc(sizeof(*dequoted_str) * (strlen(str) + 1 + 1));
dequoted_str = malloc(sizeof(*dequoted_str) * (Strlen(str) + 1 + 1));
if (dequoted_str == NULL)
return NULL;
@ -652,7 +686,6 @@ sh_dequote(const char *str)
return dequoted_str;
}
/*
* completion function using sh quoting rules; for key binding
*/

View File

@ -1,3 +1,5 @@
/* $NetBSD: filecomplete.h,v 1.9 2009/12/30 22:37:40 christos Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
* All rights reserved.
@ -26,7 +28,6 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* $NetBSD: filecomplete.h,v 1.8 2009/02/16 00:15:45 christos Exp $
* $FreeBSD$
*/
#ifndef _FILECOMPLETE_H_
@ -35,10 +36,10 @@
int fn_complete(EditLine *,
char *(*)(const char *, int),
char **(*)(const char *, int, int),
const char *, const char *, const char *(*)(const char *), size_t,
const Char *, const Char *, const char *(*)(const char *), size_t,
int *, int *, int *, int *,
const char *(*)(const char *, const char *),
char *(*)(const char *),
const Char *(*)(const Char *, const Char *),
Char *(*)(const Char *),
char *(*)(const char *));
void fn_display_match_list(EditLine *, char **, size_t, size_t);

View File

@ -1,3 +1,5 @@
/* $NetBSD: hist.c,v 1.20 2011/07/29 15:16:33 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
@ -28,12 +30,15 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $NetBSD: hist.c,v 1.15 2003/11/01 23:36:39 christos Exp $
*/
#include "config.h"
#if !defined(lint) && !defined(SCCSID)
#if 0
static char sccsid[] = "@(#)hist.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: hist.c,v 1.20 2011/07/29 15:16:33 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@ -41,7 +46,6 @@ __FBSDID("$FreeBSD$");
/*
* hist.c: History access functions
*/
#include "sys.h"
#include <stdlib.h>
#include "el.h"
@ -54,12 +58,12 @@ hist_init(EditLine *el)
el->el_history.fun = NULL;
el->el_history.ref = NULL;
el->el_history.buf = (char *) el_malloc(EL_BUFSIZ);
el->el_history.buf = el_malloc(EL_BUFSIZ * sizeof(*el->el_history.buf));
el->el_history.sz = EL_BUFSIZ;
if (el->el_history.buf == NULL)
return (-1);
return -1;
el->el_history.last = el->el_history.buf;
return (0);
return 0;
}
@ -70,7 +74,7 @@ protected void
hist_end(EditLine *el)
{
el_free((ptr_t) el->el_history.buf);
el_free(el->el_history.buf);
el->el_history.buf = NULL;
}
@ -79,12 +83,12 @@ hist_end(EditLine *el)
* Set new history interface
*/
protected int
hist_set(EditLine *el, hist_fun_t fun, ptr_t ptr)
hist_set(EditLine *el, hist_fun_t fun, void *ptr)
{
el->el_history.ref = ptr;
el->el_history.fun = fun;
return (0);
return 0;
}
@ -95,11 +99,11 @@ hist_set(EditLine *el, hist_fun_t fun, ptr_t ptr)
protected el_action_t
hist_get(EditLine *el)
{
const char *hp;
const Char *hp;
int h;
if (el->el_history.eventno == 0) { /* if really the current line */
(void) strncpy(el->el_line.buffer, el->el_history.buf,
(void) Strncpy(el->el_line.buffer, el->el_history.buf,
el->el_history.sz);
el->el_line.lastchar = el->el_line.buffer +
(el->el_history.last - el->el_history.buf);
@ -111,24 +115,25 @@ hist_get(EditLine *el)
#endif /* KSHVI */
el->el_line.cursor = el->el_line.lastchar;
return (CC_REFRESH);
return CC_REFRESH;
}
if (el->el_history.ref == NULL)
return (CC_ERROR);
return CC_ERROR;
hp = HIST_FIRST(el);
if (hp == NULL)
return (CC_ERROR);
return CC_ERROR;
for (h = 1; h < el->el_history.eventno; h++)
if ((hp = HIST_NEXT(el)) == NULL) {
el->el_history.eventno = h;
return (CC_ERROR);
return CC_ERROR;
}
(void) strlcpy(el->el_line.buffer, hp,
(void) Strncpy(el->el_line.buffer, hp,
(size_t)(el->el_line.limit - el->el_line.buffer));
el->el_line.lastchar = el->el_line.buffer + strlen(el->el_line.buffer);
el->el_line.buffer[el->el_line.limit - el->el_line.buffer - 1] = '\0';
el->el_line.lastchar = el->el_line.buffer + Strlen(el->el_line.buffer);
if (el->el_line.lastchar > el->el_line.buffer
&& el->el_line.lastchar[-1] == '\n')
@ -143,7 +148,7 @@ hist_get(EditLine *el)
#endif /* KSHVI */
el->el_line.cursor = el->el_line.lastchar;
return (CC_REFRESH);
return CC_REFRESH;
}
@ -151,34 +156,34 @@ hist_get(EditLine *el)
* process a history command
*/
protected int
hist_command(EditLine *el, int argc, const char **argv)
hist_command(EditLine *el, int argc, const Char **argv)
{
const char *str;
const Char *str;
int num;
HistEvent ev;
TYPE(HistEvent) ev;
if (el->el_history.ref == NULL)
return (-1);
return -1;
if (argc == 1 || strcmp(argv[1], "list") == 0) {
if (argc == 1 || Strcmp(argv[1], STR("list")) == 0) {
/* List history entries */
for (str = HIST_LAST(el); str != NULL; str = HIST_PREV(el))
(void) fprintf(el->el_outfile, "%d %s",
el->el_history.ev.num, str);
return (0);
el->el_history.ev.num, ct_encode_string(str, &el->el_scratch));
return 0;
}
if (argc != 3)
return (-1);
return -1;
num = (int)strtol(argv[2], NULL, 0);
num = (int)Strtol(argv[2], NULL, 0);
if (strcmp(argv[1], "size") == 0)
return history(el->el_history.ref, &ev, H_SETSIZE, num);
if (Strcmp(argv[1], STR("size")) == 0)
return FUNW(history)(el->el_history.ref, &ev, H_SETSIZE, num);
if (strcmp(argv[1], "unique") == 0)
return history(el->el_history.ref, &ev, H_SETUNIQUE, num);
if (Strcmp(argv[1], STR("unique")) == 0)
return FUNW(history)(el->el_history.ref, &ev, H_SETUNIQUE, num);
return -1;
}
@ -191,13 +196,13 @@ protected int
/*ARGSUSED*/
hist_enlargebuf(EditLine *el, size_t oldsz, size_t newsz)
{
char *newbuf;
Char *newbuf;
newbuf = realloc(el->el_history.buf, newsz);
newbuf = el_realloc(el->el_history.buf, newsz * sizeof(*newbuf));
if (!newbuf)
return 0;
(void) memset(&newbuf[oldsz], '\0', newsz - oldsz);
(void) memset(&newbuf[oldsz], '\0', (newsz - oldsz) * sizeof(*newbuf));
el->el_history.last = newbuf +
(el->el_history.last - el->el_history.buf);
@ -206,3 +211,15 @@ hist_enlargebuf(EditLine *el, size_t oldsz, size_t newsz)
return 1;
}
#ifdef WIDECHAR
protected wchar_t *
hist_convert(EditLine *el, int fn, void *arg)
{
HistEventW ev;
if ((*(el)->el_history.fun)((el)->el_history.ref, &ev, fn, arg) == -1)
return NULL;
return ct_decode_string((const char *)(const void *)ev.str,
&el->el_scratch);
}
#endif

View File

@ -1,3 +1,5 @@
/* $NetBSD: hist.h,v 1.14 2014/05/11 01:05:17 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
@ -30,7 +32,6 @@
* SUCH DAMAGE.
*
* @(#)hist.h 8.1 (Berkeley) 6/4/93
* $NetBSD: hist.h,v 1.10 2003/08/07 16:44:31 agc Exp $
* $FreeBSD$
*/
@ -42,21 +43,29 @@
#include "histedit.h"
typedef int (*hist_fun_t)(ptr_t, HistEvent *, int, ...);
typedef int (*hist_fun_t)(void *, TYPE(HistEvent) *, int, ...);
typedef struct el_history_t {
char *buf; /* The history buffer */
Char *buf; /* The history buffer */
size_t sz; /* Size of history buffer */
char *last; /* The last character */
Char *last; /* The last character */
int eventno; /* Event we are looking for */
ptr_t ref; /* Argument for history fcns */
void * ref; /* Argument for history fcns */
hist_fun_t fun; /* Event access */
HistEvent ev; /* Event cookie */
TYPE(HistEvent) ev; /* Event cookie */
} el_history_t;
#define HIST_FUN(el, fn, arg) \
#define HIST_FUN_INTERNAL(el, fn, arg) \
((((*(el)->el_history.fun) ((el)->el_history.ref, &(el)->el_history.ev, \
fn, arg)) == -1) ? NULL : (el)->el_history.ev.str)
#ifdef WIDECHAR
#define HIST_FUN(el, fn, arg) \
(((el)->el_flags & NARROW_HISTORY) ? hist_convert(el, fn, arg) : \
HIST_FUN_INTERNAL(el, fn, arg))
#else
#define HIST_FUN(el, fn, arg) HIST_FUN_INTERNAL(el, fn, arg)
#endif
#define HIST_NEXT(el) HIST_FUN(el, H_NEXT, NULL)
#define HIST_FIRST(el) HIST_FUN(el, H_FIRST, NULL)
@ -70,8 +79,11 @@ typedef struct el_history_t {
protected int hist_init(EditLine *);
protected void hist_end(EditLine *);
protected el_action_t hist_get(EditLine *);
protected int hist_set(EditLine *, hist_fun_t, ptr_t);
protected int hist_command(EditLine *, int, const char **);
protected int hist_set(EditLine *, hist_fun_t, void *);
protected int hist_command(EditLine *, int, const Char **);
protected int hist_enlargebuf(EditLine *, size_t, size_t);
#ifdef WIDECHAR
protected wchar_t *hist_convert(EditLine *, int, void *);
#endif
#endif /* _h_el_hist */

View File

@ -1,3 +1,5 @@
/* $NetBSD: histedit.h,v 1.53 2014/06/18 18:12:28 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
@ -30,7 +32,6 @@
* SUCH DAMAGE.
*
* @(#)histedit.h 8.2 (Berkeley) 1/3/94
* $NetBSD: histedit.h,v 1.41 2009/09/07 21:24:33 christos Exp $
* $FreeBSD$
*/
@ -40,10 +41,12 @@
#ifndef _HISTEDIT_H_
#define _HISTEDIT_H_
#define LIBEDIT_MAJOR 2
#define LIBEDIT_MINOR 11
#include <sys/types.h>
#include <stdio.h>
__BEGIN_DECLS
#ifdef __cplusplus
extern "C" {
#endif
@ -82,6 +85,8 @@ typedef struct lineinfo {
* Initialization, cleanup, and resetting
*/
EditLine *el_init(const char *, FILE *, FILE *, FILE *);
EditLine *el_init_fd(const char *, FILE *, FILE *, FILE *,
int, int, int);
void el_end(EditLine *);
void el_reset(EditLine *);
@ -113,32 +118,47 @@ unsigned char _el_fn_sh_complete(EditLine *, int);
/*
* el_set/el_get parameters
*
* When using el_wset/el_wget (as opposed to el_set/el_get):
* Char is wchar_t, otherwise it is char.
* prompt_func is el_wpfunc_t, otherwise it is el_pfunc_t .
* Prompt function prototypes are:
* typedef char *(*el_pfunct_t) (EditLine *);
* typedef wchar_t *(*el_wpfunct_t) (EditLine *);
*
* For operations that support set or set/get, the argument types listed are for
* the "set" operation. For "get", each listed type must be a pointer.
* E.g. EL_EDITMODE takes an int when set, but an int* when get.
*
* Operations that only support "get" have the correct argument types listed.
*/
#define EL_PROMPT 0 /* , el_pfunc_t); */
#define EL_TERMINAL 1 /* , const char *); */
#define EL_EDITOR 2 /* , const char *); */
#define EL_SIGNAL 3 /* , int); */
#define EL_BIND 4 /* , const char *, ..., NULL); */
#define EL_TELLTC 5 /* , const char *, ..., NULL); */
#define EL_SETTC 6 /* , const char *, ..., NULL); */
#define EL_ECHOTC 7 /* , const char *, ..., NULL); */
#define EL_SETTY 8 /* , const char *, ..., NULL); */
#define EL_ADDFN 9 /* , const char *, const char * */
/* , el_func_t); */
#define EL_HIST 10 /* , hist_fun_t, const char *); */
#define EL_EDITMODE 11 /* , int); */
#define EL_RPROMPT 12 /* , el_pfunc_t); */
#define EL_GETCFN 13 /* , el_rfunc_t); */
#define EL_CLIENTDATA 14 /* , void *); */
#define EL_UNBUFFERED 15 /* , int); */
#define EL_PREP_TERM 16 /* , int); */
#define EL_GETTC 17 /* , const char *, ..., NULL); */
#define EL_GETFP 18 /* , int, FILE **); */
#define EL_SETFP 19 /* , int, FILE *); */
#define EL_PROMPT 0 /* , prompt_func); set/get */
#define EL_TERMINAL 1 /* , const char *); set/get */
#define EL_EDITOR 2 /* , const Char *); set/get */
#define EL_SIGNAL 3 /* , int); set/get */
#define EL_BIND 4 /* , const Char *, ..., NULL); set */
#define EL_TELLTC 5 /* , const Char *, ..., NULL); set */
#define EL_SETTC 6 /* , const Char *, ..., NULL); set */
#define EL_ECHOTC 7 /* , const Char *, ..., NULL); set */
#define EL_SETTY 8 /* , const Char *, ..., NULL); set */
#define EL_ADDFN 9 /* , const Char *, const Char, set */
/* el_func_t); */
#define EL_HIST 10 /* , hist_fun_t, const void *); set */
#define EL_EDITMODE 11 /* , int); set/get */
#define EL_RPROMPT 12 /* , prompt_func); set/get */
#define EL_GETCFN 13 /* , el_rfunc_t); set/get */
#define EL_CLIENTDATA 14 /* , void *); set/get */
#define EL_UNBUFFERED 15 /* , int); set/get */
#define EL_PREP_TERM 16 /* , int); set */
#define EL_GETTC 17 /* , const Char *, ..., NULL); get */
#define EL_GETFP 18 /* , int, FILE **); get */
#define EL_SETFP 19 /* , int, FILE *); set */
#define EL_REFRESH 20 /* , void); set */
#define EL_PROMPT_ESC 21 /* , prompt_func, Char); set/get */
#define EL_RPROMPT_ESC 22 /* , prompt_func, Char); set/get */
#define EL_RESIZE 23 /* , el_zfunc_t, void *); set */
#define EL_ALIAS_TEXT 24 /* , el_afunc_t, void *); set */
#define EL_BUILTIN_GETCFN (NULL)
@ -183,7 +203,6 @@ int history(History *, HistEvent *, int, ...);
#define H_FUNC 0 /* , UTSL */
#define H_SETSIZE 1 /* , const int); */
#define H_EVENT 1 /* , const int); */
#define H_GETSIZE 2 /* , void); */
#define H_FIRST 3 /* , void); */
#define H_LAST 4 /* , void); */
@ -191,12 +210,12 @@ int history(History *, HistEvent *, int, ...);
#define H_NEXT 6 /* , void); */
#define H_CURR 8 /* , const int); */
#define H_SET 7 /* , int); */
#define H_ADD 9 /* , const char *); */
#define H_ENTER 10 /* , const char *); */
#define H_APPEND 11 /* , const char *); */
#define H_ADD 9 /* , const wchar_t *); */
#define H_ENTER 10 /* , const wchar_t *); */
#define H_APPEND 11 /* , const wchar_t *); */
#define H_END 12 /* , void); */
#define H_NEXT_STR 13 /* , const char *); */
#define H_PREV_STR 14 /* , const char *); */
#define H_NEXT_STR 13 /* , const wchar_t *); */
#define H_PREV_STR 14 /* , const wchar_t *); */
#define H_NEXT_EVENT 15 /* , const int); */
#define H_PREV_EVENT 16 /* , const int); */
#define H_LOAD 17 /* , const char *); */
@ -208,7 +227,8 @@ int history(History *, HistEvent *, int, ...);
#define H_NEXT_EVDATA 23 /* , const int, histdata_t *); */
#define H_DELDATA 24 /* , int, histdata_t *);*/
#define H_REPLACE 25 /* , const char *, histdata_t); */
#define H_SAVE_FP 26 /* , FILE*); */
#define H_SAVE_FP 26 /* , FILE *); */
/*
@ -228,7 +248,75 @@ int tok_line(Tokenizer *, const LineInfo *,
int tok_str(Tokenizer *, const char *,
int *, const char ***);
__END_DECLS
/*
* Begin Wide Character Support
*/
#ifdef __linux__
/* Apparently we need _GNU_SOURCE defined to get access to wcsdup on Linux */
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#endif
#include <wchar.h>
#include <wctype.h>
/*
* Wide character versions
*/
/*
* ==== Editing ====
*/
typedef struct lineinfow {
const wchar_t *buffer;
const wchar_t *cursor;
const wchar_t *lastchar;
} LineInfoW;
const wchar_t *el_wgets(EditLine *, int *);
int el_wgetc(EditLine *, wchar_t *);
void el_wpush(EditLine *, const wchar_t *);
int el_wparse(EditLine *, int, const wchar_t **);
int el_wset(EditLine *, int, ...);
int el_wget(EditLine *, int, ...);
int el_cursor(EditLine *, int);
const LineInfoW *el_wline(EditLine *);
int el_winsertstr(EditLine *, const wchar_t *);
#define el_wdeletestr el_deletestr
/*
* ==== History ====
*/
typedef struct histeventW {
int num;
const wchar_t *str;
} HistEventW;
typedef struct historyW HistoryW;
HistoryW * history_winit(void);
void history_wend(HistoryW *);
int history_w(HistoryW *, HistEventW *, int, ...);
/*
* ==== Tokenization ====
*/
typedef struct tokenizerW TokenizerW;
/* Wide character tokenizer support */
TokenizerW *tok_winit(const wchar_t *);
void tok_wend(TokenizerW *);
void tok_wreset(TokenizerW *);
int tok_wline(TokenizerW *, const LineInfoW *,
int *, const wchar_t ***, int *, int *);
int tok_wstr(TokenizerW *, const wchar_t *,
int *, const wchar_t ***);
#ifdef __cplusplus
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,5 @@
/* $NetBSD: keymacro.c,v 1.7 2011/08/16 16:25:15 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
@ -28,31 +30,35 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $NetBSD: key.c,v 1.20 2009/02/15 21:55:23 christos Exp $
*/
#include "config.h"
#if !defined(lint) && !defined(SCCSID)
#if 0
static char sccsid[] = "@(#)key.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: keymacro.c,v 1.7 2011/08/16 16:25:15 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/*
* key.c: This module contains the procedures for maintaining
* the extended-key map.
* keymacro.c: This module contains the procedures for maintaining
* the extended-key map.
*
* An extended-key (key) is a sequence of keystrokes introduced
* with a sequence introducer and consisting of an arbitrary
* number of characters. This module maintains a map (the el->el_key.map)
* number of characters. This module maintains a map (the
* el->el_keymacro.map)
* to convert these extended-key sequences into input strs
* (XK_STR), editor functions (XK_CMD), or unix commands (XK_EXE).
*
* Warning:
* If key is a substr of some other keys, then the longer
* keys are lost!! That is, if the keys "abcd" and "abcef"
* are in el->el_key.map, adding the key "abc" will cause the first two
* definitions to be lost.
* are in el->el_keymacro.map, adding the key "abc" will cause
* the first two definitions to be lost.
*
* Restrictions:
* -------------
@ -65,102 +71,104 @@ __FBSDID("$FreeBSD$");
#include "el.h"
/*
* The Nodes of the el->el_key.map. The el->el_key.map is a linked list
* of these node elements
* The Nodes of the el->el_keymacro.map. The el->el_keymacro.map is a
* linked list of these node elements
*/
struct key_node_t {
char ch; /* single character of key */
int type; /* node type */
key_value_t val; /* command code or pointer to str, */
struct keymacro_node_t {
Char ch; /* single character of key */
int type; /* node type */
keymacro_value_t val; /* command code or pointer to str, */
/* if this is a leaf */
struct key_node_t *next; /* ptr to next char of this key */
struct key_node_t *sibling; /* ptr to another key with same prefix*/
struct keymacro_node_t *next; /* ptr to next char of this key */
struct keymacro_node_t *sibling;/* ptr to another key with same prefix*/
};
private int node_trav(EditLine *, key_node_t *, char *,
key_value_t *);
private int node__try(EditLine *, key_node_t *, const char *,
key_value_t *, int);
private key_node_t *node__get(int);
private void node__free(key_node_t *);
private void node__put(EditLine *, key_node_t *);
private int node__delete(EditLine *, key_node_t **, const char *);
private int node_lookup(EditLine *, const char *, key_node_t *,
size_t);
private int node_enum(EditLine *, key_node_t *, size_t);
private int node_trav(EditLine *, keymacro_node_t *, Char *,
keymacro_value_t *);
private int node__try(EditLine *, keymacro_node_t *, const Char *,
keymacro_value_t *, int);
private keymacro_node_t *node__get(Int);
private void node__free(keymacro_node_t *);
private void node__put(EditLine *, keymacro_node_t *);
private int node__delete(EditLine *, keymacro_node_t **,
const Char *);
private int node_lookup(EditLine *, const Char *,
keymacro_node_t *, size_t);
private int node_enum(EditLine *, keymacro_node_t *, size_t);
#define KEY_BUFSIZ EL_BUFSIZ
/* key_init():
/* keymacro_init():
* Initialize the key maps
*/
protected int
key_init(EditLine *el)
keymacro_init(EditLine *el)
{
el->el_key.buf = (char *) el_malloc(KEY_BUFSIZ);
if (el->el_key.buf == NULL)
return (-1);
el->el_key.map = NULL;
key_reset(el);
return (0);
el->el_keymacro.buf = el_malloc(KEY_BUFSIZ *
sizeof(*el->el_keymacro.buf));
if (el->el_keymacro.buf == NULL)
return -1;
el->el_keymacro.map = NULL;
keymacro_reset(el);
return 0;
}
/* key_end():
/* keymacro_end():
* Free the key maps
*/
protected void
key_end(EditLine *el)
keymacro_end(EditLine *el)
{
el_free((ptr_t) el->el_key.buf);
el->el_key.buf = NULL;
node__free(el->el_key.map);
el_free(el->el_keymacro.buf);
el->el_keymacro.buf = NULL;
node__free(el->el_keymacro.map);
}
/* key_map_cmd():
/* keymacro_map_cmd():
* Associate cmd with a key value
*/
protected key_value_t *
key_map_cmd(EditLine *el, int cmd)
protected keymacro_value_t *
keymacro_map_cmd(EditLine *el, int cmd)
{
el->el_key.val.cmd = (el_action_t) cmd;
return (&el->el_key.val);
el->el_keymacro.val.cmd = (el_action_t) cmd;
return &el->el_keymacro.val;
}
/* key_map_str():
/* keymacro_map_str():
* Associate str with a key value
*/
protected key_value_t *
key_map_str(EditLine *el, char *str)
protected keymacro_value_t *
keymacro_map_str(EditLine *el, Char *str)
{
el->el_key.val.str = str;
return (&el->el_key.val);
el->el_keymacro.val.str = str;
return &el->el_keymacro.val;
}
/* key_reset():
* Takes all nodes on el->el_key.map and puts them on free list. Then
* initializes el->el_key.map with arrow keys
/* keymacro_reset():
* Takes all nodes on el->el_keymacro.map and puts them on free list.
* Then initializes el->el_keymacro.map with arrow keys
* [Always bind the ansi arrow keys?]
*/
protected void
key_reset(EditLine *el)
keymacro_reset(EditLine *el)
{
node__put(el, el->el_key.map);
el->el_key.map = NULL;
node__put(el, el->el_keymacro.map);
el->el_keymacro.map = NULL;
return;
}
/* key_get():
* Calls the recursive function with entry point el->el_key.map
/* keymacro_get():
* Calls the recursive function with entry point el->el_keymacro.map
* Looks up *ch in map and then reads characters until a
* complete match is found or a mismatch occurs. Returns the
* type of the match found (XK_STR, XK_CMD, or XK_EXE).
@ -168,98 +176,101 @@ key_reset(EditLine *el)
* The last character read is returned in *ch.
*/
protected int
key_get(EditLine *el, char *ch, key_value_t *val)
keymacro_get(EditLine *el, Char *ch, keymacro_value_t *val)
{
return (node_trav(el, el->el_key.map, ch, val));
return node_trav(el, el->el_keymacro.map, ch, val);
}
/* key_add():
* Adds key to the el->el_key.map and associates the value in val with it.
* If key is already is in el->el_key.map, the new code is applied to the
* existing key. Ntype specifies if code is a command, an
* out str or a unix command.
/* keymacro_add():
* Adds key to the el->el_keymacro.map and associates the value in
* val with it. If key is already is in el->el_keymacro.map, the new
* code is applied to the existing key. Ntype specifies if code is a
* command, an out str or a unix command.
*/
protected void
key_add(EditLine *el, const char *key, key_value_t *val, int ntype)
keymacro_add(EditLine *el, const Char *key, keymacro_value_t *val, int ntype)
{
if (key[0] == '\0') {
(void) fprintf(el->el_errfile,
"key_add: Null extended-key not allowed.\n");
"keymacro_add: Null extended-key not allowed.\n");
return;
}
if (ntype == XK_CMD && val->cmd == ED_SEQUENCE_LEAD_IN) {
(void) fprintf(el->el_errfile,
"key_add: sequence-lead-in command not allowed\n");
"keymacro_add: sequence-lead-in command not allowed\n");
return;
}
if (el->el_key.map == NULL)
if (el->el_keymacro.map == NULL)
/* tree is initially empty. Set up new node to match key[0] */
el->el_key.map = node__get(key[0]);
el->el_keymacro.map = node__get(key[0]);
/* it is properly initialized */
/* Now recurse through el->el_key.map */
(void) node__try(el, el->el_key.map, key, val, ntype);
/* Now recurse through el->el_keymacro.map */
(void) node__try(el, el->el_keymacro.map, key, val, ntype);
return;
}
/* key_clear():
/* keymacro_clear():
*
*/
protected void
key_clear(EditLine *el, el_action_t *map, const char *in)
keymacro_clear(EditLine *el, el_action_t *map, const Char *in)
{
#ifdef WIDECHAR
if (*in > N_KEYS) /* can't be in the map */
return;
#endif
if ((map[(unsigned char)*in] == ED_SEQUENCE_LEAD_IN) &&
((map == el->el_map.key &&
el->el_map.alt[(unsigned char)*in] != ED_SEQUENCE_LEAD_IN) ||
(map == el->el_map.alt &&
el->el_map.key[(unsigned char)*in] != ED_SEQUENCE_LEAD_IN)))
(void) key_delete(el, in);
(void) keymacro_delete(el, in);
}
/* key_delete():
/* keymacro_delete():
* Delete the key and all longer keys staring with key, if
* they exists.
*/
protected int
key_delete(EditLine *el, const char *key)
keymacro_delete(EditLine *el, const Char *key)
{
if (key[0] == '\0') {
(void) fprintf(el->el_errfile,
"key_delete: Null extended-key not allowed.\n");
return (-1);
"keymacro_delete: Null extended-key not allowed.\n");
return -1;
}
if (el->el_key.map == NULL)
return (0);
if (el->el_keymacro.map == NULL)
return 0;
(void) node__delete(el, &el->el_key.map, key);
return (0);
(void) node__delete(el, &el->el_keymacro.map, key);
return 0;
}
/* key_print():
/* keymacro_print():
* Print the binding associated with key key.
* Print entire el->el_key.map if null
* Print entire el->el_keymacro.map if null
*/
protected void
key_print(EditLine *el, const char *key)
keymacro_print(EditLine *el, const Char *key)
{
/* do nothing if el->el_key.map is empty and null key specified */
if (el->el_key.map == NULL && *key == 0)
/* do nothing if el->el_keymacro.map is empty and null key specified */
if (el->el_keymacro.map == NULL && *key == 0)
return;
el->el_key.buf[0] = '"';
if (node_lookup(el, key, el->el_key.map, 1) <= -1)
el->el_keymacro.buf[0] = '"';
if (node_lookup(el, key, el->el_keymacro.map, (size_t)1) <= -1)
/* key is not bound */
(void) fprintf(el->el_errfile, "Unbound extended key \"%s\"\n",
key);
(void) fprintf(el->el_errfile, "Unbound extended key \"" FSTR
"\"\n", key);
return;
}
@ -269,34 +280,34 @@ key_print(EditLine *el, const char *key)
* found. May read in more characters.
*/
private int
node_trav(EditLine *el, key_node_t *ptr, char *ch, key_value_t *val)
node_trav(EditLine *el, keymacro_node_t *ptr, Char *ch, keymacro_value_t *val)
{
if (ptr->ch == *ch) {
/* match found */
if (ptr->next) {
/* key not complete so get next char */
if (el_getc(el, ch) != 1) { /* if EOF or error */
if (FUN(el,getc)(el, ch) != 1) {/* if EOF or error */
val->cmd = ED_END_OF_FILE;
return (XK_CMD);
return XK_CMD;
/* PWP: Pretend we just read an end-of-file */
}
return (node_trav(el, ptr->next, ch, val));
return node_trav(el, ptr->next, ch, val);
} else {
*val = ptr->val;
if (ptr->type != XK_CMD)
*ch = '\0';
return (ptr->type);
return ptr->type;
}
} else {
/* no match found here */
if (ptr->sibling) {
/* try next sibling */
return (node_trav(el, ptr->sibling, ch, val));
return node_trav(el, ptr->sibling, ch, val);
} else {
/* no next sibling -- mismatch */
val->str = NULL;
return (XK_STR);
return XK_STR;
}
}
}
@ -306,11 +317,12 @@ node_trav(EditLine *el, key_node_t *ptr, char *ch, key_value_t *val)
* Find a node that matches *str or allocate a new one
*/
private int
node__try(EditLine *el, key_node_t *ptr, const char *str, key_value_t *val, int ntype)
node__try(EditLine *el, keymacro_node_t *ptr, const Char *str,
keymacro_value_t *val, int ntype)
{
if (ptr->ch != *str) {
key_node_t *xm;
keymacro_node_t *xm;
for (xm = ptr; xm->sibling != NULL; xm = xm->sibling)
if (xm->sibling->ch == *str)
@ -333,7 +345,7 @@ node__try(EditLine *el, key_node_t *ptr, const char *str, key_value_t *val, int
case XK_STR:
case XK_EXE:
if (ptr->val.str)
el_free((ptr_t) ptr->val.str);
el_free(ptr->val.str);
break;
default:
EL_ABORT((el->el_errfile, "Bad XK_ type %d\n",
@ -347,7 +359,7 @@ node__try(EditLine *el, key_node_t *ptr, const char *str, key_value_t *val, int
break;
case XK_STR:
case XK_EXE:
if ((ptr->val.str = el_strdup(val->str)) == NULL)
if ((ptr->val.str = Strdup(val->str)) == NULL)
return -1;
break;
default:
@ -360,7 +372,7 @@ node__try(EditLine *el, key_node_t *ptr, const char *str, key_value_t *val, int
ptr->next = node__get(*str); /* setup new node */
(void) node__try(el, ptr->next, str, val, ntype);
}
return (0);
return 0;
}
@ -368,21 +380,21 @@ node__try(EditLine *el, key_node_t *ptr, const char *str, key_value_t *val, int
* Delete node that matches str
*/
private int
node__delete(EditLine *el, key_node_t **inptr, const char *str)
node__delete(EditLine *el, keymacro_node_t **inptr, const Char *str)
{
key_node_t *ptr;
key_node_t *prev_ptr = NULL;
keymacro_node_t *ptr;
keymacro_node_t *prev_ptr = NULL;
ptr = *inptr;
if (ptr->ch != *str) {
key_node_t *xm;
keymacro_node_t *xm;
for (xm = ptr; xm->sibling != NULL; xm = xm->sibling)
if (xm->sibling->ch == *str)
break;
if (xm->sibling == NULL)
return (0);
return 0;
prev_ptr = xm;
ptr = xm->sibling;
}
@ -394,20 +406,20 @@ node__delete(EditLine *el, key_node_t **inptr, const char *str)
prev_ptr->sibling = ptr->sibling;
ptr->sibling = NULL;
node__put(el, ptr);
return (1);
return 1;
} else if (ptr->next != NULL &&
node__delete(el, &ptr->next, str) == 1) {
if (ptr->next != NULL)
return (0);
return 0;
if (prev_ptr == NULL)
*inptr = ptr->sibling;
else
prev_ptr->sibling = ptr->sibling;
ptr->sibling = NULL;
node__put(el, ptr);
return (1);
return 1;
} else {
return (0);
return 0;
}
}
@ -416,7 +428,7 @@ node__delete(EditLine *el, key_node_t **inptr, const char *str)
* Puts a tree of nodes onto free list using free(3).
*/
private void
node__put(EditLine *el, key_node_t *ptr)
node__put(EditLine *el, keymacro_node_t *ptr)
{
if (ptr == NULL)
return;
@ -434,25 +446,25 @@ node__put(EditLine *el, key_node_t *ptr)
case XK_EXE:
case XK_STR:
if (ptr->val.str != NULL)
el_free((ptr_t) ptr->val.str);
el_free(ptr->val.str);
break;
default:
EL_ABORT((el->el_errfile, "Bad XK_ type %d\n", ptr->type));
break;
}
el_free((ptr_t) ptr);
el_free(ptr);
}
/* node__get():
* Returns pointer to a key_node_t for ch.
* Returns pointer to a keymacro_node_t for ch.
*/
private key_node_t *
node__get(int ch)
private keymacro_node_t *
node__get(Int ch)
{
key_node_t *ptr;
keymacro_node_t *ptr;
ptr = (key_node_t *) el_malloc((size_t) sizeof(key_node_t));
ptr = el_malloc(sizeof(*ptr));
if (ptr == NULL)
return NULL;
ptr->ch = ch;
@ -460,17 +472,17 @@ node__get(int ch)
ptr->val.str = NULL;
ptr->next = NULL;
ptr->sibling = NULL;
return (ptr);
return ptr;
}
private void
node__free(key_node_t *k)
node__free(keymacro_node_t *k)
{
if (k == NULL)
return;
node__free(k->sibling);
node__free(k->next);
el_free((ptr_t) k);
el_free(k);
}
/* node_lookup():
@ -478,38 +490,40 @@ node__free(key_node_t *k)
* Print if last node
*/
private int
node_lookup(EditLine *el, const char *str, key_node_t *ptr, size_t cnt)
node_lookup(EditLine *el, const Char *str, keymacro_node_t *ptr, size_t cnt)
{
size_t ncnt;
ssize_t used;
if (ptr == NULL)
return (-1); /* cannot have null ptr */
return -1; /* cannot have null ptr */
if (*str == 0) {
if (!str || *str == 0) {
/* no more chars in str. node_enum from here. */
(void) node_enum(el, ptr, cnt);
return (0);
return 0;
} else {
/* If match put this char into el->el_key.buf. Recurse */
/* If match put this char into el->el_keymacro.buf. Recurse */
if (ptr->ch == *str) {
/* match found */
ncnt = key__decode_char(el->el_key.buf,
(size_t)KEY_BUFSIZ, cnt,
(unsigned char) ptr->ch);
used = ct_visual_char(el->el_keymacro.buf + cnt,
KEY_BUFSIZ - cnt, ptr->ch);
if (used == -1)
return -1; /* ran out of buffer space */
if (ptr->next != NULL)
/* not yet at leaf */
return (node_lookup(el, str + 1, ptr->next,
ncnt + 1));
(size_t)used + cnt));
else {
/* next node is null so key should be complete */
if (str[1] == 0) {
el->el_key.buf[ncnt + 1] = '"';
el->el_key.buf[ncnt + 2] = '\0';
key_kprint(el, el->el_key.buf,
size_t px = cnt + (size_t)used;
el->el_keymacro.buf[px] = '"';
el->el_keymacro.buf[px + 1] = '\0';
keymacro_kprint(el, el->el_keymacro.buf,
&ptr->val, ptr->type);
return (0);
return 0;
} else
return (-1);
return -1;
/* mismatch -- str still has chars */
}
} else {
@ -518,7 +532,7 @@ node_lookup(EditLine *el, const char *str, key_node_t *ptr, size_t cnt)
return (node_lookup(el, str, ptr->sibling,
cnt));
else
return (-1);
return -1;
}
}
}
@ -528,49 +542,50 @@ node_lookup(EditLine *el, const char *str, key_node_t *ptr, size_t cnt)
* Traverse the node printing the characters it is bound in buffer
*/
private int
node_enum(EditLine *el, key_node_t *ptr, size_t cnt)
node_enum(EditLine *el, keymacro_node_t *ptr, size_t cnt)
{
size_t ncnt;
ssize_t used;
if (cnt >= KEY_BUFSIZ - 5) { /* buffer too small */
el->el_key.buf[++cnt] = '"';
el->el_key.buf[++cnt] = '\0';
el->el_keymacro.buf[++cnt] = '"';
el->el_keymacro.buf[++cnt] = '\0';
(void) fprintf(el->el_errfile,
"Some extended keys too long for internal print buffer");
(void) fprintf(el->el_errfile, " \"%s...\"\n", el->el_key.buf);
return (0);
(void) fprintf(el->el_errfile, " \"" FSTR "...\"\n",
el->el_keymacro.buf);
return 0;
}
if (ptr == NULL) {
#ifdef DEBUG_EDIT
(void) fprintf(el->el_errfile,
"node_enum: BUG!! Null ptr passed\n!");
#endif
return (-1);
return -1;
}
/* put this char at end of str */
ncnt = key__decode_char(el->el_key.buf, (size_t)KEY_BUFSIZ, cnt,
(unsigned char)ptr->ch);
used = ct_visual_char(el->el_keymacro.buf + cnt, KEY_BUFSIZ - cnt,
ptr->ch);
if (ptr->next == NULL) {
/* print this key and function */
el->el_key.buf[ncnt + 1] = '"';
el->el_key.buf[ncnt + 2] = '\0';
key_kprint(el, el->el_key.buf, &ptr->val, ptr->type);
el->el_keymacro.buf[cnt + (size_t)used ] = '"';
el->el_keymacro.buf[cnt + (size_t)used + 1] = '\0';
keymacro_kprint(el, el->el_keymacro.buf, &ptr->val, ptr->type);
} else
(void) node_enum(el, ptr->next, ncnt + 1);
(void) node_enum(el, ptr->next, cnt + (size_t)used);
/* go to sibling if there is one */
if (ptr->sibling)
(void) node_enum(el, ptr->sibling, cnt);
return (0);
return 0;
}
/* key_kprint():
/* keymacro_kprint():
* Print the specified key and its associated
* function specified by val
*/
protected void
key_kprint(EditLine *el, const char *key, key_value_t *val, int ntype)
keymacro_kprint(EditLine *el, const Char *key, keymacro_value_t *val, int ntype)
{
el_bindings_t *fp;
char unparsbuf[EL_BUFSIZ];
@ -580,16 +595,19 @@ key_kprint(EditLine *el, const char *key, key_value_t *val, int ntype)
switch (ntype) {
case XK_STR:
case XK_EXE:
(void) key__decode_str(val->str, unparsbuf,
(void) keymacro__decode_str(val->str, unparsbuf,
sizeof(unparsbuf),
ntype == XK_STR ? "\"\"" : "[]");
(void) fprintf(el->el_outfile, fmt, key, unparsbuf);
(void) fprintf(el->el_outfile, fmt,
ct_encode_string(key, &el->el_scratch), unparsbuf);
break;
case XK_CMD:
for (fp = el->el_map.help; fp->name; fp++)
if (val->cmd == fp->func) {
ct_wcstombs(unparsbuf, fp->name, sizeof(unparsbuf));
unparsbuf[sizeof(unparsbuf) -1] = '\0';
(void) fprintf(el->el_outfile, fmt,
key, fp->name);
ct_encode_string(key, &el->el_scratch), unparsbuf);
break;
}
#ifdef DEBUG_KEY
@ -604,7 +622,8 @@ key_kprint(EditLine *el, const char *key, key_value_t *val, int ntype)
break;
}
else
(void) fprintf(el->el_outfile, fmt, key, "no input");
(void) fprintf(el->el_outfile, fmt, ct_encode_string(key,
&el->el_scratch), "no input");
}
@ -613,54 +632,14 @@ key_kprint(EditLine *el, const char *key, key_value_t *val, int ntype)
*b++ = c; \
else \
b++
/* key__decode_char():
* Put a printable form of char in buf.
*/
protected size_t
key__decode_char(char *buf, size_t cnt, size_t off, int ch)
{
char *sb = buf + off;
char *eb = buf + cnt;
char *b = sb;
ch = (unsigned char)ch;
if (ch == 0) {
ADDC('^');
ADDC('@');
return (int)(b - sb);
}
if (iscntrl(ch)) {
ADDC('^');
if (ch == '\177')
ADDC('?');
else
ADDC(toascii(ch) | 0100);
} else if (ch == '^') {
ADDC('\\');
ADDC('^');
} else if (ch == '\\') {
ADDC('\\');
ADDC('\\');
} else if (ch == ' ' || (isprint(ch) && !isspace(ch))) {
ADDC(ch);
} else {
ADDC('\\');
ADDC((((unsigned int) ch >> 6) & 7) + '0');
ADDC((((unsigned int) ch >> 3) & 7) + '0');
ADDC((ch & 7) + '0');
}
return (size_t)(b - sb);
}
/* key__decode_str():
/* keymacro__decode_str():
* Make a printable version of the ey
*/
protected size_t
key__decode_str(const char *str, char *buf, size_t len, const char *sep)
keymacro__decode_str(const Char *str, char *buf, size_t len, const char *sep)
{
char *b = buf, *eb = b + len;
const char *p;
const Char *p;
b = buf;
if (sep[0] != '\0') {
@ -669,36 +648,24 @@ key__decode_str(const char *str, char *buf, size_t len, const char *sep)
if (*str == '\0') {
ADDC('^');
ADDC('@');
if (sep[0] != '\0' && sep[1] != '\0') {
ADDC(sep[1]);
}
goto done;
goto add_endsep;
}
for (p = str; *p != 0; p++) {
if (iscntrl((unsigned char) *p)) {
ADDC('^');
if (*p == '\177') {
ADDC('?');
} else {
ADDC(toascii(*p) | 0100);
}
} else if (*p == '^' || *p == '\\') {
ADDC('\\');
ADDC(*p);
} else if (*p == ' ' || (isprint((unsigned char) *p) &&
!isspace((unsigned char) *p))) {
ADDC(*p);
} else {
ADDC('\\');
ADDC((((unsigned int) *p >> 6) & 7) + '0');
ADDC((((unsigned int) *p >> 3) & 7) + '0');
ADDC((*p & 7) + '0');
Char dbuf[VISUAL_WIDTH_MAX];
Char *p2 = dbuf;
ssize_t l = ct_visual_char(dbuf, VISUAL_WIDTH_MAX, *p);
while (l-- > 0) {
ssize_t n = ct_encode_char(b, (size_t)(eb - b), *p2++);
if (n == -1) /* ran out of space */
goto add_endsep;
else
b += n;
}
}
add_endsep:
if (sep[0] != '\0' && sep[1] != '\0') {
ADDC(sep[1]);
}
done:
ADDC('\0');
if ((size_t)(b - buf) >= len)
buf[len - 1] = '\0';

View File

@ -1,3 +1,5 @@
/* $NetBSD: keymacro.h,v 1.2 2011/07/28 03:44:36 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
@ -30,54 +32,46 @@
* SUCH DAMAGE.
*
* @(#)key.h 8.1 (Berkeley) 6/4/93
* $NetBSD: key.h,v 1.10 2006/03/23 20:22:51 christos Exp $
* $FreeBSD$
*/
/*
* el.key.h: Key macro header
* el.keymacro.h: Key macro header
*/
#ifndef _h_el_key
#define _h_el_key
#ifndef _h_el_keymacro
#define _h_el_keymacro
typedef union key_value_t {
typedef union keymacro_value_t {
el_action_t cmd; /* If it is a command the # */
char *str; /* If it is a string... */
} key_value_t;
Char *str; /* If it is a string... */
} keymacro_value_t;
typedef struct key_node_t key_node_t;
typedef struct keymacro_node_t keymacro_node_t;
typedef struct el_key_t {
char *buf; /* Key print buffer */
key_node_t *map; /* Key map */
key_value_t val; /* Local conversion buffer */
} el_key_t;
typedef struct el_keymacromacro_t {
Char *buf; /* Key print buffer */
keymacro_node_t *map; /* Key map */
keymacro_value_t val; /* Local conversion buffer */
} el_keymacro_t;
#define XK_CMD 0
#define XK_STR 1
#define XK_NOD 2
#define XK_EXE 3
#include <term.h>
#undef key_end
#undef key_clear
#undef key_print
protected int key_init(EditLine *);
protected void key_end(EditLine *);
protected key_value_t *key_map_cmd(EditLine *, int);
protected key_value_t *key_map_str(EditLine *, char *);
protected void key_reset(EditLine *);
protected int key_get(EditLine *, char *, key_value_t *);
protected void key_add(EditLine *, const char *, key_value_t *, int);
protected void key_clear(EditLine *, el_action_t *, const char *);
protected int key_delete(EditLine *, const char *);
protected void key_print(EditLine *, const char *);
protected void key_kprint(EditLine *, const char *, key_value_t *,
protected int keymacro_init(EditLine *);
protected void keymacro_end(EditLine *);
protected keymacro_value_t *keymacro_map_cmd(EditLine *, int);
protected keymacro_value_t *keymacro_map_str(EditLine *, Char *);
protected void keymacro_reset(EditLine *);
protected int keymacro_get(EditLine *, Char *, keymacro_value_t *);
protected void keymacro_add(EditLine *, const Char *, keymacro_value_t *, int);
protected void keymacro_clear(EditLine *, el_action_t *, const Char *);
protected int keymacro_delete(EditLine *, const Char *);
protected void keymacro_print(EditLine *, const Char *);
protected void keymacro_kprint(EditLine *, const Char *, keymacro_value_t *,
int);
protected size_t key__decode_str(const char *, char *, size_t,
protected size_t keymacro__decode_str(const Char *, char *, size_t,
const char *);
protected size_t key__decode_char(char *, size_t, size_t, int);
#endif /* _h_el_key */
#endif /* _h_el_keymacro */

View File

@ -1,6 +1,6 @@
#!/bin/sh -
# $NetBSD: makelist,v 1.11 2005/10/22 16:45:03 christos Exp $
# $FreeBSD$
# $NetBSD: makelist,v 1.18 2012/03/21 05:34:54 matt Exp $
#
# Copyright (c) 1992, 1993
# The Regents of the University of California. All rights reserved.
@ -37,7 +37,7 @@
# makelist.sh: Automatically generate header files...
AWK=awk
USAGE="usage: $0 -h|-e|-fc|-fh|-bc|-bh|-m <filenames>"
USAGE="Usage: $0 -n|-h|-e|-fc|-fh|-bc|-bh|-m <filenames>"
if [ "x$1" = "x" ]
then
@ -54,6 +54,15 @@ case $FLAG in
# generate foo.h file from foo.c
#
-n)
cat << _EOF
#include "config.h"
#undef WIDECHAR
#define NARROWCHAR
#include "${FILES}"
_EOF
;;
-h)
set - `echo $FILES | sed -e 's/\\./_/g'`
hdr="_h_`basename $1`"
@ -70,7 +79,7 @@ case $FLAG in
# XXX: need a space between name and prototype so that -fc and -fh
# parsing is much easier
#
printf("protected el_action_t\t%s (EditLine *, int);\n", name);
printf("protected el_action_t\t%s (EditLine *, Int);\n", name);
}
}
END {
@ -84,7 +93,8 @@ case $FLAG in
cat $FILES | $AWK '
BEGIN {
printf("/* Automatically generated file, do not edit */\n");
printf("#include \"sys.h\"\n#include \"el.h\"\n");
printf("#include \"config.h\"\n#include \"el.h\"\n");
printf("#include \"chartype.h\"\n");
printf("private const struct el_bindings_t el_func_help[] = {\n");
low = "abcdefghijklmnopqrstuvwxyz_";
high = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_";
@ -105,22 +115,22 @@ case $FLAG in
fname = fname s;
}
printf(" { %-30.30s %-30.30s\n","\"" fname "\",", uname ",");
printf(" { %-30.30s %-30.30s\n","STR(\"" fname "\"),", uname ",");
ok = 1;
}
}
/^ \*/ {
if (ok) {
printf(" \"");
printf(" STR(\"");
for (i = 2; i < NF; i++)
printf("%s ", $i);
printf("%s\" },\n", $i);
printf("%s\") },\n", $i);
ok = 0;
}
}
END {
printf("};\n");
printf("\nprotected const el_bindings_t* help__get()");
printf("\nprotected const el_bindings_t* help__get(void)");
printf("{ return el_func_help; }\n");
}'
;;
@ -141,7 +151,7 @@ case $FLAG in
#
-fh)
cat $FILES | $AWK '/el_action_t/ { print $3 }' | \
sort | LC_ALL=C tr '[:lower:]' '[:upper:]' | $AWK '
sort | tr '[:lower:]' '[:upper:]' | $AWK '
BEGIN {
printf("/* Automatically generated file, do not edit */\n");
printf("#ifndef _h_fcns_c\n#define _h_fcns_c\n");
@ -153,7 +163,7 @@ case $FLAG in
END {
printf("#define\t%-30.30s\t%3d\n", "EL_NUM_FCNS", count);
printf("typedef el_action_t (*el_func_t)(EditLine *, int);");
printf("typedef el_action_t (*el_func_t)(EditLine *, Int);");
printf("\nprotected const el_func_t* func__get(void);\n");
printf("#endif /* _h_fcns_c */\n");
}'
@ -165,7 +175,7 @@ case $FLAG in
cat $FILES | $AWK '/el_action_t/ { print $3 }' | sort | $AWK '
BEGIN {
printf("/* Automatically generated file, do not edit */\n");
printf("#include \"sys.h\"\n#include \"el.h\"\n");
printf("#include \"config.h\"\n#include \"el.h\"\n");
printf("private const el_func_t el_func[] = {");
maxlen = 80;
needn = 1;
@ -186,7 +196,7 @@ case $FLAG in
}
END {
printf("\n};\n");
printf("\nprotected const el_func_t* func__get() { return el_func; }\n");
printf("\nprotected const el_func_t* func__get(void) { return el_func; }\n");
}'
;;

View File

@ -1,3 +1,5 @@
/* $NetBSD: map.c,v 1.34 2014/07/06 18:15:34 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
@ -28,12 +30,15 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $NetBSD: map.c,v 1.24 2006/04/09 01:36:51 christos Exp $
*/
#include "config.h"
#if !defined(lint) && !defined(SCCSID)
#if 0
static char sccsid[] = "@(#)map.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: map.c,v 1.34 2014/07/06 18:15:34 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@ -41,14 +46,11 @@ __FBSDID("$FreeBSD$");
/*
* map.c: Editor function definitions
*/
#include "sys.h"
#include <stdlib.h>
#include "el.h"
#define N_KEYS 256
private void map_print_key(EditLine *, el_action_t *, const char *);
private void map_print_some_keys(EditLine *, el_action_t *, int, int);
private void map_print_key(EditLine *, el_action_t *, const Char *);
private void map_print_some_keys(EditLine *, el_action_t *, Int, Int);
private void map_print_all_keys(EditLine *);
private void map_init_nls(EditLine *);
private void map_init_meta(EditLine *);
@ -903,26 +905,25 @@ map_init(EditLine *el)
EL_ABORT((el->errfile, "Vi insert map incorrect\n"));
#endif
el->el_map.alt = (el_action_t *)el_malloc(sizeof(el_action_t) * N_KEYS);
el->el_map.alt = el_malloc(sizeof(*el->el_map.alt) * N_KEYS);
if (el->el_map.alt == NULL)
return (-1);
el->el_map.key = (el_action_t *)el_malloc(sizeof(el_action_t) * N_KEYS);
return -1;
el->el_map.key = el_malloc(sizeof(*el->el_map.key) * N_KEYS);
if (el->el_map.key == NULL)
return (-1);
return -1;
el->el_map.emacs = el_map_emacs;
el->el_map.vic = el_map_vi_command;
el->el_map.vii = el_map_vi_insert;
el->el_map.help = (el_bindings_t *) el_malloc(sizeof(el_bindings_t) *
EL_NUM_FCNS);
el->el_map.help = el_malloc(sizeof(*el->el_map.help) * EL_NUM_FCNS);
if (el->el_map.help == NULL)
return (-1);
return -1;
(void) memcpy(el->el_map.help, help__get(),
sizeof(el_bindings_t) * EL_NUM_FCNS);
el->el_map.func = (el_func_t *)el_malloc(sizeof(el_func_t) *
EL_NUM_FCNS);
sizeof(*el->el_map.help) * EL_NUM_FCNS);
el->el_map.func = el_malloc(sizeof(*el->el_map.func) * EL_NUM_FCNS);
if (el->el_map.func == NULL)
return (-1);
memcpy(el->el_map.func, func__get(), sizeof(el_func_t) * EL_NUM_FCNS);
return -1;
memcpy(el->el_map.func, func__get(), sizeof(*el->el_map.func)
* EL_NUM_FCNS);
el->el_map.nfunc = EL_NUM_FCNS;
#ifdef VIDEFAULT
@ -930,7 +931,7 @@ map_init(EditLine *el)
#else
map_init_emacs(el);
#endif /* VIDEFAULT */
return (0);
return 0;
}
@ -941,16 +942,16 @@ protected void
map_end(EditLine *el)
{
el_free((ptr_t) el->el_map.alt);
el_free(el->el_map.alt);
el->el_map.alt = NULL;
el_free((ptr_t) el->el_map.key);
el_free(el->el_map.key);
el->el_map.key = NULL;
el->el_map.emacs = NULL;
el->el_map.vic = NULL;
el->el_map.vii = NULL;
el_free((ptr_t) el->el_map.help);
el_free(el->el_map.help);
el->el_map.help = NULL;
el_free((ptr_t) el->el_map.func);
el_free(el->el_map.func);
el->el_map.func = NULL;
}
@ -966,7 +967,7 @@ map_init_nls(EditLine *el)
el_action_t *map = el->el_map.key;
for (i = 0200; i <= 0377; i++)
if (isprint(i))
if (Isprint(i))
map[i] = ED_INSERT;
}
@ -977,7 +978,7 @@ map_init_nls(EditLine *el)
private void
map_init_meta(EditLine *el)
{
char buf[3];
Char buf[3];
int i;
el_action_t *map = el->el_map.key;
el_action_t *alt = el->el_map.alt;
@ -995,7 +996,7 @@ map_init_meta(EditLine *el)
} else
map = alt;
}
buf[0] = (char) i;
buf[0] = (Char) i;
buf[2] = 0;
for (i = 0200; i <= 0377; i++)
switch (map[i]) {
@ -1005,7 +1006,7 @@ map_init_meta(EditLine *el)
break;
default:
buf[1] = i & 0177;
key_add(el, buf, key_map_cmd(el, (int) map[i]), XK_CMD);
keymacro_add(el, buf, keymacro_map_cmd(el, (int) map[i]), XK_CMD);
break;
}
map[(int) buf[0]] = ED_SEQUENCE_LEAD_IN;
@ -1027,7 +1028,7 @@ map_init_vi(EditLine *el)
el->el_map.type = MAP_VI;
el->el_map.current = el->el_map.key;
key_reset(el);
keymacro_reset(el);
for (i = 0; i < N_KEYS; i++) {
key[i] = vii[i];
@ -1038,7 +1039,7 @@ map_init_vi(EditLine *el)
map_init_nls(el);
tty_bind_char(el, 1);
term_bind_arrow(el);
terminal_bind_arrow(el);
}
@ -1049,14 +1050,14 @@ protected void
map_init_emacs(EditLine *el)
{
int i;
char buf[3];
Char buf[3];
el_action_t *key = el->el_map.key;
el_action_t *alt = el->el_map.alt;
const el_action_t *emacs = el->el_map.emacs;
el->el_map.type = MAP_EMACS;
el->el_map.current = el->el_map.key;
key_reset(el);
keymacro_reset(el);
for (i = 0; i < N_KEYS; i++) {
key[i] = emacs[i];
@ -1069,10 +1070,10 @@ map_init_emacs(EditLine *el)
buf[0] = CONTROL('X');
buf[1] = CONTROL('X');
buf[2] = 0;
key_add(el, buf, key_map_cmd(el, EM_EXCHANGE_MARK), XK_CMD);
keymacro_add(el, buf, keymacro_map_cmd(el, EM_EXCHANGE_MARK), XK_CMD);
tty_bind_char(el, 1);
term_bind_arrow(el);
terminal_bind_arrow(el);
}
@ -1080,18 +1081,18 @@ map_init_emacs(EditLine *el)
* Set the editor
*/
protected int
map_set_editor(EditLine *el, char *editor)
map_set_editor(EditLine *el, Char *editor)
{
if (strcmp(editor, "emacs") == 0) {
if (Strcmp(editor, STR("emacs")) == 0) {
map_init_emacs(el);
return (0);
return 0;
}
if (strcmp(editor, "vi") == 0) {
if (Strcmp(editor, STR("vi")) == 0) {
map_init_vi(el);
return (0);
return 0;
}
return (-1);
return -1;
}
@ -1099,20 +1100,20 @@ map_set_editor(EditLine *el, char *editor)
* Retrieve the editor
*/
protected int
map_get_editor(EditLine *el, const char **editor)
map_get_editor(EditLine *el, const Char **editor)
{
if (editor == NULL)
return (-1);
return -1;
switch (el->el_map.type) {
case MAP_EMACS:
*editor = "emacs";
return (0);
*editor = STR("emacs");
return 0;
case MAP_VI:
*editor = "vi";
return (0);
*editor = STR("vi");
return 0;
}
return (-1);
return -1;
}
@ -1120,22 +1121,22 @@ map_get_editor(EditLine *el, const char **editor)
* Print the function description for 1 key
*/
private void
map_print_key(EditLine *el, el_action_t *map, const char *in)
map_print_key(EditLine *el, el_action_t *map, const Char *in)
{
char outbuf[EL_BUFSIZ];
el_bindings_t *bp, *ep;
if (in[0] == '\0' || in[1] == '\0') {
(void) key__decode_str(in, outbuf, sizeof(outbuf), "");
(void) keymacro__decode_str(in, outbuf, sizeof(outbuf), "");
ep = &el->el_map.help[el->el_map.nfunc];
for (bp = el->el_map.help; bp < ep; bp++)
if (bp->func == map[(unsigned char) *in]) {
(void) fprintf(el->el_outfile,
"%s\t->\t%s\n", outbuf, bp->name);
"%s\t->\t" FSTR "\n", outbuf, bp->name);
return;
}
} else
key_print(el, in);
keymacro_print(el, in);
}
@ -1143,10 +1144,10 @@ map_print_key(EditLine *el, el_action_t *map, const char *in)
* Print keys from first to last
*/
private void
map_print_some_keys(EditLine *el, el_action_t *map, int first, int last)
map_print_some_keys(EditLine *el, el_action_t *map, Int first, Int last)
{
el_bindings_t *bp, *ep;
char firstbuf[2], lastbuf[2];
Char firstbuf[2], lastbuf[2];
char unparsbuf[EL_BUFSIZ], extrabuf[EL_BUFSIZ];
firstbuf[0] = first;
@ -1155,7 +1156,7 @@ map_print_some_keys(EditLine *el, el_action_t *map, int first, int last)
lastbuf[1] = 0;
if (map[first] == ED_UNASSIGNED) {
if (first == last) {
(void) key__decode_str(firstbuf, unparsbuf,
(void) keymacro__decode_str(firstbuf, unparsbuf,
sizeof(unparsbuf), STRQQ);
(void) fprintf(el->el_outfile,
"%-15s-> is undefined\n", unparsbuf);
@ -1166,17 +1167,17 @@ map_print_some_keys(EditLine *el, el_action_t *map, int first, int last)
for (bp = el->el_map.help; bp < ep; bp++) {
if (bp->func == map[first]) {
if (first == last) {
(void) key__decode_str(firstbuf, unparsbuf,
(void) keymacro__decode_str(firstbuf, unparsbuf,
sizeof(unparsbuf), STRQQ);
(void) fprintf(el->el_outfile, "%-15s-> %s\n",
(void) fprintf(el->el_outfile, "%-15s-> " FSTR "\n",
unparsbuf, bp->name);
} else {
(void) key__decode_str(firstbuf, unparsbuf,
(void) keymacro__decode_str(firstbuf, unparsbuf,
sizeof(unparsbuf), STRQQ);
(void) key__decode_str(lastbuf, extrabuf,
(void) keymacro__decode_str(lastbuf, extrabuf,
sizeof(extrabuf), STRQQ);
(void) fprintf(el->el_outfile,
"%-4s to %-7s-> %s\n",
"%-4s to %-7s-> " FSTR "\n",
unparsbuf, extrabuf, bp->name);
}
return;
@ -1184,14 +1185,14 @@ map_print_some_keys(EditLine *el, el_action_t *map, int first, int last)
}
#ifdef MAP_DEBUG
if (map == el->el_map.key) {
(void) key__decode_str(firstbuf, unparsbuf,
(void) keymacro__decode_str(firstbuf, unparsbuf,
sizeof(unparsbuf), STRQQ);
(void) fprintf(el->el_outfile,
"BUG!!! %s isn't bound to anything.\n", unparsbuf);
(void) fprintf(el->el_outfile, "el->el_map.key[%d] == %d\n",
first, el->el_map.key[first]);
} else {
(void) key__decode_str(firstbuf, unparsbuf,
(void) keymacro__decode_str(firstbuf, unparsbuf,
sizeof(unparsbuf), STRQQ);
(void) fprintf(el->el_outfile,
"BUG!!! %s isn't bound to anything.\n", unparsbuf);
@ -1232,9 +1233,9 @@ map_print_all_keys(EditLine *el)
map_print_some_keys(el, el->el_map.alt, prev, i - 1);
(void) fprintf(el->el_outfile, "Multi-character bindings\n");
key_print(el, "");
keymacro_print(el, STR(""));
(void) fprintf(el->el_outfile, "Arrow key bindings\n");
term_print_arrow(el, "");
terminal_print_arrow(el, STR(""));
}
@ -1242,21 +1243,21 @@ map_print_all_keys(EditLine *el)
* Add/remove/change bindings
*/
protected int
map_bind(EditLine *el, int argc, const char **argv)
map_bind(EditLine *el, int argc, const Char **argv)
{
el_action_t *map;
int ntype, rem;
const char *p;
char inbuf[EL_BUFSIZ];
char outbuf[EL_BUFSIZ];
const char *in = NULL;
char *out;
const Char *p;
Char inbuf[EL_BUFSIZ];
Char outbuf[EL_BUFSIZ];
const Char *in = NULL;
Char *out;
el_bindings_t *bp, *ep;
int cmd;
int key;
if (argv == NULL)
return (-1);
return -1;
map = el->el_map.key;
ntype = XK_CMD;
@ -1286,22 +1287,22 @@ map_bind(EditLine *el, int argc, const char **argv)
case 'v':
map_init_vi(el);
return (0);
return 0;
case 'e':
map_init_emacs(el);
return (0);
return 0;
case 'l':
ep = &el->el_map.help[el->el_map.nfunc];
for (bp = el->el_map.help; bp < ep; bp++)
(void) fprintf(el->el_outfile,
"%s\n\t%s\n",
"" FSTR "\n\t" FSTR "\n",
bp->name, bp->description);
return (0);
return 0;
default:
(void) fprintf(el->el_errfile,
"%s: Invalid switch `%c'.\n",
"" FSTR ": Invalid switch `%c'.\n",
argv[0], p[1]);
}
else
@ -1309,40 +1310,40 @@ map_bind(EditLine *el, int argc, const char **argv)
if (argv[argc] == NULL) {
map_print_all_keys(el);
return (0);
return 0;
}
if (key)
in = argv[argc++];
else if ((in = parse__string(inbuf, argv[argc++])) == NULL) {
(void) fprintf(el->el_errfile,
"%s: Invalid \\ or ^ in instring.\n",
"" FSTR ": Invalid \\ or ^ in instring.\n",
argv[0]);
return (-1);
return -1;
}
if (rem) {
if (key) {
(void) term_clear_arrow(el, in);
return (-1);
(void) terminal_clear_arrow(el, in);
return -1;
}
if (in[1])
(void) key_delete(el, in);
(void) keymacro_delete(el, in);
else if (map[(unsigned char) *in] == ED_SEQUENCE_LEAD_IN)
(void) key_delete(el, in);
(void) keymacro_delete(el, in);
else
map[(unsigned char) *in] = ED_UNASSIGNED;
return (0);
return 0;
}
if (argv[argc] == NULL) {
if (key)
term_print_arrow(el, in);
terminal_print_arrow(el, in);
else
map_print_key(el, map, in);
return (0);
return 0;
}
#ifdef notyet
if (argv[argc + 1] != NULL) {
bindkey_usage();
return (-1);
bindkeymacro_usage();
return -1;
}
#endif
@ -1351,40 +1352,42 @@ map_bind(EditLine *el, int argc, const char **argv)
case XK_EXE:
if ((out = parse__string(outbuf, argv[argc])) == NULL) {
(void) fprintf(el->el_errfile,
"%s: Invalid \\ or ^ in outstring.\n", argv[0]);
return (-1);
"" FSTR ": Invalid \\ or ^ in outstring.\n", argv[0]);
return -1;
}
if (key)
term_set_arrow(el, in, key_map_str(el, out), ntype);
terminal_set_arrow(el, in, keymacro_map_str(el, out), ntype);
else
key_add(el, in, key_map_str(el, out), ntype);
keymacro_add(el, in, keymacro_map_str(el, out), ntype);
map[(unsigned char) *in] = ED_SEQUENCE_LEAD_IN;
break;
case XK_CMD:
if ((cmd = parse_cmd(el, argv[argc])) == -1) {
(void) fprintf(el->el_errfile,
"%s: Invalid command `%s'.\n", argv[0], argv[argc]);
return (-1);
"" FSTR ": Invalid command `" FSTR "'.\n",
argv[0], argv[argc]);
return -1;
}
if (key)
term_set_arrow(el, in, key_map_cmd(el, cmd), ntype);
terminal_set_arrow(el, in, keymacro_map_cmd(el, cmd), ntype);
else {
if (in[1]) {
key_add(el, in, key_map_cmd(el, cmd), ntype);
keymacro_add(el, in, keymacro_map_cmd(el, cmd), ntype);
map[(unsigned char) *in] = ED_SEQUENCE_LEAD_IN;
} else {
key_clear(el, map, in);
map[(unsigned char) *in] = cmd;
keymacro_clear(el, map, in);
map[(unsigned char) *in] = (el_action_t)cmd;
}
}
break;
/* coverity[dead_error_begin] */
default:
EL_ABORT((el->el_errfile, "Bad XK_ type %d\n", ntype));
break;
}
return (0);
return 0;
}
@ -1392,29 +1395,30 @@ map_bind(EditLine *el, int argc, const char **argv)
* add a user defined function
*/
protected int
map_addfunc(EditLine *el, const char *name, const char *help, el_func_t func)
map_addfunc(EditLine *el, const Char *name, const Char *help, el_func_t func)
{
void *p;
int nf = el->el_map.nfunc + 1;
size_t nf = el->el_map.nfunc + 1;
if (name == NULL || help == NULL || func == NULL)
return (-1);
return -1;
if ((p = el_realloc(el->el_map.func, nf * sizeof(el_func_t))) == NULL)
return (-1);
el->el_map.func = (el_func_t *) p;
if ((p = el_realloc(el->el_map.help, nf * sizeof(el_bindings_t)))
if ((p = el_realloc(el->el_map.func, nf *
sizeof(*el->el_map.func))) == NULL)
return -1;
el->el_map.func = p;
if ((p = el_realloc(el->el_map.help, nf * sizeof(*el->el_map.help)))
== NULL)
return (-1);
el->el_map.help = (el_bindings_t *) p;
return -1;
el->el_map.help = p;
nf = el->el_map.nfunc;
nf = (size_t)el->el_map.nfunc;
el->el_map.func[nf] = func;
el->el_map.help[nf].name = name;
el->el_map.help[nf].func = nf;
el->el_map.help[nf].func = (int)nf;
el->el_map.help[nf].description = help;
el->el_map.nfunc++;
return (0);
return 0;
}

View File

@ -1,3 +1,5 @@
/* $NetBSD: map.h,v 1.10 2014/07/06 18:15:34 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
@ -30,7 +32,6 @@
* SUCH DAMAGE.
*
* @(#)map.h 8.1 (Berkeley) 6/4/93
* $NetBSD: map.h,v 1.8 2003/08/07 16:44:32 agc Exp $
* $FreeBSD$
*/
@ -41,9 +42,9 @@
#define _h_el_map
typedef struct el_bindings_t { /* for the "bind" shell command */
const char *name; /* function name for bind command */
const Char *name; /* function name for bind command */
int func; /* function numeric value */
const char *description; /* description of function */
const Char *description; /* description of function */
} el_bindings_t;
@ -57,19 +58,21 @@ typedef struct el_map_t {
int type; /* Emacs or vi */
el_bindings_t *help; /* The help for the editor functions */
el_func_t *func; /* List of available functions */
int nfunc; /* The number of functions/help items */
size_t nfunc; /* The number of functions/help items */
} el_map_t;
#define MAP_EMACS 0
#define MAP_VI 1
protected int map_bind(EditLine *, int, const char **);
#define N_KEYS 256
protected int map_bind(EditLine *, int, const Char **);
protected int map_init(EditLine *);
protected void map_end(EditLine *);
protected void map_init_vi(EditLine *);
protected void map_init_emacs(EditLine *);
protected int map_set_editor(EditLine *, char *);
protected int map_get_editor(EditLine *, const char **);
protected int map_addfunc(EditLine *, const char *, const char *, el_func_t);
protected int map_set_editor(EditLine *, Char *);
protected int map_get_editor(EditLine *, const Char **);
protected int map_addfunc(EditLine *, const Char *, const Char *, el_func_t);
#endif /* _h_el_map */

View File

@ -1,3 +1,5 @@
/* $NetBSD: parse.c,v 1.27 2014/07/06 18:15:34 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
@ -28,12 +30,15 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $NetBSD: parse.c,v 1.22 2005/05/29 04:58:15 lukem Exp $
*/
#include "config.h"
#if !defined(lint) && !defined(SCCSID)
#if 0
static char sccsid[] = "@(#)parse.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: parse.c,v 1.27 2014/07/06 18:15:34 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@ -51,22 +56,21 @@ __FBSDID("$FreeBSD$");
* settc
* setty
*/
#include "sys.h"
#include "el.h"
#include <stdlib.h>
private const struct {
const char *name;
int (*func)(EditLine *, int, const char **);
const Char *name;
int (*func)(EditLine *, int, const Char **);
} cmds[] = {
{ "bind", map_bind },
{ "echotc", term_echotc },
{ "edit", el_editmode },
{ "history", hist_command },
{ "telltc", term_telltc },
{ "settc", term_settc },
{ "setty", tty_stty },
{ NULL, NULL }
{ STR("bind"), map_bind },
{ STR("echotc"), terminal_echotc },
{ STR("edit"), el_editmode },
{ STR("history"), hist_command },
{ STR("telltc"), terminal_telltc },
{ STR("settc"), terminal_settc },
{ STR("setty"), tty_stty },
{ NULL, NULL }
};
@ -74,17 +78,17 @@ private const struct {
* Parse a line and dispatch it
*/
protected int
parse_line(EditLine *el, const char *line)
parse_line(EditLine *el, const Char *line)
{
const char **argv;
const Char **argv;
int argc;
Tokenizer *tok;
TYPE(Tokenizer) *tok;
tok = tok_init(NULL);
tok_str(tok, line, &argc, &argv);
argc = el_parse(el, argc, argv);
tok_end(tok);
return (argc);
tok = FUN(tok,init)(NULL);
FUN(tok,str)(tok, line, &argc, &argv);
argc = FUN(el,parse)(el, argc, argv);
FUN(tok,end)(tok);
return argc;
}
@ -92,57 +96,57 @@ parse_line(EditLine *el, const char *line)
* Command dispatcher
*/
public int
el_parse(EditLine *el, int argc, const char *argv[])
FUN(el,parse)(EditLine *el, int argc, const Char *argv[])
{
const char *ptr;
const Char *ptr;
int i;
if (argc < 1)
return (-1);
ptr = strchr(argv[0], ':');
return -1;
ptr = Strchr(argv[0], ':');
if (ptr != NULL) {
char *tprog;
Char *tprog;
size_t l;
if (ptr == argv[0])
return (0);
l = ptr - argv[0] - 1;
tprog = (char *) el_malloc(l + 1);
return 0;
l = (size_t)(ptr - argv[0] - 1);
tprog = el_malloc((l + 1) * sizeof(*tprog));
if (tprog == NULL)
return (0);
(void) strncpy(tprog, argv[0], l);
return 0;
(void) Strncpy(tprog, argv[0], l);
tprog[l] = '\0';
ptr++;
l = el_match(el->el_prog, tprog);
l = (size_t)el_match(el->el_prog, tprog);
el_free(tprog);
if (!l)
return (0);
return 0;
} else
ptr = argv[0];
for (i = 0; cmds[i].name != NULL; i++)
if (strcmp(cmds[i].name, ptr) == 0) {
if (Strcmp(cmds[i].name, ptr) == 0) {
i = (*cmds[i].func) (el, argc, argv);
return (-i);
return -i;
}
return (-1);
return -1;
}
/* parse__escape():
* Parse a string of the form ^<char> \<odigit> \<char> and return
* Parse a string of the form ^<char> \<odigit> \<char> \U+xxxx and return
* the appropriate character or -1 if the escape is not valid
*/
protected int
parse__escape(const char **ptr)
parse__escape(const Char **ptr)
{
const char *p;
int c;
const Char *p;
Int c;
p = *ptr;
if (p[1] == 0)
return (-1);
return -1;
if (*p == '\\') {
p++;
@ -171,6 +175,28 @@ parse__escape(const char **ptr)
case 'e':
c = '\033'; /* Escape */
break;
case 'U': /* Unicode \U+xxxx or \U+xxxxx format */
{
int i;
const Char hex[] = STR("0123456789ABCDEF");
const Char *h;
++p;
if (*p++ != '+')
return -1;
c = 0;
for (i = 0; i < 5; ++i) {
h = Strchr(hex, *p++);
if (!h && i < 4)
return -1;
else if (h)
c = (c << 4) | ((int)(h - hex));
else
--p;
}
if (c > 0x10FFFF) /* outside valid character range */
return -1;
break;
}
case '0':
case '1':
case '2':
@ -190,8 +216,8 @@ parse__escape(const char **ptr)
}
c = (c << 3) | (ch - '0');
}
if ((c & 0xffffff00) != 0)
return (-1);
if ((c & (wint_t)0xffffff00) != (wint_t)0)
return -1;
--p;
break;
}
@ -205,28 +231,28 @@ parse__escape(const char **ptr)
} else
c = *p;
*ptr = ++p;
return ((unsigned char)c);
return c;
}
/* parse__string():
* Parse the escapes from in and put the raw string out
*/
protected char *
parse__string(char *out, const char *in)
protected Char *
parse__string(Char *out, const Char *in)
{
char *rv = out;
Char *rv = out;
int n;
for (;;)
switch (*in) {
case '\0':
*out = '\0';
return (rv);
return rv;
case '\\':
case '^':
if ((n = parse__escape(&in)) == -1)
return (NULL);
return NULL;
*out++ = n;
break;
@ -250,12 +276,13 @@ parse__string(char *out, const char *in)
* or -1 if one is not found
*/
protected int
parse_cmd(EditLine *el, const char *cmd)
parse_cmd(EditLine *el, const Char *cmd)
{
el_bindings_t *b;
el_bindings_t *b = el->el_map.help;
size_t i;
for (b = el->el_map.help; b->name != NULL; b++)
if (strcmp(b->name, cmd) == 0)
return (b->func);
return (-1);
for (i = 0; i < el->el_map.nfunc; i++)
if (Strcmp(b[i].name, cmd) == 0)
return b[i].func;
return -1;
}

View File

@ -1,3 +1,5 @@
/* $NetBSD: parse.h,v 1.7 2009/12/30 22:37:40 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
@ -30,7 +32,6 @@
* SUCH DAMAGE.
*
* @(#)parse.h 8.1 (Berkeley) 6/4/93
* $NetBSD: parse.h,v 1.6 2005/05/29 04:58:15 lukem Exp $
* $FreeBSD$
*/
@ -40,9 +41,9 @@
#ifndef _h_el_parse
#define _h_el_parse
protected int parse_line(EditLine *, const char *);
protected int parse__escape(const char **);
protected char *parse__string(char *, const char *);
protected int parse_cmd(EditLine *, const char *);
protected int parse_line(EditLine *, const Char *);
protected int parse__escape(const Char **);
protected Char *parse__string(Char *, const Char *);
protected int parse_cmd(EditLine *, const Char *);
#endif /* _h_el_parse */

View File

@ -1,3 +1,5 @@
/* $NetBSD: prompt.c,v 1.20 2011/07/29 15:16:33 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
@ -28,12 +30,15 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $NetBSD: prompt.c,v 1.14 2009/03/31 17:38:27 christos Exp $
*/
#include "config.h"
#if !defined(lint) && !defined(SCCSID)
#if 0
static char sccsid[] = "@(#)prompt.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: prompt.c,v 1.20 2011/07/29 15:16:33 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@ -41,50 +46,46 @@ __FBSDID("$FreeBSD$");
/*
* prompt.c: Prompt printing functions
*/
#include "sys.h"
#include <stdio.h>
#include "el.h"
private char *prompt_default(EditLine *);
private char *prompt_default_r(EditLine *);
private Char *prompt_default(EditLine *);
private Char *prompt_default_r(EditLine *);
/* prompt_default():
* Just a default prompt, in case the user did not provide one
*/
private char *
private Char *
/*ARGSUSED*/
prompt_default(EditLine *el __unused)
prompt_default(EditLine *el __attribute__((__unused__)))
{
static char a[3] = {'?', ' ', '\0'};
static Char a[3] = {'?', ' ', '\0'};
return (a);
return a;
}
/* prompt_default_r():
* Just a default rprompt, in case the user did not provide one
*/
private char *
private Char *
/*ARGSUSED*/
prompt_default_r(EditLine *el __unused)
prompt_default_r(EditLine *el __attribute__((__unused__)))
{
static char a[1] = {'\0'};
static Char a[1] = {'\0'};
return (a);
return a;
}
/* prompt_print():
* Print the prompt and update the prompt position.
* We use an array of integers in case we want to pass
* literal escape sequences in the prompt and we want a
* bit to flag them
*/
protected void
prompt_print(EditLine *el, int op)
{
el_prompt_t *elp;
char *p;
Char *p;
int ignore = 0;
if (op == EL_PROMPT)
@ -92,13 +93,19 @@ prompt_print(EditLine *el, int op)
else
elp = &el->el_rprompt;
for (p = (*elp->p_func)(el); *p; p++) {
if (elp->p_wide)
p = (*elp->p_func)(el);
else
p = ct_decode_string((char *)(void *)(*elp->p_func)(el),
&el->el_scratch);
for (; *p; p++) {
if (elp->p_ignore == *p) {
ignore = !ignore;
continue;
}
if (ignore)
term__putc(el, *p);
terminal__putc(el, *p);
else
re_putc(el, *p, 1);
}
@ -132,7 +139,7 @@ prompt_init(EditLine *el)
*/
protected void
/*ARGSUSED*/
prompt_end(EditLine *el __unused)
prompt_end(EditLine *el __attribute__((__unused__)))
{
}
@ -141,7 +148,7 @@ prompt_end(EditLine *el __unused)
* Install a prompt printing function
*/
protected int
prompt_set(EditLine *el, el_pfunc_t prf, char c, int op)
prompt_set(EditLine *el, el_pfunc_t prf, Char c, int op, int wide)
{
el_prompt_t *p;
@ -155,13 +162,15 @@ prompt_set(EditLine *el, el_pfunc_t prf, char c, int op)
p->p_func = prompt_default;
else
p->p_func = prompt_default_r;
} else
} else {
p->p_func = prf;
}
p->p_ignore = c;
p->p_pos.v = 0;
p->p_pos.h = 0;
p->p_wide = wide;
return 0;
}
@ -171,7 +180,7 @@ prompt_set(EditLine *el, el_pfunc_t prf, char c, int op)
* Retrieve the prompt printing function
*/
protected int
prompt_get(EditLine *el, el_pfunc_t *prf, char *c, int op)
prompt_get(EditLine *el, el_pfunc_t *prf, Char *c, int op)
{
el_prompt_t *p;
@ -183,8 +192,8 @@ prompt_get(EditLine *el, el_pfunc_t *prf, char *c, int op)
else
p = &el->el_rprompt;
*prf = el->el_rprompt.p_func;
if (prf)
*prf = p->p_func;
if (c)
*c = p->p_ignore;

View File

@ -1,3 +1,5 @@
/* $NetBSD: prompt.h,v 1.10 2009/12/30 22:37:40 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
@ -30,7 +32,6 @@
* SUCH DAMAGE.
*
* @(#)prompt.h 8.1 (Berkeley) 6/4/93
* $NetBSD: prompt.h,v 1.9 2009/03/31 17:38:27 christos Exp $
* $FreeBSD$
*/
@ -42,18 +43,18 @@
#include "histedit.h"
typedef char * (*el_pfunc_t)(EditLine*);
typedef Char *(*el_pfunc_t)(EditLine *);
typedef struct el_prompt_t {
el_pfunc_t p_func; /* Function to return the prompt */
coord_t p_pos; /* position in the line after prompt */
char p_ignore; /* character to start/end literal
*/
Char p_ignore; /* character to start/end literal */
int p_wide;
} el_prompt_t;
protected void prompt_print(EditLine *, int);
protected int prompt_set(EditLine *, el_pfunc_t, char, int);
protected int prompt_get(EditLine *, el_pfunc_t *, char *, int);
protected int prompt_set(EditLine *, el_pfunc_t, Char, int, int);
protected int prompt_get(EditLine *, el_pfunc_t *, Char *, int);
protected int prompt_init(EditLine *);
protected void prompt_end(EditLine *);

View File

@ -1,3 +1,5 @@
/* $NetBSD: read.c,v 1.71 2014/07/06 18:15:34 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
@ -28,12 +30,15 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $NetBSD: read.c,v 1.52 2009/07/22 15:57:00 christos Exp $
*/
#include "config.h"
#if !defined(lint) && !defined(SCCSID)
#if 0
static char sccsid[] = "@(#)read.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: read.c,v 1.71 2014/07/06 18:15:34 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@ -42,19 +47,19 @@ __FBSDID("$FreeBSD$");
* read.c: Clean this junk up! This is horrible code.
* Terminal read functions
*/
#include "sys.h"
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <limits.h>
#include "el.h"
#define OKCMD -1
#define OKCMD -1 /* must be -1! */
private int read__fixio(int, int);
private int read_preread(EditLine *);
private int read_char(EditLine *, char *);
private int read_getcmd(EditLine *, el_action_t *, char *);
private int read_char(EditLine *, Char *);
private int read_getcmd(EditLine *, el_action_t *, Char *);
private void read_pop(c_macro_t *);
/* read_init():
@ -88,7 +93,7 @@ el_read_setfn(EditLine *el, el_rfunc_t rc)
protected el_rfunc_t
el_read_getfn(EditLine *el)
{
return (el->el_read.read_char == read_char) ?
return el->el_read.read_char == read_char ?
EL_BUILTIN_GETCFN : el->el_read.read_char;
}
@ -121,7 +126,7 @@ read_debug(EditLine *el)
*/
/* ARGSUSED */
private int
read__fixio(int fd __unused, int e)
read__fixio(int fd __attribute__((__unused__)), int e)
{
switch (e) {
@ -130,7 +135,7 @@ read__fixio(int fd __unused, int e)
#ifdef EWOULDBLOCK
case EWOULDBLOCK:
#ifndef TRY_AGAIN
#define TRY_AGAIN
#define TRY_AGAIN
#endif
#endif /* EWOULDBLOCK */
@ -138,7 +143,7 @@ read__fixio(int fd __unused, int e)
#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
case EAGAIN:
#ifndef TRY_AGAIN
#define TRY_AGAIN
#define TRY_AGAIN
#endif
#endif /* EWOULDBLOCK && EWOULDBLOCK != EAGAIN */
#endif /* POSIX && EAGAIN */
@ -147,10 +152,10 @@ read__fixio(int fd __unused, int e)
#ifdef TRY_AGAIN
#if defined(F_SETFL) && defined(O_NDELAY)
if ((e = fcntl(fd, F_GETFL, 0)) == -1)
return (-1);
return -1;
if (fcntl(fd, F_SETFL, e & ~O_NDELAY) == -1)
return (-1);
return -1;
else
e = 1;
#endif /* F_SETFL && O_NDELAY */
@ -159,21 +164,21 @@ read__fixio(int fd __unused, int e)
{
int zero = 0;
if (ioctl(fd, FIONBIO, (ioctl_t) & zero) == -1)
return (-1);
if (ioctl(fd, FIONBIO, &zero) == -1)
return -1;
else
e = 1;
}
#endif /* FIONBIO */
#endif /* TRY_AGAIN */
return (e ? 0 : -1);
return e ? 0 : -1;
case EINTR:
return (0);
return 0;
default:
return (-1);
return -1;
}
}
@ -187,10 +192,13 @@ read_preread(EditLine *el)
int chrs = 0;
if (el->el_tty.t_mode == ED_IO)
return (0);
return 0;
#ifndef WIDECHAR
/* FIONREAD attempts to buffer up multiple bytes, and to make that work
* properly with partial wide/UTF-8 characters would need some careful work. */
#ifdef FIONREAD
(void) ioctl(el->el_infd, FIONREAD, (ioctl_t) & chrs);
(void) ioctl(el->el_infd, FIONREAD, &chrs);
if (chrs > 0) {
char buf[EL_BUFSIZ];
@ -202,8 +210,8 @@ read_preread(EditLine *el)
}
}
#endif /* FIONREAD */
return (chrs > 0);
#endif
return chrs > 0;
}
@ -211,35 +219,36 @@ read_preread(EditLine *el)
* Push a macro
*/
public void
el_push(EditLine *el, const char *str)
FUN(el,push)(EditLine *el, const Char *str)
{
c_macro_t *ma = &el->el_chared.c_macro;
if (str != NULL && ma->level + 1 < EL_MAXMACRO) {
ma->level++;
if ((ma->macro[ma->level] = el_strdup(str)) != NULL)
if ((ma->macro[ma->level] = Strdup(str)) != NULL)
return;
ma->level--;
}
term_beep(el);
term__flush(el);
terminal_beep(el);
terminal__flush(el);
}
/* read_getcmd():
* Return next command from the input stream.
* Get next command from the input stream, return OKCMD on success.
* Character values > 255 are not looked up in the map, but inserted.
*/
private int
read_getcmd(EditLine *el, el_action_t *cmdnum, char *ch)
read_getcmd(EditLine *el, el_action_t *cmdnum, Char *ch)
{
el_action_t cmd;
int num;
el->el_errno = 0;
do {
if ((num = el_getc(el, ch)) != 1) { /* if EOF or error */
if ((num = FUN(el,getc)(el, ch)) != 1) {/* if EOF or error */
el->el_errno = num == 0 ? 0 : errno;
return (num);
return 0; /* not OKCMD */
}
#ifdef KANJI
@ -254,15 +263,20 @@ read_getcmd(EditLine *el, el_action_t *cmdnum, char *ch)
el->el_state.metanext = 0;
*ch |= 0200;
}
cmd = el->el_map.current[(unsigned char) *ch];
#ifdef WIDECHAR
if (*ch >= N_KEYS)
cmd = ED_INSERT;
else
#endif
cmd = el->el_map.current[(unsigned char) *ch];
if (cmd == ED_SEQUENCE_LEAD_IN) {
key_value_t val;
switch (key_get(el, ch, &val)) {
keymacro_value_t val;
switch (keymacro_get(el, ch, &val)) {
case XK_CMD:
cmd = val.cmd;
break;
case XK_STR:
el_push(el, val.str);
FUN(el,push)(el, val.str);
break;
#ifdef notyet
case XK_EXE:
@ -279,34 +293,90 @@ read_getcmd(EditLine *el, el_action_t *cmdnum, char *ch)
el->el_map.current = el->el_map.key;
} while (cmd == ED_SEQUENCE_LEAD_IN);
*cmdnum = cmd;
return (OKCMD);
return OKCMD;
}
#ifdef WIDECHAR
/* utf8_islead():
* Test whether a byte is a leading byte of a UTF-8 sequence.
*/
private int
utf8_islead(int c)
{
return c < 0x80 || /* single byte char */
(c >= 0xc2 && c <= 0xf4); /* start of multibyte sequence */
}
#endif
/* read_char():
* Read a character from the tty.
*/
private int
read_char(EditLine *el, char *cp)
read_char(EditLine *el, Char *cp)
{
ssize_t num_read;
int tried = 0;
char cbuf[MB_LEN_MAX];
size_t cbp = 0;
int bytes = 0;
again:
el->el_signal->sig_no = 0;
while ((num_read = read(el->el_infd, cp, 1)) == -1) {
if (el->el_signal->sig_no == SIGCONT) {
while ((num_read = read(el->el_infd, cbuf + cbp, (size_t)1)) == -1) {
int e = errno;
switch (el->el_signal->sig_no) {
case SIGCONT:
FUN(el,set)(el, EL_REFRESH);
/*FALLTHROUGH*/
case SIGWINCH:
sig_set(el);
el_set(el, EL_REFRESH);
goto again;
default:
break;
}
if (!tried && read__fixio(el->el_infd, errno) == 0)
if (!tried && read__fixio(el->el_infd, e) == 0)
tried = 1;
else {
errno = e;
*cp = '\0';
return (-1);
return -1;
}
}
/* Test for EOF */
if (num_read == 0) {
errno = 0;
*cp = '\0';
return 0;
}
#ifdef WIDECHAR
if (el->el_flags & CHARSET_IS_UTF8) {
if (!utf8_islead((unsigned char)cbuf[0]))
goto again; /* discard the byte we read and try again */
++cbp;
if ((bytes = ct_mbtowc(cp, cbuf, cbp)) == -1) {
ct_mbtowc_reset;
if (cbp >= MB_LEN_MAX) { /* "shouldn't happen" */
errno = EILSEQ;
*cp = '\0';
return -1;
}
goto again;
}
} else if (isascii((unsigned char)cbuf[0]) ||
/* we don't support other multibyte charsets */
++cbp != 1 ||
/* Try non-ASCII characters in a 8-bit character set */
(bytes = ct_mbtowc(cp, cbuf, cbp)) != 1)
#endif
*cp = (unsigned char)cbuf[0];
if ((el->el_flags & IGNORE_EXTCHARS) && bytes > 1) {
cbp = 0; /* skip this character */
goto again;
}
return (int)num_read;
}
@ -329,12 +399,12 @@ read_pop(c_macro_t *ma)
* Read a character
*/
public int
el_getc(EditLine *el, char *cp)
FUN(el,getc)(EditLine *el, Char *cp)
{
int num_read;
c_macro_t *ma = &el->el_chared.c_macro;
term__flush(el);
terminal__flush(el);
for (;;) {
if (ma->level < 0) {
if (!read_preread(el))
@ -349,30 +419,36 @@ el_getc(EditLine *el, char *cp)
continue;
}
*cp = ma->macro[0][ma->offset++] & 0377;
*cp = ma->macro[0][ma->offset++];
if (ma->macro[0][ma->offset] == '\0') {
/* Needed for QuoteMode On */
read_pop(ma);
}
return (1);
return 1;
}
#ifdef DEBUG_READ
(void) fprintf(el->el_errfile, "Turning raw mode on\n");
#endif /* DEBUG_READ */
if (tty_rawmode(el) < 0)/* make sure the tty is set up correctly */
return (0);
return 0;
#ifdef DEBUG_READ
(void) fprintf(el->el_errfile, "Reading a character\n");
#endif /* DEBUG_READ */
num_read = (*el->el_read.read_char)(el, cp);
if (num_read < 0)
el->el_errno = errno;
#ifdef WIDECHAR
if (el->el_flags & NARROW_READ)
*cp = *(char *)(void *)cp;
#endif
#ifdef DEBUG_READ
(void) fprintf(el->el_errfile, "Got it %c\n", *cp);
#endif /* DEBUG_READ */
return (num_read);
return num_read;
}
protected void
@ -393,7 +469,7 @@ read_prepare(EditLine *el)
re_refresh(el); /* print the prompt */
if (el->el_flags & UNBUFFERED)
term__flush(el);
terminal__flush(el);
}
protected void
@ -405,13 +481,13 @@ read_finish(EditLine *el)
sig_clr(el);
}
public const char *
el_gets(EditLine *el, int *nread)
public const Char *
FUN(el,gets)(EditLine *el, int *nread)
{
int retval;
el_action_t cmdnum = 0;
int num; /* how many chars we have read at NL */
char ch;
Char ch, *cp;
int crlf = 0;
int nrb;
#ifdef FIONREAD
@ -423,14 +499,14 @@ el_gets(EditLine *el, int *nread)
*nread = 0;
if (el->el_flags & NO_TTY) {
char *cp = el->el_line.buffer;
size_t idx;
cp = el->el_line.buffer;
while ((num = (*el->el_read.read_char)(el, cp)) == 1) {
/* make sure there is space for next character */
if (cp + 1 >= el->el_line.limit) {
idx = (cp - el->el_line.buffer);
if (!ch_enlargebufs(el, 2))
idx = (size_t)(cp - el->el_line.buffer);
if (!ch_enlargebufs(el, (size_t)2))
break;
cp = &el->el_line.buffer[idx];
}
@ -440,13 +516,13 @@ el_gets(EditLine *el, int *nread)
if (cp[-1] == '\r' || cp[-1] == '\n')
break;
}
if (num == -1)
if (num == -1) {
if (errno == EINTR)
cp = el->el_line.buffer;
el->el_errno = errno;
}
el->el_line.cursor = el->el_line.lastchar = cp;
*cp = '\0';
*nread = (int)(el->el_line.cursor - el->el_line.buffer);
goto done;
goto noedit;
}
@ -454,12 +530,12 @@ el_gets(EditLine *el, int *nread)
if (el->el_tty.t_mode == EX_IO && ma->level < 0) {
long chrs = 0;
(void) ioctl(el->el_infd, FIONREAD, (ioctl_t) & chrs);
(void) ioctl(el->el_infd, FIONREAD, &chrs);
if (chrs == 0) {
if (tty_rawmode(el) < 0) {
errno = 0;
*nread = 0;
return (NULL);
return NULL;
}
}
}
@ -469,7 +545,6 @@ el_gets(EditLine *el, int *nread)
read_prepare(el);
if (el->el_flags & EDIT_DISABLED) {
char *cp;
size_t idx;
if ((el->el_flags & UNBUFFERED) == 0)
@ -477,13 +552,13 @@ el_gets(EditLine *el, int *nread)
else
cp = el->el_line.lastchar;
term__flush(el);
terminal__flush(el);
while ((num = (*el->el_read.read_char)(el, cp)) == 1) {
/* make sure there is space next character */
if (cp + 1 >= el->el_line.limit) {
idx = (cp - el->el_line.buffer);
if (!ch_enlargebufs(el, 2))
idx = (size_t)(cp - el->el_line.buffer);
if (!ch_enlargebufs(el, (size_t)2))
break;
cp = &el->el_line.buffer[idx];
}
@ -496,12 +571,12 @@ el_gets(EditLine *el, int *nread)
}
if (num == -1) {
if (errno == EINTR)
cp = el->el_line.buffer;
el->el_errno = errno;
}
el->el_line.cursor = el->el_line.lastchar = cp;
*cp = '\0';
goto done;
goto noedit;
}
for (num = OKCMD; num == OKCMD;) { /* while still editing this
@ -511,13 +586,20 @@ el_gets(EditLine *el, int *nread)
#endif /* DEBUG_EDIT */
/* if EOF or error */
if ((num = read_getcmd(el, &cmdnum, &ch)) != OKCMD) {
num = -1;
#ifdef DEBUG_READ
(void) fprintf(el->el_errfile,
"Returning from el_gets %d\n", num);
#endif /* DEBUG_READ */
break;
}
if ((unsigned int)cmdnum >= (unsigned int)el->el_map.nfunc) { /* BUG CHECK command */
if (el->el_errno == EINTR) {
el->el_line.buffer[0] = '\0';
el->el_line.lastchar =
el->el_line.cursor = el->el_line.buffer;
break;
}
if ((size_t)cmdnum >= el->el_map.nfunc) { /* BUG CHECK command */
#ifdef DEBUG_EDIT
(void) fprintf(el->el_errfile,
"ERROR: illegal command from key 0%o\r\n", ch);
@ -547,7 +629,7 @@ el_gets(EditLine *el, int *nread)
el->el_chared.c_redo.pos < el->el_chared.c_redo.lim) {
if (cmdnum == VI_DELETE_PREV_CHAR &&
el->el_chared.c_redo.pos != el->el_chared.c_redo.buf
&& isprint((unsigned char)el->el_chared.c_redo.pos[-1]))
&& Isprint(el->el_chared.c_redo.pos[-1]))
el->el_chared.c_redo.pos--;
else
*el->el_chared.c_redo.pos++ = ch;
@ -578,7 +660,7 @@ el_gets(EditLine *el, int *nread)
case CC_REFRESH_BEEP:
re_refresh(el);
term_beep(el);
terminal_beep(el);
break;
case CC_NORM: /* normal char */
@ -610,7 +692,7 @@ el_gets(EditLine *el, int *nread)
/* put (real) cursor in a known place */
re_clear_display(el); /* reset the display stuff */
ch_reset(el, 1); /* reset the input pointers */
re_refresh(el); /* print the prompt again */
re_refresh(el); /* print the prompt again */
break;
case CC_ERROR:
@ -619,8 +701,8 @@ el_gets(EditLine *el, int *nread)
(void) fprintf(el->el_errfile,
"*** editor ERROR ***\r\n\n");
#endif /* DEBUG_READ */
term_beep(el);
term__flush(el);
terminal_beep(el);
terminal__flush(el);
break;
}
el->el_state.argument = 1;
@ -630,7 +712,7 @@ el_gets(EditLine *el, int *nread)
break;
}
term__flush(el); /* flush any buffered output */
terminal__flush(el); /* flush any buffered output */
/* make sure the tty is set up correctly */
if ((el->el_flags & UNBUFFERED) == 0) {
read_finish(el);
@ -638,6 +720,11 @@ el_gets(EditLine *el, int *nread)
} else {
*nread = (int)(el->el_line.lastchar - el->el_line.buffer);
}
goto done;
noedit:
el->el_line.cursor = el->el_line.lastchar = cp;
*cp = '\0';
*nread = (int)(el->el_line.cursor - el->el_line.buffer);
done:
if (*nread == 0) {
if (num == -1) {

View File

@ -1,3 +1,5 @@
/* $NetBSD: read.h,v 1.7 2009/12/30 22:37:40 christos Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
* All rights reserved.
@ -26,7 +28,6 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* $NetBSD: read.h,v 1.6 2008/04/29 06:53:01 martin Exp $
* $FreeBSD$
*/
@ -36,7 +37,7 @@
#ifndef _h_el_read
#define _h_el_read
typedef int (*el_rfunc_t)(EditLine *, char *);
typedef int (*el_rfunc_t)(EditLine *, Char *);
typedef struct el_read_t {
el_rfunc_t read_char; /* Function to read a character */

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,5 @@
/* $NetBSD: refresh.c,v 1.37 2011/07/29 23:44:45 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
@ -28,12 +30,15 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $NetBSD: refresh.c,v 1.34 2009/12/28 22:15:36 christos Exp $
*/
#include "config.h"
#if !defined(lint) && !defined(SCCSID)
#if 0
static char sccsid[] = "@(#)refresh.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: refresh.c,v 1.37 2011/07/29 23:44:45 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@ -41,7 +46,6 @@ __FBSDID("$FreeBSD$");
/*
* refresh.c: Lower level screen refreshing functions
*/
#include "sys.h"
#include <stdio.h>
#include <ctype.h>
#include <unistd.h>
@ -50,14 +54,14 @@ __FBSDID("$FreeBSD$");
#include "el.h"
private void re_nextline(EditLine *);
private void re_addc(EditLine *, int);
private void re_update_line(EditLine *, char *, char *, int);
private void re_insert (EditLine *, char *, int, int, char *, int);
private void re_delete(EditLine *, char *, int, int, int);
private void re_fastputc(EditLine *, int);
private void re_addc(EditLine *, Int);
private void re_update_line(EditLine *, Char *, Char *, int);
private void re_insert (EditLine *, Char *, int, int, Char *, int);
private void re_delete(EditLine *, Char *, int, int, int);
private void re_fastputc(EditLine *, Int);
private void re_clear_eol(EditLine *, int, int, int);
private void re__strncopy(char *, char *, size_t);
private void re__copy_and_pad(char *, const char *, size_t);
private void re__strncopy(Char *, Char *, size_t);
private void re__copy_and_pad(Char *, const Char *, size_t);
#ifdef DEBUG_REFRESH
private void re_printstr(EditLine *, const char *, char *, char *);
@ -101,9 +105,9 @@ re_nextline(EditLine *el)
* We do this via pointer shuffling - it's safe in this case
* and we avoid memcpy().
*/
if (el->el_refresh.r_cursor.v + 1 >= el->el_term.t_size.v) {
int i, lins = el->el_term.t_size.v;
char *firstline = el->el_vdisplay[0];
if (el->el_refresh.r_cursor.v + 1 >= el->el_terminal.t_size.v) {
int i, lins = el->el_terminal.t_size.v;
Char *firstline = el->el_vdisplay[0];
for(i = 1; i < lins; i++)
el->el_vdisplay[i - 1] = el->el_vdisplay[i];
@ -113,9 +117,9 @@ re_nextline(EditLine *el)
} else
el->el_refresh.r_cursor.v++;
ELRE_ASSERT(el->el_refresh.r_cursor.v >= el->el_term.t_size.v,
ELRE_ASSERT(el->el_refresh.r_cursor.v >= el->el_terminal.t_size.v,
(__F, "\r\nre_putc: overflow! r_cursor.v == %d > %d\r\n",
el->el_refresh.r_cursor.v, el->el_term.t_size.v),
el->el_refresh.r_cursor.v, el->el_terminal.t_size.v),
abort());
}
@ -123,38 +127,34 @@ re_nextline(EditLine *el)
* Draw c, expanding tabs, control chars etc.
*/
private void
re_addc(EditLine *el, int c)
re_addc(EditLine *el, Int c)
{
if (isprint(c)) {
re_putc(el, c, 1);
return;
}
if (c == '\n') { /* expand the newline */
int oldv = el->el_refresh.r_cursor.v;
re_putc(el, '\0', 0); /* assure end of line */
if (oldv == el->el_refresh.r_cursor.v) /* XXX */
re_nextline(el);
return;
}
if (c == '\t') { /* expand the tab */
switch (ct_chr_class((Char)c)) {
case CHTYPE_TAB: /* expand the tab */
for (;;) {
re_putc(el, ' ', 1);
if ((el->el_refresh.r_cursor.h & 07) == 0)
break; /* go until tab stop */
}
} else if (iscntrl(c)) {
re_putc(el, '^', 1);
if (c == 0177)
re_putc(el, '?', 1);
else
/* uncontrolify it; works only for iso8859-1 like sets */
re_putc(el, (toascii(c) | 0100), 1);
} else {
re_putc(el, '\\', 1);
re_putc(el, (int) ((((unsigned int) c >> 6) & 07) + '0'), 1);
re_putc(el, (int) ((((unsigned int) c >> 3) & 07) + '0'), 1);
re_putc(el, (c & 07) + '0', 1);
break;
case CHTYPE_NL: {
int oldv = el->el_refresh.r_cursor.v;
re_putc(el, '\0', 0); /* assure end of line */
if (oldv == el->el_refresh.r_cursor.v) /* XXX */
re_nextline(el);
break;
}
case CHTYPE_PRINT:
re_putc(el, c, 1);
break;
default: {
Char visbuf[VISUAL_WIDTH_MAX];
ssize_t i, n =
ct_visual_char(visbuf, VISUAL_WIDTH_MAX, (Char)c);
for (i = 0; n-- > 0; ++i)
re_putc(el, visbuf[i], 1);
break;
}
}
}
@ -163,23 +163,32 @@ re_addc(EditLine *el, int c)
* Draw the character given
*/
protected void
re_putc(EditLine *el, int c, int shift)
re_putc(EditLine *el, Int c, int shift)
{
int i, w = Width(c);
ELRE_DEBUG(1, (__F, "printing %5x '%c'\r\n", c, c));
ELRE_DEBUG(1, (__F, "printing %3.3o '%c'\r\n", c, c));
while (shift && (el->el_refresh.r_cursor.h + w > el->el_terminal.t_size.h))
re_putc(el, ' ', 1);
el->el_vdisplay[el->el_refresh.r_cursor.v]
[el->el_refresh.r_cursor.h] = c;
/* assumes !shift is only used for single-column chars */
i = w;
while (--i > 0)
el->el_vdisplay[el->el_refresh.r_cursor.v]
[el->el_refresh.r_cursor.h + i] = MB_FILL_CHAR;
el->el_vdisplay[el->el_refresh.r_cursor.v][el->el_refresh.r_cursor.h] = c;
if (!shift)
return;
el->el_refresh.r_cursor.h++; /* advance to next place */
if (el->el_refresh.r_cursor.h >= el->el_term.t_size.h) {
el->el_refresh.r_cursor.h += w; /* advance to next place */
if (el->el_refresh.r_cursor.h >= el->el_terminal.t_size.h) {
/* assure end of line */
el->el_vdisplay[el->el_refresh.r_cursor.v][el->el_term.t_size.h]
el->el_vdisplay[el->el_refresh.r_cursor.v][el->el_terminal.t_size.h]
= '\0';
re_nextline(el);
}
}
@ -193,7 +202,7 @@ protected void
re_refresh(EditLine *el)
{
int i, rhdiff;
char *cp, *st;
Char *cp, *st;
coord_t cur;
#ifdef notyet
size_t termsz;
@ -228,7 +237,7 @@ re_refresh(EditLine *el)
/* draw the current input buffer */
#if notyet
termsz = el->el_term.t_size.h * el->el_term.t_size.v;
termsz = el->el_terminal.t_size.h * el->el_terminal.t_size.v;
if (el->el_line.lastchar - el->el_line.buffer > termsz) {
/*
* If line is longer than terminal, process only part
@ -237,26 +246,33 @@ re_refresh(EditLine *el)
size_t rem = (el->el_line.lastchar-el->el_line.buffer)%termsz;
st = el->el_line.lastchar - rem
- (termsz - (((rem / el->el_term.t_size.v) - 1)
* el->el_term.t_size.v));
- (termsz - (((rem / el->el_terminal.t_size.v) - 1)
* el->el_terminal.t_size.v));
} else
#endif
st = el->el_line.buffer;
for (cp = st; cp < el->el_line.lastchar; cp++) {
if (cp == el->el_line.cursor) {
int w = Width(*cp);
/* save for later */
cur.h = el->el_refresh.r_cursor.h;
cur.v = el->el_refresh.r_cursor.v;
/* handle being at a linebroken doublewidth char */
if (w > 1 && el->el_refresh.r_cursor.h + w >
el->el_terminal.t_size.h) {
cur.h = 0;
cur.v++;
}
}
re_addc(el, (unsigned char) *cp);
re_addc(el, *cp);
}
if (cur.h == -1) { /* if I haven't been set yet, I'm at the end */
cur.h = el->el_refresh.r_cursor.h;
cur.v = el->el_refresh.r_cursor.v;
}
rhdiff = el->el_term.t_size.h - el->el_refresh.r_cursor.h -
rhdiff = el->el_terminal.t_size.h - el->el_refresh.r_cursor.h -
el->el_rprompt.p_pos.h;
if (el->el_rprompt.p_pos.h && !el->el_rprompt.p_pos.v &&
!el->el_refresh.r_cursor.v && rhdiff > 1) {
@ -279,8 +295,8 @@ re_refresh(EditLine *el)
ELRE_DEBUG(1, (__F,
"term.h=%d vcur.h=%d vcur.v=%d vdisplay[0]=\r\n:%80.80s:\r\n",
el->el_term.t_size.h, el->el_refresh.r_cursor.h,
el->el_refresh.r_cursor.v, el->el_vdisplay[0]));
el->el_terminal.t_size.h, el->el_refresh.r_cursor.h,
el->el_refresh.r_cursor.v, ct_encode_string(el->el_vdisplay[0])));
ELRE_DEBUG(1, (__F, "updating %d lines.\r\n", el->el_refresh.r_newcv));
for (i = 0; i <= el->el_refresh.r_newcv; i++) {
@ -295,7 +311,7 @@ re_refresh(EditLine *el)
* leftover stuff.
*/
re__copy_and_pad(el->el_display[i], el->el_vdisplay[i],
(size_t) el->el_term.t_size.h);
(size_t) el->el_terminal.t_size.h);
}
ELRE_DEBUG(1, (__F,
"\r\nel->el_refresh.r_cursor.v=%d,el->el_refresh.r_oldcv=%d i=%d\r\n",
@ -303,11 +319,12 @@ re_refresh(EditLine *el)
if (el->el_refresh.r_oldcv > el->el_refresh.r_newcv)
for (; i <= el->el_refresh.r_oldcv; i++) {
term_move_to_line(el, i);
term_move_to_char(el, 0);
term_clear_EOL(el, (int) strlen(el->el_display[i]));
terminal_move_to_line(el, i);
terminal_move_to_char(el, 0);
/* This Strlen should be safe even with MB_FILL_CHARs */
terminal_clear_EOL(el, (int) Strlen(el->el_display[i]));
#ifdef DEBUG_REFRESH
term_overwrite(el, "C\b", (size_t)2);
terminal_overwrite(el, "C\b", (size_t)2);
#endif /* DEBUG_REFRESH */
el->el_display[i][0] = '\0';
}
@ -317,8 +334,8 @@ re_refresh(EditLine *el)
"\r\ncursor.h = %d, cursor.v = %d, cur.h = %d, cur.v = %d\r\n",
el->el_refresh.r_cursor.h, el->el_refresh.r_cursor.v,
cur.h, cur.v));
term_move_to_line(el, cur.v); /* go to where the cursor is */
term_move_to_char(el, cur.h);
terminal_move_to_line(el, cur.v); /* go to where the cursor is */
terminal_move_to_char(el, cur.h);
}
@ -329,10 +346,10 @@ protected void
re_goto_bottom(EditLine *el)
{
term_move_to_line(el, el->el_refresh.r_oldcv);
term__putc(el, '\n');
terminal_move_to_line(el, el->el_refresh.r_oldcv);
terminal__putc(el, '\n');
re_clear_display(el);
term__flush(el);
terminal__flush(el);
}
@ -342,10 +359,10 @@ re_goto_bottom(EditLine *el)
*/
private void
/*ARGSUSED*/
re_insert(EditLine *el __unused,
char *d, int dat, int dlen, char *s, int num)
re_insert(EditLine *el __attribute__((__unused__)),
Char *d, int dat, int dlen, Char *s, int num)
{
char *a, *b;
Char *a, *b;
if (num <= 0)
return;
@ -354,8 +371,8 @@ re_insert(EditLine *el __unused,
ELRE_DEBUG(1,
(__F, "re_insert() starting: %d at %d max %d, d == \"%s\"\n",
num, dat, dlen, d));
ELRE_DEBUG(1, (__F, "s == \"%s\"\n", s));
num, dat, dlen, ct_encode_string(d)));
ELRE_DEBUG(1, (__F, "s == \"%s\"\n", ct_encode_string(s)));
/* open up the space for num chars */
if (num > 0) {
@ -365,19 +382,24 @@ re_insert(EditLine *el __unused,
*b-- = *a--;
d[dlen] = '\0'; /* just in case */
}
ELRE_DEBUG(1, (__F,
"re_insert() after insert: %d at %d max %d, d == \"%s\"\n",
num, dat, dlen, d));
ELRE_DEBUG(1, (__F, "s == \"%s\"\n", s));
num, dat, dlen, ct_encode_string(d)));
ELRE_DEBUG(1, (__F, "s == \"%s\"\n", ct_encode_string(s)));
/* copy the characters */
for (a = d + dat; (a < d + dlen) && (num > 0); num--)
*a++ = *s++;
#ifdef notyet
/* ct_encode_string() uses a static buffer, so we can't conveniently
* encode both d & s here */
ELRE_DEBUG(1,
(__F, "re_insert() after copy: %d at %d max %d, %s == \"%s\"\n",
num, dat, dlen, d, s));
ELRE_DEBUG(1, (__F, "s == \"%s\"\n", s));
#endif
}
@ -386,10 +408,10 @@ re_insert(EditLine *el __unused,
*/
private void
/*ARGSUSED*/
re_delete(EditLine *el __unused,
char *d, int dat, int dlen, int num)
re_delete(EditLine *el __attribute__((__unused__)),
Char *d, int dat, int dlen, int num)
{
char *a, *b;
Char *a, *b;
if (num <= 0)
return;
@ -399,7 +421,7 @@ re_delete(EditLine *el __unused,
}
ELRE_DEBUG(1,
(__F, "re_delete() starting: %d at %d max %d, d == \"%s\"\n",
num, dat, dlen, d));
num, dat, dlen, ct_encode_string(d)));
/* open up the space for num chars */
if (num > 0) {
@ -411,7 +433,7 @@ re_delete(EditLine *el __unused,
}
ELRE_DEBUG(1,
(__F, "re_delete() after delete: %d at %d max %d, d == \"%s\"\n",
num, dat, dlen, d));
num, dat, dlen, ct_encode_string(d)));
}
@ -419,7 +441,7 @@ re_delete(EditLine *el __unused,
* Like strncpy without padding.
*/
private void
re__strncopy(char *a, char *b, size_t n)
re__strncopy(Char *a, Char *b, size_t n)
{
while (n-- && *b)
@ -430,7 +452,7 @@ re__strncopy(char *a, char *b, size_t n)
* Find the number of characters we need to clear till the end of line
* in order to make sure that we have cleared the previous contents of
* the line. fx and sx is the number of characters inserted or deleted
* int the first or second diff, diff is the difference between the
* in the first or second diff, diff is the difference between the
* number of characters between the new and old line.
*/
private void
@ -450,7 +472,7 @@ re_clear_eol(EditLine *el, int fx, int sx, int diff)
diff = sx;
ELRE_DEBUG(1, (__F, "re_clear_eol %d\n", diff));
term_clear_EOL(el, diff);
terminal_clear_EOL(el, diff);
}
/*****************************************************************
@ -478,11 +500,11 @@ new: eddie> Oh, my little buggy says to me, as lurgid as
#define MIN_END_KEEP 4
private void
re_update_line(EditLine *el, char *old, char *new, int i)
re_update_line(EditLine *el, Char *old, Char *new, int i)
{
char *o, *n, *p, c;
char *ofd, *ols, *oe, *nfd, *nls, *ne;
char *osb, *ose, *nsb, *nse;
Char *o, *n, *p, c;
Char *ofd, *ols, *oe, *nfd, *nls, *ne;
Char *osb, *ose, *nsb, *nse;
int fx, sx;
size_t len;
@ -697,7 +719,7 @@ re_update_line(EditLine *el, char *old, char *new, int i)
* don't have to change the line, we don't move to it. el_cursor.h to
* first diff char
*/
term_move_to_line(el, i);
terminal_move_to_line(el, i);
/*
* at this point we have something like this:
@ -721,7 +743,7 @@ re_update_line(EditLine *el, char *old, char *new, int i)
* if we have a net insert on the first difference, AND inserting the
* net amount ((nsb-nfd) - (osb-ofd)) won't push the last useful
* character (which is ne if nls != ne, otherwise is nse) off the edge
* of the screen (el->el_term.t_size.h) else we do the deletes first
* of the screen (el->el_terminal.t_size.h) else we do the deletes first
* so that we keep everything we need to.
*/
@ -743,13 +765,13 @@ re_update_line(EditLine *el, char *old, char *new, int i)
* No insert or delete
*/
if ((nsb != nfd) && fx > 0 &&
((p - old) + fx <= el->el_term.t_size.h)) {
((p - old) + fx <= el->el_terminal.t_size.h)) {
ELRE_DEBUG(1,
(__F, "first diff insert at %d...\r\n", nfd - new));
/*
* Move to the first char to insert, where the first diff is.
*/
term_move_to_char(el, (int)(nfd - new));
terminal_move_to_char(el, (int)(nfd - new));
/*
* Check if we have stuff to keep at end
*/
@ -761,21 +783,21 @@ re_update_line(EditLine *el, char *old, char *new, int i)
if (fx > 0) {
ELRE_DEBUG(!EL_CAN_INSERT, (__F,
"ERROR: cannot insert in early first diff\n"));
term_insertwrite(el, nfd, fx);
terminal_insertwrite(el, nfd, fx);
re_insert(el, old, (int)(ofd - old),
el->el_term.t_size.h, nfd, fx);
el->el_terminal.t_size.h, nfd, fx);
}
/*
* write (nsb-nfd) - fx chars of new starting at
* (nfd + fx)
*/
len = (size_t) ((nsb - nfd) - fx);
term_overwrite(el, (nfd + fx), len);
terminal_overwrite(el, (nfd + fx), len);
re__strncopy(ofd + fx, nfd + fx, len);
} else {
ELRE_DEBUG(1, (__F, "without anything to save\r\n"));
len = (size_t)(nsb - nfd);
term_overwrite(el, nfd, len);
terminal_overwrite(el, nfd, len);
re__strncopy(ofd, nfd, len);
/*
* Done
@ -788,7 +810,7 @@ re_update_line(EditLine *el, char *old, char *new, int i)
/*
* move to the first char to delete where the first diff is
*/
term_move_to_char(el, (int)(ofd - old));
terminal_move_to_char(el, (int)(ofd - old));
/*
* Check if we have stuff to save
*/
@ -801,15 +823,15 @@ re_update_line(EditLine *el, char *old, char *new, int i)
if (fx < 0) {
ELRE_DEBUG(!EL_CAN_DELETE, (__F,
"ERROR: cannot delete in first diff\n"));
term_deletechars(el, -fx);
terminal_deletechars(el, -fx);
re_delete(el, old, (int)(ofd - old),
el->el_term.t_size.h, -fx);
el->el_terminal.t_size.h, -fx);
}
/*
* write (nsb-nfd) chars of new starting at nfd
*/
len = (size_t) (nsb - nfd);
term_overwrite(el, nfd, len);
terminal_overwrite(el, nfd, len);
re__strncopy(ofd, nfd, len);
} else {
@ -818,7 +840,7 @@ re_update_line(EditLine *el, char *old, char *new, int i)
/*
* write (nsb-nfd) chars of new starting at nfd
*/
term_overwrite(el, nfd, (size_t)(nsb - nfd));
terminal_overwrite(el, nfd, (size_t)(nsb - nfd));
re_clear_eol(el, fx, sx,
(int)((oe - old) - (ne - new)));
/*
@ -829,7 +851,7 @@ re_update_line(EditLine *el, char *old, char *new, int i)
} else
fx = 0;
if (sx < 0 && (ose - old) + fx < el->el_term.t_size.h) {
if (sx < 0 && (ose - old) + fx < el->el_terminal.t_size.h) {
ELRE_DEBUG(1, (__F,
"second diff delete at %d...\r\n", (ose - old) + fx));
/*
@ -839,7 +861,7 @@ re_update_line(EditLine *el, char *old, char *new, int i)
* fx is the number of characters inserted (+) or deleted (-)
*/
term_move_to_char(el, (int)((ose - old) + fx));
terminal_move_to_char(el, (int)((ose - old) + fx));
/*
* Check if we have stuff to save
*/
@ -851,16 +873,16 @@ re_update_line(EditLine *el, char *old, char *new, int i)
if (sx < 0) {
ELRE_DEBUG(!EL_CAN_DELETE, (__F,
"ERROR: cannot delete in second diff\n"));
term_deletechars(el, -sx);
terminal_deletechars(el, -sx);
}
/*
* write (nls-nse) chars of new starting at nse
*/
term_overwrite(el, nse, (size_t)(nls - nse));
terminal_overwrite(el, nse, (size_t)(nls - nse));
} else {
ELRE_DEBUG(1, (__F,
"but with nothing left to save\r\n"));
term_overwrite(el, nse, (size_t)(nls - nse));
terminal_overwrite(el, nse, (size_t)(nls - nse));
re_clear_eol(el, fx, sx,
(int)((oe - old) - (ne - new)));
}
@ -872,7 +894,7 @@ re_update_line(EditLine *el, char *old, char *new, int i)
ELRE_DEBUG(1, (__F, "late first diff insert at %d...\r\n",
nfd - new));
term_move_to_char(el, (int)(nfd - new));
terminal_move_to_char(el, (int)(nfd - new));
/*
* Check if we have stuff to keep at the end
*/
@ -890,21 +912,21 @@ re_update_line(EditLine *el, char *old, char *new, int i)
*/
ELRE_DEBUG(!EL_CAN_INSERT, (__F,
"ERROR: cannot insert in late first diff\n"));
term_insertwrite(el, nfd, fx);
terminal_insertwrite(el, nfd, fx);
re_insert(el, old, (int)(ofd - old),
el->el_term.t_size.h, nfd, fx);
el->el_terminal.t_size.h, nfd, fx);
}
/*
* write (nsb-nfd) - fx chars of new starting at
* (nfd + fx)
*/
len = (size_t) ((nsb - nfd) - fx);
term_overwrite(el, (nfd + fx), len);
terminal_overwrite(el, (nfd + fx), len);
re__strncopy(ofd + fx, nfd + fx, len);
} else {
ELRE_DEBUG(1, (__F, "without anything to save\r\n"));
len = (size_t) (nsb - nfd);
term_overwrite(el, nfd, len);
terminal_overwrite(el, nfd, len);
re__strncopy(ofd, nfd, len);
}
}
@ -914,24 +936,24 @@ re_update_line(EditLine *el, char *old, char *new, int i)
if (sx >= 0) {
ELRE_DEBUG(1, (__F,
"second diff insert at %d...\r\n", (int)(nse - new)));
term_move_to_char(el, (int)(nse - new));
terminal_move_to_char(el, (int)(nse - new));
if (ols != oe) {
ELRE_DEBUG(1, (__F, "with stuff to keep at end\r\n"));
if (sx > 0) {
/* insert sx chars of new starting at nse */
ELRE_DEBUG(!EL_CAN_INSERT, (__F,
"ERROR: cannot insert in second diff\n"));
term_insertwrite(el, nse, sx);
terminal_insertwrite(el, nse, sx);
}
/*
* write (nls-nse) - sx chars of new starting at
* (nse + sx)
*/
term_overwrite(el, (nse + sx),
terminal_overwrite(el, (nse + sx),
(size_t)((nls - nse) - sx));
} else {
ELRE_DEBUG(1, (__F, "without anything to save\r\n"));
term_overwrite(el, nse, (size_t)(nls - nse));
terminal_overwrite(el, nse, (size_t)(nls - nse));
/*
* No need to do a clear-to-end here because we were
@ -948,7 +970,7 @@ re_update_line(EditLine *el, char *old, char *new, int i)
* Copy string and pad with spaces
*/
private void
re__copy_and_pad(char *dst, const char *src, size_t width)
re__copy_and_pad(Char *dst, const Char *src, size_t width)
{
size_t i;
@ -971,8 +993,8 @@ re__copy_and_pad(char *dst, const char *src, size_t width)
protected void
re_refresh_cursor(EditLine *el)
{
char *cp, c;
int h, v, th;
Char *cp;
int h, v, th, w;
if (el->el_line.cursor >= el->el_line.lastchar) {
if (el->el_map.current == el->el_map.alt
@ -985,41 +1007,46 @@ re_refresh_cursor(EditLine *el)
/* first we must find where the cursor is... */
h = el->el_prompt.p_pos.h;
v = el->el_prompt.p_pos.v;
th = el->el_term.t_size.h; /* optimize for speed */
th = el->el_terminal.t_size.h; /* optimize for speed */
/* do input buffer to el->el_line.cursor */
for (cp = el->el_line.buffer; cp < el->el_line.cursor; cp++) {
c = *cp;
switch (c) {
case '\n': /* handle newline in data part too */
switch (ct_chr_class(*cp)) {
case CHTYPE_NL: /* handle newline in data part too */
h = 0;
v++;
break;
case '\t': /* if a tab, to next tab stop */
case CHTYPE_TAB: /* if a tab, to next tab stop */
while (++h & 07)
continue;
break;
default:
if (iscntrl((unsigned char) c))
h += 2; /* ^x */
else if (!isprint((unsigned char) c))
h += 4; /* octal \xxx */
else
h++;
w = Width(*cp);
if (w > 1 && h + w > th) { /* won't fit on line */
h = 0;
v++;
}
h += ct_visual_width(*cp);
break;
}
}
if (h >= th) { /* check, extra long tabs picked up here also */
h -= th;
v++;
}
}
/* if we have a next character, and it's a doublewidth one, we need to
* check whether we need to linebreak for it to fit */
if (cp < el->el_line.lastchar && (w = Width(*cp)) > 1)
if (h + w > th) {
h = 0;
v++;
}
/* now go there */
term_move_to_line(el, v);
term_move_to_char(el, h);
term__flush(el);
terminal_move_to_line(el, v);
terminal_move_to_char(el, h);
terminal__flush(el);
}
@ -1027,12 +1054,19 @@ re_refresh_cursor(EditLine *el)
* Add a character fast.
*/
private void
re_fastputc(EditLine *el, int c)
re_fastputc(EditLine *el, Int c)
{
int w = Width((Char)c);
while (w > 1 && el->el_cursor.h + w > el->el_terminal.t_size.h)
re_fastputc(el, ' ');
term__putc(el, c);
terminal__putc(el, c);
el->el_display[el->el_cursor.v][el->el_cursor.h++] = c;
if (el->el_cursor.h >= el->el_term.t_size.h) {
while (--w > 0)
el->el_display[el->el_cursor.v][el->el_cursor.h++]
= MB_FILL_CHAR;
if (el->el_cursor.h >= el->el_terminal.t_size.h) {
/* if we must overflow */
el->el_cursor.h = 0;
@ -1042,14 +1076,14 @@ re_fastputc(EditLine *el, int c)
* We do this via pointer shuffling - it's safe in this case
* and we avoid memcpy().
*/
if (el->el_cursor.v + 1 >= el->el_term.t_size.v) {
int i, lins = el->el_term.t_size.v;
char *firstline = el->el_display[0];
if (el->el_cursor.v + 1 >= el->el_terminal.t_size.v) {
int i, lins = el->el_terminal.t_size.v;
Char *firstline = el->el_display[0];
for(i = 1; i < lins; i++)
el->el_display[i - 1] = el->el_display[i];
re__copy_and_pad(firstline, "", 0);
re__copy_and_pad(firstline, STR(""), (size_t)0);
el->el_display[i - 1] = firstline;
} else {
el->el_cursor.v++;
@ -1057,12 +1091,12 @@ re_fastputc(EditLine *el, int c)
}
if (EL_HAS_AUTO_MARGINS) {
if (EL_HAS_MAGIC_MARGINS) {
term__putc(el, ' ');
term__putc(el, '\b');
terminal__putc(el, ' ');
terminal__putc(el, '\b');
}
} else {
term__putc(el, '\r');
term__putc(el, '\n');
terminal__putc(el, '\r');
terminal__putc(el, '\n');
}
}
}
@ -1075,34 +1109,39 @@ re_fastputc(EditLine *el, int c)
protected void
re_fastaddc(EditLine *el)
{
char c;
Char c;
int rhdiff;
c = (unsigned char)el->el_line.cursor[-1];
c = el->el_line.cursor[-1];
if (c == '\t' || el->el_line.cursor != el->el_line.lastchar) {
re_refresh(el); /* too hard to handle */
return;
}
rhdiff = el->el_term.t_size.h - el->el_cursor.h -
rhdiff = el->el_terminal.t_size.h - el->el_cursor.h -
el->el_rprompt.p_pos.h;
if (el->el_rprompt.p_pos.h && rhdiff < 3) {
re_refresh(el); /* clear out rprompt if less than 1 char gap */
return;
} /* else (only do at end of line, no TAB) */
if (iscntrl((unsigned char) c)) { /* if control char, do caret */
char mc = (c == 0177) ? '?' : (toascii(c) | 0100);
re_fastputc(el, '^');
re_fastputc(el, mc);
} else if (isprint((unsigned char) c)) { /* normal char */
switch (ct_chr_class(c)) {
case CHTYPE_TAB: /* already handled, should never happen here */
break;
case CHTYPE_NL:
case CHTYPE_PRINT:
re_fastputc(el, c);
} else {
re_fastputc(el, '\\');
re_fastputc(el, (int)(((((unsigned int)c) >> 6) & 3) + '0'));
re_fastputc(el, (int)(((((unsigned int)c) >> 3) & 7) + '0'));
re_fastputc(el, (c & 7) + '0');
break;
case CHTYPE_ASCIICTL:
case CHTYPE_NONPRINT: {
Char visbuf[VISUAL_WIDTH_MAX];
ssize_t i, n =
ct_visual_char(visbuf, VISUAL_WIDTH_MAX, (Char)c);
for (i = 0; n-- > 0; ++i)
re_fastputc(el, visbuf[i]);
break;
}
term__flush(el);
}
terminal__flush(el);
}
@ -1116,7 +1155,7 @@ re_clear_display(EditLine *el)
el->el_cursor.v = 0;
el->el_cursor.h = 0;
for (i = 0; i < el->el_term.t_size.v; i++)
for (i = 0; i < el->el_terminal.t_size.v; i++)
el->el_display[i][0] = '\0';
el->el_refresh.r_oldcv = 0;
}
@ -1133,14 +1172,14 @@ re_clear_lines(EditLine *el)
int i;
for (i = el->el_refresh.r_oldcv; i >= 0; i--) {
/* for each line on the screen */
term_move_to_line(el, i);
term_move_to_char(el, 0);
term_clear_EOL(el, el->el_term.t_size.h);
terminal_move_to_line(el, i);
terminal_move_to_char(el, 0);
terminal_clear_EOL(el, el->el_terminal.t_size.h);
}
} else {
term_move_to_line(el, el->el_refresh.r_oldcv);
terminal_move_to_line(el, el->el_refresh.r_oldcv);
/* go to last line */
term__putc(el, '\r'); /* go to BOL */
term__putc(el, '\n'); /* go to new line */
terminal__putc(el, '\r'); /* go to BOL */
terminal__putc(el, '\n'); /* go to new line */
}
}

View File

@ -1,3 +1,5 @@
/* $NetBSD: refresh.h,v 1.6 2009/12/30 22:37:40 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
@ -30,7 +32,6 @@
* SUCH DAMAGE.
*
* @(#)refresh.h 8.1 (Berkeley) 6/4/93
* $NetBSD: refresh.h,v 1.5 2003/08/07 16:44:33 agc Exp $
* $FreeBSD$
*/
@ -48,7 +49,7 @@ typedef struct {
int r_newcv;
} el_refresh_t;
protected void re_putc(EditLine *, int, int);
protected void re_putc(EditLine *, Int, int);
protected void re_clear_lines(EditLine *);
protected void re_clear_display(EditLine *);
protected void re_refresh(EditLine *);

View File

@ -1,3 +1,5 @@
/* $NetBSD: search.c,v 1.30 2011/10/04 15:27:04 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
@ -28,12 +30,15 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $NetBSD: search.c,v 1.21 2009/02/15 21:55:23 christos Exp $
*/
#include "config.h"
#if !defined(lint) && !defined(SCCSID)
#if 0
static char sccsid[] = "@(#)search.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: search.c,v 1.30 2011/10/04 15:27:04 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@ -41,7 +46,6 @@ __FBSDID("$FreeBSD$");
/*
* search.c: History and character search functions
*/
#include "sys.h"
#include <stdlib.h>
#if defined(REGEX)
#include <regex.h>
@ -64,15 +68,16 @@ protected int
search_init(EditLine *el)
{
el->el_search.patbuf = (char *) el_malloc(EL_BUFSIZ);
el->el_search.patbuf = el_malloc(EL_BUFSIZ *
sizeof(*el->el_search.patbuf));
if (el->el_search.patbuf == NULL)
return (-1);
return -1;
el->el_search.patlen = 0;
el->el_search.patdir = -1;
el->el_search.chacha = '\0';
el->el_search.chadir = CHAR_FWD;
el->el_search.chatflg = 0;
return (0);
return 0;
}
@ -83,7 +88,7 @@ protected void
search_end(EditLine *el)
{
el_free((ptr_t) el->el_search.patbuf);
el_free(el->el_search.patbuf);
el->el_search.patbuf = NULL;
}
@ -104,8 +109,11 @@ regerror(const char *msg)
* Return if string matches pattern
*/
protected int
el_match(const char *str, const char *pat)
el_match(const Char *str, const Char *pat)
{
#ifdef WIDECHAR
static ct_buffer_t conv;
#endif
#if defined (REGEX)
regex_t re;
int rv;
@ -117,30 +125,31 @@ el_match(const char *str, const char *pat)
extern int re_exec(const char *);
#endif
if (strstr(str, pat) != NULL)
return (1);
if (Strstr(str, pat) != 0)
return 1;
#if defined(REGEX)
if (regcomp(&re, pat, 0) == 0) {
rv = regexec(&re, str, 0, NULL, 0) == 0;
if (regcomp(&re, ct_encode_string(pat, &conv), 0) == 0) {
rv = regexec(&re, ct_encode_string(str, &conv), (size_t)0, NULL,
0) == 0;
regfree(&re);
} else {
rv = 0;
}
return (rv);
return rv;
#elif defined(REGEXP)
if ((re = regcomp(pat)) != NULL) {
rv = regexec(re, str);
free((ptr_t) re);
if ((re = regcomp(ct_encode_string(pat, &conv))) != NULL) {
rv = regexec(re, ct_encode_string(str, &conv));
el_free(re);
} else {
rv = 0;
}
return (rv);
return rv;
#else
if (re_comp(pat) != NULL)
return (0);
if (re_comp(ct_encode_string(pat, &conv)) != NULL)
return 0;
else
return (re_exec(str) == 1);
return re_exec(ct_encode_string(str, &conv) == 1);
#endif
}
@ -149,14 +158,14 @@ el_match(const char *str, const char *pat)
* return True if the pattern matches the prefix
*/
protected int
c_hmatch(EditLine *el, const char *str)
c_hmatch(EditLine *el, const Char *str)
{
#ifdef SDEBUG
(void) fprintf(el->el_errfile, "match `%s' with `%s'\n",
el->el_search.patbuf, str);
#endif /* SDEBUG */
return (el_match(str, el->el_search.patbuf));
return el_match(str, el->el_search.patbuf);
}
@ -168,15 +177,16 @@ c_setpat(EditLine *el)
{
if (el->el_state.lastcmd != ED_SEARCH_PREV_HISTORY &&
el->el_state.lastcmd != ED_SEARCH_NEXT_HISTORY) {
el->el_search.patlen = EL_CURSOR(el) - el->el_line.buffer;
el->el_search.patlen =
(size_t)(EL_CURSOR(el) - el->el_line.buffer);
if (el->el_search.patlen >= EL_BUFSIZ)
el->el_search.patlen = EL_BUFSIZ - 1;
if (el->el_search.patlen != 0) {
(void) strncpy(el->el_search.patbuf, el->el_line.buffer,
(void) Strncpy(el->el_search.patbuf, el->el_line.buffer,
el->el_search.patlen);
el->el_search.patbuf[el->el_search.patlen] = '\0';
} else
el->el_search.patlen = strlen(el->el_search.patbuf);
el->el_search.patlen = Strlen(el->el_search.patbuf);
}
#ifdef SDEBUG
(void) fprintf(el->el_errfile, "\neventno = %d\n",
@ -197,12 +207,12 @@ c_setpat(EditLine *el)
protected el_action_t
ce_inc_search(EditLine *el, int dir)
{
static const char STRfwd[] = {'f', 'w', 'd', '\0'},
static const Char STRfwd[] = {'f', 'w', 'd', '\0'},
STRbck[] = {'b', 'c', 'k', '\0'};
static char pchar = ':';/* ':' = normal, '?' = failed */
static char endcmd[2] = {'\0', '\0'};
char ch, *ocursor = el->el_line.cursor, oldpchar = pchar;
const char *cp;
static Char pchar = ':';/* ':' = normal, '?' = failed */
static Char endcmd[2] = {'\0', '\0'};
Char ch, *ocursor = el->el_line.cursor, oldpchar = pchar;
const Char *cp;
el_action_t ret = CC_NORM;
@ -211,9 +221,10 @@ ce_inc_search(EditLine *el, int dir)
int newdir = dir;
int done, redo;
if (el->el_line.lastchar + sizeof(STRfwd) / sizeof(char) + 2 +
if (el->el_line.lastchar + sizeof(STRfwd) /
sizeof(*el->el_line.lastchar) + 2 +
el->el_search.patlen >= el->el_line.limit)
return (CC_ERROR);
return CC_ERROR;
for (;;) {
@ -240,14 +251,14 @@ ce_inc_search(EditLine *el, int dir)
*el->el_line.lastchar = '\0';
re_refresh(el);
if (el_getc(el, &ch) != 1)
return (ed_end_of_file(el, 0));
if (FUN(el,getc)(el, &ch) != 1)
return ed_end_of_file(el, 0);
switch (el->el_map.current[(unsigned char) ch]) {
case ED_INSERT:
case ED_DIGIT:
if (el->el_search.patlen >= EL_BUFSIZ - LEN)
term_beep(el);
terminal_beep(el);
else {
el->el_search.patbuf[el->el_search.patlen++] =
ch;
@ -272,7 +283,7 @@ ce_inc_search(EditLine *el, int dir)
if (el->el_search.patlen > LEN)
done++;
else
term_beep(el);
terminal_beep(el);
break;
default:
@ -296,7 +307,7 @@ ce_inc_search(EditLine *el, int dir)
*el->el_line.cursor != '\n') {
if (el->el_search.patlen >=
EL_BUFSIZ - LEN) {
term_beep(el);
terminal_beep(el);
break;
}
el->el_search.patbuf[el->el_search.patlen++] =
@ -309,14 +320,14 @@ ce_inc_search(EditLine *el, int dir)
re_refresh(el);
break;
} else if (isglob(*cp)) {
term_beep(el);
terminal_beep(el);
break;
}
break;
default: /* Terminate and execute cmd */
endcmd[0] = ch;
el_push(el, endcmd);
FUN(el,push)(el, endcmd);
/* FALLTHROUGH */
case 0033: /* ESC: Terminate */
@ -378,9 +389,10 @@ ce_inc_search(EditLine *el, int dir)
/* avoid c_setpat */
el->el_state.lastcmd =
(el_action_t) newdir;
ret = newdir == ED_SEARCH_PREV_HISTORY ?
ret = (el_action_t)
(newdir == ED_SEARCH_PREV_HISTORY ?
ed_search_prev_history(el, 0) :
ed_search_next_history(el, 0);
ed_search_next_history(el, 0));
if (ret != CC_ERROR) {
el->el_line.cursor = newdir ==
ED_SEARCH_PREV_HISTORY ?
@ -394,13 +406,13 @@ ce_inc_search(EditLine *el, int dir)
el->el_search.patbuf[el->el_search.patlen] =
'\0';
if (ret == CC_ERROR) {
term_beep(el);
terminal_beep(el);
if (el->el_history.eventno !=
ohisteventno) {
el->el_history.eventno =
ohisteventno;
if (hist_get(el) == CC_ERROR)
return (CC_ERROR);
return CC_ERROR;
}
el->el_line.cursor = ocursor;
pchar = '?';
@ -425,14 +437,14 @@ ce_inc_search(EditLine *el, int dir)
if (el->el_history.eventno != ohisteventno) {
el->el_history.eventno = ohisteventno;
if (hist_get(el) == CC_ERROR)
return (CC_ERROR);
return CC_ERROR;
}
el->el_line.cursor = ocursor;
if (ret == CC_ERROR)
re_refresh(el);
}
if (done || ret != CC_NORM)
return (ret);
return ret;
}
}
@ -443,9 +455,9 @@ ce_inc_search(EditLine *el, int dir)
protected el_action_t
cv_search(EditLine *el, int dir)
{
char ch;
char tmpbuf[EL_BUFSIZ];
int tmplen;
Char ch;
Char tmpbuf[EL_BUFSIZ];
ssize_t tmplen;
#ifdef ANCHOR
tmpbuf[0] = '.';
@ -456,7 +468,7 @@ cv_search(EditLine *el, int dir)
el->el_search.patdir = dir;
tmplen = c_gets(el, &tmpbuf[LEN],
dir == ED_SEARCH_PREV_HISTORY ? "\n/" : "\n?" );
dir == ED_SEARCH_PREV_HISTORY ? STR("\n/") : STR("\n?") );
if (tmplen == -1)
return CC_REFRESH;
@ -470,16 +482,16 @@ cv_search(EditLine *el, int dir)
*/
if (el->el_search.patlen == 0) {
re_refresh(el);
return (CC_ERROR);
return CC_ERROR;
}
#ifdef ANCHOR
if (el->el_search.patbuf[0] != '.' &&
el->el_search.patbuf[0] != '*') {
(void) strncpy(tmpbuf, el->el_search.patbuf,
sizeof(tmpbuf) - 1);
(void) Strncpy(tmpbuf, el->el_search.patbuf,
sizeof(tmpbuf) / sizeof(*tmpbuf) - 1);
el->el_search.patbuf[0] = '.';
el->el_search.patbuf[1] = '*';
(void) strncpy(&el->el_search.patbuf[2], tmpbuf,
(void) Strncpy(&el->el_search.patbuf[2], tmpbuf,
EL_BUFSIZ - 3);
el->el_search.patlen++;
el->el_search.patbuf[el->el_search.patlen++] = '.';
@ -493,21 +505,21 @@ cv_search(EditLine *el, int dir)
tmpbuf[tmplen++] = '*';
#endif
tmpbuf[tmplen] = '\0';
(void) strncpy(el->el_search.patbuf, tmpbuf, EL_BUFSIZ - 1);
el->el_search.patlen = tmplen;
(void) Strncpy(el->el_search.patbuf, tmpbuf, EL_BUFSIZ - 1);
el->el_search.patlen = (size_t)tmplen;
}
el->el_state.lastcmd = (el_action_t) dir; /* avoid c_setpat */
el->el_line.cursor = el->el_line.lastchar = el->el_line.buffer;
if ((dir == ED_SEARCH_PREV_HISTORY ? ed_search_prev_history(el, 0) :
ed_search_next_history(el, 0)) == CC_ERROR) {
re_refresh(el);
return (CC_ERROR);
return CC_ERROR;
}
if (ch == 0033) {
re_refresh(el);
return ed_newline(el, 0);
}
return (CC_REFRESH);
return CC_REFRESH;
}
@ -517,9 +529,9 @@ cv_search(EditLine *el, int dir)
protected el_action_t
ce_search_line(EditLine *el, int dir)
{
char *cp = el->el_line.cursor;
char *pattern = el->el_search.patbuf;
char oc, *ocp;
Char *cp = el->el_line.cursor;
Char *pattern = el->el_search.patbuf;
Char oc, *ocp;
#ifdef ANCHOR
ocp = &pattern[1];
oc = *ocp;
@ -534,21 +546,21 @@ ce_search_line(EditLine *el, int dir)
if (el_match(cp, ocp)) {
*ocp = oc;
el->el_line.cursor = cp;
return (CC_NORM);
return CC_NORM;
}
}
*ocp = oc;
return (CC_ERROR);
return CC_ERROR;
} else {
for (; *cp != '\0' && cp < el->el_line.limit; cp++) {
if (el_match(cp, ocp)) {
*ocp = oc;
el->el_line.cursor = cp;
return (CC_NORM);
return CC_NORM;
}
}
*ocp = oc;
return (CC_ERROR);
return CC_ERROR;
}
}
@ -557,12 +569,12 @@ ce_search_line(EditLine *el, int dir)
* Vi repeat search
*/
protected el_action_t
cv_repeat_srch(EditLine *el, int c)
cv_repeat_srch(EditLine *el, Int c)
{
#ifdef SDEBUG
(void) fprintf(el->el_errfile, "dir %d patlen %d patbuf %s\n",
c, el->el_search.patlen, el->el_search.patbuf);
c, el->el_search.patlen, ct_encode_string(el->el_search.patbuf));
#endif
el->el_state.lastcmd = (el_action_t) c; /* Hack to stop c_setpat */
@ -570,11 +582,11 @@ cv_repeat_srch(EditLine *el, int c)
switch (c) {
case ED_SEARCH_NEXT_HISTORY:
return (ed_search_next_history(el, 0));
return ed_search_next_history(el, 0);
case ED_SEARCH_PREV_HISTORY:
return (ed_search_prev_history(el, 0));
return ed_search_prev_history(el, 0);
default:
return (CC_ERROR);
return CC_ERROR;
}
}
@ -583,16 +595,16 @@ cv_repeat_srch(EditLine *el, int c)
* Vi character search
*/
protected el_action_t
cv_csearch(EditLine *el, int direction, int ch, int count, int tflag)
cv_csearch(EditLine *el, int direction, Int ch, int count, int tflag)
{
char *cp;
Char *cp;
if (ch == 0)
return CC_ERROR;
if (ch == -1) {
char c;
if (el_getc(el, &c) != 1)
if (ch == (Int)-1) {
Char c;
if (FUN(el,getc)(el, &c) != 1)
return ed_end_of_file(el, 0);
ch = c;
}
@ -600,18 +612,18 @@ cv_csearch(EditLine *el, int direction, int ch, int count, int tflag)
/* Save for ';' and ',' commands */
el->el_search.chacha = ch;
el->el_search.chadir = direction;
el->el_search.chatflg = tflag;
el->el_search.chatflg = (char)tflag;
cp = el->el_line.cursor;
while (count--) {
if (*cp == ch)
if ((Int)*cp == ch)
cp += direction;
for (;;cp += direction) {
if (cp >= el->el_line.lastchar)
return CC_ERROR;
if (cp < el->el_line.buffer)
return CC_ERROR;
if (*cp == ch)
if ((Int)*cp == ch)
break;
}
}

View File

@ -1,3 +1,5 @@
/* $NetBSD: search.h,v 1.9 2009/12/30 22:37:40 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
@ -30,7 +32,6 @@
* SUCH DAMAGE.
*
* @(#)search.h 8.1 (Berkeley) 6/4/93
* $NetBSD: search.h,v 1.8 2003/10/18 23:27:36 christos Exp $
* $FreeBSD$
*/
@ -43,24 +44,24 @@
#include "histedit.h"
typedef struct el_search_t {
char *patbuf; /* The pattern buffer */
Char *patbuf; /* The pattern buffer */
size_t patlen; /* Length of the pattern buffer */
int patdir; /* Direction of the last search */
int chadir; /* Character search direction */
char chacha; /* Character we are looking for */
Char chacha; /* Character we are looking for */
char chatflg; /* 0 if f, 1 if t */
} el_search_t;
protected int el_match(const char *, const char *);
protected int el_match(const Char *, const Char *);
protected int search_init(EditLine *);
protected void search_end(EditLine *);
protected int c_hmatch(EditLine *, const char *);
protected int c_hmatch(EditLine *, const Char *);
protected void c_setpat(EditLine *);
protected el_action_t ce_inc_search(EditLine *, int);
protected el_action_t cv_search(EditLine *, int);
protected el_action_t ce_search_line(EditLine *, int);
protected el_action_t cv_repeat_srch(EditLine *, int);
protected el_action_t cv_csearch(EditLine *, int, int, int, int);
protected el_action_t cv_repeat_srch(EditLine *, Int);
protected el_action_t cv_csearch(EditLine *, int, Int, int, int);
#endif /* _h_el_search */

View File

@ -1,3 +1,5 @@
/* $NetBSD: sig.c,v 1.17 2011/07/28 20:50:55 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
@ -28,12 +30,15 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $NetBSD: sig.c,v 1.15 2009/02/19 15:20:22 christos Exp $
*/
#include "config.h"
#if !defined(lint) && !defined(SCCSID)
#if 0
static char sccsid[] = "@(#)sig.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: sig.c,v 1.17 2011/07/28 20:50:55 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@ -43,7 +48,6 @@ __FBSDID("$FreeBSD$");
* our policy is to trap all signals, set a good state
* and pass the ball to our caller.
*/
#include "sys.h"
#include "el.h"
#include <stdlib.h>
@ -80,7 +84,7 @@ sig_handler(int signo)
tty_rawmode(sel);
if (ed_redisplay(sel, 0) == CC_REFRESH)
re_refresh(sel);
term__flush(sel);
terminal__flush(sel);
break;
case SIGWINCH:
@ -144,7 +148,7 @@ protected void
sig_end(EditLine *el)
{
el_free((ptr_t) el->el_signal);
el_free(el->el_signal);
el->el_signal = NULL;
}

View File

@ -1,3 +1,5 @@
/* $NetBSD: sig.h,v 1.8 2009/02/19 15:20:22 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
@ -30,7 +32,6 @@
* SUCH DAMAGE.
*
* @(#)sig.h 8.1 (Berkeley) 6/4/93
* $NetBSD: sig.h,v 1.8 2009/02/19 15:20:22 christos Exp $
* $FreeBSD$
*/

View File

@ -1,3 +1,5 @@
/* $NetBSD: sys.h,v 1.17 2011/09/28 14:08:04 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
@ -30,7 +32,6 @@
* SUCH DAMAGE.
*
* @(#)sys.h 8.1 (Berkeley) 6/4/93
* $NetBSD: sys.h,v 1.12 2009/08/31 00:05:43 christos Exp $
* $FreeBSD$
*/
@ -40,8 +41,24 @@
#ifndef _h_sys
#define _h_sys
#ifdef HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
#endif
#if !defined(__attribute__) && (defined(__cplusplus) || !defined(__GNUC__) || __GNUC__ == 2 && __GNUC_MINOR__ < 8)
# define __attribute__(A)
#endif
#ifndef __BEGIN_DECLS
# ifdef __cplusplus
# define __BEGIN_DECLS extern "C" {
# define __END_DECLS }
# else
# define __BEGIN_DECLS
# define __END_DECLS
# endif
#endif
#ifndef public
# define public /* Externally visible functions/variables */
#endif
@ -55,18 +72,48 @@
/* When we want to hide everything */
#endif
#ifndef _PTR_T
# define _PTR_T
typedef void *ptr_t;
#endif
#ifndef _IOCTL_T
# define _IOCTL_T
typedef void *ioctl_t;
#ifndef __arraycount
# define __arraycount(a) (sizeof(a) / sizeof(*(a)))
#endif
#include <stdio.h>
#ifndef HAVE_STRLCAT
#define strlcat libedit_strlcat
size_t strlcat(char *dst, const char *src, size_t size);
#endif
#ifndef HAVE_STRLCPY
#define strlcpy libedit_strlcpy
size_t strlcpy(char *dst, const char *src, size_t size);
#endif
#ifndef HAVE_FGETLN
#define fgetln libedit_fgetln
char *fgetln(FILE *fp, size_t *len);
#endif
#ifndef HAVE_WCSDUP
#include <wchar.h>
wchar_t *wcsdup(const wchar_t *);
#endif
#ifndef _DIAGASSERT
#define _DIAGASSERT(x)
#endif
#ifndef __RCSID
#define __RCSID(x)
#endif
#ifndef HAVE_U_INT32_T
typedef unsigned int u_int32_t;
#endif
#ifndef SIZE_T_MAX
#define SIZE_T_MAX ((size_t)-1)
#endif
#define REGEX /* Use POSIX.2 regular expression functions */
#undef REGEXP /* Use UNIX V8 regular expression functions */
@ -79,40 +126,4 @@ extern char* tgoto(const char*, int, int);
extern char* tgetstr(char*, char**);
#endif
#ifdef notdef
# undef REGEX
# undef REGEXP
# include <malloc.h>
# ifdef __GNUC__
/*
* Broken hdrs.
*/
extern int tgetent(const char *bp, char *name);
extern int tgetflag(const char *id);
extern int tgetnum(const char *id);
extern char *tgetstr(const char *id, char **area);
extern char *tgoto(const char *cap, int col, int row);
extern int tputs(const char *str, int affcnt, int (*putc)(int));
extern char *getenv(const char *);
extern int fprintf(FILE *, const char *, ...);
extern int sigsetmask(int);
extern int sigblock(int);
extern int fputc(int, FILE *);
extern int fgetc(FILE *);
extern int fflush(FILE *);
extern int tolower(int);
extern int toupper(int);
extern int errno, sys_nerr;
extern char *sys_errlist[];
extern void perror(const char *);
# include <string.h>
# define strerror(e) sys_errlist[e]
# endif
# ifdef SABER
extern ptr_t memcpy(ptr_t, const ptr_t, size_t);
extern ptr_t memset(ptr_t, int, size_t);
# endif
extern char *fgetline(FILE *, int *);
#endif
#endif /* _h_sys */

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,5 @@
/* $NetBSD: terminal.h,v 1.4 2012/03/24 20:09:30 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
@ -30,24 +32,23 @@
* SUCH DAMAGE.
*
* @(#)term.h 8.1 (Berkeley) 6/4/93
* $NetBSD: term.h,v 1.20 2009/03/31 17:38:27 christos Exp $
* $FreeBSD$
*/
/*
* el.term.h: Termcap header
*/
#ifndef _h_el_term
#define _h_el_term
#ifndef _h_el_terminal
#define _h_el_terminal
#include "histedit.h"
typedef struct { /* Symbolic function key bindings */
const char *name; /* name of the key */
const Char *name; /* name of the key */
int key; /* Index in termcap table */
key_value_t fun; /* Function bound to it */
keymacro_value_t fun; /* Function bound to it */
int type; /* Type of function */
} fkey_t;
} funckey_t;
typedef struct {
const char *t_name; /* the terminal name */
@ -63,12 +64,12 @@ typedef struct {
#define TERM_HAS_AUTO_MARGINS 0x080 /* Has auto margins */
#define TERM_HAS_MAGIC_MARGINS 0x100 /* Has magic margins */
char *t_buf; /* Termcap buffer */
int t_loc; /* location used */
size_t t_loc; /* location used */
char **t_str; /* termcap strings */
int *t_val; /* termcap values */
char *t_cap; /* Termcap buffer */
fkey_t *t_fkey; /* Array of keys */
} el_term_t;
funckey_t *t_fkey; /* Array of keys */
} el_terminal_t;
/*
* fKey indexes
@ -82,36 +83,36 @@ typedef struct {
#define A_K_DE 6
#define A_K_NKEYS 7
protected void term_move_to_line(EditLine *, int);
protected void term_move_to_char(EditLine *, int);
protected void term_clear_EOL(EditLine *, int);
protected void term_overwrite(EditLine *, const char *, size_t);
protected void term_insertwrite(EditLine *, char *, int);
protected void term_deletechars(EditLine *, int);
protected void term_clear_screen(EditLine *);
protected void term_beep(EditLine *);
protected int term_change_size(EditLine *, int, int);
protected int term_get_size(EditLine *, int *, int *);
protected int term_init(EditLine *);
protected void term_bind_arrow(EditLine *);
protected void term_print_arrow(EditLine *, const char *);
protected int term_clear_arrow(EditLine *, const char *);
protected int term_set_arrow(EditLine *, const char *, key_value_t *, int);
protected void term_end(EditLine *);
protected void term_get(EditLine *, const char **);
protected int term_set(EditLine *, const char *);
protected int term_settc(EditLine *, int, const char **);
protected int term_gettc(EditLine *, int, char **);
protected int term_telltc(EditLine *, int, const char **);
protected int term_echotc(EditLine *, int, const char **);
protected void term_writec(EditLine *, int);
protected int term__putc(EditLine *, int);
protected void term__flush(EditLine *);
protected void terminal_move_to_line(EditLine *, int);
protected void terminal_move_to_char(EditLine *, int);
protected void terminal_clear_EOL(EditLine *, int);
protected void terminal_overwrite(EditLine *, const Char *, size_t);
protected void terminal_insertwrite(EditLine *, Char *, int);
protected void terminal_deletechars(EditLine *, int);
protected void terminal_clear_screen(EditLine *);
protected void terminal_beep(EditLine *);
protected int terminal_change_size(EditLine *, int, int);
protected int terminal_get_size(EditLine *, int *, int *);
protected int terminal_init(EditLine *);
protected void terminal_bind_arrow(EditLine *);
protected void terminal_print_arrow(EditLine *, const Char *);
protected int terminal_clear_arrow(EditLine *, const Char *);
protected int terminal_set_arrow(EditLine *, const Char *, keymacro_value_t *, int);
protected void terminal_end(EditLine *);
protected void terminal_get(EditLine *, const char **);
protected int terminal_set(EditLine *, const char *);
protected int terminal_settc(EditLine *, int, const Char **);
protected int terminal_gettc(EditLine *, int, char **);
protected int terminal_telltc(EditLine *, int, const Char **);
protected int terminal_echotc(EditLine *, int, const Char **);
protected void terminal_writec(EditLine *, Int);
protected int terminal__putc(EditLine *, Int);
protected void terminal__flush(EditLine *);
/*
* Easy access macros
*/
#define EL_FLAGS (el)->el_term.t_flags
#define EL_FLAGS (el)->el_terminal.t_flags
#define EL_CAN_INSERT (EL_FLAGS & TERM_CAN_INSERT)
#define EL_CAN_DELETE (EL_FLAGS & TERM_CAN_DELETE)
@ -123,4 +124,4 @@ protected void term__flush(EditLine *);
#define EL_HAS_AUTO_MARGINS (EL_FLAGS & TERM_HAS_AUTO_MARGINS)
#define EL_HAS_MAGIC_MARGINS (EL_FLAGS & TERM_HAS_MAGIC_MARGINS)
#endif /* _h_el_term */
#endif /* _h_el_terminal */

View File

@ -1,3 +1,5 @@
/* $NetBSD: tokenizer.c,v 1.21 2011/08/16 16:25:15 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
@ -28,62 +30,66 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $NetBSD: tokenizer.c,v 1.15 2009/02/15 21:55:23 christos Exp $
*/
#include "config.h"
#if !defined(lint) && !defined(SCCSID)
#if 0
static char sccsid[] = "@(#)tokenizer.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: tokenizer.c,v 1.21 2011/08/16 16:25:15 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/* We build this file twice, once as NARROW, once as WIDE. */
/*
* tokenize.c: Bourne shell like tokenizer
*/
#include "sys.h"
#include <string.h>
#include <stdlib.h>
#include "histedit.h"
#include "chartype.h"
typedef enum {
Q_none, Q_single, Q_double, Q_one, Q_doubleone
} quote_t;
#define IFS "\t \n"
#define TOK_KEEP 1
#define TOK_EAT 2
#define WINCR 20
#define AINCR 10
#define tok_strdup(a) strdup(a)
#define IFS STR("\t \n")
#define tok_malloc(a) malloc(a)
#define tok_free(a) free(a)
#define tok_realloc(a, b) realloc(a, b)
#define tok_strdup(a) Strdup(a)
struct tokenizer {
char *ifs; /* In field separator */
int argc, amax; /* Current and maximum number of args */
char **argv; /* Argument list */
char *wptr, *wmax; /* Space and limit on the word buffer */
char *wstart; /* Beginning of next word */
char *wspace; /* Space of word buffer */
struct TYPE(tokenizer) {
Char *ifs; /* In field separator */
size_t argc, amax; /* Current and maximum number of args */
Char **argv; /* Argument list */
Char *wptr, *wmax; /* Space and limit on the word buffer */
Char *wstart; /* Beginning of next word */
Char *wspace; /* Space of word buffer */
quote_t quote; /* Quoting state */
int flags; /* flags; */
};
private void tok_finish(Tokenizer *);
private void FUN(tok,finish)(TYPE(Tokenizer) *);
/* tok_finish():
/* FUN(tok,finish)():
* Finish a word in the tokenizer.
*/
private void
tok_finish(Tokenizer *tok)
FUN(tok,finish)(TYPE(Tokenizer) *tok)
{
*tok->wptr = '\0';
@ -96,35 +102,35 @@ tok_finish(Tokenizer *tok)
}
/* tok_init():
/* FUN(tok,init)():
* Initialize the tokenizer
*/
public Tokenizer *
tok_init(const char *ifs)
public TYPE(Tokenizer) *
FUN(tok,init)(const Char *ifs)
{
Tokenizer *tok = (Tokenizer *) tok_malloc(sizeof(Tokenizer));
TYPE(Tokenizer) *tok = tok_malloc(sizeof(*tok));
if (tok == NULL)
return NULL;
tok->ifs = tok_strdup(ifs ? ifs : IFS);
if (tok->ifs == NULL) {
tok_free((ptr_t)tok);
tok_free(tok);
return NULL;
}
tok->argc = 0;
tok->amax = AINCR;
tok->argv = (char **) tok_malloc(sizeof(char *) * tok->amax);
tok->argv = tok_malloc(sizeof(*tok->argv) * tok->amax);
if (tok->argv == NULL) {
tok_free((ptr_t)tok->ifs);
tok_free((ptr_t)tok);
tok_free(tok->ifs);
tok_free(tok);
return NULL;
}
tok->argv[0] = NULL;
tok->wspace = (char *) tok_malloc(WINCR);
tok->wspace = tok_malloc(WINCR * sizeof(*tok->wspace));
if (tok->wspace == NULL) {
tok_free((ptr_t)tok->argv);
tok_free((ptr_t)tok->ifs);
tok_free((ptr_t)tok);
tok_free(tok->argv);
tok_free(tok->ifs);
tok_free(tok);
return NULL;
}
tok->wmax = tok->wspace + WINCR;
@ -133,15 +139,15 @@ tok_init(const char *ifs)
tok->flags = 0;
tok->quote = Q_none;
return (tok);
return tok;
}
/* tok_reset():
/* FUN(tok,reset)():
* Reset the tokenizer
*/
public void
tok_reset(Tokenizer *tok)
FUN(tok,reset)(TYPE(Tokenizer) *tok)
{
tok->argc = 0;
@ -152,25 +158,25 @@ tok_reset(Tokenizer *tok)
}
/* tok_end():
/* FUN(tok,end)():
* Clean up
*/
public void
tok_end(Tokenizer *tok)
FUN(tok,end)(TYPE(Tokenizer) *tok)
{
tok_free((ptr_t) tok->ifs);
tok_free((ptr_t) tok->wspace);
tok_free((ptr_t) tok->argv);
tok_free((ptr_t) tok);
tok_free(tok->ifs);
tok_free(tok->wspace);
tok_free(tok->argv);
tok_free(tok);
}
/* tok_line():
/* FUN(tok,line)():
* Bourne shell (sh(1)) like tokenizing
* Arguments:
* tok current tokenizer state (setup with tok_init())
* tok current tokenizer state (setup with FUN(tok,init)())
* line line to parse
* Returns:
* -1 Internal error
@ -185,19 +191,19 @@ tok_end(Tokenizer *tok)
* cursorv if !NULL, offset in argv[cursorc] of cursor
*/
public int
tok_line(Tokenizer *tok, const LineInfo *line,
int *argc, const char ***argv, int *cursorc, int *cursoro)
FUN(tok,line)(TYPE(Tokenizer) *tok, const TYPE(LineInfo) *line,
int *argc, const Char ***argv, int *cursorc, int *cursoro)
{
const char *ptr;
const Char *ptr;
int cc, co;
cc = co = -1;
ptr = line->buffer;
for (ptr = line->buffer; ;ptr++) {
if (ptr >= line->lastchar)
ptr = "";
ptr = STR("");
if (ptr == line->cursor) {
cc = tok->argc;
cc = (int)tok->argc;
co = (int)(tok->wptr - tok->wstart);
}
switch (*ptr) {
@ -229,7 +235,7 @@ tok_line(Tokenizer *tok, const LineInfo *line,
break;
default:
return (-1);
return -1;
}
break;
@ -260,7 +266,7 @@ tok_line(Tokenizer *tok, const LineInfo *line,
break;
default:
return (-1);
return -1;
}
break;
@ -291,7 +297,7 @@ tok_line(Tokenizer *tok, const LineInfo *line,
break;
default:
return (-1);
return -1;
}
break;
@ -317,7 +323,7 @@ tok_line(Tokenizer *tok, const LineInfo *line,
break;
default:
return (0);
return 0;
}
break;
@ -327,15 +333,15 @@ tok_line(Tokenizer *tok, const LineInfo *line,
/* Finish word and return */
if (tok->flags & TOK_EAT) {
tok->flags &= ~TOK_EAT;
return (3);
return 3;
}
goto tok_line_outok;
case Q_single:
return (1);
return 1;
case Q_double:
return (2);
return 2;
case Q_doubleone:
tok->quote = Q_double;
@ -348,7 +354,7 @@ tok_line(Tokenizer *tok, const LineInfo *line,
break;
default:
return (-1);
return -1;
}
break;
@ -356,8 +362,8 @@ tok_line(Tokenizer *tok, const LineInfo *line,
tok->flags &= ~TOK_EAT;
switch (tok->quote) {
case Q_none:
if (strchr(tok->ifs, *ptr) != NULL)
tok_finish(tok);
if (Strchr(tok->ifs, *ptr) != NULL)
FUN(tok,finish)(tok);
else
*tok->wptr++ = *ptr;
break;
@ -380,20 +386,21 @@ tok_line(Tokenizer *tok, const LineInfo *line,
break;
default:
return (-1);
return -1;
}
break;
}
if (tok->wptr >= tok->wmax - 4) {
size_t size = tok->wmax - tok->wspace + WINCR;
char *s = (char *) tok_realloc(tok->wspace, size);
size_t size = (size_t)(tok->wmax - tok->wspace + WINCR);
Char *s = tok_realloc(tok->wspace,
size * sizeof(*s));
if (s == NULL)
return (-1);
return -1;
if (s != tok->wspace) {
int i;
size_t i;
for (i = 0; i < tok->argc; i++) {
tok->argv[i] =
(tok->argv[i] - tok->wspace) + s;
@ -405,41 +412,41 @@ tok_line(Tokenizer *tok, const LineInfo *line,
tok->wmax = s + size;
}
if (tok->argc >= tok->amax - 4) {
char **p;
Char **p;
tok->amax += AINCR;
p = (char **) tok_realloc(tok->argv,
tok->amax * sizeof(char *));
p = tok_realloc(tok->argv, tok->amax * sizeof(*p));
if (p == NULL)
return (-1);
return -1;
tok->argv = p;
}
}
tok_line_outok:
if (cc == -1 && co == -1) {
cc = tok->argc;
cc = (int)tok->argc;
co = (int)(tok->wptr - tok->wstart);
}
if (cursorc != NULL)
*cursorc = cc;
if (cursoro != NULL)
*cursoro = co;
tok_finish(tok);
*argv = (const char **)tok->argv;
*argc = tok->argc;
return (0);
FUN(tok,finish)(tok);
*argv = (const Char **)tok->argv;
*argc = (int)tok->argc;
return 0;
}
/* tok_str():
/* FUN(tok,str)():
* Simpler version of tok_line, taking a NUL terminated line
* and splitting into words, ignoring cursor state.
*/
public int
tok_str(Tokenizer *tok, const char *line, int *argc, const char ***argv)
FUN(tok,str)(TYPE(Tokenizer) *tok, const Char *line, int *argc,
const Char ***argv)
{
LineInfo li;
TYPE(LineInfo) li;
memset(&li, 0, sizeof(li));
li.buffer = line;
li.cursor = li.lastchar = strchr(line, '\0');
return (tok_line(tok, &li, argc, argv, NULL, NULL));
li.cursor = li.lastchar = Strchr(line, '\0');
return FUN(tok,line(tok, &li, argc, argv, NULL, NULL));
}

View File

@ -1,3 +1,5 @@
/* $NetBSD: tty.c,v 1.46 2014/06/18 18:52:49 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
@ -28,12 +30,15 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $NetBSD: tty.c,v 1.31 2009/07/22 15:58:09 christos Exp $
*/
#include "config.h"
#if !defined(lint) && !defined(SCCSID)
#if 0
static char sccsid[] = "@(#)tty.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: tty.c,v 1.46 2014/06/18 18:52:49 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@ -42,9 +47,12 @@ __FBSDID("$FreeBSD$");
* tty.c: tty interface stuff
*/
#include <assert.h>
#include "sys.h"
#include "tty.h"
#include <errno.h>
#include <unistd.h> /* for isatty */
#include <strings.h> /* for ffs */
#include <stdlib.h> /* for abort */
#include "el.h"
#include "tty.h"
typedef struct ttymodes_t {
const char *m_name;
@ -53,7 +61,7 @@ typedef struct ttymodes_t {
} ttymodes_t;
typedef struct ttymap_t {
int nch, och; /* Internal and termio rep of chars */
Int nch, och; /* Internal and termio rep of chars */
el_action_t bind[3]; /* emacs, vi, and vi-cmd */
} ttymap_t;
@ -149,7 +157,7 @@ private const ttymap_t tty_map[] = {
{C_LNEXT, VLNEXT,
{ED_QUOTED_INSERT, ED_QUOTED_INSERT, ED_UNASSIGNED}},
#endif /* VLNEXT */
{-1, -1,
{(Int)-1, (Int)-1,
{ED_UNASSIGNED, ED_UNASSIGNED, ED_UNASSIGNED}}
};
@ -454,6 +462,7 @@ private void tty__getchar(struct termios *, unsigned char *);
private void tty__setchar(struct termios *, unsigned char *);
private speed_t tty__getspeed(struct termios *);
private int tty_setup(EditLine *);
private void tty_setup_flags(EditLine *, struct termios *, int);
#define t_qu t_ts
@ -490,21 +499,30 @@ tty_setup(EditLine *el)
int rst = 1;
if (el->el_flags & EDIT_DISABLED)
return (0);
return 0;
if (tty_getty(el, &el->el_tty.t_ed) == -1) {
if (!isatty(el->el_outfd)) {
#ifdef DEBUG_TTY
(void) fprintf(el->el_errfile,
"tty_setup: tty_getty: %s\n", strerror(errno));
(void) fprintf(el->el_errfile, "%s: isatty: %s\n", __func__,
strerror(errno));
#endif /* DEBUG_TTY */
return (-1);
return -1;
}
el->el_tty.t_ts = el->el_tty.t_ex = el->el_tty.t_ed;
if (tty_getty(el, &el->el_tty.t_or) == -1) {
#ifdef DEBUG_TTY
(void) fprintf(el->el_errfile, "%s: tty_getty: %s\n", __func__,
strerror(errno));
#endif /* DEBUG_TTY */
return -1;
}
el->el_tty.t_ts = el->el_tty.t_ex = el->el_tty.t_ed = el->el_tty.t_or;
el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ex);
el->el_tty.t_tabs = tty__gettabs(&el->el_tty.t_ex);
el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ex);
tty_setup_flags(el, &el->el_tty.t_ex, EX_IO);
/*
* Reset the tty chars to reasonable defaults
* If they are disabled, then enable them.
@ -528,23 +546,21 @@ tty_setup(EditLine *el)
el->el_tty.t_c[EX_IO][rst] =
el->el_tty.t_c[TS_IO][rst];
}
tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ex) == -1) {
#ifdef DEBUG_TTY
(void) fprintf(el->el_errfile, "%s: tty_setty: %s\n",
__func__, strerror(errno));
#endif /* DEBUG_TTY */
return -1;
}
}
el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][MD_INP].t_clrmask;
el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][MD_INP].t_setmask;
el->el_tty.t_ed.c_oflag &= ~el->el_tty.t_t[ED_IO][MD_OUT].t_clrmask;
el->el_tty.t_ed.c_oflag |= el->el_tty.t_t[ED_IO][MD_OUT].t_setmask;
el->el_tty.t_ed.c_cflag &= ~el->el_tty.t_t[ED_IO][MD_CTL].t_clrmask;
el->el_tty.t_ed.c_cflag |= el->el_tty.t_t[ED_IO][MD_CTL].t_setmask;
el->el_tty.t_ed.c_lflag &= ~el->el_tty.t_t[ED_IO][MD_LIN].t_clrmask;
el->el_tty.t_ed.c_lflag |= el->el_tty.t_t[ED_IO][MD_LIN].t_setmask;
tty_setup_flags(el, &el->el_tty.t_ed, ED_IO);
tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]);
tty_bind_char(el, 1);
return (0);
return 0;
}
protected int
@ -555,7 +571,7 @@ tty_init(EditLine *el)
el->el_tty.t_vdisable = _POSIX_VDISABLE;
(void) memcpy(el->el_tty.t_t, ttyperm, sizeof(ttyperm_t));
(void) memcpy(el->el_tty.t_c, ttychar, sizeof(ttychar_t));
return (tty_setup(el));
return tty_setup(el);
}
@ -564,10 +580,14 @@ tty_init(EditLine *el)
*/
protected void
/*ARGSUSED*/
tty_end(EditLine *el __unused)
tty_end(EditLine *el)
{
/* XXX: Maybe reset to an initial state? */
if (tty_setty(el, TCSAFLUSH, &el->el_tty.t_or) == -1) {
#ifdef DEBUG_TTY
(void) fprintf(el->el_errfile,
"%s: tty_setty: %s\n", __func__, strerror(errno));
#endif /* DEBUG_TTY */
}
}
@ -581,7 +601,7 @@ tty__getspeed(struct termios *td)
if ((spd = cfgetispeed(td)) == 0)
spd = cfgetospeed(td);
return (spd);
return spd;
}
/* tty__getspeed():
@ -865,7 +885,7 @@ tty_bind_char(EditLine *el, int force)
unsigned char *t_n = el->el_tty.t_c[ED_IO];
unsigned char *t_o = el->el_tty.t_ed.c_cc;
unsigned char new[2], old[2];
Char new[2], old[2];
const ttymap_t *tp;
el_action_t *map, *alt;
const el_action_t *dmap, *dalt;
@ -881,27 +901,79 @@ tty_bind_char(EditLine *el, int force)
dalt = NULL;
}
for (tp = tty_map; tp->nch != -1; tp++) {
for (tp = tty_map; tp->nch != (Int)-1; tp++) {
new[0] = t_n[tp->nch];
old[0] = t_o[tp->och];
if (new[0] == old[0] && !force)
continue;
/* Put the old default binding back, and set the new binding */
key_clear(el, map, (char *)old);
map[old[0]] = dmap[old[0]];
key_clear(el, map, (char *)new);
keymacro_clear(el, map, old);
map[UC(old[0])] = dmap[UC(old[0])];
keymacro_clear(el, map, new);
/* MAP_VI == 1, MAP_EMACS == 0... */
map[new[0]] = tp->bind[el->el_map.type];
map[UC(new[0])] = tp->bind[el->el_map.type];
if (dalt) {
key_clear(el, alt, (char *)old);
alt[old[0]] = dalt[old[0]];
key_clear(el, alt, (char *)new);
alt[new[0]] = tp->bind[el->el_map.type + 1];
keymacro_clear(el, alt, old);
alt[UC(old[0])] = dalt[UC(old[0])];
keymacro_clear(el, alt, new);
alt[UC(new[0])] = tp->bind[el->el_map.type + 1];
}
}
}
private tcflag_t *
tty__get_flag(struct termios *t, int kind) {
switch (kind) {
case MD_INP:
return &t->c_iflag;
case MD_OUT:
return &t->c_oflag;
case MD_CTL:
return &t->c_cflag;
case MD_LIN:
return &t->c_lflag;
default:
abort();
/*NOTREACHED*/
}
}
private tcflag_t
tty_update_flag(EditLine *el, tcflag_t f, int mode, int kind)
{
f &= ~el->el_tty.t_t[mode][kind].t_clrmask;
f |= el->el_tty.t_t[mode][kind].t_setmask;
return f;
}
private void
tty_update_flags(EditLine *el, int kind)
{
tcflag_t *tt, *ed, *ex;
tt = tty__get_flag(&el->el_tty.t_ts, kind);
ed = tty__get_flag(&el->el_tty.t_ed, kind);
ex = tty__get_flag(&el->el_tty.t_ex, kind);
if (*tt != *ex && (kind != MD_CTL || *tt != *ed)) {
*ed = tty_update_flag(el, *tt, ED_IO, kind);
*ex = tty_update_flag(el, *tt, EX_IO, kind);
}
}
private void
tty_update_char(EditLine *el, int mode, int c) {
if (!((el->el_tty.t_t[mode][MD_CHAR].t_setmask & C_SH(c)))
&& (el->el_tty.t_c[TS_IO][c] != el->el_tty.t_c[EX_IO][c]))
el->el_tty.t_c[mode][c] = el->el_tty.t_c[TS_IO][c];
if (el->el_tty.t_t[mode][MD_CHAR].t_clrmask & C_SH(c))
el->el_tty.t_c[mode][c] = el->el_tty.t_vdisable;
}
/* tty_rawmode():
* Set terminal into 1 character at a time mode.
*/
@ -910,123 +982,80 @@ tty_rawmode(EditLine *el)
{
if (el->el_tty.t_mode == ED_IO || el->el_tty.t_mode == QU_IO)
return (0);
return 0;
if (el->el_flags & EDIT_DISABLED)
return (0);
return 0;
if (tty_getty(el, &el->el_tty.t_ts) == -1) {
#ifdef DEBUG_TTY
(void) fprintf(el->el_errfile, "tty_rawmode: tty_getty: %s\n",
(void) fprintf(el->el_errfile, "%s: tty_getty: %s\n", __func__,
strerror(errno));
#endif /* DEBUG_TTY */
return (-1);
return -1;
}
/*
* We always keep up with the eight bit setting and the speed of the
* tty. But only we only believe changes that are made to cooked mode!
* tty. But we only believe changes that are made to cooked mode!
*/
el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ts);
el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ts);
if (tty__getspeed(&el->el_tty.t_ed) != el->el_tty.t_speed) {
if (tty__getspeed(&el->el_tty.t_ex) != el->el_tty.t_speed ||
tty__getspeed(&el->el_tty.t_ed) != el->el_tty.t_speed) {
(void) cfsetispeed(&el->el_tty.t_ex, el->el_tty.t_speed);
(void) cfsetospeed(&el->el_tty.t_ex, el->el_tty.t_speed);
(void) cfsetispeed(&el->el_tty.t_ed, el->el_tty.t_speed);
(void) cfsetospeed(&el->el_tty.t_ed, el->el_tty.t_speed);
}
if (tty__cooked_mode(&el->el_tty.t_ts)) {
if ((el->el_tty.t_ts.c_cflag != el->el_tty.t_ex.c_cflag) &&
(el->el_tty.t_ts.c_cflag != el->el_tty.t_ed.c_cflag)) {
el->el_tty.t_ed.c_cflag =
el->el_tty.t_ts.c_cflag;
el->el_tty.t_ed.c_cflag &=
~el->el_tty.t_t[ED_IO][MD_CTL].t_clrmask;
el->el_tty.t_ed.c_cflag |=
el->el_tty.t_t[ED_IO][MD_CTL].t_setmask;
}
if ((el->el_tty.t_ts.c_lflag != el->el_tty.t_ex.c_lflag) &&
(el->el_tty.t_ts.c_lflag != el->el_tty.t_ed.c_lflag)) {
el->el_tty.t_ed.c_lflag =
el->el_tty.t_ts.c_lflag;
el->el_tty.t_ed.c_lflag &=
~el->el_tty.t_t[ED_IO][MD_LIN].t_clrmask;
el->el_tty.t_ed.c_lflag |=
el->el_tty.t_t[ED_IO][MD_LIN].t_setmask;
}
if ((el->el_tty.t_ts.c_iflag != el->el_tty.t_ex.c_iflag) &&
(el->el_tty.t_ts.c_iflag != el->el_tty.t_ed.c_iflag)) {
el->el_tty.t_ed.c_iflag =
el->el_tty.t_ts.c_iflag;
el->el_tty.t_ed.c_iflag &=
~el->el_tty.t_t[ED_IO][MD_INP].t_clrmask;
el->el_tty.t_ed.c_iflag |=
el->el_tty.t_t[ED_IO][MD_INP].t_setmask;
}
if ((el->el_tty.t_ts.c_oflag != el->el_tty.t_ex.c_oflag) &&
(el->el_tty.t_ts.c_oflag != el->el_tty.t_ed.c_oflag)) {
el->el_tty.t_ed.c_oflag =
el->el_tty.t_ts.c_oflag;
el->el_tty.t_ed.c_oflag &=
~el->el_tty.t_t[ED_IO][MD_OUT].t_clrmask;
el->el_tty.t_ed.c_oflag |=
el->el_tty.t_t[ED_IO][MD_OUT].t_setmask;
}
int i;
for (i = MD_INP; i <= MD_LIN; i++)
tty_update_flags(el, i);
if (tty__gettabs(&el->el_tty.t_ex) == 0)
el->el_tty.t_tabs = 0;
else
el->el_tty.t_tabs = EL_CAN_TAB ? 1 : 0;
{
int i;
tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]);
/*
* Check if the user made any changes.
* If he did, then propagate the changes to the
* edit and execute data structures.
*/
for (i = 0; i < C_NCC; i++)
if (el->el_tty.t_c[TS_IO][i] !=
el->el_tty.t_c[EX_IO][i])
break;
tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]);
if (i != C_NCC) {
/*
* Check if the user made any changes.
* If he did, then propagate the changes to the
* edit and execute data structures.
*/
* Propagate changes only to the unprotected
* chars that have been modified just now.
*/
for (i = 0; i < C_NCC; i++)
if (el->el_tty.t_c[TS_IO][i] !=
el->el_tty.t_c[EX_IO][i])
break;
tty_update_char(el, ED_IO, i);
if (i != C_NCC) {
/*
* Propagate changes only to the unprotected
* chars that have been modified just now.
*/
for (i = 0; i < C_NCC; i++) {
if (!((el->el_tty.t_t[ED_IO][MD_CHAR].t_setmask & C_SH(i)))
&& (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i]))
el->el_tty.t_c[ED_IO][i] = el->el_tty.t_c[TS_IO][i];
if (el->el_tty.t_t[ED_IO][MD_CHAR].t_clrmask & C_SH(i))
el->el_tty.t_c[ED_IO][i] = el->el_tty.t_vdisable;
}
tty_bind_char(el, 0);
tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]);
tty_bind_char(el, 0);
tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]);
for (i = 0; i < C_NCC; i++) {
if (!((el->el_tty.t_t[EX_IO][MD_CHAR].t_setmask & C_SH(i)))
&& (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i]))
el->el_tty.t_c[EX_IO][i] = el->el_tty.t_c[TS_IO][i];
if (el->el_tty.t_t[EX_IO][MD_CHAR].t_clrmask & C_SH(i))
el->el_tty.t_c[EX_IO][i] = el->el_tty.t_vdisable;
}
}
for (i = 0; i < C_NCC; i++)
tty_update_char(el, EX_IO, i);
tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
}
}
if (el->el_tty.t_mode == EX_IO)
el->el_tty.t_ex = el->el_tty.t_ts;
if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ed) == -1) {
#ifdef DEBUG_TTY
(void) fprintf(el->el_errfile, "tty_rawmode: tty_setty: %s\n",
(void) fprintf(el->el_errfile, "%s: tty_setty: %s\n", __func__,
strerror(errno));
#endif /* DEBUG_TTY */
return (-1);
return -1;
}
el->el_tty.t_mode = ED_IO;
return (0);
return 0;
}
@ -1038,21 +1067,20 @@ tty_cookedmode(EditLine *el)
{ /* set tty in normal setup */
if (el->el_tty.t_mode == EX_IO)
return (0);
return 0;
if (el->el_flags & EDIT_DISABLED)
return (0);
return 0;
if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ex) == -1) {
#ifdef DEBUG_TTY
(void) fprintf(el->el_errfile,
"tty_cookedmode: tty_setty: %s\n",
(void) fprintf(el->el_errfile, "%s: tty_setty: %s\n", __func__,
strerror(errno));
#endif /* DEBUG_TTY */
return (-1);
return -1;
}
el->el_tty.t_mode = EX_IO;
return (0);
return 0;
}
@ -1063,31 +1091,21 @@ protected int
tty_quotemode(EditLine *el)
{
if (el->el_tty.t_mode == QU_IO)
return (0);
return 0;
el->el_tty.t_qu = el->el_tty.t_ed;
el->el_tty.t_qu.c_iflag &= ~el->el_tty.t_t[QU_IO][MD_INP].t_clrmask;
el->el_tty.t_qu.c_iflag |= el->el_tty.t_t[QU_IO][MD_INP].t_setmask;
el->el_tty.t_qu.c_oflag &= ~el->el_tty.t_t[QU_IO][MD_OUT].t_clrmask;
el->el_tty.t_qu.c_oflag |= el->el_tty.t_t[QU_IO][MD_OUT].t_setmask;
el->el_tty.t_qu.c_cflag &= ~el->el_tty.t_t[QU_IO][MD_CTL].t_clrmask;
el->el_tty.t_qu.c_cflag |= el->el_tty.t_t[QU_IO][MD_CTL].t_setmask;
el->el_tty.t_qu.c_lflag &= ~el->el_tty.t_t[QU_IO][MD_LIN].t_clrmask;
el->el_tty.t_qu.c_lflag |= el->el_tty.t_t[QU_IO][MD_LIN].t_setmask;
tty_setup_flags(el, &el->el_tty.t_qu, QU_IO);
if (tty_setty(el, TCSADRAIN, &el->el_tty.t_qu) == -1) {
#ifdef DEBUG_TTY
(void) fprintf(el->el_errfile, "QuoteModeOn: tty_setty: %s\n",
(void) fprintf(el->el_errfile, "%s: tty_setty: %s\n", __func__,
strerror(errno));
#endif /* DEBUG_TTY */
return (-1);
return -1;
}
el->el_tty.t_mode = QU_IO;
return (0);
return 0;
}
@ -1099,16 +1117,16 @@ tty_noquotemode(EditLine *el)
{
if (el->el_tty.t_mode != QU_IO)
return (0);
return 0;
if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ed) == -1) {
#ifdef DEBUG_TTY
(void) fprintf(el->el_errfile, "QuoteModeOff: tty_setty: %s\n",
(void) fprintf(el->el_errfile, "%s: tty_setty: %s\n", __func__,
strerror(errno));
#endif /* DEBUG_TTY */
return (-1);
return -1;
}
el->el_tty.t_mode = ED_IO;
return (0);
return 0;
}
@ -1117,19 +1135,20 @@ tty_noquotemode(EditLine *el)
*/
protected int
/*ARGSUSED*/
tty_stty(EditLine *el, int argc __unused, const char **argv)
tty_stty(EditLine *el, int argc __attribute__((__unused__)), const Char **argv)
{
const ttymodes_t *m;
char x;
int aflag = 0;
const char *s, *d;
const char *name;
const Char *s, *d;
char name[EL_BUFSIZ];
struct termios *tios = &el->el_tty.t_ex;
int z = EX_IO;
if (argv == NULL)
return (-1);
name = *argv++;
return -1;
strncpy(name, ct_encode_string(*argv++, &el->el_scratch), sizeof(name));
name[sizeof(name) - 1] = '\0';
while (argv && *argv && argv[0][0] == '-' && argv[0][2] == '\0')
switch (argv[0][1]) {
@ -1156,7 +1175,7 @@ tty_stty(EditLine *el, int argc __unused, const char **argv)
(void) fprintf(el->el_errfile,
"%s: Unknown switch `%c'.\n",
name, argv[0][1]);
return (-1);
return -1;
}
if (!argv || !*argv) {
@ -1174,8 +1193,9 @@ tty_stty(EditLine *el, int argc __unused, const char **argv)
if (i != -1) {
x = (el->el_tty.t_t[z][i].t_setmask & m->m_value)
? '+' : '\0';
x = (el->el_tty.t_t[z][i].t_clrmask & m->m_value)
? '-' : x;
if (el->el_tty.t_t[z][i].t_clrmask & m->m_value)
x = '-';
} else {
x = '\0';
}
@ -1184,7 +1204,8 @@ tty_stty(EditLine *el, int argc __unused, const char **argv)
cu = strlen(m->m_name) + (x != '\0') + 1;
if (len + cu >= (size_t)el->el_term.t_size.h) {
if (len + cu >=
(size_t)el->el_terminal.t_size.h) {
(void) fprintf(el->el_outfile, "\n%*s",
(int)st, "");
len = st + cu;
@ -1200,41 +1221,43 @@ tty_stty(EditLine *el, int argc __unused, const char **argv)
}
}
(void) fprintf(el->el_outfile, "\n");
return (0);
return 0;
}
while (argv && (s = *argv++)) {
const char *p;
const Char *p;
switch (*s) {
case '+':
case '-':
x = *s++;
x = (char)*s++;
break;
default:
x = '\0';
break;
}
d = s;
p = strchr(s, '=');
p = Strchr(s, '=');
for (m = ttymodes; m->m_name; m++)
if ((p ? strncmp(m->m_name, d, (size_t)(p - d)) :
strcmp(m->m_name, d)) == 0 &&
if ((p ? strncmp(m->m_name, ct_encode_string(d,
&el->el_scratch), (size_t)(p - d)) :
strcmp(m->m_name, ct_encode_string(d,
&el->el_scratch))) == 0 &&
(p == NULL || m->m_type == MD_CHAR))
break;
if (!m->m_name) {
(void) fprintf(el->el_errfile,
"%s: Invalid argument `%s'.\n", name, d);
return (-1);
"%s: Invalid argument `" FSTR "'.\n", name, d);
return -1;
}
if (p) {
int c = ffs((int)m->m_value);
int v = *++p ? parse__escape((const char **) &p) :
int v = *++p ? parse__escape(&p) :
el->el_tty.t_vdisable;
assert(c != 0);
c--;
c = tty__getcharindex(c);
assert(c != -1);
tios->c_cc[c] = v;
tios->c_cc[c] = (cc_t)v;
continue;
}
switch (x) {
@ -1253,17 +1276,18 @@ tty_stty(EditLine *el, int argc __unused, const char **argv)
}
}
tty_setup_flags(el, tios, z);
if (el->el_tty.t_mode == z) {
if (tty_setty(el, TCSADRAIN, tios) == -1) {
#ifdef DEBUG_TTY
(void) fprintf(el->el_errfile,
"tty_stty: tty_setty: %s\n", strerror(errno));
(void) fprintf(el->el_errfile, "%s: tty_setty: %s\n",
__func__, strerror(errno));
#endif /* DEBUG_TTY */
return (-1);
return -1;
}
}
return (0);
return 0;
}
@ -1290,3 +1314,14 @@ tty_printchar(EditLine *el, unsigned char *s)
(void) fprintf(el->el_errfile, "\n");
}
#endif /* notyet */
private void
tty_setup_flags(EditLine *el, struct termios *tios, int mode)
{
int kind;
for (kind = MD_INP; kind <= MD_LIN; kind++) {
tcflag_t *f = tty__get_flag(tios, kind);
*f = tty_update_flag(el, *f, mode, kind);
}
}

View File

@ -1,3 +1,5 @@
/* $NetBSD: tty.h,v 1.15 2014/05/19 19:54:12 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
@ -30,7 +32,6 @@
* SUCH DAMAGE.
*
* @(#)tty.h 8.1 (Berkeley) 6/4/93
* $NetBSD: tty.h,v 1.11 2005/06/01 11:37:52 lukem Exp $
* $FreeBSD$
*/
@ -40,6 +41,7 @@
#ifndef _h_el_tty
#define _h_el_tty
#include "sys.h"
#include "histedit.h"
#include <termios.h>
#include <unistd.h>
@ -430,7 +432,7 @@
#define C_MIN 23
#define C_TIME 24
#define C_NCC 25
#define C_SH(A) (1 << (A))
#define C_SH(A) ((unsigned int)(1 << (A)))
/*
* Terminal dependend data structures
@ -441,6 +443,7 @@
#define QU_IO 2 /* used only for quoted chars */
#define NN_IO 3 /* The number of entries */
/* Don't re-order */
#define MD_INP 0
#define MD_OUT 1
#define MD_CTL 2
@ -458,7 +461,7 @@ typedef unsigned char ttychar_t[NN_IO][C_NCC];
protected int tty_init(EditLine *);
protected void tty_end(EditLine *);
protected int tty_stty(EditLine *, int, const char **);
protected int tty_stty(EditLine *, int, const Char **);
protected int tty_rawmode(EditLine *);
protected int tty_cookedmode(EditLine *);
protected int tty_quotemode(EditLine *);
@ -468,7 +471,7 @@ protected void tty_bind_char(EditLine *, int);
typedef struct {
ttyperm_t t_t;
ttychar_t t_c;
struct termios t_ex, t_ed, t_ts;
struct termios t_or, t_ex, t_ed, t_ts;
int t_tabs;
int t_eight;
speed_t t_speed;

View File

@ -1,3 +1,5 @@
/* $NetBSD: vi.c,v 1.45 2014/06/18 18:12:28 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
@ -28,12 +30,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $NetBSD: vi.c,v 1.30 2009/02/21 23:31:56 christos Exp $
*/
#include "config.h"
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>
#include <sys/wait.h>
#if !defined(lint) && !defined(SCCSID)
#if 0
static char sccsid[] = "@(#)vi.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: vi.c,v 1.45 2014/06/18 18:12:28 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@ -41,23 +51,21 @@ __FBSDID("$FreeBSD$");
/*
* vi.c: Vi mode commands.
*/
#include <sys/wait.h>
#include "sys.h"
#include "el.h"
private el_action_t cv_action(EditLine *, int);
private el_action_t cv_paste(EditLine *, int);
private el_action_t cv_action(EditLine *, Int);
private el_action_t cv_paste(EditLine *, Int);
/* cv_action():
* Handle vi actions.
*/
private el_action_t
cv_action(EditLine *el, int c)
cv_action(EditLine *el, Int c)
{
if (el->el_chared.c_vcmd.action != NOP) {
/* 'cc', 'dd' and (possibly) friends */
if (c != el->el_chared.c_vcmd.action)
if (c != (Int)el->el_chared.c_vcmd.action)
return CC_ERROR;
if (!(c & YANK))
@ -73,24 +81,24 @@ cv_action(EditLine *el, int c)
if (c & INSERT)
el->el_map.current = el->el_map.key;
return (CC_REFRESH);
return CC_REFRESH;
}
el->el_chared.c_vcmd.pos = el->el_line.cursor;
el->el_chared.c_vcmd.action = c;
return (CC_ARGHACK);
return CC_ARGHACK;
}
/* cv_paste():
* Paste previous deletion before or after the cursor
*/
private el_action_t
cv_paste(EditLine *el, int c)
cv_paste(EditLine *el, Int c)
{
c_kill_t *k = &el->el_chared.c_kill;
size_t len = (size_t)(k->last - k->buf);
if (k->buf == NULL || len == 0)
return (CC_ERROR);
return CC_ERROR;
#ifdef DEBUG_PASTE
(void) fprintf(el->el_errfile, "Paste: \"%.*s\"\n", (int)len, k->buf);
#endif
@ -102,10 +110,11 @@ cv_paste(EditLine *el, int c)
c_insert(el, (int)len);
if (el->el_line.cursor + len > el->el_line.lastchar)
return (CC_ERROR);
(void) memcpy(el->el_line.cursor, k->buf, len);
return CC_ERROR;
(void) memcpy(el->el_line.cursor, k->buf, len *
sizeof(*el->el_line.cursor));
return (CC_REFRESH);
return CC_REFRESH;
}
@ -115,10 +124,10 @@ cv_paste(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
vi_paste_next(EditLine *el, int c __unused)
vi_paste_next(EditLine *el, Int c __attribute__((__unused__)))
{
return (cv_paste(el, 0));
return cv_paste(el, 0);
}
@ -128,10 +137,10 @@ vi_paste_next(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
vi_paste_prev(EditLine *el, int c __unused)
vi_paste_prev(EditLine *el, Int c __attribute__((__unused__)))
{
return (cv_paste(el, 1));
return cv_paste(el, 1);
}
@ -141,11 +150,11 @@ vi_paste_prev(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
vi_prev_big_word(EditLine *el, int c)
vi_prev_big_word(EditLine *el, Int c __attribute__((__unused__)))
{
if (el->el_line.cursor == el->el_line.buffer)
return (CC_ERROR);
return CC_ERROR;
el->el_line.cursor = cv_prev_word(el->el_line.cursor,
el->el_line.buffer,
@ -154,9 +163,9 @@ vi_prev_big_word(EditLine *el, int c)
if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el);
return (CC_REFRESH);
return CC_REFRESH;
}
return (CC_CURSOR);
return CC_CURSOR;
}
@ -166,11 +175,11 @@ vi_prev_big_word(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
vi_prev_word(EditLine *el, int c __unused)
vi_prev_word(EditLine *el, Int c __attribute__((__unused__)))
{
if (el->el_line.cursor == el->el_line.buffer)
return (CC_ERROR);
return CC_ERROR;
el->el_line.cursor = cv_prev_word(el->el_line.cursor,
el->el_line.buffer,
@ -179,9 +188,9 @@ vi_prev_word(EditLine *el, int c __unused)
if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el);
return (CC_REFRESH);
return CC_REFRESH;
}
return (CC_CURSOR);
return CC_CURSOR;
}
@ -191,11 +200,11 @@ vi_prev_word(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
vi_next_big_word(EditLine *el, int c)
vi_next_big_word(EditLine *el, Int c __attribute__((__unused__)))
{
if (el->el_line.cursor >= el->el_line.lastchar - 1)
return (CC_ERROR);
return CC_ERROR;
el->el_line.cursor = cv_next_word(el, el->el_line.cursor,
el->el_line.lastchar, el->el_state.argument, cv__isWord);
@ -203,9 +212,9 @@ vi_next_big_word(EditLine *el, int c)
if (el->el_map.type == MAP_VI)
if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el);
return (CC_REFRESH);
return CC_REFRESH;
}
return (CC_CURSOR);
return CC_CURSOR;
}
@ -215,11 +224,11 @@ vi_next_big_word(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
vi_next_word(EditLine *el, int c __unused)
vi_next_word(EditLine *el, Int c __attribute__((__unused__)))
{
if (el->el_line.cursor >= el->el_line.lastchar - 1)
return (CC_ERROR);
return CC_ERROR;
el->el_line.cursor = cv_next_word(el, el->el_line.cursor,
el->el_line.lastchar, el->el_state.argument, cv__isword);
@ -227,9 +236,9 @@ vi_next_word(EditLine *el, int c __unused)
if (el->el_map.type == MAP_VI)
if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el);
return (CC_REFRESH);
return CC_REFRESH;
}
return (CC_CURSOR);
return CC_CURSOR;
}
@ -238,20 +247,20 @@ vi_next_word(EditLine *el, int c __unused)
* [~]
*/
protected el_action_t
vi_change_case(EditLine *el, int c)
vi_change_case(EditLine *el, Int c)
{
int i;
if (el->el_line.cursor >= el->el_line.lastchar)
return (CC_ERROR);
return CC_ERROR;
cv_undo(el);
for (i = 0; i < el->el_state.argument; i++) {
c = *(unsigned char *)el->el_line.cursor;
if (isupper(c))
*el->el_line.cursor = tolower(c);
else if (islower(c))
*el->el_line.cursor = toupper(c);
c = *el->el_line.cursor;
if (Isupper(c))
*el->el_line.cursor = Tolower(c);
else if (Islower(c))
*el->el_line.cursor = Toupper(c);
if (++el->el_line.cursor >= el->el_line.lastchar) {
el->el_line.cursor--;
@ -270,14 +279,14 @@ vi_change_case(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
vi_change_meta(EditLine *el, int c __unused)
vi_change_meta(EditLine *el, Int c __attribute__((__unused__)))
{
/*
* Delete with insert == change: first we delete and then we leave in
* insert mode.
*/
return (cv_action(el, DELETE | INSERT));
return cv_action(el, DELETE | INSERT);
}
@ -287,13 +296,13 @@ vi_change_meta(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
vi_insert_at_bol(EditLine *el, int c __unused)
vi_insert_at_bol(EditLine *el, Int c __attribute__((__unused__)))
{
el->el_line.cursor = el->el_line.buffer;
cv_undo(el);
el->el_map.current = el->el_map.key;
return (CC_CURSOR);
return CC_CURSOR;
}
@ -303,7 +312,7 @@ vi_insert_at_bol(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
vi_replace_char(EditLine *el, int c __unused)
vi_replace_char(EditLine *el, Int c __attribute__((__unused__)))
{
if (el->el_line.cursor >= el->el_line.lastchar)
@ -312,7 +321,7 @@ vi_replace_char(EditLine *el, int c __unused)
el->el_map.current = el->el_map.key;
el->el_state.inputmode = MODE_REPLACE_1;
cv_undo(el);
return (CC_ARGHACK);
return CC_ARGHACK;
}
@ -322,13 +331,13 @@ vi_replace_char(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
vi_replace_mode(EditLine *el, int c __unused)
vi_replace_mode(EditLine *el, Int c __attribute__((__unused__)))
{
el->el_map.current = el->el_map.key;
el->el_state.inputmode = MODE_REPLACE;
cv_undo(el);
return (CC_NORM);
return CC_NORM;
}
@ -338,12 +347,12 @@ vi_replace_mode(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
vi_substitute_char(EditLine *el, int c __unused)
vi_substitute_char(EditLine *el, Int c __attribute__((__unused__)))
{
c_delafter(el, el->el_state.argument);
el->el_map.current = el->el_map.key;
return (CC_REFRESH);
return CC_REFRESH;
}
@ -353,7 +362,7 @@ vi_substitute_char(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
vi_substitute_line(EditLine *el, int c __unused)
vi_substitute_line(EditLine *el, Int c __attribute__((__unused__)))
{
cv_undo(el);
@ -361,7 +370,7 @@ vi_substitute_line(EditLine *el, int c __unused)
(int)(el->el_line.lastchar - el->el_line.buffer));
(void) em_kill_line(el, 0);
el->el_map.current = el->el_map.key;
return (CC_REFRESH);
return CC_REFRESH;
}
@ -371,7 +380,7 @@ vi_substitute_line(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
vi_change_to_eol(EditLine *el, int c __unused)
vi_change_to_eol(EditLine *el, Int c __attribute__((__unused__)))
{
cv_undo(el);
@ -379,7 +388,7 @@ vi_change_to_eol(EditLine *el, int c __unused)
(int)(el->el_line.lastchar - el->el_line.cursor));
(void) ed_kill_line(el, 0);
el->el_map.current = el->el_map.key;
return (CC_REFRESH);
return CC_REFRESH;
}
@ -389,12 +398,12 @@ vi_change_to_eol(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
vi_insert(EditLine *el, int c __unused)
vi_insert(EditLine *el, Int c __attribute__((__unused__)))
{
el->el_map.current = el->el_map.key;
cv_undo(el);
return (CC_NORM);
return CC_NORM;
}
@ -404,7 +413,7 @@ vi_insert(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
vi_add(EditLine *el, int c __unused)
vi_add(EditLine *el, Int c __attribute__((__unused__)))
{
int ret;
@ -419,7 +428,7 @@ vi_add(EditLine *el, int c __unused)
cv_undo(el);
return (ret);
return (el_action_t)ret;
}
@ -429,13 +438,13 @@ vi_add(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
vi_add_at_eol(EditLine *el, int c __unused)
vi_add_at_eol(EditLine *el, Int c __attribute__((__unused__)))
{
el->el_map.current = el->el_map.key;
el->el_line.cursor = el->el_line.lastchar;
cv_undo(el);
return (CC_CURSOR);
return CC_CURSOR;
}
@ -445,10 +454,10 @@ vi_add_at_eol(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
vi_delete_meta(EditLine *el, int c __unused)
vi_delete_meta(EditLine *el, Int c __attribute__((__unused__)))
{
return (cv_action(el, DELETE));
return cv_action(el, DELETE);
}
@ -458,11 +467,11 @@ vi_delete_meta(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
vi_end_big_word(EditLine *el, int c)
vi_end_big_word(EditLine *el, Int c __attribute__((__unused__)))
{
if (el->el_line.cursor == el->el_line.lastchar)
return (CC_ERROR);
return CC_ERROR;
el->el_line.cursor = cv__endword(el->el_line.cursor,
el->el_line.lastchar, el->el_state.argument, cv__isWord);
@ -470,9 +479,9 @@ vi_end_big_word(EditLine *el, int c)
if (el->el_chared.c_vcmd.action != NOP) {
el->el_line.cursor++;
cv_delfini(el);
return (CC_REFRESH);
return CC_REFRESH;
}
return (CC_CURSOR);
return CC_CURSOR;
}
@ -482,11 +491,11 @@ vi_end_big_word(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
vi_end_word(EditLine *el, int c __unused)
vi_end_word(EditLine *el, Int c __attribute__((__unused__)))
{
if (el->el_line.cursor == el->el_line.lastchar)
return (CC_ERROR);
return CC_ERROR;
el->el_line.cursor = cv__endword(el->el_line.cursor,
el->el_line.lastchar, el->el_state.argument, cv__isword);
@ -494,9 +503,9 @@ vi_end_word(EditLine *el, int c __unused)
if (el->el_chared.c_vcmd.action != NOP) {
el->el_line.cursor++;
cv_delfini(el);
return (CC_REFRESH);
return CC_REFRESH;
}
return (CC_CURSOR);
return CC_CURSOR;
}
@ -506,7 +515,7 @@ vi_end_word(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
vi_undo(EditLine *el, int c __unused)
vi_undo(EditLine *el, Int c __attribute__((__unused__)))
{
c_undo_t un = el->el_chared.c_undo;
@ -523,7 +532,7 @@ vi_undo(EditLine *el, int c __unused)
el->el_line.cursor = un.buf + un.cursor;
el->el_line.lastchar = un.buf + un.len;
return (CC_REFRESH);
return CC_REFRESH;
}
@ -533,7 +542,7 @@ vi_undo(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
vi_command_mode(EditLine *el, int c __unused)
vi_command_mode(EditLine *el, Int c __attribute__((__unused__)))
{
/* [Esc] cancels pending action */
@ -548,7 +557,7 @@ vi_command_mode(EditLine *el, int c __unused)
if (el->el_line.cursor > el->el_line.buffer)
el->el_line.cursor--;
#endif
return (CC_CURSOR);
return CC_CURSOR;
}
@ -557,7 +566,7 @@ vi_command_mode(EditLine *el, int c __unused)
* [0]
*/
protected el_action_t
vi_zero(EditLine *el, int c)
vi_zero(EditLine *el, Int c)
{
if (el->el_state.doingarg)
@ -566,9 +575,9 @@ vi_zero(EditLine *el, int c)
el->el_line.cursor = el->el_line.buffer;
if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el);
return (CC_REFRESH);
return CC_REFRESH;
}
return (CC_CURSOR);
return CC_CURSOR;
}
@ -578,15 +587,15 @@ vi_zero(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
vi_delete_prev_char(EditLine *el, int c __unused)
vi_delete_prev_char(EditLine *el, Int c __attribute__((__unused__)))
{
if (el->el_line.cursor <= el->el_line.buffer)
return (CC_ERROR);
return CC_ERROR;
c_delbefore1(el);
el->el_line.cursor--;
return (CC_REFRESH);
return CC_REFRESH;
}
@ -596,32 +605,32 @@ vi_delete_prev_char(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
vi_list_or_eof(EditLine *el, int c)
vi_list_or_eof(EditLine *el, Int c)
{
if (el->el_line.cursor == el->el_line.lastchar) {
if (el->el_line.cursor == el->el_line.buffer) {
term_writec(el, c); /* then do a EOF */
return (CC_EOF);
terminal_writec(el, c); /* then do a EOF */
return CC_EOF;
} else {
/*
* Here we could list completions, but it is an
* error right now
*/
term_beep(el);
return (CC_ERROR);
terminal_beep(el);
return CC_ERROR;
}
} else {
#ifdef notyet
re_goto_bottom(el);
*el->el_line.lastchar = '\0'; /* just in case */
return (CC_LIST_CHOICES);
return CC_LIST_CHOICES;
#else
/*
* Just complain for now.
*/
term_beep(el);
return (CC_ERROR);
terminal_beep(el);
return CC_ERROR;
#endif
}
}
@ -633,9 +642,9 @@ vi_list_or_eof(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
vi_kill_line_prev(EditLine *el, int c __unused)
vi_kill_line_prev(EditLine *el, Int c __attribute__((__unused__)))
{
char *kp, *cp;
Char *kp, *cp;
cp = el->el_line.buffer;
kp = el->el_chared.c_kill.buf;
@ -644,7 +653,7 @@ vi_kill_line_prev(EditLine *el, int c __unused)
el->el_chared.c_kill.last = kp;
c_delbefore(el, (int)(el->el_line.cursor - el->el_line.buffer));
el->el_line.cursor = el->el_line.buffer; /* zap! */
return (CC_REFRESH);
return CC_REFRESH;
}
@ -654,10 +663,10 @@ vi_kill_line_prev(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
vi_search_prev(EditLine *el, int c __unused)
vi_search_prev(EditLine *el, Int c __attribute__((__unused__)))
{
return (cv_search(el, ED_SEARCH_PREV_HISTORY));
return cv_search(el, ED_SEARCH_PREV_HISTORY);
}
@ -667,10 +676,10 @@ vi_search_prev(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
vi_search_next(EditLine *el, int c __unused)
vi_search_next(EditLine *el, Int c __attribute__((__unused__)))
{
return (cv_search(el, ED_SEARCH_NEXT_HISTORY));
return cv_search(el, ED_SEARCH_NEXT_HISTORY);
}
@ -680,13 +689,13 @@ vi_search_next(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
vi_repeat_search_next(EditLine *el, int c __unused)
vi_repeat_search_next(EditLine *el, Int c __attribute__((__unused__)))
{
if (el->el_search.patlen == 0)
return (CC_ERROR);
return CC_ERROR;
else
return (cv_repeat_srch(el, el->el_search.patdir));
return cv_repeat_srch(el, el->el_search.patdir);
}
@ -696,11 +705,11 @@ vi_repeat_search_next(EditLine *el, int c __unused)
*/
/*ARGSUSED*/
protected el_action_t
vi_repeat_search_prev(EditLine *el, int c __unused)
vi_repeat_search_prev(EditLine *el, Int c __attribute__((__unused__)))
{
if (el->el_search.patlen == 0)
return (CC_ERROR);
return CC_ERROR;
else
return (cv_repeat_srch(el,
el->el_search.patdir == ED_SEARCH_PREV_HISTORY ?
@ -714,7 +723,7 @@ vi_repeat_search_prev(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
vi_next_char(EditLine *el, int c __unused)
vi_next_char(EditLine *el, Int c __attribute__((__unused__)))
{
return cv_csearch(el, CHAR_FWD, -1, el->el_state.argument, 0);
}
@ -726,7 +735,7 @@ vi_next_char(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
vi_prev_char(EditLine *el, int c __unused)
vi_prev_char(EditLine *el, Int c __attribute__((__unused__)))
{
return cv_csearch(el, CHAR_BACK, -1, el->el_state.argument, 0);
}
@ -738,7 +747,7 @@ vi_prev_char(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
vi_to_next_char(EditLine *el, int c __unused)
vi_to_next_char(EditLine *el, Int c __attribute__((__unused__)))
{
return cv_csearch(el, CHAR_FWD, -1, el->el_state.argument, 1);
}
@ -750,7 +759,7 @@ vi_to_next_char(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
vi_to_prev_char(EditLine *el, int c __unused)
vi_to_prev_char(EditLine *el, Int c __attribute__((__unused__)))
{
return cv_csearch(el, CHAR_BACK, -1, el->el_state.argument, 1);
}
@ -762,7 +771,7 @@ vi_to_prev_char(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
vi_repeat_next_char(EditLine *el, int c __unused)
vi_repeat_next_char(EditLine *el, Int c __attribute__((__unused__)))
{
return cv_csearch(el, el->el_search.chadir, el->el_search.chacha,
@ -776,7 +785,7 @@ vi_repeat_next_char(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
vi_repeat_prev_char(EditLine *el, int c __unused)
vi_repeat_prev_char(EditLine *el, Int c __attribute__((__unused__)))
{
el_action_t r;
int dir = el->el_search.chadir;
@ -794,20 +803,20 @@ vi_repeat_prev_char(EditLine *el, int c __unused)
*/
protected el_action_t
/*ARGSUSED*/
vi_match(EditLine *el, int c)
vi_match(EditLine *el, Int c __attribute__((__unused__)))
{
const char match_chars[] = "()[]{}";
char *cp;
const Char match_chars[] = STR("()[]{}");
Char *cp;
size_t delta, i, count;
char o_ch, c_ch;
Char o_ch, c_ch;
*el->el_line.lastchar = '\0'; /* just in case */
i = strcspn(el->el_line.cursor, match_chars);
i = Strcspn(el->el_line.cursor, match_chars);
o_ch = el->el_line.cursor[i];
if (o_ch == 0)
return CC_ERROR;
delta = strchr(match_chars, o_ch) - match_chars;
delta = (size_t)(Strchr(match_chars, o_ch) - match_chars);
c_ch = match_chars[delta ^ 1];
count = 1;
delta = 1 - (delta & 1) * 2;
@ -830,9 +839,9 @@ vi_match(EditLine *el, int c)
if (delta > 0)
el->el_line.cursor++;
cv_delfini(el);
return (CC_REFRESH);
return CC_REFRESH;
}
return (CC_CURSOR);
return CC_CURSOR;
}
/* vi_undo_line():
@ -841,7 +850,7 @@ vi_match(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
vi_undo_line(EditLine *el, int c)
vi_undo_line(EditLine *el, Int c __attribute__((__unused__)))
{
cv_undo(el);
@ -855,7 +864,7 @@ vi_undo_line(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
vi_to_column(EditLine *el, int c)
vi_to_column(EditLine *el, Int c __attribute__((__unused__)))
{
el->el_line.cursor = el->el_line.buffer;
@ -869,7 +878,7 @@ vi_to_column(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
vi_yank_end(EditLine *el, int c)
vi_yank_end(EditLine *el, Int c __attribute__((__unused__)))
{
cv_yank(el, el->el_line.cursor,
@ -883,7 +892,7 @@ vi_yank_end(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
vi_yank(EditLine *el, int c)
vi_yank(EditLine *el, Int c __attribute__((__unused__)))
{
return cv_action(el, YANK);
@ -895,7 +904,7 @@ vi_yank(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
vi_comment_out(EditLine *el, int c)
vi_comment_out(EditLine *el, Int c __attribute__((__unused__)))
{
el->el_line.cursor = el->el_line.buffer;
@ -913,30 +922,24 @@ vi_comment_out(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
vi_alias(EditLine *el, int c)
vi_alias(EditLine *el, Int c __attribute__((__unused__)))
{
#ifdef __weak_extern
char alias_name[3];
char *alias_text;
extern char *get_alias_text(const char *);
__weak_extern(get_alias_text);
const char *alias_text;
if (get_alias_text == 0) {
if (el->el_chared.c_aliasfun == NULL)
return CC_ERROR;
}
alias_name[0] = '_';
alias_name[2] = 0;
if (el_getc(el, &alias_name[1]) != 1)
return CC_ERROR;
alias_text = get_alias_text(alias_name);
alias_text = (*el->el_chared.c_aliasfun)(el->el_chared.c_aliasarg,
alias_name);
if (alias_text != NULL)
el_push(el, alias_text);
FUN(el,push)(el, ct_decode_string(alias_text, &el->el_scratch));
return CC_NORM;
#else
return CC_ERROR;
#endif
}
/* vi_to_history_line():
@ -945,14 +948,14 @@ vi_alias(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
vi_to_history_line(EditLine *el, int c)
vi_to_history_line(EditLine *el, Int c __attribute__((__unused__)))
{
int sv_event_no = el->el_history.eventno;
el_action_t rval;
if (el->el_history.eventno == 0) {
(void) strncpy(el->el_history.buf, el->el_line.buffer,
(void) Strncpy(el->el_history.buf, el->el_line.buffer,
EL_BUFSIZ);
el->el_history.last = el->el_history.buf +
(el->el_line.lastchar - el->el_line.buffer);
@ -990,14 +993,16 @@ vi_to_history_line(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
vi_histedit(EditLine *el, int c)
vi_histedit(EditLine *el, Int c __attribute__((__unused__)))
{
int fd;
pid_t pid;
ssize_t st;
int status;
char tempfile[] = "/tmp/histedit.XXXXXXXXXX";
char *cp;
char *cp = NULL;
size_t len;
Char *line = NULL;
if (el->el_state.doingarg) {
if (vi_to_history_line(el, 0) == CC_ERROR)
@ -1007,15 +1012,25 @@ vi_histedit(EditLine *el, int c)
fd = mkstemp(tempfile);
if (fd < 0)
return CC_ERROR;
cp = el->el_line.buffer;
write(fd, cp, (size_t)(el->el_line.lastchar - cp));
write(fd, "\n", 1);
len = (size_t)(el->el_line.lastchar - el->el_line.buffer);
#define TMP_BUFSIZ (EL_BUFSIZ * MB_LEN_MAX)
cp = el_malloc(TMP_BUFSIZ * sizeof(*cp));
if (cp == NULL)
goto error;
line = el_malloc(len * sizeof(*line) + 1);
if (line == NULL)
goto error;
Strncpy(line, el->el_line.buffer, len);
line[len] = '\0';
ct_wcstombs(cp, line, TMP_BUFSIZ - 1);
cp[TMP_BUFSIZ - 1] = '\0';
len = strlen(cp);
write(fd, cp, len);
write(fd, "\n", (size_t)1);
pid = fork();
switch (pid) {
case -1:
close(fd);
unlink(tempfile);
return CC_ERROR;
goto error;
case 0:
close(fd);
execlp("vi", "vi", tempfile, (char *)NULL);
@ -1025,11 +1040,20 @@ vi_histedit(EditLine *el, int c)
while (waitpid(pid, &status, 0) != pid)
continue;
lseek(fd, (off_t)0, SEEK_SET);
st = read(fd, cp, (size_t)(el->el_line.limit - cp));
if (st > 0 && cp[st - 1] == '\n')
st--;
el->el_line.cursor = cp;
el->el_line.lastchar = cp + st;
st = read(fd, cp, TMP_BUFSIZ);
if (st > 0) {
len = (size_t)(el->el_line.lastchar -
el->el_line.buffer);
len = ct_mbstowcs(el->el_line.buffer, cp, len);
if (len > 0 && el->el_line.buffer[len -1] == '\n')
--len;
}
else
len = 0;
el->el_line.cursor = el->el_line.buffer;
el->el_line.lastchar = el->el_line.buffer + len;
el_free(cp);
el_free(line);
break;
}
@ -1037,6 +1061,12 @@ vi_histedit(EditLine *el, int c)
unlink(tempfile);
/* return CC_REFRESH; */
return ed_newline(el, 0);
error:
el_free(line);
el_free(cp);
close(fd);
unlink(tempfile);
return CC_ERROR;
}
/* vi_history_word():
@ -1047,28 +1077,29 @@ vi_histedit(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
vi_history_word(EditLine *el, int c)
vi_history_word(EditLine *el, Int c __attribute__((__unused__)))
{
const char *wp = HIST_FIRST(el);
const char *wep, *wsp;
const Char *wp = HIST_FIRST(el);
const Char *wep, *wsp;
int len;
char *cp;
const char *lim;
Char *cp;
const Char *lim;
if (wp == NULL)
return CC_ERROR;
wep = wsp = 0;
do {
while (isspace((unsigned char)*wp))
while (Isspace(*wp))
wp++;
if (*wp == 0)
break;
wsp = wp;
while (*wp && !isspace((unsigned char)*wp))
while (*wp && !Isspace(*wp))
wp++;
wep = wp;
} while ((!el->el_state.doingarg || --el->el_state.argument > 0) && *wp != 0);
} while ((!el->el_state.doingarg || --el->el_state.argument > 0)
&& *wp != 0);
if (wsp == 0 || (el->el_state.doingarg && el->el_state.argument != 0))
return CC_ERROR;
@ -1096,7 +1127,7 @@ vi_history_word(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
vi_redo(EditLine *el, int c)
vi_redo(EditLine *el, Int c __attribute__((__unused__)))
{
c_redo_t *r = &el->el_chared.c_redo;
@ -1112,10 +1143,10 @@ vi_redo(EditLine *el, int c)
/* sanity */
r->pos = r->lim - 1;
r->pos[0] = 0;
el_push(el, r->buf);
FUN(el,push)(el, r->buf);
}
el->el_state.thiscmd = r->cmd;
el->el_state.thisch = r->ch;
return (*el->el_map.func[r->cmd])(el, r->ch);
return (*el->el_map.func[r->cmd])(el, r->ch);
}