svn commit: r203498 - head/usr.bin/bc
Xin LI
delphij at FreeBSD.org
Thu Feb 4 18:43:06 UTC 2010
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 <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]);
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 <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);
+}
+
More information about the svn-src-all
mailing list