summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorotto <otto@openbsd.org>2004-10-19 07:36:51 +0000
committerotto <otto@openbsd.org>2004-10-19 07:36:51 +0000
commitb1fdaab8f79dc80c955b0142d7eb21a684a60e43 (patch)
tree28c673153aaea924b725f6b19760501fc1a1ed48
parentUse inet6 pf rules only for inet6-capable setups, first spotted (diff)
downloadwireguard-openbsd-b1fdaab8f79dc80c955b0142d7eb21a684a60e43.tar.xz
wireguard-openbsd-b1fdaab8f79dc80c955b0142d7eb21a684a60e43.zip
Implement -e expression, for command line expression evaluation.
ok deraadt@
-rw-r--r--usr.bin/bc/bc.125
-rw-r--r--usr.bin/bc/bc.y50
-rw-r--r--usr.bin/bc/extern.h7
-rw-r--r--usr.bin/bc/scan.l48
4 files changed, 93 insertions, 37 deletions
diff --git a/usr.bin/bc/bc.1 b/usr.bin/bc/bc.1
index 018822e48c2..990e2baffac 100644
--- a/usr.bin/bc/bc.1
+++ b/usr.bin/bc/bc.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: bc.1,v 1.17 2004/08/25 21:59:59 jmc Exp $
+.\" $OpenBSD: bc.1,v 1.18 2004/10/19 07:36:51 otto Exp $
.\"
.\" Copyright (C) Caldera International Inc. 2001-2002.
.\" All rights reserved.
@@ -42,13 +42,14 @@
.Sh SYNOPSIS
.Nm bc
.Op Fl cl
+.Op Fl e Ar expression
.Op Ar file ...
.Sh DESCRIPTION
.Nm
is an interactive processor for a language which resembles
C but provides unlimited precision arithmetic.
-It takes input from any files given, then reads
-the standard input.
+It takes input from any expressions on the command line and
+any files given, then reads the standard input.
.Pp
Options available:
.Bl -tag -width Ds
@@ -66,9 +67,17 @@ instructions are sent to the standard output,
instead of being interpreted by a running
.Xr dc 1
process.
+.It Fl e Ar expression
+Evaluate
+.Ar expression .
+If multiple
+.Fl e
+options are specified, they are processed in the order given,
+separated by newlines.
.It Fl l
-Allow specification
-of an arbitrary precision math library.
+Allow specification of an arbitrary precision math library.
+The definitions in the library are available to command line
+expressions.
.El
.Pp
The syntax for
@@ -322,6 +331,12 @@ the exponential function and
.Pp
prints approximate values of the exponential function of
the first ten integers.
+.Pp
+.Bd -literal -offset indent
+$ bc -l -e 'scale = 500; 2 * a(2^10000)' -e quit
+.Ed
+.Pp
+prints an approximation of pi.
.Sh FILES
.Bl -tag -width /usr/share/misc/bc.library -compact
.It Pa /usr/share/misc/bc.library
diff --git a/usr.bin/bc/bc.y b/usr.bin/bc/bc.y
index 31d844e9f07..97482102909 100644
--- a/usr.bin/bc/bc.y
+++ b/usr.bin/bc/bc.y
@@ -1,5 +1,5 @@
%{
-/* $OpenBSD: bc.y,v 1.23 2004/02/18 07:43:58 otto Exp $ */
+/* $OpenBSD: bc.y,v 1.24 2004/10/19 07:36:51 otto Exp $ */
/*
* Copyright (c) 2003, Otto Moerbeek <otto@drijf.net>
@@ -31,7 +31,7 @@
*/
#ifndef lint
-static const char rcsid[] = "$OpenBSD: bc.y,v 1.23 2004/02/18 07:43:58 otto Exp $";
+static const char rcsid[] = "$OpenBSD: bc.y,v 1.24 2004/10/19 07:36:51 otto Exp $";
#endif /* not lint */
#include <ctype.h>
@@ -62,6 +62,12 @@ struct tree {
int yyparse(void);
int yywrap(void);
+int fileindex;
+int sargc;
+char **sargv;
+char *filename;
+char *cmdexpr;
+
static void grow(void);
static ssize_t cs(const char *);
static ssize_t as(const char *);
@@ -94,10 +100,6 @@ static ssize_t prologue;
static ssize_t epilogue;
static bool st_has_continue;
static char str_table[UCHAR_MAX][2];
-static int fileindex;
-static int sargc;
-static char **sargv;
-static char *filename;
static bool do_fork = true;
static u_short var_count;
@@ -921,26 +923,6 @@ add_local(ssize_t n)
epilogue = node(epilogue, cs("L"), n, cs("s."), END_NODE);
}
-int
-yywrap(void)
-{
- if (fileindex < sargc) {
- filename = sargv[fileindex++];
- yyin = fopen(filename, "r");
- lineno = 1;
- if (yyin == NULL)
- err(1, "cannot open %s", filename);
- return 0;
- } else if (fileindex == sargc) {
- fileindex++;
- yyin = stdin;
- lineno = 1;
- filename = "stdin";
- return 0;
- }
- return 1;
-}
-
void
yyerror(char *s)
{
@@ -994,7 +976,8 @@ init(void)
static __dead void
usage(void)
{
- fprintf(stderr, "%s: usage: [-cl] [file ...]\n", __progname);
+ fprintf(stderr, "%s: usage: [-cl] [-e expression] [file ...]\n",
+ __progname);
exit(1);
}
@@ -1058,6 +1041,7 @@ main(int argc, char *argv[])
{
int i, ch, ret;
int p[2];
+ char *q;
init();
setlinebuf(stdout);
@@ -1066,13 +1050,21 @@ main(int argc, char *argv[])
if (sargv == NULL)
err(1, NULL);
- /* The d debug option is 4.4 BSD dc(1) compatible */
- while ((ch = getopt(argc, argv, "cdl")) != -1) {
+ if ((cmdexpr = strdup("")) == NULL)
+ err(1, NULL);
+ /* The d debug option is 4.4 BSD bc(1) compatible */
+ while ((ch = getopt(argc, argv, "cde:l")) != -1) {
switch (ch) {
case 'c':
case 'd':
do_fork = false;
break;
+ case 'e':
+ q = cmdexpr;
+ if (asprintf(&cmdexpr, "%s%s\n", cmdexpr, optarg) == -1)
+ err(1, NULL);
+ free(q);
+ break;
case 'l':
sargv[sargc++] = _PATH_LIBB;
break;
diff --git a/usr.bin/bc/extern.h b/usr.bin/bc/extern.h
index cc99d12adfa..fc2f5ee5b71 100644
--- a/usr.bin/bc/extern.h
+++ b/usr.bin/bc/extern.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: extern.h,v 1.4 2003/12/02 09:00:07 otto Exp $ */
+/* $OpenBSD: extern.h,v 1.5 2004/10/19 07:36:51 otto Exp $ */
/*
* Copyright (c) 2003, Otto Moerbeek <otto@drijf.net>
@@ -31,3 +31,8 @@ void abort_line(int);
extern int lineno;
extern char *yytext;
extern FILE *yyin;
+extern int fileindex;
+extern int sargc;
+extern char **sargv;
+extern char *filename;
+extern char *cmdexpr;
diff --git a/usr.bin/bc/scan.l b/usr.bin/bc/scan.l
index 1e8a3ebaf13..31058afb41f 100644
--- a/usr.bin/bc/scan.l
+++ b/usr.bin/bc/scan.l
@@ -1,5 +1,5 @@
%{
-/* $OpenBSD: scan.l,v 1.14 2003/12/02 09:00:07 otto Exp $ */
+/* $OpenBSD: scan.l,v 1.15 2004/10/19 07:36:51 otto Exp $ */
/*
* Copyright (c) 2003, Otto Moerbeek <otto@drijf.net>
@@ -18,7 +18,7 @@
*/
#ifndef lint
-static const char rcsid[] = "$OpenBSD: scan.l,v 1.14 2003/12/02 09:00:07 otto Exp $";
+static const char rcsid[] = "$OpenBSD: scan.l,v 1.15 2004/10/19 07:36:51 otto Exp $";
#endif /* not lint */
#include <err.h>
@@ -26,6 +26,7 @@ static const char rcsid[] = "$OpenBSD: scan.l,v 1.14 2003/12/02 09:00:07 otto Ex
#include <string.h>
#include "extern.h"
+#include "pathnames.h"
#include "y.tab.h"
int lineno;
@@ -227,3 +228,46 @@ abort_line(int sig)
printf("[\n]P\n");
}
}
+
+int
+yywrap(void)
+{
+ static int state;
+ static YY_BUFFER_STATE buf;
+
+ if (fileindex == 0 && sargc > 0 && strcmp(sargv[0], _PATH_LIBB) == 0) {
+ filename = sargv[fileindex++];
+ yyin = fopen(filename, "r");
+ lineno = 1;
+ if (yyin == NULL)
+ err(1, "cannot open %s", filename);
+ return (0);
+ }
+ if (state == 0 && cmdexpr[0] != '\0') {
+ buf = yy_scan_string(cmdexpr);
+ state++;
+ lineno = 1;
+ filename = "command line";
+ return (0);
+ } else if (state == 1) {
+ yy_delete_buffer(buf);
+ free(cmdexpr);
+ state++;
+ }
+ if (fileindex < sargc) {
+ filename = sargv[fileindex++];
+ yyin = fopen(filename, "r");
+ lineno = 1;
+ if (yyin == NULL)
+ err(1, "cannot open %s", filename);
+ return (0);
+ } else if (fileindex == sargc) {
+ fileindex++;
+ yyin = stdin;
+ lineno = 1;
+ filename = "stdin";
+ return (0);
+ }
+ return (1);
+}
+