Index: usr.bin/bc/bc.y =================================================================== --- usr.bin/bc/bc.y (revision 203497) +++ usr.bin/bc/bc.y (working copy) @@ -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]); Index: usr.bin/bc/extern.h =================================================================== --- usr.bin/bc/extern.h (revision 203497) +++ usr.bin/bc/extern.h (working copy) @@ -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; + Index: usr.bin/bc/Makefile =================================================================== --- usr.bin/bc/Makefile (revision 203497) +++ usr.bin/bc/Makefile (working copy) @@ -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 Index: usr.bin/bc/scan.l =================================================================== --- usr.bin/bc/scan.l (revision 203497) +++ usr.bin/bc/scan.l (working copy) @@ -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); +} +