HEADSUP: BSDL bc/dc in head [Was: svn commit: r202719 - in head: . gnu/usr.bin usr.bin usr.bin/bc usr.bin/bc/USD.doc usr.bin/dc usr.bin/dc/USD.doc]

Xin LI delphij at delphij.net
Thu Feb 4 18:00:07 UTC 2010


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 2010/02/04 09:52, Lucius Windschuh wrote:
> 2010/2/4 Xin LI <delphij at gmail.com>:
>> Hi, Lucius,
>>
>> On Thu, Feb 4, 2010 at 2:31 AM, Lucius Windschuh
>> <lwindschuh at googlemail.com> wrote:
>>> Hi Gabor,
>>> is there any chance that the BSD-licensed bc will get readline support
>>> or that you add a switch in math/gnubc to re-enable readline support?
>>> This i a huge enhancement if you use bc interactively.
>>> I know that libreadline is GPL-licensed. But maybe, there is an alternative.
>>
>> Try this patch:
>>
>> http://pastebin.com/m3f92c202
> 
> Thanks. :-D That's what I missed.
> And I didn't know about libedit. I really wondered if there was no
> alternative to GNU readline (as I need a command line parser in some
> other projects).

libedit has provided most functionality that GNU readline provided under
a BSD license.  (We may want to update it to a newer snapshot from
NetBSD anyways).

> Lucius
> 
> BTW: Pastebin converted the line endings to DOS format, which I find a
> bit strange.

Em...  That's weird, maybe I should have uploaded the patch instead of
pasting it?

- -- 
Xin LI <delphij at delphij.net>	http://www.delphij.net/
FreeBSD - The Power to Serve!	       Live free or die
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.14 (FreeBSD)

iQEcBAEBAgAGBQJLawsWAAoJEATO+BI/yjfBM1YIAJ1H58m0Kbh+AhFB5pm+pxLG
M0MilVACBDbKmINmR9RRuF8N9x3gEIdYgO41UC69ggUlMDN9b9sZk7dbN09tVKRr
2O58kHrW1MHWgdgv85ayRyBCC3oGs0PKqPwzHLyj9lYd6w7P5YAhiVAvArjdzvJM
+lftPKZOdY+0iP7ACGOmcpFlCN23sF+AdcyJA281z41iOcwNXztHgqZIgZSGUyI6
HWFyeeGaJuAOWhSP0uhnpkoUkvMDAggAPRAfdi8DXPioWbn5GB/PkOjsC54TmINC
GSwCqpDeW2W6+GfxMlhh8nT5Z0zLXvta5KrOUszUq8hKnJSgV+ickwmpxkYaW/k=
=42x1
-----END PGP SIGNATURE-----
-------------- next part --------------
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 <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]);
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 <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 freebsd-current mailing list