From owner-svn-src-all@FreeBSD.ORG Thu Feb 4 18:43:06 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id EB4651065672; Thu, 4 Feb 2010 18:43:05 +0000 (UTC) (envelope-from delphij@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id DB0898FC13; Thu, 4 Feb 2010 18:43:05 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o14Ih50C098678; Thu, 4 Feb 2010 18:43:05 GMT (envelope-from delphij@svn.freebsd.org) Received: (from delphij@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o14Ih5HF098673; Thu, 4 Feb 2010 18:43:05 GMT (envelope-from delphij@svn.freebsd.org) Message-Id: <201002041843.o14Ih5HF098673@svn.freebsd.org> From: Xin LI Date: Thu, 4 Feb 2010 18:43:05 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r203498 - head/usr.bin/bc X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 04 Feb 2010 18:43:06 -0000 Author: delphij Date: Thu Feb 4 18:43:05 2010 New Revision: 203498 URL: http://svn.freebsd.org/changeset/base/203498 Log: Use libedit when interacting with tty, which provided history functionality, etc. as did by GNU bc. This also fixes an issue where BSDL bc can not handle very long line. Reported by: imp Reviewed by: imp Modified: head/usr.bin/bc/Makefile head/usr.bin/bc/bc.y head/usr.bin/bc/extern.h head/usr.bin/bc/scan.l Modified: head/usr.bin/bc/Makefile ============================================================================== --- head/usr.bin/bc/Makefile Thu Feb 4 17:35:11 2010 (r203497) +++ head/usr.bin/bc/Makefile Thu Feb 4 18:43:05 2010 (r203498) @@ -5,6 +5,9 @@ PROG= bc SRCS= bc.y scan.l CFLAGS+= -I. -I${.CURDIR} +DPADD= ${LIBEDIT} ${LIBTERMCAP} +LDADD= -ledit -ltermcap + FILES+= bc.library FILESDIR=${SHAREDIR}/misc Modified: head/usr.bin/bc/bc.y ============================================================================== --- head/usr.bin/bc/bc.y Thu Feb 4 17:35:11 2010 (r203497) +++ head/usr.bin/bc/bc.y Thu Feb 4 18:43:05 2010 (r203498) @@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -1106,6 +1107,13 @@ sigchld(int signo) } } +static const char * +dummy_prompt(void) +{ + + return (""); +} + int main(int argc, char *argv[]) { @@ -1173,6 +1181,16 @@ main(int argc, char *argv[]) dup(p[1]); close(p[0]); close(p[1]); + if (interactive) { + el = el_init("bc", stdin, stderr, stderr); + hist = history_init(); + history(hist, &he, H_SETSIZE, 100); + el_set(el, EL_HIST, history, hist); + el_set(el, EL_EDITOR, "emacs"); + el_set(el, EL_SIGNAL, 1); + el_set(el, EL_PROMPT, dummy_prompt); + el_source(el, NULL); + } } else { close(STDIN_FILENO); dup(p[0]); Modified: head/usr.bin/bc/extern.h ============================================================================== --- head/usr.bin/bc/extern.h Thu Feb 4 17:35:11 2010 (r203497) +++ head/usr.bin/bc/extern.h Thu Feb 4 18:43:05 2010 (r203498) @@ -35,4 +35,8 @@ extern int sargc; extern const char **sargv; extern const char *filename; extern char *cmdexpr; -bool interactive; +extern bool interactive; +extern EditLine *el; +extern History *hist; +extern HistEvent he; + Modified: head/usr.bin/bc/scan.l ============================================================================== --- head/usr.bin/bc/scan.l Thu Feb 4 17:35:11 2010 (r203497) +++ head/usr.bin/bc/scan.l Thu Feb 4 18:43:05 2010 (r203498) @@ -22,6 +22,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -33,13 +34,22 @@ __FBSDID("$FreeBSD$"); int lineno; +bool interactive; +HistEvent he; +EditLine *el; +History *hist; + static char *strbuf = NULL; static size_t strbuf_sz = 1; static bool dot_seen; static void init_strbuf(void); static void add_str(const char *); +static int bc_yyinput(char *, int); +#undef YY_INPUT +#define YY_INPUT(buf,retval,max) \ + (retval = bc_yyinput(buf, max)) %} %option always-interactive @@ -286,3 +296,32 @@ yywrap(void) } return (1); } + +static int +bc_yyinput(char *buf, int maxlen) +{ + int num; + if (interactive) { + const char *bp; + + if ((bp = el_gets(el, &num)) == NULL || num == 0) + return (0); + if (num > maxlen) { + el_push(el, (char *)(uintptr_t)(bp) + maxlen); + num = maxlen; + } + memcpy(buf, bp, num); + history(hist, &he, H_ENTER, bp); + } else { + int c = '*'; + for (num = 0; num < maxlen && + (c = getc(yyin)) != EOF && c != '\n'; ++num) + buf[num] = (char) c; + if (c == '\n') + buf[num++] = (char) c; + if (c == EOF && ferror(yyin)) + YY_FATAL_ERROR( "input in flex scanner failed" ); + } + return (num); +} +