From 5f2a1d653696ec5457bfd044f0ebcd873bfc3c80 Mon Sep 17 00:00:00 2001 From: peter Date: Sun, 11 Aug 2013 20:03:12 +0000 Subject: Update nvi-1.79 to 2.1.1-4334a8297f This is the gsoc-2011 project to clean up and backport multibyte support from other nvi forks in a form we can use. USE_WIDECHAR is on unless building for the rescue crunchgen. This should allow editing in the native locale encoding. USE_ICONV depends on make.conf having 'WITH_ICONV=YES' for now. This adds the ability to do things like edit a KOI8-R file while having $LANG set to (say) en_US.UTF-8. iconv is used to transcode the characters for display. Other points: * It uses gencat and catopen/etc instead of homegrown msg catalog stuff. * A lot of stuff has been trimmed out, eg: the perl and tcl bindings which we could never use in base anyway. * It uses ncursesw when in widechar mode. This could be interesting. GSoC info: http://www.google-melange.com/gsoc/proposal/review/google/gsoc2011/zy/1 Repo at: https://github.com/lichray/nvi2 Obtained from: Zhihao Yuan --- contrib/nvi/ex/ex_script.c | 313 ++++++++++----------------------------------- 1 file changed, 71 insertions(+), 242 deletions(-) (limited to 'contrib/nvi/ex/ex_script.c') diff --git a/contrib/nvi/ex/ex_script.c b/contrib/nvi/ex/ex_script.c index 9ca6d60..5ba0acf 100644 --- a/contrib/nvi/ex/ex_script.c +++ b/contrib/nvi/ex/ex_script.c @@ -13,32 +13,32 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)ex_script.c 10.30 (Berkeley) 9/24/96"; +static const char sccsid[] = "$Id: ex_script.c,v 10.44 2012/10/05 10:17:47 zy Exp $"; #endif /* not lint */ #include #include #include -#ifdef HAVE_SYS_SELECT_H #include -#endif #include -#ifdef HAVE_SYS5_PTY -#include -#endif -#include #include #include #include #include -#include /* XXX: OSF/1 bug: include before */ #include #include +#include +#include #include #include #include #include +#ifdef HAVE_LIBUTIL_H +#include +#else +#include +#endif #include "../common/common.h" #include "../vi/vi.h" @@ -50,7 +50,6 @@ static int sscr_getprompt __P((SCR *)); static int sscr_init __P((SCR *)); static int sscr_insert __P((SCR *)); static int sscr_matchprompt __P((SCR *, char *, size_t, size_t *)); -static int sscr_pty __P((int *, int *, char *, struct termios *, void *)); static int sscr_setprompt __P((SCR *, char *, size_t)); /* @@ -60,9 +59,7 @@ static int sscr_setprompt __P((SCR *, char *, size_t)); * PUBLIC: int ex_script __P((SCR *, EXCMD *)); */ int -ex_script(sp, cmdp) - SCR *sp; - EXCMD *cmdp; +ex_script(SCR *sp, EXCMD *cmdp) { /* Vi only command. */ if (!F_ISSET(sp, SC_VI)) { @@ -87,8 +84,7 @@ ex_script(sp, cmdp) * Create a pty setup for a shell. */ static int -sscr_init(sp) - SCR *sp; +sscr_init(SCR *sp) { SCRIPT *sc; char *sh, *sh_path; @@ -119,24 +115,16 @@ sscr_init(sp) sc->sh_term.c_oflag &= ~OPOST; sc->sh_term.c_cflag &= ~(ECHO|ECHOE|ECHONL|ECHOK); -#ifdef TIOCGWINSZ if (ioctl(STDIN_FILENO, TIOCGWINSZ, &sc->sh_win) == -1) { msgq(sp, M_SYSERR, "tcgetattr"); goto err; } - if (sscr_pty(&sc->sh_master, + if (openpty(&sc->sh_master, &sc->sh_slave, sc->sh_name, &sc->sh_term, &sc->sh_win) == -1) { - msgq(sp, M_SYSERR, "pty"); + msgq(sp, M_SYSERR, "openpty"); goto err; } -#else - if (sscr_pty(&sc->sh_master, - &sc->sh_slave, sc->sh_name, &sc->sh_term, NULL) == -1) { - msgq(sp, M_SYSERR, "pty"); - goto err; - } -#endif /* * __TK__ huh? @@ -203,17 +191,20 @@ err: if (sc->sh_master != -1) * carriage return comes; set the prompt from that line. */ static int -sscr_getprompt(sp) - SCR *sp; +sscr_getprompt(SCR *sp) { + EX_PRIVATE *exp; struct timeval tv; - CHAR_T *endp, *p, *t, buf[1024]; + char *endp, *p, *t, buf[1024]; SCRIPT *sc; fd_set fdset; recno_t lline; size_t llen, len; - u_int value; int nr; + CHAR_T *wp; + size_t wlen; + + exp = EXP(sp); FD_ZERO(&fdset); endp = buf; @@ -251,10 +242,11 @@ more: len = sizeof(buf) - (endp - buf); /* If any complete lines, push them into the file. */ for (p = t = buf; p < endp; ++p) { - value = KEY_VAL(sp, *p); - if (value == K_CR || value == K_NL) { + if (*p == '\r' || *p == '\n') { + if (CHAR2INT5(sp, exp->ibcw, t, p - t, wp, wlen)) + goto conv_err; if (db_last(sp, &lline) || - db_append(sp, 0, lline, t, p - t)) + db_append(sp, 0, lline, wp, wlen)) goto prompterr; t = p + 1; } @@ -284,7 +276,11 @@ more: len = sizeof(buf) - (endp - buf); endp = buf; /* Append the line into the file. */ - if (db_last(sp, &lline) || db_append(sp, 0, lline, buf, llen)) { + if (CHAR2INT5(sp, exp->ibcw, buf, llen, wp, wlen)) + goto conv_err; + if (db_last(sp, &lline) || db_append(sp, 0, lline, wp, wlen)) { + if (0) +conv_err: msgq(sp, M_ERR, "323|Invalid input. Truncated."); prompterr: sscr_end(sp); return (1); } @@ -299,38 +295,40 @@ prompterr: sscr_end(sp); * PUBLIC: int sscr_exec __P((SCR *, recno_t)); */ int -sscr_exec(sp, lno) - SCR *sp; - recno_t lno; +sscr_exec(SCR *sp, recno_t lno) { SCRIPT *sc; recno_t last_lno; size_t blen, len, last_len, tlen; int isempty, matchprompt, nw, rval; - char *bp, *p; + char *bp = NULL, *p; + CHAR_T *wp; + size_t wlen; /* If there's a prompt on the last line, append the command. */ if (db_last(sp, &last_lno)) return (1); - if (db_get(sp, last_lno, DBG_FATAL, &p, &last_len)) + if (db_get(sp, last_lno, DBG_FATAL, &wp, &wlen)) return (1); + INT2CHAR(sp, wp, wlen, p, last_len); if (sscr_matchprompt(sp, p, last_len, &tlen) && tlen == 0) { matchprompt = 1; - GET_SPACE_RET(sp, bp, blen, last_len + 128); + GET_SPACE_RETC(sp, bp, blen, last_len + 128); memmove(bp, p, last_len); } else matchprompt = 0; /* Get something to execute. */ - if (db_eget(sp, lno, &p, &len, &isempty)) { + if (db_eget(sp, lno, &wp, &wlen, &isempty)) { if (isempty) goto empty; goto err1; } /* Empty lines aren't interesting. */ - if (len == 0) + if (wlen == 0) goto empty; + INT2CHAR(sp, wp, wlen, p, len); /* Delete any prompt. */ if (sscr_matchprompt(sp, p, len, &tlen)) { @@ -355,9 +353,10 @@ err2: if (nw == 0) } if (matchprompt) { - ADD_SPACE_RET(sp, bp, blen, last_len + len); + ADD_SPACE_RETC(sp, bp, blen, last_len + len); memmove(bp + last_len, p, len); - if (db_set(sp, last_lno, bp, last_len + len)) + CHAR2INT(sp, bp, last_len + len, wp, wlen); + if (db_set(sp, last_lno, wp, wlen)) err1: rval = 1; } if (matchprompt) @@ -372,8 +371,7 @@ err1: rval = 1; * PUBLIC: int sscr_input __P((SCR *)); */ int -sscr_input(sp) - SCR *sp; +sscr_input(SCR *sp) { GS *gp; struct timeval poll; @@ -388,7 +386,7 @@ loop: maxfd = 0; poll.tv_usec = 0; /* Set up the input mask. */ - for (sp = gp->dq.cqh_first; sp != (void *)&gp->dq; sp = sp->q.cqe_next) + TAILQ_FOREACH(sp, gp->dq, q) if (F_ISSET(sp, SC_SCRIPT)) { FD_SET(sp->script->sh_master, &rdfd); if (sp->script->sh_master > maxfd) @@ -407,9 +405,10 @@ loop: maxfd = 0; } /* Read the input. */ - for (sp = gp->dq.cqh_first; sp != (void *)&gp->dq; sp = sp->q.cqe_next) + TAILQ_FOREACH(sp, gp->dq, q) if (F_ISSET(sp, SC_SCRIPT) && - FD_ISSET(sp->script->sh_master, &rdfd) && sscr_insert(sp)) + FD_ISSET(sp->script->sh_master, &rdfd) && + sscr_insert(sp)) return (1); goto loop; } @@ -419,25 +418,29 @@ loop: maxfd = 0; * Take a line from the shell and insert it into the file. */ static int -sscr_insert(sp) - SCR *sp; +sscr_insert(SCR *sp) { + EX_PRIVATE *exp; struct timeval tv; - CHAR_T *endp, *p, *t; + char *endp, *p, *t; SCRIPT *sc; fd_set rdfd; recno_t lno; size_t blen, len, tlen; - u_int value; int nr, rval; char *bp; + CHAR_T *wp; + size_t wlen = 0; + + exp = EXP(sp); + /* Find out where the end of the file is. */ if (db_last(sp, &lno)) return (1); #define MINREAD 1024 - GET_SPACE_RET(sp, bp, blen, MINREAD); + GET_SPACE_RETC(sp, bp, blen, MINREAD); endp = bp; /* Read the characters. */ @@ -458,10 +461,11 @@ more: switch (nr = read(sc->sh_master, endp, MINREAD)) { /* Append the lines into the file. */ for (p = t = bp; p < endp; ++p) { - value = KEY_VAL(sp, *p); - if (value == K_CR || value == K_NL) { + if (*p == '\r' || *p == '\n') { len = p - t; - if (db_append(sp, 1, lno++, t, len)) + if (CHAR2INT5(sp, exp->ibcw, t, len, wp, wlen)) + goto conv_err; + if (db_append(sp, 1, lno++, wp, wlen)) goto ret; t = p + 1; } @@ -489,15 +493,20 @@ more: switch (nr = read(sc->sh_master, endp, MINREAD)) { } if (sscr_setprompt(sp, t, len)) return (1); - if (db_append(sp, 1, lno++, t, len)) + if (CHAR2INT5(sp, exp->ibcw, t, len, wp, wlen)) + goto conv_err; + if (db_append(sp, 1, lno++, wp, wlen)) goto ret; } /* The cursor moves to EOF. */ sp->lno = lno; - sp->cno = len ? len - 1 : 0; + sp->cno = wlen ? wlen - 1 : 0; rval = vs_refresh(sp, 1); + if (0) +conv_err: msgq(sp, M_ERR, "323|Invalid input. Truncated."); + ret: FREE_SPACE(sp, bp, blen); return (rval); } @@ -509,10 +518,7 @@ ret: FREE_SPACE(sp, bp, blen); * */ static int -sscr_setprompt(sp, buf, len) - SCR *sp; - char *buf; - size_t len; +sscr_setprompt(SCR *sp, char *buf, size_t len) { SCRIPT *sc; @@ -536,10 +542,7 @@ sscr_setprompt(sp, buf, len) * parts that can change, in both content and size. */ static int -sscr_matchprompt(sp, lp, line_len, lenp) - SCR *sp; - char *lp; - size_t line_len, *lenp; +sscr_matchprompt(SCR *sp, char *lp, size_t line_len, size_t *lenp) { SCRIPT *sc; size_t prompt_len; @@ -577,8 +580,7 @@ sscr_matchprompt(sp, lp, line_len, lenp) * PUBLIC: int sscr_end __P((SCR *)); */ int -sscr_end(sp) - SCR *sp; +sscr_end(SCR *sp) { SCRIPT *sc; @@ -611,188 +613,15 @@ sscr_end(sp) * Set/clear the global scripting bit. */ static void -sscr_check(sp) - SCR *sp; +sscr_check(SCR *sp) { GS *gp; gp = sp->gp; - for (sp = gp->dq.cqh_first; sp != (void *)&gp->dq; sp = sp->q.cqe_next) + TAILQ_FOREACH(sp, gp->dq, q) if (F_ISSET(sp, SC_SCRIPT)) { F_SET(gp, G_SCRWIN); return; } F_CLR(gp, G_SCRWIN); } - -#ifdef HAVE_SYS5_PTY -static int ptys_open __P((int, char *)); -static int ptym_open __P((char *)); - -static int -sscr_pty(amaster, aslave, name, termp, winp) - int *amaster, *aslave; - char *name; - struct termios *termp; - void *winp; -{ - int master, slave, ttygid; - - /* open master terminal */ - if ((master = ptym_open(name)) < 0) { - errno = ENOENT; /* out of ptys */ - return (-1); - } - - /* open slave terminal */ - if ((slave = ptys_open(master, name)) >= 0) { - *amaster = master; - *aslave = slave; - } else { - errno = ENOENT; /* out of ptys */ - return (-1); - } - - if (termp) - (void) tcsetattr(slave, TCSAFLUSH, termp); -#ifdef TIOCSWINSZ - if (winp != NULL) - (void) ioctl(slave, TIOCSWINSZ, (struct winsize *)winp); -#endif - return (0); -} - -/* - * ptym_open -- - * This function opens a master pty and returns the file descriptor - * to it. pts_name is also returned which is the name of the slave. - */ -static int -ptym_open(pts_name) - char *pts_name; -{ - int fdm; - char *ptr, *ptsname(); - - strcpy(pts_name, _PATH_SYSV_PTY); - if ((fdm = open(pts_name, O_RDWR)) < 0 ) - return (-1); - - if (grantpt(fdm) < 0) { - close(fdm); - return (-2); - } - - if (unlockpt(fdm) < 0) { - close(fdm); - return (-3); - } - - if (unlockpt(fdm) < 0) { - close(fdm); - return (-3); - } - - /* get slave's name */ - if ((ptr = ptsname(fdm)) == NULL) { - close(fdm); - return (-3); - } - strcpy(pts_name, ptr); - return (fdm); -} - -/* - * ptys_open -- - * This function opens the slave pty. - */ -static int -ptys_open(fdm, pts_name) - int fdm; - char *pts_name; -{ - int fds; - - if ((fds = open(pts_name, O_RDWR)) < 0) { - close(fdm); - return (-5); - } - - if (ioctl(fds, I_PUSH, "ptem") < 0) { - close(fds); - close(fdm); - return (-6); - } - - if (ioctl(fds, I_PUSH, "ldterm") < 0) { - close(fds); - close(fdm); - return (-7); - } - - if (ioctl(fds, I_PUSH, "ttcompat") < 0) { - close(fds); - close(fdm); - return (-8); - } - - return (fds); -} - -#else /* !HAVE_SYS5_PTY */ - -static int -sscr_pty(amaster, aslave, name, termp, winp) - int *amaster, *aslave; - char *name; - struct termios *termp; - void *winp; -{ - static char line[] = "/dev/ptyXX"; - register char *cp1, *cp2; - register int master, slave, ttygid; - struct group *gr; - - if ((gr = getgrnam("tty")) != NULL) - ttygid = gr->gr_gid; - else - ttygid = -1; - - for (cp1 = "pqrs"; *cp1; cp1++) { - line[8] = *cp1; - for (cp2 = "0123456789abcdef"; *cp2; cp2++) { - line[5] = 'p'; - line[9] = *cp2; - if ((master = open(line, O_RDWR, 0)) == -1) { - if (errno == ENOENT) - return (-1); /* out of ptys */ - } else { - line[5] = 't'; - (void) chown(line, getuid(), ttygid); - (void) chmod(line, S_IRUSR|S_IWUSR|S_IWGRP); -#ifdef HAVE_REVOKE - (void) revoke(line); -#endif - if ((slave = open(line, O_RDWR, 0)) != -1) { - *amaster = master; - *aslave = slave; - if (name) - strcpy(name, line); - if (termp) - (void) tcsetattr(slave, - TCSAFLUSH, termp); -#ifdef TIOCSWINSZ - if (winp) - (void) ioctl(slave, TIOCSWINSZ, - (char *)winp); -#endif - return (0); - } - (void) close(master); - } - } - } - errno = ENOENT; /* out of ptys */ - return (-1); -} -#endif /* HAVE_SYS5_PTY */ -- cgit v1.1