Giter Site home page Giter Site logo

lcn2 / calc Goto Github PK

View Code? Open in Web Editor NEW
331.0 14.0 52.0 4.12 MB

C-style arbitrary precision calculator

Home Page: http://www.isthe.com/chongo/tech/comp/calc/index.html

License: Other

Makefile 11.67% C 86.26% Roff 1.02% Awk 0.09% sed 0.04% Shell 0.93%
calc calculator mathematical-functions complex-numbers fraction exponentiation calc-language multiprecision bignum math

calc's Introduction

TL;DR Try calc

TL;DR Install calc

misc linux: sudo yum install calc
on Debian:  sudo apt install calc
on RHEL:    sudo dnf install calc
on Ubuntu:  sudo apt install calc
via Termux: apt install calc
via src:    sudo make clobber all chk instsll

TL;DR Run calc

misc shell:   calc
via bash:     calc
via misc app: launch calc via Termux
via zsh:      calc

What is calc?

Calc is an interactive calculator which provides for easy large numeric calculations, but which also can be easily programmed for difficult or long calculations. It can accept a command line argument, in which case it executes that single command and exits. Otherwise, it enters interactive mode. In this mode, it accepts commands one at a time, processes them, and displays the answers. In the simplest case, commands are simply expressions which are evaluated. For example, the following line can be input:

3 * (4 + 1)

and the calculator will print:

15

Calc has the usual collection of arithmetic operators +, -, /, * as well as ^ (exponentiation), % (modulus) and // (integer divide). For example:

3 * 19^43 - 1

will produce:

29075426613099201338473141505176993450849249622191102976

Notice that calc values can be very large. For example:

2^23209-1

will print:

402874115778988778181873329071 ... many digits ... 3779264511

The special '.' symbol (called dot), represents the result of the last command expression, if any. This is of great use when a series of partial results are calculated, or when the output mode is changed and the last result needs to be redisplayed. For example, the above result can be modified by typing:

. % (2^127-1)

and the calculator will print:

47385033654019111249345128555354223304

For more complex calculations, variables can be used to save the intermediate results. For example, the result of adding 7 to the previous result can be saved by typing:

curds = 15
whey = 7 + 2*curds

Functions can be used in expressions. There are a great number of pre-defined functions. For example, the following will calculate the factorial of the value of 'whey':

fact(whey)

and the calculator prints:

13763753091226345046315979581580902400000000

The calculator also knows about complex numbers, so that typing:

(2+3i) * (4-3i)
cos(.)

will print:

17+6i
-55.50474777265624667147+193.9265235748927986537i

The calculator can calculate transcendental functions, and accept and display numbers in real or exponential format. For example, typing:

config("display", 70),
epsilon(1e-70),
sin(1)

prints:

0.8414709848078965066525023216302989996225630607983710656727517099919104

Calc can output values in terms of fractions, octal or hexadecimal. For example:

config("mode", "fraction"),
(17/19)^23
print
base(16),
(19/17)^29
print
log(79.3i)

will print:

19967568900859523802559065713/257829627945307727248226067259

0x9201e65bdbb801eaf403f657efcf863/0x5cd2e2a01291ffd73bee6aa7dcf7d1

0x17b5164ac24ee836bf/0xc7b7a8e3ef5fcf752+0x883eaf5adadd26be3/0xc7b7a8e3ef5fcf752i

All numbers are represented as fractions with arbitrarily large numerators and denominators which are always reduced to lowest terms. Real or exponential format numbers can be input and are converted to the equivalent fraction. Hex, binary, or octal numbers can be input by using numbers with leading '0x', '0b' or '0' characters. Complex numbers can be input using a trailing 'i', as in '2+3i'. Strings and characters are input by using single or double quotes.

Commands are statements in a C-like language, where each input line is treated as the body of a procedure. Thus the command line can contain variable declarations, expressions, labels, conditional tests, and loops. Assignments to any variable name will automatically define that name as a global variable. The other important thing to know is that all non-assignment expressions which are evaluated are automatically printed. Thus, you can evaluate an expression's value by simply typing it in.

Many useful built-in mathematical functions are available. Use the:

help builtin

command to list them.

You can also define your own functions by using the 'define' keyword, followed by a function declaration very similar to C.

define f2(n)
{
	local ans;

	ans = 1;
	while (n > 1)
		ans *= (n -= 2);
	return ans;
}

Thus the input:

f2(79)

will produce:

1009847364737869270905302433221592504062302663202724609375

Functions which only need to return a simple expression can be defined using an equals sign, as in the example:

define sc(a,b) = a^3 + b^3

Thus the input:

sc(31, 61)

will produce:

256772

Variables in functions can be defined as either 'global', 'local', or 'static'. Global variables are common to all functions and the command line, whereas local variables are unique to each function level, and are destroyed when the function returns. Static variables are scoped within single input files, or within functions, and are never destroyed. Variables are not typed at definition time, but dynamically change as they are used.

For more information about the calc language and features, try:

help overview

Calc has a help command that will produce information about every builtin function, command as well as a number of other aspects of calc usage. Try the command:

help help

for and overview of the help system. The command:

help builtin

provides information on built-in mathematical functions, whereas:

help asinh

will provides information a specific function. The following help files:

help command
help define
help operator
help statement
help variable

provide a good overview of the calc language. If you are familiar with C, you should also try:

help unexpected

It contains information about differences between C and calc that may surprise C programmers.

calc's People

Contributors

10110111 avatar ashamedbit avatar atsampson avatar bambooleafz avatar coreysciuto-toast avatar fruityloops1 avatar fweimer-rh avatar guilhermgonzaga avatar heitzmann avatar jcul avatar john-peterson avatar lcn2 avatar leoongithub avatar marcodegio avatar planet36 avatar thegithubr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

calc's Issues

Bug: calc doesn't compile with musl libc on gentoo

Calc bug report template version: 1.2 2022-02-24

Describe the bug
I tried to install calc on my gentoo. Build failed, I notice a long-standing bug:
https://bugs.gentoo.org/717694
So I downloaded the latest calc from master and tried to compile. It failed the same way.

To Reproduce
Download the latest git variant of calc (3e4391e), make.
There is an error:

➜  calc git:(25dcd8c) ✗ make clean debug 2>&1 > debug.log
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-gentoo-linux-musl/11.3.0/lto-wrapper
Target: x86_64-gentoo-linux-musl
Configured with: /var/tmp/portage/sys-devel/gcc-11.3.0/work/gcc-11.3.0/configure --host=x86_64-gentoo-linux-musl --build=x86_64-gentoo-linux-musl --prefix=/usr --bindir=/usr/x86_64-gentoo-linux-musl/gcc-bin/11.3.0 --includedir=/usr/lib/gcc/x86_64-gentoo-linux-musl/11.3.0/include --datadir=/usr/share/gcc-data/x86_64-gentoo-linux-musl/11.3.0 --mandir=/usr/share/gcc-data/x86_64-gentoo-linux-musl/11.3.0/man --infodir=/usr/share/gcc-data/x86_64-gentoo-linux-musl/11.3.0/info --with-gxx-include-dir=/usr/lib/gcc/x86_64-gentoo-linux-musl/11.3.0/include/g++-v11 --with-python-dir=/share/gcc-data/x86_64-gentoo-linux-musl/11.3.0/python --enable-languages=c,c++,fortran --enable-obsolete --enable-secureplt --disable-werror --with-system-zlib --disable-nls --disable-libunwind-exceptions --enable-checking=release --with-bugurl=https://bugs.gentoo.org/ --with-pkgversion='Gentoo 11.3.0 p7' --disable-esp --enable-libstdcxx-time --disable-libstdcxx-pch --enable-shared --enable-threads=posix --enable-__cxa_atexit --disable-multilib --with-multilib-list=m64 --disable-fixed-point --enable-targets=all --enable-libgomp --disable-libssp --disable-libada --disable-cet --disable-systemtap --disable-valgrind-annotations --disable-vtable-verify --disable-libvtv --without-zstd --enable-lto --without-isl --disable-libsanitizer --enable-default-pie --enable-default-ssp
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 11.3.0 (Gentoo 11.3.0 p7)
In file included from qmath.h:32,
                 from cmath.h:32,
                 from byteswap.c:28:
byteswap.c: In function 'swap_HALF_in_ZVALUE':
zmath.h:581:36: warning: '*dest.v' may be used uninitialized [-Wmaybe-uninitialized]
  581 | #define zcopyval(z1,z2) memcpy((z2).v, (z1).v, (z1).len * sizeof(HALF))
      |                                ~~~~^~
byteswap.c:543:36: note: in expansion of macro 'zcopyval'
  543 |                 dest->v = (HALF *) zcopyval(*src, *dest);
      |                                    ^~~~~~~~
In file included from file.c:44:
file.c: In function 'filepos2z':
fposval.h:16:54: error: 'FPOS_POS_LEN' undeclared (first use in this function); did you mean 'FILEPOS_LEN'?
   16 |         memcpy((void *)(dest), (void *)(src), sizeof(FPOS_POS_LEN))
      |                                                      ^~~~~~~~~~~~
file.c:1391:9: note: in expansion of macro 'SWAP_HALF_IN_FILEPOS'
 1391 |         SWAP_HALF_IN_FILEPOS(ret.v, &pos);
      |         ^~~~~~~~~~~~~~~~~~~~
fposval.h:16:54: note: each undeclared identifier is reported only once for each function it appears in
   16 |         memcpy((void *)(dest), (void *)(src), sizeof(FPOS_POS_LEN))
      |                                                      ^~~~~~~~~~~~
file.c:1391:9: note: in expansion of macro 'SWAP_HALF_IN_FILEPOS'
 1391 |         SWAP_HALF_IN_FILEPOS(ret.v, &pos);
      |         ^~~~~~~~~~~~~~~~~~~~
file.c: In function 'z2filepos':
file.c:1462:67: error: expected ')' before ';' token
 1462 |                 memcpy(&tmp, zpos.v, MIN(sizeof(tmp), FILEPOS_LEN);
      |                       ~                                           ^
file.c:1462:68: error: expected ';' before '}' token
 1462 |                 memcpy(&tmp, zpos.v, MIN(sizeof(tmp), FILEPOS_LEN);
      |                                                                    ^
      |                                                                    ;
 1463 |         } else {
      |         ~
file.c:60:24: warning: comparison of integer expressions of different signedness: 'long unsigned int' and 'int' [-Wsign-compare]
   60 | #define MIN(a,b) (((a) <= (b)) ? (a) : (b))
      |                        ^~
file.c:1466:38: note: in expansion of macro 'MIN'
 1466 |                 memcpy(&tmp, zpos.v, MIN(sizeof(tmp),
      |                                      ^~~
file.c:60:40: warning: operand of '?:' changes signedness from 'int' to 'long unsigned int' due to unsignedness of other operand [-Wsign-compare]
   60 | #define MIN(a,b) (((a) <= (b)) ? (a) : (b))
      |                                        ^~~
file.c:1466:38: note: in expansion of macro 'MIN'
 1466 |                 memcpy(&tmp, zpos.v, MIN(sizeof(tmp),
      |                                      ^~~
In file included from file.c:44:
fposval.h:16:54: error: 'FPOS_POS_LEN' undeclared (first use in this function); did you mean 'FILEPOS_LEN'?
   16 |         memcpy((void *)(dest), (void *)(src), sizeof(FPOS_POS_LEN))
      |                                                      ^~~~~~~~~~~~
file.c:1470:9: note: in expansion of macro 'SWAP_HALF_IN_FILEPOS'
 1470 |         SWAP_HALF_IN_FILEPOS(&ret, &tmp);
      |         ^~~~~~~~~~~~~~~~~~~~
make[1]: *** [Makefile:2688: file.o] Error 1
make: *** [Makefile:4964: debug] Error 2

Attach make debug output

debug.log

Execution environment (please complete the following information):

  • OS:
    Gentoo Linux with musl and clang

  • Calc Version
    v2.14.1.1

Enhancement: Alternative representations of some results.

Some calculations like 1/3 that results in
~0.33333333333333333333
or -1/3
~-0.33333333333333333333

I believe it would be better to add a space, so that results shows like
~ 0.33333333333333333333
~ -0.33333333333333333333

or in alternative a space followed by ellipsis at the end (that is a space and 3 dots, not the utf-8 for the ellipsis), like the followed:
0.33333333333333333333 ...
-0.33333333333333333333 ...

it would be nice users can configure the representation of such numbers, either as a ~ or ... or both, however the space after ~ should really exist, since in a fast glace, in my terminal I took ~0.333 by -0.333.

Also....

In the site example:

config("mode", "fraction"),
(17/19)^23

19967568900859523802559065713/257829627945307727248226067259

base(16),
(19/17)^29

0x9201e65bdbb801eaf403f657efcf863/0x5cd2e2a01291ffd73bee6aa7dcf7d1

There should be spaces on both sides of '/', I very much doubt everyone can see that result is a fraction, I didn't saw it at first...

so results should be:
19967568900859523802559065713 / 257829627945307727248226067259

0x9201e65bdbb801eaf403f657efcf863 / 0x5cd2e2a01291ffd73bee6aa7dcf7d1

I would do it some of the changes myself, however I have no ideia where to change this in the source code.

Thanks

Bug: realloc of globalnames by addstr results in heap-use-after-free

When compiling calc with clang on macOS AND with the following in Makefile.local:

CFLAGS+= -fsanitize=address
LDFLAGS+= -fsanitize=address

Running 'make chk' results calc reporting:

AddressSanitizer: heap-use-after-free

See issue.txt for details.

The problem here is that when addglobal() (see addglobal symbol.c:122):

    sp->g_name = addstr(&globalnames, name);

and then addstr() does a realloc (see addstr str.c:115):

            list = (char *)realloc(hp->h_list, newsize + 1);

pointers into that global block become BOGUS. Normally symbols are located within globalnames by an offset, which is correct. Something in calc is doing the wrong thing and is retaining a pointer into globalnames when it should use an offset instead.

Realloc is allowed to move the memory block, so global symbol lookup should use an OFFSET into globalnames, NOT pointers!

This bug is triggered when lots of global symbols are defined. This happens, for example, when the cal/regress.cal code is run. Because of the extensive script use, enough global symbols are defined that the initial global symbol block is filled and realloc() can move it.

Triggering this bug is highly dependent on the libc allocator, so your kilometer-age may vary. :-)

Nevertheless, the issue of realloc in calc should be carefully examined when it goes to larger blocks such as that for globalnames.

While this bug was first observed in v2.14.0.14, it appears this bug goes way back to pre-1999. Thanks to clang, we have identified this flaw and intend to correct it.

Comments, and bug fix patches are welcome!

Bug: build is broken on PowerPC: make: [charbit.h] Error 127 (ignored)

--->  Configuring calc
--->  Building calc
Executing:  cd "/opt/local/var/macports/build/_opt_PPCSnowLeopardPorts_math_calc/calc/work/calc-2.14.2.1" && /usr/bin/make -j1 -w all CC=/opt/local/bin/gcc-mp-12 DARWIN_ARCH="-arch ppc" 
make: Entering directory `/opt/local/var/macports/build/_opt_PPCSnowLeopardPorts_math_calc/calc/work/calc-2.14.2.1'
forming have_limits.h
have_limits.h formed
forming have_ban_pragma.h
have_ban_pragma.h formed
forming charbit.h
make: [charbit.h] Error 127 (ignored)
charbit.h formed
forming have_unistd.h
have_unistd.h formed
forming have_stdlib.h
have_stdlib.h formed
forming longbits.h
make: *** [longbits.h] Error 127
make: Leaving directory `/opt/local/var/macports/build/_opt_PPCSnowLeopardPorts_math_calc/calc/work/calc-2.14.2.1'
Command failed:  cd "/opt/local/var/macports/build/_opt_PPCSnowLeopardPorts_math_calc/calc/work/calc-2.14.2.1" && /usr/bin/make -j1 -w all CC=/opt/local/bin/gcc-mp-12 DARWIN_ARCH="-arch ppc" 
Exit code: 2
Error: Failed to build calc: command execution failed

Same failure with gcc-4.2 and gcc-12.

error: buildtin memcpy forming offset [9, 16] is out of the bounds [0, 8] of object 'pos' with type 'FULL'

Just checked out the latest build, 2.12.17.5, ran 'make clean' then 'make all', but received the following errors:

~/git/calc$ make all make[1]: Entering directory '/home/dan/git/calc' make[1]: Leaving directory '/home/dan/git/calc' make[1]: Entering directory '/home/dan/git/calc' gcc -DCALC_SRC -DCUSTOM -Wall -march=native -fPIC longbits.c -c rm -f longbits gcc -DCALC_SRC -DCUSTOM -Wall -march=native -fPIC longbits.o -o longbits forming longbits.h longbits.h formed forming align32.h align32.h formed gcc -DCALC_SRC -DCUSTOM -Wall -march=native -fPIC endian.c -c rm -f endian gcc -DCALC_SRC -DCUSTOM -Wall -march=native -fPIC endian.o -o endian forming endian_calc.h endian_calc.h formed forming fposval.h fposval.h formed gcc -Werror -Wextra -pedantic -DCALC_SRC -DCUSTOM -Wall -march=native -fPIC -O3 -g3 -c -o addop.o addop.c gcc -Werror -Wextra -pedantic -DCALC_SRC -DCUSTOM -Wall -march=native -fPIC -O3 -g3 -c -o assocfunc.o assocfunc.c gcc -Werror -Wextra -pedantic -DCALC_SRC -DCUSTOM -Wall -march=native -fPIC -O3 -g3 -c -o blkcpy.o blkcpy.c gcc -Werror -Wextra -pedantic -DCALC_SRC -DCUSTOM -Wall -march=native -fPIC -O3 -g3 -c -o block.o block.c gcc -Werror -Wextra -pedantic -DCALC_SRC -DCUSTOM -Wall -march=native -fPIC -O3 -g3 -c -o byteswap.o byteswap.c gcc -Werror -Wextra -pedantic -DCALC_SRC -DCUSTOM -Wall -march=native -fPIC -O3 -g3 -c -o calcerr.o calcerr.c gcc -Werror -Wextra -pedantic -DCALC_SRC -DCUSTOM -Wall -march=native -fPIC -O3 -g3 -c -o codegen.o codegen.c gcc -Werror -Wextra -pedantic -DCALC_SRC -DCUSTOM -Wall -march=native -fPIC -O3 -g3 -c -o comfunc.o comfunc.c gcc -Werror -Wextra -pedantic -DCALC_SRC -DCUSTOM -Wall -march=native -fPIC -O3 -g3 -c -o commath.o commath.c gcc -Werror -Wextra -pedantic -DCALC_SRC -DCUSTOM -Wall -march=native -fPIC -O3 -g3 -c -o config.o config.c gcc -Werror -Wextra -pedantic -DCALC_SRC -DCUSTOM -Wall -march=native -fPIC -O3 -g3 -c -o const.o const.c gcc -Werror -Wextra -pedantic -DCALC_SRC -DCUSTOM -Wall -march=native -fPIC -O3 -g3 -c -o custom.o custom.c gcc -Werror -Wextra -pedantic -DCALC_SRC -DCUSTOM -Wall -march=native -fPIC -O3 -g3 -Wno-error=long-long -Wno-long-long -c file.c In file included from /usr/include/string.h:495, from alloc.h:42, from zmath.h:39, from qmath.h:32, from cmath.h:32, from value.h:33, from calc.h:33, from file.c:39: In function 'memcpy', inlined from 'z2filepos' at file.c:1419:2, inlined from 'set_open_pos' at file.c:1638:8, inlined from 'setloc' at file.c:1700:9: /usr/include/x86_64-linux-gnu/bits/string_fortified.h:34:10: error: '__builtin_memcpy' forming offset [9, 16] is out of the bounds [0, 8] of object 'pos' with type 'FULL' {aka 'long unsigned int'} [-Werror=array-bounds] 34 | return __builtin___memcpy_chk (__dest, __src, __len, __bos0 (__dest)); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ file.c: In function 'setloc': file.c:1403:7: note: 'pos' declared here 1403 | FULL pos; /* zpos as a FULL */ | ^~~ In file included from /usr/include/string.h:495, from alloc.h:42, from zmath.h:39, from qmath.h:32, from cmath.h:32, from value.h:33, from calc.h:33, from file.c:39: In function 'memcpy', inlined from 'z2filepos' at file.c:1419:2, inlined from 'fseekid' at file.c:1585:9: /usr/include/x86_64-linux-gnu/bits/string_fortified.h:34:10: error: '__builtin_memcpy' forming offset [9, 16] is out of the bounds [0, 8] of object 'pos' with type 'FULL' {aka 'long unsigned int'} [-Werror=array-bounds] 34 | return __builtin___memcpy_chk (__dest, __src, __len, __bos0 (__dest)); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ file.c: In function 'fseekid': file.c:1403:7: note: 'pos' declared here 1403 | FULL pos; /* zpos as a FULL */ | ^~~ In file included from /usr/include/string.h:495, from alloc.h:42, from zmath.h:39, from qmath.h:32, from cmath.h:32, from value.h:33, from calc.h:33, from file.c:39: In function 'memcpy', inlined from 'z2filepos' at file.c:1419:2, inlined from 'fseekid' at file.c:1602:9: /usr/include/x86_64-linux-gnu/bits/string_fortified.h:34:10: error: '__builtin_memcpy' forming offset [9, 16] is out of the bounds [0, 8] of object 'pos' with type 'FULL' {aka 'long unsigned int'} [-Werror=array-bounds] 34 | return __builtin___memcpy_chk (__dest, __src, __len, __bos0 (__dest)); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ file.c: In function 'fseekid': file.c:1403:7: note: 'pos' declared here 1403 | FULL pos; /* zpos as a FULL */ | ^~~ In file included from /usr/include/string.h:495, from alloc.h:42, from zmath.h:39, from qmath.h:32, from cmath.h:32, from value.h:33, from calc.h:33, from file.c:39: In function 'memcpy', inlined from 'z2filepos' at file.c:1419:2, inlined from 'fseekid' at file.c:1569:9: /usr/include/x86_64-linux-gnu/bits/string_fortified.h:34:10: error: '__builtin_memcpy' forming offset [9, 16] is out of the bounds [0, 8] of object 'pos' with type 'FULL' {aka 'long unsigned int'} [-Werror=array-bounds] 34 | return __builtin___memcpy_chk (__dest, __src, __len, __bos0 (__dest)); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ file.c: In function 'fseekid': file.c:1403:7: note: 'pos' declared here 1403 | FULL pos; /* zpos as a FULL */ | ^~~ In file included from /usr/include/string.h:495, from alloc.h:42, from zmath.h:39, from qmath.h:32, from cmath.h:32, from value.h:33, from calc.h:33, from file.c:39: In function 'memcpy', inlined from 'z2filepos' at file.c:1419:2, inlined from 'fsearch' at file.c:2653:8: /usr/include/x86_64-linux-gnu/bits/string_fortified.h:34:10: error: '__builtin_memcpy' forming offset [9, 16] is out of the bounds [0, 8] of object 'pos' with type 'FULL' {aka 'long unsigned int'} [-Werror=array-bounds] 34 | return __builtin___memcpy_chk (__dest, __src, __len, __bos0 (__dest)); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ file.c: In function 'fsearch': file.c:1403:7: note: 'pos' declared here 1403 | FULL pos; /* zpos as a FULL */ | ^~~ In file included from /usr/include/string.h:495, from alloc.h:42, from zmath.h:39, from qmath.h:32, from cmath.h:32, from value.h:33, from calc.h:33, from file.c:39: In function 'memcpy', inlined from 'z2filepos' at file.c:1419:2, inlined from 'frsearch' at file.c:2812:8: /usr/include/x86_64-linux-gnu/bits/string_fortified.h:34:10: error: '__builtin_memcpy' forming offset [9, 16] is out of the bounds [0, 8] of object 'pos' with type 'FULL' {aka 'long unsigned int'} [-Werror=array-bounds] 34 | return __builtin___memcpy_chk (__dest, __src, __len, __bos0 (__dest)); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ file.c: In function 'frsearch': file.c:1403:7: note: 'pos' declared here 1403 | FULL pos; /* zpos as a FULL */ | ^~~ In file included from /usr/include/string.h:495, from alloc.h:42, from zmath.h:39, from qmath.h:32, from cmath.h:32, from value.h:33, from calc.h:33, from file.c:39: In function 'memcpy', inlined from 'z2filepos' at file.c:1419:2, inlined from 'frsearch' at file.c:2780:9: /usr/include/x86_64-linux-gnu/bits/string_fortified.h:34:10: error: '__builtin_memcpy' forming offset [9, 16] is out of the bounds [0, 8] of object 'pos' with type 'FULL' {aka 'long unsigned int'} [-Werror=array-bounds] 34 | return __builtin___memcpy_chk (__dest, __src, __len, __bos0 (__dest)); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ file.c: In function 'frsearch': file.c:1403:7: note: 'pos' declared here 1403 | FULL pos; /* zpos as a FULL */ | ^~~ In file included from /usr/include/string.h:495, from alloc.h:42, from zmath.h:39, from qmath.h:32, from cmath.h:32, from value.h:33, from calc.h:33, from file.c:39: In function 'memcpy', inlined from 'z2filepos' at file.c:1419:2, inlined from 'frsearch' at file.c:2768:9: /usr/include/x86_64-linux-gnu/bits/string_fortified.h:34:10: error: '__builtin_memcpy' forming offset [9, 16] is out of the bounds [0, 8] of object 'pos' with type 'FULL' {aka 'long unsigned int'} [-Werror=array-bounds] 34 | return __builtin___memcpy_chk (__dest, __src, __len, __bos0 (__dest)); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ file.c: In function 'frsearch': file.c:1403:7: note: 'pos' declared here 1403 | FULL pos; /* zpos as a FULL */ | ^~~ cc1: all warnings being treated as errors make[1]: *** [Makefile.ship:2371: file.o] Error 1 make[1]: Leaving directory '/home/dan/git/calc' make: *** [Makefile:206: all] Error 2

calc v2.12.7.2 print the input twice (MINGW32 GCC)

OS: Windows 8.1 64bit
Compiler: MINGW32 GCC
After making some very small change the source file, I compiled calc.exe successfully.
Everything is OK but calc.exe print the input twice like below.

; 9+9
9+9
      18
; 3*3
3*3
      9

Bug report: Possibly-security sensitive warnings from 2.14.1.2 build

-Wmaybe-uninitialized

gcc  -DCALC_SRC -UCUSTOM -Wall -Wextra -pedantic     -UUNBAN -fPIC -O2 -flto=auto -ffat-lto-objects
 -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 
-Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -
specs=/usr/lib/rpm/redhat/redhat-annobin-cc1  -m64  -mtune=generic -fasynchronous-unwind-tables -fs
tack-clash-protection -fcf-protection   -c -o byteswap.o byteswap.c
In file included from qmath.h:32,
                 from cmath.h:32,
                 from byteswap.c:28:
zmath.h: In function 'swap_HALF_in_ZVALUE':
zmath.h:581:36: warning: 'dest_40->v' may be used uninitialized [-Wmaybe-uninitialized]
  581 | #define zcopyval(z1,z2) memcpy((z2).v, (z1).v, (z1).len * sizeof(HALF))
      |                                    ^

I think this might just be because the compiler is not understanding/trusting what's going on with the not_reached() in the check for NULL, but... maybe there's something else going on?

-Wuse-after-free

gcc  -DCALC_SRC -UCUSTOM -Wall -Wextra -pedantic     -UUNBAN -fPIC -O2 -flto=auto -ffat-lto-objects
 -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 
-Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -
specs=/usr/lib/rpm/redhat/redhat-annobin-cc1  -m64  -mtune=generic -fasynchronous-unwind-tables -fs
tack-clash-protection -fcf-protection   -c -o lib_calc.o lib_calc.c
lib_calc.c: In function 'find_tty_state':
lib_calc.c:805:36: warning: pointer may be used after 'realloc' [-Wuse-after-free]
  805 |         new_fd_orig = (ttystruct *)realloc(fd_setup, sizeof(fd_orig[0]) *
      |                                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  806 |                                             (fd_setup_len+1));
      |                                             ~~~~~~~~~~~~~~~~~
lib_calc.c:799:31: note: call to 'realloc' here
  799 |         new_fd_setup = (int *)realloc(fd_setup, sizeof(fd_setup[0]) *
      |                               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  800 |                                       (fd_setup_len+1));
      |                                       ~~~~~~~~~~~~~~~~~

I think this is is a bug — realloc of fd_setup on both https://github.com/lcn2/calc/blob/master/lib_calc.c#L799 and https://github.com/lcn2/calc/blob/master/lib_calc.c#L805, and if the memory moves in the first call, fd_setup will have been freed, right?

-Wclobbered

gcc  -DCALC_SRC -UCUSTOM -Wall -Wextra -pedantic     -UUNBAN -fPIC -O2 -flto=auto -ffat-lto-objects
 -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 
-Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -
specs=/usr/lib/rpm/redhat/redhat-annobin-cc1  -m64  -mtune=generic -fasynchronous-unwind-tables -fs
tack-clash-protection -fcf-protection -Wno-implicit -Wno-error=long-long \
    -Wno-long-long -c seed.c
seed.c: In function 'pseudo_seed':
seed.c:481:12: warning: variable 'hash_val' might be clobbered by 'longjmp' or 'vfork' [-Wclobbered]
  481 |     hash64 hash_val;                    /* fnv64 hash of sdata */
      |            ^~~~~~~~

I have no idea what's going on here, actually. :)

Enhancement: Some control of protection "inheritance"

Is your feature request related to a problem? Please describe.
"If B is a variable with positive status and assignment of B to A is permitted, execution of the assignment A = B adds to the protections of A all protections of B that A does not already have." (from calc help)

This could be understood as protection "inheritance", a very powerful feature, but not what some users might anticipate. Any assignment of pi or e to a variable "freezes" that variable.

Describe the solution you'd like
More intuitive (for my application anyway) would be some default or initializable defense against protection "inheritance", in effect giving some variables the same no-inherited-protection as builtin functions. Like 512: A protections not inherited. In any case,

Describe alternatives you've considered
My choices might be: a) forcing the user to understand pi and e as functions, b) remember to "protect(user_variable, 0);" at least after assignment from pi or e, or "define pi() { x = pi; protect(x, 0); return x};" which puts me back to square one.

Additional context
/---------------------------------------------------------------------------------------------------------------------/
Add the following line after line 181 in your current value.h:
#define V_PROTECTNOINHERIT 512 /* protection status 512 /
/
---------------------------------------------------------------------------------------------------------------------/
Add the following line after line 876 in your current opcodes.c:
if (tmp.v_subtype & V_PROTECTNOINHERIT) var->v_subtype = 0;
/
---------------------------------------------------------------------------------------------------------------------*/
Tested in my application & works well.

statistics.cal: `ervinf` in `probit` definition should be `erfinv`

The probit function is defined in cal/statistics.cal as follows (v2.13.0.1):

calc/cal/statistics.cal

Lines 372 to 375 in 3d33c6c

define probit(p){
if(p<0 || p > 1) return newerror("probit: p out of domain 0<=p<=1");
return sqrt(2)*ervinv(2*p-1);
}

There is no function named ervinf; this is certainly a misspelling of erfinv (the inverse error function). Calling probit results in the following error: Function "ervinv" is undefined.

Fix: ervinv should be corrected to erfinv.

Version used: 2.12.7.2
Version(s) affected: >=2.12.4.10 (based on file history)
Operating System: Linux (x86_64), Ubuntu 21.04

Seg fault caused by dereferencing null pointer when calculating sec(x) or csc(x)

While sin(x) and cos(x) prompted a "too large im(argument) for sin/cos" error, calculating sec(x) and csc(x) with x being a big complex number led to a crash.

The segfault is due to c_sin() (at func.c:2356) return a null pointer when input is a big complex number, which is never checked after that and finally is dereferenced in ciszero().

In f_csc()

case V_COM:
    tmp.v_type=V_COM;
    tmp.v_com=c_sin(vals[0]->v_com,err);    <—— return (complex *) 0x0
    invertvalue(&tmp,&result); 

In invertvalue()

invertvalue(VALUE *vp,VALUE *vres)
{
    ...
    case V_COM:         
        vres->v_com = c_inv(vp->v_com);    <—— vp->v_com is (complex *) 0x0
        return;

In c_inv()

c_inv(COMPLEX *c)
{   
    COMPLEX *r;
    NUMBER *q1, *q2, *den;
        
    if (ciszero(c))    <——— c is (complex *) 0x0 

Macro expansion of ciszero()

ciszero(c) 
cisreal(c) && qiszero((c)->real) 
qiszero((c)->imag) && qiszero((c)->real)

Here de-referencing c, which is 0x0, causes the segmentation fault.

Following are backtraces.
csc(2E9i)

commath.c:258:6: runtime error: member access within null pointer of type 'struct COMPLEX'
ASAN:DEADLYSIGNAL
=================================================================
==23131==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000008 (pc 0x556be61386f7 bp 0x7ffe458306d0 sp 0x7ffe45830690 T0)
   #0 0x556be61386f6 in c_inv commath.c:258
   #1 0x556be60862d0 in invertvalue value.c:684
   #2 0x556be5f67555 in f_csc func.c:2357
   #3 0x556be5fb1bb1 in builtinfunc func.c:9195
   #4 0x556be6000722 in o_call opcodes.c:2726
   #5 0x556be60087da in calculate opcodes.c:3918
   #6 0x556be5f3c2aa in evaluate codegen.c:293
   #7 0x556be5f3bf2a in getcommands codegen.c:223
   #8 0x556be5f3a0ad in main calc.c:619
   #9 0x7f4d1b03b2e0 in __libc_start_main (libc.so.6+0x202e0)
   #10 0x556be5f36809 in _start (calc+0x2ae809)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /home/wuxh/Projects/fuzz/fot/fot-fuzz/res/projects/experiments/calc/calc-analysis/commath.c:258 in c_inv
==23131==ABORTING

sec(2E9i)

commath.c:258:6: runtime error: member access within null pointer of type 'struct COMPLEX'
ASAN:DEADLYSIGNAL
=================================================================
==23218==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000008 (pc 0x55d711e2b6f7 bp 0x7ffccdd82030 sp 0x7ffccdd81ff0 T0)
   #0 0x55d711e2b6f6 in c_inv commath.c:258
   #1 0x55d711d792d0 in invertvalue value.c:684
   #2 0x55d711c5908a in f_sec func.c:2279
   #3 0x55d711ca4bb1 in builtinfunc func.c:9195
   #4 0x55d711cf3722 in o_call opcodes.c:2726
   #5 0x55d711cfb7da in calculate opcodes.c:3918
   #6 0x55d711c2f2aa in evaluate codegen.c:293
   #7 0x55d711c2ef2a in getcommands codegen.c:223
   #8 0x55d711c2d0ad in main calc.c:619
   #9 0x7f743e73b2e0 in __libc_start_main (libc.so.6+0x202e0)
   #10 0x55d711c29809 in _start (calc+0x2ae809)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /home/wuxh/Projects/fuzz/fot/fot-fuzz/res/projects/experiments/calc/calc-analysis/commath.c:258 in c_inv
==23218==ABORTING

Variable value setting issue

Describe the bug
Under different circumstances assigning a value to a variable has different results. If the variable is assigned the value of a list member real integer 2, we get the expected results. But if the same list member is pi, we get a different (wrong) result. Freeing the variable before assignment gives the correct result in both cases.

To Reproduce
See attached file

Expected behavior
See attached file

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • OS: macOS 11.6.3
  • Browser Chrome
  • Version 98.0.4758.102 (Official Build) (x86_64)

Smartphone (please complete the following information):

  • Device: [e.g. iPhone6]
  • OS: [e.g. iOS8.1]
  • Browser [e.g. stock browser, safari]
  • Version [e.g. 22]

Additional context
This is using calc 2.12.4.14, searching release notes for 2.14.0.15 not seeing this bug.
Error_Report.txt

Enhancement: Library version?

Hi @lcn2 .

$ ldd calc 
        ...
        libcalc.so.2.14.1.0 => ~/git/calc/libcalc.so.2.14.1.0 (0x00007fafa43dd000)
        libcustcalc.so.2.14.1.0 => ~/git/calc/libcustcalc.so.2.14.1.0 (0x00007fafa43d4000)
        ...

Shouldn't it link to the SO (MAJOR) version?:

        libcalc.so.2 => ...
        libcustcalc.so.2 => ...

And name libcustcalc. Maybe libcalccust?

Cant figure out how to get percent.

version 2.12.7.2
I need some help. I want to get the percent. For example: 2% from 400 = 8

; 400%2
	0
; 400*%2
Missing expression

; 400*2%
Missing expression

; %2*400
Missing expression

; 2%400
	2
; 

How to get 8?

Fix atoq and atoz cruft in LIBRARY

As a new user, I found this confusing. If I were a longtime user, it may also be confusing. If atoq and atoz have been removed or renamed, then the only acceptable references ought to be in the CHANGES file. Submitting a pull request.

'make all' produces errors - "Function calls not allowed as expressions"

I'm trying to compile calc on Ubuntu 18.04 using gcc and encountered the following errors:

~/git/calc$ make all make[1]: Entering directory '/home/dan/git/calc' make[1]: Leaving directory '/home/dan/git/calc' make[1]: Entering directory '/home/dan/git/calc' gcc -Werror -Wextra -pedantic -DCALC_SRC -DCUSTOM -Wall -fPIC -O3 -g3 -c -o codegen.o codegen.c codegen.c: In function 'getterm': codegen.c:2211:5: error: this statement may fall through [-Werror=implicit-fallthrough=] scanerror(T_NULL, ^~~~~~~~~~~~~~~~~ "Function calls not allowed " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ "as expressions"); ~~~~~~~~~~~~~~~~~ codegen.c:2214:4: note: here default: ^~~~~~~ codegen.c: In function 'creatematrix': codegen.c:1396:5: error: this statement may fall through [-Werror=implicit-fallthrough=] rescantoken(); ^~~~~~~~~~~~~ codegen.c:1397:4: note: here case T_COMMA: ^~~~ codegen.c:1386:4: error: this statement may fall through [-Werror=implicit-fallthrough=] rescantoken(); ^~~~~~~~~~~~~ codegen.c:1387:3: note: here case T_COMMA: ^~~~ codegen.c: In function 'getidexpr': codegen.c:2248:6: error: this statement may fall through [-Werror=implicit-fallthrough=] if (autodef != T_GLOBAL && autodef != T_LOCAL && ^ codegen.c:2252:2: note: here default: ^~~~~~~ codegen.c:2277:4: error: this statement may fall through [-Werror=implicit-fallthrough=] scanerror(T_NULL, ^~~~~~~~~~~~~~~~~ "Function calls not allowed " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ "as expressions"); ~~~~~~~~~~~~~~~~~ codegen.c:2280:3: note: here default: ^~~~~~~ codegen.c: In function 'getstatement': codegen.c:1023:3: error: this statement may fall through [-Werror=implicit-fallthrough=] reread(); ^~~~~~~~ codegen.c:1026:2: note: here default: ^~~~~~~ cc1: all warnings being treated as errors <builtin>: recipe for target 'codegen.o' failed make[1]: *** [codegen.o] Error 1 make[1]: Leaving directory '/home/dan/git/calc' Makefile:205: recipe for target 'all' failed make: *** [all] Error 2

Any advice on how to proceed?

Thanks!

Consider this "issue" positive feedback.

I've used 'calc' for years, and it's great. Easy to use, text based, intuitive, powerful, and the best part of all; it's constantly inviting to experimentation and playing around with numbers.

Big thanks to everyone involved in developing this incredible tool!

Enhancement: Build System, Cross Compiling, Android, Termux, Clang, CMake

Is your feature request related to a problem? Please describe.
Background, context. I'm using Termux on an Android device to make Android apps in Android itself, for various reasons, including an exercise in learning, a "fun constraint", morbid curiousity, poverty, disability/accessibility, spiteful resentment of Google's HEAVY, PC-centric oppressive bias, closed-source, rottenly documented tools, as well as disdain for the ecosystem of closed-source, paid SaaS, like ReactNative/expo, and others. Thus far, I've been able to build and install a basic "Hello World" app, with additional "Hello World" accessed via JNI to C. Further, I cross compiled this trivial C library as a .so for both aarch64 and armv7a, assembled in a single .apk file (in directories lib/arm64-v8a and lib/armeabi-v7a, respectively), and tested on both hardware devices (aarch64 Android 12, armv7l ['el' not 'one'] Android 5).

This brings me to my next phase. How do I cross compile libcalc as a .so on aarch64 for armv7a? That's a lot to unpack. Yes, the Termux project has compiled and packaged calc (thus libcalc) for Android, which is how I learned about calc. I could just copy the .so files (I'm aware of the possible libcalc dependency on other .so's, not ignoring, just deferring concern). However, it besides "cheating", it doesn't help if I'm trying to compile for armv7a. Nor does it help if I am on a Linux or Windows PC (say AMD or Intel x64 or server CPU), either physically or remotely, and wish to cross compile libcalc.so for aarch64 and armv7a.

In Termux, when I compile calc from unmodified source using the minimum commands (just make or make -f Makefile), I see gcc is chosen, and there are lots of errors, and something ends in failure, yet there are some compiled binary executables and libs.

First problem, Google officially dropped gcc on Android years ago due primarily to GPL licensing and also cited project management issues as a (possibly bogus) excuse. While there is an unofficial, quasi-maintained patch to gcc within Termux, itself an unofficial, sporadically maintained set of patches, that gcc can be a source of untold errors. It seems to work fine, on simple programs, but who knows? Clang is far more supported on Android in Termux. Using clang --target arm64-linux-android24 (redundant when I'm on the device) and clang --target armv7a-linux-androideabi24 (with -fPIC -shared) seems to get the .so format that makes the Java/Android subsystem happy when calling System.loadLibrary().

I'm having difficulty knowing what command line options and/or variables to set, and/or if/what parts of the Makefile need to be modified to properly detect the Termux build environment, and how to build ONLY the libraries.

uname -s is Linux
uname -p is unknown
uname -m is aarch64
uname -o is Android (but this is stored in a variable named MINGW, ugh! hould be OS or OSNAME or something, an os-neutral variable name)

Describe the solution you'd like

I think I already have the ability to build the library, but ut seems to ONLY allow building shared library .so not only the .a libraries? I don't think I need .a only right now, but it seemed odd to lack that granularity of control.

I'm not sure if the code checks can be run to test libraries only, or if that requires the full command line utility to be built in order to run the tests. Separate lib-only tests would be nice, to isolate command line bugs from library bugs. Maybe it doesn't yield enough benefit for the effort? Clarity on this point?

I'd like to see, at a bare minimum, Android/Termux properly identified, clang chosen.

I'd really like to be able to specify cross-compilation, not assume that the current build-CPU arch is the only arch in the universe.

I'd really, really like to be able to specify multiple targets for cross compilation, run a single build command, and collect the binaries. I can manage via scripting (shell or Python) as an interim workaround (loop for each target, clean/clobber, build, copy, next).

It'd be nice to have a CMake build system, to manage these sorts of things. I'll let Santa, the Easter Bunny, and the Tooth Fairy know. I'm sure they'll get right on that. :o) But seriously, has this been considered, discussed? Is there a conversation somewhere that I may have missed? If so, direct me there. I'm curious about feasability, specific concerns, particularly regarding complex dependency issues between Makefile, Makefile.ship and custom/Makefile` which are currently blocking parallel builds, possibly blocking cross compilation and multi-target builds. Does CMake offer easier access to these features? As well as the boilerplate utility and OS testing, which may make a large portion of existing Makefile redundant?

Finally, I'd eventually like to have my Android calculator app build on Linux proper, as well as Windows under WSLv2, MinGW/MSYS (implies Cygwin, sort of), and maybe one day if possible Visual Studio Build Tools (command line C preprocessor, C compiler, library linker), though I'm not optimistic about ARM cross compilation with freely available tools from MS (they tend to charge money for advanced features and then rabidly vendor-lock in a limited subset of environments), but who knows, I may be ignorant, hence the exploration of possibility.

Describe alternatives you've considered
make calc-dynamic-only LCC=clang CFLAGS="--target=arm64-linux-android24" BLD_TYPE=calc-dynamic-only

forming have_limits.h
have_limits.h formed
forming have_ban_pragma.h
have_ban_pragma.h formed
forming charbit.h
charbit.h formed
forming have_unistd.h
have_unistd.h formed
forming have_stdlib.h
have_stdlib.h formed
forming longbits.h
longbits.h formed
forming align32.h
align32.h formed
forming have_string.h
have_string.h formed
forming args.h
args.h formed
forming calcerr.h
calcerr.h formed
forming conf.h
conf.h formed
forming endian_calc.h
endian_calc.h formed
forming have_fpos.h
have_fpos.h formed
forming have_posscl.h
have_posscl.h formed
forming have_fpos_pos.h
have_fpos_pos.h formed
forming have_offscl.h
have_offscl.h formed
forming have_newstr.h
have_newstr.h formed
forming have_memmv.h
have_memmv.h formed
forming fposval.h                                                           fposval.h formed
forming have_const.h                                                        have_const.h formed                                                         forming have_getpgid.h
have_getpgid.h formed
forming have_getprid.h
have_getprid.h formed
forming have_getsid.h
have_getsid.h formed
forming have_gettime.h
have_gettime.h formed
forming have_rusage.h
have_rusage.h formed
forming have_strdup.h
have_strdup.h formed
forming have_strlcat.h
have_strlcat.h formed
forming have_strlcpy.h
have_strlcpy.h formed
forming have_times.h
have_times.h formed
forming have_uid_t.h
have_uid_t.h formed
forming have_unused.h
have_unused.h formed
forming have_urandom.h
have_urandom.h formed
forming have_ustat.h
have_ustat.h formed
forming terminal.h
terminal.h formed
forming have_environ.h
have_environ.h formed
forming have_arc4random.h
have_arc4random.h formed
forming calcerr.c
calcerr.c formed
rm -f custom/.all
cd custom; make -f Makefile ALLOW_CUSTOM="-DCUSTOM" AR="ar" ARCH_CFLAGS="" AWK="awk" BINDIR="/usr/bin" BLD_TYPE="calc-dynamic-only" CALC_INCDIR="/usr/include/calc" CALC_SHAREDIR="/usr/share/calc" CAT="cat" CC=" clang " CCBAN="-UUNBAN" CCERR="" CCMISC="" CCOPT="-O3 -g3" CCWARN="-Wall -Wextra -pedantic" CC_SHARE="-fPIC" CFLAGS="--target=arm64-linux-android24 -I.." CHMOD="chmod" CMP="cmp" CO="co" COMMON_ADD="" COMMON_CFLAGS="-DCALC_SRC -DCUSTOM -Wall -Wextra -pedantic     -I.." COMMON_LDFLAGS=" " CP="cp" CUSTOMCALDIR="/usr/share/calc/custom" CUSTOMHELPDIR="/usr/share/calc/custhelp" CUSTOMINCDIR="/usr/include/calc/custom" DEBUG="-O3 -g3" DEFAULT_LIB_INSTALL_PATH="/data/data/com.termux/files/home/dev/calc-2.14.1.0:/lib:/usr/lib:/usr/lib:/usr/local/lib" DIFF="diff" E="2>/dev/null" FMT="fmt" GREP="egrep" H="@" HELPDIR="/usr/share/calc/help" ICFLAGS="-DCALC_SRC -DCUSTOM -Wall -Wextra -pedantic     -UUNBAN -fPIC -I.." ILDFLAGS=" " INCDIR="/usr/include" LANG="C" LCC="clang" LDCONFIG="ldconfig" LDFLAGS="  " LD_SHARE=""-Wl,-rpath,/data/data/com.termux/files/home/dev/calc-2.14.1.0:/lib:/usr/lib:/usr/lib:/usr/local/lib" "-Wl,-rpath-link,/data/data/com.termux/files/home/dev/calc-2.14.1.0:/lib:/usr/lib:/usr/lib:/usr/local/lib"" LIBCUSTCALC_SHLIB="-shared "-Wl,-soname,libcustcalc.so.2.14.1.0"" LIBDIR="/usr/lib" LN="ln" LS="ls" MAKE="make" MAKEDEPEND="makedepend" MAKE_FILE=Makefile MKDIR="mkdir" MV="mv" MINGW="Android" PREFIX="/usr/local" PURIFY="" Q="@" RANLIB="ranlib" RM="rm" RMDIR="rmdir" S=">/dev/null 2>&1" SCRIPTDIR="/usr/bin/cscript" SED="sed" SHELL="/bin/bash" SORT="sort" T="" TAIL="tail" TOUCH="touch" TRUE="true" V="@:" VERSION="2.14.1.0" WNO_IMPLICT="-Wno-implicit" WNO_ERROR_LONG_LONG="-Wno-error=long-long" WNO_LONG_LONG="-Wno-long-long" target="Linux" all
make[1]: Entering directory '/data/data/com.termux/files/home/dev/calc-2.14.1.0/custom'
clang  --target=arm64-linux-android24 -I..   -c -o custtbl.o custtbl.c
In file included from custtbl.c:30:
In file included from ../value.h:42:                                        /data/data/com.termux/files/usr/include/calc/decl.h:29:10: fatal error: 'calc/have_const.h' file not found
#include "calc/have_const.h"
         ^~~~~~~~~~~~~~~~~~~
1 error generated.
make[1]: *** [<builtin>: custtbl.o] Error 1
make[1]: Leaving directory '/data/data/com.termux/files/home/dev/calc-2.14.1.0/custom'
make: *** [Makefile:4373: custom/.all] Error 2

Additional context
I used bc for nearly 3 decades. Then I found that it couldn't do decimal exponentiation. Then I found GMP but it has no CLI. Then I found calc via Termux package system, and it has a CLI, a library, and handles decimal exponentiation. Used this for a couple years. Then I had the (dumb, crazy, fun) idea to make a calculator app, after my old propietary app started spying. Existing Android build processes depend way too much on bloated, buggy, exponentially complex, proprietary nonsense. So I decided to build on Android in Termux using only bash, vim, openjdk's javac, jar, and keytool, android.jar, and whatever other build tools are necessary, like aapt2, d8 (DEX v8), 7z (or Info-Zip's zip would work), zipalign, apksigner, later, clang and llvm-strip, eventually git to publish on GitHub. I looked again at GMP and it was highly recommended by a friend, but the exponentiation functions only handle integers, meaning a fair bit of cooking the decomal into reduced rational form and doing many steps, common tasks which belong in a library as utility wrappers, which GMP is uninterested in. Also, I find that some of GMPs other decimal functions provide little or no better accuracy than IEEE 754 with its rounding errors. Hence the need to also use the MPFR library for all floating points. Ok. But the current release is 4.x. There's a Java binding library for MPFR but only v3.x. So I'd have to do the Android to JNI to C wrappers myself, straightforward, hopefully. MPFR lists aarch64-unknown-linux-gnu (gcc 8.5.0 and 12.2.0, clang 15.0.4 on Termux/Android, tcc mob branch); as the very first supported platform, with both gcc and clang testing. It's nice to be placed as a first class platform, rather than an annoyance to be dismissed. My phone and old desktop PC are nearly equal in power. If my truck breaks down, I can use my phone to get help. I can't make a phone call by telepathic link to my desktop and then VOIP from my desktop. Can only afford one upgrade. Needed to delay desktop/laptop upgrade. Also, disability randomly makes sitting at desk impossible, sometimes for weeks at a time. It's easier to hold a 4oz phone in my hand while reclining, than an 80lb computer (including all peripherals). Sure, it'd be nice to afford a big enough room to live in and afford a large reclining chair with computer, monitor, and keyboard/mouse mounts, but see constraint above regarding computer upgrade. Even a laptop would honestly be very difficult to use. A tablet might be better, but can't call for help if I fall, get stuck, or car breaks down, or illness temporarily impairs ability to get to landline phone. Hence why I ended up on Android as my "primary" platform. All of that's no reason to stop learning and trying to build things. :o)

Enhancement: Try to support BASEB == 64

This is a synthetic double register size type, many architectures can compute twice as many bits from a multiplication, eg u64 * u64 = u128.

long long have the same meaning on 32-bit architectures as __int128 on 64-bit ones.

You might not like it, since it's a non-standard type (-pedantic prevents it from being used), but it will give twice faster addition/subtraction and 4-x faster multiplication.

The calc code seems to be very tied to HALF/FULL type definitions, but __int128 should only be used in certain places in zmath.c.

You can detect its availability by adding this to longbits.c:

#ifdef CHECK_B128
		if (sizeof(__int128) == 16) {
			printf("#undef HAVE_B128\n");
			printf("#define HAVE_B128\t\t/%s/\n",
			  "* have USB128 and SB128 types *");
			printf("typedef unsigned __int128 USB128;\t/%s/\n",
			  "* unsigned 128 bits *");
			printf("typedef __int128 SB128;\t\t/%s/\n",
			  "* signed 128 bits *");
			putchar('\n');
		}
#endif

And using this in the Makefile:

	${Q} ${LCC} ${ICFLAGS} -DCHECK_B128 longbits.c -c ${S} || ${LCC} ${ICFLAGS} longbits.c -c ${S}

So if compilation with CHECK_B128 fails, it will build without it.

Enhancement: add log based 2 and log base n builtin functions

Add log2(x [,eps]) builtin function for log base 2.

When x is an intger power of 2, including a negative power of 2, be sure that log2(x) returns an exact integer. Otherwise compute and return the equivalent of the expression ln(x) / ln(2).

The code that implements the builtin function ilog2() will assist in detecting when n x is an intger power of 2.

Add logn(x, n, [,eps]) builtin function for log base n.

When x is an integer power of n, including a negative power of n, be sure that logn(x, n) returns an exact integer. Otherwise compute and return the equivalent of the expression ln(x) / ln(n).

The code that implements the builtin function ilog() will assist in detecting when n x is an intger power of n.

Of course, check for bogus/invalid values of x and n and raise an error if given.

clang error building on MacOS

I get constant errors building recent calc versions (e.g. 2.14.0.14) on MacOS 10.13 (using default makefile):

[...]
clang  -DCALC_SRC -DCUSTOM -Wall -Wextra -pedantic     -UUNBAN -fPIC -O3 -g3   -c -o zrandom.o zrandom.c
rm -f ver_calc
clang -DCALC_SRC -DCUSTOM -Wall -Wextra -pedantic     -UUNBAN -fPIC -DCALC_VER   version.c strl.c -o ver_calc
clang  -single_module -undefined dynamic_lookup -dynamiclib -install_name /usr/local/lib/libcalc.2.14.0.14.dylib  addop.o assocfunc.o blkcpy.o block.o byteswap.o calcerr.o codegen.o comfunc.o commath.o config.o const.o custom.o file.o func.o hash.o help.o hist.o input.o jump.o label.o lib_calc.o lib_util.o listfunc.o matfunc.o math_error.o obj.o opcodes.o pix.o poly.o prime.o qfunc.o qio.o qmath.o qmod.o qtrans.o quickhash.o seed.o sha1.o size.o str.o strl.o symbol.o token.o value.o version.o zfunc.o zio.o zmath.o zmod.o zmul.o zprime.o zrand.o zrandom.o \
	      -lreadline -lhistory -lncurses -o libcalc.2.14.0.14.dylib
ld: library not found for -lhistory
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [libcalc.2.14.0.14.dylib] Error 1

Last working release without make errors was 2.14.0.10

Seg fault caused by dereferencing null pointer when calculating tan(x) or cot(x)

While sin(x) and cos(x) prompted a "too large argument" error, calculating tan(x) and cot(x) with x being a big complex number led to a crash.

C-style arbitrary precision calculator (version 2.12.6.7)
Calc is open software. For license details type:  help copyright
[Type "exit" to exit, or "help" for help.]

; a=sin(2E9i)
; strerror(a)
    "Too-large im(argument) for sin"
; b=cos(2E9i)
; strerror(b)
    "Too-large im(argument) for cos"
; tan(2E9i)
[1]    24579 segmentation fault  ../calc/calc

; cot(2E9i)
[1]    24771 segmentation fault  ../calc/calc

Re-run with ASAN shows it was a member access within null pointer of type 'struct COMPLEX'

value.c:2343:11: runtime error: member access within null pointer of type 'struct COMPLEX'
ASAN:DEADLYSIGNAL
=================================================================
==25345==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000008 (pc 0x560dbd2c6fbe bp
 0x7ffd4b8373a0 sp 0x7ffd4b837300 T0)
    #0 0x560dbd2c6fbd in testvalue /home/user/Projects/calc/value.c:2343
    #1 0x560dbd2c3041 in divvalue /home/user/Projects/calc/value.c:2109
    #2 0x560dbd18cb4e in f_cot /home/user/Projects/calc/func.c:2319
    #3 0x560dbd1d7bb1 in builtinfunc /home/user/Projects/calc/func.c:9195
    #4 0x560dbd226722 in o_call /home/user/Projects/calc/opcodes.c:2726
    #5 0x560dbd22e7da in calculate /home/user/Projects/calc/opcodes.c:3918
    #6 0x560dbd1622aa in evaluate /home/user/Projects/calc/codegen.c:293
    #7 0x560dbd161f2a in getcommands /home/user/Projects/calc/codegen.c:223
    #8 0x560dbd1600ad in main /home/user/Projects/calc/calc.c:619
    #9 0x7fe1bb87d2e0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202e0)
    #10 0x560dbd15c809 in _start (/home/user/Projects/calc/calc+0x2ae809)

argv in calc script

print version();
argc = argv();
for (i = 0; i < argc; i++) print "argv[": i : '] = "': argv(i) : '"';

When the above calc script is invoked like this:
calc -f test-argv.cal a bb ccc

This is the output:

2.12.7.2
"a" is undefined

Error in commands

When the "-s" option is given after the -f arg, it's correct.
calc -f test-argv.cal -s a bb ccc

2.12.7.2
argv[0] = "a"
argv[1] = "bb"
argv[2] = "ccc"

According to the man page:

   -f
          Use of -f implies -s.

   -s     By default, all calc_cmd args are evaluated and executed.   This
          flag  will disable their evaluation and instead make them avail‐
          able as strings for the argv() builtin function.

I thought that by giving "-f" that "-s" was unnecessary.

Bug: Variable value setting depends on RH source values

Calc bug report template version: 1.2 2022-02-24

Describe the bug
Under different circumstances assigning a value to a variable has different results. If the variable is assigned the value of a list member real integer 2, we get the expected results. But if the same list member is pi, we get a different (wrong) result. Freeing the variable before assignment gives the correct result in both cases.

To Reproduce
See attached file

  1. How you started calc
    In my case calc is embedded in a GUI calculator UI with different "modes", e.g. RPN

  2. Calc commands and their output
    See attached file

    Calc compiles perfectly and nearly always performs perfectly.

  3. Indicate where the problem is
    See attached file, copy/pasted directly from working code.

Expected behavior
See attached file, there are two examples, one working correctly, the other working incorrectly. There's also a work-around that solves the issue under all known circumstances, problem being that according to documentation, work-around should not be required.

Have also brute force work-around, which is approximately:
... user clicks on a visible rpnstack entry, expected behavior is for the internal value of that rpnstack entry to be pushed ...
QString rpn_commands = "";
QString clicked_stack_internal = Trim_Calc_Result(Calc_Evaluate("estr(rpnstack[" + stack_idx + "])"));
... code that modifies rpnstack ...
rpn_commands += "push(rpnstack, " + clicked_stack_internal + ");";
... execute Calc command in rpn_commands ...

Attach make debug output
See attached file.

Screenshots
See attached file

Execution environment (please complete the following information):

  • OS: macOS 11.6.3 and Android version 12, both exhibit same symptoms

  • OS version:
    see above

  • OS distribution:
    macOS Big Sur, Android 12 UI 4.0 Samsung Galaxy Tab S7

  • Calc Version
    Calc 2.12.4.14, searched release notes for 2.14.0.15 without seeing this bug.

  • Shell and shell version
    NA

Calc mods
Calc source has been modified such that all calls to OS services I/O, file system, etc. have been eliminated. This is so that the Calc engine can be embedded as the "micro code" of other applications, e.g. a GUI calculator. This modification has been working correctly at least since Calc 2.12.4.14 was released. The previous version, released 5 years ago can be found here:
https://github.com/kcrossen/APCalculator

What prompted this report is while updating/enhancing APCalculator and porting to Android, more features of Calc were being used that weren't being used previously.

Patch
If you have a recommended code patch to address the problem, please attach your file

Additional context
Calc 2.12.4.14, searched release notes for 2.14.0.15 without seeing this bug.
Error_Report.txt

Makefile.ship missing from the 2.14.0.12 release archive?

It seems that this change e5c8f00#r61722277 introduces a build dep on Makefile.ship, resulting in

  make[1]: *** No rule to make target '../Makefile.ship', needed by 'Makefile.simple'.  Stop.

when trying to build as normal. I'm not using Makefile.simple, so possibly the fix is actually to just remove it from LATE_TARGETS in the main Makefile and TARGETS in custom/Makefile?

Possibly all of this complication suggests that it might be time to consider more modern alternatives to Make altogether.

Enhancement: support hex floats

Hexadecimal floats are a formatting for floating point values supported in C since C99. It shows the mantissa in hex. This is useful because it shows the exact number with no rounding or decimal approximation.

E.g. 0.486224 is 0x1.eff2bp+6.

Use PREFIX (or somethign similar) instead of hard-coding install locations in Makefile

Howdy!

There are a lot of places in the Makefile that refer to /usr/local and the like. It would be neat if most of these were parameterized by a variable that could be passed in (something like PREFIX or what have you.) That way, package maintainers that want to install to a quite different place (to / or to /opt/local or what have you) could avoid needing to patch the Makefile.

Right now, for MacPorts, I maintain a patch file that does a lot of:

 # default LIBDIR for macOS
-LIBDIR= /usr/local/lib
+LIBDIR= ___PREFIX___/lib

type of machinery, followed by a sed pass that changes ___PREFIX___ to an appropriate value for the particular user. This could all be eliminated if instead it read

LIBDIR=${PREFIX}/lib

or some such.

need to tag production class releases

When a tested release has undergo and passed a quorum of qualification procedures by external groups, we
need to add a new tag to such a release.

We need to add a tag of there form:

prod-2.x.y.z to a calc v2 tested release to indicate it is "production" ready.

Enhancement: Document or warn when the numerator is assumed

When doing a division(e.g. 1/2), the provided numerator is used.

However when you don't specify the numerator(e.g. /2), calc assumes the numerator is 1 and process it with that value. I couldn't find documentation if this is a intended change or not as all calculators I've used trowed a error on such expression. Is this intended, or is this a bug?

Great code!

Thanks for open sourcing this, I've been using this for a while now.

Enhancement: Set Ctrl+C to exit if calc is not busy

Interactive calc is an amazing tool I use very often, but I am always annoyed a little bit when I have to exit it. I have to type "quit" every time and documentation is sparse enough that I didn't manage to find a way to make a shortcut for it.

I would like to either have the ability to make a shortcut (ex. "q") for quit, that is automatically loaded whenever I execute calc, or to have Ctrl+C exit the calc. When I hit Ctrl+C I only get the message "ABORT", once. I assume this is helpful when I want to abort some calculation that takes too much time, but when there is clearly nothing to stop, it would be nice to just exit the program. I can't find the main program in the source files, so unfortunatelly, I can't make the change myself and make a pull request.

Separate thousands with comma

Hello,
May I know if there is any way to separate thousands (1000) with comma like 190,988,888 instead of 1909888888?

Engineering mode

First, thanks for the work on calc! It's my go-to calculator for simple and complex stuff.

Would you be open to adding a new output mode? It is usually referred to "engineering mode" and it consists basically in representing the output in scientific notation but only using exponents that are multiples of 3 (which make it easy to translate into SI prefixes).

If so, I can give it a shot at implementing and submitting a PR.

Enhancement: Improve calc Makefiles to work with parallel make

Right now, I have to instruct MacPorts not to do make -jN when building because parallel builds seem to consistently fail during configuration. I'm not sure if you have tested parallel make, but it would be nice (for speed) to be able to remove the restriction that calc be built serially.

For example, on my machine, where -j16 would probably be appropriate, I get errors like:

make[1]: *** No rule to make target `../endian_calc.h', needed by `custtbl.o'.  Stop.

after which everything dies. (Everything is fine if -j16 is omitted by the build system.)

My guess is that there are just a bunch of dependencies on .h files built during configuration that aren't reflected in the make rules.

Zero in power of evaluated zero

; 0^(0)

and

; 0^(2-2)

produce different results, 1 and 0 respectively on calc 2.12.7.1

With other power targets it seems to be fine:

; 5^(0)

and

; 5^(2-2)

Both produce 1.

Bug report: incompatible types in SWAP_HALF_IN_FILEPOS error cause build failure on S390x in 2.14.1.2

Calc bug report template version: 1.3 2022-11-27

Describe the bug

While updating to the latest package, I ran into a build error on S390x. Specifically:

D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1  -m64 -march=z13 -mtune=z14 -fasynchronous-unwind-tables -fstack-clash-protection -Wno-error=long-long -Wno-long-long -c file.c
In file included from file.c:44:
file.c: In function 'filepos2z':
fposval.h:46:60: error: incompatible types when assigning to type 'HALF' {aka 'unsigned int'} from type 'FILEPOS' {aka 'fpos_t'}
   46 | #define SWAP_HALF_IN_FILEPOS(dest, src)         (*(dest) = *(src))
      |                                                            ^
file.c:1391:9: note: in expansion of macro 'SWAP_HALF_IN_FILEPOS'
 1391 |         SWAP_HALF_IN_FILEPOS(ret.v, &pos);
      |         ^~~~~~~~~~~~~~~~~~~~
make: *** [Makefile:2688: file.o] Error 1

Since SWAP_HALF_IN_FILEPOS was changed in this release, I assume this is new....

To Reproduce

Probably just "try to build on S390x". Certainly "try to build with the buildflags, etc., that Fedora uses".

Expected behavior

Build success

Attach debug.out

Not applicable, but see full build logs at:

https://koji.fedoraproject.org/koji/taskinfo?taskID=94836528

and specifically

https://kojipkgs.fedoraproject.org//work/tasks/6638/94836638/build.log

slight issue building 2.14.0.0 on MacOS

I often diff the resulting files on old and new versions of a package for MacPorts. We seem to be missing the dylib symlinks you normally get on a mac now. No idea why.

-/opt/local/lib/libcalc.2.13.0.1.dylib
-/opt/local/lib/libcalc.dylib
-/opt/local/lib/libcustcalc.2.13.0.1.dylib
-/opt/local/lib/libcustcalc.dylib
+/opt/local/lib/libcalc.2.14.0.0.dylib
+/opt/local/lib/libcustcalc.2.14.0.0.dylib

Note that before libcalc.dylib was a symlink to libcalc.2.13.0.1.dylib; beats me why these symlinks are now missing.

Bug: calc doesn't compile with musl libc

Calc bug report template version: 1.2 2022-02-24

Describe the bug
I tried to install calc on my gentoo. Build failed, I notice a long-standing bug:
https://bugs.gentoo.org/717694
So I downloaded the latest calc from master and tried to compile. It failed the same way.

To Reproduce
Download the latest git variant of calc (3e4391e), make.
There is an error:

file.c: In function 'filepos2z':
fposval.h:16:54: error: 'FPOS_POS_LEN' undeclared (first use in this function); did you mean 'FILEPOS_LEN'?
   16 |         memcpy((void *)(dest), (void *)(src), sizeof(FPOS_POS_LEN))
      |                                                      ^~~~~~~~~~~~
file.c:1391:9: note: in expansion of macro 'SWAP_HALF_IN_FILEPOS'
 1391 |         SWAP_HALF_IN_FILEPOS(ret.v, &pos);
      |         ^~~~~~~~~~~~~~~~~~~~
fposval.h:16:54: note: each undeclared identifier is reported only once for each function it appears in
   16 |         memcpy((void *)(dest), (void *)(src), sizeof(FPOS_POS_LEN))
      |                                                      ^~~~~~~~~~~~
file.c:1391:9: note: in expansion of macro 'SWAP_HALF_IN_FILEPOS'
 1391 |         SWAP_HALF_IN_FILEPOS(ret.v, &pos);
      |         ^~~~~~~~~~~~~~~~~~~~
file.c: In function 'z2filepos':
file.c:1462:67: error: expected ')' before ';' token
 1462 |                 memcpy(&tmp, zpos.v, MIN(sizeof(tmp), FILEPOS_LEN);
      |                       ~                                           ^
file.c:1462:68: error: expected ';' before '}' token
 1462 |                 memcpy(&tmp, zpos.v, MIN(sizeof(tmp), FILEPOS_LEN);
      |                                                                    ^
      |                                                                    ;
 1463 |         } else {
      |         ~
file.c:60:24: warning: comparison of integer expressions of different signedness: 'long unsigned int' and 'int' [-Wsign-compare]
   60 | #define MIN(a,b) (((a) <= (b)) ? (a) : (b))
      |                        ^~
file.c:1466:38: note: in expansion of macro 'MIN'
 1466 |                 memcpy(&tmp, zpos.v, MIN(sizeof(tmp),
      |                                      ^~~
file.c:60:40: warning: operand of '?:' changes signedness from 'int' to 'long unsigned int' due to unsignedness of other operand [-Wsign-compare]
   60 | #define MIN(a,b) (((a) <= (b)) ? (a) : (b))
      |                                        ^~~
file.c:1466:38: note: in expansion of macro 'MIN'
 1466 |                 memcpy(&tmp, zpos.v, MIN(sizeof(tmp),
      |                                      ^~~
In file included from file.c:44:
fposval.h:16:54: error: 'FPOS_POS_LEN' undeclared (first use in this function); did you mean 'FILEPOS_LEN'?
   16 |         memcpy((void *)(dest), (void *)(src), sizeof(FPOS_POS_LEN))
      |                                                      ^~~~~~~~~~~~
file.c:1470:9: note: in expansion of macro 'SWAP_HALF_IN_FILEPOS'
 1470 |         SWAP_HALF_IN_FILEPOS(&ret, &tmp);
      |         ^~~~~~~~~~~~~~~~~~~~
make: *** [Makefile:2688: file.o] Error 1

Execution environment (please complete the following information):

  • OS:
    Gentoo Linux with musl and clang

  • Calc Version
    3e4391e

2.12.9.0: typo in help/Makefile crashes the build

hi

there is a question/questions typo in help/Makefile which makes the
build of 2.12.9.0 (cloned from github) fail for me

This fixes things:

----8<----
diff -c help/Makefile.FIX_QUESTIONS help/Makefile
*** help/Makefile.FIX_QUESTIONS	Fri Mar 12 16:09:50 2021
--- help/Makefile	Fri Mar 12 16:09:50 2021
***************
*** 252,258 ****

  STD_HELP_FILES_14= credit

! BLT_HELP_FILES_14= contrib COPYING COPYING-LGPL question

  STD_HELP_FILES_15= wishlist todo

--- 252,258 ----

  STD_HELP_FILES_14= credit

! BLT_HELP_FILES_14= contrib COPYING COPYING-LGPL questions

  STD_HELP_FILES_15= wishlist todo

***************
*** 536,542 ****
            ${TRUE}; \
        fi

! question: ../QUESTIONS
        ${RM} -f $@
        ${CP} ../QUESTIONS $@
        ${CHMOD} 0444 $@
--- 536,542 ----
            ${TRUE}; \
        fi

! questions: ../QUESTIONS
        ${RM} -f $@
        ${CP} ../QUESTIONS $@
        ${CHMOD} 0444 $@
***************
*** 705,711 ****
                 ! -name mat ! -name obj.file ! -name operator \
                 ! -name overview ! -name script ! -name statement \
                 ! -name todo ! -name types ! -name unexpected \
! 		 ! -name variable ! -name wishlist ! -name question \
                 -print | \
           while read i; do \
                if [ X"$$i" != X"/dev/null" ]; then \
--- 705,711 ----
                 ! -name mat ! -name obj.file ! -name operator \
                 ! -name overview ! -name script ! -name statement \
                 ! -name todo ! -name types ! -name unexpected \
! 		 ! -name variable ! -name wishlist ! -name questions \
                 -print | \
           while read i; do \
                if [ X"$$i" != X"/dev/null" ]; then \
***************
*** 740,746 ****

  clean:
        ${RM} -f obj mkbuiltin funclist.c funclist.o funclist${EXT}
! 	${RM} -f COPYING COPYING-LGPL question

  clobber: clean
        ${RM} -f ${BLT_HELP_FILES} full .all calc
--- 740,746 ----

  clean:
        ${RM} -f obj mkbuiltin funclist.c funclist.o funclist${EXT}
! 	${RM} -f COPYING COPYING-LGPL questions

  clobber: clean
        ${RM} -f ${BLT_HELP_FILES} full .all calc
---->8----

thanks for your valuable work

ciao

-gabriele

Cannot configure location of ~/.calc_history

While the locations of ~/.cal and ~/.calcrc/~/.calcinit can be changed (via CALCPATH and CALCRC, respectively), ~/.calc_history has a fixed location. It would be nice if this could be configured in the environment as well — perhaps CALCHISTFILE, similar to the existing LESSHISTFILE for less.

lib_calc.c requires CUSTOM

HI,
version 2.12.8.0/1, commit 91991bb introduced code which relies in CUSTOM to be set:

gcc  -DCALC_SRC -UCUSTOM -Wall  -march=native   -fPIC -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=pentium4 -fasync
hronous-unwind-tables   -c -o lib_calc.o lib_calc.c                                                                                                                                   
lib_calc.c: In function 'initenv':                                                                                                                                                    
lib_calc.c:573: error: 'CUSTOMHELPDIR' undeclared (first use in this function)                                                                                                        
lib_calc.c:573: error: (Each undeclared identifier is reported only once                                                                                                              
lib_calc.c:573: error: for each function it appears in.)                                                                                                                              
make: *** [lib_calc.o] Error 1                                                                                                                                                        

For it to compile without CUSTOM, the block of code beginning at

calc/lib_calc.c

Line 568 in 91991bb

/* determine the $CALCCUSTOMHELP value */
needs to be protected by #if defined(CUSTOM).

I won't create a PR for a simple fix - here's my patch:

--- calc-2.12.8.1/lib_calc.c    2021-02-13 01:06:04.000000000 +0100
+++ calc-2.12.8.1-nocustom/lib_calc.c   2021-02-20 13:03:07.000000000 +0100
@@ -565,6 +565,7 @@
                calc_helpdir = HELPDIR;
        }
 
+#if defined(CUSTOM)
        /* determine the $CALCCUSTOMHELP value */
        c = (no_env ? NULL : getenv(CALCCUSTOMHELP));
        calc_customhelpdir = (c ? strdup(c) : NULL);
@@ -572,6 +573,7 @@
                /* will use /usr/local/share/calc/custhelp */
                calc_customhelpdir = CUSTOMHELPDIR;
        }
+#endif
 }

"Works for me." Thanks.

Conflicting types for memmove on OS X Big Sur

When building calc v2.12.7.1 on OS X Big Sur with conflicting type errors are raised.

Compile steps:

$ tar jxvf ../calc-2.12.7.1.tar.bz2
$ cd calc-2.12.7.1
$ make target=Darwin clobber
$ make target=Darwin all
forming have_unistd.h
have_unistd.h formed
forming have_stdlib.h
have_stdlib.h formed
clang -DCALC_SRC -DCUSTOM -Wall    -fPIC longbits.c -c
rm -f longbits
clang -DCALC_SRC -DCUSTOM -Wall    -fPIC longbits.o -o longbits
forming longbits.h
longbits.h formed
forming align32.h
align32.h formed
forming have_string.h
have_string.h formed
forming args.h
args.h formed
forming calcerr.h
calcerr.h formed
forming conf.h
conf.h formed
clang -DCALC_SRC -DCUSTOM -Wall    -fPIC  endian.c -c
rm -f endian
clang -DCALC_SRC -DCUSTOM -Wall    -fPIC endian.o -o endian
forming endian_calc.h
endian_calc.h formed
forming have_fpos.h
have_fpos.h formed
forming have_posscl.h
have_posscl.h formed
forming have_fpos_pos.h
have_fpos_pos.h formed
forming have_offscl.h
have_offscl.h formed
forming fposval.h
fposval.h formed
forming have_const.h
have_const.h formed
forming have_memmv.h
have_memmv.h formed
forming have_newstr.h
have_newstr.h formed
forming have_times.h
have_times.h formed
forming have_uid_t.h
have_uid_t.h formed
forming terminal.h
terminal.h formed
forming have_ustat.h
have_ustat.h formed
forming have_getsid.h
have_getsid.h formed
forming have_getpgid.h
have_getpgid.h formed
forming have_gettime.h
have_gettime.h formed
forming have_getprid.h
have_getprid.h formed
forming have_urandom.h
have_urandom.h formed
forming have_rusage.h
have_rusage.h formed
forming have_strdup.h
have_strdup.h formed
forming have_unused.h
have_unused.h formed
forming calcerr.c
calcerr.c formed
rm -f custom/.all
cd custom; make -f Makefile ALLOW_CUSTOM="-DCUSTOM" AR=ar AWK=awk BINDIR="/usr/local/bin" BLD_TYPE="calc-dynamic-only" CALC_INCDIR="/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.0.sdk/usr/include/calc" CALC_SHAREDIR="/usr/local/share/calc" CAT=cat CC=" clang " CCERR="" CCMISC="" CCOPT="-O3 -g3" CCWARN="-Wall" CC_SHARE="-fPIC" CFLAGS="-DCALC_SRC -DCUSTOM -Wall    -fPIC -O3 -g3 -I.." CHMOD=chmod CMP=cmp CO=co COMMON_ADD="" COMMON_CFLAGS="-DCALC_SRC -DCUSTOM -Wall    -I.." COMMON_LDFLAGS=" " CP=cp CUSTOMCALDIR="/usr/local/share/calc/custom" CUSTOMHELPDIR="/usr/local/share/calc/custhelp" CUSTOMINCDIR="/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.0.sdk/usr/include/calc/custom" DEBUG="-O3 -g3" DEFAULT_LIB_INSTALL_PATH="/Users/mar/build/unpack/calc-2.12.7.1:/usr/local/lib:/usr/local/lib" FMT=fmt GREP=egrep HELPDIR="/usr/local/share/calc/help" ICFLAGS="-DCALC_SRC -DCUSTOM -Wall    -fPIC -I.." ILDFLAGS=" " INCDIR="/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.0.sdk/usr/include" LANG=C LCC="clang" LDCONFIG= LDFLAGS="  " LD_SHARE="" LIBCUSTCALC_SHLIB="-single_module -undefined dynamic_lookup -dynamiclib -install_name /usr/local/lib/libcustcalc.2.12.7.1.dylib " LIBDIR="/usr/local/lib" LN=ln MAKE=make MAKEDEPEND=makedepend MAKE_FILE=Makefile MKDIR=mkdir MV=mv PURIFY="" Q="@" RANLIB="ranlib" RM=rm RMDIR=rmdir SCRIPTDIR="/usr/local/bin/cscript" SED=sed SORT=sort T= TOP_MAKE_FILE=Makefile TOUCH=touch TRUE=true VERSION=2.12.7.1 target=Darwin all
clang  -DCALC_SRC -DCUSTOM -Wall    -fPIC -O3 -g3 -I..   -c -o custtbl.o custtbl.c
In file included from custtbl.c:30:
In file included from ../value.h:33:
In file included from ../cmath.h:32:
In file included from ../qmath.h:32:
In file included from ../zmath.h:39:
../alloc.h:88:14: error: expected parameter declarator
E_FUNC void *memmove(void *s1, CONST void *s2, MEMMOVE_SIZE_T n);
             ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/secure/_string.h:70:47: note: 
      expanded from macro 'memmove'
                __builtin___memmove_chk (dest, __VA_ARGS__, __darwin_obs...
                                                            ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/secure/_common.h:38:63: note: 
      expanded from macro '__darwin_obsz0'
#define __darwin_obsz0(object) __builtin_object_size (object, 0)
                                                              ^
In file included from custtbl.c:30:
In file included from ../value.h:33:
In file included from ../cmath.h:32:
In file included from ../qmath.h:32:
In file included from ../zmath.h:39:
../alloc.h:88:14: error: expected ')'
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/secure/_string.h:70:47: note: 
      expanded from macro 'memmove'
                __builtin___memmove_chk (dest, __VA_ARGS__, __darwin_obs...
                                                            ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/secure/_common.h:38:63: note: 
      expanded from macro '__darwin_obsz0'
#define __darwin_obsz0(object) __builtin_object_size (object, 0)
                                                              ^
../alloc.h:88:14: note: to match this '('
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/secure/_string.h:70:47: note: 
      expanded from macro 'memmove'
                __builtin___memmove_chk (dest, __VA_ARGS__, __darwin_obs...
                                                            ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/secure/_common.h:38:54: note: 
      expanded from macro '__darwin_obsz0'
#define __darwin_obsz0(object) __builtin_object_size (object, 0)
                                                     ^
In file included from custtbl.c:30:
In file included from ../value.h:33:
In file included from ../cmath.h:32:
In file included from ../qmath.h:32:
In file included from ../zmath.h:39:
../alloc.h:88:14: warning: type specifier missing, defaults to 'int'
      [-Wimplicit-int]
E_FUNC void *memmove(void *s1, CONST void *s2, MEMMOVE_SIZE_T n);
             ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/secure/_string.h:70:47: note: 
      expanded from macro 'memmove'
                __builtin___memmove_chk (dest, __VA_ARGS__, __darwin_obs...
                                                            ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/secure/_common.h:38:32: note: 
      expanded from macro '__darwin_obsz0'
#define __darwin_obsz0(object) __builtin_object_size (object, 0)
                               ^
In file included from custtbl.c:30:
In file included from ../value.h:33:
In file included from ../cmath.h:32:
In file included from ../qmath.h:32:
In file included from ../zmath.h:39:
../alloc.h:88:14: error: conflicting types for '__builtin___memmove_chk'
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/secure/_string.h:70:3: note: 
      expanded from macro 'memmove'
                __builtin___memmove_chk (dest, __VA_ARGS__, __darwin_obs...
                ^
../alloc.h:88:14: note: '__builtin___memmove_chk' is a builtin with type 'void
      *(void *, const void *, unsigned long, unsigned long)'
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/secure/_string.h:70:3: note: 
      expanded from macro 'memmove'
                __builtin___memmove_chk (dest, __VA_ARGS__, __darwin_obs...
                ^
1 warning and 3 errors generated.
make[1]: *** [custtbl.o] Error 1
make: *** [custom/.all] Error 2

Feature request: prebuilt packages

Not anyone has a compiler installed. Most people just want to be able to use the tool without the headache of building it.
Consider offering prebuilt packages for Linux/Windows/MacOS ?

Note that Github actions allow to create these builds automatically.

Allow Makefile customizations in one place

Because specifying settings requires patching Makefile.ship extensively, updating calc is non-trivial for maintainers of package spec files (I maintain FreeBSD's port).

If Makefile.ship could be trained to source a file (such as Makefile.local) to overwrite defaults, it'd allow definitions in one place and make maintaining calc much simpler.

Is this something you'd be interested in?

Automation broken by release URL for 2.18.8.2

Howdy! The source artifacts for 2.18.8.2 are located in

https://github.com/lcn2/calc/releases/download/v2.12.8.2/calc-2.12.8.2.tar.bz2

If it followed the pattern of the previous releases, it would be in:

https://github.com/lcn2/calc/releases/download/2.12.8.2/calc-2.12.8.2.tar.bz2

(Note the lack of the v in the second URL.)

I suspect that there was some git tag issue that caused this. It's helpful for downstream distributions using heavy automation if the pattern remains pretty consistent over time because we tend to have automated machinery to which we just feed a new version number.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.