diff options
Diffstat (limited to 'usr.bin/bc')
-rw-r--r-- | usr.bin/bc/Makefile | 3 | ||||
-rw-r--r-- | usr.bin/bc/bc.y | 18 | ||||
-rw-r--r-- | usr.bin/bc/extern.h | 6 | ||||
-rw-r--r-- | usr.bin/bc/scan.l | 39 |
4 files changed, 65 insertions, 1 deletions
diff --git a/usr.bin/bc/Makefile b/usr.bin/bc/Makefile index 17514ca..55f465d 100644 --- a/usr.bin/bc/Makefile +++ b/usr.bin/bc/Makefile @@ -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 diff --git a/usr.bin/bc/bc.y b/usr.bin/bc/bc.y index b00d140..b00d5ac 100644 --- a/usr.bin/bc/bc.y +++ b/usr.bin/bc/bc.y @@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$"); #include <err.h> #include <errno.h> #include <getopt.h> +#include <histedit.h> #include <limits.h> #include <search.h> #include <signal.h> @@ -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]); diff --git a/usr.bin/bc/extern.h b/usr.bin/bc/extern.h index a99c46c..d1e9fe8 100644 --- a/usr.bin/bc/extern.h +++ b/usr.bin/bc/extern.h @@ -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; + diff --git a/usr.bin/bc/scan.l b/usr.bin/bc/scan.l index 81dd862..40f8ae6 100644 --- a/usr.bin/bc/scan.l +++ b/usr.bin/bc/scan.l @@ -22,6 +22,7 @@ __FBSDID("$FreeBSD$"); #include <err.h> #include <errno.h> +#include <histedit.h> #include <signal.h> #include <stdbool.h> #include <string.h> @@ -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); +} + |