bc: Add support for the bc library - sbase - suckless unix tools
 (HTM) git clone git://git.suckless.org/sbase
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 56b93ad91becdb1370523190f0e1645f8286a524
 (DIR) parent 0850438f93155902b6a062c94786fa99e4269715
 (HTM) 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(-)
       ---
 (DIR) 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 \
 (DIR) 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
       +        }
       +}
 (DIR) 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);