commit 56b93ad91becdb1370523190f0e1645f8286a524
parent 0850438f93155902b6a062c94786fa99e4269715
Author: Roberto E. Vargas Caballero <k0ga@shike2.net>
Date: Sun, 23 Nov 2025 11:42:10 +0100
bc: Add support for the bc library
This library was imported from the BSD 4.4 source code but it is a
portion of code with ownership from AT&T and it can be used under
the Caldera open source license.
Diffstat:
| M | Makefile | | | 1 | + |
| A | bc.library | | | 233 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| M | bc.y | | | 37 | +++++++++++++++++++++++++++++++++++++ |
3 files changed, 271 insertions(+), 0 deletions(-)
diff --git a/Makefile b/Makefile
@@ -5,6 +5,7 @@ include config.mk
.SUFFIXES: .y .o .c
CPPFLAGS =\
+ -DPREFIX=\"$(PREFIX)\" \
-D_DEFAULT_SOURCE \
-D_NETBSD_SOURCE \
-D_BSD_SOURCE \
diff --git a/bc.library b/bc.library
@@ -0,0 +1,233 @@
+/*
+ * 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.
+ */
+
+/*
+ *
+ * @(#)bc.library 8.1 (Berkeley) 6/6/93
+ */
+
+scale = 20
+define e(x){
+ auto a, b, c, d, e, g, t, w, y
+
+ t = scale
+ scale = t + .434*x + 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
+ 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
+ if(x <=0) return(1-10^scale)
+ t = scale
+
+ f=1
+ scale = scale + scale(x) - length(x) + 1
+ s=scale
+ while(x > 2){
+ s = s + (length(x)-scale(x))/2 + 1
+ if(s>0) scale = s
+ x = sqrt(x)
+ f=f*2
+ }
+ while(x < .5){
+ s = s + (length(x)-scale(x))/2 + 1
+ if(s>0) scale = s
+ x = sqrt(x)
+ f=f*2
+ }
+
+ scale = t + length(f) - scale(f) + 1
+ u = (x-1)/(x+1)
+
+ scale = scale + 1.1*length(t) - 1.1*scale(t)
+ s = u*u
+ 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
+ return(u*c/d)
+ }
+ e=g
+ }
+}
+
+define s(x){
+ auto a, b, c, s, t, y, p, n, i
+ 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; return(s/1)}
+ s = s+c
+ }
+}
+
+define c(x){
+ auto t
+ t = scale
+ scale = scale+1
+ x = s(x+2*a(1))
+ scale = t
+ return(x/1)
+}
+
+define a(x){
+ auto a, b, c, d, e, f, g, s, t
+ if(x==0) return(0)
+ if(x==1) {
+ if(scale<52) {
+return(.7853981633974483096156608458198757210492923498437764/1)
+ }
+ }
+ 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){
+ scale = t
+ return(x*c/d)
+ }
+ e=g
+ }
+}
+
+define j(n,x){
+auto a,b,c,d,e,g,i,s,k,t
+
+ 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){
+ scale = t
+ return(g/1)
+ }
+ e=g
+ }
+}
diff --git a/bc.y b/bc.y
@@ -1,4 +1,5 @@
%{
+#include <libgen.h>
#include <unistd.h>
#include <ctype.h>
@@ -693,6 +694,40 @@ bc(char *fname)
for (init(); run(); init())
;
}
+static void
+loadlib(void)
+{
+ int r;
+ size_t len;
+ char bin[FILENAME_MAX], fname[FILENAME_MAX];
+ static char bclib[] = "bc.library";
+
+ /*
+ * try first to load the library from the same directory than
+ * the executable, because that can makes easier the tests
+ * because it does not require to install to test the last version
+ */
+ len = strlen(argv0);
+ if (len >= FILENAME_MAX)
+ goto share;
+ memcpy(bin, argv0, len + 1);
+
+ r = snprintf(fname, sizeof(fname), "%s/%s", dirname(bin), bclib);
+ if (r < 0 || r >= sizeof(fname))
+ goto share;
+
+ if (access(fname, F_OK) < 0)
+ goto share;
+
+ bc(fname);
+ return;
+
+share:
+ r = snprintf(fname, sizeof(fname), "%s/share/misc/%s", PREFIX, bclib);
+ if (r < 0 || r >= sizeof(fname))
+ eprintf("bc: invalid path name for bc.library\n");
+ bc(fname);
+}
static void
usage(void)
@@ -723,6 +758,8 @@ main(int argc, char *argv[])
if (!cflag)
spawn();
+ if (lflag)
+ loadlib();
if (*argv == NULL) {
bc(NULL);