diff options
author | 2004-10-19 07:36:51 +0000 | |
---|---|---|
committer | 2004-10-19 07:36:51 +0000 | |
commit | b1fdaab8f79dc80c955b0142d7eb21a684a60e43 (patch) | |
tree | 28c673153aaea924b725f6b19760501fc1a1ed48 | |
parent | Use inet6 pf rules only for inet6-capable setups, first spotted (diff) | |
download | wireguard-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.1 | 25 | ||||
-rw-r--r-- | usr.bin/bc/bc.y | 50 | ||||
-rw-r--r-- | usr.bin/bc/extern.h | 7 | ||||
-rw-r--r-- | usr.bin/bc/scan.l | 48 |
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); +} + |