Page MenuHomeFreeBSD

D46876.diff
No OneTemporary

D46876.diff

diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc
--- a/ObsoleteFiles.inc
+++ b/ObsoleteFiles.inc
@@ -51,6 +51,13 @@
# xargs -n1 | sort | uniq -d;
# done
+# 20241124: library and tests of OpenBSD dc
+OLD_FILES+=usr/share/misc/bc.library
+OLD_FILES+=usr/tests/usr.bin/dc/Kyuafile
+OLD_FILES+=usr/tests/usr.bin/dc/bcode
+OLD_FILES+=usr/tests/usr.bin/dc/inout
+OLD_DIRS+=usr/tests/usr.bin/dc
+
# 20241119: rewrite mv tests
OLD_FILES+=usr/tests/bin/mv/legacy_test
diff --git a/UPDATING b/UPDATING
--- a/UPDATING
+++ b/UPDATING
@@ -27,6 +27,11 @@
world, or to merely disable the most expensive debugging functionality
at runtime, run "ln -s 'abort:false,junk:false' /etc/malloc.conf".)
+20241124:
+ The OpenBSD derived bc and dc implementations and the WITHOUT_GH_BC
+ option that allowed building them instead of the advanced version
+ imported more than 4 years ago have been removed.
+
20241025:
The support for the rc_fast_and_loose variable has been removed from
rc.subr(8). Users setting rc_fast_and_loose on their systems are
diff --git a/share/man/man5/src.conf.5 b/share/man/man5/src.conf.5
--- a/share/man/man5/src.conf.5
+++ b/share/man/man5/src.conf.5
@@ -712,12 +712,6 @@
.Xr ftpd 8 .
.It Va WITHOUT_GAMES
Do not build games.
-.It Va WITHOUT_GH_BC
-Install the traditional FreeBSD
-.Xr bc 1
-and
-.Xr dc 1
-programs instead of the enhanced versions.
.It Va WITHOUT_GNU_DIFF
Do not build GNU
.Xr diff3 1 ;
diff --git a/share/mk/src.opts.mk b/share/mk/src.opts.mk
--- a/share/mk/src.opts.mk
+++ b/share/mk/src.opts.mk
@@ -101,7 +101,6 @@
FREEBSD_UPDATE \
FTP \
GAMES \
- GH_BC \
GNU_DIFF \
GOOGLETEST \
GPIO \
diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc
--- a/tools/build/mk/OptionalObsoleteFiles.inc
+++ b/tools/build/mk/OptionalObsoleteFiles.inc
@@ -2071,14 +2071,6 @@
OLD_FILES+=usr/share/man/man8/unstr.8.gz
.endif
-.if ${MK_GH_BC} == no
-OLD_FILES+=usr/share/misc/bc.library
-OLD_FILES+=usr/tests/usr.bin/dc/Kyuafile
-OLD_FILES+=usr/tests/usr.bin/dc/bcode
-OLD_FILES+=usr/tests/usr.bin/dc/inout
-OLD_DIRS+=usr/tests/usr.bin/dc
-.endif
-
.if ${MK_GOOGLETEST} == no
OLD_FILES+=usr/include/private/gmock/gmock-actions.h
OLD_FILES+=usr/include/private/gmock/gmock-cardinalities.h
diff --git a/tools/build/options/WITHOUT_GH_BC b/tools/build/options/WITHOUT_GH_BC
deleted file mode 100644
--- a/tools/build/options/WITHOUT_GH_BC
+++ /dev/null
@@ -1,5 +0,0 @@
-Install the traditional FreeBSD
-.Xr bc 1
-and
-.Xr dc 1
-programs instead of the enhanced versions.
diff --git a/usr.bin/Makefile b/usr.bin/Makefile
--- a/usr.bin/Makefile
+++ b/usr.bin/Makefile
@@ -207,12 +207,7 @@
SUBDIR.${MK_GAMES}+= pom
SUBDIR.${MK_GAMES}+= primes
SUBDIR.${MK_GAMES}+= random
-.if ${MK_GH_BC} == "yes"
SUBDIR+= gh-bc
-.else
-SUBDIR.${MK_OPENSSL}+= bc
-SUBDIR.${MK_OPENSSL}+= dc
-.endif
.if ${MK_GNU_DIFF} == "no"
SUBDIR+= diff3
.endif
diff --git a/usr.bin/bc/Makefile b/usr.bin/bc/Makefile
deleted file mode 100644
--- a/usr.bin/bc/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-# $OpenBSD: Makefile,v 1.7 2013/09/19 16:12:00 otto Exp $
-
-PROG= bc
-SRCS= bc.y scan.l tty.c
-CFLAGS+= -I. -I${.CURDIR}
-
-LIBADD= edit
-
-NO_WMISSING_VARIABLE_DECLARATIONS=
-
-FILES+= bc.library
-FILESDIR=${SHAREDIR}/misc
-
-.include <bsd.prog.mk>
diff --git a/usr.bin/bc/Makefile.depend b/usr.bin/bc/Makefile.depend
deleted file mode 100644
--- a/usr.bin/bc/Makefile.depend
+++ /dev/null
@@ -1,17 +0,0 @@
-# Autogenerated - do NOT edit!
-
-DIRDEPS = \
- include \
- include/xlocale \
- lib/${CSU_DIR} \
- lib/libc \
- lib/libcompiler_rt \
- lib/libedit \
- usr.bin/yacc.host \
-
-
-.include <dirdeps.mk>
-
-.if ${DEP_RELDIR} == ${_DEP_RELDIR}
-# local dependencies - needed for -jN in clean tree
-.endif
diff --git a/usr.bin/bc/bc.1 b/usr.bin/bc/bc.1
deleted file mode 100644
--- a/usr.bin/bc/bc.1
+++ /dev/null
@@ -1,413 +0,0 @@
-.\" $OpenBSD: bc.1,v 1.32 2015/11/17 05:45:35 mmcc Exp $
-.\"
-.\" Copyright (C) Caldera International Inc. 2001-2002.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code and documentation must retain the above
-.\" copyright notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed or owned by Caldera
-.\" International, Inc.
-.\" 4. Neither the name of Caldera International, Inc. nor the names of other
-.\" contributors may be used to endorse or promote products derived from
-.\" this software without specific prior written permission.
-.\"
-.\" USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
-.\" INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
-.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-.\" IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE FOR ANY DIRECT,
-.\" INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-.\" (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-.\" SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-.\" IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-.\" POSSIBILITY OF SUCH DAMAGE.
-.\"
-.Dd November 21, 2015
-.Dt BC 1
-.Os
-.Sh NAME
-.Nm bc
-.Nd arbitrary-precision arithmetic language and calculator
-.Sh SYNOPSIS
-.Nm bc
-.Op Fl chlv
-.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 expressions on the command line and
-any files given, then reads the standard input.
-.Pp
-Options available:
-.Bl -tag -width Ds
-.It Fl c
-.Nm
-is actually a preprocessor for
-.Xr dc 1 ,
-which it invokes automatically, unless the
-.Fl c
-.Pq compile only
-option is present.
-In this case the generated
-.Xr dc 1
-instructions are sent to the standard output,
-instead of being interpreted by a running
-.Xr dc 1
-process.
-.It Fl e Ar expression , Fl Fl expression Ar expression
-Evaluate
-.Ar expression .
-If multiple
-.Fl e
-options are specified, they are processed in the order given,
-separated by newlines.
-.It Fl h , Fl Fl help
-Prints usage information.
-.It Fl l , Fl Fl mathlib
-Allow specification of an arbitrary precision math library.
-The definitions in the library are available to command line
-expressions.
-.It Fl v , Fl Fl version
-Prints version information.
-.El
-.Pp
-The syntax for
-.Nm
-programs is as follows:
-.Sq L
-means letter a-z;
-.Sq E
-means expression;
-.Sq S
-means statement.
-As a non-portable extension, it is possible to use long names
-in addition to single letter names.
-A long name is a sequence starting with a lowercase letter
-followed by any number of lowercase letters and digits.
-The underscore character
-.Pq Sq _
-counts as a letter.
-.Pp
-Comments
-.Bd -unfilled -offset indent -compact
-are enclosed in /* and */
-are enclosed in # and the next newline
-.Ed
-.Pp
-The newline is not part of the line comment,
-which in itself is a non-portable extension.
-.Pp
-Names
-.Bd -unfilled -offset indent -compact
-simple variables: L
-array elements: L [ E ]
-The words `ibase', `obase', and `scale'
-The word `last' or a single dot
-.Ed
-.Pp
-Other operands
-.Bd -unfilled -offset indent -compact
-arbitrarily long numbers with optional sign and decimal point
-( E )
-sqrt ( E )
-length ( E ) number of significant decimal digits
-scale ( E ) number of digits right of decimal point
-L ( E , ... , E )
-.Ed
-.Pp
-The sequence
-.Sq \e<newline><whitespace>
-is ignored within numbers.
-.Pp
-Operators
-.Pp
-The following arithmetic and logical operators can be used.
-The semantics of the operators is the same as in the C language.
-They are listed in order of decreasing precedence.
-Operators in the same group have the same precedence.
-.Bl -column "= += \-= *= /= %= ^=" "Associativity" "multiply, divide, modulus" -offset indent
-.It Sy "Operator" Ta Sy "Associativity" Ta Sy "Description"
-.It "++ \-\-" Ta "none" Ta "increment, decrement"
-.It "\-" Ta "none" Ta "unary minus"
-.It "^" Ta "right" Ta "power"
-.It "* / %" Ta "left" Ta "multiply, divide, modulus"
-.It "+ \-" Ta "left" Ta "plus, minus"
-.It "= += -= *= /= %= ^=" Ta "right" Ta "assignment"
-.It "== <= >= != < >" Ta "none" Ta "relational"
-.It "!" Ta "none" Ta "boolean not"
-.It "&&" Ta "left" Ta "boolean and"
-.It "||" Ta "left" Ta "boolean or"
-.El
-.Pp
-Note the following:
-.Bl -bullet -offset indent
-.It
-The relational operators may appear in any expression.
-The
-.St -p1003.1-2008
-standard only allows them in the conditional expression of an
-.Sq if ,
-.Sq while
-or
-.Sq for
-statement.
-.It
-The relational operators have a lower precedence than the assignment
-operators.
-This has the consequence that the expression
-.Sy a = b < c
-is interpreted as
-.Sy (a = b) < c ,
-which is probably not what the programmer intended.
-.It
-In contrast with the C language, the relational operators all have
-the same precedence, and are non-associative.
-The expression
-.Sy a < b < c
-will produce a syntax error.
-.It
-The boolean operators (!, && and ||) are non-portable extensions.
-.It
-The boolean not
-(!) operator has much lower precedence than the same operator in the
-C language.
-This has the consequence that the expression
-.Sy !a < b
-is interpreted as
-.Sy !(a < b) .
-Prudent programmers use parentheses when writing expressions involving
-boolean operators.
-.El
-.Pp
-Statements
-.Bd -unfilled -offset indent -compact
-E
-{ S ; ... ; S }
-if ( E ) S
-if ( E ) S else S
-while ( E ) S
-for ( E ; E ; E ) S
-null statement
-break
-continue
-quit
-a string of characters, enclosed in double quotes
-print E ,..., E
-.Ed
-.Pp
-A string may contain any character, except double quote.
-The if statement with an else branch is a non-portable extension.
-All three E's in a for statement may be empty.
-This is a non-portable extension.
-The continue and print statements are also non-portable extensions.
-.Pp
-The print statement takes a list of comma-separated expressions.
-Each expression in the list is evaluated and the computed
-value is printed and assigned to the variable `last'.
-No trailing newline is printed.
-The expression may also be a string enclosed in double quotes.
-Within these strings the following escape sequences may be used:
-.Sq \ea
-for bell (alert),
-.Sq \eb
-for backspace,
-.Sq \ef
-for formfeed,
-.Sq \en
-for newline,
-.Sq \er
-for carriage return,
-.Sq \et
-for tab,
-.Sq \eq
-for double quote and
-.Sq \e\e
-for backslash.
-Any other character following a backslash will be ignored.
-Strings will not be assigned to `last'.
-.Pp
-Function definitions
-.Bd -unfilled -offset indent
-define L ( L ,..., L ) {
- auto L, ... , L
- S; ... S
- return ( E )
-}
-.Ed
-.Pp
-As a non-portable extension, the opening brace of the define statement
-may appear on the next line.
-The return statement may also appear in the following forms:
-.Bd -unfilled -offset indent
-return
-return ()
-return E
-.Ed
-.Pp
-The first two are equivalent to the statement
-.Dq return 0 .
-The last form is a non-portable extension.
-Not specifying a return statement is equivalent to writing
-.Dq return (0) .
-.Pp
-Functions available in the math library, which is loaded by specifying the
-.Fl l
-flag on the command line
-.Pp
-.Bl -tag -width j(n,x) -offset indent -compact
-.It s(x)
-sine
-.It c(x)
-cosine
-.It e(x)
-exponential
-.It l(x)
-log
-.It a(x)
-arctangent
-.It j(n,x)
-Bessel function
-.El
-.Pp
-All function arguments are passed by value.
-.Pp
-The value of a statement that is an expression is printed
-unless the main operator is an assignment.
-The value printed is assigned to the special variable `last'.
-This is a non-portable extension.
-A single dot may be used as a synonym for `last'.
-Either semicolons or newlines may separate statements.
-Assignment to
-.Ar scale
-influences the number of digits to be retained on arithmetic
-operations in the manner of
-.Xr dc 1 .
-Assignments to
-.Ar ibase
-or
-.Ar obase
-set the input and output number radix respectively.
-.Pp
-The same letter may be used as an array, a function,
-and a simple variable simultaneously.
-All variables are global to the program.
-`Auto' variables are pushed down during function calls.
-When using arrays as function arguments
-or defining them as automatic variables,
-empty square brackets must follow the array name.
-.Pp
-For example
-.Bd -literal -offset indent
-scale = 20
-define e(x){
- auto a, b, c, i, s
- a = 1
- b = 1
- s = 1
- for(i=1; 1==1; i++){
- a = a*x
- b = b*i
- c = a/b
- if(c == 0) return(s)
- s = s+c
- }
-}
-.Ed
-.Pp
-defines a function to compute an approximate value of
-the exponential function and
-.Pp
-.Dl for(i=1; i<=10; i++) e(i)
-.Pp
-prints approximate values of the exponential function of
-the first ten integers.
-.Bd -literal -offset indent
-$ bc -l -e 'scale = 500; 2 * a(2^10000)' -e quit
-.Ed
-.Pp
-prints an approximation of pi.
-.Sh COMMAND LINE EDITING
-.Nm
-supports interactive command line editing, via the
-.Xr editline 3
-library.
-It is enabled by default if input is from a tty.
-Previous lines can be recalled and edited with the arrow keys,
-and other GNU Emacs-style editing keys may be used as well.
-.Pp
-The
-.Xr editline 3
-library is configured with a
-.Pa .editrc
-file \- refer to
-.Xr editrc 5
-for more information.
-.Sh FILES
-.Bl -tag -width /usr/share/misc/bc.library -compact
-.It Pa /usr/share/misc/bc.library
-math library, read when the
-.Fl l
-option is specified on the command line.
-.El
-.Sh COMPATIBILITY
-The
-.Fl q
-and
-.Fl Fl quiet
-options are no-ops for compatibility with some other implementations of
-.Nm
-and their use is discouraged.
-.Sh SEE ALSO
-.Xr dc 1
-.Sh STANDARDS
-The
-.Nm
-utility is compliant with the
-.St -p1003.1-2008
-specification.
-.Pp
-The flags
-.Op Fl ce ,
-as well as the parts noted above,
-are extensions to that specification.
-.Sh HISTORY
-The
-.Nm
-command first appeared in
-.At v6 .
-A complete rewrite of the
-.Nm
-command first appeared in
-.Ox 3.5 .
-.Sh AUTHORS
-.An -nosplit
-The original version of the
-.Nm
-command was written by
-.An Robert Morris
-and
-.An Lorinda Cherry .
-The current version of the
-.Nm
-utility was written by
-.An Otto Moerbeek .
-.Sh BUGS
-The
-.Ql quit
-statement is interpreted when read, not when executed.
-.Pp
-Some non-portable extensions, as found in the GNU version of the
-.Nm
-utility are not implemented (yet).
diff --git a/usr.bin/bc/bc.library b/usr.bin/bc/bc.library
deleted file mode 100644
--- a/usr.bin/bc/bc.library
+++ /dev/null
@@ -1,272 +0,0 @@
-/* $OpenBSD: bc.library,v 1.4 2012/03/14 07:35:53 otto Exp $ */
-
-/*
- * Copyright (C) Caldera International Inc. 2001-2002.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code and documentation must retain the above
- * copyright notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed or owned by Caldera
- * International, Inc.
- * 4. Neither the name of Caldera International, Inc. nor the names of other
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
- * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE FOR ANY DIRECT,
- * INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- */
-
-scale = 20
-define e(x) {
- auto a, b, c, d, e, g, t, w, y, r
-
- r = ibase
- ibase = A
- t = scale
- scale = 0
- if (x > 0) scale = (0.435*x)/1
- scale = scale + t + length(scale + t) + 1
-
- w = 0
- if (x < 0) {
- x = -x
- w = 1
- }
- y = 0
- while (x > 2) {
- x = x/2
- y = y + 1
- }
-
- a = 1
- b = 1
- c = b
- d = 1
- e = 1
- for (a = 1; 1 == 1; a++) {
- b = b*x
- c = c*a + b
- d = d*a
- g = c/d
- if (g == e) {
- g = g/1
- while (y--) {
- g = g*g
- }
- scale = t
- ibase = r
- if (w == 1) return (1/g)
- return (g/1)
- }
- e = g
- }
-}
-
-define l(x) {
- auto a, b, c, d, e, f, g, u, s, t, r
- r = ibase
- ibase = A
- if (x <= 0) {
- a = (1 - 10^scale)
- ibase = r
- return (a)
- }
- t = scale
-
- f = 1
- if (x < 1) {
- s = scale(x)
- } else {
- s = length(x)-scale(x)
- }
- scale = 0
- a = (2.31*s)/1 /* estimated integer part of the answer */
- s = t + length(a) + 2 /* estimated length of the answer */
- while (x > 2) {
- scale = 0
- scale = (length(x) + scale(x))/2 + 1
- if (scale < s) scale = s
- x = sqrt(x)
- f = f*2
- }
- while (x < .5) {
- scale = 0
- scale = scale(x)/2 + 1
- if (scale < s) scale = s
- x = sqrt(x)
- f = f*2
- }
-
- scale = 0
- scale = t + length(f) + length((1.05*(t+length(f))/1)) + 1
- u = (x - 1)/(x + 1)
- s = u*u
- scale = t + 2
- b = 2*f
- c = b
- d = 1
- e = 1
- for (a = 3; 1 == 1 ; a = a + 2) {
- b = b*s
- c = c*a + d*b
- d = d*a
- g = c/d
- if (g == e) {
- scale = t
- ibase = r
- return (u*c/d)
- }
- e = g
- }
-}
-
-define s(x) {
- auto a, b, c, s, t, y, p, n, i, r
- r = ibase
- ibase = A
- t = scale
- y = x/.7853
- s = t + length(y) - scale(y)
- if (s < t) s = t
- scale = s
- p = a(1)
-
- scale = 0
- if (x >= 0) n = (x/(2*p) + 1)/2
- if (x < 0) n = (x/(2*p) - 1)/2
- x = x - 4*n*p
- if (n % 2 != 0) x = -x
-
- scale = t + length(1.2*t) - scale(1.2*t)
- y = -x*x
- a = x
- b = 1
- s = x
- for (i =3 ; 1 == 1; i = i + 2) {
- a = a*y
- b = b*i*(i - 1)
- c = a/b
- if (c == 0) {
- scale = t
- ibase = r
- return (s/1)
- }
- s = s + c
- }
-}
-
-define c(x) {
- auto t, r
- r = ibase
- ibase = A
- t = scale
- scale = scale + 1
- x = s(x + 2*a(1))
- scale = t
- ibase = r
- return (x/1)
-}
-
-define a(x) {
- auto a, b, c, d, e, f, g, s, t, r
- if (x == 0) return(0)
-
- r = ibase
- ibase = A
- if (x == 1) {
- if (scale < 52) {
- a = .7853981633974483096156608458198757210492923498437764/1
- ibase = r
- return (a)
- }
- }
- t = scale
- f = 1
- while (x > .5) {
- scale = scale + 1
- x = -(1 - sqrt(1. + x*x))/x
- f = f*2
- }
- while (x < -.5) {
- scale = scale + 1
- x = -(1 - sqrt(1. + x*x))/x
- f = f*2
- }
- s = -x*x
- b = f
- c = f
- d = 1
- e = 1
- for (a = 3; 1 == 1; a = a + 2) {
- b = b*s
- c = c*a + d*b
- d = d*a
- g = c/d
- if (g == e) {
- ibase = r
- scale = t
- return (x*c/d)
- }
- e = g
- }
-}
-
-define j(n,x) {
- auto a, b, c, d, e, g, i, s, k, t, r
-
- r = ibase
- ibase = A
- t = scale
- k = 1.36*x + 1.16*t - n
- k = length(k) - scale(k)
- if (k > 0) scale = scale + k
-
- s = -x*x/4
- if (n < 0) {
- n = -n
- x = -x
- }
- a = 1
- c = 1
- for (i = 1; i <= n; i++) {
- a = a*x
- c = c*2*i
- }
- b = a
- d = 1
- e = 1
- for (i = 1; 1; i++) {
- a = a*s
- b = b*i*(n + i) + a
- c = c*i*(n + i)
- g = b/c
- if (g == e) {
- ibase = r
- scale = t
- return (g/1)
- }
- e = g
- }
-}
-/* vim: set filetype=bc shiftwidth=8 noexpandtab: */
diff --git a/usr.bin/bc/bc.y b/usr.bin/bc/bc.y
deleted file mode 100644
--- a/usr.bin/bc/bc.y
+++ /dev/null
@@ -1,1214 +0,0 @@
-%{
-/* $OpenBSD: bc.y,v 1.46 2014/10/14 15:35:18 deraadt Exp $ */
-
-/*
- * Copyright (c) 2003, Otto Moerbeek <otto@drijf.net>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * This implementation of bc(1) uses concepts from the original 4.4
- * BSD bc(1). The code itself is a complete rewrite, based on the
- * Posix defined bc(1) grammar. Other differences include type safe
- * usage of pointers to build the tree of emitted code, typed yacc
- * rule values, dynamic allocation of all data structures and a
- * completely rewritten lexical analyzer using lex(1).
- *
- * Some effort has been made to make sure that the generated code is
- * the same as the code generated by the older version, to provide
- * easy regression testing.
- */
-
-#include <sys/types.h>
-#include <sys/wait.h>
-
-#include <ctype.h>
-#include <err.h>
-#include <errno.h>
-#include <getopt.h>
-#include <histedit.h>
-#include <limits.h>
-#include <search.h>
-#include <signal.h>
-#include <stdarg.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdlib.h>
-
-#include "extern.h"
-#include "pathnames.h"
-
-#define BC_VER "1.1-FreeBSD"
-#define END_NODE ((ssize_t) -1)
-#define CONST_STRING ((ssize_t) -2)
-#define ALLOC_STRING ((ssize_t) -3)
-
-extern char *yytext;
-extern FILE *yyin;
-
-struct tree {
- union {
- char *astr;
- const char *cstr;
- } u;
- ssize_t index;
-};
-
-int yywrap(void);
-
-int fileindex;
-int sargc;
-const char **sargv;
-const char *filename;
-char *cmdexpr;
-
-static void grow(void);
-static ssize_t cs(const char *);
-static ssize_t as(const char *);
-static ssize_t node(ssize_t, ...);
-static void emit(ssize_t, int);
-static void emit_macro(int, ssize_t);
-static void free_tree(void);
-static ssize_t numnode(int);
-static ssize_t lookup(char *, size_t, char);
-static ssize_t letter_node(char *);
-static ssize_t array_node(char *);
-static ssize_t function_node(char *);
-
-static void add_par(ssize_t);
-static void add_local(ssize_t);
-static void warning(const char *);
-static void init(void);
-static void usage(void);
-static char *escape(const char *);
-
-static ssize_t instr_sz = 0;
-static struct tree *instructions = NULL;
-static ssize_t current = 0;
-static int macro_char = '0';
-static int reset_macro_char = '0';
-static int nesting = 0;
-static int breakstack[16];
-static int breaksp = 0;
-static ssize_t prologue;
-static ssize_t epilogue;
-static bool st_has_continue;
-static char str_table[UCHAR_MAX][2];
-static bool do_fork = true;
-static u_short var_count;
-static pid_t dc;
-
-static void sigchld(int);
-
-extern char *__progname;
-
-#define BREAKSTACK_SZ (sizeof(breakstack)/sizeof(breakstack[0]))
-
-/* These values are 4.4BSD bc compatible */
-#define FUNC_CHAR 0x01
-#define ARRAY_CHAR 0xa1
-
-/* Skip '\0', [, \ and ] */
-#define ENCODE(c) ((c) < '[' ? (c) : (c) + 3);
-#define VAR_BASE (256-4)
-#define MAX_VARIABLES (VAR_BASE * VAR_BASE)
-
-const struct option long_options[] =
-{
- {"expression", required_argument, NULL, 'e'},
- {"help", no_argument, NULL, 'h'},
- {"mathlib", no_argument, NULL, 'l'},
- /* compatibility option */
- {"quiet", no_argument, NULL, 'q'},
- {"version", no_argument, NULL, 'v'},
- {NULL, no_argument, NULL, 0}
-};
-
-%}
-
-%start program
-
-%union {
- struct lvalue lvalue;
- const char *str;
- char *astr;
- ssize_t node;
-}
-
-%token COMMA SEMICOLON LPAR RPAR LBRACE RBRACE LBRACKET RBRACKET DOT
-%token NEWLINE
-%token <astr> LETTER
-%token <str> NUMBER STRING
-%token DEFINE BREAK QUIT LENGTH
-%token RETURN FOR IF WHILE SQRT
-%token SCALE IBASE OBASE AUTO
-%token CONTINUE ELSE PRINT
-
-%left BOOL_OR
-%left BOOL_AND
-%nonassoc BOOL_NOT
-%nonassoc EQUALS LESS_EQ GREATER_EQ UNEQUALS LESS GREATER
-%right <str> ASSIGN_OP
-%left PLUS MINUS
-%left MULTIPLY DIVIDE REMAINDER
-%right EXPONENT
-%nonassoc UMINUS
-%nonassoc INCR DECR
-
-%type <lvalue> named_expression
-%type <node> argument_list
-%type <node> alloc_macro
-%type <node> expression
-%type <node> function
-%type <node> function_header
-%type <node> input_item
-%type <node> opt_argument_list
-%type <node> opt_expression
-%type <node> opt_relational_expression
-%type <node> opt_statement
-%type <node> print_expression
-%type <node> print_expression_list
-%type <node> relational_expression
-%type <node> return_expression
-%type <node> semicolon_list
-%type <node> statement
-%type <node> statement_list
-
-%%
-
-program : /* empty */
- | program input_item
- ;
-
-input_item : semicolon_list NEWLINE
- {
- emit($1, 0);
- macro_char = reset_macro_char;
- putchar('\n');
- free_tree();
- st_has_continue = false;
- }
- | function
- {
- putchar('\n');
- free_tree();
- st_has_continue = false;
- }
- | error NEWLINE
- {
- yyerrok;
- }
- | error QUIT
- {
- yyerrok;
- }
- ;
-
-semicolon_list : /* empty */
- {
- $$ = cs("");
- }
- | statement
- | semicolon_list SEMICOLON statement
- {
- $$ = node($1, $3, END_NODE);
- }
- | semicolon_list SEMICOLON
- ;
-
-statement_list : /* empty */
- {
- $$ = cs("");
- }
- | statement
- | statement_list NEWLINE
- | statement_list NEWLINE statement
- {
- $$ = node($1, $3, END_NODE);
- }
- | statement_list SEMICOLON
- | statement_list SEMICOLON statement
- {
- $$ = node($1, $3, END_NODE);
- }
- ;
-
-
-opt_statement : /* empty */
- {
- $$ = cs("");
- }
- | statement
- ;
-
-statement : expression
- {
- $$ = node($1, cs("ps."), END_NODE);
- }
- | named_expression ASSIGN_OP expression
- {
- if ($2[0] == '\0')
- $$ = node($3, cs($2), $1.store,
- END_NODE);
- else
- $$ = node($1.load, $3, cs($2), $1.store,
- END_NODE);
- }
- | STRING
- {
- $$ = node(cs("["), as($1),
- cs("]P"), END_NODE);
- }
- | BREAK
- {
- if (breaksp == 0) {
- warning("break not in for or while");
- YYERROR;
- } else {
- $$ = node(
- numnode(nesting -
- breakstack[breaksp-1]),
- cs("Q"), END_NODE);
- }
- }
- | CONTINUE
- {
- if (breaksp == 0) {
- warning("continue not in for or while");
- YYERROR;
- } else {
- st_has_continue = true;
- $$ = node(numnode(nesting -
- breakstack[breaksp-1] - 1),
- cs("J"), END_NODE);
- }
- }
- | QUIT
- {
- sigset_t mask;
-
- putchar('q');
- fflush(stdout);
- if (dc) {
- sigprocmask(SIG_BLOCK, NULL, &mask);
- sigsuspend(&mask);
- } else
- exit(0);
- }
- | RETURN return_expression
- {
- if (nesting == 0) {
- warning("return must be in a function");
- YYERROR;
- }
- $$ = $2;
- }
- | FOR LPAR alloc_macro opt_expression SEMICOLON
- opt_relational_expression SEMICOLON
- opt_expression RPAR opt_statement pop_nesting
- {
- ssize_t n;
-
- if (st_has_continue)
- n = node($10, cs("M"), $8, cs("s."),
- $6, $3, END_NODE);
- else
- n = node($10, $8, cs("s."), $6, $3,
- END_NODE);
-
- emit_macro($3, n);
- $$ = node($4, cs("s."), $6, $3, cs(" "),
- END_NODE);
- }
- | IF LPAR alloc_macro pop_nesting relational_expression RPAR
- opt_statement
- {
- emit_macro($3, $7);
- $$ = node($5, $3, cs(" "), END_NODE);
- }
- | IF LPAR alloc_macro pop_nesting relational_expression RPAR
- opt_statement ELSE alloc_macro pop_nesting opt_statement
- {
- emit_macro($3, $7);
- emit_macro($9, $11);
- $$ = node($5, $3, cs("e"), $9, cs(" "),
- END_NODE);
- }
- | WHILE LPAR alloc_macro relational_expression RPAR
- opt_statement pop_nesting
- {
- ssize_t n;
-
- if (st_has_continue)
- n = node($6, cs("M"), $4, $3, END_NODE);
- else
- n = node($6, $4, $3, END_NODE);
- emit_macro($3, n);
- $$ = node($4, $3, cs(" "), END_NODE);
- }
- | LBRACE statement_list RBRACE
- {
- $$ = $2;
- }
- | PRINT print_expression_list
- {
- $$ = $2;
- }
- ;
-
-alloc_macro : /* empty */
- {
- $$ = cs(str_table[macro_char]);
- macro_char++;
- /* Do not use [, \ and ] */
- if (macro_char == '[')
- macro_char += 3;
- /* skip letters */
- else if (macro_char == 'a')
- macro_char = '{';
- else if (macro_char == ARRAY_CHAR)
- macro_char += 26;
- else if (macro_char == 255)
- fatal("program too big");
- if (breaksp == BREAKSTACK_SZ)
- fatal("nesting too deep");
- breakstack[breaksp++] = nesting++;
- }
- ;
-
-pop_nesting : /* empty */
- {
- breaksp--;
- }
- ;
-
-function : function_header opt_parameter_list RPAR opt_newline
- LBRACE NEWLINE opt_auto_define_list
- statement_list RBRACE
- {
- int n = node(prologue, $8, epilogue,
- cs("0"), numnode(nesting),
- cs("Q"), END_NODE);
- emit_macro($1, n);
- reset_macro_char = macro_char;
- nesting = 0;
- breaksp = 0;
- }
- ;
-
-function_header : DEFINE LETTER LPAR
- {
- $$ = function_node($2);
- free($2);
- prologue = cs("");
- epilogue = cs("");
- nesting = 1;
- breaksp = 0;
- breakstack[breaksp] = 0;
- }
- ;
-
-opt_newline : /* empty */
- | NEWLINE
- ;
-
-opt_parameter_list
- : /* empty */
- | parameter_list
- ;
-
-
-parameter_list : LETTER
- {
- add_par(letter_node($1));
- free($1);
- }
- | LETTER LBRACKET RBRACKET
- {
- add_par(array_node($1));
- free($1);
- }
- | parameter_list COMMA LETTER
- {
- add_par(letter_node($3));
- free($3);
- }
- | parameter_list COMMA LETTER LBRACKET RBRACKET
- {
- add_par(array_node($3));
- free($3);
- }
- ;
-
-
-
-opt_auto_define_list
- : /* empty */
- | AUTO define_list NEWLINE
- | AUTO define_list SEMICOLON
- ;
-
-
-define_list : LETTER
- {
- add_local(letter_node($1));
- free($1);
- }
- | LETTER LBRACKET RBRACKET
- {
- add_local(array_node($1));
- free($1);
- }
- | define_list COMMA LETTER
- {
- add_local(letter_node($3));
- free($3);
- }
- | define_list COMMA LETTER LBRACKET RBRACKET
- {
- add_local(array_node($3));
- free($3);
- }
- ;
-
-
-opt_argument_list
- : /* empty */
- {
- $$ = cs("");
- }
- | argument_list
- ;
-
-
-argument_list : expression
- | argument_list COMMA expression
- {
- $$ = node($1, $3, END_NODE);
- }
- | argument_list COMMA LETTER LBRACKET RBRACKET
- {
- $$ = node($1, cs("l"), array_node($3),
- END_NODE);
- free($3);
- }
- ;
-
-opt_relational_expression
- : /* empty */
- {
- $$ = cs(" 0 0=");
- }
- | relational_expression
- ;
-
-relational_expression
- : expression EQUALS expression
- {
- $$ = node($1, $3, cs("="), END_NODE);
- }
- | expression UNEQUALS expression
- {
- $$ = node($1, $3, cs("!="), END_NODE);
- }
- | expression LESS expression
- {
- $$ = node($1, $3, cs(">"), END_NODE);
- }
- | expression LESS_EQ expression
- {
- $$ = node($1, $3, cs("!<"), END_NODE);
- }
- | expression GREATER expression
- {
- $$ = node($1, $3, cs("<"), END_NODE);
- }
- | expression GREATER_EQ expression
- {
- $$ = node($1, $3, cs("!>"), END_NODE);
- }
- | expression
- {
- $$ = node($1, cs(" 0!="), END_NODE);
- }
- ;
-
-
-return_expression
- : /* empty */
- {
- $$ = node(cs("0"), epilogue,
- numnode(nesting), cs("Q"), END_NODE);
- }
- | expression
- {
- $$ = node($1, epilogue,
- numnode(nesting), cs("Q"), END_NODE);
- }
- | LPAR RPAR
- {
- $$ = node(cs("0"), epilogue,
- numnode(nesting), cs("Q"), END_NODE);
- }
- ;
-
-
-opt_expression : /* empty */
- {
- $$ = cs(" 0");
- }
- | expression
- ;
-
-expression : named_expression
- {
- $$ = node($1.load, END_NODE);
- }
- | DOT {
- $$ = node(cs("l."), END_NODE);
- }
- | NUMBER
- {
- $$ = node(cs(" "), as($1), END_NODE);
- }
- | LPAR expression RPAR
- {
- $$ = $2;
- }
- | LETTER LPAR opt_argument_list RPAR
- {
- $$ = node($3, cs("l"),
- function_node($1), cs("x"),
- END_NODE);
- free($1);
- }
- | MINUS expression %prec UMINUS
- {
- $$ = node(cs(" 0"), $2, cs("-"),
- END_NODE);
- }
- | expression PLUS expression
- {
- $$ = node($1, $3, cs("+"), END_NODE);
- }
- | expression MINUS expression
- {
- $$ = node($1, $3, cs("-"), END_NODE);
- }
- | expression MULTIPLY expression
- {
- $$ = node($1, $3, cs("*"), END_NODE);
- }
- | expression DIVIDE expression
- {
- $$ = node($1, $3, cs("/"), END_NODE);
- }
- | expression REMAINDER expression
- {
- $$ = node($1, $3, cs("%"), END_NODE);
- }
- | expression EXPONENT expression
- {
- $$ = node($1, $3, cs("^"), END_NODE);
- }
- | INCR named_expression
- {
- $$ = node($2.load, cs("1+d"), $2.store,
- END_NODE);
- }
- | DECR named_expression
- {
- $$ = node($2.load, cs("1-d"),
- $2.store, END_NODE);
- }
- | named_expression INCR
- {
- $$ = node($1.load, cs("d1+"),
- $1.store, END_NODE);
- }
- | named_expression DECR
- {
- $$ = node($1.load, cs("d1-"),
- $1.store, END_NODE);
- }
- | named_expression ASSIGN_OP expression
- {
- if ($2[0] == '\0')
- $$ = node($3, cs($2), cs("d"), $1.store,
- END_NODE);
- else
- $$ = node($1.load, $3, cs($2), cs("d"),
- $1.store, END_NODE);
- }
- | LENGTH LPAR expression RPAR
- {
- $$ = node($3, cs("Z"), END_NODE);
- }
- | SQRT LPAR expression RPAR
- {
- $$ = node($3, cs("v"), END_NODE);
- }
- | SCALE LPAR expression RPAR
- {
- $$ = node($3, cs("X"), END_NODE);
- }
- | BOOL_NOT expression
- {
- $$ = node($2, cs("N"), END_NODE);
- }
- | expression BOOL_AND alloc_macro pop_nesting expression
- {
- ssize_t n = node(cs("R"), $5, END_NODE);
- emit_macro($3, n);
- $$ = node($1, cs("d0!="), $3, END_NODE);
- }
- | expression BOOL_OR alloc_macro pop_nesting expression
- {
- ssize_t n = node(cs("R"), $5, END_NODE);
- emit_macro($3, n);
- $$ = node($1, cs("d0="), $3, END_NODE);
- }
- | expression EQUALS expression
- {
- $$ = node($1, $3, cs("G"), END_NODE);
- }
- | expression UNEQUALS expression
- {
- $$ = node($1, $3, cs("GN"), END_NODE);
- }
- | expression LESS expression
- {
- $$ = node($3, $1, cs("("), END_NODE);
- }
- | expression LESS_EQ expression
- {
- $$ = node($3, $1, cs("{"), END_NODE);
- }
- | expression GREATER expression
- {
- $$ = node($1, $3, cs("("), END_NODE);
- }
- | expression GREATER_EQ expression
- {
- $$ = node($1, $3, cs("{"), END_NODE);
- }
- ;
-
-named_expression
- : LETTER
- {
- $$.load = node(cs("l"), letter_node($1),
- END_NODE);
- $$.store = node(cs("s"), letter_node($1),
- END_NODE);
- free($1);
- }
- | LETTER LBRACKET expression RBRACKET
- {
- $$.load = node($3, cs(";"),
- array_node($1), END_NODE);
- $$.store = node($3, cs(":"),
- array_node($1), END_NODE);
- free($1);
- }
- | SCALE
- {
- $$.load = cs("K");
- $$.store = cs("k");
- }
- | IBASE
- {
- $$.load = cs("I");
- $$.store = cs("i");
- }
- | OBASE
- {
- $$.load = cs("O");
- $$.store = cs("o");
- }
- ;
-
-print_expression_list
- : print_expression
- | print_expression_list COMMA print_expression
- {
- $$ = node($1, $3, END_NODE);
- }
-
-print_expression
- : expression
- {
- $$ = node($1, cs("ds.n"), END_NODE);
- }
- | STRING
- {
- char *p = escape($1);
- $$ = node(cs("["), as(p), cs("]n"), END_NODE);
- free(p);
- }
-%%
-
-
-static void
-grow(void)
-{
- struct tree *p;
- size_t newsize;
-
- if (current == instr_sz) {
- newsize = instr_sz * 2 + 1;
- p = reallocarray(instructions, newsize, sizeof(*p));
- if (p == NULL) {
- free(instructions);
- err(1, NULL);
- }
- instructions = p;
- instr_sz = newsize;
- }
-}
-
-static ssize_t
-cs(const char *str)
-{
-
- grow();
- instructions[current].index = CONST_STRING;
- instructions[current].u.cstr = str;
- return (current++);
-}
-
-static ssize_t
-as(const char *str)
-{
-
- grow();
- instructions[current].index = ALLOC_STRING;
- instructions[current].u.astr = strdup(str);
- if (instructions[current].u.astr == NULL)
- err(1, NULL);
- return (current++);
-}
-
-static ssize_t
-node(ssize_t arg, ...)
-{
- va_list ap;
- ssize_t ret;
-
- va_start(ap, arg);
-
- ret = current;
- grow();
- instructions[current++].index = arg;
-
- do {
- arg = va_arg(ap, ssize_t);
- grow();
- instructions[current++].index = arg;
- } while (arg != END_NODE);
-
- va_end(ap);
- return (ret);
-}
-
-static void
-emit(ssize_t i, int level)
-{
-
- if (level > 1000)
- errx(1, "internal error: tree level > 1000");
- if (instructions[i].index >= 0) {
- while (instructions[i].index != END_NODE &&
- instructions[i].index != i) {
- emit(instructions[i].index, level + 1);
- i++;
- }
- } else if (instructions[i].index != END_NODE)
- fputs(instructions[i].u.cstr, stdout);
-}
-
-static void
-emit_macro(int nodeidx, ssize_t code)
-{
-
- putchar('[');
- emit(code, 0);
- printf("]s%s\n", instructions[nodeidx].u.cstr);
- nesting--;
-}
-
-static void
-free_tree(void)
-{
- ssize_t i;
-
- for (i = 0; i < current; i++)
- if (instructions[i].index == ALLOC_STRING)
- free(instructions[i].u.astr);
- current = 0;
-}
-
-static ssize_t
-numnode(int num)
-{
- const char *p;
-
- if (num < 10)
- p = str_table['0' + num];
- else if (num < 16)
- p = str_table['A' - 10 + num];
- else
- errx(1, "internal error: break num > 15");
- return (node(cs(" "), cs(p), END_NODE));
-}
-
-
-static ssize_t
-lookup(char * str, size_t len, char type)
-{
- ENTRY entry, *found;
- u_char *p;
- u_short num;
-
- /* The scanner allocated an extra byte already */
- if (str[len-1] != type) {
- str[len] = type;
- str[len+1] = '\0';
- }
- entry.key = str;
- found = hsearch(entry, FIND);
- if (found == NULL) {
- if (var_count == MAX_VARIABLES)
- errx(1, "too many variables");
- p = malloc(4);
- if (p == NULL)
- err(1, NULL);
- num = var_count++;
- p[0] = 255;
- p[1] = ENCODE(num / VAR_BASE + 1);
- p[2] = ENCODE(num % VAR_BASE + 1);
- p[3] = '\0';
-
- entry.data = (char *)p;
- entry.key = strdup(str);
- if (entry.key == NULL)
- err(1, NULL);
- found = hsearch(entry, ENTER);
- if (found == NULL)
- err(1, NULL);
- }
- return (cs(found->data));
-}
-
-static ssize_t
-letter_node(char *str)
-{
- size_t len;
-
- len = strlen(str);
- if (len == 1 && str[0] != '_')
- return (cs(str_table[(int)str[0]]));
- else
- return (lookup(str, len, 'L'));
-}
-
-static ssize_t
-array_node(char *str)
-{
- size_t len;
-
- len = strlen(str);
- if (len == 1 && str[0] != '_')
- return (cs(str_table[(int)str[0] - 'a' + ARRAY_CHAR]));
- else
- return (lookup(str, len, 'A'));
-}
-
-static ssize_t
-function_node(char *str)
-{
- size_t len;
-
- len = strlen(str);
- if (len == 1 && str[0] != '_')
- return (cs(str_table[(int)str[0] - 'a' + FUNC_CHAR]));
- else
- return (lookup(str, len, 'F'));
-}
-
-static void
-add_par(ssize_t n)
-{
-
- prologue = node(cs("S"), n, prologue, END_NODE);
- epilogue = node(epilogue, cs("L"), n, cs("s."), END_NODE);
-}
-
-static void
-add_local(ssize_t n)
-{
-
- prologue = node(cs("0S"), n, prologue, END_NODE);
- epilogue = node(epilogue, cs("L"), n, cs("s."), END_NODE);
-}
-
-void
-yyerror(const char *s)
-{
- char *p, *str;
- int n;
-
- if (yyin != NULL && feof(yyin))
- n = asprintf(&str, "%s: %s:%d: %s: unexpected EOF",
- __progname, filename, lineno, s);
- else if (yytext[0] == '\n')
- n = asprintf(&str,
- "%s: %s:%d: %s: newline unexpected",
- __progname, filename, lineno, s);
- else if (isspace((unsigned char)yytext[0]) ||
- !isprint((unsigned char)yytext[0]))
- n = asprintf(&str,
- "%s: %s:%d: %s: ascii char 0x%02x unexpected",
- __progname, filename, lineno, s, yytext[0] & 0xff);
- else
- n = asprintf(&str, "%s: %s:%d: %s: %s unexpected",
- __progname, filename, lineno, s, yytext);
- if (n == -1)
- err(1, NULL);
-
- fputs("c[", stdout);
- for (p = str; *p != '\0'; p++) {
- if (*p == '[' || *p == ']' || *p =='\\')
- putchar('\\');
- putchar(*p);
- }
- fputs("]ec\n", stdout);
- free(str);
-}
-
-void
-fatal(const char *s)
-{
-
- errx(1, "%s:%d: %s", filename, lineno, s);
-}
-
-static void
-warning(const char *s)
-{
-
- warnx("%s:%d: %s", filename, lineno, s);
-}
-
-static void
-init(void)
-{
- unsigned int i;
-
- for (i = 0; i < UCHAR_MAX; i++) {
- str_table[i][0] = i;
- str_table[i][1] = '\0';
- }
- if (hcreate(1 << 16) == 0)
- err(1, NULL);
-}
-
-
-static void
-usage(void)
-{
-
- fprintf(stderr, "usage: %s [-chlv] [-e expression] [file ...]\n",
- __progname);
- exit(1);
-}
-
-static char *
-escape(const char *str)
-{
- char *p, *ret;
-
- ret = malloc(strlen(str) + 1);
- if (ret == NULL)
- err(1, NULL);
-
- p = ret;
- while (*str != '\0') {
- /*
- * We get _escaped_ strings here. Single backslashes are
- * already converted to double backslashes
- */
- if (*str == '\\') {
- if (*++str == '\\') {
- switch (*++str) {
- case 'a':
- *p++ = '\a';
- break;
- case 'b':
- *p++ = '\b';
- break;
- case 'f':
- *p++ = '\f';
- break;
- case 'n':
- *p++ = '\n';
- break;
- case 'q':
- *p++ = '"';
- break;
- case 'r':
- *p++ = '\r';
- break;
- case 't':
- *p++ = '\t';
- break;
- case '\\':
- *p++ = '\\';
- break;
- }
- str++;
- } else {
- *p++ = '\\';
- *p++ = *str++;
- }
- } else
- *p++ = *str++;
- }
- *p = '\0';
- return (ret);
-}
-
-/* ARGSUSED */
-static void
-sigchld(int signo __unused)
-{
- pid_t pid;
- int status, save_errno = errno;
-
- for (;;) {
- pid = waitpid(dc, &status, WCONTINUED | WNOHANG);
- if (pid == -1) {
- if (errno == EINTR)
- continue;
- _exit(0);
- } else if (pid == 0)
- break;
- if (WIFEXITED(status) || WIFSIGNALED(status))
- _exit(0);
- else
- break;
- }
- errno = save_errno;
-}
-
-static const char *
-dummy_prompt(void)
-{
-
- return ("");
-}
-
-int
-main(int argc, char *argv[])
-{
- char *q;
- int p[2];
- int ch, i;
-
- init();
- setvbuf(stdout, NULL, _IOLBF, 0);
-
- sargv = reallocarray(NULL, argc, sizeof(char *));
- if (sargv == NULL)
- err(1, NULL);
-
- if ((cmdexpr = strdup("")) == NULL)
- err(1, NULL);
- /* The d debug option is 4.4 BSD bc(1) compatible */
- while ((ch = getopt_long(argc, argv, "cde:hlqv",
- long_options, NULL)) != -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 'h':
- usage();
- break;
- case 'l':
- sargv[sargc++] = _PATH_LIBB;
- break;
- case 'q':
- /* compatibility option */
- break;
- case 'v':
- fprintf(stderr, "%s (BSD bc) %s\n", __progname, BC_VER);
- exit(0);
- break;
- default:
- usage();
- }
- }
-
- argc -= optind;
- argv += optind;
-
- interactive = isatty(STDIN_FILENO) && isatty(STDOUT_FILENO) &&
- isatty(STDERR_FILENO);
- for (i = 0; i < argc; i++)
- sargv[sargc++] = argv[i];
-
- if (do_fork) {
- if (pipe(p) == -1)
- err(1, "cannot create pipe");
- dc = fork();
- if (dc == -1)
- err(1, "cannot fork");
- else if (dc != 0) {
- signal(SIGCHLD, sigchld);
- close(STDOUT_FILENO);
- dup(p[1]);
- close(p[0]);
- close(p[1]);
- } else {
- close(STDIN_FILENO);
- dup(p[0]);
- close(p[0]);
- close(p[1]);
- execl(_PATH_DC, "dc", "-x", (char *)NULL);
- err(1, "cannot find dc");
- }
- }
- if (interactive) {
- gettty(&ttysaved);
- 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_set(el, EL_ADDFN, "bc_eof", "", bc_eof);
- el_set(el, EL_BIND, "^D", "bc_eof", NULL);
- el_source(el, NULL);
- }
- yywrap();
- return (yyparse());
-}
diff --git a/usr.bin/bc/extern.h b/usr.bin/bc/extern.h
deleted file mode 100644
--- a/usr.bin/bc/extern.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* $OpenBSD: extern.h,v 1.12 2014/04/17 19:07:14 otto Exp $ */
-
-/*
- * Copyright (c) 2003, Otto Moerbeek <otto@drijf.net>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <stdbool.h>
-#include <stdio.h>
-
-struct lvalue {
- ssize_t load;
- ssize_t store;
-};
-
-int yylex(void);
-void yyerror(const char *);
-void fatal(const char *);
-void abort_line(int);
-struct termios;
-int gettty(struct termios *);
-void tstpcont(int);
-unsigned char bc_eof(EditLine *, int);
-
-extern int lineno;
-extern int fileindex;
-extern int sargc;
-extern const char **sargv;
-extern const char *filename;
-extern bool interactive;
-extern EditLine *el;
-extern History *hist;
-extern HistEvent he;
-extern char *cmdexpr;
-extern struct termios ttysaved;
diff --git a/usr.bin/bc/pathnames.h b/usr.bin/bc/pathnames.h
deleted file mode 100644
--- a/usr.bin/bc/pathnames.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/* $OpenBSD: pathnames.h,v 1.1 2003/09/25 19:32:44 otto Exp $ */
-
-/*
- * Copyright (c) 2003, Otto Moerbeek <otto@drijf.net>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#define _PATH_LIBB "/usr/share/misc/bc.library"
-#define _PATH_DC "/usr/bin/dc"
diff --git a/usr.bin/bc/scan.l b/usr.bin/bc/scan.l
deleted file mode 100644
--- a/usr.bin/bc/scan.l
+++ /dev/null
@@ -1,368 +0,0 @@
-%{
-/* $OpenBSD: scan.l,v 1.28 2013/09/19 16:12:01 otto Exp $ */
-
-/*
- * Copyright (c) 2003, Otto Moerbeek <otto@drijf.net>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/cdefs.h>
-#include <err.h>
-#include <errno.h>
-#include <histedit.h>
-#include <stdbool.h>
-#include <signal.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "extern.h"
-#include "bc.h"
-#include "pathnames.h"
-
-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 int use_el;
-static volatile sig_atomic_t skipchars;
-
-static void init_strbuf(void);
-static void add_str(const char *);
-
-static int bc_yyinput(char *, int);
-
-#define YY_DECL int yylex(void)
-#define YY_NO_INPUT
-#undef YY_INPUT
-#define YY_INPUT(buf,retval,max) \
- (retval = bc_yyinput(buf, max))
-
-%}
-
-%option always-interactive
-
-DIGIT [0-9A-F]
-ALPHA [a-z_]
-ALPHANUM [a-z_0-9]
-
-%x comment string number
-
-%%
-
-"/*" BEGIN(comment);
-<comment>{
- "*/" BEGIN(INITIAL);
- \n lineno++;
- \* ;
- [^*\n]+ ;
- <<EOF>> fatal("end of file in comment");
-}
-
-\" BEGIN(string); init_strbuf();
-<string>{
- [^"\n\\\[\]]+ add_str(yytext);
- \[ add_str("\\[");
- \] add_str("\\]");
- \\ add_str("\\\\");
- \n add_str("\n"); lineno++;
- \" BEGIN(INITIAL); yylval.str = strbuf; return STRING;
- <<EOF>> fatal("end of file in string");
-}
-
-{DIGIT}+ {
- BEGIN(number);
- dot_seen = false;
- init_strbuf();
- add_str(yytext);
- }
-\. {
- BEGIN(number);
- dot_seen = true;
- init_strbuf();
- add_str(".");
- }
-<number>{
- {DIGIT}+ add_str(yytext);
- \. {
- if (dot_seen) {
- BEGIN(INITIAL);
- yylval.str = strbuf;
- unput('.');
- return NUMBER;
- } else {
- dot_seen = true;
- add_str(".");
- }
- }
- \\\n[ \t]* lineno++;
- [^0-9A-F\.] {
- BEGIN(INITIAL);
- unput(yytext[0]);
- if (strcmp(strbuf, ".") == 0)
- return DOT;
- else {
- yylval.str = strbuf;
- return NUMBER;
- }
- }
-}
-
-"auto" return AUTO;
-"break" return BREAK;
-"continue" return CONTINUE;
-"define" return DEFINE;
-"else" return ELSE;
-"ibase" return IBASE;
-"if" return IF;
-"last" return DOT;
-"for" return FOR;
-"length" return LENGTH;
-"obase" return OBASE;
-"print" return PRINT;
-"quit" return QUIT;
-"return" return RETURN;
-"scale" return SCALE;
-"sqrt" return SQRT;
-"while" return WHILE;
-
-"^" return EXPONENT;
-"*" return MULTIPLY;
-"/" return DIVIDE;
-"%" return REMAINDER;
-
-"!" return BOOL_NOT;
-"&&" return BOOL_AND;
-"||" return BOOL_OR;
-
-"+" return PLUS;
-"-" return MINUS;
-
-"++" return INCR;
-"--" return DECR;
-
-"=" yylval.str = ""; return ASSIGN_OP;
-"+=" yylval.str = "+"; return ASSIGN_OP;
-"-=" yylval.str = "-"; return ASSIGN_OP;
-"*=" yylval.str = "*"; return ASSIGN_OP;
-"/=" yylval.str = "/"; return ASSIGN_OP;
-"%=" yylval.str = "%"; return ASSIGN_OP;
-"^=" yylval.str = "^"; return ASSIGN_OP;
-
-"==" return EQUALS;
-"<=" return LESS_EQ;
-">=" return GREATER_EQ;
-"!=" return UNEQUALS;
-"<" return LESS;
-">" return GREATER;
-
-"," return COMMA;
-";" return SEMICOLON;
-
-"(" return LPAR;
-")" return RPAR;
-
-"[" return LBRACKET;
-"]" return RBRACKET;
-
-"{" return LBRACE;
-"}" return RBRACE;
-
-{ALPHA}{ALPHANUM}* {
- /* alloc an extra byte for the type marker */
- char *p = malloc(yyleng + 2);
- if (p == NULL)
- err(1, NULL);
- strlcpy(p, yytext, yyleng + 1);
- yylval.astr = p;
- return LETTER;
- }
-
-\\\n lineno++;
-\n lineno++; return NEWLINE;
-
-#[^\n]* ;
-[ \t] ;
-<<EOF>> return QUIT;
-. yyerror("illegal character");
-
-%%
-
-static void
-init_strbuf(void)
-{
- if (strbuf == NULL) {
- strbuf = malloc(strbuf_sz);
- if (strbuf == NULL)
- err(1, NULL);
- }
- strbuf[0] = '\0';
-}
-
-static void
-add_str(const char *str)
-{
- size_t arglen;
-
- arglen = strlen(str);
-
- if (strlen(strbuf) + arglen + 1 > strbuf_sz) {
- size_t newsize;
- char *p;
-
- newsize = strbuf_sz + arglen + 1;
- p = realloc(strbuf, newsize);
- if (p == NULL) {
- free(strbuf);
- err(1, NULL);
- }
- strbuf_sz = newsize;
- strbuf = p;
- }
- strlcat(strbuf, str, strbuf_sz);
-}
-
-/* ARGSUSED */
-void
-abort_line(int sig __unused)
-{
- static const char str1[] = "[\n]P\n";
- static const char str2[] = "[^C\n]P\n";
- int save_errno;
- const LineInfo *info;
-
- save_errno = errno;
- if (use_el) {
- write(STDOUT_FILENO, str2, sizeof(str2) - 1);
- info = el_line(el);
- skipchars = info->lastchar - info->buffer;
- } else
- write(STDOUT_FILENO, str1, sizeof(str1) - 1);
- errno = save_errno;
-}
-
-/*
- * Avoid the echo of ^D by the default code of editline and take
- * into account skipchars to make ^D work when the cursor is at start of
- * line after a ^C.
- */
-unsigned char
-bc_eof(EditLine *e, int ch __unused)
-{
- const struct lineinfo *info = el_line(e);
-
- if (info->buffer + skipchars == info->cursor &&
- info->cursor == info->lastchar)
- return (CC_EOF);
- else
- return (CC_ERROR);
-}
-
-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 (yyin != NULL && yyin != stdin)
- fclose(yyin);
- 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;
- if (interactive) {
- signal(SIGINT, abort_line);
- signal(SIGTSTP, tstpcont);
- }
- lineno = 1;
- filename = "stdin";
- return (0);
- }
- return (1);
-}
-
-static int
-bc_yyinput(char *buf, int maxlen)
-{
- int num;
-
- if (el != NULL)
- el_get(el, EL_EDITMODE, &use_el);
-
- if (yyin == stdin && interactive && use_el) {
- const char *bp;
- sigset_t oset, nset;
-
- if ((bp = el_gets(el, &num)) == NULL || num == 0)
- return (0);
- sigemptyset(&nset);
- sigaddset(&nset, SIGINT);
- sigprocmask(SIG_BLOCK, &nset, &oset);
- if (skipchars < num) {
- bp += skipchars;
- num -= skipchars;
- }
- skipchars = 0;
- sigprocmask(SIG_SETMASK, &oset, NULL);
- if (num > maxlen) {
- el_push(el, bp + maxlen);
- num = maxlen;
- }
- memcpy(buf, bp, num);
- history(hist, &he, H_ENTER, bp);
- el_get(el, EL_EDITMODE, &use_el);
- } 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);
-}
-
-
diff --git a/usr.bin/bc/tty.c b/usr.bin/bc/tty.c
deleted file mode 100644
--- a/usr.bin/bc/tty.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/* $OpenBSD: tty.c,v 1.3 2015/09/05 09:49:24 jsg Exp $ */
-
-/*
- * Copyright (c) 2013, Otto Moerbeek <otto@drijf.net>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <errno.h>
-#include <signal.h>
-#include <histedit.h>
-#include <termios.h>
-#include "extern.h"
-
-struct termios ttysaved, ttyedit;
-
-static int
-settty(struct termios *t)
-{
- int ret;
-
- while ((ret = tcsetattr(0, TCSADRAIN, t)) == -1 && errno == EINTR)
- continue;
- return ret;
-}
-
-int
-gettty(struct termios *t)
-{
- int ret;
-
- while ((ret = tcgetattr(0, t)) == -1 && errno == EINTR)
- continue;
- return ret;
-}
-
-/* ARGSUSED */
-void
-tstpcont(int sig)
-{
- int save_errno = errno;
-
- if (sig == SIGTSTP) {
- signal(SIGCONT, tstpcont);
- gettty(&ttyedit);
- settty(&ttysaved);
- } else {
- signal(SIGTSTP, tstpcont);
- settty(&ttyedit);
- }
- signal(sig, SIG_DFL);
- kill(0, sig);
- errno = save_errno;
-}
diff --git a/usr.bin/dc/Makefile b/usr.bin/dc/Makefile
deleted file mode 100644
--- a/usr.bin/dc/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# $OpenBSD: Makefile,v 1.2 2006/11/26 11:31:09 deraadt Exp $
-
-.include <src.opts.mk>
-
-PROG= dc
-SRCS= dc.c bcode.c inout.c mem.c stack.c
-LIBADD= crypto
-
-HAS_TESTS=
-SUBDIR.${MK_TESTS}+= tests
-
-.include <bsd.prog.mk>
diff --git a/usr.bin/dc/Makefile.depend b/usr.bin/dc/Makefile.depend
deleted file mode 100644
--- a/usr.bin/dc/Makefile.depend
+++ /dev/null
@@ -1,18 +0,0 @@
-# Autogenerated - do NOT edit!
-
-DIRDEPS = \
- include \
- include/xlocale \
- lib/${CSU_DIR} \
- lib/libc \
- lib/libcapsicum \
- lib/libcasper/libcasper \
- lib/libcompiler_rt \
- secure/lib/libcrypto \
-
-
-.include <dirdeps.mk>
-
-.if ${DEP_RELDIR} == ${_DEP_RELDIR}
-# local dependencies - needed for -jN in clean tree
-.endif
diff --git a/usr.bin/dc/bcode.h b/usr.bin/dc/bcode.h
deleted file mode 100644
--- a/usr.bin/dc/bcode.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/* $OpenBSD: bcode.h,v 1.7 2012/11/07 11:06:14 otto Exp $ */
-
-/*
- * Copyright (c) 2003, Otto Moerbeek <otto@drijf.net>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/types.h>
-#include <openssl/bn.h>
-
-struct number {
- BIGNUM *number;
- u_int scale;
-};
-
-enum stacktype {
- BCODE_NONE,
- BCODE_NUMBER,
- BCODE_STRING
-};
-
-enum bcode_compare {
- BCODE_EQUAL,
- BCODE_NOT_EQUAL,
- BCODE_LESS,
- BCODE_NOT_LESS,
- BCODE_GREATER,
- BCODE_NOT_GREATER
-};
-
-struct array;
-
-struct value {
- union {
- struct number *num;
- char *string;
- } u;
- struct array *array;
- enum stacktype type;
-};
-
-struct array {
- struct value *data;
- size_t size;
-};
-
-struct stack {
- struct value *stack;
- ssize_t size;
- ssize_t sp;
-};
-
-struct source;
-
-struct vtable {
- int (*readchar)(struct source *);
- void (*unreadchar)(struct source *);
- char *(*readline)(struct source *);
- void (*free)(struct source *);
-};
-
-struct source {
- union {
- struct {
- u_char *buf;
- size_t pos;
- } string;
- FILE *stream;
- } u;
- struct vtable *vtable;
- int lastchar;
-};
-
-void init_bmachine(bool);
-void reset_bmachine(struct source *);
-u_int bmachine_scale(void);
-void scale_number(BIGNUM *, int);
-void normalize(struct number *, u_int);
-void eval(void);
-void pn(const char *, const struct number *);
-void pbn(const char *, const BIGNUM *);
-void negate(struct number *);
-void split_number(const struct number *, BIGNUM *, BIGNUM *);
-void bmul_number(struct number *, struct number *,
- struct number *, u_int scale);
-
-static __inline u_int
-max(u_int a, u_int b)
-{
-
- return (a > b ? a : b);
-}
diff --git a/usr.bin/dc/bcode.c b/usr.bin/dc/bcode.c
deleted file mode 100644
--- a/usr.bin/dc/bcode.c
+++ /dev/null
@@ -1,1773 +0,0 @@
-/* $OpenBSD: bcode.c,v 1.46 2014/10/08 03:59:56 doug Exp $ */
-
-/*
- * Copyright (c) 2003, Otto Moerbeek <otto@drijf.net>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/cdefs.h>
-#include <err.h>
-#include <limits.h>
-#include <openssl/ssl.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "extern.h"
-
-/* #define DEBUGGING */
-
-#define MAX_ARRAY_INDEX 2048
-#define READSTACK_SIZE 8
-
-#define NO_ELSE -2 /* -1 is EOF */
-#define REG_ARRAY_SIZE_SMALL (UCHAR_MAX + 1)
-#define REG_ARRAY_SIZE_BIG (UCHAR_MAX + 1 + USHRT_MAX + 1)
-
-struct bmachine {
- struct source *readstack;
- struct stack *reg;
- struct stack stack;
- u_int scale;
- u_int obase;
- u_int ibase;
- size_t readsp;
- size_t reg_array_size;
- size_t readstack_sz;
- bool extended_regs;
-};
-
-static struct bmachine bmachine;
-
-static __inline int readch(void);
-static __inline void unreadch(void);
-static __inline char *readline(void);
-static __inline void src_free(void);
-
-static u_long get_ulong(struct number *);
-
-static __inline void push_number(struct number *);
-static __inline void push_string(char *);
-static __inline void push(struct value *);
-static __inline struct value *tos(void);
-static __inline struct number *pop_number(void);
-static __inline char *pop_string(void);
-static __inline void clear_stack(void);
-static __inline void print_tos(void);
-static void print_err(void);
-static void pop_print(void);
-static void pop_printn(void);
-static __inline void print_stack(void);
-static __inline void dup(void);
-static void swap(void);
-static void drop(void);
-
-static void get_scale(void);
-static void set_scale(void);
-static void get_obase(void);
-static void set_obase(void);
-static void get_ibase(void);
-static void set_ibase(void);
-static void stackdepth(void);
-static void push_scale(void);
-static u_int count_digits(const struct number *);
-static void num_digits(void);
-static void to_ascii(void);
-static void push_line(void);
-static void comment(void);
-static void bexec(char *);
-static void badd(void);
-static void bsub(void);
-static void bmul(void);
-static void bdiv(void);
-static void bmod(void);
-static void bdivmod(void);
-static void bexp(void);
-static bool bsqrt_stop(const BIGNUM *, const BIGNUM *, u_int *);
-static void bsqrt(void);
-static void not(void);
-static void equal_numbers(void);
-static void less_numbers(void);
-static void lesseq_numbers(void);
-static void equal(void);
-static void not_equal(void);
-static void less(void);
-static void not_less(void);
-static void greater(void);
-static void not_greater(void);
-static void not_compare(void);
-static bool compare_numbers(enum bcode_compare, struct number *,
- struct number *);
-static void compare(enum bcode_compare);
-static int readreg(void);
-static void load(void);
-static void store(void);
-static void load_stack(void);
-static void store_stack(void);
-static void load_array(void);
-static void store_array(void);
-static void nop(void);
-static void quit(void);
-static void quitN(void);
-static void skipN(void);
-static void skip_until_mark(void);
-static void parse_number(void);
-static void unknown(void);
-static void eval_string(char *);
-static void eval_line(void);
-static void eval_tos(void);
-
-
-typedef void (*opcode_function)(void);
-
-struct jump_entry {
- u_char ch;
- opcode_function f;
-};
-
-static opcode_function jump_table[UCHAR_MAX];
-
-static const struct jump_entry jump_table_data[] = {
- { ' ', nop },
- { '!', not_compare },
- { '#', comment },
- { '%', bmod },
- { '(', less_numbers },
- { '*', bmul },
- { '+', badd },
- { '-', bsub },
- { '.', parse_number },
- { '/', bdiv },
- { '0', parse_number },
- { '1', parse_number },
- { '2', parse_number },
- { '3', parse_number },
- { '4', parse_number },
- { '5', parse_number },
- { '6', parse_number },
- { '7', parse_number },
- { '8', parse_number },
- { '9', parse_number },
- { ':', store_array },
- { ';', load_array },
- { '<', less },
- { '=', equal },
- { '>', greater },
- { '?', eval_line },
- { 'A', parse_number },
- { 'B', parse_number },
- { 'C', parse_number },
- { 'D', parse_number },
- { 'E', parse_number },
- { 'F', parse_number },
- { 'G', equal_numbers },
- { 'I', get_ibase },
- { 'J', skipN },
- { 'K', get_scale },
- { 'L', load_stack },
- { 'M', nop },
- { 'N', not },
- { 'O', get_obase },
- { 'P', pop_print },
- { 'Q', quitN },
- { 'R', drop },
- { 'S', store_stack },
- { 'X', push_scale },
- { 'Z', num_digits },
- { '[', push_line },
- { '\f', nop },
- { '\n', nop },
- { '\r', nop },
- { '\t', nop },
- { '^', bexp },
- { '_', parse_number },
- { 'a', to_ascii },
- { 'c', clear_stack },
- { 'd', dup },
- { 'e', print_err },
- { 'f', print_stack },
- { 'i', set_ibase },
- { 'k', set_scale },
- { 'l', load },
- { 'n', pop_printn },
- { 'o', set_obase },
- { 'p', print_tos },
- { 'q', quit },
- { 'r', swap },
- { 's', store },
- { 'v', bsqrt },
- { 'x', eval_tos },
- { 'z', stackdepth },
- { '{', lesseq_numbers },
- { '~', bdivmod }
-};
-
-#define JUMP_TABLE_DATA_SIZE \
- (sizeof(jump_table_data)/sizeof(jump_table_data[0]))
-
-void
-init_bmachine(bool extended_registers)
-{
- unsigned int i;
-
- bmachine.extended_regs = extended_registers;
- bmachine.reg_array_size = bmachine.extended_regs ?
- REG_ARRAY_SIZE_BIG : REG_ARRAY_SIZE_SMALL;
-
- bmachine.reg = calloc(bmachine.reg_array_size,
- sizeof(bmachine.reg[0]));
- if (bmachine.reg == NULL)
- err(1, NULL);
-
- for (i = 0; i < UCHAR_MAX; i++)
- jump_table[i] = unknown;
- for (i = 0; i < JUMP_TABLE_DATA_SIZE; i++)
- jump_table[jump_table_data[i].ch] = jump_table_data[i].f;
-
- stack_init(&bmachine.stack);
-
- for (i = 0; i < bmachine.reg_array_size; i++)
- stack_init(&bmachine.reg[i]);
-
- bmachine.readstack_sz = READSTACK_SIZE;
- bmachine.readstack = calloc(sizeof(struct source),
- bmachine.readstack_sz);
- if (bmachine.readstack == NULL)
- err(1, NULL);
- bmachine.obase = bmachine.ibase = 10;
-}
-
-u_int
-bmachine_scale(void)
-{
- return bmachine.scale;
-}
-
-/* Reset the things needed before processing a (new) file */
-void
-reset_bmachine(struct source *src)
-{
-
- bmachine.readsp = 0;
- bmachine.readstack[0] = *src;
-}
-
-static __inline int
-readch(void)
-{
- struct source *src = &bmachine.readstack[bmachine.readsp];
-
- return (src->vtable->readchar(src));
-}
-
-static __inline void
-unreadch(void)
-{
- struct source *src = &bmachine.readstack[bmachine.readsp];
-
- src->vtable->unreadchar(src);
-}
-
-static __inline char *
-readline(void)
-{
- struct source *src = &bmachine.readstack[bmachine.readsp];
-
- return (src->vtable->readline(src));
-}
-
-static __inline void
-src_free(void)
-{
- struct source *src = &bmachine.readstack[bmachine.readsp];
-
- src->vtable->free(src);
-}
-
-#ifdef DEBUGGING
-void
-pn(const char *str, const struct number *n)
-{
- char *p = BN_bn2dec(n->number);
-
- if (p == NULL)
- err(1, "BN_bn2dec failed");
- fputs(str, stderr);
- fprintf(stderr, " %s (%u)\n" , p, n->scale);
- OPENSSL_free(p);
-}
-
-void
-pbn(const char *str, const BIGNUM *n)
-{
- char *p = BN_bn2dec(n);
-
- if (p == NULL)
- err(1, "BN_bn2dec failed");
- fputs(str, stderr);
- fprintf(stderr, " %s\n", p);
- OPENSSL_free(p);
-}
-
-#endif
-
-static unsigned long factors[] = {
- 0, 10, 100, 1000, 10000, 100000, 1000000, 10000000,
- 100000000, 1000000000
-};
-
-/* Multiply n by 10^s */
-void
-scale_number(BIGNUM *n, int s)
-{
- unsigned int abs_scale;
-
- if (s == 0)
- return;
-
- abs_scale = s > 0 ? s : -s;
-
- if (abs_scale < sizeof(factors)/sizeof(factors[0])) {
- if (s > 0)
- bn_check(BN_mul_word(n, factors[abs_scale]));
- else
- BN_div_word(n, factors[abs_scale]);
- } else {
- BIGNUM *a, *p;
- BN_CTX *ctx;
-
- a = BN_new();
- bn_checkp(a);
- p = BN_new();
- bn_checkp(p);
- ctx = BN_CTX_new();
- bn_checkp(ctx);
-
- bn_check(BN_set_word(a, 10));
- bn_check(BN_set_word(p, abs_scale));
- bn_check(BN_exp(a, a, p, ctx));
- if (s > 0)
- bn_check(BN_mul(n, n, a, ctx));
- else
- bn_check(BN_div(n, NULL, n, a, ctx));
- BN_CTX_free(ctx);
- BN_free(a);
- BN_free(p);
- }
-}
-
-void
-split_number(const struct number *n, BIGNUM *i, BIGNUM *f)
-{
- u_long rem;
-
- bn_checkp(BN_copy(i, n->number));
-
- if (n->scale == 0 && f != NULL)
- BN_zero(f);
- else if (n->scale < sizeof(factors)/sizeof(factors[0])) {
- rem = BN_div_word(i, factors[n->scale]);
- if (f != NULL)
- bn_check(BN_set_word(f, rem));
- } else {
- BIGNUM *a, *p;
- BN_CTX *ctx;
-
- a = BN_new();
- bn_checkp(a);
- p = BN_new();
- bn_checkp(p);
- ctx = BN_CTX_new();
- bn_checkp(ctx);
-
- bn_check(BN_set_word(a, 10));
- bn_check(BN_set_word(p, n->scale));
- bn_check(BN_exp(a, a, p, ctx));
- bn_check(BN_div(i, f, n->number, a, ctx));
- BN_CTX_free(ctx);
- BN_free(a);
- BN_free(p);
- }
-}
-
-/* Change the scale of n to s. Reducing scale may truncate the mantissa */
-void
-normalize(struct number *n, u_int s)
-{
-
- scale_number(n->number, s - n->scale);
- n->scale = s;
-}
-
-static u_long
-get_ulong(struct number *n)
-{
-
- normalize(n, 0);
- return (BN_get_word(n->number));
-}
-
-void
-negate(struct number *n)
-{
- BN_set_negative(n->number, !BN_is_negative(n->number));
-}
-
-static __inline void
-push_number(struct number *n)
-{
-
- stack_pushnumber(&bmachine.stack, n);
-}
-
-static __inline void
-push_string(char *string)
-{
-
- stack_pushstring(&bmachine.stack, string);
-}
-
-static __inline void
-push(struct value *v)
-{
-
- stack_push(&bmachine.stack, v);
-}
-
-static __inline struct value *
-tos(void)
-{
-
- return (stack_tos(&bmachine.stack));
-}
-
-static __inline struct value *
-pop(void)
-{
-
- return (stack_pop(&bmachine.stack));
-}
-
-static __inline struct number *
-pop_number(void)
-{
-
- return (stack_popnumber(&bmachine.stack));
-}
-
-static __inline char *
-pop_string(void)
-{
-
- return (stack_popstring(&bmachine.stack));
-}
-
-static __inline void
-clear_stack(void)
-{
-
- stack_clear(&bmachine.stack);
-}
-
-static __inline void
-print_stack(void)
-{
-
- stack_print(stdout, &bmachine.stack, "", bmachine.obase);
-}
-
-static __inline void
-print_tos(void)
-{
- struct value *value = tos();
-
- if (value != NULL) {
- print_value(stdout, value, "", bmachine.obase);
- putchar('\n');
- }
- else
- warnx("stack empty");
-}
-
-static void
-print_err(void)
-{
- struct value *value = tos();
- if (value != NULL) {
- print_value(stderr, value, "", bmachine.obase);
- (void)putc('\n', stderr);
- }
- else
- warnx("stack empty");
-}
-
-static void
-pop_print(void)
-{
- struct value *value = pop();
-
- if (value != NULL) {
- switch (value->type) {
- case BCODE_NONE:
- break;
- case BCODE_NUMBER:
- normalize(value->u.num, 0);
- print_ascii(stdout, value->u.num);
- fflush(stdout);
- break;
- case BCODE_STRING:
- fputs(value->u.string, stdout);
- fflush(stdout);
- break;
- }
- stack_free_value(value);
- }
-}
-
-static void
-pop_printn(void)
-{
- struct value *value = pop();
-
- if (value != NULL) {
- print_value(stdout, value, "", bmachine.obase);
- fflush(stdout);
- stack_free_value(value);
- }
-}
-
-static __inline void
-dup(void)
-{
-
- stack_dup(&bmachine.stack);
-}
-
-static void
-swap(void)
-{
-
- stack_swap(&bmachine.stack);
-}
-
-static void
-drop(void)
-{
- struct value *v = pop();
- if (v != NULL)
- stack_free_value(v);
-}
-
-static void
-get_scale(void)
-{
- struct number *n;
-
- n = new_number();
- bn_check(BN_set_word(n->number, bmachine.scale));
- push_number(n);
-}
-
-static void
-set_scale(void)
-{
- struct number *n;
- u_long scale;
-
- n = pop_number();
- if (n != NULL) {
- if (BN_is_negative(n->number))
- warnx("scale must be a nonnegative number");
- else {
- scale = get_ulong(n);
- if (scale != ULONG_MAX && scale <= UINT_MAX)
- bmachine.scale = (u_int)scale;
- else
- warnx("scale too large");
- }
- free_number(n);
- }
-}
-
-static void
-get_obase(void)
-{
- struct number *n;
-
- n = new_number();
- bn_check(BN_set_word(n->number, bmachine.obase));
- push_number(n);
-}
-
-static void
-set_obase(void)
-{
- struct number *n;
- u_long base;
-
- n = pop_number();
- if (n != NULL) {
- base = get_ulong(n);
- if (base != ULONG_MAX && base > 1 && base <= UINT_MAX)
- bmachine.obase = (u_int)base;
- else
- warnx("output base must be a number greater than 1");
- free_number(n);
- }
-}
-
-static void
-get_ibase(void)
-{
- struct number *n;
-
- n = new_number();
- bn_check(BN_set_word(n->number, bmachine.ibase));
- push_number(n);
-}
-
-static void
-set_ibase(void)
-{
- struct number *n;
- u_long base;
-
- n = pop_number();
- if (n != NULL) {
- base = get_ulong(n);
- if (base != ULONG_MAX && 2 <= base && base <= 16)
- bmachine.ibase = (u_int)base;
- else
- warnx("input base must be a number between 2 and 16 "
- "(inclusive)");
- free_number(n);
- }
-}
-
-static void
-stackdepth(void)
-{
- struct number *n;
- size_t i;
-
- i = stack_size(&bmachine.stack);
- n = new_number();
- bn_check(BN_set_word(n->number, i));
- push_number(n);
-}
-
-static void
-push_scale(void)
-{
- struct number *n;
- struct value *value;
- u_int scale = 0;
-
- value = pop();
- if (value != NULL) {
- switch (value->type) {
- case BCODE_NONE:
- return;
- case BCODE_NUMBER:
- scale = value->u.num->scale;
- break;
- case BCODE_STRING:
- break;
- }
- stack_free_value(value);
- n = new_number();
- bn_check(BN_set_word(n->number, scale));
- push_number(n);
- }
-}
-
-static u_int
-count_digits(const struct number *n)
-{
- struct number *int_part, *fract_part;
- u_int i;
-
- if (BN_is_zero(n->number))
- return n->scale ? n->scale : 1;
-
- int_part = new_number();
- fract_part = new_number();
- fract_part->scale = n->scale;
- split_number(n, int_part->number, fract_part->number);
-
- i = 0;
- while (!BN_is_zero(int_part->number)) {
- BN_div_word(int_part->number, 10);
- i++;
- }
- free_number(int_part);
- free_number(fract_part);
- return (i + n->scale);
-}
-
-static void
-num_digits(void)
-{
- struct number *n = NULL;
- struct value *value;
- size_t digits;
-
- value = pop();
- if (value != NULL) {
- switch (value->type) {
- case BCODE_NONE:
- return;
- case BCODE_NUMBER:
- digits = count_digits(value->u.num);
- n = new_number();
- bn_check(BN_set_word(n->number, digits));
- break;
- case BCODE_STRING:
- digits = strlen(value->u.string);
- n = new_number();
- bn_check(BN_set_word(n->number, digits));
- break;
- }
- stack_free_value(value);
- push_number(n);
- }
-}
-
-static void
-to_ascii(void)
-{
- struct number *n;
- struct value *value;
- char str[2];
-
- value = pop();
- if (value != NULL) {
- str[1] = '\0';
- switch (value->type) {
- case BCODE_NONE:
- return;
- case BCODE_NUMBER:
- n = value->u.num;
- normalize(n, 0);
- if (BN_num_bits(n->number) > 8)
- bn_check(BN_mask_bits(n->number, 8));
- str[0] = (char)BN_get_word(n->number);
- break;
- case BCODE_STRING:
- str[0] = value->u.string[0];
- break;
- }
- stack_free_value(value);
- push_string(bstrdup(str));
- }
-}
-
-static int
-readreg(void)
-{
- int ch1, ch2, idx;
-
- idx = readch();
- if (idx == 0xff && bmachine.extended_regs) {
- ch1 = readch();
- ch2 = readch();
- if (ch1 == EOF || ch2 == EOF) {
- warnx("unexpected eof");
- idx = -1;
- } else
- idx = (ch1 << 8) + ch2 + UCHAR_MAX + 1;
- }
- if (idx < 0 || (unsigned)idx >= bmachine.reg_array_size) {
- warnx("internal error: reg num = %d", idx);
- idx = -1;
- }
- return (idx);
-}
-
-static void
-load(void)
-{
- struct number *n;
- struct value *v;
- struct value copy;
- int idx;
-
- idx = readreg();
- if (idx >= 0) {
- v = stack_tos(&bmachine.reg[idx]);
- if (v == NULL) {
- n = new_number();
- BN_zero(n->number);
- push_number(n);
- } else
- push(stack_dup_value(v, &copy));
- }
-}
-
-static void
-store(void)
-{
- struct value *val;
- int idx;
-
- idx = readreg();
- if (idx >= 0) {
- val = pop();
- if (val == NULL) {
- return;
- }
- stack_set_tos(&bmachine.reg[idx], val);
- }
-}
-
-static void
-load_stack(void)
-{
- struct stack *stack;
- struct value *value;
- int idx;
-
- idx = readreg();
- if (idx >= 0) {
- stack = &bmachine.reg[idx];
- value = NULL;
- if (stack_size(stack) > 0) {
- value = stack_pop(stack);
- }
- if (value != NULL)
- push(value);
- else
- warnx("stack register '%c' (0%o) is empty",
- idx, idx);
- }
-}
-
-static void
-store_stack(void)
-{
- struct value *value;
- int idx;
-
- idx = readreg();
- if (idx >= 0) {
- value = pop();
- if (value == NULL)
- return;
- stack_push(&bmachine.reg[idx], value);
- }
-}
-
-static void
-load_array(void)
-{
- struct number *inumber, *n;
- struct stack *stack;
- struct value *v;
- struct value copy;
- u_long idx;
- int reg;
-
- reg = readreg();
- if (reg >= 0) {
- inumber = pop_number();
- if (inumber == NULL)
- return;
- idx = get_ulong(inumber);
- if (BN_is_negative(inumber->number))
- warnx("negative idx");
- else if (idx == ULONG_MAX || idx > MAX_ARRAY_INDEX)
- warnx("idx too big");
- else {
- stack = &bmachine.reg[reg];
- v = frame_retrieve(stack, idx);
- if (v == NULL || v->type == BCODE_NONE) {
- n = new_number();
- BN_zero(n->number);
- push_number(n);
- }
- else
- push(stack_dup_value(v, &copy));
- }
- free_number(inumber);
- }
-}
-
-static void
-store_array(void)
-{
- struct number *inumber;
- struct value *value;
- struct stack *stack;
- u_long idx;
- int reg;
-
- reg = readreg();
- if (reg >= 0) {
- inumber = pop_number();
- if (inumber == NULL)
- return;
- value = pop();
- if (value == NULL) {
- free_number(inumber);
- return;
- }
- idx = get_ulong(inumber);
- if (BN_is_negative(inumber->number)) {
- warnx("negative idx");
- stack_free_value(value);
- } else if (idx == ULONG_MAX || idx > MAX_ARRAY_INDEX) {
- warnx("idx too big");
- stack_free_value(value);
- } else {
- stack = &bmachine.reg[reg];
- frame_assign(stack, idx, value);
- }
- free_number(inumber);
- }
-}
-
-static void
-push_line(void)
-{
-
- push_string(read_string(&bmachine.readstack[bmachine.readsp]));
-}
-
-static void
-comment(void)
-{
-
- free(readline());
-}
-
-static void
-bexec(char *line)
-{
-
- system(line);
- free(line);
-}
-
-static void
-badd(void)
-{
- struct number *a, *b, *r;
-
- a = pop_number();
- if (a == NULL)
- return;
- b = pop_number();
- if (b == NULL) {
- push_number(a);
- return;
- }
-
- r = new_number();
- r->scale = max(a->scale, b->scale);
- if (r->scale > a->scale)
- normalize(a, r->scale);
- else if (r->scale > b->scale)
- normalize(b, r->scale);
- bn_check(BN_add(r->number, a->number, b->number));
- push_number(r);
- free_number(a);
- free_number(b);
-}
-
-static void
-bsub(void)
-{
- struct number *a, *b, *r;
-
- a = pop_number();
- if (a == NULL)
- return;
- b = pop_number();
- if (b == NULL) {
- push_number(a);
- return;
- }
-
- r = new_number();
-
- r->scale = max(a->scale, b->scale);
- if (r->scale > a->scale)
- normalize(a, r->scale);
- else if (r->scale > b->scale)
- normalize(b, r->scale);
- bn_check(BN_sub(r->number, b->number, a->number));
- push_number(r);
- free_number(a);
- free_number(b);
-}
-
-void
-bmul_number(struct number *r, struct number *a, struct number *b, u_int scale)
-{
- BN_CTX *ctx;
-
- /* Create copies of the scales, since r might be equal to a or b */
- u_int ascale = a->scale;
- u_int bscale = b->scale;
- u_int rscale = ascale + bscale;
-
- ctx = BN_CTX_new();
- bn_checkp(ctx);
- bn_check(BN_mul(r->number, a->number, b->number, ctx));
- BN_CTX_free(ctx);
-
- r->scale = rscale;
- if (rscale > bmachine.scale && rscale > ascale && rscale > bscale)
- normalize(r, max(scale, max(ascale, bscale)));
-}
-
-static void
-bmul(void)
-{
- struct number *a, *b, *r;
-
- a = pop_number();
- if (a == NULL)
- return;
- b = pop_number();
- if (b == NULL) {
- push_number(a);
- return;
- }
-
- r = new_number();
- bmul_number(r, a, b, bmachine.scale);
-
- push_number(r);
- free_number(a);
- free_number(b);
-}
-
-static void
-bdiv(void)
-{
- struct number *a, *b, *r;
-
- a = pop_number();
- if (a == NULL)
- return;
- b = pop_number();
- if (b == NULL) {
- push_number(a);
- return;
- }
-
- r = div_number(b, a, bmachine.scale);
-
- push_number(r);
- free_number(a);
- free_number(b);
-}
-
-static void
-bmod(void)
-{
- struct number *a, *b, *r;
- BN_CTX *ctx;
- u_int scale;
-
- a = pop_number();
- if (a == NULL)
- return;
- b = pop_number();
- if (b == NULL) {
- push_number(a);
- return;
- }
-
- r = new_number();
- scale = max(a->scale, b->scale);
- r->scale = scale;
-
- if (BN_is_zero(a->number))
- warnx("remainder by zero");
- else {
- normalize(a, scale);
- normalize(b, scale);
-
- ctx = BN_CTX_new();
- bn_checkp(ctx);
- bn_check(BN_mod(r->number, b->number, a->number, ctx));
- BN_CTX_free(ctx);
- }
- push_number(r);
- free_number(a);
- free_number(b);
-}
-
-static void
-bdivmod(void)
-{
- struct number *a, *b, *frac, *quotient, *rdiv, *remainder;
- BN_CTX *ctx;
- u_int scale;
-
- a = pop_number();
- if (a == NULL)
- return;
- b = pop_number();
- if (b == NULL) {
- push_number(a);
- return;
- }
-
- rdiv = new_number();
- quotient = new_number();
- remainder = new_number();
- scale = max(a->scale, b->scale);
- rdiv->scale = 0;
- remainder->scale = scale;
- quotient->scale = bmachine.scale;
- scale = max(a->scale, b->scale);
-
- if (BN_is_zero(a->number))
- warnx("divide by zero");
- else {
- normalize(a, scale);
- normalize(b, scale);
-
- ctx = BN_CTX_new();
- bn_checkp(ctx);
- /*
- * Unlike other languages' divmod operations, dc is specified
- * to return the remainder and the full quotient, rather than
- * the remainder and the floored quotient. bn(3) has no
- * function to calculate both. So we'll use BN_div to get the
- * remainder and floored quotient, then calculate the full
- * quotient from those.
- *
- * quotient = rdiv + remainder / divisor
- */
- bn_check(BN_div(rdiv->number, remainder->number,
- b->number, a->number, ctx));
- frac = div_number(remainder, a, bmachine.scale);
- normalize(rdiv, bmachine.scale);
- normalize(remainder, scale);
- bn_check(BN_add(quotient->number, rdiv->number, frac->number));
- free_number(frac);
- BN_CTX_free(ctx);
- }
- push_number(quotient);
- push_number(remainder);
- free_number(rdiv);
- free_number(a);
- free_number(b);
-}
-
-static void
-bexp(void)
-{
- struct number *a, *p;
- struct number *r;
- bool neg;
- u_int rscale;
-
- p = pop_number();
- if (p == NULL)
- return;
- a = pop_number();
- if (a == NULL) {
- push_number(p);
- return;
- }
-
- if (p->scale != 0) {
- BIGNUM *i, *f;
- i = BN_new();
- bn_checkp(i);
- f = BN_new();
- bn_checkp(f);
- split_number(p, i, f);
- if (!BN_is_zero(f))
- warnx("Runtime warning: non-zero fractional part in exponent");
- BN_free(i);
- BN_free(f);
- }
-
- normalize(p, 0);
-
- neg = false;
- if (BN_is_negative(p->number)) {
- neg = true;
- negate(p);
- rscale = bmachine.scale;
- } else {
- /* Posix bc says min(a.scale * b, max(a.scale, scale) */
- u_long b;
- u_int m;
-
- b = BN_get_word(p->number);
- m = max(a->scale, bmachine.scale);
- rscale = a->scale * (u_int)b;
- if (rscale > m || (a->scale > 0 && (b == ULONG_MAX ||
- b > UINT_MAX)))
- rscale = m;
- }
-
- if (BN_is_zero(p->number)) {
- r = new_number();
- bn_check(BN_one(r->number));
- normalize(r, rscale);
- } else {
- u_int ascale, mscale;
-
- ascale = a->scale;
- while (!BN_is_bit_set(p->number, 0)) {
- ascale *= 2;
- bmul_number(a, a, a, ascale);
- bn_check(BN_rshift1(p->number, p->number));
- }
-
- r = dup_number(a);
- bn_check(BN_rshift1(p->number, p->number));
-
- mscale = ascale;
- while (!BN_is_zero(p->number)) {
- ascale *= 2;
- bmul_number(a, a, a, ascale);
- if (BN_is_bit_set(p->number, 0)) {
- mscale += ascale;
- bmul_number(r, r, a, mscale);
- }
- bn_check(BN_rshift1(p->number, p->number));
- }
-
- if (neg) {
- BN_CTX *ctx;
- BIGNUM *one;
-
- one = BN_new();
- bn_checkp(one);
- bn_check(BN_one(one));
- ctx = BN_CTX_new();
- bn_checkp(ctx);
- scale_number(one, r->scale + rscale);
-
- if (BN_is_zero(r->number))
- warnx("divide by zero");
- else
- bn_check(BN_div(r->number, NULL, one,
- r->number, ctx));
- BN_free(one);
- BN_CTX_free(ctx);
- r->scale = rscale;
- } else
- normalize(r, rscale);
- }
- push_number(r);
- free_number(a);
- free_number(p);
-}
-
-static bool
-bsqrt_stop(const BIGNUM *x, const BIGNUM *y, u_int *onecount)
-{
- BIGNUM *r;
- bool ret;
-
- r = BN_new();
- bn_checkp(r);
- bn_check(BN_sub(r, x, y));
- if (BN_is_one(r))
- (*onecount)++;
- ret = BN_is_zero(r);
- BN_free(r);
- return (ret || *onecount > 1);
-}
-
-static void
-bsqrt(void)
-{
- struct number *n, *r;
- BIGNUM *x, *y;
- BN_CTX *ctx;
- u_int onecount, scale;
-
- onecount = 0;
- n = pop_number();
- if (n == NULL)
- return;
- if (BN_is_zero(n->number)) {
- r = new_number();
- push_number(r);
- } else if (BN_is_negative(n->number))
- warnx("square root of negative number");
- else {
- scale = max(bmachine.scale, n->scale);
- normalize(n, 2*scale);
- x = BN_dup(n->number);
- bn_checkp(x);
- bn_check(BN_rshift(x, x, BN_num_bits(x)/2));
- y = BN_new();
- bn_checkp(y);
- ctx = BN_CTX_new();
- bn_checkp(ctx);
- for (;;) {
- bn_checkp(BN_copy(y, x));
- bn_check(BN_div(x, NULL, n->number, x, ctx));
- bn_check(BN_add(x, x, y));
- bn_check(BN_rshift1(x, x));
- if (bsqrt_stop(x, y, &onecount))
- break;
- }
- r = bmalloc(sizeof(*r));
- r->scale = scale;
- r->number = y;
- BN_free(x);
- BN_CTX_free(ctx);
- push_number(r);
- }
-
- free_number(n);
-}
-
-static void
-not(void)
-{
- struct number *a;
-
- a = pop_number();
- if (a == NULL)
- return;
- a->scale = 0;
- bn_check(BN_set_word(a->number, BN_get_word(a->number) ? 0 : 1));
- push_number(a);
-}
-
-static void
-equal(void)
-{
-
- compare(BCODE_EQUAL);
-}
-
-static void
-equal_numbers(void)
-{
- struct number *a, *b, *r;
-
- a = pop_number();
- if (a == NULL)
- return;
- b = pop_number();
- if (b == NULL) {
- push_number(a);
- return;
- }
- r = new_number();
- bn_check(BN_set_word(r->number,
- compare_numbers(BCODE_EQUAL, a, b) ? 1 : 0));
- push_number(r);
-}
-
-static void
-less_numbers(void)
-{
- struct number *a, *b, *r;
-
- a = pop_number();
- if (a == NULL)
- return;
- b = pop_number();
- if (b == NULL) {
- push_number(a);
- return;
- }
- r = new_number();
- bn_check(BN_set_word(r->number,
- compare_numbers(BCODE_LESS, a, b) ? 1 : 0));
- push_number(r);
-}
-
-static void
-lesseq_numbers(void)
-{
- struct number *a, *b, *r;
-
- a = pop_number();
- if (a == NULL)
- return;
- b = pop_number();
- if (b == NULL) {
- push_number(a);
- return;
- }
- r = new_number();
- bn_check(BN_set_word(r->number,
- compare_numbers(BCODE_NOT_GREATER, a, b) ? 1 : 0));
- push_number(r);
-}
-
-static void
-not_equal(void)
-{
-
- compare(BCODE_NOT_EQUAL);
-}
-
-static void
-less(void)
-{
-
- compare(BCODE_LESS);
-}
-
-static void
-not_compare(void)
-{
-
- switch (readch()) {
- case '<':
- not_less();
- break;
- case '>':
- not_greater();
- break;
- case '=':
- not_equal();
- break;
- default:
- unreadch();
- bexec(readline());
- break;
- }
-}
-
-static void
-not_less(void)
-{
-
- compare(BCODE_NOT_LESS);
-}
-
-static void
-greater(void)
-{
-
- compare(BCODE_GREATER);
-}
-
-static void
-not_greater(void)
-{
-
- compare(BCODE_NOT_GREATER);
-}
-
-static bool
-compare_numbers(enum bcode_compare type, struct number *a, struct number *b)
-{
- u_int scale;
- int cmp;
-
- scale = max(a->scale, b->scale);
-
- if (scale > a->scale)
- normalize(a, scale);
- else if (scale > b->scale)
- normalize(b, scale);
-
- cmp = BN_cmp(a->number, b->number);
-
- free_number(a);
- free_number(b);
-
- switch (type) {
- case BCODE_EQUAL:
- return (cmp == 0);
- case BCODE_NOT_EQUAL:
- return (cmp != 0);
- case BCODE_LESS:
- return (cmp < 0);
- case BCODE_NOT_LESS:
- return (cmp >= 0);
- case BCODE_GREATER:
- return (cmp > 0);
- case BCODE_NOT_GREATER:
- return (cmp <= 0);
- }
- return (false);
-}
-
-static void
-compare(enum bcode_compare type)
-{
- struct number *a, *b;
- struct value *v;
- int idx, elseidx;
- bool ok;
-
- elseidx = NO_ELSE;
- idx = readreg();
- if (readch() == 'e')
- elseidx = readreg();
- else
- unreadch();
-
- a = pop_number();
- if (a == NULL)
- return;
- b = pop_number();
- if (b == NULL) {
- push_number(a);
- return;
- }
-
- ok = compare_numbers(type, a, b);
-
- if (!ok && elseidx != NO_ELSE)
- idx = elseidx;
-
- if (idx >= 0 && (ok || (!ok && elseidx != NO_ELSE))) {
- v = stack_tos(&bmachine.reg[idx]);
- if (v == NULL)
- warnx("register '%c' (0%o) is empty", idx, idx);
- else {
- switch(v->type) {
- case BCODE_NONE:
- warnx("register '%c' (0%o) is empty", idx, idx);
- break;
- case BCODE_NUMBER:
- warn("eval called with non-string argument");
- break;
- case BCODE_STRING:
- eval_string(bstrdup(v->u.string));
- break;
- }
- }
- }
-}
-
-
-static void
-nop(void)
-{
-
-}
-
-static void
-quit(void)
-{
-
- if (bmachine.readsp < 2)
- exit(0);
- src_free();
- bmachine.readsp--;
- src_free();
- bmachine.readsp--;
-}
-
-static void
-quitN(void)
-{
- struct number *n;
- u_long i;
-
- n = pop_number();
- if (n == NULL)
- return;
- i = get_ulong(n);
- free_number(n);
- if (i == ULONG_MAX || i == 0)
- warnx("Q command requires a number >= 1");
- else if (bmachine.readsp < i)
- warnx("Q command argument exceeded string execution depth");
- else {
- while (i-- > 0) {
- src_free();
- bmachine.readsp--;
- }
- }
-}
-
-static void
-skipN(void)
-{
- struct number *n;
- u_long i;
-
- n = pop_number();
- if (n == NULL)
- return;
- i = get_ulong(n);
- if (i == ULONG_MAX)
- warnx("J command requires a number >= 0");
- else if (i > 0 && bmachine.readsp < i)
- warnx("J command argument exceeded string execution depth");
- else {
- while (i-- > 0) {
- src_free();
- bmachine.readsp--;
- }
- skip_until_mark();
- }
-}
-
-static void
-skip_until_mark(void)
-{
-
- for (;;) {
- switch (readch()) {
- case 'M':
- return;
- case EOF:
- errx(1, "mark not found");
- return;
- case 'l':
- case 'L':
- case 's':
- case 'S':
- case ':':
- case ';':
- case '<':
- case '>':
- case '=':
- readreg();
- if (readch() == 'e')
- readreg();
- else
- unreadch();
- break;
- case '[':
- free(read_string(&bmachine.readstack[bmachine.readsp]));
- break;
- case '!':
- switch (readch()) {
- case '<':
- case '>':
- case '=':
- readreg();
- if (readch() == 'e')
- readreg();
- else
- unreadch();
- break;
- default:
- free(readline());
- break;
- }
- break;
- default:
- break;
- }
- }
-}
-
-static void
-parse_number(void)
-{
-
- unreadch();
- push_number(readnumber(&bmachine.readstack[bmachine.readsp],
- bmachine.ibase, bmachine.scale));
-}
-
-static void
-unknown(void)
-{
- int ch = bmachine.readstack[bmachine.readsp].lastchar;
- warnx("%c (0%o) is unimplemented", ch, ch);
-}
-
-static void
-eval_string(char *p)
-{
- int ch;
-
- if (bmachine.readsp > 0) {
- /* Check for tail call. Do not recurse in that case. */
- ch = readch();
- if (ch == EOF) {
- src_free();
- src_setstring(&bmachine.readstack[bmachine.readsp], p);
- return;
- } else
- unreadch();
- }
- if (bmachine.readsp == bmachine.readstack_sz - 1) {
- size_t newsz = bmachine.readstack_sz * 2;
- struct source *stack;
- stack = reallocarray(bmachine.readstack, newsz,
- sizeof(struct source));
- if (stack == NULL)
- err(1, "recursion too deep");
- bmachine.readstack_sz = newsz;
- bmachine.readstack = stack;
- }
- src_setstring(&bmachine.readstack[++bmachine.readsp], p);
-}
-
-static void
-eval_line(void)
-{
- /* Always read from stdin */
- struct source in;
- char *p;
-
- clearerr(stdin);
- src_setstream(&in, stdin);
- p = (*in.vtable->readline)(&in);
- eval_string(p);
-}
-
-static void
-eval_tos(void)
-{
- char *p;
-
- p = pop_string();
- if (p != NULL)
- eval_string(p);
-}
-
-void
-eval(void)
-{
- int ch;
-
- for (;;) {
- ch = readch();
- if (ch == EOF) {
- if (bmachine.readsp == 0)
- return;
- src_free();
- bmachine.readsp--;
- continue;
- }
-#ifdef DEBUGGING
- fprintf(stderr, "# %c\n", ch);
- stack_print(stderr, &bmachine.stack, "* ",
- bmachine.obase);
- fprintf(stderr, "%zd =>\n", bmachine.readsp);
-#endif
-
- if (0 <= ch && ch < (signed)UCHAR_MAX)
- (*jump_table[ch])();
- else
- warnx("internal error: opcode %d", ch);
-
-#ifdef DEBUGGING
- stack_print(stderr, &bmachine.stack, "* ",
- bmachine.obase);
- fprintf(stderr, "%zd ==\n", bmachine.readsp);
-#endif
- }
-}
diff --git a/usr.bin/dc/dc.1 b/usr.bin/dc/dc.1
deleted file mode 100644
--- a/usr.bin/dc/dc.1
+++ /dev/null
@@ -1,555 +0,0 @@
-.\" $OpenBSD: dc.1,v 1.27 2012/08/19 12:07:21 jmc Exp $
-.\"
-.\" Copyright (C) Caldera International Inc. 2001-2002.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code and documentation must retain the above
-.\" copyright notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed or owned by Caldera
-.\" International, Inc.
-.\" 4. Neither the name of Caldera International, Inc. nor the names of other
-.\" contributors may be used to endorse or promote products derived from
-.\" this software without specific prior written permission.
-.\"
-.\" USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
-.\" INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
-.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-.\" IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE FOR ANY DIRECT,
-.\" INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-.\" (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-.\" SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-.\" IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-.\" POSSIBILITY OF SUCH DAMAGE.
-.\"
-.Dd September 4, 2019
-.Dt DC 1
-.Os
-.Sh NAME
-.Nm dc
-.Nd desk calculator
-.Sh SYNOPSIS
-.Nm
-.Op Fl hxV
-.Op Fl e Ar expression
-.Op Fl f Ar filename
-.Op Ar filename
-.Sh DESCRIPTION
-.Nm
-is an arbitrary precision arithmetic package.
-The overall structure of
-.Nm
-is
-a stacking (reverse Polish) calculator i.e.\&
-numbers are stored on a stack.
-Adding a number pushes it onto the stack.
-Arithmetic operations pop arguments off the stack
-and push the results.
-See also the
-.Xr bc 1
-utility, which is a preprocessor for
-.Nm
-providing infix notation and a C-like syntax
-which implements functions and reasonable control
-structures for programs.
-The options are as follows:
-.Bl -tag -width Ds
-.It Fl e Ar expr , Fl Fl expression Ar expr
-Evaluate
-.Ar expression .
-If multiple
-.Fl e
-options are specified, they will be processed in the order given.
-.It Fl f Ar filename , Fl Fl file Ar filename
-Process the content of the given file before further calculations are done.
-If multiple
-.Fl f
-options are specified, they will be processed in the order given.
-.It Fl h , Fl Fl help
-Print short usage info.
-.It Fl V , Fl Fl version
-Print version info.
-.It Fl x
-Enable extended register mode.
-This mode is used by
-.Xr bc 1
-to allow more than 256 registers.
-See
-.Sx Registers
-for a more detailed description.
-.El
-.Pp
-If neither
-.Ar expression
-nor
-.Ar file
-are specified on the command line,
-.Nm
-reads from the standard input.
-Otherwise
-.Ar expression
-and
-.Ar file
-are processed and
-.Nm
-exits.
-.Pp
-Ordinarily,
-.Nm
-operates on decimal integers,
-but one may specify an input base, output base,
-and a number of fractional digits (scale) to be maintained.
-Whitespace is ignored, except where it signals the end of a number,
-end of a line or when a register name is expected.
-The following constructions are recognized:
-.Bl -tag -width "number"
-.It Va number
-The value of the number is pushed on the stack.
-A number is an unbroken string of the digits 0\-9 and letters A\-F.
-It may be preceded by an underscore
-.Pq Sq _
-to input a negative number.
-A number may contain a single decimal point.
-A number may also contain the characters A\-F, with the values 10\-15.
-.It Cm "+ - / * % ~ ^"
-The
-top two values on the stack are added
-(+),
-subtracted
-(\-),
-multiplied (*),
-divided (/),
-remaindered (%),
-divided and remaindered (~),
-or exponentiated (^).
-The two entries are popped off the stack;
-the result is pushed on the stack in their place.
-Any fractional part of an exponent is ignored.
-.Pp
-For addition, subtraction, and remainder, the scale of the result is the
-maximum of scales of the operands.
-For division the scale of the result is defined
-by the scale set by the
-.Ic k
-operation.
-For multiplication, the scale is defined by the expression
-.Sy min(a+b,max(a,b,scale)) ,
-where
-.Sy a
-and
-.Sy b
-are the scales of the operands, and
-.Sy scale
-is the scale defined by the
-.Ic k
-operation.
-For exponentiation with a non-negative exponent, the scale of the result is
-.Sy min(a*b,max(scale,a)) ,
-where
-.Sy a
-is the scale of the base, and
-.Sy b
-is the
-.Em value
-of the exponent.
-If the exponent is negative, the scale of the result is the scale
-defined by the
-.Ic k
-operation.
-.Pp
-In the case of the division and modulus operator (~),
-the resultant quotient is pushed first followed by the remainder.
-This is a shorthand for the sequence:
-.Bd -literal -offset indent -compact
-x y / x y %
-.Ed
-The division and modulus operator is a non-portable extension.
-.It Ic a
-Pop the top value from the stack.
-If that value is a number, compute the integer part of the number modulo 256.
-If the result is zero, push an empty string.
-Otherwise push a one character string by interpreting the computed value
-as an
-.Tn ASCII
-character.
-.Pp
-If the top value is a string, push a string containing the first character
-of the original string.
-If the original string is empty, an empty string is pushed back.
-The
-.Ic a
-operator is a non-portable extension.
-.It Ic c
-All values on the stack are popped.
-.It Ic d
-The top value on the stack is duplicated.
-.It Ic e
-Equivalent to
-.Ic p ,
-except that the output is written to the standard error stream.
-.It Ic f
-All values on the stack are printed, separated by newlines.
-.It Ic G
-The top two numbers are popped from the stack and compared.
-A one is pushed if the top of the stack is equal to the second number
-on the stack.
-A zero is pushed otherwise.
-This is a non-portable extension.
-.It Ic I
-Pushes the input base on the top of the stack.
-.It Ic i
-The top value on the stack is popped and used as the
-base for further input.
-The initial input base is 10.
-.It Ic J
-Pop the top value from the stack.
-The recursion level is popped by that value and, following that,
-the input is skipped until the first occurrence of the
-.Ic M
-operator.
-The
-.Ic J
-operator is a non-portable extension, used by the
-.Xr bc 1
-command.
-.It Ic K
-The current scale factor is pushed onto the stack.
-.It Ic k
-The top of the stack is popped, and that value is used as
-a non-negative scale factor:
-the appropriate number of places
-are printed on output,
-and maintained during multiplication, division, and exponentiation.
-The interaction of scale factor,
-input base, and output base will be reasonable if all are changed
-together.
-.It Ic L Ns Ar x
-Register
-.Ar x
-is treated as a stack and its top value is popped onto the main stack.
-.It Ic l Ns Ar x
-The
-value in register
-.Ar x
-is pushed on the stack.
-The register
-.Ar x
-is not altered.
-Initially, all registers contain the value zero.
-.It Ic M
-Mark used by the
-.Ic J
-operator.
-The
-.Ic M
-operator is a non-portable extensions, used by the
-.Xr bc 1
-command.
-.It Ic N
-The top of the stack is replaced by one if the top of the stack
-is equal to zero.
-If the top of the stack is unequal to zero, it is replaced by zero.
-This is a non-portable extension.
-.It Ic n
-The top value on the stack is popped and printed without a newline.
-This is a non-portable extension.
-.It Ic O
-Pushes the output base on the top of the stack.
-.It Ic o
-The top value on the stack is popped and used as the
-base for further output.
-The initial output base is 10.
-.It Ic P
-The top of the stack is popped.
-If the top of the stack is a string, it is printed without a trailing newline.
-If the top of the stack is a number, it is interpreted as a
-base 256 number, and each digit of this base 256 number is printed as
-an
-.Tn ASCII
-character, without a trailing newline.
-.It Ic p
-The top value on the stack is printed with a trailing newline.
-The top value remains unchanged.
-.It Ic Q
-The top value on the stack is popped and the string execution level is popped
-by that value.
-.It Ic q
-Exits the program.
-If executing a string, the recursion level is
-popped by two.
-.It Ic R
-The top of the stack is removed (popped).
-This is a non-portable extension.
-.It Ic r
-The top two values on the stack are reversed (swapped).
-This is a non-portable extension.
-.It Ic S Ns Ar x
-Register
-.Ar x
-is treated as a stack.
-The top value of the main stack is popped and pushed on it.
-.It Ic s Ns Ar x
-The
-top of the stack is popped and stored into
-a register named
-.Ar x .
-.It Ic v
-Replaces the top element on the stack by its square root.
-The scale of the result is the maximum of the scale of the argument
-and the current value of scale.
-.It Ic X
-Replaces the number on the top of the stack with its scale factor.
-If the top of the stack is a string, replace it with the integer 0.
-.It Ic x
-Treats the top element of the stack as a character string
-and executes it as a string of
-.Nm
-commands.
-.It Ic Z
-Replaces the number on the top of the stack with its length.
-The length of a string is its number of characters.
-The length of a number is its number of digits, not counting the minus sign
-and decimal point.
-.It Ic z
-The stack level is pushed onto the stack.
-.It Cm \&[ Ns ... Ns Cm \&]
-Puts the bracketed
-.Tn ASCII
-string onto the top of the stack.
-If the string includes brackets, these must be properly balanced.
-The backslash character
-.Pq Sq \e
-may be used as an escape character, making it
-possible to include unbalanced brackets in strings.
-To include a backslash in a string, use a double backslash.
-.It Xo
-.Cm < Ns Va x
-.Cm > Ns Va x
-.Cm = Ns Va x
-.Cm !< Ns Va x
-.Cm !> Ns Va x
-.Cm != Ns Va x
-.Xc
-The top two elements of the stack are popped and compared.
-Register
-.Ar x
-is executed if they obey the stated
-relation.
-.It Xo
-.Cm < Ns Va x Ns e Ns Va y
-.Cm > Ns Va x Ns e Ns Va y
-.Cm = Ns Va x Ns e Ns Va y
-.Cm !< Ns Va x Ns e Ns Va y
-.Cm !> Ns Va x Ns e Ns Va y
-.Cm != Ns Va x Ns e Ns Va y
-.Xc
-These operations are variants of the comparison operations above.
-The first register name is followed by the letter
-.Sq e
-and another register name.
-Register
-.Ar x
-will be executed if the relation is true, and register
-.Ar y
-will be executed if the relation is false.
-This is a non-portable extension.
-.It Ic \&(
-The top two numbers are popped from the stack and compared.
-A one is pushed if the top of the stack is less than the second number
-on the stack.
-A zero is pushed otherwise.
-This is a non-portable extension.
-.It Ic {
-The top two numbers are popped from the stack and compared.
-A one is pushed if the top of stack is less than or equal to the
-second number on the stack.
-A zero is pushed otherwise.
-This is a non-portable extension.
-.It Ic \&!
-Interprets the rest of the line as a
-.Ux
-command.
-.It Ic \&?
-A line of input is taken from the input source (usually the terminal)
-and executed.
-.It Ic \&: Ns Ar r
-Pop two values from the stack.
-The second value on the stack is stored into the array
-.Ar r
-indexed by the top of stack.
-.It Ic \&; Ns Ar r
-Pop a value from the stack.
-The value is used as an index into register
-.Ar r .
-The value in this register is pushed onto the stack.
-.Pp
-Array elements initially have the value zero.
-Each level of a stacked register has its own array associated with
-it.
-The command sequence
-.Bd -literal -offset indent
-[first] 0:a [dummy] Sa [second] 0:a 0;a p La 0;a p
-.Ed
-.Pp
-will print
-.Bd -literal -offset indent
-second
-first
-.Ed
-.Pp
-since the string
-.Ql second
-is written in an array that is later popped, to reveal the array that
-stored
-.Ql first .
-.It Ic #
-Skip the rest of the line.
-This is a non-portable extension.
-.El
-.Ss Registers
-Registers have a single character name
-.Ar x ,
-where
-.Ar x
-may be any character, including space, tab or any other special character.
-If extended register mode is enabled using the
-.Fl x
-option and the register identifier
-.Ar x
-has the value 255, the next two characters are interpreted as a
-two-byte register index.
-The set of standard single character registers and the set of extended
-registers do not overlap.
-Extended register mode is a non-portable extension.
-.Sh EXAMPLES
-An example which prints the first ten values of
-.Ic n! :
-.Bd -literal -offset indent
-[la1+dsa*pla10>y]sy
-0sa1
-lyx
-.Ed
-.Pp
-Independent of the current input base, the command
-.Bd -literal -offset indent
-Ai
-.Ed
-.Pp
-will reset the input base to decimal 10.
-.Sh DIAGNOSTICS
-.Bl -diag
-.It %c (0%o) is unimplemented
-an undefined operation was called.
-.It stack empty
-for not enough elements on the stack to do what was asked.
-.It stack register '%c' (0%o) is empty
-for an
-.Ar L
-operation from a stack register that is empty.
-.It Runtime warning: non-zero scale in exponent
-for a fractional part of an exponent that is being ignored.
-.It divide by zero
-for trying to divide by zero.
-.It remainder by zero
-for trying to take a remainder by zero.
-.It square root of negative number
-for trying to take the square root of a negative number.
-.It index too big
-for an array index that is larger than 2048.
-.It negative index
-for a negative array index.
-.It "input base must be a number between 2 and 16"
-for trying to set an illegal input base.
-.It output base must be a number greater than 1
-for trying to set an illegal output base.
-.It scale must be a nonnegative number
-for trying to set a negative or zero scale.
-.It scale too large
-for trying to set a scale that is too large.
-A scale must be representable as a 32-bit unsigned number.
-.It Q command argument exceeded string execution depth
-for trying to pop the recursion level more than the current
-recursion level.
-.It Q command requires a number >= 1
-for trying to pop an illegal number of recursion levels.
-.It recursion too deep
-for too many levels of nested execution.
-.Pp
-The recursion level is increased by one if the
-.Ar x
-or
-.Ar ?\&
-operation or one of the compare operations resulting in the execution
-of register is executed.
-As an exception, the recursion level is not increased if the operation
-is executed as the last command of a string.
-For example, the commands
-.Bd -literal -offset indent
-[lax]sa
-1 lax
-.Ed
-.Pp
-will execute an endless loop, while the commands
-.Bd -literal -offset indent
-[laxp]sa
-1 lax
-.Ed
-.Pp
-will terminate because of a too deep recursion level.
-.It J command argument exceeded string execution depth
-for trying to pop the recursion level more than the current
-recursion level.
-.It mark not found
-for a failed scan for an occurrence of the
-.Ic M
-operator.
-.El
-.Sh SEE ALSO
-.Xr bc 1
-.Pp
-.An -nosplit
-.An L. L. Cherry ,
-.An R. Morris
-"DC \- An Interactive Desk Calculator"
-.Pa /usr/share/doc/usd/05.dc/ .
-.Sh STANDARDS
-The arithmetic operations of the
-.Nm
-utility are expected to conform to the definition listed in the
-.Xr bc 1
-section of the
-.St -p1003.2
-specification.
-.Sh HISTORY
-The
-.Nm
-command first appeared in
-.At v1 .
-A complete rewrite of the
-.Nm
-command using the
-.Xr bn 3
-big number routines first appeared in
-.Ox 3.5 .
-.Sh AUTHORS
-.An -nosplit
-The original version of the
-.Nm
-command was written by
-.An Robert Morris
-and
-.An Lorinda Cherry .
-The current version of the
-.Nm
-utility was written by
-.An Otto Moerbeek .
diff --git a/usr.bin/dc/dc.c b/usr.bin/dc/dc.c
deleted file mode 100644
--- a/usr.bin/dc/dc.c
+++ /dev/null
@@ -1,154 +0,0 @@
-/* $OpenBSD: dc.c,v 1.11 2009/10/27 23:59:37 deraadt Exp $ */
-
-/*
- * Copyright (c) 2003, Otto Moerbeek <otto@drijf.net>
- * Copyright (c) 2009, Gabor Kovesdan <gabor@FreeBSD.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/cdefs.h>
-#include <sys/stat.h>
-
-#include <capsicum_helpers.h>
-#include <ctype.h>
-#include <err.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <getopt.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "extern.h"
-
-#define DC_VER "1.3-FreeBSD"
-
-static void usage(void);
-
-extern char *__progname;
-
-static struct source src;
-
-static const struct option long_options[] =
-{
- {"expression", required_argument, NULL, 'e'},
- {"file", required_argument, NULL, 'f'},
- {"help", no_argument, NULL, 'h'},
- {"version", no_argument, NULL, 'V'}
-};
-
-static void
-usage(void)
-{
- fprintf(stderr, "usage: %s [-hVx] [-e expression] [file]\n",
- __progname);
- exit(1);
-}
-
-static void
-procfd(int fd, char *fname) {
- struct stat st;
- FILE *file;
-
- file = fdopen(fd, "r");
- if (file == NULL)
- err(1, "cannot open file %s", fname);
- if (fstat(fileno(file), &st) == -1)
- err(1, "%s", fname);
- if (S_ISDIR(st.st_mode)) {
- errno = EISDIR;
- err(1, "%s", fname);
- }
- src_setstream(&src, file);
- reset_bmachine(&src);
- eval();
- fclose(file);
-}
-
-int
-main(int argc, char *argv[])
-{
- int ch, fd;
- bool extended_regs = false, preproc_done = false;
-
- /* accept and ignore a single dash to be 4.4BSD dc(1) compatible */
- while ((ch = getopt_long(argc, argv, "e:f:hVx", long_options, NULL)) != -1) {
- switch (ch) {
- case 'e':
- if (!preproc_done)
- init_bmachine(extended_regs);
- src_setstring(&src, optarg);
- reset_bmachine(&src);
- eval();
- preproc_done = true;
- break;
- case 'f':
- if (!preproc_done)
- init_bmachine(extended_regs);
- fd = open(optarg, O_RDONLY);
- if (fd < 0)
- err(1, "cannot open file %s", optarg);
- procfd(fd, optarg);
- preproc_done = true;
- break;
- case 'x':
- extended_regs = true;
- break;
- case 'V':
- fprintf(stderr, "%s (BSD bc) %s\n", __progname, DC_VER);
- exit(0);
- break;
- case '-':
- break;
- case 'h':
- /* FALLTHROUGH */
- default:
- usage();
- }
- }
- argc -= optind;
- argv += optind;
-
- if (!preproc_done)
- init_bmachine(extended_regs);
- (void)setvbuf(stdout, NULL, _IOLBF, 0);
- (void)setvbuf(stderr, NULL, _IOLBF, 0);
-
- if (argc > 1)
- usage();
- if (argc == 1) {
- fd = open(argv[0], O_RDONLY);
- if (fd < 0)
- err(1, "cannot open file %s", argv[0]);
-
- if (caph_limit_stream(fd, CAPH_READ) < 0 ||
- caph_limit_stdio() < 0 ||
- caph_enter() < 0)
- err(1, "capsicum");
-
- procfd(fd, argv[0]);
- preproc_done = true;
- }
- if (preproc_done)
- return (0);
-
- if (caph_limit_stdio() < 0 || caph_enter())
- err(1, "capsicum");
- src_setstream(&src, stdin);
- reset_bmachine(&src);
- eval();
-
- return (0);
-}
diff --git a/usr.bin/dc/extern.h b/usr.bin/dc/extern.h
deleted file mode 100644
--- a/usr.bin/dc/extern.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* $OpenBSD: extern.h,v 1.4 2014/12/01 13:13:00 deraadt Exp $ */
-
-/*
- * Copyright (c) 2003, Otto Moerbeek <otto@drijf.net>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <stdbool.h>
-#include "bcode.h"
-
-
-/* inout.c */
-void src_setstream(struct source *, FILE *);
-void src_setstring(struct source *, char *);
-struct number *readnumber(struct source *, u_int, u_int);
-void printnumber(FILE *, const struct number *, u_int);
-char *read_string(struct source *);
-void print_value(FILE *, const struct value *, const char *, u_int);
-void print_ascii(FILE *, const struct number *);
-
-/* mem.c */
-struct number *new_number(void);
-void free_number(struct number *);
-struct number *div_number(struct number *, struct number *, u_int scale);
-struct number *dup_number(const struct number *);
-void *bmalloc(size_t);
-void *breallocarray(void *, size_t, size_t);
-char *bstrdup(const char *p);
-void bn_check(int);
-void bn_checkp(const void *);
-
-/* stack.c */
-void stack_init(struct stack *);
-void stack_free_value(struct value *);
-struct value *stack_dup_value(const struct value *, struct value *);
-void stack_swap(struct stack *);
-size_t stack_size(const struct stack *);
-void stack_dup(struct stack *);
-void stack_pushnumber(struct stack *, struct number *);
-void stack_pushstring(struct stack *stack, char *);
-void stack_push(struct stack *, struct value *);
-void stack_set_tos(struct stack *, struct value *);
-struct value *stack_tos(const struct stack *);
-struct value *stack_pop(struct stack *);
-struct number *stack_popnumber(struct stack *);
-char *stack_popstring(struct stack *);
-void stack_clear(struct stack *);
-void stack_print(FILE *, const struct stack *, const char *,
- u_int base);
-void frame_assign(struct stack *, size_t, const struct value *);
-struct value *frame_retrieve(const struct stack *, size_t);
-/* void frame_free(struct stack *); */
diff --git a/usr.bin/dc/inout.c b/usr.bin/dc/inout.c
deleted file mode 100644
--- a/usr.bin/dc/inout.c
+++ /dev/null
@@ -1,446 +0,0 @@
-/* $OpenBSD: inout.c,v 1.18 2014/12/01 13:13:00 deraadt Exp $ */
-
-/*
- * Copyright (c) 2003, Otto Moerbeek <otto@drijf.net>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/cdefs.h>
-#include <openssl/ssl.h>
-#include <ctype.h>
-#include <err.h>
-#include <string.h>
-
-#include "extern.h"
-
-#define MAX_CHARS_PER_LINE 68
-
-static int lastchar;
-static int charcount;
-
-static int src_getcharstream(struct source *);
-static void src_ungetcharstream(struct source *);
-static char *src_getlinestream(struct source *);
-static int src_getcharstring(struct source *);
-static void src_ungetcharstring(struct source *);
-static char *src_getlinestring(struct source *);
-static void src_freestring(struct source *);
-static void flushwrap(FILE *);
-static void putcharwrap(FILE *, int);
-static void printwrap(FILE *, const char *);
-static char *get_digit(u_long, int, u_int);
-
-static struct vtable stream_vtable = {
- src_getcharstream,
- src_ungetcharstream,
- src_getlinestream,
- NULL
-};
-
-static struct vtable string_vtable = {
- src_getcharstring,
- src_ungetcharstring,
- src_getlinestring,
- src_freestring
-};
-
-void
-src_setstream(struct source *src, FILE *stream)
-{
-
- src->u.stream = stream;
- src->vtable = &stream_vtable;
-}
-
-void
-src_setstring(struct source *src, char *p)
-{
-
- src->u.string.buf = (u_char *)p;
- src->u.string.pos = 0;
- src->vtable = &string_vtable;
-}
-
-static int
-src_getcharstream(struct source *src)
-{
-
- return (src->lastchar = getc(src->u.stream));
-}
-
-static void
-src_ungetcharstream(struct source *src)
-{
-
- ungetc(src->lastchar, src->u.stream);
-}
-
-static char *
-src_getlinestream(struct source *src)
-{
- char buf[BUFSIZ];
-
- if (fgets(buf, BUFSIZ, src->u.stream) == NULL)
- return (bstrdup(""));
- return bstrdup(buf);
-}
-
-static int
-src_getcharstring(struct source *src)
-{
-
- src->lastchar = src->u.string.buf[src->u.string.pos];
- if (src->lastchar == '\0')
- return (EOF);
- else {
- src->u.string.pos++;
- return (src->lastchar);
- }
-}
-
-static void
-src_ungetcharstring(struct source *src)
-{
-
- if (src->u.string.pos > 0) {
- if (src->lastchar != '\0')
- --src->u.string.pos;
- }
-}
-
-static char *
-src_getlinestring(struct source *src)
-{
- char buf[BUFSIZ];
- int i, ch;
-
- i = 0;
- while (i < BUFSIZ-1) {
- ch = src_getcharstring(src);
- if (ch == EOF)
- break;
- buf[i++] = ch;
- if (ch == '\n')
- break;
- }
- buf[i] = '\0';
- return (bstrdup(buf));
-}
-
-static void
-src_freestring(struct source *src)
-{
-
- free(src->u.string.buf);
-}
-
-static void
-flushwrap(FILE *f)
-{
-
- if (lastchar != -1)
- putc(lastchar, f);
-}
-
-static void
-putcharwrap(FILE *f, int ch)
-{
-
- if (charcount >= MAX_CHARS_PER_LINE) {
- charcount = 0;
- fputs("\\\n", f);
- }
- if (lastchar != -1) {
- charcount++;
- putc(lastchar, f);
- }
- lastchar = ch;
-}
-
-static void
-printwrap(FILE *f, const char *p)
-{
- char *q;
- char buf[12];
-
- q = buf;
- strlcpy(buf, p, sizeof(buf));
- while (*q)
- putcharwrap(f, *q++);
-}
-
-struct number *
-readnumber(struct source *src, u_int base, u_int bscale)
-{
- struct number *n;
- BN_ULONG v;
- int ch;
- u_int iscale = 0;
- bool dot = false, sign = false;
-
- n = new_number();
- BN_zero(n->number);
-
- while ((ch = (*src->vtable->readchar)(src)) != EOF) {
-
- if ('0' <= ch && ch <= '9')
- v = ch - '0';
- else if ('A' <= ch && ch <= 'F')
- v = ch - 'A' + 10;
- else if (ch == '_') {
- sign = true;
- continue;
- } else if (ch == '.') {
- if (dot)
- break;
- dot = true;
- continue;
- } else {
- (*src->vtable->unreadchar)(src);
- break;
- }
- if (dot)
- iscale++;
-
- bn_check(BN_mul_word(n->number, base));
- bn_check(BN_add_word(n->number, v));
- }
- if (base == 10) {
- n->scale = iscale;
- } else {
- /* At this point, the desired result is n->number / base^iscale*/
- struct number *quotient, *divisor, *_n;
- BIGNUM *base_n, *exponent;
- BN_CTX *ctx;
-
- ctx = BN_CTX_new();
- base_n = BN_new();
- exponent = BN_new();
- divisor = new_number();
- BN_zero(base_n);
- BN_zero(exponent);
-
- bn_check(BN_add_word(base_n, base));
- bn_check(BN_add_word(exponent, iscale));
- bn_check(BN_exp(divisor->number, base_n, exponent, ctx));
- divisor->scale = 0;
- quotient = div_number(n, divisor, bscale);
- _n = n;
- n = quotient;
-
- /*
- * Trim off trailing zeros to yield the smallest scale without
- * loss of accuracy
- */
- while ( n->scale > 0 &&
- BN_mod_word(n->number, 10) == 0) {
- normalize(n, n->scale - 1);
- }
-
- free_number(_n);
- free_number(divisor);
- BN_CTX_free(ctx);
- BN_free(base_n);
- BN_free(exponent);
- }
- if (sign)
- negate(n);
- return (n);
-}
-
-char *
-read_string(struct source *src)
-{
- char *p;
- int count, ch, i, new_sz, sz;
- bool escape;
-
- escape = false;
- count = 1;
- i = 0;
- sz = 15;
- p = bmalloc(sz + 1);
-
- while ((ch = (*src->vtable->readchar)(src)) != EOF) {
- if (!escape) {
- if (ch == '[')
- count++;
- else if (ch == ']')
- count--;
- if (count == 0)
- break;
- }
- if (ch == '\\' && !escape)
- escape = true;
- else {
- escape = false;
- if (i == sz) {
- new_sz = sz * 2;
- p = breallocarray(p, 1, new_sz + 1);
- sz = new_sz;
- }
- p[i++] = ch;
- }
- }
- p[i] = '\0';
- return (p);
-}
-
-static char *
-get_digit(u_long num, int digits, u_int base)
-{
- char *p;
-
- if (base <= 16) {
- p = bmalloc(2);
- p[0] = num >= 10 ? num + 'A' - 10 : num + '0';
- p[1] = '\0';
- } else {
- if (asprintf(&p, "%0*lu", digits, num) == -1)
- err(1, NULL);
- }
- return (p);
-}
-
-void
-printnumber(FILE *f, const struct number *b, u_int base)
-{
- struct number *fract_part, *int_part;
- struct stack stack;
- char *p;
- char buf[11];
- size_t sz;
- unsigned int i;
- int digits;
-
- charcount = 0;
- lastchar = -1;
- if (BN_is_zero(b->number))
- putcharwrap(f, '0');
-
- int_part = new_number();
- fract_part = new_number();
- fract_part->scale = b->scale;
-
- if (base <= 16)
- digits = 1;
- else {
- digits = snprintf(buf, sizeof(buf), "%u", base-1);
- }
- split_number(b, int_part->number, fract_part->number);
-
- i = 0;
- stack_init(&stack);
- while (!BN_is_zero(int_part->number)) {
- BN_ULONG rem = BN_div_word(int_part->number, base);
- stack_pushstring(&stack, get_digit(rem, digits, base));
- i++;
- }
- sz = i;
- if (BN_is_negative(b->number))
- putcharwrap(f, '-');
- for (i = 0; i < sz; i++) {
- p = stack_popstring(&stack);
- if (base > 16)
- putcharwrap(f, ' ');
- printwrap(f, p);
- free(p);
- }
- stack_clear(&stack);
- if (b->scale > 0) {
- struct number *num_base;
- BIGNUM *mult, *stop;
-
- putcharwrap(f, '.');
- num_base = new_number();
- bn_check(BN_set_word(num_base->number, base));
- mult = BN_new();
- bn_checkp(mult);
- bn_check(BN_one(mult));
- stop = BN_new();
- bn_checkp(stop);
- bn_check(BN_one(stop));
- scale_number(stop, b->scale);
-
- i = 0;
- while (BN_cmp(mult, stop) < 0) {
- u_long rem;
-
- if (i && base > 16)
- putcharwrap(f, ' ');
- i = 1;
-
- bmul_number(fract_part, fract_part, num_base,
- bmachine_scale());
- split_number(fract_part, int_part->number, NULL);
- rem = BN_get_word(int_part->number);
- p = get_digit(rem, digits, base);
- int_part->scale = 0;
- normalize(int_part, fract_part->scale);
- bn_check(BN_sub(fract_part->number, fract_part->number,
- int_part->number));
- printwrap(f, p);
- free(p);
- bn_check(BN_mul_word(mult, base));
- }
- free_number(num_base);
- BN_free(mult);
- BN_free(stop);
- }
- flushwrap(f);
- free_number(int_part);
- free_number(fract_part);
-}
-
-void
-print_value(FILE *f, const struct value *value, const char *prefix, u_int base)
-{
-
- fputs(prefix, f);
- switch (value->type) {
- case BCODE_NONE:
- if (value->array != NULL)
- fputs("<array>", f);
- break;
- case BCODE_NUMBER:
- printnumber(f, value->u.num, base);
- break;
- case BCODE_STRING:
- fputs(value->u.string, f);
- break;
- }
-}
-
-void
-print_ascii(FILE *f, const struct number *n)
-{
- BIGNUM *v;
- int ch, i, numbits;
-
- v = BN_dup(n->number);
- bn_checkp(v);
-
- if (BN_is_negative(v))
- BN_set_negative(v, 0);
-
- numbits = BN_num_bytes(v) * 8;
- while (numbits > 0) {
- ch = 0;
- for (i = 0; i < 8; i++)
- ch |= BN_is_bit_set(v, numbits-i-1) << (7 - i);
- putc(ch, f);
- numbits -= 8;
- }
- BN_free(v);
-}
diff --git a/usr.bin/dc/mem.c b/usr.bin/dc/mem.c
deleted file mode 100644
--- a/usr.bin/dc/mem.c
+++ /dev/null
@@ -1,140 +0,0 @@
-/* $OpenBSD: mem.c,v 1.6 2014/12/01 13:13:00 deraadt Exp $ */
-
-/*
- * Copyright (c) 2003, Otto Moerbeek <otto@drijf.net>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/cdefs.h>
-#include <openssl/err.h>
-
-#include <err.h>
-#include <limits.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "extern.h"
-
-struct number *
-new_number(void)
-{
- struct number *n;
-
- n = bmalloc(sizeof(*n));
- n->scale = 0;
- n->number = BN_new();
- if (n->number == NULL)
- err(1, NULL);
- return (n);
-}
-
-void
-free_number(struct number *n)
-{
-
- BN_free(n->number);
- free(n);
-}
-
-/*
- * Divide dividend by divisor, returning the result. Retain bscale places of
- * precision.
- * The result must be freed when no longer in use
- */
-struct number *
-div_number(struct number *dividend, struct number *divisor, u_int bscale)
-{
- struct number *quotient;
- BN_CTX *ctx;
- u_int scale;
-
- quotient = new_number();
- quotient->scale = bscale;
- scale = max(divisor->scale, dividend->scale);
-
- if (BN_is_zero(divisor->number))
- warnx("divide by zero");
- else {
- normalize(divisor, scale);
- normalize(dividend, scale + quotient->scale);
-
- ctx = BN_CTX_new();
- bn_checkp(ctx);
- bn_check(BN_div(quotient->number, NULL, dividend->number,
- divisor->number, ctx));
- BN_CTX_free(ctx);
- }
- return (quotient);
-}
-
-struct number *
-dup_number(const struct number *a)
-{
- struct number *n;
-
- n = bmalloc(sizeof(*n));
- n->scale = a->scale;
- n->number = BN_dup(a->number);
- bn_checkp(n->number);
- return (n);
-}
-
-void *
-bmalloc(size_t sz)
-{
- void *p;
-
- p = malloc(sz);
- if (p == NULL)
- err(1, NULL);
- return (p);
-}
-
-void *
-breallocarray(void *p, size_t nmemb, size_t size)
-{
- void *q;
-
- q = reallocarray(p, nmemb, size);
- if (q == NULL)
- err(1, NULL);
- return (q);
-}
-
-char *
-bstrdup(const char *p)
-{
- char *q;
-
- q = strdup(p);
- if (q == NULL)
- err(1, NULL);
- return (q);
-}
-
-void
-bn_check(int x) \
-{
-
- if (x == 0)
- err(1, "big number failure %lx", ERR_get_error());
-}
-
-void
-bn_checkp(const void *p) \
-{
-
- if (p == NULL)
- err(1, "allocation failure %lx", ERR_get_error());
-}
diff --git a/usr.bin/dc/stack.c b/usr.bin/dc/stack.c
deleted file mode 100644
--- a/usr.bin/dc/stack.c
+++ /dev/null
@@ -1,370 +0,0 @@
-/* $OpenBSD: stack.c,v 1.13 2014/12/01 13:13:00 deraadt Exp $ */
-
-/*
- * Copyright (c) 2003, Otto Moerbeek <otto@drijf.net>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/cdefs.h>
-#include <err.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "extern.h"
-
-static __inline bool stack_empty(const struct stack *);
-static void stack_grow(struct stack *);
-static struct array *array_new(void);
-static __inline void array_free(struct array *);
-static struct array *array_dup(const struct array *);
-static __inline void array_grow(struct array *, size_t);
-static __inline void array_assign(struct array *, size_t, const struct value *);
-static __inline struct value *array_retrieve(const struct array *, size_t);
-
-void
-stack_init(struct stack *stack)
-{
-
- stack->size = 0;
- stack->sp = -1;
- stack->stack = NULL;
-}
-
-static __inline bool
-stack_empty(const struct stack *stack)
-{
- bool empty = stack->sp == -1;
-
- if (empty)
- warnx("stack empty");
- return empty;
-}
-
-/* Clear number or string, but leave value itself */
-void
-stack_free_value(struct value *v)
-{
-
- switch (v->type) {
- case BCODE_NONE:
- break;
- case BCODE_NUMBER:
- free_number(v->u.num);
- break;
- case BCODE_STRING:
- free(v->u.string);
- break;
- }
- array_free(v->array);
- v->array = NULL;
-}
-
-/* Copy number or string content into already allocated target */
-struct value *
-stack_dup_value(const struct value *a, struct value *copy)
-{
-
- copy->type = a->type;
-
- switch (a->type) {
- case BCODE_NONE:
- break;
- case BCODE_NUMBER:
- copy->u.num = dup_number(a->u.num);
- break;
- case BCODE_STRING:
- copy->u.string = strdup(a->u.string);
- if (copy->u.string == NULL)
- err(1, NULL);
- break;
- }
-
- copy->array = a->array == NULL ? NULL : array_dup(a->array);
-
- return (copy);
-}
-
-size_t
-stack_size(const struct stack *stack)
-{
-
- return (stack->sp + 1);
-}
-
-void
-stack_dup(struct stack *stack)
-{
- struct value *value;
- struct value copy;
-
- value = stack_tos(stack);
- if (value == NULL) {
- warnx("stack empty");
- return;
- }
- stack_push(stack, stack_dup_value(value, &copy));
-}
-
-void
-stack_swap(struct stack *stack)
-{
- struct value copy;
-
- if (stack->sp < 1) {
- warnx("stack empty");
- return;
- }
- copy = stack->stack[stack->sp];
- stack->stack[stack->sp] = stack->stack[stack->sp-1];
- stack->stack[stack->sp-1] = copy;
-}
-
-static void
-stack_grow(struct stack *stack)
-{
- size_t new_size;
-
- if (++stack->sp == stack->size) {
- new_size = stack->size * 2 + 1;
- stack->stack = breallocarray(stack->stack,
- new_size, sizeof(*stack->stack));
- stack->size = new_size;
- }
-}
-
-void
-stack_pushnumber(struct stack *stack, struct number *b)
-{
-
- stack_grow(stack);
- stack->stack[stack->sp].type = BCODE_NUMBER;
- stack->stack[stack->sp].u.num = b;
- stack->stack[stack->sp].array = NULL;
-}
-
-void
-stack_pushstring(struct stack *stack, char *string)
-{
-
- stack_grow(stack);
- stack->stack[stack->sp].type = BCODE_STRING;
- stack->stack[stack->sp].u.string = string;
- stack->stack[stack->sp].array = NULL;
-}
-
-void
-stack_push(struct stack *stack, struct value *v)
-{
-
- switch (v->type) {
- case BCODE_NONE:
- stack_grow(stack);
- stack->stack[stack->sp].type = BCODE_NONE;
- break;
- case BCODE_NUMBER:
- stack_pushnumber(stack, v->u.num);
- break;
- case BCODE_STRING:
- stack_pushstring(stack, v->u.string);
- break;
- }
- stack->stack[stack->sp].array = v->array == NULL ?
- NULL : array_dup(v->array);
-}
-
-struct value *
-stack_tos(const struct stack *stack)
-{
-
- if (stack->sp == -1)
- return (NULL);
- return &stack->stack[stack->sp];
-}
-
-void
-stack_set_tos(struct stack *stack, struct value *v)
-{
-
- if (stack->sp == -1)
- stack_push(stack, v);
- else {
- stack_free_value(&stack->stack[stack->sp]);
- stack->stack[stack->sp] = *v;
- stack->stack[stack->sp].array = v->array == NULL ?
- NULL : array_dup(v->array);
- }
-}
-
-struct value *
-stack_pop(struct stack *stack)
-{
-
- if (stack_empty(stack))
- return (NULL);
- return &stack->stack[stack->sp--];
-}
-
-struct number *
-stack_popnumber(struct stack *stack)
-{
-
- if (stack_empty(stack))
- return (NULL);
- array_free(stack->stack[stack->sp].array);
- stack->stack[stack->sp].array = NULL;
- if (stack->stack[stack->sp].type != BCODE_NUMBER) {
- warnx("not a number"); /* XXX remove */
- return (NULL);
- }
- return stack->stack[stack->sp--].u.num;
-}
-
-char *
-stack_popstring(struct stack *stack)
-{
-
- if (stack_empty(stack))
- return (NULL);
- array_free(stack->stack[stack->sp].array);
- stack->stack[stack->sp].array = NULL;
- if (stack->stack[stack->sp].type != BCODE_STRING) {
- warnx("not a string"); /* XXX remove */
- return (NULL);
- }
- return stack->stack[stack->sp--].u.string;
-}
-
-void
-stack_clear(struct stack *stack)
-{
-
- while (stack->sp >= 0)
- stack_free_value(&stack->stack[stack->sp--]);
- free(stack->stack);
- stack_init(stack);
-}
-
-void
-stack_print(FILE *f, const struct stack *stack, const char *prefix, u_int base)
-{
- ssize_t i;
-
- for (i = stack->sp; i >= 0; i--) {
- print_value(f, &stack->stack[i], prefix, base);
- putc('\n', f);
- }
-}
-
-
-static struct array *
-array_new(void)
-{
- struct array *a;
-
- a = bmalloc(sizeof(*a));
- a->data = NULL;
- a->size = 0;
- return a;
-}
-
-static __inline void
-array_free(struct array *a)
-{
- size_t i;
-
- if (a == NULL)
- return;
- for (i = 0; i < a->size; i++)
- stack_free_value(&a->data[i]);
- free(a->data);
- free(a);
-}
-
-static struct array *
-array_dup(const struct array *a)
-{
- struct array *n;
- size_t i;
-
- if (a == NULL)
- return (NULL);
- n = array_new();
- array_grow(n, a->size);
- for (i = 0; i < a->size; i++)
- stack_dup_value(&a->data[i], &n->data[i]);
- return (n);
-}
-
-static __inline void
-array_grow(struct array *array, size_t newsize)
-{
- size_t i;
-
- array->data = breallocarray(array->data, newsize, sizeof(*array->data));
- for (i = array->size; i < newsize; i++) {
- array->data[i].type = BCODE_NONE;
- array->data[i].array = NULL;
- }
- array->size = newsize;
-}
-
-static __inline void
-array_assign(struct array *array, size_t i, const struct value *v)
-{
-
- if (i >= array->size)
- array_grow(array, i + 1);
- stack_free_value(&array->data[i]);
- array->data[i] = *v;
-}
-
-static __inline struct value *
-array_retrieve(const struct array *array, size_t i)
-{
-
- if (i >= array->size)
- return (NULL);
- return &array->data[i];
-}
-
-void
-frame_assign(struct stack *stack, size_t i, const struct value *v)
-{
- struct array *a;
- struct value n;
-
- if (stack->sp == -1) {
- n.type = BCODE_NONE;
- n.array = NULL;
- stack_push(stack, &n);
- }
-
- a = stack->stack[stack->sp].array;
- if (a == NULL)
- a = stack->stack[stack->sp].array = array_new();
- array_assign(a, i, v);
-}
-
-struct value *
-frame_retrieve(const struct stack *stack, size_t i)
-{
- struct array *a;
-
- if (stack->sp == -1)
- return (NULL);
- a = stack->stack[stack->sp].array;
- if (a == NULL)
- a = stack->stack[stack->sp].array = array_new();
- return array_retrieve(a, i);
-}
diff --git a/usr.bin/dc/tests/Makefile b/usr.bin/dc/tests/Makefile
deleted file mode 100644
--- a/usr.bin/dc/tests/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-PACKAGE= tests
-
-ATF_TESTS_SH= inout
-ATF_TESTS_SH+= bcode
-
-.include <bsd.test.mk>
diff --git a/usr.bin/dc/tests/bcode.sh b/usr.bin/dc/tests/bcode.sh
deleted file mode 100755
--- a/usr.bin/dc/tests/bcode.sh
+++ /dev/null
@@ -1,142 +0,0 @@
-# SPDX-License-Identifier: BSD-2-Clause
-#
-# Copyright (c) 2017 Alan Somers
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-# 1. Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# 2. Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-# SUCH DAMAGE.
-#
-
-atf_test_case bmod
-bmod_head()
-{
- atf_set "descr" "Tests the remainder % operator"
-}
-bmod_body()
-{
- cat > input.dc << EOF
-0 3 % p # basic usage
-1 3 % p
-2 3 % p
-3 3 % p
-4 3 % p
-_1 3 % p # negative dividends work like a remainder, not a modulo
-1 _3 % p # negative divisors use the divisor's absolute value
-1k # fractional remainders
-5 3 % p
-6 5 % p
-5.4 3 % p
-_.1 3 % p
-1.1 _3 % p
-1 .3 % p
-EOF
- dc input.dc > output.txt
- cat > expect.txt << EOF
-0
-1
-2
-0
-1
--1
-1
-2
-1
-2.4
--.1
-1.1
-.1
-EOF
- atf_check cmp expect.txt output.txt
-}
-
-atf_test_case bmod_by_zero
-bmod_by_zero_head()
-{
- atf_set "descr" "remaindering by zero should print a warning"
-}
-bmod_by_zero_body()
-{
- atf_check -e match:"remainder by zero" dc -e '1 0 %'
-}
-
-atf_test_case bdivmod
-bdivmod_head()
-{
- atf_set "descr" "Tests the divide and modulo ~ operator"
-}
-bdivmod_body()
-{
- cat > input.dc << EOF
-0 3 ~ n32Pp # basic usage
-1 3 ~ n32Pp
-2 3 ~ n32Pp
-3 3 ~ n32Pp
-4 3 ~ n32Pp
-_1 3 ~ n32Pp # negative dividends work like a remainder, not a modulo
-_4 3 ~ n32Pp # sign of quotient and divisor must agree
-1 _3 ~ n32Pp # negative divisors use the divisor's absolute value
-1k # fractional remainders
-5 3 ~ n32Pp
-6 5 ~ n32Pp
-5.4 3 ~ n32Pp
-_.1 3 ~ n32Pp
-1.1 _3 ~ n32Pp
-1 .3 ~ n32Pp
-4k
-.01 .003 ~ n32Pp # divmod quotient always has scale=0
-EOF
- dc input.dc > output.txt
- cat > expect.txt << EOF
-0 0
-1 0
-2 0
-0 1
-1 1
--1 0
--1 -1
-1 0
-2 1.6
-1 1.2
-2.4 1.8
--.1 0.0
-1.1 -.3
-.1 3.3
-.001 3.3333
-EOF
- atf_check cmp expect.txt output.txt
-}
-
-atf_test_case bdivmod_by_zero
-bdivmod_by_zero_head()
-{
- atf_set "descr" "divmodding by zero should print a warning"
-}
-bdivmod_by_zero_body()
-{
- atf_check -e match:"divide by zero" dc -e '1 0 ~'
-}
-
-atf_init_test_cases()
-{
- atf_add_test_case bmod
- atf_add_test_case bmod_by_zero
- atf_add_test_case bdivmod
- atf_add_test_case bdivmod_by_zero
-}
diff --git a/usr.bin/dc/tests/inout.sh b/usr.bin/dc/tests/inout.sh
deleted file mode 100755
--- a/usr.bin/dc/tests/inout.sh
+++ /dev/null
@@ -1,100 +0,0 @@
-# SPDX-License-Identifier: BSD-2-Clause
-#
-# Copyright (c) 2017 Alan Somers
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-# 1. Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# 2. Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-# SUCH DAMAGE.
-#
-
-atf_test_case base16_input
-base16_input_head()
-{
- atf_set "descr" "Input hexadecimal numbers"
-}
-base16_input_body()
-{
- cat > input.dc << EOF
-4k # set scale to 4 decimal places
-16i # switch to base 16
-0 p
-10 p
-1 p
-1. p # The '.' should have no effect
-1.0 p # Unlike with decimal, should not change the result's scale
-.8 p # Can input fractions
-# Check that we can input fractions that need more scale in base 10 than in 16
-# See PR 206230
-.1 p
-.10 p # Result should be .0625, with scale=4
-.01 p # Result should be truncated to scale=4
-8k # Increase scale to 8 places
-.01 p # Result should be exact again
-0.1 p # Leading zeros are ignored
-00.1 p # Leading zeros are ignored
-EOF
- dc input.dc > output.txt
- cat > expect.txt << EOF
-0
-16
-1
-1
-1
-.5
-.0625
-.0625
-.0039
-.00390625
-.0625
-.0625
-EOF
- atf_check cmp expect.txt output.txt
-}
-
-atf_test_case base3_input
-base3_input_head()
-{
- atf_set "descr" "Input ternary numbers"
-}
-base3_input_body()
-{
- cat > input.dc << EOF
-4k # 4 digits of precision
-3i # Base 3 input
-0 p
-1 p
-10 p
-.1 p # Repeating fractions get truncated
-EOF
-dc input.dc > output.txt
-cat > expect.txt << EOF
-0
-1
-3
-.3333
-EOF
- atf_check cmp expect.txt output.txt
-}
-
-atf_init_test_cases()
-{
- atf_add_test_case base16_input
- atf_add_test_case base3_input
-}

File Metadata

Mime Type
text/plain
Expires
Thu, Feb 6, 6:50 PM (20 h, 48 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16499325
Default Alt Text
D46876.diff (141 KB)

Event Timeline