The following are the changes from calc version 2.12.3.0 to date:

    Fixed the Jacobi function where it returned 1 when it should have
    returned 0.  Thanks goes to Kevin Sopp (baraclese at googlemail dot com)
    for discovering the problem and suggesting the nature if the fix.

    Calc versions will always be of the form x.y.z.w even when the
    MINOR_PATCH (w) is 0.  Thus, 2.12.3.0 will be printed as 2.12.3.0
    instread of just 2.12.3.

    Added MINGW32_NT-5.0 compile target based on a patch from
    Brian L. Angus (angus at eng dot utah dot edu).

    Removed the use of rpm.release in the Makefile.

    Mac OS Darwin targets no longer attempt to use ldconfig.  Under the
    Darwin target, the LDCONFIG make variable is redefined to be
    an empty value.  Thanks goes to Ralf Trinler (art at infra dot de)
    for reporting this problem.

    The ${CALC_INCDIR}/custom is no longer being removed at install time
    if it is empty.  Now when ${ALLOW_CUSTOM} make variable is empty,
    an empty ${CALC_INCDIR}/custom may be left hehind.

    Fixed a problem where a "make clobber" would remove custom/Makefile
    and fail to rebuilt it.


The following are the changes from calc version 2.12.2.3 to 2.12.2.4:

    Added OpenBSD target.

    Using the -r test instead of the -e test in Makefiles because some
    out of date shells still do not have the -e test.

    The Makefile now avoids the use of if ! command because some out of
    date shells to not support the ! construct.


The following are the changes from calc version 2.12.1.1 to 2.12.2.2:

    Added an explicit Solaris target.

    Fixed confusion in Makefile where some uses of ${EXT} were misnamed ${EXE}.

    Added a "make strip" rule, per suggestion from Igor Furlan <primorec
    at sbcglobal dot net>, to allow one to strip previously built binary
    executables and libraries.

    Under the Darwin / OS X target, ${DARWIN_ARCH} is left empty meaning
    that calc is compiled for the native CPU type instead of Universal
    Binary (Intel and PPC).

    By default, the calc binary that is built for the rpm forces
    ${LD_SHARE} to be empty.  An empty ${LD_SHARE} means that the calc
    from the rpm does not set rpath.  This in turn causes the default
    system path to be searched when looking for libcalc and libcustcalc.

    The Makefile shipped with calc still sets ${LD_SHARE} for host targets.
    By default, the dynamic shared library search path for all targets
    starts with the source directory.  Starting the search in the source
    directory is convenient for testing and debugging but is not appropriate
    for installation on a production system.  To get the same effect
    as the calc binary in the calc rpm, try:

	make clobber
	make calc-dynamic-only BLD_TYPE=calc-dynamic-only LD_SHARE=
	make install

    The libcalc and libcustcalc shared libraries are now tied to
    the 4 level calc version instead of just 3 levels.  For example,
    under Linux calc version 2.12.2.1 uses /usr/lib/libcalc.so.2.12.2.1
    instead of just the /usr/lib/libcalc.so.2.12.2 file.  This change
    was made so that calc produced by 'make clobber; make all install'
    is consistent with the calc rpm.

    Calc is now releasing the calc-debuginfo rpm for those RPM users who
    which to use non-stripped libraries and binaries for debugging
    purposes.  By default, the calc rpm installed stripped binaries
    and libraries.

    Added this high priority item to the calc help/todo list:

	It is overkill to have nearly everything wind up in libcalc.
	Form a libcalcmath and a libcalclang so that an application
	that just wants to link with the calc math libs can use them
	without dragging in all of the other calc language, I/O,
	and builtin functions.

    Fixed the wording for the -i flag in the calc man page.

    Added some notes to the help/unexpected file regarding calc
    and interactice shells.

    Fixed bug where a FILEPOS was copied FPOS_POS_BITS octets instead of
    FPOS_POS_LEN octets.

    Split out ${READLINE_EXTRAS} Makefile variables from ${READLINE_LIB}
    to better deal with Fedora rpm requirements.

    Bit 8 (0x80) of calc_debug is reserved for custom debugging.
    See help/config and custom/HOW_TO_ADD for details.

    When the Makefile variable ${ALLOW_CUSTOM} is not defined or empty,
    the libcustcalc library is not built or linked against, certain make
    rules skip going into the custom sub-directory, the install
    rule skips certain custom installation actions, and the common
    C flags (${COMMON_CFLAGS}) is given -UCUSTOM.  Other make rules such
    as "make clean" and "make clobber" still work as before.  Also
    the Makefile.simple assumes that the Makefile variable ${ALLOW_CUSTOM}
    is -DCUSTOM.

    Clarified that the calc builtin functions rand() and random()
    operate over a half closed interval.  The help/rand and help/random
    refer to  the top of the interval as "beyond" instead of "max".

    Releaseing source tar balls using bzip2 instead of with gzip.  So
    what was calc-something.tar.gz is now calc-something.tar.bz2.
    To "uncompress" use:

    	bunzip2 calc-something.tar.bz2

    On some systems, one may untar directly by:

	tar -jxvf calc-something.tar.bz2

   The Makefile variable ${BYTE_ORDER} was replaced by ${CALC_BYTE_ORDER}.

   Changed the way the Makefile can force the calc byte order.  If you set
   the Makefile variable ${CALC_BYTE_ORDER} to be -DCALC_BIG_ENDIAN then
   endian.h will force the CPP symbol CALC_BYTE_ORDER to be BIG_ENDIAN.
   If you set ${CALC_BYTE_ORDER} to be -DCALC_LITTLE_ENDIAN then endian.h
   will force the CPP symbol CALC_BYTE_ORDER to be LITTLE_ENDIAN.
   If the Makefile variable ${CALC_BYTE_ORDER} is empty, then the CPP
   symbol CALC_BYTE_ORDER will set to the CPP symbol BYTE_ORDER as
   defined by some system include file (if the Makefile can find such
   an include file), or the Makefile compiling endian.c and hopefully
   using that result to set CPP symbol CALC_BYTE_ORDER.  Regardless of
   how it happens, the CPP symbol CALC_BYTE_ORDER should end up set in
   endian_calc.h include file.


The following are the changes from calc version 2.12.1.10 to 2.12.2:

    Put back the missing -s flags on the cscripts:  mersenne, 4dsphere,
    fprodcut, plus, and powerterm.  Thanks goes to Bradley Reed
    <bradreed1 at gmail dot com> for discovering this problem.

    All static variables are now declared with the symbol STATIC.
    All extern variables are now declared with the symbol EXTERN.
    All static functions are now declared with the symbol S_FUNC.
    All extern functions are now declared with the symbol E_FUNC.
    The include file decl.h defines these 4 symbols by default
    to static, extern, static, and extern respectively.  Under
    Windoz, DLL is also defined according to the _EXPORTING symbol
    and is prepended to the EXTERN and E_FUNC symbols.  The decl.h
    file has replaced the win32dll.h file.

    When WITH_TLS is defined, calc attempts to compile with Thread Local
    Storage.  As of version 2.12.1.12 this mode is extremely experimental.
    Calc may not compile when WITH_TLS defined.

    Fixed E_FUNC vs EXTERN issues discovered by Mirko Viviani
    <mirko at objectlab dot org>.

    Removed include of <malloc.h>.  The building of the include file
    "have_malloc.h" has been removed from the Makefile.  One some
    systems such as FreeBSD, the file /usr/include/malloc.h exists
    and contains an forced error saying that stdlib.h should be used
    instead.  The Makefile symbol HAVE_MALLOC has been removed.

    Moved the sample code in the sample sub-directory up into the
    main source level.  The sample/many_random.c source file is
    now sample_many.c.  The sample/test_random.c source file is now
    sample_rand.c.  The sample Makefile and the sub-directory is no more.

    Renamed the following source files:

	math_error.h		==>    lib_calc.h
	string.c		==>    str.c
	string.h		==>    str.h

    Renamed the following variables related to calc error processing:

	int calc_jmp		==>    int calc_use_matherr_jmpbuf
    	jmp_buf calc_jmp_buf	==>    jmp_buf calc_matherr_jmpbuf

	int post_init		==>    int calc_use_scanerr_jmpbuf
	jmp_buf jmpbuf		==>    jmpbuf calc_scanerr_jmpbuf

	char *calc_error	==>    char calc_err_msg[MAXERROR+1]

    These values are now declared in the lib_calc.h include file.
    The value MAXERROR is now defined in lib_calc.h instead of calc.h.
    The calc_err_msg[] buffer is now used for math errors as well
    as scan and parse errors.

    Parse/scan errors will not be printed if calc_print_scanerr_msg
    is zero.  By default:

    	int calc_print_scanerr_msg = 1;

    This variable is declared in the lib_calc.h include file.  Storage
    comes from libcalc.

    Parse/scan warnings will not be printed if calc_print_scanwarn_msg
    is zero.  By default:

    	int calc_print_scanwarn_msg = 1;

    This variable is declared in the lib_calc.h include file.  Storage
    comes from libcalc.

    The last parse/scan error message is stored in the calc_err_msg[]
    buffer.  This happens even when calc_print_scanerr_msg is zero.

    The last parse/scan warning message is stored in the calc_warn_msg[]
    buffer.  After each parse/scan warning condition is detected,
    the value calc_warn_cnt is incremented.  This happens even when
    calc_print_scanwarn_msg is zero.

    The calc_warn_msg[] buffer and calc_warn_cnt variables are declared
    in the lib_calc.h include file.  Storage comes from libcalc.

    See the file, LIBRARY or use the calc command "help libcalc" for
    more information on calc error processing.  This file has been
    updated to reflect the changes noted above in this section.

    The make install rule removes std_arg.h, have_malloc.h, math_error.h,
    string.h, and win32dll.h from ${INCDIR} if they exist.  These calc
    include files are no longer supported.

    Do reduce the number of special case .o build rules, the
    ${ALLOW_CUSTOM} make flag is added to ${CFLAGS} by default.  This means
    that if ALLOW_CUSTOM= -DCUSTOM, then -DCUSTOM is given to the compile
    line of most .c files.

    Calc -v reports "w/custom functions" or "w/o custom functions" on
    the version string depending on if calc was compiled with the
    ALLOW_CUSTOM= -DCUSTOM or not.

    Replaced the concept of compiler sets in the Makefile with
    host target section in the Makefile.  Initial host targets are:

    	Linux
	Darwin
	FreeBSD
	(default)	<<== Target does not match any previous target name
	Simple

    	NOTE: If your target is not supported below and the default target
	      is not suitable for your needs, please send to the:

	      	calc-contrib at asthe dot com

	      EMail address an "ifeq ($(target),YOUR_TARGET_NAME)"
	      ... "endif" set of lines from the Makefile so that
	      we can consider them for the next release.

    The custom/Makefile is now constructed from 3 parts: custom/Makefile.head,
    the host target section in Makefile, and the custom/Makefile.tail.

    The top level Makefile and the custom/Makefile require a GNU Make
    (such as gmake) or an equivalently advanced make.  On many targets,
    the default make is sufficient.  On FreeBSD for example, one must
    use gmake instead of make.

    If your target system does not have GNU Make (or equivalent), then
    you should try using the Makefile.simple and custom/Makefile.simple
    files:

	mv Makefile Makefile.gmake
	cp Makefile.simple Makefile
	mv custom/Makefile custom/Makefile.gmake
	cp custom/Makefile.simple custom/Makefile
	make all

    Added the ability to build calc with dynamic libraries, static
    libraries or both.  Many thanks goes to Matthew Miller (mattdm
    at mattdm dot org) and Mirko Viviani (mirko at objectlab dot
    org) for this help, encouragement, and testing of this major change!

    Added BLD_TYPE Makefile variable to control how calc is
    built.  The BLD_TYPE value may be one of:

	BLD_TYPE= calc-dynamic-only
	BLD_TYPE= calc-static-only

    Each host target establishes a default BLD_TYPE value.  Of course
    one can override the host target BLD_TYPE on the make command line:

	make clobber
	make calc-dynamic-only BLD_TYPE=calc-dynamic-only

	make clobber
	make calc-static-only BLD_TYPE=calc-static-only

	NOTE: It is a very good idea to first clobber (remove) any previously
	      built .o, libs and executables before switching the build
	      between static and dynamic.

    which have the same effect as make all with a given build phase set.

    For Linux and Darwin, the default BLD_TYPE is calc-dynamic-only.
    For the simple case, BLD_TYPE is calc-static-only.  For the
    default target (the target does not match any of the previous
    defined targets), BLD_TYPE is calc-static-only.

    Added ${CSFLAGS} make variable to hold the {$CC} flags for compiling
    without shared library.  By default, ${CFLAGS} is ${CSFLAGS} with
    ${CC_SHARE} added to it.

    Added ${CC_SHARE}, ${LIBCALC_SHLIB}, ${LIBCUSTCALC_SHLIB}, and
    ${LD_SHARE} to the remaining compiler sets.

    Fixed make depend and make uninstall rules.   Performed various
    makefile syntax cleanups.

    Removed ${PROGS} and ${STATIC_PROGS} Makefile variables due to
    the new BLD_TYPE system (see above).

    Added missing help for cp, calcpath, and stoponerror.

    Noted that calc fails the regression test (and will crash at
    various times) when compiled with gcc v4.1.0.  This problem was
    first reported under Fedora Core 5 by Christian Siebert.

    Set the LESSCHARSET to iso8859 so that less will not confuse or
    upset the col utility with Invalid or incomplete multi-byte or wide
    characters.

    Updated the Free Software Foundation postal address and updated
    the COPYING-LGPL from http://www.fsf.org/licensing/licenses/lgpl.txt
    on 2007-Mar-14.  Calc is using the same Version 2.1 of the LGPL,
    only the postal address of the Free Software Foundation has
    been updated.  All source files were updated to RCS level 30.
    Thanks goes to Martin Buck (m at rtin-buck dor de) for this patch.

    Added printf arg checking for GNU C compilers that helps check
    printf-style functions in calc.  Thanks goes to Martin Buck (m at
    rtin-buck dor de) for this patch.

    Fixed issues where the argument of a printf-like did not match the
    format type.

    Removed build function md5().  The MD5 hash has been compromised to
    such a degree that is it no longer advisable to use this function.

    Removed build function sha().  The SHA hash has been compromised to
    such a degree that is it no longer advisable to use this function.
    Note that the SHA-1 hash has not been compromised to the same degree
    and so this hash function remains.

    Renamed shs1.c to sha1.c.  Renamed shs1.h to sha1.h.

    Added custom registers.  The custom register function:

	custom("register", 3)

    returns the value of custom register 3.  Custom registers, initialized
    with 0, may take on any calc value:

	custom("register", regnum, value)

    Added REGNUM_MAX to the sysinfo custom function to return the maximum
    register number:

	custom("sysinfo", "REGNUM_MAX")

    which defaults to 31.  The first custom register is 0 and thus the
    default number of custom registers is 32.

    Added E_OK #define in calc.h to indicate no error (0).

    Renamed C function powivalue() in value.c to powvalue() because it
    now handles raising NUMBER or COMPLEX to a NUMBER or COMPLEX power.

    The powervalue() function in value.c may be given a NULL epsilon
    which will cause to the builtin epsilon value to be used.

    Calc supports both real and complex exponentiation bases and exponents.
    For a ^ b and a ** b, "a" and "b" can be a real value or a complex value:

        2^3                     3i^4
	2.5 ^ 3.5               0.5i ^ 0.25
	2.5 ^ 2.718i            3.13145i ^ 0.30103i

    Fixed typos in the calc man page thanks to a Debian bug report
    by A. Costa <agcosta at gis dot .net> that wsa kindly forwarded
    to us by Martin Buck <m at rtin-buck dot de>.


The following are the changes from calc version 2.12.1.8 to 2.12.1.9:

    Fixed calc cscripts that contained comments that were not valid calc
    comments.  Improved calc comment documentation in "help unexpected"
    to help other avoid similar mistakes.  Calc comments are of the form:

    	/* c style comments */
	/*
	 * multi-line
	 * comments
	 */
	## two or more #-signs
	### in a row
	### Note that # along is a calc unary and binary operator

    Added "help pound" or "help #' to document the # operator, comments,
    and the first line of cscript files.

    Documented these help commands in "help help":

    	help ->
	help *
	help .
	help %
	help //
	help #

    The usage help file is now formed from the contents of the calc man page.
    So "help usage" prints the version of the calc man page.  Added ${COL}
    makefile symbol to support the formation of the calc.usage file from
    calc.1 via the CALCPAGER (less) or NROFF (if NROFF is non-empty).

    The "help calc" command is now equivalent to "help help".

    The "help define" command is now equivalent to "help command".

    Fixed calc command line usage message.

    Fixed missing README.src file in RPM src and tgz src tarball.

    Removed HAVE_SNPRINTF test in version.c.  We now assume that
    all systems come with the standard snprintf() library function.

    Make does not assume that DONT_HAVE_VSPRINTF must be defined in
    order to test for varargs (via have_varvs.c).  Instead it uses the
    ${HAVE_VSPRINTF} to determine if the vsprintf() and vsnprintf()
    should be tested to assumed to exist or not exist.

    Tests for the existence of vsprintf() now also require the existence
    of vsnprintf().  Test for the existence of vsnprintf() now also
    require the existence of vsprintf().

    The #define CALC_SIZE_T was never used except when memmove() was
    not found.  This symbol was renamed to MEMMOVE_SIZE_T.  Calc
    requires that size_t must be a known type.

    Calc and cscripts are installed mode 0755 instead of 0555 to
    make rpmlint happy.

    Make clobber cleanup as suggested by Martin Buck <m at rtin-buck dot de>.
    The clobber rule now depends on the clean rule.


The following are the changes from calc version 2.12.1.6 to 2.12.1.7:

    Added the calc builtin function, usertime(), to return the amount of
    user CPU time used by the current process.  Unlike the old runtime()
    builtin, the CPU time reported for long running processes will not
    wrap around to 0 after only a few months.

    Added the calc built0in function, systime(), to return the amount of
    kernel CPU time used by the current process.

    The runtime() builtin function now returns the total amount of CPU
    time used by the current process.  This time includes both user mode
    and kernel mode time.  Unlike the old runtime() builtin, the builtin
    includes time spent executing operating system code on behalf of
    the current process.

    Fixed runtime() so that the CPU time reported for long running
    processes will wrap around to 0 for a long time.

    Added config("hz") to return the clock tick rate.  This is
    a read-only configuration value.

    Added regression tests for recently added config() parameters.

    Fixed the #define symbols that were created in have_strdup.h.
    Previously this file looked as if have_rusage.h has been
    included already.

    Restored the function of "help" (without any args) printing the
    default help file.  Thanks for this fix goes to Silvan Minghetti
    <bullet at users dot sourceforge dot net>.

    Fixed a problem where some old MS environments failed some of the
    regression tests because "read -once foo.cal" was not behaving
    correctly due to how the _fullpath() was being called.  Thanks for
    this fix goes to Anatoly <notexistent-anb at yandex dot ru>.

    Documented the mis-feature about how calc parses if, for, while
    and do statements in an unexpected way.   For example:

	This works as expected:

	    if (expr) {
		...
	    }

	However this WILL NOT WORK AS EXPECTED:

	    if (expr)
	    {
		...
	    }

	because calc will parse the if being terminated by
	an empty statement followed by a

	    if (expr) ;
	    {
		...
	    }

    See also "help statement", "help unexpected", "help todo", and
    "help bugs".


The following are the changes from calc version 2.12.1 to 2.12.1.5:

    Fixed minor typos in the 'version 2.12.0 to 2.12.0.8' section below.
    Made minor formatting changes as well.

    Changed use of ${Q} in the Makefile to avoid an make "feature"
    related to OpenBSD.  Added ${RM} make variable for make tools that
    do not have builtin defined terms.

    Removed the ECHO_PROG Makefile variable.  Also removed it from
    the sysinfo() custom function.

    Improved the support for cross-compiled environments by using
    make symbols for all non-shell commands executed by Makefiles.

    Fixed a problem with the make chk awk script which failed under
    OS X 10.4.7.

    Fixed a few minor variables that were not set to default values in
    lower level Makefiles.

    Fixed a reference to a non-existent make variable in HOWTO.INSTALL.


The following are the changes from calc version 2.12.0 to 2.12.0.8:

    Fixed ellip.cal to deal with a calc syntax change that happened
    many ages ago but was never applied to this file until now.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Fixed a problem where comments using # followed by a !, newline or
    another # works.  This bug was fixed by Ernest Bowen <ebowen at une
    dot edu dot au>.

    The show builtins display for functions with long descriptions
    is now broken into multi-line descriptions.

    The str functions, such as strcpy(s1, s2), will now copy as many
    characters as possible from s2 to s1, treating '\0' like any other
    character until the end of s2 is reached. If s2 is shorter than s1,
    a '\0' is inserted.

    The strcmp(s1, s2) builtin, for strings s1, s2: strcmp(s1, s2) == 0 now
    means the same as s1 == s2.

    The str(s) builtin has been changed so that it will return only the
    string formed by the characters of 's' up to the first '\0'.

    The substr(s, start, num) builtin has been changed so that '\0' characters
    are treated like any other.

    Fixed a bug where strcpy("", "a") used to cause a segmentation fault.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Make minor change to natnumset.cal in how the tail variable is initialized.

    Fixed bugs in the strcmp, strncmp, strcpy, and strncpy help files.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Added cal/screen.cal which Defines ANSI control sequences providing
    (i.e., cursor movement, changing foreground or background color,
    etc.) for VT100 terminals and terminal window emulators (i.e., xterm,
    Apple OS/X Terminal, etc.) that support them.  For example:

	; read screen
	; print green:"This is green. ":red:"This is red.":black

    Fixed a bug where too many open files returned E_FOPEN3.  Now
    a new error symbol F_MANYOPEN is used for too many open files.

    Added the builtin function fpathopen() to open a file while
    searching along a path:

    	; fd2 = fpathopen("tmp/date", "r", ".:~:~sc:/tmp:/var/tmp:/var")
	; print fd2
	"/var/tmp/date"

    By default, fpathopen() searches along CALCPATH.

    Added the calcpath() builtin function to return the current value
    of CALCPATH.

    Fixed prompt characters in the EXAMPLE section of help files.

    Fixed problems related to the protect function and its documentation.
    This bug was reported by David Gilham <davidgilham at gmail dot com>.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Raised the limit of exponent in exponential notation.  It was set to
    arbitrary 1000000 (making 1e1000001 in invalid exponential notation
    value).  The exponent for exponential notation is now int(MAXLONG/10).
    On 32 bit machines, this means a limit of 214748364.  On 64 bit
    machines, this means 922337203685477580.  Of course, you may not
    have enough memory to hold such huge values, but if you did you can
    now express such values in exponential notation.

    Added log() builtin for base 10 logarithm.

    Fixed problems where internal use of libc strcpy() might have caused
    a buffer overflow.  Calc now only uses libc strcpy() when the source
    string is a constant.

    The calc STRING and STRINGHEAD now use the standard size_t (an unsigned
    type) length.  Calc mostly uses size_t in dealing with string lengths
    and object sizes when possible.

    Added ${CCWERR} make variable to allow one to force compiler warnings
    to be treated as errors.  The ${CC} make variable now uses ${CCWERR}
    however the ${LCC} (used by the Makefile test code for building hsrc
    files) does not use ${CCWERR}.  By default, ${CCWERR} is empty.
    In development Makefiles, we set CCWERR= -Werror to force us to
    address compiler warnings before the next release.

    The calc make variable, CALCPAGER, now defaults to CALCPAGER= less
    because the less utility is now very common.  Set CALCPAGER= more
    if you do not have less.

    Calc source had two styles of switch indentation.  Converted the
    style where case statements were indented with respect to the switch
    statement into the style where the case statements are at the same
    level.  When comparing with older source, one may use the -b argument
    of the diff command to ignore changes in amount of white space:

    	diff -b -r -u calc-2.11.11 calc-2.12.0

    The read, write, and help commands use the value of global string
    variable if the symbol name starts with a $.  For example:

    	global x = "lucas.cal";
	read $x;	/* same as read lucas.cal or read "lucas.cal" */

    Added dotest.cal resource.  Based on a design by Ernest Bowen
    <ebowen at une dot edu dot au>, the dotest evaluates individual
    lines from a file.  The dotest() function takes 1 to 3 arguments:

	dotest(dotest_file [,dotest_code [,dotest_maxcond]])

	dotest_file

	    Search along CALCPATH for dotest_file, which contains lines that
	    should evaluate to 1.  Comment lines and empty lines are ignored.
	    Comment lines should use ## instead of the multi like /* ... */
	    because lines are evaluated one line at a time.

	dotest_code

	    Assign the code number that is to be printed at the start of
	    each non-error line and after **** in each error line.
	    The default code number is 999.

	dotest_maxcond

	    The maximum number of error conditions that may be detected.
	    An error condition is not a sign of a problem, in some cases
	    a line deliberately forces an error condition.  A value of -1,
	    the default, implies a maximum of 2147483647.

	Global variables and functions must be declared ahead of time because
	the dotest scope of evaluation is a line at a time.  For example:

	    ; read dotest.cal
	    ; read set8700.cal
	    ; dotest("set8700.line");

    Updated the todo / wish list items.  The top priority now is to
    convert calc to GNU autoconf / configure to build the calc.

	; help todo

    Added missing help file for the stoponerror() builtin.

    Corrected and improved the help documentation for factor and lfactor.

    Fixed a problem where some error messages that should have been
    written to a file or string, went to stderr instead.  This bug was
    fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Corrected the documentation relating to the calc -c command line option.
    The -c relates to scan/parse errors only, not execution errors.

    Corrected a stack overflow problem where the math_fmt() in zio.c
    could be induced to overflow the stack.  This problem was independently
    reported by Chew Keong Tan of Secunia Research <vuln at secunia dot com>.

    Corrected a stack overflow problem where the scanerror() in token.c
    could be induced to overflow the stack by a malformed token.

    Made math_error() in math_error.c more robust against a error
    message constant that is too long.

    Made read_bindings() in hist.c more robust against very long bindings
    config lines.

    Made listsort() in listfunc.c and matsort() matfunc.c more robust
    against sorting of impossibly huge lists and matrices.

    Warnings about an undefining a builtin or undefined function, a
    constant before the comma operator, and an unterminated comment is
    now processed by scanerrors (not simply written directly to stderr).
    These warnings file and line number in which the "error" occurred
    as well as a more precise message than before.  If using -c on the
    calc command line or if stoponerror(-1), then assuming there are
    no other compile errors, only the unterminated comment will stop
    completion of the function being defined.

    The cal/regress.cal now reads most of the calc resource files.

    The issq() test had a slight performance boost.  A minor note
    was added to the help/issq file.

    Improved the documentation of the mul2, sq2, pow2, and redc2 config
    parameters in help/config.

    Added config("baseb"), a read-only configuration value to return
    the number of bits in the fundamental base in which calculations
    are performed.  This is a read-only configuration value.

    Calc now will allow syntax such as ++*p-- and  ++*----*++p----
    where p is an lvalue; successful evaluation of course require the
    successive operations to be performed to have operands of appropriate
    types; e.g. in *A, A is usually an lvalue whose current value is a
    pointer. ++ and -- act on lvalues. In the above examples there are
    implied parentheses from the beginning to immediately after p. If
    there are no pre ++ or -- operations, as in **p++.  The implied
    parentheses are from immediately before p to the end.

    Improved the error message when && is used as a prefix operator.

    Changed the help/config file to read like a builtin function help file.

    One can no longer set to 1, or to a value < 0, the config()
    parameters: "mul2", "sq2", "pow2", and "redc2".  These values
    in the past would result in improper configuration of internal
    calc algorithms.  Changed cal/test4100.cal to use the minimal
    value of 2 for "pow2", and "redc2".

    Changed the default values for the following config() parameters:

    	config("mul2") == 1780
	config("sq2") == 3388
	config("pow2") == 176

	These values were determined established on a 1.8GHz AMD 32-bit
	CPU of ~3406 BogoMIPS by the new resource file:

	    cal/alg_config.cal

   Regarding the alg_config.cal resource file:

	The best_mul2() function returns the optimal value of config("mul2").
	The best_sq2() function returns the optimal value of config("sq2").
	The best_pow2() function returns the optimal value of config("pow2").
	The other functions are just support functions.

	By design, best_mul2(), best_sq2(), and best_pow2() take a few
	minutes to run.  These functions increase the number of times a
	given computational loop is executed until a minimum amount of CPU
	time is consumed.  To watch these functions progress, one can set
	the config("user_debug") value.

	Here is a suggested way to use the alg_config.cal resource file:

	    ; read alg_config
	    ; config("user_debug",2),;
	    ; best_mul2(); best_sq2(); best_pow2();
	    ; best_mul2(); best_sq2(); best_pow2();
	    ; best_mul2(); best_sq2(); best_pow2();

	NOTE: It is perfectly normal for the optimal value returned
	to differ slightly from run to run.  Slight variations due to
	inaccuracy in CPU timings will cause the best value returned to
	differ slightly from run to run.

	See "help resource" for more information on alg_config.cal.

    Updated the "help variable" text to reflect the current calc
    use of ` (backquote), * (star), and & (ampersand).

    Removal of some restrictions on the use of the same identifier
    for more than one of parameter, local, static or global variable.

	For example, at command level, one could use:

	    for (local x = 0; x < 10; x++) print sqrt(x);

	At the beginning of a statement, "(global A)" is a way of
	indicating a reference to the variable A, whereas "global A"
	would be taken as a declaration. Parentheses are not required in
	"++global A" or "global A++" when "global" is used in this way.

	The patch extends this "specifier" (or "qualifier") feature
	to static variables, but such that "static A" refers only
	to a static variable at the current file and function scope
	levels. (If there is already a static variable A at the current
	file and function levels, a declaration statement "static A"
	would end the scope of that variable and define a new static
	variable with identifier A. A "global A" declaration is more
	drastic in that it ends the scope of any static variable A at
	the same or higher scope levels.)

	Unlike a static declaration in which an "initialization" occurs at
	most once, in the specifier case, "static A = expr" is simply an
	assignment which may be repeated any number of times.  An example
	of its use is:

	    define np() = static a = nextprime(a);

	For n not too large, the n-th call to this function will
	return the n-th prime. The variable a here will be private to
	the function.

	Because one can use "global", "local" or "static" to specify a
	type of variable, there seems little point in restricting the
	ways identifiers that can be used in more than one of these
	or as parameters. Obviously, introducing A as a local variable
	when it is being used as a parameter can lead to confusion and a
	warning is appropriate, but if it is to be used only occasionally,
	it might be convenient to be able to refer to it as "local A"
	rather than introducing another identifier. While it may be
	silly to use the same identifier for both a parameter and local
	variable, it should not be illegal.

    Added warnings for possibly questionable code in function definitions.

    Added config("redecl_warn", boolean) to control if calc issues
    warnings about variables being declared.  The config("redecl_warn")
    value is TRUE by default.

    Added config("dupvar_warn", boolean) to control if calc issues
    warnings about when variable names collide.  The config("dupvar_warn")
    value is TRUE by default.  Examples of variable name collisions
    include when:

    	* both local and static variables have the same name
    	* both local and global variables have the same name
    	* both function parameter and local variables have the same name
    	* both function parameter and global variables have the same name

    Fix of a bug which causes some static variables not to be correctly
    unscoped when their identifiers are used in a global declaration.

    Change of "undefine" from a command-level keyword to statement level and
    introduction of an "undefine static A" statement to end the scope of a
    static variable A at the current file/function levels.

    Change/restored the syntax rules for "for" and "while" loops to
    recognize an unescaped newline in top-level command-level statements.

    Updated help/avg, help/define, help/fprintf, help/gcd, help/hash,
    help/hmean, help/lcm, help/max, help/min, help/null, help/poly,
    help/printf, help/ssq, help/strcat, help/strprintf, help/sum,
    help/xor.

    Changed the definition of the function ssq() to enable list arguments
    to be processed in the same way as in sum().  For example:

    	ssq(1,2, list(3,4,list(5,6)), list(), 7, 8)

    returns the value of 1^2 + 2^2 + ... + 8^2 == 204.

    Added the calc resource sumtimes.cal, to give the runtimes for
    various ways of evaluating sums, sums of squares, etc, for large
    lists and matrices.  For example:

    	read slet at users dot sourceforge dot net>.

    Fixed a problem where some old MS environments failed some of the
    regression tests because "read -once foo.cal" was not behaving
    correctly due to how the _fullpath() was being called.  Thanks for
    this fix goes to Anatoly <notexistent-anb at yandex dot ru>.

    Documented the mis-feature about how calc parses if, for, while
    and do statements in an unexpected way.   For example:

	This works as expected:

	    if (expr) {
		...
	    }

	However this WILL NOT WORK AS EXPECTED:

	    if (expr)
	    {
		...
	    }

	because calc will parse the if being terminated by
	an empty statement followed by a

	    if (expr) ;
	    {
		...
	    }

    See also "help statement", "help unexpected", "help todo", and
    "help bugs".


The following are the changes from calc version 2.12.1 to 2.12.1.5:

    Fixed minor typos in the 'version 2.12.0 to 2.12.0.8' section below.
    Made minor formatting changes as well.

    Changed use of ${Q} in the Makefile to avoid an make "feature"
    related to OpenBSD.  Added ${RM} make variable for make tools that
    do not have builtin defined terms.

    Removed the ECHO_PROG Makefile variable.  Also removed it from
    the sysinfo() custom function.

    Improved the support for cross-compiled environments by using
    make symbols for all non-shell commands executed by Makefiles.

    Fixed a problem with the make chk awk script which failed under
    OS X 10.4.7.

    Fixed a few minor variables that were not set to default values in
    lower level Makefiles.

    Fixed a reference to a non-existent make variable in HOWTO.INSTALL.


The following are the changes from calc version 2.12.0 to 2.12.0.8:

    Fixed ellip.cal to deal with a calc syntax change that happened
    many ages ago but was never applied to this file until now.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Fixed a problem where comments using # followed by a !, newline or
    another # works.  This bug was fixed by Ernest Bowen <ebowen at une
    dot edu dot au>.

    The show builtins display for functions with long descriptions
    is now broken into multi-line descriptions.

    The str functions, such as strcpy(s1, s2), will now copy as many
    characters as possible from s2 to s1, treating '\0' like any other
    character until the end of s2 is reached. If s2 is shorter than s1,
    a '\0' is inserted.

    The strcmp(s1, s2) builtin, for strings s1, s2: strcmp(s1, s2) == 0 now
    means the same as s1 == s2.

    The str(s) builtin has been changed so that it will return only the
    string formed by the characters of 's' up to the first '\0'.

    The substr(s, start, num) builtin has been changed so that '\0' characters
    are treated like any other.

    Fixed a bug where strcpy("", "a") used to cause a segmentation fault.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Make minor change to natnumset.cal in how the tail variable is initialized.

    Fixed bugs in the strcmp, strncmp, strcpy, and strncpy help files.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Added cal/screen.cal which Defines ANSI control sequences providing
    (i.e., cursor movement, changing foreground or background color,
    etc.) for VT100 terminals and terminal window emulators (i.e., xterm,
    Apple OS/X Terminal, etc.) that support them.  For example:

	; read screen
	; print green:"This is green. ":red:"This is red.":black

    Fixed a bug where too many open files returned E_FOPEN3.  Now
    a new error symbol F_MANYOPEN is used for too many open files.

    Added the builtin function fpathopen() to open a file while
    searching along a path:

    	; fd2 = fpathopen("tmp/date", "r", ".:~:~sc:/tmp:/var/tmp:/var")
	; print fd2
	"/var/tmp/date"

    By default, fpathopen() searches along CALCPATH.

    Added the calcpath() builtin function to return the current value
    of CALCPATH.

    Fixed prompt characters in the EXAMPLE section of help files.

    Fixed problems related to the protect function and its documentation.
    This bug was reported by David Gilham <davidgilham at gmail dot com>.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Raised the limit of exponent in exponential notation.  It was set to
    arbitrary 1000000 (making 1e1000001 in invalid exponential notation
    value).  The exponent for exponential notation is now int(MAXLONG/10).
    On 32 bit machines, this means a limit of 214748364.  On 64 bit
    machines, this means 922337203685477580.  Of course, you may not
    have enough memory to hold such huge values, but if you did you can
    now express such values in exponential notation.

    Added log() builtin for base 10 logarithm.

    Fixed problems where internal use of libc strcpy() might have caused
    a buffer overflow.  Calc now only uses libc strcpy() when the source
    string is a constant.

    The calc STRING and STRINGHEAD now use the standard size_t (an unsigned
    type) length.  Calc mostly uses size_t in dealing with string lengths
    and object sizes when possible.

    Added ${CCWERR} make variable to allow one to force compiler warnings
    to be treated as errors.  The ${CC} make variable now uses ${CCWERR}
    however the ${LCC} (used by the Makefile test code for building hsrc
    files) does not use ${CCWERR}.  By default, ${CCWERR} is empty.
    In development Makefiles, we set CCWERR= -Werror to force us to
    address compiler warnings before the next release.

    The calc make variable, CALCPAGER, now defaults to CALCPAGER= less
    because the less utility is now very common.  Set CALCPAGER= more
    if you do not have less.

    Calc source had two styles of switch indentation.  Converted the
    style where case statements were indented with respect to the switch
    statement into the style where the case statements are at the same
    level.  When comparing with older source, one may use the -b argument
    of the diff command to ignore changes in amount of white space:

    	diff -b -r -u calc-2.11.11 calc-2.12.0

    The read, write, and help commands use the value of global string
    variable if the symbol name starts with a $.  For example:

    	global x = "lucas.cal";
	read $x;	/* same as read lucas.cal or read "lucas.cal" */

    Added dotest.cal resource.  Based on a design by Ernest Bowen
    <ebowen at une dot edu dot au>, the dotest evaluates individual
    lines from a file.  The dotest() function takes 1 to 3 arguments:

	dotest(dotest_file [,dotest_code [,dotest_maxcond]])

	dotest_file

	    Search along CALCPATH for dotest_file, which contains lines that
	    should evaluate to 1.  Comment lines and empty lines are ignored.
	    Comment lines should use ## instead of the multi like /* ... */
	    because lines are evaluated one line at a time.

	dotest_code

	    Assign the code number that is to be printed at the start of
	    each non-error line and after **** in each error line.
	    The default code number is 999.

	dotest_maxcond

	    The maximum number of error conditions that may be detected.
	    An error condition is not a sign of a problem, in some cases
	    a line deliberately forces an error condition.  A value of -1,
	    the default, implies a maximum of 2147483647.

	Global variables and functions must be declared ahead of time because
	the dotest scope of evaluation is a line at a time.  For example:

	    ; read dotest.cal
	    ; read set8700.cal
	    ; dotest("set8700.line");

    Updated the todo / wish list items.  The top priority now is to
    convert calc to GNU autoconf / configure to build the calc.

	; help todo

    Added missing help file for the stoponerror() builtin.

    Corrected and improved the help documentation for factor and lfactor.

    Fixed a problem where some error messages that should have been
    written to a file or string, went to stderr instead.  This bug was
    fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Corrected the documentation relating to the calc -c command line option.
    The -c relates to scan/parse errors only, not execution errors.

    Corrected a stack overflow problem where the math_fmt() in zio.c
    could be induced to overflow the stack.  This problem was independently
    reported by Chew Keong Tan of Secunia Research <vuln at secunia dot com>.

    Corrected a stack overflow problem where the scanerror() in token.c
    could be induced to overflow the stack by a malformed token.

    Made math_error() in math_error.c more robust against a error
    message constant that is too long.

    Made read_bindings() in hist.c more robust against very long bindings
    config lines.

    Made listsort() in listfunc.c and matsort() matfunc.c more robust
    against sorting of impossibly huge lists and matrices.

    Warnings about an undefining a builtin or undefined function, a
    constant before the comma operator, and an unterminated comment is
    now processed by scanerrors (not simply written directly to stderr).
    These warnings file and line number in which the "error" occurred
    as well as a more precise message than before.  If using -c on the
    calc command line or if stoponerror(-1), then assuming there are
    no other compile errors, only the unterminated comment will stop
    completion of the function being defined.

    The cal/regress.cal now reads most of the calc resource files.

    The issq() test had a slight performance boost.  A minor note
    was added to the help/issq file.

    Improved the documentation of the mul2, sq2, pow2, and redc2 config
    parameters in help/config.

    Added config("baseb"), a read-only configuration value to return
    the number of bits in the fundamental base in which calculations
    are performed.  This is a read-only configuration value.

    Calc now will allow syntax such as ++*p-- and  ++*----*++p----
    where p is an lvalue; successful evaluation of course require the
    successive operations to be performed to have operands of appropriate
    types; e.g. in *A, A is usually an lvalue whose current value is a
    pointer. ++ and -- act on lvalues. In the above examples there are
    implied parentheses from the beginning to immediately after p. If
    there are no pre ++ or -- operations, as in **p++.  The implied
    parentheses are from immediately before p to the end.

    Improved the error message when && is used as a prefix operator.

    Changed the help/config file to read like a builtin function help file.

    One can no longer set to 1, or to a value < 0, the config()
    parameters: "mul2", "sq2", "pow2", and "redc2".  These values
    in the past would result in improper configuration of internal
    calc algorithms.  Changed cal/test4100.cal to use the minimal
    value of 2 for "pow2", and "redc2".

    Changed the default values for the following config() parameters:

    	config("mul2") == 1780
	config("sq2") == 3388
	config("pow2") == 176

	These values were determined established on a 1.8GHz AMD 32-bit
	CPU of ~3406 BogoMIPS by the new resource file:

	    cal/alg_config.cal

   Regarding the alg_config.cal resource file:

	The best_mul2() function returns the optimal value of config("mul2").
	The best_sq2() function returns the optimal value of config("sq2").
	The best_pow2() function returns the optimal value of config("pow2").
	The other functions are just support functions.

	By design, best_mul2(), best_sq2(), and best_pow2() take a few
	minutes to run.  These functions increase the number of times a
	given computational loop is executed until a minimum amount of CPU
	time is consumed.  To watch these functions progress, one can set
	the config("user_debug") value.

	Here is a suggested way to use the alg_config.cal resource file:

	    ; read alg_config
	    ; config("user_debug",2),;
	    ; best_mul2(); best_sq2(); best_pow2();
	    ; best_mul2(); best_sq2(); best_pow2();
	    ; best_mul2(); best_sq2(); best_pow2();

	NOTE: It is perfectly normal for the optimal value returned
	to differ slightly from run to run.  Slight variations due to
	inaccuracy in CPU timings will cause the best value returned to
	differ slightly from run to run.

	See "help resource" for more information on alg_config.cal.

    Updated the "help variable" text to reflect the current calc
    use of ` (backquote), * (star), and & (ampersand).

    Removal of some restrictions on the use of the same identifier
    for more than one of parameter, local, static or global variable.

	For example, at command level, one could use:

	    for (local x = 0; x < 10; x++) print sqrt(x);

	At the beginning of a statement, "(global A)" is a way of
	indicating a reference to the variable A, whereas "global A"
	would be taken as a declaration. Parentheses are not required in
	"++global A" or "global A++" when "global" is used in this way.

	The patch extends this "specifier" (or "qualifier") feature
	to static variables, but such that "static A" refers only
	to a static variable at the current file and function scope
	levels. (If there is already a static variable A at the current
	file and function levels, a declaration statement "static A"
	would end the scope of that variable and define a new static
	variable with identifier A. A "global A" declaration is more
	drastic in that it ends the scope of any static variable A at
	the same or higher scope levels.)

	Unlike a static declaration in which an "initialization" occurs at
	most once, in the specifier case, "static A = expr" is simply an
	assignment which may be repeated any number of times.  An example
	of its use is:

	    define np() = static a = nextprime(a);

	For n not too large, the n-th call to this function will
	return the n-th prime. The variable a here will be private to
	the function.

	Because one can use "global", "local" or "static" to specify a
	type of variable, there seems little point in restricting the
	ways identifiers that can be used in more than one of these
	or as parameters. Obviously, introducing A as a local variable
	when it is being used as a parameter can lead to confusion and a
	warning is appropriate, but if it is to be used only occasionally,
	it might be convenient to be able to refer to it as "local A"
	rather than introducing another identifier. While it may be
	silly to use the same identifier for both a parameter and local
	variable, it should not be illegal.

    Added warnings for possibly questionable code in function definitions.

    Added config("redecl_warn", boolean) to control if calc issues
    warnings about variables being declared.  The config("redecl_warn")
    value is TRUE by default.

    Added config("dupvar_warn", boolean) to control if calc issues
    warnings about when variable names collide.  The config("dupvar_warn")
    value is TRUE by default.  Examples of variable name collisions
    include when:

    	* both local and static variables have the same name
    	* both local and global variables have the same name
    	* both function parameter and local variables have the same name
    	* both function parameter and global variables have the same name

    Fix of a bug which causes some static variables not to be correctly
    unscoped when their identifiers are used in a global declaration.

    Change of "undefine" from a command-level keyword to statement level and
    introduction of an "undefine static A" statement to end the scope of a
    static variable A at the current file/function levels.

    Change/restored the syntax rules for "for" and "while" loops to
    recognize an unescaped newline in top-level command-level statements.

    Updated help/avg, help/define, help/fprintf, help/gcd, help/hash,
    help/hmean, help/lcm, help/max, help/min, help/null, help/poly,
    help/printf, help/ssq, help/strcat, help/strprintf, help/sum,
    help/xor.

    Changed the definition of the function ssq() to enable list arguments
    to be processed in the same way as in sum().  For example:

    	ssq(1,2, list(3,4,list(5,6)), list(), 7, 8)

    returns the value of 1^2 + 2^2 + ... + 8^2 == 204.

    Added the calc resource sumtimes.cal, to give the runtimes for
    various ways of evaluating sums, sums of squares, etc, for large
    lists and matrices.  For example:

    	read slet at users dot sourceforge dot net>.

    Fixed a problem where some old MS environments failed some of the
    regression tests because "read -once foo.cal" was not behaving
    correctly due to how the _fullpath() was being called.  Thanks for
    this fix goes to Anatoly <notexistent-anb at yandex dot ru>.

    Documented the mis-feature about how calc parses if, for, while
    and do statements in an unexpected way.   For example:

	This works as expected:

	    if (expr) {
		...
	    }

	However this WILL NOT WORK AS EXPECTED:

	    if (expr)
	    {
		...
	    }

	because calc will parse the if being terminated by
	an empty statement followed by a

	    if (expr) ;
	    {
		...
	    }

    See also "help statement", "help unexpected", "help todo", and
    "help bugs".


The following are the changes from calc version 2.12.1 to 2.12.1.5:

    Fixed minor typos in the 'version 2.12.0 to 2.12.0.8' section below.
    Made minor formatting changes as well.

    Changed use of ${Q} in the Makefile to avoid an make "feature"
    related to OpenBSD.  Added ${RM} make variable for make tools that
    do not have builtin defined terms.

    Removed the ECHO_PROG Makefile variable.  Also removed it from
    the sysinfo() custom function.

    Improved the support for cross-compiled environments by using
    make symbols for all non-shell commands executed by Makefiles.

    Fixed a problem with the make chk awk script which failed under
    OS X 10.4.7.

    Fixed a few minor variables that were not set to default values in
    lower level Makefiles.

    Fixed a reference to a non-existent make variable in HOWTO.INSTALL.


The following are the changes from calc version 2.12.0 to 2.12.0.8:

    Fixed ellip.cal to deal with a calc syntax change that happened
    many ages ago but was never applied to this file until now.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Fixed a problem where comments using # followed by a !, newline or
    another # works.  This bug was fixed by Ernest Bowen <ebowen at une
    dot edu dot au>.

    The show builtins display for functions with long descriptions
    is now broken into multi-line descriptions.

    The str functions, such as strcpy(s1, s2), will now copy as many
    characters as possible from s2 to s1, treating '\0' like any other
    character until the end of s2 is reached. If s2 is shorter than s1,
    a '\0' is inserted.

    The strcmp(s1, s2) builtin, for strings s1, s2: strcmp(s1, s2) == 0 now
    means the same as s1 == s2.

    The str(s) builtin has been changed so that it will return only the
    string formed by the characters of 's' up to the first '\0'.

    The substr(s, start, num) builtin has been changed so that '\0' characters
    are treated like any other.

    Fixed a bug where strcpy("", "a") used to cause a segmentation fault.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Make minor change to natnumset.cal in how the tail variable is initialized.

    Fixed bugs in the strcmp, strncmp, strcpy, and strncpy help files.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Added cal/screen.cal which Defines ANSI control sequences providing
    (i.e., cursor movement, changing foreground or background color,
    etc.) for VT100 terminals and terminal window emulators (i.e., xterm,
    Apple OS/X Terminal, etc.) that support them.  For example:

	; read screen
	; print green:"This is green. ":red:"This is red.":black

    Fixed a bug where too many open files returned E_FOPEN3.  Now
    a new error symbol F_MANYOPEN is used for too many open files.

    Added the builtin function fpathopen() to open a file while
    searching along a path:

    	; fd2 = fpathopen("tmp/date", "r", ".:~:~sc:/tmp:/var/tmp:/var")
	; print fd2
	"/var/tmp/date"

    By default, fpathopen() searches along CALCPATH.

    Added the calcpath() builtin function to return the current value
    of CALCPATH.

    Fixed prompt characters in the EXAMPLE section of help files.

    Fixed problems related to the protect function and its documentation.
    This bug was reported by David Gilham <davidgilham at gmail dot com>.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Raised the limit of exponent in exponential notation.  It was set to
    arbitrary 1000000 (making 1e1000001 in invalid exponential notation
    value).  The exponent for exponential notation is now int(MAXLONG/10).
    On 32 bit machines, this means a limit of 214748364.  On 64 bit
    machines, this means 922337203685477580.  Of course, you may not
    have enough memory to hold such huge values, but if you did you can
    now express such values in exponential notation.

    Added log() builtin for base 10 logarithm.

    Fixed problems where internal use of libc strcpy() might have caused
    a buffer overflow.  Calc now only uses libc strcpy() when the source
    string is a constant.

    The calc STRING and STRINGHEAD now use the standard size_t (an unsigned
    type) length.  Calc mostly uses size_t in dealing with string lengths
    and object sizes when possible.

    Added ${CCWERR} make variable to allow one to force compiler warnings
    to be treated as errors.  The ${CC} make variable now uses ${CCWERR}
    however the ${LCC} (used by the Makefile test code for building hsrc
    files) does not use ${CCWERR}.  By default, ${CCWERR} is empty.
    In development Makefiles, we set CCWERR= -Werror to force us to
    address compiler warnings before the next release.

    The calc make variable, CALCPAGER, now defaults to CALCPAGER= less
    because the less utility is now very common.  Set CALCPAGER= more
    if you do not have less.

    Calc source had two styles of switch indentation.  Converted the
    style where case statements were indented with respect to the switch
    statement into the style where the case statements are at the same
    level.  When comparing with older source, one may use the -b argument
    of the diff command to ignore changes in amount of white space:

    	diff -b -r -u calc-2.11.11 calc-2.12.0

    The read, write, and help commands use the value of global string
    variable if the symbol name starts with a $.  For example:

    	global x = "lucas.cal";
	read $x;	/* same as read lucas.cal or read "lucas.cal" */

    Added dotest.cal resource.  Based on a design by Ernest Bowen
    <ebowen at une dot edu dot au>, the dotest evaluates individual
    lines from a file.  The dotest() function takes 1 to 3 arguments:

	dotest(dotest_file [,dotest_code [,dotest_maxcond]])

	dotest_file

	    Search along CALCPATH for dotest_file, which contains lines that
	    should evaluate to 1.  Comment lines and empty lines are ignored.
	    Comment lines should use ## instead of the multi like /* ... */
	    because lines are evaluated one line at a time.

	dotest_code

	    Assign the code number that is to be printed at the start of
	    each non-error line and after **** in each error line.
	    The default code number is 999.

	dotest_maxcond

	    The maximum number of error conditions that may be detected.
	    An error condition is not a sign of a problem, in some cases
	    a line deliberately forces an error condition.  A value of -1,
	    the default, implies a maximum of 2147483647.

	Global variables and functions must be declared ahead of time because
	the dotest scope of evaluation is a line at a time.  For example:

	    ; read dotest.cal
	    ; read set8700.cal
	    ; dotest("set8700.line");

    Updated the todo / wish list items.  The top priority now is to
    convert calc to GNU autoconf / configure to build the calc.

	; help todo

    Added missing help file for the stoponerror() builtin.

    Corrected and improved the help documentation for factor and lfactor.

    Fixed a problem where some error messages that should have been
    written to a file or string, went to stderr instead.  This bug was
    fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Corrected the documentation relating to the calc -c command line option.
    The -c relates to scan/parse errors only, not execution errors.

    Corrected a stack overflow problem where the math_fmt() in zio.c
    could be induced to overflow the stack.  This problem was independently
    reported by Chew Keong Tan of Secunia Research <vuln at secunia dot com>.

    Corrected a stack overflow problem where the scanerror() in token.c
    could be induced to overflow the stack by a malformed token.

    Made math_error() in math_error.c more robust against a error
    message constant that is too long.

    Made read_bindings() in hist.c more robust against very long bindings
    config lines.

    Made listsort() in listfunc.c and matsort() matfunc.c more robust
    against sorting of impossibly huge lists and matrices.

    Warnings about an undefining a builtin or undefined function, a
    constant before the comma operator, and an unterminated comment is
    now processed by scanerrors (not simply written directly to stderr).
    These warnings file and line number in which the "error" occurred
    as well as a more precise message than before.  If using -c on the
    calc command line or if stoponerror(-1), then assuming there are
    no other compile errors, only the unterminated comment will stop
    completion of the function being defined.

    The cal/regress.cal now reads most of the calc resource files.

    The issq() test had a slight performance boost.  A minor note
    was added to the help/issq file.

    Improved the documentation of the mul2, sq2, pow2, and redc2 config
    parameters in help/config.

    Added config("baseb"), a read-only configuration value to return
    the number of bits in the fundamental base in which calculations
    are performed.  This is a read-only configuration value.

    Calc now will allow syntax such as ++*p-- and  ++*----*++p----
    where p is an lvalue; successful evaluation of course require the
    successive operations to be performed to have operands of appropriate
    types; e.g. in *A, A is usually an lvalue whose current value is a
    pointer. ++ and -- act on lvalues. In the above examples there are
    implied parentheses from the beginning to immediately after p. If
    there are no pre ++ or -- operations, as in **p++.  The implied
    parentheses are from immediately before p to the end.

    Improved the error message when && is used as a prefix operator.

    Changed the help/config file to read like a builtin function help file.

    One can no longer set to 1, or to a value < 0, the config()
    parameters: "mul2", "sq2", "pow2", and "redc2".  These values
    in the past would result in improper configuration of internal
    calc algorithms.  Changed cal/test4100.cal to use the minimal
    value of 2 for "pow2", and "redc2".

    Changed the default values for the following config() parameters:

    	config("mul2") == 1780
	config("sq2") == 3388
	config("pow2") == 176

	These values were determined established on a 1.8GHz AMD 32-bit
	CPU of ~3406 BogoMIPS by the new resource file:

	    cal/alg_config.cal

   Regarding the alg_config.cal resource file:

	The best_mul2() function returns the optimal value of config("mul2").
	The best_sq2() function returns the optimal value of config("sq2").
	The best_pow2() function returns the optimal value of config("pow2").
	The other functions are just support functions.

	By design, best_mul2(), best_sq2(), and best_pow2() take a few
	minutes to run.  These functions increase the number of times a
	given computational loop is executed until a minimum amount of CPU
	time is consumed.  To watch these functions progress, one can set
	the config("user_debug") value.

	Here is a suggested way to use the alg_config.cal resource file:

	    ; read alg_config
	    ; config("user_debug",2),;
	    ; best_mul2(); best_sq2(); best_pow2();
	    ; best_mul2(); best_sq2(); best_pow2();
	    ; best_mul2(); best_sq2(); best_pow2();

	NOTE: It is perfectly normal for the optimal value returned
	to differ slightly from run to run.  Slight variations due to
	inaccuracy in CPU timings will cause the best value returned to
	differ slightly from run to run.

	See "help resource" for more information on alg_config.cal.

    Updated the "help variable" text to reflect the current calc
    use of ` (backquote), * (star), and & (ampersand).

    Removal of some restrictions on the use of the same identifier
    for more than one of parameter, local, static or global variable.

	For example, at command level, one could use:

	    for (local x = 0; x < 10; x++) print sqrt(x);

	At the beginning of a statement, "(global A)" is a way of
	indicating a reference to the variable A, whereas "global A"
	would be taken as a declaration. Parentheses are not required in
	"++global A" or "global A++" when "global" is used in this way.

	The patch extends this "specifier" (or "qualifier") feature
	to static variables, but such that "static A" refers only
	to a static variable at the current file and function scope
	levels. (If there is already a static variable A at the current
	file and function levels, a declaration statement "static A"
	would end the scope of that variable and define a new static
	variable with identifier A. A "global A" declaration is more
	drastic in that it ends the scope of any static variable A at
	the same or higher scope levels.)

	Unlike a static declaration in which an "initialization" occurs at
	most once, in the specifier case, "static A = expr" is simply an
	assignment which may be repeated any number of times.  An example
	of its use is:

	    define np() = static a = nextprime(a);

	For n not too large, the n-th call to this function will
	return the n-th prime. The variable a here will be private to
	the function.

	Because one can use "global", "local" or "static" to specify a
	type of variable, there seems little point in restricting the
	ways identifiers that can be used in more than one of these
	or as parameters. Obviously, introducing A as a local variable
	when it is being used as a parameter can lead to confusion and a
	warning is appropriate, but if it is to be used only occasionally,
	it might be convenient to be able to refer to it as "local A"
	rather than introducing another identifier. While it may be
	silly to use the same identifier for both a parameter and local
	variable, it should not be illegal.

    Added warnings for possibly questionable code in function definitions.

    Added config("redecl_warn", boolean) to control if calc issues
    warnings about variables being declared.  The config("redecl_warn")
    value is TRUE by default.

    Added config("dupvar_warn", boolean) to control if calc issues
    warnings about when variable names collide.  The config("dupvar_warn")
    value is TRUE by default.  Examples of variable name collisions
    include when:

    	* both local and static variables have the same name
    	* both local and global variables have the same name
    	* both function parameter and local variables have the same name
    	* both function parameter and global variables have the same name

    Fix of a bug which causes some static variables not to be correctly
    unscoped when their identifiers are used in a global declaration.

    Change of "undefine" from a command-level keyword to statement level and
    introduction of an "undefine static A" statement to end the scope of a
    static variable A at the current file/function levels.

    Change/restored the syntax rules for "for" and "while" loops to
    recognize an unescaped newline in top-level command-level statements.

    Updated help/avg, help/define, help/fprintf, help/gcd, help/hash,
    help/hmean, help/lcm, help/max, help/min, help/null, help/poly,
    help/printf, help/ssq, help/strcat, help/strprintf, help/sum,
    help/xor.

    Changed the definition of the function ssq() to enable list arguments
    to be processed in the same way as in sum().  For example:

    	ssq(1,2, list(3,4,list(5,6)), list(), 7, 8)

    returns the value of 1^2 + 2^2 + ... + 8^2 == 204.

    Added the calc resource sumtimes.cal, to give the runtimes for
    various ways of evaluating sums, sums of squares, etc, for large
    lists and matrices.  For example:

    	read slet at users dot sourceforge dot net>.

    Fixed a problem where some old MS environments failed some of the
    regression tests because "read -once foo.cal" was not behaving
    correctly due to how the _fullpath() was being called.  Thanks for
    this fix goes to Anatoly <notexistent-anb at yandex dot ru>.

    Documented the mis-feature about how calc parses if, for, while
    and do statements in an unexpected way.   For example:

	This works as expected:

	    if (expr) {
		...
	    }

	However this WILL NOT WORK AS EXPECTED:

	    if (expr)
	    {
		...
	    }

	because calc will parse the if being terminated by
	an empty statement followed by a

	    if (expr) ;
	    {
		...
	    }

    See also "help statement", "help unexpected", "help todo", and
    "help bugs".


The following are the changes from calc version 2.12.1 to 2.12.1.5:

    Fixed minor typos in the 'version 2.12.0 to 2.12.0.8' section below.
    Made minor formatting changes as well.

    Changed use of ${Q} in the Makefile to avoid an make "feature"
    related to OpenBSD.  Added ${RM} make variable for make tools that
    do not have builtin defined terms.

    Removed the ECHO_PROG Makefile variable.  Also removed it from
    the sysinfo() custom function.

    Improved the support for cross-compiled environments by using
    make symbols for all non-shell commands executed by Makefiles.

    Fixed a problem with the make chk awk script which failed under
    OS X 10.4.7.

    Fixed a few minor variables that were not set to default values in
    lower level Makefiles.

    Fixed a reference to a non-existent make variable in HOWTO.INSTALL.


The following are the changes from calc version 2.12.0 to 2.12.0.8:

    Fixed ellip.cal to deal with a calc syntax change that happened
    many ages ago but was never applied to this file until now.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Fixed a problem where comments using # followed by a !, newline or
    another # works.  This bug was fixed by Ernest Bowen <ebowen at une
    dot edu dot au>.

    The show builtins display for functions with long descriptions
    is now broken into multi-line descriptions.

    The str functions, such as strcpy(s1, s2), will now copy as many
    characters as possible from s2 to s1, treating '\0' like any other
    character until the end of s2 is reached. If s2 is shorter than s1,
    a '\0' is inserted.

    The strcmp(s1, s2) builtin, for strings s1, s2: strcmp(s1, s2) == 0 now
    means the same as s1 == s2.

    The str(s) builtin has been changed so that it will return only the
    string formed by the characters of 's' up to the first '\0'.

    The substr(s, start, num) builtin has been changed so that '\0' characters
    are treated like any other.

    Fixed a bug where strcpy("", "a") used to cause a segmentation fault.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Make minor change to natnumset.cal in how the tail variable is initialized.

    Fixed bugs in the strcmp, strncmp, strcpy, and strncpy help files.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Added cal/screen.cal which Defines ANSI control sequences providing
    (i.e., cursor movement, changing foreground or background color,
    etc.) for VT100 terminals and terminal window emulators (i.e., xterm,
    Apple OS/X Terminal, etc.) that support them.  For example:

	; read screen
	; print green:"This is green. ":red:"This is red.":black

    Fixed a bug where too many open files returned E_FOPEN3.  Now
    a new error symbol F_MANYOPEN is used for too many open files.

    Added the builtin function fpathopen() to open a file while
    searching along a path:

    	; fd2 = fpathopen("tmp/date", "r", ".:~:~sc:/tmp:/var/tmp:/var")
	; print fd2
	"/var/tmp/date"

    By default, fpathopen() searches along CALCPATH.

    Added the calcpath() builtin function to return the current value
    of CALCPATH.

    Fixed prompt characters in the EXAMPLE section of help files.

    Fixed problems related to the protect function and its documentation.
    This bug was reported by David Gilham <davidgilham at gmail dot com>.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Raised the limit of exponent in exponential notation.  It was set to
    arbitrary 1000000 (making 1e1000001 in invalid exponential notation
    value).  The exponent for exponential notation is now int(MAXLONG/10).
    On 32 bit machines, this means a limit of 214748364.  On 64 bit
    machines, this means 922337203685477580.  Of course, you may not
    have enough memory to hold such huge values, but if you did you can
    now express such values in exponential notation.

    Added log() builtin for base 10 logarithm.

    Fixed problems where internal use of libc strcpy() might have caused
    a buffer overflow.  Calc now only uses libc strcpy() when the source
    string is a constant.

    The calc STRING and STRINGHEAD now use the standard size_t (an unsigned
    type) length.  Calc mostly uses size_t in dealing with string lengths
    and object sizes when possible.

    Added ${CCWERR} make variable to allow one to force compiler warnings
    to be treated as errors.  The ${CC} make variable now uses ${CCWERR}
    however the ${LCC} (used by the Makefile test code for building hsrc
    files) does not use ${CCWERR}.  By default, ${CCWERR} is empty.
    In development Makefiles, we set CCWERR= -Werror to force us to
    address compiler warnings before the next release.

    The calc make variable, CALCPAGER, now defaults to CALCPAGER= less
    because the less utility is now very common.  Set CALCPAGER= more
    if you do not have less.

    Calc source had two styles of switch indentation.  Converted the
    style where case statements were indented with respect to the switch
    statement into the style where the case statements are at the same
    level.  When comparing with older source, one may use the -b argument
    of the diff command to ignore changes in amount of white space:

    	diff -b -r -u calc-2.11.11 calc-2.12.0

    The read, write, and help commands use the value of global string
    variable if the symbol name starts with a $.  For example:

    	global x = "lucas.cal";
	read $x;	/* same as read lucas.cal or read "lucas.cal" */

    Added dotest.cal resource.  Based on a design by Ernest Bowen
    <ebowen at une dot edu dot au>, the dotest evaluates individual
    lines from a file.  The dotest() function takes 1 to 3 arguments:

	dotest(dotest_file [,dotest_code [,dotest_maxcond]])

	dotest_file

	    Search along CALCPATH for dotest_file, which contains lines that
	    should evaluate to 1.  Comment lines and empty lines are ignored.
	    Comment lines should use ## instead of the multi like /* ... */
	    because lines are evaluated one line at a time.

	dotest_code

	    Assign the code number that is to be printed at the start of
	    each non-error line and after **** in each error line.
	    The default code number is 999.

	dotest_maxcond

	    The maximum number of error conditions that may be detected.
	    An error condition is not a sign of a problem, in some cases
	    a line deliberately forces an error condition.  A value of -1,
	    the default, implies a maximum of 2147483647.

	Global variables and functions must be declared ahead of time because
	the dotest scope of evaluation is a line at a time.  For example:

	    ; read dotest.cal
	    ; read set8700.cal
	    ; dotest("set8700.line");

    Updated the todo / wish list items.  The top priority now is to
    convert calc to GNU autoconf / configure to build the calc.

	; help todo

    Added missing help file for the stoponerror() builtin.

    Corrected and improved the help documentation for factor and lfactor.

    Fixed a problem where some error messages that should have been
    written to a file or string, went to stderr instead.  This bug was
    fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Corrected the documentation relating to the calc -c command line option.
    The -c relates to scan/parse errors only, not execution errors.

    Corrected a stack overflow problem where the math_fmt() in zio.c
    could be induced to overflow the stack.  This problem was independently
    reported by Chew Keong Tan of Secunia Research <vuln at secunia dot com>.

    Corrected a stack overflow problem where the scanerror() in token.c
    could be induced to overflow the stack by a malformed token.

    Made math_error() in math_error.c more robust against a error
    message constant that is too long.

    Made read_bindings() in hist.c more robust against very long bindings
    config lines.

    Made listsort() in listfunc.c and matsort() matfunc.c more robust
    against sorting of impossibly huge lists and matrices.

    Warnings about an undefining a builtin or undefined function, a
    constant before the comma operator, and an unterminated comment is
    now processed by scanerrors (not simply written directly to stderr).
    These warnings file and line number in which the "error" occurred
    as well as a more precise message than before.  If using -c on the
    calc command line or if stoponerror(-1), then assuming there are
    no other compile errors, only the unterminated comment will stop
    completion of the function being defined.

    The cal/regress.cal now reads most of the calc resource files.

    The issq() test had a slight performance boost.  A minor note
    was added to the help/issq file.

    Improved the documentation of the mul2, sq2, pow2, and redc2 config
    parameters in help/config.

    Added config("baseb"), a read-only configuration value to return
    the number of bits in the fundamental base in which calculations
    are performed.  This is a read-only configuration value.

    Calc now will allow syntax such as ++*p-- and  ++*----*++p----
    where p is an lvalue; successful evaluation of course require the
    successive operations to be performed to have operands of appropriate
    types; e.g. in *A, A is usually an lvalue whose current value is a
    pointer. ++ and -- act on lvalues. In the above examples there are
    implied parentheses from the beginning to immediately after p. If
    there are no pre ++ or -- operations, as in **p++.  The implied
    parentheses are from immediately before p to the end.

    Improved the error message when && is used as a prefix operator.

    Changed the help/config file to read like a builtin function help file.

    One can no longer set to 1, or to a value < 0, the config()
    parameters: "mul2", "sq2", "pow2", and "redc2".  These values
    in the past would result in improper configuration of internal
    calc algorithms.  Changed cal/test4100.cal to use the minimal
    value of 2 for "pow2", and "redc2".

    Changed the default values for the following config() parameters:

    	config("mul2") == 1780
	config("sq2") == 3388
	config("pow2") == 176

	These values were determined established on a 1.8GHz AMD 32-bit
	CPU of ~3406 BogoMIPS by the new resource file:

	    cal/alg_config.cal

   Regarding the alg_config.cal resource file:

	The best_mul2() function returns the optimal value of config("mul2").
	The best_sq2() function returns the optimal value of config("sq2").
	The best_pow2() function returns the optimal value of config("pow2").
	The other functions are just support functions.

	By design, best_mul2(), best_sq2(), and best_pow2() take a few
	minutes to run.  These functions increase the number of times a
	given computational loop is executed until a minimum amount of CPU
	time is consumed.  To watch these functions progress, one can set
	the config("user_debug") value.

	Here is a suggested way to use the alg_config.cal resource file:

	    ; read alg_config
	    ; config("user_debug",2),;
	    ; best_mul2(); best_sq2(); best_pow2();
	    ; best_mul2(); best_sq2(); best_pow2();
	    ; best_mul2(); best_sq2(); best_pow2();

	NOTE: It is perfectly normal for the optimal value returned
	to differ slightly from run to run.  Slight variations due to
	inaccuracy in CPU timings will cause the best value returned to
	differ slightly from run to run.

	See "help resource" for more information on alg_config.cal.

    Updated the "help variable" text to reflect the current calc
    use of ` (backquote), * (star), and & (ampersand).

    Removal of some restrictions on the use of the same identifier
    for more than one of parameter, local, static or global variable.

	For example, at command level, one could use:

	    for (local x = 0; x < 10; x++) print sqrt(x);

	At the beginning of a statement, "(global A)" is a way of
	indicating a reference to the variable A, whereas "global A"
	would be taken as a declaration. Parentheses are not required in
	"++global A" or "global A++" when "global" is used in this way.

	The patch extends this "specifier" (or "qualifier") feature
	to static variables, but such that "static A" refers only
	to a static variable at the current file and function scope
	levels. (If there is already a static variable A at the current
	file and function levels, a declaration statement "static A"
	would end the scope of that variable and define a new static
	variable with identifier A. A "global A" declaration is more
	drastic in that it ends the scope of any static variable A at
	the same or higher scope levels.)

	Unlike a static declaration in which an "initialization" occurs at
	most once, in the specifier case, "static A = expr" is simply an
	assignment which may be repeated any number of times.  An example
	of its use is:

	    define np() = static a = nextprime(a);

	For n not too large, the n-th call to this function will
	return the n-th prime. The variable a here will be private to
	the function.

	Because one can use "global", "local" or "static" to specify a
	type of variable, there seems little point in restricting the
	ways identifiers that can be used in more than one of these
	or as parameters. Obviously, introducing A as a local variable
	when it is being used as a parameter can lead to confusion and a
	warning is appropriate, but if it is to be used only occasionally,
	it might be convenient to be able to refer to it as "local A"
	rather than introducing another identifier. While it may be
	silly to use the same identifier for both a parameter and local
	variable, it should not be illegal.

    Added warnings for possibly questionable code in function definitions.

    Added config("redecl_warn", boolean) to control if calc issues
    warnings about variables being declared.  The config("redecl_warn")
    value is TRUE by default.

    Added config("dupvar_warn", boolean) to control if calc issues
    warnings about when variable names collide.  The config("dupvar_warn")
    value is TRUE by default.  Examples of variable name collisions
    include when:

    	* both local and static variables have the same name
    	* both local and global variables have the same name
    	* both function parameter and local variables have the same name
    	* both function parameter and global variables have the same name

    Fix of a bug which causes some static variables not to be correctly
    unscoped when their identifiers are used in a global declaration.

    Change of "undefine" from a command-level keyword to statement level and
    introduction of an "undefine static A" statement to end the scope of a
    static variable A at the current file/function levels.

    Change/restored the syntax rules for "for" and "while" loops to
    recognize an unescaped newline in top-level command-level statements.

    Updated help/avg, help/define, help/fprintf, help/gcd, help/hash,
    help/hmean, help/lcm, help/max, help/min, help/null, help/poly,
    help/printf, help/ssq, help/strcat, help/strprintf, help/sum,
    help/xor.

    Changed the definition of the function ssq() to enable list arguments
    to be processed in the same way as in sum().  For example:

    	ssq(1,2, list(3,4,list(5,6)), list(), 7, 8)

    returns the value of 1^2 + 2^2 + ... + 8^2 == 204.

    Added the calc resource sumtimes.cal, to give the runtimes for
    various ways of evaluating sums, sums of squares, etc, for large
    lists and matrices.  For example:

    	read slet at users dot sourceforge dot net>.

    Fixed a problem where some old MS environments failed some of the
    regression tests because "read -once foo.cal" was not behaving
    correctly due to how the _fullpath() was being called.  Thanks for
    this fix goes to Anatoly <notexistent-anb at yandex dot ru>.

    Documented the mis-feature about how calc parses if, for, while
    and do statements in an unexpected way.   For example:

	This works as expected:

	    if (expr) {
		...
	    }

	However this WILL NOT WORK AS EXPECTED:

	    if (expr)
	    {
		...
	    }

	because calc will parse the if being terminated by
	an empty statement followed by a

	    if (expr) ;
	    {
		...
	    }

    See also "help statement", "help unexpected", "help todo", and
    "help bugs".


The following are the changes from calc version 2.12.1 to 2.12.1.5:

    Fixed minor typos in the 'version 2.12.0 to 2.12.0.8' section below.
    Made minor formatting changes as well.

    Changed use of ${Q} in the Makefile to avoid an make "feature"
    related to OpenBSD.  Added ${RM} make variable for make tools that
    do not have builtin defined terms.

    Removed the ECHO_PROG Makefile variable.  Also removed it from
    the sysinfo() custom function.

    Improved the support for cross-compiled environments by using
    make symbols for all non-shell commands executed by Makefiles.

    Fixed a problem with the make chk awk script which failed under
    OS X 10.4.7.

    Fixed a few minor variables that were not set to default values in
    lower level Makefiles.

    Fixed a reference to a non-existent make variable in HOWTO.INSTALL.


The following are the changes from calc version 2.12.0 to 2.12.0.8:

    Fixed ellip.cal to deal with a calc syntax change that happened
    many ages ago but was never applied to this file until now.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Fixed a problem where comments using # followed by a !, newline or
    another # works.  This bug was fixed by Ernest Bowen <ebowen at une
    dot edu dot au>.

    The show builtins display for functions with long descriptions
    is now broken into multi-line descriptions.

    The str functions, such as strcpy(s1, s2), will now copy as many
    characters as possible from s2 to s1, treating '\0' like any other
    character until the end of s2 is reached. If s2 is shorter than s1,
    a '\0' is inserted.

    The strcmp(s1, s2) builtin, for strings s1, s2: strcmp(s1, s2) == 0 now
    means the same as s1 == s2.

    The str(s) builtin has been changed so that it will return only the
    string formed by the characters of 's' up to the first '\0'.

    The substr(s, start, num) builtin has been changed so that '\0' characters
    are treated like any other.

    Fixed a bug where strcpy("", "a") used to cause a segmentation fault.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Make minor change to natnumset.cal in how the tail variable is initialized.

    Fixed bugs in the strcmp, strncmp, strcpy, and strncpy help files.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Added cal/screen.cal which Defines ANSI control sequences providing
    (i.e., cursor movement, changing foreground or background color,
    etc.) for VT100 terminals and terminal window emulators (i.e., xterm,
    Apple OS/X Terminal, etc.) that support them.  For example:

	; read screen
	; print green:"This is green. ":red:"This is red.":black

    Fixed a bug where too many open files returned E_FOPEN3.  Now
    a new error symbol F_MANYOPEN is used for too many open files.

    Added the builtin function fpathopen() to open a file while
    searching along a path:

    	; fd2 = fpathopen("tmp/date", "r", ".:~:~sc:/tmp:/var/tmp:/var")
	; print fd2
	"/var/tmp/date"

    By default, fpathopen() searches along CALCPATH.

    Added the calcpath() builtin function to return the current value
    of CALCPATH.

    Fixed prompt characters in the EXAMPLE section of help files.

    Fixed problems related to the protect function and its documentation.
    This bug was reported by David Gilham <davidgilham at gmail dot com>.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Raised the limit of exponent in exponential notation.  It was set to
    arbitrary 1000000 (making 1e1000001 in invalid exponential notation
    value).  The exponent for exponential notation is now int(MAXLONG/10).
    On 32 bit machines, this means a limit of 214748364.  On 64 bit
    machines, this means 922337203685477580.  Of course, you may not
    have enough memory to hold such huge values, but if you did you can
    now express such values in exponential notation.

    Added log() builtin for base 10 logarithm.

    Fixed problems where internal use of libc strcpy() might have caused
    a buffer overflow.  Calc now only uses libc strcpy() when the source
    string is a constant.

    The calc STRING and STRINGHEAD now use the standard size_t (an unsigned
    type) length.  Calc mostly uses size_t in dealing with string lengths
    and object sizes when possible.

    Added ${CCWERR} make variable to allow one to force compiler warnings
    to be treated as errors.  The ${CC} make variable now uses ${CCWERR}
    however the ${LCC} (used by the Makefile test code for building hsrc
    files) does not use ${CCWERR}.  By default, ${CCWERR} is empty.
    In development Makefiles, we set CCWERR= -Werror to force us to
    address compiler warnings before the next release.

    The calc make variable, CALCPAGER, now defaults to CALCPAGER= less
    because the less utility is now very common.  Set CALCPAGER= more
    if you do not have less.

    Calc source had two styles of switch indentation.  Converted the
    style where case statements were indented with respect to the switch
    statement into the style where the case statements are at the same
    level.  When comparing with older source, one may use the -b argument
    of the diff command to ignore changes in amount of white space:

    	diff -b -r -u calc-2.11.11 calc-2.12.0

    The read, write, and help commands use the value of global string
    variable if the symbol name starts with a $.  For example:

    	global x = "lucas.cal";
	read $x;	/* same as read lucas.cal or read "lucas.cal" */

    Added dotest.cal resource.  Based on a design by Ernest Bowen
    <ebowen at une dot edu dot au>, the dotest evaluates individual
    lines from a file.  The dotest() function takes 1 to 3 arguments:

	dotest(dotest_file [,dotest_code [,dotest_maxcond]])

	dotest_file

	    Search along CALCPATH for dotest_file, which contains lines that
	    should evaluate to 1.  Comment lines and empty lines are ignored.
	    Comment lines should use ## instead of the multi like /* ... */
	    because lines are evaluated one line at a time.

	dotest_code

	    Assign the code number that is to be printed at the start of
	    each non-error line and after **** in each error line.
	    The default code number is 999.

	dotest_maxcond

	    The maximum number of error conditions that may be detected.
	    An error condition is not a sign of a problem, in some cases
	    a line deliberately forces an error condition.  A value of -1,
	    the default, implies a maximum of 2147483647.

	Global variables and functions must be declared ahead of time because
	the dotest scope of evaluation is a line at a time.  For example:

	    ; read dotest.cal
	    ; read set8700.cal
	    ; dotest("set8700.line");

    Updated the todo / wish list items.  The top priority now is to
    convert calc to GNU autoconf / configure to build the calc.

	; help todo

    Added missing help file for the stoponerror() builtin.

    Corrected and improved the help documentation for factor and lfactor.

    Fixed a problem where some error messages that should have been
    written to a file or string, went to stderr instead.  This bug was
    fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Corrected the documentation relating to the calc -c command line option.
    The -c relates to scan/parse errors only, not execution errors.

    Corrected a stack overflow problem where the math_fmt() in zio.c
    could be induced to overflow the stack.  This problem was independently
    reported by Chew Keong Tan of Secunia Research <vuln at secunia dot com>.

    Corrected a stack overflow problem where the scanerror() in token.c
    could be induced to overflow the stack by a malformed token.

    Made math_error() in math_error.c more robust against a error
    message constant that is too long.

    Made read_bindings() in hist.c more robust against very long bindings
    config lines.

    Made listsort() in listfunc.c and matsort() matfunc.c more robust
    against sorting of impossibly huge lists and matrices.

    Warnings about an undefining a builtin or undefined function, a
    constant before the comma operator, and an unterminated comment is
    now processed by scanerrors (not simply written directly to stderr).
    These warnings file and line number in which the "error" occurred
    as well as a more precise message than before.  If using -c on the
    calc command line or if stoponerror(-1), then assuming there are
    no other compile errors, only the unterminated comment will stop
    completion of the function being defined.

    The cal/regress.cal now reads most of the calc resource files.

    The issq() test had a slight performance boost.  A minor note
    was added to the help/issq file.

    Improved the documentation of the mul2, sq2, pow2, and redc2 config
    parameters in help/config.

    Added config("baseb"), a read-only configuration value to return
    the number of bits in the fundamental base in which calculations
    are performed.  This is a read-only configuration value.

    Calc now will allow syntax such as ++*p-- and  ++*----*++p----
    where p is an lvalue; successful evaluation of course require the
    successive operations to be performed to have operands of appropriate
    types; e.g. in *A, A is usually an lvalue whose current value is a
    pointer. ++ and -- act on lvalues. In the above examples there are
    implied parentheses from the beginning to immediately after p. If
    there are no pre ++ or -- operations, as in **p++.  The implied
    parentheses are from immediately before p to the end.

    Improved the error message when && is used as a prefix operator.

    Changed the help/config file to read like a builtin function help file.

    One can no longer set to 1, or to a value < 0, the config()
    parameters: "mul2", "sq2", "pow2", and "redc2".  These values
    in the past would result in improper configuration of internal
    calc algorithms.  Changed cal/test4100.cal to use the minimal
    value of 2 for "pow2", and "redc2".

    Changed the default values for the following config() parameters:

    	config("mul2") == 1780
	config("sq2") == 3388
	config("pow2") == 176

	These values were determined established on a 1.8GHz AMD 32-bit
	CPU of ~3406 BogoMIPS by the new resource file:

	    cal/alg_config.cal

   Regarding the alg_config.cal resource file:

	The best_mul2() function returns the optimal value of config("mul2").
	The best_sq2() function returns the optimal value of config("sq2").
	The best_pow2() function returns the optimal value of config("pow2").
	The other functions are just support functions.

	By design, best_mul2(), best_sq2(), and best_pow2() take a few
	minutes to run.  These functions increase the number of times a
	given computational loop is executed until a minimum amount of CPU
	time is consumed.  To watch these functions progress, one can set
	the config("user_debug") value.

	Here is a suggested way to use the alg_config.cal resource file:

	    ; read alg_config
	    ; config("user_debug",2),;
	    ; best_mul2(); best_sq2(); best_pow2();
	    ; best_mul2(); best_sq2(); best_pow2();
	    ; best_mul2(); best_sq2(); best_pow2();

	NOTE: It is perfectly normal for the optimal value returned
	to differ slightly from run to run.  Slight variations due to
	inaccuracy in CPU timings will cause the best value returned to
	differ slightly from run to run.

	See "help resource" for more information on alg_config.cal.

    Updated the "help variable" text to reflect the current calc
    use of ` (backquote), * (star), and & (ampersand).

    Removal of some restrictions on the use of the same identifier
    for more than one of parameter, local, static or global variable.

	For example, at command level, one could use:

	    for (local x = 0; x < 10; x++) print sqrt(x);

	At the beginning of a statement, "(global A)" is a way of
	indicating a reference to the variable A, whereas "global A"
	would be taken as a declaration. Parentheses are not required in
	"++global A" or "global A++" when "global" is used in this way.

	The patch extends this "specifier" (or "qualifier") feature
	to static variables, but such that "static A" refers only
	to a static variable at the current file and function scope
	levels. (If there is already a static variable A at the current
	file and function levels, a declaration statement "static A"
	would end the scope of that variable and define a new static
	variable with identifier A. A "global A" declaration is more
	drastic in that it ends the scope of any static variable A at
	the same or higher scope levels.)

	Unlike a static declaration in which an "initialization" occurs at
	most once, in the specifier case, "static A = expr" is simply an
	assignment which may be repeated any number of times.  An example
	of its use is:

	    define np() = static a = nextprime(a);

	For n not too large, the n-th call to this function will
	return the n-th prime. The variable a here will be private to
	the function.

	Because one can use "global", "local" or "static" to specify a
	type of variable, there seems little point in restricting the
	ways identifiers that can be used in more than one of these
	or as parameters. Obviously, introducing A as a local variable
	when it is being used as a parameter can lead to confusion and a
	warning is appropriate, but if it is to be used only occasionally,
	it might be convenient to be able to refer to it as "local A"
	rather than introducing another identifier. While it may be
	silly to use the same identifier for both a parameter and local
	variable, it should not be illegal.

    Added warnings for possibly questionable code in function definitions.

    Added config("redecl_warn", boolean) to control if calc issues
    warnings about variables being declared.  The config("redecl_warn")
    value is TRUE by default.

    Added config("dupvar_warn", boolean) to control if calc issues
    warnings about when variable names collide.  The config("dupvar_warn")
    value is TRUE by default.  Examples of variable name collisions
    include when:

    	* both local and static variables have the same name
    	* both local and global variables have the same name
    	* both function parameter and local variables have the same name
    	* both function parameter and global variables have the same name

    Fix of a bug which causes some static variables not to be correctly
    unscoped when their identifiers are used in a global declaration.

    Change of "undefine" from a command-level keyword to statement level and
    introduction of an "undefine static A" statement to end the scope of a
    static variable A at the current file/function levels.

    Change/restored the syntax rules for "for" and "while" loops to
    recognize an unescaped newline in top-level command-level statements.

    Updated help/avg, help/define, help/fprintf, help/gcd, help/hash,
    help/hmean, help/lcm, help/max, help/min, help/null, help/poly,
    help/printf, help/ssq, help/strcat, help/strprintf, help/sum,
    help/xor.

    Changed the definition of the function ssq() to enable list arguments
    to be processed in the same way as in sum().  For example:

    	ssq(1,2, list(3,4,list(5,6)), list(), 7, 8)

    returns the value of 1^2 + 2^2 + ... + 8^2 == 204.

    Added the calc resource sumtimes.cal, to give the runtimes for
    various ways of evaluating sums, sums of squares, etc, for large
    lists and matrices.  For example:

    	read slet at users dot sourceforge dot net>.

    Fixed a problem where some old MS environments failed some of the
    regression tests because "read -once foo.cal" was not behaving
    correctly due to how the _fullpath() was being called.  Thanks for
    this fix goes to Anatoly <notexistent-anb at yandex dot ru>.

    Documented the mis-feature about how calc parses if, for, while
    and do statements in an unexpected way.   For example:

	This works as expected:

	    if (expr) {
		...
	    }

	However this WILL NOT WORK AS EXPECTED:

	    if (expr)
	    {
		...
	    }

	because calc will parse the if being terminated by
	an empty statement followed by a

	    if (expr) ;
	    {
		...
	    }

    See also "help statement", "help unexpected", "help todo", and
    "help bugs".


The following are the changes from calc version 2.12.1 to 2.12.1.5:

    Fixed minor typos in the 'version 2.12.0 to 2.12.0.8' section below.
    Made minor formatting changes as well.

    Changed use of ${Q} in the Makefile to avoid an make "feature"
    related to OpenBSD.  Added ${RM} make variable for make tools that
    do not have builtin defined terms.

    Removed the ECHO_PROG Makefile variable.  Also removed it from
    the sysinfo() custom function.

    Improved the support for cross-compiled environments by using
    make symbols for all non-shell commands executed by Makefiles.

    Fixed a problem with the make chk awk script which failed under
    OS X 10.4.7.

    Fixed a few minor variables that were not set to default values in
    lower level Makefiles.

    Fixed a reference to a non-existent make variable in HOWTO.INSTALL.


The following are the changes from calc version 2.12.0 to 2.12.0.8:

    Fixed ellip.cal to deal with a calc syntax change that happened
    many ages ago but was never applied to this file until now.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Fixed a problem where comments using # followed by a !, newline or
    another # works.  This bug was fixed by Ernest Bowen <ebowen at une
    dot edu dot au>.

    The show builtins display for functions with long descriptions
    is now broken into multi-line descriptions.

    The str functions, such as strcpy(s1, s2), will now copy as many
    characters as possible from s2 to s1, treating '\0' like any other
    character until the end of s2 is reached. If s2 is shorter than s1,
    a '\0' is inserted.

    The strcmp(s1, s2) builtin, for strings s1, s2: strcmp(s1, s2) == 0 now
    means the same as s1 == s2.

    The str(s) builtin has been changed so that it will return only the
    string formed by the characters of 's' up to the first '\0'.

    The substr(s, start, num) builtin has been changed so that '\0' characters
    are treated like any other.

    Fixed a bug where strcpy("", "a") used to cause a segmentation fault.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Make minor change to natnumset.cal in how the tail variable is initialized.

    Fixed bugs in the strcmp, strncmp, strcpy, and strncpy help files.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Added cal/screen.cal which Defines ANSI control sequences providing
    (i.e., cursor movement, changing foreground or background color,
    etc.) for VT100 terminals and terminal window emulators (i.e., xterm,
    Apple OS/X Terminal, etc.) that support them.  For example:

	; read screen
	; print green:"This is green. ":red:"This is red.":black

    Fixed a bug where too many open files returned E_FOPEN3.  Now
    a new error symbol F_MANYOPEN is used for too many open files.

    Added the builtin function fpathopen() to open a file while
    searching along a path:

    	; fd2 = fpathopen("tmp/date", "r", ".:~:~sc:/tmp:/var/tmp:/var")
	; print fd2
	"/var/tmp/date"

    By default, fpathopen() searches along CALCPATH.

    Added the calcpath() builtin function to return the current value
    of CALCPATH.

    Fixed prompt characters in the EXAMPLE section of help files.

    Fixed problems related to the protect function and its documentation.
    This bug was reported by David Gilham <davidgilham at gmail dot com>.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Raised the limit of exponent in exponential notation.  It was set to
    arbitrary 1000000 (making 1e1000001 in invalid exponential notation
    value).  The exponent for exponential notation is now int(MAXLONG/10).
    On 32 bit machines, this means a limit of 214748364.  On 64 bit
    machines, this means 922337203685477580.  Of course, you may not
    have enough memory to hold such huge values, but if you did you can
    now express such values in exponential notation.

    Added log() builtin for base 10 logarithm.

    Fixed problems where internal use of libc strcpy() might have caused
    a buffer overflow.  Calc now only uses libc strcpy() when the source
    string is a constant.

    The calc STRING and STRINGHEAD now use the standard size_t (an unsigned
    type) length.  Calc mostly uses size_t in dealing with string lengths
    and object sizes when possible.

    Added ${CCWERR} make variable to allow one to force compiler warnings
    to be treated as errors.  The ${CC} make variable now uses ${CCWERR}
    however the ${LCC} (used by the Makefile test code for building hsrc
    files) does not use ${CCWERR}.  By default, ${CCWERR} is empty.
    In development Makefiles, we set CCWERR= -Werror to force us to
    address compiler warnings before the next release.

    The calc make variable, CALCPAGER, now defaults to CALCPAGER= less
    because the less utility is now very common.  Set CALCPAGER= more
    if you do not have less.

    Calc source had two styles of switch indentation.  Converted the
    style where case statements were indented with respect to the switch
    statement into the style where the case statements are at the same
    level.  When comparing with older source, one may use the -b argument
    of the diff command to ignore changes in amount of white space:

    	diff -b -r -u calc-2.11.11 calc-2.12.0

    The read, write, and help commands use the value of global string
    variable if the symbol name starts with a $.  For example:

    	global x = "lucas.cal";
	read $x;	/* same as read lucas.cal or read "lucas.cal" */

    Added dotest.cal resource.  Based on a design by Ernest Bowen
    <ebowen at une dot edu dot au>, the dotest evaluates individual
    lines from a file.  The dotest() function takes 1 to 3 arguments:

	dotest(dotest_file [,dotest_code [,dotest_maxcond]])

	dotest_file

	    Search along CALCPATH for dotest_file, which contains lines that
	    should evaluate to 1.  Comment lines and empty lines are ignored.
	    Comment lines should use ## instead of the multi like /* ... */
	    because lines are evaluated one line at a time.

	dotest_code

	    Assign the code number that is to be printed at the start of
	    each non-error line and after **** in each error line.
	    The default code number is 999.

	dotest_maxcond

	    The maximum number of error conditions that may be detected.
	    An error condition is not a sign of a problem, in some cases
	    a line deliberately forces an error condition.  A value of -1,
	    the default, implies a maximum of 2147483647.

	Global variables and functions must be declared ahead of time because
	the dotest scope of evaluation is a line at a time.  For example:

	    ; read dotest.cal
	    ; read set8700.cal
	    ; dotest("set8700.line");

    Updated the todo / wish list items.  The top priority now is to
    convert calc to GNU autoconf / configure to build the calc.

	; help todo

    Added missing help file for the stoponerror() builtin.

    Corrected and improved the help documentation for factor and lfactor.

    Fixed a problem where some error messages that should have been
    written to a file or string, went to stderr instead.  This bug was
    fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Corrected the documentation relating to the calc -c command line option.
    The -c relates to scan/parse errors only, not execution errors.

    Corrected a stack overflow problem where the math_fmt() in zio.c
    could be induced to overflow the stack.  This problem was independently
    reported by Chew Keong Tan of Secunia Research <vuln at secunia dot com>.

    Corrected a stack overflow problem where the scanerror() in token.c
    could be induced to overflow the stack by a malformed token.

    Made math_error() in math_error.c more robust against a error
    message constant that is too long.

    Made read_bindings() in hist.c more robust against very long bindings
    config lines.

    Made listsort() in listfunc.c and matsort() matfunc.c more robust
    against sorting of impossibly huge lists and matrices.

    Warnings about an undefining a builtin or undefined function, a
    constant before the comma operator, and an unterminated comment is
    now processed by scanerrors (not simply written directly to stderr).
    These warnings file and line number in which the "error" occurred
    as well as a more precise message than before.  If using -c on the
    calc command line or if stoponerror(-1), then assuming there are
    no other compile errors, only the unterminated comment will stop
    completion of the function being defined.

    The cal/regress.cal now reads most of the calc resource files.

    The issq() test had a slight performance boost.  A minor note
    was added to the help/issq file.

    Improved the documentation of the mul2, sq2, pow2, and redc2 config
    parameters in help/config.

    Added config("baseb"), a read-only configuration value to return
    the number of bits in the fundamental base in which calculations
    are performed.  This is a read-only configuration value.

    Calc now will allow syntax such as ++*p-- and  ++*----*++p----
    where p is an lvalue; successful evaluation of course require the
    successive operations to be performed to have operands of appropriate
    types; e.g. in *A, A is usually an lvalue whose current value is a
    pointer. ++ and -- act on lvalues. In the above examples there are
    implied parentheses from the beginning to immediately after p. If
    there are no pre ++ or -- operations, as in **p++.  The implied
    parentheses are from immediately before p to the end.

    Improved the error message when && is used as a prefix operator.

    Changed the help/config file to read like a builtin function help file.

    One can no longer set to 1, or to a value < 0, the config()
    parameters: "mul2", "sq2", "pow2", and "redc2".  These values
    in the past would result in improper configuration of internal
    calc algorithms.  Changed cal/test4100.cal to use the minimal
    value of 2 for "pow2", and "redc2".

    Changed the default values for the following config() parameters:

    	config("mul2") == 1780
	config("sq2") == 3388
	config("pow2") == 176

	These values were determined established on a 1.8GHz AMD 32-bit
	CPU of ~3406 BogoMIPS by the new resource file:

	    cal/alg_config.cal

   Regarding the alg_config.cal resource file:

	The best_mul2() function returns the optimal value of config("mul2").
	The best_sq2() function returns the optimal value of config("sq2").
	The best_pow2() function returns the optimal value of config("pow2").
	The other functions are just support functions.

	By design, best_mul2(), best_sq2(), and best_pow2() take a few
	minutes to run.  These functions increase the number of times a
	given computational loop is executed until a minimum amount of CPU
	time is consumed.  To watch these functions progress, one can set
	the config("user_debug") value.

	Here is a suggested way to use the alg_config.cal resource file:

	    ; read alg_config
	    ; config("user_debug",2),;
	    ; best_mul2(); best_sq2(); best_pow2();
	    ; best_mul2(); best_sq2(); best_pow2();
	    ; best_mul2(); best_sq2(); best_pow2();

	NOTE: It is perfectly normal for the optimal value returned
	to differ slightly from run to run.  Slight variations due to
	inaccuracy in CPU timings will cause the best value returned to
	differ slightly from run to run.

	See "help resource" for more information on alg_config.cal.

    Updated the "help variable" text to reflect the current calc
    use of ` (backquote), * (star), and & (ampersand).

    Removal of some restrictions on the use of the same identifier
    for more than one of parameter, local, static or global variable.

	For example, at command level, one could use:

	    for (local x = 0; x < 10; x++) print sqrt(x);

	At the beginning of a statement, "(global A)" is a way of
	indicating a reference to the variable A, whereas "global A"
	would be taken as a declaration. Parentheses are not required in
	"++global A" or "global A++" when "global" is used in this way.

	The patch extends this "specifier" (or "qualifier") feature
	to static variables, but such that "static A" refers only
	to a static variable at the current file and function scope
	levels. (If there is already a static variable A at the current
	file and function levels, a declaration statement "static A"
	would end the scope of that variable and define a new static
	variable with identifier A. A "global A" declaration is more
	drastic in that it ends the scope of any static variable A at
	the same or higher scope levels.)

	Unlike a static declaration in which an "initialization" occurs at
	most once, in the specifier case, "static A = expr" is simply an
	assignment which may be repeated any number of times.  An example
	of its use is:

	    define np() = static a = nextprime(a);

	For n not too large, the n-th call to this function will
	return the n-th prime. The variable a here will be private to
	the function.

	Because one can use "global", "local" or "static" to specify a
	type of variable, there seems little point in restricting the
	ways identifiers that can be used in more than one of these
	or as parameters. Obviously, introducing A as a local variable
	when it is being used as a parameter can lead to confusion and a
	warning is appropriate, but if it is to be used only occasionally,
	it might be convenient to be able to refer to it as "local A"
	rather than introducing another identifier. While it may be
	silly to use the same identifier for both a parameter and local
	variable, it should not be illegal.

    Added warnings for possibly questionable code in function definitions.

    Added config("redecl_warn", boolean) to control if calc issues
    warnings about variables being declared.  The config("redecl_warn")
    value is TRUE by default.

    Added config("dupvar_warn", boolean) to control if calc issues
    warnings about when variable names collide.  The config("dupvar_warn")
    value is TRUE by default.  Examples of variable name collisions
    include when:

    	* both local and static variables have the same name
    	* both local and global variables have the same name
    	* both function parameter and local variables have the same name
    	* both function parameter and global variables have the same name

    Fix of a bug which causes some static variables not to be correctly
    unscoped when their identifiers are used in a global declaration.

    Change of "undefine" from a command-level keyword to statement level and
    introduction of an "undefine static A" statement to end the scope of a
    static variable A at the current file/function levels.

    Change/restored the syntax rules for "for" and "while" loops to
    recognize an unescaped newline in top-level command-level statements.

    Updated help/avg, help/define, help/fprintf, help/gcd, help/hash,
    help/hmean, help/lcm, help/max, help/min, help/null, help/poly,
    help/printf, help/ssq, help/strcat, help/strprintf, help/sum,
    help/xor.

    Changed the definition of the function ssq() to enable list arguments
    to be processed in the same way as in sum().  For example:

    	ssq(1,2, list(3,4,list(5,6)), list(), 7, 8)

    returns the value of 1^2 + 2^2 + ... + 8^2 == 204.

    Added the calc resource sumtimes.cal, to give the runtimes for
    various ways of evaluating sums, sums of squares, etc, for large
    lists and matrices.  For example:

    	read slet at users dot sourceforge dot net>.

    Fixed a problem where some old MS environments failed some of the
    regression tests because "read -once foo.cal" was not behaving
    correctly due to how the _fullpath() was being called.  Thanks for
    this fix goes to Anatoly <notexistent-anb at yandex dot ru>.

    Documented the mis-feature about how calc parses if, for, while
    and do statements in an unexpected way.   For example:

	This works as expected:

	    if (expr) {
		...
	    }

	However this WILL NOT WORK AS EXPECTED:

	    if (expr)
	    {
		...
	    }

	because calc will parse the if being terminated by
	an empty statement followed by a

	    if (expr) ;
	    {
		...
	    }

    See also "help statement", "help unexpected", "help todo", and
    "help bugs".


The following are the changes from calc version 2.12.1 to 2.12.1.5:

    Fixed minor typos in the 'version 2.12.0 to 2.12.0.8' section below.
    Made minor formatting changes as well.

    Changed use of ${Q} in the Makefile to avoid an make "feature"
    related to OpenBSD.  Added ${RM} make variable for make tools that
    do not have builtin defined terms.

    Removed the ECHO_PROG Makefile variable.  Also removed it from
    the sysinfo() custom function.

    Improved the support for cross-compiled environments by using
    make symbols for all non-shell commands executed by Makefiles.

    Fixed a problem with the make chk awk script which failed under
    OS X 10.4.7.

    Fixed a few minor variables that were not set to default values in
    lower level Makefiles.

    Fixed a reference to a non-existent make variable in HOWTO.INSTALL.


The following are the changes from calc version 2.12.0 to 2.12.0.8:

    Fixed ellip.cal to deal with a calc syntax change that happened
    many ages ago but was never applied to this file until now.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Fixed a problem where comments using # followed by a !, newline or
    another # works.  This bug was fixed by Ernest Bowen <ebowen at une
    dot edu dot au>.

    The show builtins display for functions with long descriptions
    is now broken into multi-line descriptions.

    The str functions, such as strcpy(s1, s2), will now copy as many
    characters as possible from s2 to s1, treating '\0' like any other
    character until the end of s2 is reached. If s2 is shorter than s1,
    a '\0' is inserted.

    The strcmp(s1, s2) builtin, for strings s1, s2: strcmp(s1, s2) == 0 now
    means the same as s1 == s2.

    The str(s) builtin has been changed so that it will return only the
    string formed by the characters of 's' up to the first '\0'.

    The substr(s, start, num) builtin has been changed so that '\0' characters
    are treated like any other.

    Fixed a bug where strcpy("", "a") used to cause a segmentation fault.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Make minor change to natnumset.cal in how the tail variable is initialized.

    Fixed bugs in the strcmp, strncmp, strcpy, and strncpy help files.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Added cal/screen.cal which Defines ANSI control sequences providing
    (i.e., cursor movement, changing foreground or background color,
    etc.) for VT100 terminals and terminal window emulators (i.e., xterm,
    Apple OS/X Terminal, etc.) that support them.  For example:

	; read screen
	; print green:"This is green. ":red:"This is red.":black

    Fixed a bug where too many open files returned E_FOPEN3.  Now
    a new error symbol F_MANYOPEN is used for too many open files.

    Added the builtin function fpathopen() to open a file while
    searching along a path:

    	; fd2 = fpathopen("tmp/date", "r", ".:~:~sc:/tmp:/var/tmp:/var")
	; print fd2
	"/var/tmp/date"

    By default, fpathopen() searches along CALCPATH.

    Added the calcpath() builtin function to return the current value
    of CALCPATH.

    Fixed prompt characters in the EXAMPLE section of help files.

    Fixed problems related to the protect function and its documentation.
    This bug was reported by David Gilham <davidgilham at gmail dot com>.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Raised the limit of exponent in exponential notation.  It was set to
    arbitrary 1000000 (making 1e1000001 in invalid exponential notation
    value).  The exponent for exponential notation is now int(MAXLONG/10).
    On 32 bit machines, this means a limit of 214748364.  On 64 bit
    machines, this means 922337203685477580.  Of course, you may not
    have enough memory to hold such huge values, but if you did you can
    now express such values in exponential notation.

    Added log() builtin for base 10 logarithm.

    Fixed problems where internal use of libc strcpy() might have caused
    a buffer overflow.  Calc now only uses libc strcpy() when the source
    string is a constant.

    The calc STRING and STRINGHEAD now use the standard size_t (an unsigned
    type) length.  Calc mostly uses size_t in dealing with string lengths
    and object sizes when possible.

    Added ${CCWERR} make variable to allow one to force compiler warnings
    to be treated as errors.  The ${CC} make variable now uses ${CCWERR}
    however the ${LCC} (used by the Makefile test code for building hsrc
    files) does not use ${CCWERR}.  By default, ${CCWERR} is empty.
    In development Makefiles, we set CCWERR= -Werror to force us to
    address compiler warnings before the next release.

    The calc make variable, CALCPAGER, now defaults to CALCPAGER= less
    because the less utility is now very common.  Set CALCPAGER= more
    if you do not have less.

    Calc source had two styles of switch indentation.  Converted the
    style where case statements were indented with respect to the switch
    statement into the style where the case statements are at the same
    level.  When comparing with older source, one may use the -b argument
    of the diff command to ignore changes in amount of white space:

    	diff -b -r -u calc-2.11.11 calc-2.12.0

    The read, write, and help commands use the value of global string
    variable if the symbol name starts with a $.  For example:

    	global x = "lucas.cal";
	read $x;	/* same as read lucas.cal or read "lucas.cal" */

    Added dotest.cal resource.  Based on a design by Ernest Bowen
    <ebowen at une dot edu dot au>, the dotest evaluates individual
    lines from a file.  The dotest() function takes 1 to 3 arguments:

	dotest(dotest_file [,dotest_code [,dotest_maxcond]])

	dotest_file

	    Search along CALCPATH for dotest_file, which contains lines that
	    should evaluate to 1.  Comment lines and empty lines are ignored.
	    Comment lines should use ## instead of the multi like /* ... */
	    because lines are evaluated one line at a time.

	dotest_code

	    Assign the code number that is to be printed at the start of
	    each non-error line and after **** in each error line.
	    The default code number is 999.

	dotest_maxcond

	    The maximum number of error conditions that may be detected.
	    An error condition is not a sign of a problem, in some cases
	    a line deliberately forces an error condition.  A value of -1,
	    the default, implies a maximum of 2147483647.

	Global variables and functions must be declared ahead of time because
	the dotest scope of evaluation is a line at a time.  For example:

	    ; read dotest.cal
	    ; read set8700.cal
	    ; dotest("set8700.line");

    Updated the todo / wish list items.  The top priority now is to
    convert calc to GNU autoconf / configure to build the calc.

	; help todo

    Added missing help file for the stoponerror() builtin.

    Corrected and improved the help documentation for factor and lfactor.

    Fixed a problem where some error messages that should have been
    written to a file or string, went to stderr instead.  This bug was
    fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Corrected the documentation relating to the calc -c command line option.
    The -c relates to scan/parse errors only, not execution errors.

    Corrected a stack overflow problem where the math_fmt() in zio.c
    could be induced to overflow the stack.  This problem was independently
    reported by Chew Keong Tan of Secunia Research <vuln at secunia dot com>.

    Corrected a stack overflow problem where the scanerror() in token.c
    could be induced to overflow the stack by a malformed token.

    Made math_error() in math_error.c more robust against a error
    message constant that is too long.

    Made read_bindings() in hist.c more robust against very long bindings
    config lines.

    Made listsort() in listfunc.c and matsort() matfunc.c more robust
    against sorting of impossibly huge lists and matrices.

    Warnings about an undefining a builtin or undefined function, a
    constant before the comma operator, and an unterminated comment is
    now processed by scanerrors (not simply written directly to stderr).
    These warnings file and line number in which the "error" occurred
    as well as a more precise message than before.  If using -c on the
    calc command line or if stoponerror(-1), then assuming there are
    no other compile errors, only the unterminated comment will stop
    completion of the function being defined.

    The cal/regress.cal now reads most of the calc resource files.

    The issq() test had a slight performance boost.  A minor note
    was added to the help/issq file.

    Improved the documentation of the mul2, sq2, pow2, and redc2 config
    parameters in help/config.

    Added config("baseb"), a read-only configuration value to return
    the number of bits in the fundamental base in which calculations
    are performed.  This is a read-only configuration value.

    Calc now will allow syntax such as ++*p-- and  ++*----*++p----
    where p is an lvalue; successful evaluation of course require the
    successive operations to be performed to have operands of appropriate
    types; e.g. in *A, A is usually an lvalue whose current value is a
    pointer. ++ and -- act on lvalues. In the above examples there are
    implied parentheses from the beginning to immediately after p. If
    there are no pre ++ or -- operations, as in **p++.  The implied
    parentheses are from immediately before p to the end.

    Improved the error message when && is used as a prefix operator.

    Changed the help/config file to read like a builtin function help file.

    One can no longer set to 1, or to a value < 0, the config()
    parameters: "mul2", "sq2", "pow2", and "redc2".  These values
    in the past would result in improper configuration of internal
    calc algorithms.  Changed cal/test4100.cal to use the minimal
    value of 2 for "pow2", and "redc2".

    Changed the default values for the following config() parameters:

    	config("mul2") == 1780
	config("sq2") == 3388
	config("pow2") == 176

	These values were determined established on a 1.8GHz AMD 32-bit
	CPU of ~3406 BogoMIPS by the new resource file:

	    cal/alg_config.cal

   Regarding the alg_config.cal resource file:

	The best_mul2() function returns the optimal value of config("mul2").
	The best_sq2() function returns the optimal value of config("sq2").
	The best_pow2() function returns the optimal value of config("pow2").
	The other functions are just support functions.

	By design, best_mul2(), best_sq2(), and best_pow2() take a few
	minutes to run.  These functions increase the number of times a
	given computational loop is executed until a minimum amount of CPU
	time is consumed.  To watch these functions progress, one can set
	the config("user_debug") value.

	Here is a suggested way to use the alg_config.cal resource file:

	    ; read alg_config
	    ; config("user_debug",2),;
	    ; best_mul2(); best_sq2(); best_pow2();
	    ; best_mul2(); best_sq2(); best_pow2();
	    ; best_mul2(); best_sq2(); best_pow2();

	NOTE: It is perfectly normal for the optimal value returned
	to differ slightly from run to run.  Slight variations due to
	inaccuracy in CPU timings will cause the best value returned to
	differ slightly from run to run.

	See "help resource" for more information on alg_config.cal.

    Updated the "help variable" text to reflect the current calc
    use of ` (backquote), * (star), and & (ampersand).

    Removal of some restrictions on the use of the same identifier
    for more than one of parameter, local, static or global variable.

	For example, at command level, one could use:

	    for (local x = 0; x < 10; x++) print sqrt(x);

	At the beginning of a statement, "(global A)" is a way of
	indicating a reference to the variable A, whereas "global A"
	would be taken as a declaration. Parentheses are not required in
	"++global A" or "global A++" when "global" is used in this way.

	The patch extends this "specifier" (or "qualifier") feature
	to static variables, but such that "static A" refers only
	to a static variable at the current file and function scope
	levels. (If there is already a static variable A at the current
	file and function levels, a declaration statement "static A"
	would end the scope of that variable and define a new static
	variable with identifier A. A "global A" declaration is more
	drastic in that it ends the scope of any static variable A at
	the same or higher scope levels.)

	Unlike a static declaration in which an "initialization" occurs at
	most once, in the specifier case, "static A = expr" is simply an
	assignment which may be repeated any number of times.  An example
	of its use is:

	    define np() = static a = nextprime(a);

	For n not too large, the n-th call to this function will
	return the n-th prime. The variable a here will be private to
	the function.

	Because one can use "global", "local" or "static" to specify a
	type of variable, there seems little point in restricting the
	ways identifiers that can be used in more than one of these
	or as parameters. Obviously, introducing A as a local variable
	when it is being used as a parameter can lead to confusion and a
	warning is appropriate, but if it is to be used only occasionally,
	it might be convenient to be able to refer to it as "local A"
	rather than introducing another identifier. While it may be
	silly to use the same identifier for both a parameter and local
	variable, it should not be illegal.

    Added warnings for possibly questionable code in function definitions.

    Added config("redecl_warn", boolean) to control if calc issues
    warnings about variables being declared.  The config("redecl_warn")
    value is TRUE by default.

    Added config("dupvar_warn", boolean) to control if calc issues
    warnings about when variable names collide.  The config("dupvar_warn")
    value is TRUE by default.  Examples of variable name collisions
    include when:

    	* both local and static variables have the same name
    	* both local and global variables have the same name
    	* both function parameter and local variables have the same name
    	* both function parameter and global variables have the same name

    Fix of a bug which causes some static variables not to be correctly
    unscoped when their identifiers are used in a global declaration.

    Change of "undefine" from a command-level keyword to statement level and
    introduction of an "undefine static A" statement to end the scope of a
    static variable A at the current file/function levels.

    Change/restored the syntax rules for "for" and "while" loops to
    recognize an unescaped newline in top-level command-level statements.

    Updated help/avg, help/define, help/fprintf, help/gcd, help/hash,
    help/hmean, help/lcm, help/max, help/min, help/null, help/poly,
    help/printf, help/ssq, help/strcat, help/strprintf, help/sum,
    help/xor.

    Changed the definition of the function ssq() to enable list arguments
    to be processed in the same way as in sum().  For example:

    	ssq(1,2, list(3,4,list(5,6)), list(), 7, 8)

    returns the value of 1^2 + 2^2 + ... + 8^2 == 204.

    Added the calc resource sumtimes.cal, to give the runtimes for
    various ways of evaluating sums, sums of squares, etc, for large
    lists and matrices.  For example:

    	read slet at users dot sourceforge dot net>.

    Fixed a problem where some old MS environments failed some of the
    regression tests because "read -once foo.cal" was not behaving
    correctly due to how the _fullpath() was being called.  Thanks for
    this fix goes to Anatoly <notexistent-anb at yandex dot ru>.

    Documented the mis-feature about how calc parses if, for, while
    and do statements in an unexpected way.   For example:

	This works as expected:

	    if (expr) {
		...
	    }

	However this WILL NOT WORK AS EXPECTED:

	    if (expr)
	    {
		...
	    }

	because calc will parse the if being terminated by
	an empty statement followed by a

	    if (expr) ;
	    {
		...
	    }

    See also "help statement", "help unexpected", "help todo", and
    "help bugs".


The following are the changes from calc version 2.12.1 to 2.12.1.5:

    Fixed minor typos in the 'version 2.12.0 to 2.12.0.8' section below.
    Made minor formatting changes as well.

    Changed use of ${Q} in the Makefile to avoid an make "feature"
    related to OpenBSD.  Added ${RM} make variable for make tools that
    do not have builtin defined terms.

    Removed the ECHO_PROG Makefile variable.  Also removed it from
    the sysinfo() custom function.

    Improved the support for cross-compiled environments by using
    make symbols for all non-shell commands executed by Makefiles.

    Fixed a problem with the make chk awk script which failed under
    OS X 10.4.7.

    Fixed a few minor variables that were not set to default values in
    lower level Makefiles.

    Fixed a reference to a non-existent make variable in HOWTO.INSTALL.


The following are the changes from calc version 2.12.0 to 2.12.0.8:

    Fixed ellip.cal to deal with a calc syntax change that happened
    many ages ago but was never applied to this file until now.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Fixed a problem where comments using # followed by a !, newline or
    another # works.  This bug was fixed by Ernest Bowen <ebowen at une
    dot edu dot au>.

    The show builtins display for functions with long descriptions
    is now broken into multi-line descriptions.

    The str functions, such as strcpy(s1, s2), will now copy as many
    characters as possible from s2 to s1, treating '\0' like any other
    character until the end of s2 is reached. If s2 is shorter than s1,
    a '\0' is inserted.

    The strcmp(s1, s2) builtin, for strings s1, s2: strcmp(s1, s2) == 0 now
    means the same as s1 == s2.

    The str(s) builtin has been changed so that it will return only the
    string formed by the characters of 's' up to the first '\0'.

    The substr(s, start, num) builtin has been changed so that '\0' characters
    are treated like any other.

    Fixed a bug where strcpy("", "a") used to cause a segmentation fault.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Make minor change to natnumset.cal in how the tail variable is initialized.

    Fixed bugs in the strcmp, strncmp, strcpy, and strncpy help files.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Added cal/screen.cal which Defines ANSI control sequences providing
    (i.e., cursor movement, changing foreground or background color,
    etc.) for VT100 terminals and terminal window emulators (i.e., xterm,
    Apple OS/X Terminal, etc.) that support them.  For example:

	; read screen
	; print green:"This is green. ":red:"This is red.":black

    Fixed a bug where too many open files returned E_FOPEN3.  Now
    a new error symbol F_MANYOPEN is used for too many open files.

    Added the builtin function fpathopen() to open a file while
    searching along a path:

    	; fd2 = fpathopen("tmp/date", "r", ".:~:~sc:/tmp:/var/tmp:/var")
	; print fd2
	"/var/tmp/date"

    By default, fpathopen() searches along CALCPATH.

    Added the calcpath() builtin function to return the current value
    of CALCPATH.

    Fixed prompt characters in the EXAMPLE section of help files.

    Fixed problems related to the protect function and its documentation.
    This bug was reported by David Gilham <davidgilham at gmail dot com>.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Raised the limit of exponent in exponential notation.  It was set to
    arbitrary 1000000 (making 1e1000001 in invalid exponential notation
    value).  The exponent for exponential notation is now int(MAXLONG/10).
    On 32 bit machines, this means a limit of 214748364.  On 64 bit
    machines, this means 922337203685477580.  Of course, you may not
    have enough memory to hold such huge values, but if you did you can
    now express such values in exponential notation.

    Added log() builtin for base 10 logarithm.

    Fixed problems where internal use of libc strcpy() might have caused
    a buffer overflow.  Calc now only uses libc strcpy() when the source
    string is a constant.

    The calc STRING and STRINGHEAD now use the standard size_t (an unsigned
    type) length.  Calc mostly uses size_t in dealing with string lengths
    and object sizes when possible.

    Added ${CCWERR} make variable to allow one to force compiler warnings
    to be treated as errors.  The ${CC} make variable now uses ${CCWERR}
    however the ${LCC} (used by the Makefile test code for building hsrc
    files) does not use ${CCWERR}.  By default, ${CCWERR} is empty.
    In development Makefiles, we set CCWERR= -Werror to force us to
    address compiler warnings before the next release.

    The calc make variable, CALCPAGER, now defaults to CALCPAGER= less
    because the less utility is now very common.  Set CALCPAGER= more
    if you do not have less.

    Calc source had two styles of switch indentation.  Converted the
    style where case statements were indented with respect to the switch
    statement into the style where the case statements are at the same
    level.  When comparing with older source, one may use the -b argument
    of the diff command to ignore changes in amount of white space:

    	diff -b -r -u calc-2.11.11 calc-2.12.0

    The read, write, and help commands use the value of global string
    variable if the symbol name starts with a $.  For example:

    	global x = "lucas.cal";
	read $x;	/* same as read lucas.cal or read "lucas.cal" */

    Added dotest.cal resource.  Based on a design by Ernest Bowen
    <ebowen at une dot edu dot au>, the dotest evaluates individual
    lines from a file.  The dotest() function takes 1 to 3 arguments:

	dotest(dotest_file [,dotest_code [,dotest_maxcond]])

	dotest_file

	    Search along CALCPATH for dotest_file, which contains lines that
	    should evaluate to 1.  Comment lines and empty lines are ignored.
	    Comment lines should use ## instead of the multi like /* ... */
	    because lines are evaluated one line at a time.

	dotest_code

	    Assign the code number that is to be printed at the start of
	    each non-error line and after **** in each error line.
	    The default code number is 999.

	dotest_maxcond

	    The maximum number of error conditions that may be detected.
	    An error condition is not a sign of a problem, in some cases
	    a line deliberately forces an error condition.  A value of -1,
	    the default, implies a maximum of 2147483647.

	Global variables and functions must be declared ahead of time because
	the dotest scope of evaluation is a line at a time.  For example:

	    ; read dotest.cal
	    ; read set8700.cal
	    ; dotest("set8700.line");

    Updated the todo / wish list items.  The top priority now is to
    convert calc to GNU autoconf / configure to build the calc.

	; help todo

    Added missing help file for the stoponerror() builtin.

    Corrected and improved the help documentation for factor and lfactor.

    Fixed a problem where some error messages that should have been
    written to a file or string, went to stderr instead.  This bug was
    fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Corrected the documentation relating to the calc -c command line option.
    The -c relates to scan/parse errors only, not execution errors.

    Corrected a stack overflow problem where the math_fmt() in zio.c
    could be induced to overflow the stack.  This problem was independently
    reported by Chew Keong Tan of Secunia Research <vuln at secunia dot com>.

    Corrected a stack overflow problem where the scanerror() in token.c
    could be induced to overflow the stack by a malformed token.

    Made math_error() in math_error.c more robust against a error
    message constant that is too long.

    Made read_bindings() in hist.c more robust against very long bindings
    config lines.

    Made listsort() in listfunc.c and matsort() matfunc.c more robust
    against sorting of impossibly huge lists and matrices.

    Warnings about an undefining a builtin or undefined function, a
    constant before the comma operator, and an unterminated comment is
    now processed by scanerrors (not simply written directly to stderr).
    These warnings file and line number in which the "error" occurred
    as well as a more precise message than before.  If using -c on the
    calc command line or if stoponerror(-1), then assuming there are
    no other compile errors, only the unterminated comment will stop
    completion of the function being defined.

    The cal/regress.cal now reads most of the calc resource files.

    The issq() test had a slight performance boost.  A minor note
    was added to the help/issq file.

    Improved the documentation of the mul2, sq2, pow2, and redc2 config
    parameters in help/config.

    Added config("baseb"), a read-only configuration value to return
    the number of bits in the fundamental base in which calculations
    are performed.  This is a read-only configuration value.

    Calc now will allow syntax such as ++*p-- and  ++*----*++p----
    where p is an lvalue; successful evaluation of course require the
    successive operations to be performed to have operands of appropriate
    types; e.g. in *A, A is usually an lvalue whose current value is a
    pointer. ++ and -- act on lvalues. In the above examples there are
    implied parentheses from the beginning to immediately after p. If
    there are no pre ++ or -- operations, as in **p++.  The implied
    parentheses are from immediately before p to the end.

    Improved the error message when && is used as a prefix operator.

    Changed the help/config file to read like a builtin function help file.

    One can no longer set to 1, or to a value < 0, the config()
    parameters: "mul2", "sq2", "pow2", and "redc2".  These values
    in the past would result in improper configuration of internal
    calc algorithms.  Changed cal/test4100.cal to use the minimal
    value of 2 for "pow2", and "redc2".

    Changed the default values for the following config() parameters:

    	config("mul2") == 1780
	config("sq2") == 3388
	config("pow2") == 176

	These values were determined established on a 1.8GHz AMD 32-bit
	CPU of ~3406 BogoMIPS by the new resource file:

	    cal/alg_config.cal

   Regarding the alg_config.cal resource file:

	The best_mul2() function returns the optimal value of config("mul2").
	The best_sq2() function returns the optimal value of config("sq2").
	The best_pow2() function returns the optimal value of config("pow2").
	The other functions are just support functions.

	By design, best_mul2(), best_sq2(), and best_pow2() take a few
	minutes to run.  These functions increase the number of times a
	given computational loop is executed until a minimum amount of CPU
	time is consumed.  To watch these functions progress, one can set
	the config("user_debug") value.

	Here is a suggested way to use the alg_config.cal resource file:

	    ; read alg_config
	    ; config("user_debug",2),;
	    ; best_mul2(); best_sq2(); best_pow2();
	    ; best_mul2(); best_sq2(); best_pow2();
	    ; best_mul2(); best_sq2(); best_pow2();

	NOTE: It is perfectly normal for the optimal value returned
	to differ slightly from run to run.  Slight variations due to
	inaccuracy in CPU timings will cause the best value returned to
	differ slightly from run to run.

	See "help resource" for more information on alg_config.cal.

    Updated the "help variable" text to reflect the current calc
    use of ` (backquote), * (star), and & (ampersand).

    Removal of some restrictions on the use of the same identifier
    for more than one of parameter, local, static or global variable.

	For example, at command level, one could use:

	    for (local x = 0; x < 10; x++) print sqrt(x);

	At the beginning of a statement, "(global A)" is a way of
	indicating a reference to the variable A, whereas "global A"
	would be taken as a declaration. Parentheses are not required in
	"++global A" or "global A++" when "global" is used in this way.

	The patch extends this "specifier" (or "qualifier") feature
	to static variables, but such that "static A" refers only
	to a static variable at the current file and function scope
	levels. (If there is already a static variable A at the current
	file and function levels, a declaration statement "static A"
	would end the scope of that variable and define a new static
	variable with identifier A. A "global A" declaration is more
	drastic in that it ends the scope of any static variable A at
	the same or higher scope levels.)

	Unlike a static declaration in which an "initialization" occurs at
	most once, in the specifier case, "static A = expr" is simply an
	assignment which may be repeated any number of times.  An example
	of its use is:

	    define np() = static a = nextprime(a);

	For n not too large, the n-th call to this function will
	return the n-th prime. The variable a here will be private to
	the function.

	Because one can use "global", "local" or "static" to specify a
	type of variable, there seems little point in restricting the
	ways identifiers that can be used in more than one of these
	or as parameters. Obviously, introducing A as a local variable
	when it is being used as a parameter can lead to confusion and a
	warning is appropriate, but if it is to be used only occasionally,
	it might be convenient to be able to refer to it as "local A"
	rather than introducing another identifier. While it may be
	silly to use the same identifier for both a parameter and local
	variable, it should not be illegal.

    Added warnings for possibly questionable code in function definitions.

    Added config("redecl_warn", boolean) to control if calc issues
    warnings about variables being declared.  The config("redecl_warn")
    value is TRUE by default.

    Added config("dupvar_warn", boolean) to control if calc issues
    warnings about when variable names collide.  The config("dupvar_warn")
    value is TRUE by default.  Examples of variable name collisions
    include when:

    	* both local and static variables have the same name
    	* both local and global variables have the same name
    	* both function parameter and local variables have the same name
    	* both function parameter and global variables have the same name

    Fix of a bug which causes some static variables not to be correctly
    unscoped when their identifiers are used in a global declaration.

    Change of "undefine" from a command-level keyword to statement level and
    introduction of an "undefine static A" statement to end the scope of a
    static variable A at the current file/function levels.

    Change/restored the syntax rules for "for" and "while" loops to
    recognize an unescaped newline in top-level command-level statements.

    Updated help/avg, help/define, help/fprintf, help/gcd, help/hash,
    help/hmean, help/lcm, help/max, help/min, help/null, help/poly,
    help/printf, help/ssq, help/strcat, help/strprintf, help/sum,
    help/xor.

    Changed the definition of the function ssq() to enable list arguments
    to be processed in the same way as in sum().  For example:

    	ssq(1,2, list(3,4,list(5,6)), list(), 7, 8)

    returns the value of 1^2 + 2^2 + ... + 8^2 == 204.

    Added the calc resource sumtimes.cal, to give the runtimes for
    various ways of evaluating sums, sums of squares, etc, for large
    lists and matrices.  For example:

    	read slet at users dot sourceforge dot net>.

    Fixed a problem where some old MS environments failed some of the
    regression tests because "read -once foo.cal" was not behaving
    correctly due to how the _fullpath() was being called.  Thanks for
    this fix goes to Anatoly <notexistent-anb at yandex dot ru>.

    Documented the mis-feature about how calc parses if, for, while
    and do statements in an unexpected way.   For example:

	This works as expected:

	    if (expr) {
		...
	    }

	However this WILL NOT WORK AS EXPECTED:

	    if (expr)
	    {
		...
	    }

	because calc will parse the if being terminated by
	an empty statement followed by a

	    if (expr) ;
	    {
		...
	    }

    See also "help statement", "help unexpected", "help todo", and
    "help bugs".


The following are the changes from calc version 2.12.1 to 2.12.1.5:

    Fixed minor typos in the 'version 2.12.0 to 2.12.0.8' section below.
    Made minor formatting changes as well.

    Changed use of ${Q} in the Makefile to avoid an make "feature"
    related to OpenBSD.  Added ${RM} make variable for make tools that
    do not have builtin defined terms.

    Removed the ECHO_PROG Makefile variable.  Also removed it from
    the sysinfo() custom function.

    Improved the support for cross-compiled environments by using
    make symbols for all non-shell commands executed by Makefiles.

    Fixed a problem with the make chk awk script which failed under
    OS X 10.4.7.

    Fixed a few minor variables that were not set to default values in
    lower level Makefiles.

    Fixed a reference to a non-existent make variable in HOWTO.INSTALL.


The following are the changes from calc version 2.12.0 to 2.12.0.8:

    Fixed ellip.cal to deal with a calc syntax change that happened
    many ages ago but was never applied to this file until now.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Fixed a problem where comments using # followed by a !, newline or
    another # works.  This bug was fixed by Ernest Bowen <ebowen at une
    dot edu dot au>.

    The show builtins display for functions with long descriptions
    is now broken into multi-line descriptions.

    The str functions, such as strcpy(s1, s2), will now copy as many
    characters as possible from s2 to s1, treating '\0' like any other
    character until the end of s2 is reached. If s2 is shorter than s1,
    a '\0' is inserted.

    The strcmp(s1, s2) builtin, for strings s1, s2: strcmp(s1, s2) == 0 now
    means the same as s1 == s2.

    The str(s) builtin has been changed so that it will return only the
    string formed by the characters of 's' up to the first '\0'.

    The substr(s, start, num) builtin has been changed so that '\0' characters
    are treated like any other.

    Fixed a bug where strcpy("", "a") used to cause a segmentation fault.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Make minor change to natnumset.cal in how the tail variable is initialized.

    Fixed bugs in the strcmp, strncmp, strcpy, and strncpy help files.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Added cal/screen.cal which Defines ANSI control sequences providing
    (i.e., cursor movement, changing foreground or background color,
    etc.) for VT100 terminals and terminal window emulators (i.e., xterm,
    Apple OS/X Terminal, etc.) that support them.  For example:

	; read screen
	; print green:"This is green. ":red:"This is red.":black

    Fixed a bug where too many open files returned E_FOPEN3.  Now
    a new error symbol F_MANYOPEN is used for too many open files.

    Added the builtin function fpathopen() to open a file while
    searching along a path:

    	; fd2 = fpathopen("tmp/date", "r", ".:~:~sc:/tmp:/var/tmp:/var")
	; print fd2
	"/var/tmp/date"

    By default, fpathopen() searches along CALCPATH.

    Added the calcpath() builtin function to return the current value
    of CALCPATH.

    Fixed prompt characters in the EXAMPLE section of help files.

    Fixed problems related to the protect function and its documentation.
    This bug was reported by David Gilham <davidgilham at gmail dot com>.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Raised the limit of exponent in exponential notation.  It was set to
    arbitrary 1000000 (making 1e1000001 in invalid exponential notation
    value).  The exponent for exponential notation is now int(MAXLONG/10).
    On 32 bit machines, this means a limit of 214748364.  On 64 bit
    machines, this means 922337203685477580.  Of course, you may not
    have enough memory to hold such huge values, but if you did you can
    now express such values in exponential notation.

    Added log() builtin for base 10 logarithm.

    Fixed problems where internal use of libc strcpy() might have caused
    a buffer overflow.  Calc now only uses libc strcpy() when the source
    string is a constant.

    The calc STRING and STRINGHEAD now use the standard size_t (an unsigned
    type) length.  Calc mostly uses size_t in dealing with string lengths
    and object sizes when possible.

    Added ${CCWERR} make variable to allow one to force compiler warnings
    to be treated as errors.  The ${CC} make variable now uses ${CCWERR}
    however the ${LCC} (used by the Makefile test code for building hsrc
    files) does not use ${CCWERR}.  By default, ${CCWERR} is empty.
    In development Makefiles, we set CCWERR= -Werror to force us to
    address compiler warnings before the next release.

    The calc make variable, CALCPAGER, now defaults to CALCPAGER= less
    because the less utility is now very common.  Set CALCPAGER= more
    if you do not have less.

    Calc source had two styles of switch indentation.  Converted the
    style where case statements were indented with respect to the switch
    statement into the style where the case statements are at the same
    level.  When comparing with older source, one may use the -b argument
    of the diff command to ignore changes in amount of white space:

    	diff -b -r -u calc-2.11.11 calc-2.12.0

    The read, write, and help commands use the value of global string
    variable if the symbol name starts with a $.  For example:

    	global x = "lucas.cal";
	read $x;	/* same as read lucas.cal or read "lucas.cal" */

    Added dotest.cal resource.  Based on a design by Ernest Bowen
    <ebowen at une dot edu dot au>, the dotest evaluates individual
    lines from a file.  The dotest() function takes 1 to 3 arguments:

	dotest(dotest_file [,dotest_code [,dotest_maxcond]])

	dotest_file

	    Search along CALCPATH for dotest_file, which contains lines that
	    should evaluate to 1.  Comment lines and empty lines are ignored.
	    Comment lines should use ## instead of the multi like /* ... */
	    because lines are evaluated one line at a time.

	dotest_code

	    Assign the code number that is to be printed at the start of
	    each non-error line and after **** in each error line.
	    The default code number is 999.

	dotest_maxcond

	    The maximum number of error conditions that may be detected.
	    An error condition is not a sign of a problem, in some cases
	    a line deliberately forces an error condition.  A value of -1,
	    the default, implies a maximum of 2147483647.

	Global variables and functions must be declared ahead of time because
	the dotest scope of evaluation is a line at a time.  For example:

	    ; read dotest.cal
	    ; read set8700.cal
	    ; dotest("set8700.line");

    Updated the todo / wish list items.  The top priority now is to
    convert calc to GNU autoconf / configure to build the calc.

	; help todo

    Added missing help file for the stoponerror() builtin.

    Corrected and improved the help documentation for factor and lfactor.

    Fixed a problem where some error messages that should have been
    written to a file or string, went to stderr instead.  This bug was
    fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Corrected the documentation relating to the calc -c command line option.
    The -c relates to scan/parse errors only, not execution errors.

    Corrected a stack overflow problem where the math_fmt() in zio.c
    could be induced to overflow the stack.  This problem was independently
    reported by Chew Keong Tan of Secunia Research <vuln at secunia dot com>.

    Corrected a stack overflow problem where the scanerror() in token.c
    could be induced to overflow the stack by a malformed token.

    Made math_error() in math_error.c more robust against a error
    message constant that is too long.

    Made read_bindings() in hist.c more robust against very long bindings
    config lines.

    Made listsort() in listfunc.c and matsort() matfunc.c more robust
    against sorting of impossibly huge lists and matrices.

    Warnings about an undefining a builtin or undefined function, a
    constant before the comma operator, and an unterminated comment is
    now processed by scanerrors (not simply written directly to stderr).
    These warnings file and line number in which the "error" occurred
    as well as a more precise message than before.  If using -c on the
    calc command line or if stoponerror(-1), then assuming there are
    no other compile errors, only the unterminated comment will stop
    completion of the function being defined.

    The cal/regress.cal now reads most of the calc resource files.

    The issq() test had a slight performance boost.  A minor note
    was added to the help/issq file.

    Improved the documentation of the mul2, sq2, pow2, and redc2 config
    parameters in help/config.

    Added config("baseb"), a read-only configuration value to return
    the number of bits in the fundamental base in which calculations
    are performed.  This is a read-only configuration value.

    Calc now will allow syntax such as ++*p-- and  ++*----*++p----
    where p is an lvalue; successful evaluation of course require the
    successive operations to be performed to have operands of appropriate
    types; e.g. in *A, A is usually an lvalue whose current value is a
    pointer. ++ and -- act on lvalues. In the above examples there are
    implied parentheses from the beginning to immediately after p. If
    there are no pre ++ or -- operations, as in **p++.  The implied
    parentheses are from immediately before p to the end.

    Improved the error message when && is used as a prefix operator.

    Changed the help/config file to read like a builtin function help file.

    One can no longer set to 1, or to a value < 0, the config()
    parameters: "mul2", "sq2", "pow2", and "redc2".  These values
    in the past would result in improper configuration of internal
    calc algorithms.  Changed cal/test4100.cal to use the minimal
    value of 2 for "pow2", and "redc2".

    Changed the default values for the following config() parameters:

    	config("mul2") == 1780
	config("sq2") == 3388
	config("pow2") == 176

	These values were determined established on a 1.8GHz AMD 32-bit
	CPU of ~3406 BogoMIPS by the new resource file:

	    cal/alg_config.cal

   Regarding the alg_config.cal resource file:

	The best_mul2() function returns the optimal value of config("mul2").
	The best_sq2() function returns the optimal value of config("sq2").
	The best_pow2() function returns the optimal value of config("pow2").
	The other functions are just support functions.

	By design, best_mul2(), best_sq2(), and best_pow2() take a few
	minutes to run.  These functions increase the number of times a
	given computational loop is executed until a minimum amount of CPU
	time is consumed.  To watch these functions progress, one can set
	the config("user_debug") value.

	Here is a suggested way to use the alg_config.cal resource file:

	    ; read alg_config
	    ; config("user_debug",2),;
	    ; best_mul2(); best_sq2(); best_pow2();
	    ; best_mul2(); best_sq2(); best_pow2();
	    ; best_mul2(); best_sq2(); best_pow2();

	NOTE: It is perfectly normal for the optimal value returned
	to differ slightly from run to run.  Slight variations due to
	inaccuracy in CPU timings will cause the best value returned to
	differ slightly from run to run.

	See "help resource" for more information on alg_config.cal.

    Updated the "help variable" text to reflect the current calc
    use of ` (backquote), * (star), and & (ampersand).

    Removal of some restrictions on the use of the same identifier
    for more than one of parameter, local, static or global variable.

	For example, at command level, one could use:

	    for (local x = 0; x < 10; x++) print sqrt(x);

	At the beginning of a statement, "(global A)" is a way of
	indicating a reference to the variable A, whereas "global A"
	would be taken as a declaration. Parentheses are not required in
	"++global A" or "global A++" when "global" is used in this way.

	The patch extends this "specifier" (or "qualifier") feature
	to static variables, but such that "static A" refers only
	to a static variable at the current file and function scope
	levels. (If there is already a static variable A at the current
	file and function levels, a declaration statement "static A"
	would end the scope of that variable and define a new static
	variable with identifier A. A "global A" declaration is more
	drastic in that it ends the scope of any static variable A at
	the same or higher scope levels.)

	Unlike a static declaration in which an "initialization" occurs at
	most once, in the specifier case, "static A = expr" is simply an
	assignment which may be repeated any number of times.  An example
	of its use is:

	    define np() = static a = nextprime(a);

	For n not too large, the n-th call to this function will
	return the n-th prime. The variable a here will be private to
	the function.

	Because one can use "global", "local" or "static" to specify a
	type of variable, there seems little point in restricting the
	ways identifiers that can be used in more than one of these
	or as parameters. Obviously, introducing A as a local variable
	when it is being used as a parameter can lead to confusion and a
	warning is appropriate, but if it is to be used only occasionally,
	it might be convenient to be able to refer to it as "local A"
	rather than introducing another identifier. While it may be
	silly to use the same identifier for both a parameter and local
	variable, it should not be illegal.

    Added warnings for possibly questionable code in function definitions.

    Added config("redecl_warn", boolean) to control if calc issues
    warnings about variables being declared.  The config("redecl_warn")
    value is TRUE by default.

    Added config("dupvar_warn", boolean) to control if calc issues
    warnings about when variable names collide.  The config("dupvar_warn")
    value is TRUE by default.  Examples of variable name collisions
    include when:

    	* both local and static variables have the same name
    	* both local and global variables have the same name
    	* both function parameter and local variables have the same name
    	* both function parameter and global variables have the same name

    Fix of a bug which causes some static variables not to be correctly
    unscoped when their identifiers are used in a global declaration.

    Change of "undefine" from a command-level keyword to statement level and
    introduction of an "undefine static A" statement to end the scope of a
    static variable A at the current file/function levels.

    Change/restored the syntax rules for "for" and "while" loops to
    recognize an unescaped newline in top-level command-level statements.

    Updated help/avg, help/define, help/fprintf, help/gcd, help/hash,
    help/hmean, help/lcm, help/max, help/min, help/null, help/poly,
    help/printf, help/ssq, help/strcat, help/strprintf, help/sum,
    help/xor.

    Changed the definition of the function ssq() to enable list arguments
    to be processed in the same way as in sum().  For example:

    	ssq(1,2, list(3,4,list(5,6)), list(), 7, 8)

    returns the value of 1^2 + 2^2 + ... + 8^2 == 204.

    Added the calc resource sumtimes.cal, to give the runtimes for
    various ways of evaluating sums, sums of squares, etc, for large
    lists and matrices.  For example:

    	read slet at users dot sourceforge dot net>.

    Fixed a problem where some old MS environments failed some of the
    regression tests because "read -once foo.cal" was not behaving
    correctly due to how the _fullpath() was being called.  Thanks for
    this fix goes to Anatoly <notexistent-anb at yandex dot ru>.

    Documented the mis-feature about how calc parses if, for, while
    and do statements in an unexpected way.   For example:

	This works as expected:

	    if (expr) {
		...
	    }

	However this WILL NOT WORK AS EXPECTED:

	    if (expr)
	    {
		...
	    }

	because calc will parse the if being terminated by
	an empty statement followed by a

	    if (expr) ;
	    {
		...
	    }

    See also "help statement", "help unexpected", "help todo", and
    "help bugs".


The following are the changes from calc version 2.12.1 to 2.12.1.5:

    Fixed minor typos in the 'version 2.12.0 to 2.12.0.8' section below.
    Made minor formatting changes as well.

    Changed use of ${Q} in the Makefile to avoid an make "feature"
    related to OpenBSD.  Added ${RM} make variable for make tools that
    do not have builtin defined terms.

    Removed the ECHO_PROG Makefile variable.  Also removed it from
    the sysinfo() custom function.

    Improved the support for cross-compiled environments by using
    make symbols for all non-shell commands executed by Makefiles.

    Fixed a problem with the make chk awk script which failed under
    OS X 10.4.7.

    Fixed a few minor variables that were not set to default values in
    lower level Makefiles.

    Fixed a reference to a non-existent make variable in HOWTO.INSTALL.


The following are the changes from calc version 2.12.0 to 2.12.0.8:

    Fixed ellip.cal to deal with a calc syntax change that happened
    many ages ago but was never applied to this file until now.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Fixed a problem where comments using # followed by a !, newline or
    another # works.  This bug was fixed by Ernest Bowen <ebowen at une
    dot edu dot au>.

    The show builtins display for functions with long descriptions
    is now broken into multi-line descriptions.

    The str functions, such as strcpy(s1, s2), will now copy as many
    characters as possible from s2 to s1, treating '\0' like any other
    character until the end of s2 is reached. If s2 is shorter than s1,
    a '\0' is inserted.

    The strcmp(s1, s2) builtin, for strings s1, s2: strcmp(s1, s2) == 0 now
    means the same as s1 == s2.

    The str(s) builtin has been changed so that it will return only the
    string formed by the characters of 's' up to the first '\0'.

    The substr(s, start, num) builtin has been changed so that '\0' characters
    are treated like any other.

    Fixed a bug where strcpy("", "a") used to cause a segmentation fault.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Make minor change to natnumset.cal in how the tail variable is initialized.

    Fixed bugs in the strcmp, strncmp, strcpy, and strncpy help files.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Added cal/screen.cal which Defines ANSI control sequences providing
    (i.e., cursor movement, changing foreground or background color,
    etc.) for VT100 terminals and terminal window emulators (i.e., xterm,
    Apple OS/X Terminal, etc.) that support them.  For example:

	; read screen
	; print green:"This is green. ":red:"This is red.":black

    Fixed a bug where too many open files returned E_FOPEN3.  Now
    a new error symbol F_MANYOPEN is used for too many open files.

    Added the builtin function fpathopen() to open a file while
    searching along a path:

    	; fd2 = fpathopen("tmp/date", "r", ".:~:~sc:/tmp:/var/tmp:/var")
	; print fd2
	"/var/tmp/date"

    By default, fpathopen() searches along CALCPATH.

    Added the calcpath() builtin function to return the current value
    of CALCPATH.

    Fixed prompt characters in the EXAMPLE section of help files.

    Fixed problems related to the protect function and its documentation.
    This bug was reported by David Gilham <davidgilham at gmail dot com>.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Raised the limit of exponent in exponential notation.  It was set to
    arbitrary 1000000 (making 1e1000001 in invalid exponential notation
    value).  The exponent for exponential notation is now int(MAXLONG/10).
    On 32 bit machines, this means a limit of 214748364.  On 64 bit
    machines, this means 922337203685477580.  Of course, you may not
    have enough memory to hold such huge values, but if you did you can
    now express such values in exponential notation.

    Added log() builtin for base 10 logarithm.

    Fixed problems where internal use of libc strcpy() might have caused
    a buffer overflow.  Calc now only uses libc strcpy() when the source
    string is a constant.

    The calc STRING and STRINGHEAD now use the standard size_t (an unsigned
    type) length.  Calc mostly uses size_t in dealing with string lengths
    and object sizes when possible.

    Added ${CCWERR} make variable to allow one to force compiler warnings
    to be treated as errors.  The ${CC} make variable now uses ${CCWERR}
    however the ${LCC} (used by the Makefile test code for building hsrc
    files) does not use ${CCWERR}.  By default, ${CCWERR} is empty.
    In development Makefiles, we set CCWERR= -Werror to force us to
    address compiler warnings before the next release.

    The calc make variable, CALCPAGER, now defaults to CALCPAGER= less
    because the less utility is now very common.  Set CALCPAGER= more
    if you do not have less.

    Calc source had two styles of switch indentation.  Converted the
    style where case statements were indented with respect to the switch
    statement into the style where the case statements are at the same
    level.  When comparing with older source, one may use the -b argument
    of the diff command to ignore changes in amount of white space:

    	diff -b -r -u calc-2.11.11 calc-2.12.0

    The read, write, and help commands use the value of global string
    variable if the symbol name starts with a $.  For example:

    	global x = "lucas.cal";
	read $x;	/* same as read lucas.cal or read "lucas.cal" */

    Added dotest.cal resource.  Based on a design by Ernest Bowen
    <ebowen at une dot edu dot au>, the dotest evaluates individual
    lines from a file.  The dotest() function takes 1 to 3 arguments:

	dotest(dotest_file [,dotest_code [,dotest_maxcond]])

	dotest_file

	    Search along CALCPATH for dotest_file, which contains lines that
	    should evaluate to 1.  Comment lines and empty lines are ignored.
	    Comment lines should use ## instead of the multi like /* ... */
	    because lines are evaluated one line at a time.

	dotest_code

	    Assign the code number that is to be printed at the start of
	    each non-error line and after **** in each error line.
	    The default code number is 999.

	dotest_maxcond

	    The maximum number of error conditions that may be detected.
	    An error condition is not a sign of a problem, in some cases
	    a line deliberately forces an error condition.  A value of -1,
	    the default, implies a maximum of 2147483647.

	Global variables and functions must be declared ahead of time because
	the dotest scope of evaluation is a line at a time.  For example:

	    ; read dotest.cal
	    ; read set8700.cal
	    ; dotest("set8700.line");

    Updated the todo / wish list items.  The top priority now is to
    convert calc to GNU autoconf / configure to build the calc.

	; help todo

    Added missing help file for the stoponerror() builtin.

    Corrected and improved the help documentation for factor and lfactor.

    Fixed a problem where some error messages that should have been
    written to a file or string, went to stderr instead.  This bug was
    fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Corrected the documentation relating to the calc -c command line option.
    The -c relates to scan/parse errors only, not execution errors.

    Corrected a stack overflow problem where the math_fmt() in zio.c
    could be induced to overflow the stack.  This problem was independently
    reported by Chew Keong Tan of Secunia Research <vuln at secunia dot com>.

    Corrected a stack overflow problem where the scanerror() in token.c
    could be induced to overflow the stack by a malformed token.

    Made math_error() in math_error.c more robust against a error
    message constant that is too long.

    Made read_bindings() in hist.c more robust against very long bindings
    config lines.

    Made listsort() in listfunc.c and matsort() matfunc.c more robust
    against sorting of impossibly huge lists and matrices.

    Warnings about an undefining a builtin or undefined function, a
    constant before the comma operator, and an unterminated comment is
    now processed by scanerrors (not simply written directly to stderr).
    These warnings file and line number in which the "error" occurred
    as well as a more precise message than before.  If using -c on the
    calc command line or if stoponerror(-1), then assuming there are
    no other compile errors, only the unterminated comment will stop
    completion of the function being defined.

    The cal/regress.cal now reads most of the calc resource files.

    The issq() test had a slight performance boost.  A minor note
    was added to the help/issq file.

    Improved the documentation of the mul2, sq2, pow2, and redc2 config
    parameters in help/config.

    Added config("baseb"), a read-only configuration value to return
    the number of bits in the fundamental base in which calculations
    are performed.  This is a read-only configuration value.

    Calc now will allow syntax such as ++*p-- and  ++*----*++p----
    where p is an lvalue; successful evaluation of course require the
    successive operations to be performed to have operands of appropriate
    types; e.g. in *A, A is usually an lvalue whose current value is a
    pointer. ++ and -- act on lvalues. In the above examples there are
    implied parentheses from the beginning to immediately after p. If
    there are no pre ++ or -- operations, as in **p++.  The implied
    parentheses are from immediately before p to the end.

    Improved the error message when && is used as a prefix operator.

    Changed the help/config file to read like a builtin function help file.

    One can no longer set to 1, or to a value < 0, the config()
    parameters: "mul2", "sq2", "pow2", and "redc2".  These values
    in the past would result in improper configuration of internal
    calc algorithms.  Changed cal/test4100.cal to use the minimal
    value of 2 for "pow2", and "redc2".

    Changed the default values for the following config() parameters:

    	config("mul2") == 1780
	config("sq2") == 3388
	config("pow2") == 176

	These values were determined established on a 1.8GHz AMD 32-bit
	CPU of ~3406 BogoMIPS by the new resource file:

	    cal/alg_config.cal

   Regarding the alg_config.cal resource file:

	The best_mul2() function returns the optimal value of config("mul2").
	The best_sq2() function returns the optimal value of config("sq2").
	The best_pow2() function returns the optimal value of config("pow2").
	The other functions are just support functions.

	By design, best_mul2(), best_sq2(), and best_pow2() take a few
	minutes to run.  These functions increase the number of times a
	given computational loop is executed until a minimum amount of CPU
	time is consumed.  To watch these functions progress, one can set
	the config("user_debug") value.

	Here is a suggested way to use the alg_config.cal resource file:

	    ; read alg_config
	    ; config("user_debug",2),;
	    ; best_mul2(); best_sq2(); best_pow2();
	    ; best_mul2(); best_sq2(); best_pow2();
	    ; best_mul2(); best_sq2(); best_pow2();

	NOTE: It is perfectly normal for the optimal value returned
	to differ slightly from run to run.  Slight variations due to
	inaccuracy in CPU timings will cause the best value returned to
	differ slightly from run to run.

	See "help resource" for more information on alg_config.cal.

    Updated the "help variable" text to reflect the current calc
    use of ` (backquote), * (star), and & (ampersand).

    Removal of some restrictions on the use of the same identifier
    for more than one of parameter, local, static or global variable.

	For example, at command level, one could use:

	    for (local x = 0; x < 10; x++) print sqrt(x);

	At the beginning of a statement, "(global A)" is a way of
	indicating a reference to the variable A, whereas "global A"
	would be taken as a declaration. Parentheses are not required in
	"++global A" or "global A++" when "global" is used in this way.

	The patch extends this "specifier" (or "qualifier") feature
	to static variables, but such that "static A" refers only
	to a static variable at the current file and function scope
	levels. (If there is already a static variable A at the current
	file and function levels, a declaration statement "static A"
	would end the scope of that variable and define a new static
	variable with identifier A. A "global A" declaration is more
	drastic in that it ends the scope of any static variable A at
	the same or higher scope levels.)

	Unlike a static declaration in which an "initialization" occurs at
	most once, in the specifier case, "static A = expr" is simply an
	assignment which may be repeated any number of times.  An example
	of its use is:

	    define np() = static a = nextprime(a);

	For n not too large, the n-th call to this function will
	return the n-th prime. The variable a here will be private to
	the function.

	Because one can use "global", "local" or "static" to specify a
	type of variable, there seems little point in restricting the
	ways identifiers that can be used in more than one of these
	or as parameters. Obviously, introducing A as a local variable
	when it is being used as a parameter can lead to confusion and a
	warning is appropriate, but if it is to be used only occasionally,
	it might be convenient to be able to refer to it as "local A"
	rather than introducing another identifier. While it may be
	silly to use the same identifier for both a parameter and local
	variable, it should not be illegal.

    Added warnings for possibly questionable code in function definitions.

    Added config("redecl_warn", boolean) to control if calc issues
    warnings about variables being declared.  The config("redecl_warn")
    value is TRUE by default.

    Added config("dupvar_warn", boolean) to control if calc issues
    warnings about when variable names collide.  The config("dupvar_warn")
    value is TRUE by default.  Examples of variable name collisions
    include when:

    	* both local and static variables have the same name
    	* both local and global variables have the same name
    	* both function parameter and local variables have the same name
    	* both function parameter and global variables have the same name

    Fix of a bug which causes some static variables not to be correctly
    unscoped when their identifiers are used in a global declaration.

    Change of "undefine" from a command-level keyword to statement level and
    introduction of an "undefine static A" statement to end the scope of a
    static variable A at the current file/function levels.

    Change/restored the syntax rules for "for" and "while" loops to
    recognize an unescaped newline in top-level command-level statements.

    Updated help/avg, help/define, help/fprintf, help/gcd, help/hash,
    help/hmean, help/lcm, help/max, help/min, help/null, help/poly,
    help/printf, help/ssq, help/strcat, help/strprintf, help/sum,
    help/xor.

    Changed the definition of the function ssq() to enable list arguments
    to be processed in the same way as in sum().  For example:

    	ssq(1,2, list(3,4,list(5,6)), list(), 7, 8)

    returns the value of 1^2 + 2^2 + ... + 8^2 == 204.

    Added the calc resource sumtimes.cal, to give the runtimes for
    various ways of evaluating sums, sums of squares, etc, for large
    lists and matrices.  For example:

    	read slet at users dot sourceforge dot net>.

    Fixed a problem where some old MS environments failed some of the
    regression tests because "read -once foo.cal" was not behaving
    correctly due to how the _fullpath() was being called.  Thanks for
    this fix goes to Anatoly <notexistent-anb at yandex dot ru>.

    Documented the mis-feature about how calc parses if, for, while
    and do statements in an unexpected way.   For example:

	This works as expected:

	    if (expr) {
		...
	    }

	However this WILL NOT WORK AS EXPECTED:

	    if (expr)
	    {
		...
	    }

	because calc will parse the if being terminated by
	an empty statement followed by a

	    if (expr) ;
	    {
		...
	    }

    See also "help statement", "help unexpected", "help todo", and
    "help bugs".


The following are the changes from calc version 2.12.1 to 2.12.1.5:

    Fixed minor typos in the 'version 2.12.0 to 2.12.0.8' section below.
    Made minor formatting changes as well.

    Changed use of ${Q} in the Makefile to avoid an make "feature"
    related to OpenBSD.  Added ${RM} make variable for make tools that
    do not have builtin defined terms.

    Removed the ECHO_PROG Makefile variable.  Also removed it from
    the sysinfo() custom function.

    Improved the support for cross-compiled environments by using
    make symbols for all non-shell commands executed by Makefiles.

    Fixed a problem with the make chk awk script which failed under
    OS X 10.4.7.

    Fixed a few minor variables that were not set to default values in
    lower level Makefiles.

    Fixed a reference to a non-existent make variable in HOWTO.INSTALL.


The following are the changes from calc version 2.12.0 to 2.12.0.8:

    Fixed ellip.cal to deal with a calc syntax change that happened
    many ages ago but was never applied to this file until now.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Fixed a problem where comments using # followed by a !, newline or
    another # works.  This bug was fixed by Ernest Bowen <ebowen at une
    dot edu dot au>.

    The show builtins display for functions with long descriptions
    is now broken into multi-line descriptions.

    The str functions, such as strcpy(s1, s2), will now copy as many
    characters as possible from s2 to s1, treating '\0' like any other
    character until the end of s2 is reached. If s2 is shorter than s1,
    a '\0' is inserted.

    The strcmp(s1, s2) builtin, for strings s1, s2: strcmp(s1, s2) == 0 now
    means the same as s1 == s2.

    The str(s) builtin has been changed so that it will return only the
    string formed by the characters of 's' up to the first '\0'.

    The substr(s, start, num) builtin has been changed so that '\0' characters
    are treated like any other.

    Fixed a bug where strcpy("", "a") used to cause a segmentation fault.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Make minor change to natnumset.cal in how the tail variable is initialized.

    Fixed bugs in the strcmp, strncmp, strcpy, and strncpy help files.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Added cal/screen.cal which Defines ANSI control sequences providing
    (i.e., cursor movement, changing foreground or background color,
    etc.) for VT100 terminals and terminal window emulators (i.e., xterm,
    Apple OS/X Terminal, etc.) that support them.  For example:

	; read screen
	; print green:"This is green. ":red:"This is red.":black

    Fixed a bug where too many open files returned E_FOPEN3.  Now
    a new error symbol F_MANYOPEN is used for too many open files.

    Added the builtin function fpathopen() to open a file while
    searching along a path:

    	; fd2 = fpathopen("tmp/date", "r", ".:~:~sc:/tmp:/var/tmp:/var")
	; print fd2
	"/var/tmp/date"

    By default, fpathopen() searches along CALCPATH.

    Added the calcpath() builtin function to return the current value
    of CALCPATH.

    Fixed prompt characters in the EXAMPLE section of help files.

    Fixed problems related to the protect function and its documentation.
    This bug was reported by David Gilham <davidgilham at gmail dot com>.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Raised the limit of exponent in exponential notation.  It was set to
    arbitrary 1000000 (making 1e1000001 in invalid exponential notation
    value).  The exponent for exponential notation is now int(MAXLONG/10).
    On 32 bit machines, this means a limit of 214748364.  On 64 bit
    machines, this means 922337203685477580.  Of course, you may not
    have enough memory to hold such huge values, but if you did you can
    now express such values in exponential notation.

    Added log() builtin for base 10 logarithm.

    Fixed problems where internal use of libc strcpy() might have caused
    a buffer overflow.  Calc now only uses libc strcpy() when the source
    string is a constant.

    The calc STRING and STRINGHEAD now use the standard size_t (an unsigned
    type) length.  Calc mostly uses size_t in dealing with string lengths
    and object sizes when possible.

    Added ${CCWERR} make variable to allow one to force compiler warnings
    to be treated as errors.  The ${CC} make variable now uses ${CCWERR}
    however the ${LCC} (used by the Makefile test code for building hsrc
    files) does not use ${CCWERR}.  By default, ${CCWERR} is empty.
    In development Makefiles, we set CCWERR= -Werror to force us to
    address compiler warnings before the next release.

    The calc make variable, CALCPAGER, now defaults to CALCPAGER= less
    because the less utility is now very common.  Set CALCPAGER= more
    if you do not have less.

    Calc source had two styles of switch indentation.  Converted the
    style where case statements were indented with respect to the switch
    statement into the style where the case statements are at the same
    level.  When comparing with older source, one may use the -b argument
    of the diff command to ignore changes in amount of white space:

    	diff -b -r -u calc-2.11.11 calc-2.12.0

    The read, write, and help commands use the value of global string
    variable if the symbol name starts with a $.  For example:

    	global x = "lucas.cal";
	read $x;	/* same as read lucas.cal or read "lucas.cal" */

    Added dotest.cal resource.  Based on a design by Ernest Bowen
    <ebowen at une dot edu dot au>, the dotest evaluates individual
    lines from a file.  The dotest() function takes 1 to 3 arguments:

	dotest(dotest_file [,dotest_code [,dotest_maxcond]])

	dotest_file

	    Search along CALCPATH for dotest_file, which contains lines that
	    should evaluate to 1.  Comment lines and empty lines are ignored.
	    Comment lines should use ## instead of the multi like /* ... */
	    because lines are evaluated one line at a time.

	dotest_code

	    Assign the code number that is to be printed at the start of
	    each non-error line and after **** in each error line.
	    The default code number is 999.

	dotest_maxcond

	    The maximum number of error conditions that may be detected.
	    An error condition is not a sign of a problem, in some cases
	    a line deliberately forces an error condition.  A value of -1,
	    the default, implies a maximum of 2147483647.

	Global variables and functions must be declared ahead of time because
	the dotest scope of evaluation is a line at a time.  For example:

	    ; read dotest.cal
	    ; read set8700.cal
	    ; dotest("set8700.line");

    Updated the todo / wish list items.  The top priority now is to
    convert calc to GNU autoconf / configure to build the calc.

	; help todo

    Added missing help file for the stoponerror() builtin.

    Corrected and improved the help documentation for factor and lfactor.

    Fixed a problem where some error messages that should have been
    written to a file or string, went to stderr instead.  This bug was
    fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Corrected the documentation relating to the calc -c command line option.
    The -c relates to scan/parse errors only, not execution errors.

    Corrected a stack overflow problem where the math_fmt() in zio.c
    could be induced to overflow the stack.  This problem was independently
    reported by Chew Keong Tan of Secunia Research <vuln at secunia dot com>.

    Corrected a stack overflow problem where the scanerror() in token.c
    could be induced to overflow the stack by a malformed token.

    Made math_error() in math_error.c more robust against a error
    message constant that is too long.

    Made read_bindings() in hist.c more robust against very long bindings
    config lines.

    Made listsort() in listfunc.c and matsort() matfunc.c more robust
    against sorting of impossibly huge lists and matrices.

    Warnings about an undefining a builtin or undefined function, a
    constant before the comma operator, and an unterminated comment is
    now processed by scanerrors (not simply written directly to stderr).
    These warnings file and line number in which the "error" occurred
    as well as a more precise message than before.  If using -c on the
    calc command line or if stoponerror(-1), then assuming there are
    no other compile errors, only the unterminated comment will stop
    completion of the function being defined.

    The cal/regress.cal now reads most of the calc resource files.

    The issq() test had a slight performance boost.  A minor note
    was added to the help/issq file.

    Improved the documentation of the mul2, sq2, pow2, and redc2 config
    parameters in help/config.

    Added config("baseb"), a read-only configuration value to return
    the number of bits in the fundamental base in which calculations
    are performed.  This is a read-only configuration value.

    Calc now will allow syntax such as ++*p-- and  ++*----*++p----
    where p is an lvalue; successful evaluation of course require the
    successive operations to be performed to have operands of appropriate
    types; e.g. in *A, A is usually an lvalue whose current value is a
    pointer. ++ and -- act on lvalues. In the above examples there are
    implied parentheses from the beginning to immediately after p. If
    there are no pre ++ or -- operations, as in **p++.  The implied
    parentheses are from immediately before p to the end.

    Improved the error message when && is used as a prefix operator.

    Changed the help/config file to read like a builtin function help file.

    One can no longer set to 1, or to a value < 0, the config()
    parameters: "mul2", "sq2", "pow2", and "redc2".  These values
    in the past would result in improper configuration of internal
    calc algorithms.  Changed cal/test4100.cal to use the minimal
    value of 2 for "pow2", and "redc2".

    Changed the default values for the following config() parameters:

    	config("mul2") == 1780
	config("sq2") == 3388
	config("pow2") == 176

	These values were determined established on a 1.8GHz AMD 32-bit
	CPU of ~3406 BogoMIPS by the new resource file:

	    cal/alg_config.cal

   Regarding the alg_config.cal resource file:

	The best_mul2() function returns the optimal value of config("mul2").
	The best_sq2() function returns the optimal value of config("sq2").
	The best_pow2() function returns the optimal value of config("pow2").
	The other functions are just support functions.

	By design, best_mul2(), best_sq2(), and best_pow2() take a few
	minutes to run.  These functions increase the number of times a
	given computational loop is executed until a minimum amount of CPU
	time is consumed.  To watch these functions progress, one can set
	the config("user_debug") value.

	Here is a suggested way to use the alg_config.cal resource file:

	    ; read alg_config
	    ; config("user_debug",2),;
	    ; best_mul2(); best_sq2(); best_pow2();
	    ; best_mul2(); best_sq2(); best_pow2();
	    ; best_mul2(); best_sq2(); best_pow2();

	NOTE: It is perfectly normal for the optimal value returned
	to differ slightly from run to run.  Slight variations due to
	inaccuracy in CPU timings will cause the best value returned to
	differ slightly from run to run.

	See "help resource" for more information on alg_config.cal.

    Updated the "help variable" text to reflect the current calc
    use of ` (backquote), * (star), and & (ampersand).

    Removal of some restrictions on the use of the same identifier
    for more than one of parameter, local, static or global variable.

	For example, at command level, one could use:

	    for (local x = 0; x < 10; x++) print sqrt(x);

	At the beginning of a statement, "(global A)" is a way of
	indicating a reference to the variable A, whereas "global A"
	would be taken as a declaration. Parentheses are not required in
	"++global A" or "global A++" when "global" is used in this way.

	The patch extends this "specifier" (or "qualifier") feature
	to static variables, but such that "static A" refers only
	to a static variable at the current file and function scope
	levels. (If there is already a static variable A at the current
	file and function levels, a declaration statement "static A"
	would end the scope of that variable and define a new static
	variable with identifier A. A "global A" declaration is more
	drastic in that it ends the scope of any static variable A at
	the same or higher scope levels.)

	Unlike a static declaration in which an "initialization" occurs at
	most once, in the specifier case, "static A = expr" is simply an
	assignment which may be repeated any number of times.  An example
	of its use is:

	    define np() = static a = nextprime(a);

	For n not too large, the n-th call to this function will
	return the n-th prime. The variable a here will be private to
	the function.

	Because one can use "global", "local" or "static" to specify a
	type of variable, there seems little point in restricting the
	ways identifiers that can be used in more than one of these
	or as parameters. Obviously, introducing A as a local variable
	when it is being used as a parameter can lead to confusion and a
	warning is appropriate, but if it is to be used only occasionally,
	it might be convenient to be able to refer to it as "local A"
	rather than introducing another identifier. While it may be
	silly to use the same identifier for both a parameter and local
	variable, it should not be illegal.

    Added warnings for possibly questionable code in function definitions.

    Added config("redecl_warn", boolean) to control if calc issues
    warnings about variables being declared.  The config("redecl_warn")
    value is TRUE by default.

    Added config("dupvar_warn", boolean) to control if calc issues
    warnings about when variable names collide.  The config("dupvar_warn")
    value is TRUE by default.  Examples of variable name collisions
    include when:

    	* both local and static variables have the same name
    	* both local and global variables have the same name
    	* both function parameter and local variables have the same name
    	* both function parameter and global variables have the same name

    Fix of a bug which causes some static variables not to be correctly
    unscoped when their identifiers are used in a global declaration.

    Change of "undefine" from a command-level keyword to statement level and
    introduction of an "undefine static A" statement to end the scope of a
    static variable A at the current file/function levels.

    Change/restored the syntax rules for "for" and "while" loops to
    recognize an unescaped newline in top-level command-level statements.

    Updated help/avg, help/define, help/fprintf, help/gcd, help/hash,
    help/hmean, help/lcm, help/max, help/min, help/null, help/poly,
    help/printf, help/ssq, help/strcat, help/strprintf, help/sum,
    help/xor.

    Changed the definition of the function ssq() to enable list arguments
    to be processed in the same way as in sum().  For example:

    	ssq(1,2, list(3,4,list(5,6)), list(), 7, 8)

    returns the value of 1^2 + 2^2 + ... + 8^2 == 204.

    Added the calc resource sumtimes.cal, to give the runtimes for
    various ways of evaluating sums, sums of squares, etc, for large
    lists and matrices.  For example:

    	read slet at users dot sourceforge dot net>.

    Fixed a problem where some old MS environments failed some of the
    regression tests because "read -once foo.cal" was not behaving
    correctly due to how the _fullpath() was being called.  Thanks for
    this fix goes to Anatoly <notexistent-anb at yandex dot ru>.

    Documented the mis-feature about how calc parses if, for, while
    and do statements in an unexpected way.   For example:

	This works as expected:

	    if (expr) {
		...
	    }

	However this WILL NOT WORK AS EXPECTED:

	    if (expr)
	    {
		...
	    }

	because calc will parse the if being terminated by
	an empty statement followed by a

	    if (expr) ;
	    {
		...
	    }

    See also "help statement", "help unexpected", "help todo", and
    "help bugs".


The following are the changes from calc version 2.12.1 to 2.12.1.5:

    Fixed minor typos in the 'version 2.12.0 to 2.12.0.8' section below.
    Made minor formatting changes as well.

    Changed use of ${Q} in the Makefile to avoid an make "feature"
    related to OpenBSD.  Added ${RM} make variable for make tools that
    do not have builtin defined terms.

    Removed the ECHO_PROG Makefile variable.  Also removed it from
    the sysinfo() custom function.

    Improved the support for cross-compiled environments by using
    make symbols for all non-shell commands executed by Makefiles.

    Fixed a problem with the make chk awk script which failed under
    OS X 10.4.7.

    Fixed a few minor variables that were not set to default values in
    lower level Makefiles.

    Fixed a reference to a non-existent make variable in HOWTO.INSTALL.


The following are the changes from calc version 2.12.0 to 2.12.0.8:

    Fixed ellip.cal to deal with a calc syntax change that happened
    many ages ago but was never applied to this file until now.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Fixed a problem where comments using # followed by a !, newline or
    another # works.  This bug was fixed by Ernest Bowen <ebowen at une
    dot edu dot au>.

    The show builtins display for functions with long descriptions
    is now broken into multi-line descriptions.

    The str functions, such as strcpy(s1, s2), will now copy as many
    characters as possible from s2 to s1, treating '\0' like any other
    character until the end of s2 is reached. If s2 is shorter than s1,
    a '\0' is inserted.

    The strcmp(s1, s2) builtin, for strings s1, s2: strcmp(s1, s2) == 0 now
    means the same as s1 == s2.

    The str(s) builtin has been changed so that it will return only the
    string formed by the characters of 's' up to the first '\0'.

    The substr(s, start, num) builtin has been changed so that '\0' characters
    are treated like any other.

    Fixed a bug where strcpy("", "a") used to cause a segmentation fault.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Make minor change to natnumset.cal in how the tail variable is initialized.

    Fixed bugs in the strcmp, strncmp, strcpy, and strncpy help files.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Added cal/screen.cal which Defines ANSI control sequences providing
    (i.e., cursor movement, changing foreground or background color,
    etc.) for VT100 terminals and terminal window emulators (i.e., xterm,
    Apple OS/X Terminal, etc.) that support them.  For example:

	; read screen
	; print green:"This is green. ":red:"This is red.":black

    Fixed a bug where too many open files returned E_FOPEN3.  Now
    a new error symbol F_MANYOPEN is used for too many open files.

    Added the builtin function fpathopen() to open a file while
    searching along a path:

    	; fd2 = fpathopen("tmp/date", "r", ".:~:~sc:/tmp:/var/tmp:/var")
	; print fd2
	"/var/tmp/date"

    By default, fpathopen() searches along CALCPATH.

    Added the calcpath() builtin function to return the current value
    of CALCPATH.

    Fixed prompt characters in the EXAMPLE section of help files.

    Fixed problems related to the protect function and its documentation.
    This bug was reported by David Gilham <davidgilham at gmail dot com>.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Raised the limit of exponent in exponential notation.  It was set to
    arbitrary 1000000 (making 1e1000001 in invalid exponential notation
    value).  The exponent for exponential notation is now int(MAXLONG/10).
    On 32 bit machines, this means a limit of 214748364.  On 64 bit
    machines, this means 922337203685477580.  Of course, you may not
    have enough memory to hold such huge values, but if you did you can
    now express such values in exponential notation.

    Added log() builtin for base 10 logarithm.

    Fixed problems where internal use of libc strcpy() might have caused
    a buffer overflow.  Calc now only uses libc strcpy() when the source
    string is a constant.

    The calc STRING and STRINGHEAD now use the standard size_t (an unsigned
    type) length.  Calc mostly uses size_t in dealing with string lengths
    and object sizes when possible.

    Added ${CCWERR} make variable to allow one to force compiler warnings
    to be treated as errors.  The ${CC} make variable now uses ${CCWERR}
    however the ${LCC} (used by the Makefile test code for building hsrc
    files) does not use ${CCWERR}.  By default, ${CCWERR} is empty.
    In development Makefiles, we set CCWERR= -Werror to force us to
    address compiler warnings before the next release.

    The calc make variable, CALCPAGER, now defaults to CALCPAGER= less
    because the less utility is now very common.  Set CALCPAGER= more
    if you do not have less.

    Calc source had two styles of switch indentation.  Converted the
    style where case statements were indented with respect to the switch
    statement into the style where the case statements are at the same
    level.  When comparing with older source, one may use the -b argument
    of the diff command to ignore changes in amount of white space:

    	diff -b -r -u calc-2.11.11 calc-2.12.0

    The read, write, and help commands use the value of global string
    variable if the symbol name starts with a $.  For example:

    	global x = "lucas.cal";
	read $x;	/* same as read lucas.cal or read "lucas.cal" */

    Added dotest.cal resource.  Based on a design by Ernest Bowen
    <ebowen at une dot edu dot au>, the dotest evaluates individual
    lines from a file.  The dotest() function takes 1 to 3 arguments:

	dotest(dotest_file [,dotest_code [,dotest_maxcond]])

	dotest_file

	    Search along CALCPATH for dotest_file, which contains lines that
	    should evaluate to 1.  Comment lines and empty lines are ignored.
	    Comment lines should use ## instead of the multi like /* ... */
	    because lines are evaluated one line at a time.

	dotest_code

	    Assign the code number that is to be printed at the start of
	    each non-error line and after **** in each error line.
	    The default code number is 999.

	dotest_maxcond

	    The maximum number of error conditions that may be detected.
	    An error condition is not a sign of a problem, in some cases
	    a line deliberately forces an error condition.  A value of -1,
	    the default, implies a maximum of 2147483647.

	Global variables and functions must be declared ahead of time because
	the dotest scope of evaluation is a line at a time.  For example:

	    ; read dotest.cal
	    ; read set8700.cal
	    ; dotest("set8700.line");

    Updated the todo / wish list items.  The top priority now is to
    convert calc to GNU autoconf / configure to build the calc.

	; help todo

    Added missing help file for the stoponerror() builtin.

    Corrected and improved the help documentation for factor and lfactor.

    Fixed a problem where some error messages that should have been
    written to a file or string, went to stderr instead.  This bug was
    fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Corrected the documentation relating to the calc -c command line option.
    The -c relates to scan/parse errors only, not execution errors.

    Corrected a stack overflow problem where the math_fmt() in zio.c
    could be induced to overflow the stack.  This problem was independently
    reported by Chew Keong Tan of Secunia Research <vuln at secunia dot com>.

    Corrected a stack overflow problem where the scanerror() in token.c
    could be induced to overflow the stack by a malformed token.

    Made math_error() in math_error.c more robust against a error
    message constant that is too long.

    Made read_bindings() in hist.c more robust against very long bindings
    config lines.

    Made listsort() in listfunc.c and matsort() matfunc.c more robust
    against sorting of impossibly huge lists and matrices.

    Warnings about an undefining a builtin or undefined function, a
    constant before the comma operator, and an unterminated comment is
    now processed by scanerrors (not simply written directly to stderr).
    These warnings file and line number in which the "error" occurred
    as well as a more precise message than before.  If using -c on the
    calc command line or if stoponerror(-1), then assuming there are
    no other compile errors, only the unterminated comment will stop
    completion of the function being defined.

    The cal/regress.cal now reads most of the calc resource files.

    The issq() test had a slight performance boost.  A minor note
    was added to the help/issq file.

    Improved the documentation of the mul2, sq2, pow2, and redc2 config
    parameters in help/config.

    Added config("baseb"), a read-only configuration value to return
    the number of bits in the fundamental base in which calculations
    are performed.  This is a read-only configuration value.

    Calc now will allow syntax such as ++*p-- and  ++*----*++p----
    where p is an lvalue; successful evaluation of course require the
    successive operations to be performed to have operands of appropriate
    types; e.g. in *A, A is usually an lvalue whose current value is a
    pointer. ++ and -- act on lvalues. In the above examples there are
    implied parentheses from the beginning to immediately after p. If
    there are no pre ++ or -- operations, as in **p++.  The implied
    parentheses are from immediately before p to the end.

    Improved the error message when && is used as a prefix operator.

    Changed the help/config file to read like a builtin function help file.

    One can no longer set to 1, or to a value < 0, the config()
    parameters: "mul2", "sq2", "pow2", and "redc2".  These values
    in the past would result in improper configuration of internal
    calc algorithms.  Changed cal/test4100.cal to use the minimal
    value of 2 for "pow2", and "redc2".

    Changed the default values for the following config() parameters:

    	config("mul2") == 1780
	config("sq2") == 3388
	config("pow2") == 176

	These values were determined established on a 1.8GHz AMD 32-bit
	CPU of ~3406 BogoMIPS by the new resource file:

	    cal/alg_config.cal

   Regarding the alg_config.cal resource file:

	The best_mul2() function returns the optimal value of config("mul2").
	The best_sq2() function returns the optimal value of config("sq2").
	The best_pow2() function returns the optimal value of config("pow2").
	The other functions are just support functions.

	By design, best_mul2(), best_sq2(), and best_pow2() take a few
	minutes to run.  These functions increase the number of times a
	given computational loop is executed until a minimum amount of CPU
	time is consumed.  To watch these functions progress, one can set
	the config("user_debug") value.

	Here is a suggested way to use the alg_config.cal resource file:

	    ; read alg_config
	    ; config("user_debug",2),;
	    ; best_mul2(); best_sq2(); best_pow2();
	    ; best_mul2(); best_sq2(); best_pow2();
	    ; best_mul2(); best_sq2(); best_pow2();

	NOTE: It is perfectly normal for the optimal value returned
	to differ slightly from run to run.  Slight variations due to
	inaccuracy in CPU timings will cause the best value returned to
	differ slightly from run to run.

	See "help resource" for more information on alg_config.cal.

    Updated the "help variable" text to reflect the current calc
    use of ` (backquote), * (star), and & (ampersand).

    Removal of some restrictions on the use of the same identifier
    for more than one of parameter, local, static or global variable.

	For example, at command level, one could use:

	    for (local x = 0; x < 10; x++) print sqrt(x);

	At the beginning of a statement, "(global A)" is a way of
	indicating a reference to the variable A, whereas "global A"
	would be taken as a declaration. Parentheses are not required in
	"++global A" or "global A++" when "global" is used in this way.

	The patch extends this "specifier" (or "qualifier") feature
	to static variables, but such that "static A" refers only
	to a static variable at the current file and function scope
	levels. (If there is already a static variable A at the current
	file and function levels, a declaration statement "static A"
	would end the scope of that variable and define a new static
	variable with identifier A. A "global A" declaration is more
	drastic in that it ends the scope of any static variable A at
	the same or higher scope levels.)

	Unlike a static declaration in which an "initialization" occurs at
	most once, in the specifier case, "static A = expr" is simply an
	assignment which may be repeated any number of times.  An example
	of its use is:

	    define np() = static a = nextprime(a);

	For n not too large, the n-th call to this function will
	return the n-th prime. The variable a here will be private to
	the function.

	Because one can use "global", "local" or "static" to specify a
	type of variable, there seems little point in restricting the
	ways identifiers that can be used in more than one of these
	or as parameters. Obviously, introducing A as a local variable
	when it is being used as a parameter can lead to confusion and a
	warning is appropriate, but if it is to be used only occasionally,
	it might be convenient to be able to refer to it as "local A"
	rather than introducing another identifier. While it may be
	silly to use the same identifier for both a parameter and local
	variable, it should not be illegal.

    Added warnings for possibly questionable code in function definitions.

    Added config("redecl_warn", boolean) to control if calc issues
    warnings about variables being declared.  The config("redecl_warn")
    value is TRUE by default.

    Added config("dupvar_warn", boolean) to control if calc issues
    warnings about when variable names collide.  The config("dupvar_warn")
    value is TRUE by default.  Examples of variable name collisions
    include when:

    	* both local and static variables have the same name
    	* both local and global variables have the same name
    	* both function parameter and local variables have the same name
    	* both function parameter and global variables have the same name

    Fix of a bug which causes some static variables not to be correctly
    unscoped when their identifiers are used in a global declaration.

    Change of "undefine" from a command-level keyword to statement level and
    introduction of an "undefine static A" statement to end the scope of a
    static variable A at the current file/function levels.

    Change/restored the syntax rules for "for" and "while" loops to
    recognize an unescaped newline in top-level command-level statements.

    Updated help/avg, help/define, help/fprintf, help/gcd, help/hash,
    help/hmean, help/lcm, help/max, help/min, help/null, help/poly,
    help/printf, help/ssq, help/strcat, help/strprintf, help/sum,
    help/xor.

    Changed the definition of the function ssq() to enable list arguments
    to be processed in the same way as in sum().  For example:

    	ssq(1,2, list(3,4,list(5,6)), list(), 7, 8)

    returns the value of 1^2 + 2^2 + ... + 8^2 == 204.

    Added the calc resource sumtimes.cal, to give the runtimes for
    various ways of evaluating sums, sums of squares, etc, for large
    lists and matrices.  For example:

    	read slet at users dot sourceforge dot net>.

    Fixed a problem where some old MS environments failed some of the
    regression tests because "read -once foo.cal" was not behaving
    correctly due to how the _fullpath() was being called.  Thanks for
    this fix goes to Anatoly <notexistent-anb at yandex dot ru>.

    Documented the mis-feature about how calc parses if, for, while
    and do statements in an unexpected way.   For example:

	This works as expected:

	    if (expr) {
		...
	    }

	However this WILL NOT WORK AS EXPECTED:

	    if (expr)
	    {
		...
	    }

	because calc will parse the if being terminated by
	an empty statement followed by a

	    if (expr) ;
	    {
		...
	    }

    See also "help statement", "help unexpected", "help todo", and
    "help bugs".


The following are the changes from calc version 2.12.1 to 2.12.1.5:

    Fixed minor typos in the 'version 2.12.0 to 2.12.0.8' section below.
    Made minor formatting changes as well.

    Changed use of ${Q} in the Makefile to avoid an make "feature"
    related to OpenBSD.  Added ${RM} make variable for make tools that
    do not have builtin defined terms.

    Removed the ECHO_PROG Makefile variable.  Also removed it from
    the sysinfo() custom function.

    Improved the support for cross-compiled environments by using
    make symbols for all non-shell commands executed by Makefiles.

    Fixed a problem with the make chk awk script which failed under
    OS X 10.4.7.

    Fixed a few minor variables that were not set to default values in
    lower level Makefiles.

    Fixed a reference to a non-existent make variable in HOWTO.INSTALL.


The following are the changes from calc version 2.12.0 to 2.12.0.8:

    Fixed ellip.cal to deal with a calc syntax change that happened
    many ages ago but was never applied to this file until now.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Fixed a problem where comments using # followed by a !, newline or
    another # works.  This bug was fixed by Ernest Bowen <ebowen at une
    dot edu dot au>.

    The show builtins display for functions with long descriptions
    is now broken into multi-line descriptions.

    The str functions, such as strcpy(s1, s2), will now copy as many
    characters as possible from s2 to s1, treating '\0' like any other
    character until the end of s2 is reached. If s2 is shorter than s1,
    a '\0' is inserted.

    The strcmp(s1, s2) builtin, for strings s1, s2: strcmp(s1, s2) == 0 now
    means the same as s1 == s2.

    The str(s) builtin has been changed so that it will return only the
    string formed by the characters of 's' up to the first '\0'.

    The substr(s, start, num) builtin has been changed so that '\0' characters
    are treated like any other.

    Fixed a bug where strcpy("", "a") used to cause a segmentation fault.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Make minor change to natnumset.cal in how the tail variable is initialized.

    Fixed bugs in the strcmp, strncmp, strcpy, and strncpy help files.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Added cal/screen.cal which Defines ANSI control sequences providing
    (i.e., cursor movement, changing foreground or background color,
    etc.) for VT100 terminals and terminal window emulators (i.e., xterm,
    Apple OS/X Terminal, etc.) that support them.  For example:

	; read screen
	; print green:"This is green. ":red:"This is red.":black

    Fixed a bug where too many open files returned E_FOPEN3.  Now
    a new error symbol F_MANYOPEN is used for too many open files.

    Added the builtin function fpathopen() to open a file while
    searching along a path:

    	; fd2 = fpathopen("tmp/date", "r", ".:~:~sc:/tmp:/var/tmp:/var")
	; print fd2
	"/var/tmp/date"

    By default, fpathopen() searches along CALCPATH.

    Added the calcpath() builtin function to return the current value
    of CALCPATH.

    Fixed prompt characters in the EXAMPLE section of help files.

    Fixed problems related to the protect function and its documentation.
    This bug was reported by David Gilham <davidgilham at gmail dot com>.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Raised the limit of exponent in exponential notation.  It was set to
    arbitrary 1000000 (making 1e1000001 in invalid exponential notation
    value).  The exponent for exponential notation is now int(MAXLONG/10).
    On 32 bit machines, this means a limit of 214748364.  On 64 bit
    machines, this means 922337203685477580.  Of course, you may not
    have enough memory to hold such huge values, but if you did you can
    now express such values in exponential notation.

    Added log() builtin for base 10 logarithm.

    Fixed problems where internal use of libc strcpy() might have caused
    a buffer overflow.  Calc now only uses libc strcpy() when the source
    string is a constant.

    The calc STRING and STRINGHEAD now use the standard size_t (an unsigned
    type) length.  Calc mostly uses size_t in dealing with string lengths
    and object sizes when possible.

    Added ${CCWERR} make variable to allow one to force compiler warnings
    to be treated as errors.  The ${CC} make variable now uses ${CCWERR}
    however the ${LCC} (used by the Makefile test code for building hsrc
    files) does not use ${CCWERR}.  By default, ${CCWERR} is empty.
    In development Makefiles, we set CCWERR= -Werror to force us to
    address compiler warnings before the next release.

    The calc make variable, CALCPAGER, now defaults to CALCPAGER= less
    because the less utility is now very common.  Set CALCPAGER= more
    if you do not have less.

    Calc source had two styles of switch indentation.  Converted the
    style where case statements were indented with respect to the switch
    statement into the style where the case statements are at the same
    level.  When comparing with older source, one may use the -b argument
    of the diff command to ignore changes in amount of white space:

    	diff -b -r -u calc-2.11.11 calc-2.12.0

    The read, write, and help commands use the value of global string
    variable if the symbol name starts with a $.  For example:

    	global x = "lucas.cal";
	read $x;	/* same as read lucas.cal or read "lucas.cal" */

    Added dotest.cal resource.  Based on a design by Ernest Bowen
    <ebowen at une dot edu dot au>, the dotest evaluates individual
    lines from a file.  The dotest() function takes 1 to 3 arguments:

	dotest(dotest_file [,dotest_code [,dotest_maxcond]])

	dotest_file

	    Search along CALCPATH for dotest_file, which contains lines that
	    should evaluate to 1.  Comment lines and empty lines are ignored.
	    Comment lines should use ## instead of the multi like /* ... */
	    because lines are evaluated one line at a time.

	dotest_code

	    Assign the code number that is to be printed at the start of
	    each non-error line and after **** in each error line.
	    The default code number is 999.

	dotest_maxcond

	    The maximum number of error conditions that may be detected.
	    An error condition is not a sign of a problem, in some cases
	    a line deliberately forces an error condition.  A value of -1,
	    the default, implies a maximum of 2147483647.

	Global variables and functions must be declared ahead of time because
	the dotest scope of evaluation is a line at a time.  For example:

	    ; read dotest.cal
	    ; read set8700.cal
	    ; dotest("set8700.line");

    Updated the todo / wish list items.  The top priority now is to
    convert calc to GNU autoconf / configure to build the calc.

	; help todo

    Added missing help file for the stoponerror() builtin.

    Corrected and improved the help documentation for factor and lfactor.

    Fixed a problem where some error messages that should have been
    written to a file or string, went to stderr instead.  This bug was
    fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Corrected the documentation relating to the calc -c command line option.
    The -c relates to scan/parse errors only, not execution errors.

    Corrected a stack overflow problem where the math_fmt() in zio.c
    could be induced to overflow the stack.  This problem was independently
    reported by Chew Keong Tan of Secunia Research <vuln at secunia dot com>.

    Corrected a stack overflow problem where the scanerror() in token.c
    could be induced to overflow the stack by a malformed token.

    Made math_error() in math_error.c more robust against a error
    message constant that is too long.

    Made read_bindings() in hist.c more robust against very long bindings
    config lines.

    Made listsort() in listfunc.c and matsort() matfunc.c more robust
    against sorting of impossibly huge lists and matrices.

    Warnings about an undefining a builtin or undefined function, a
    constant before the comma operator, and an unterminated comment is
    now processed by scanerrors (not simply written directly to stderr).
    These warnings file and line number in which the "error" occurred
    as well as a more precise message than before.  If using -c on the
    calc command line or if stoponerror(-1), then assuming there are
    no other compile errors, only the unterminated comment will stop
    completion of the function being defined.

    The cal/regress.cal now reads most of the calc resource files.

    The issq() test had a slight performance boost.  A minor note
    was added to the help/issq file.

    Improved the documentation of the mul2, sq2, pow2, and redc2 config
    parameters in help/config.

    Added config("baseb"), a read-only configuration value to return
    the number of bits in the fundamental base in which calculations
    are performed.  This is a read-only configuration value.

    Calc now will allow syntax such as ++*p-- and  ++*----*++p----
    where p is an lvalue; successful evaluation of course require the
    successive operations to be performed to have operands of appropriate
    types; e.g. in *A, A is usually an lvalue whose current value is a
    pointer. ++ and -- act on lvalues. In the above examples there are
    implied parentheses from the beginning to immediately after p. If
    there are no pre ++ or -- operations, as in **p++.  The implied
    parentheses are from immediately before p to the end.

    Improved the error message when && is used as a prefix operator.

    Changed the help/config file to read like a builtin function help file.

    One can no longer set to 1, or to a value < 0, the config()
    parameters: "mul2", "sq2", "pow2", and "redc2".  These values
    in the past would result in improper configuration of internal
    calc algorithms.  Changed cal/test4100.cal to use the minimal
    value of 2 for "pow2", and "redc2".

    Changed the default values for the following config() parameters:

    	config("mul2") == 1780
	config("sq2") == 3388
	config("pow2") == 176

	These values were determined established on a 1.8GHz AMD 32-bit
	CPU of ~3406 BogoMIPS by the new resource file:

	    cal/alg_config.cal

   Regarding the alg_config.cal resource file:

	The best_mul2() function returns the optimal value of config("mul2").
	The best_sq2() function returns the optimal value of config("sq2").
	The best_pow2() function returns the optimal value of config("pow2").
	The other functions are just support functions.

	By design, best_mul2(), best_sq2(), and best_pow2() take a few
	minutes to run.  These functions increase the number of times a
	given computational loop is executed until a minimum amount of CPU
	time is consumed.  To watch these functions progress, one can set
	the config("user_debug") value.

	Here is a suggested way to use the alg_config.cal resource file:

	    ; read alg_config
	    ; config("user_debug",2),;
	    ; best_mul2(); best_sq2(); best_pow2();
	    ; best_mul2(); best_sq2(); best_pow2();
	    ; best_mul2(); best_sq2(); best_pow2();

	NOTE: It is perfectly normal for the optimal value returned
	to differ slightly from run to run.  Slight variations due to
	inaccuracy in CPU timings will cause the best value returned to
	differ slightly from run to run.

	See "help resource" for more information on alg_config.cal.

    Updated the "help variable" text to reflect the current calc
    use of ` (backquote), * (star), and & (ampersand).

    Removal of some restrictions on the use of the same identifier
    for more than one of parameter, local, static or global variable.

	For example, at command level, one could use:

	    for (local x = 0; x < 10; x++) print sqrt(x);

	At the beginning of a statement, "(global A)" is a way of
	indicating a reference to the variable A, whereas "global A"
	would be taken as a declaration. Parentheses are not required in
	"++global A" or "global A++" when "global" is used in this way.

	The patch extends this "specifier" (or "qualifier") feature
	to static variables, but such that "static A" refers only
	to a static variable at the current file and function scope
	levels. (If there is already a static variable A at the current
	file and function levels, a declaration statement "static A"
	would end the scope of that variable and define a new static
	variable with identifier A. A "global A" declaration is more
	drastic in that it ends the scope of any static variable A at
	the same or higher scope levels.)

	Unlike a static declaration in which an "initialization" occurs at
	most once, in the specifier case, "static A = expr" is simply an
	assignment which may be repeated any number of times.  An example
	of its use is:

	    define np() = static a = nextprime(a);

	For n not too large, the n-th call to this function will
	return the n-th prime. The variable a here will be private to
	the function.

	Because one can use "global", "local" or "static" to specify a
	type of variable, there seems little point in restricting the
	ways identifiers that can be used in more than one of these
	or as parameters. Obviously, introducing A as a local variable
	when it is being used as a parameter can lead to confusion and a
	warning is appropriate, but if it is to be used only occasionally,
	it might be convenient to be able to refer to it as "local A"
	rather than introducing another identifier. While it may be
	silly to use the same identifier for both a parameter and local
	variable, it should not be illegal.

    Added warnings for possibly questionable code in function definitions.

    Added config("redecl_warn", boolean) to control if calc issues
    warnings about variables being declared.  The config("redecl_warn")
    value is TRUE by default.

    Added config("dupvar_warn", boolean) to control if calc issues
    warnings about when variable names collide.  The config("dupvar_warn")
    value is TRUE by default.  Examples of variable name collisions
    include when:

    	* both local and static variables have the same name
    	* both local and global variables have the same name
    	* both function parameter and local variables have the same name
    	* both function parameter and global variables have the same name

    Fix of a bug which causes some static variables not to be correctly
    unscoped when their identifiers are used in a global declaration.

    Change of "undefine" from a command-level keyword to statement level and
    introduction of an "undefine static A" statement to end the scope of a
    static variable A at the current file/function levels.

    Change/restored the syntax rules for "for" and "while" loops to
    recognize an unescaped newline in top-level command-level statements.

    Updated help/avg, help/define, help/fprintf, help/gcd, help/hash,
    help/hmean, help/lcm, help/max, help/min, help/null, help/poly,
    help/printf, help/ssq, help/strcat, help/strprintf, help/sum,
    help/xor.

    Changed the definition of the function ssq() to enable list arguments
    to be processed in the same way as in sum().  For example:

    	ssq(1,2, list(3,4,list(5,6)), list(), 7, 8)

    returns the value of 1^2 + 2^2 + ... + 8^2 == 204.

    Added the calc resource sumtimes.cal, to give the runtimes for
    various ways of evaluating sums, sums of squares, etc, for large
    lists and matrices.  For example:

    	read slet at users dot sourceforge dot net>.

    Fixed a problem where some old MS environments failed some of the
    regression tests because "read -once foo.cal" was not behaving
    correctly due to how the _fullpath() was being called.  Thanks for
    this fix goes to Anatoly <notexistent-anb at yandex dot ru>.

    Documented the mis-feature about how calc parses if, for, while
    and do statements in an unexpected way.   For example:

	This works as expected:

	    if (expr) {
		...
	    }

	However this WILL NOT WORK AS EXPECTED:

	    if (expr)
	    {
		...
	    }

	because calc will parse the if being terminated by
	an empty statement followed by a

	    if (expr) ;
	    {
		...
	    }

    See also "help statement", "help unexpected", "help todo", and
    "help bugs".


The following are the changes from calc version 2.12.1 to 2.12.1.5:

    Fixed minor typos in the 'version 2.12.0 to 2.12.0.8' section below.
    Made minor formatting changes as well.

    Changed use of ${Q} in the Makefile to avoid an make "feature"
    related to OpenBSD.  Added ${RM} make variable for make tools that
    do not have builtin defined terms.

    Removed the ECHO_PROG Makefile variable.  Also removed it from
    the sysinfo() custom function.

    Improved the support for cross-compiled environments by using
    make symbols for all non-shell commands executed by Makefiles.

    Fixed a problem with the make chk awk script which failed under
    OS X 10.4.7.

    Fixed a few minor variables that were not set to default values in
    lower level Makefiles.

    Fixed a reference to a non-existent make variable in HOWTO.INSTALL.


The following are the changes from calc version 2.12.0 to 2.12.0.8:

    Fixed ellip.cal to deal with a calc syntax change that happened
    many ages ago but was never applied to this file until now.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Fixed a problem where comments using # followed by a !, newline or
    another # works.  This bug was fixed by Ernest Bowen <ebowen at une
    dot edu dot au>.

    The show builtins display for functions with long descriptions
    is now broken into multi-line descriptions.

    The str functions, such as strcpy(s1, s2), will now copy as many
    characters as possible from s2 to s1, treating '\0' like any other
    character until the end of s2 is reached. If s2 is shorter than s1,
    a '\0' is inserted.

    The strcmp(s1, s2) builtin, for strings s1, s2: strcmp(s1, s2) == 0 now
    means the same as s1 == s2.

    The str(s) builtin has been changed so that it will return only the
    string formed by the characters of 's' up to the first '\0'.

    The substr(s, start, num) builtin has been changed so that '\0' characters
    are treated like any other.

    Fixed a bug where strcpy("", "a") used to cause a segmentation fault.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Make minor change to natnumset.cal in how the tail variable is initialized.

    Fixed bugs in the strcmp, strncmp, strcpy, and strncpy help files.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Added cal/screen.cal which Defines ANSI control sequences providing
    (i.e., cursor movement, changing foreground or background color,
    etc.) for VT100 terminals and terminal window emulators (i.e., xterm,
    Apple OS/X Terminal, etc.) that support them.  For example:

	; read screen
	; print green:"This is green. ":red:"This is red.":black

    Fixed a bug where too many open files returned E_FOPEN3.  Now
    a new error symbol F_MANYOPEN is used for too many open files.

    Added the builtin function fpathopen() to open a file while
    searching along a path:

    	; fd2 = fpathopen("tmp/date", "r", ".:~:~sc:/tmp:/var/tmp:/var")
	; print fd2
	"/var/tmp/date"

    By default, fpathopen() searches along CALCPATH.

    Added the calcpath() builtin function to return the current value
    of CALCPATH.

    Fixed prompt characters in the EXAMPLE section of help files.

    Fixed problems related to the protect function and its documentation.
    This bug was reported by David Gilham <davidgilham at gmail dot com>.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Raised the limit of exponent in exponential notation.  It was set to
    arbitrary 1000000 (making 1e1000001 in invalid exponential notation
    value).  The exponent for exponential notation is now int(MAXLONG/10).
    On 32 bit machines, this means a limit of 214748364.  On 64 bit
    machines, this means 922337203685477580.  Of course, you may not
    have enough memory to hold such huge values, but if you did you can
    now express such values in exponential notation.

    Added log() builtin for base 10 logarithm.

    Fixed problems where internal use of libc strcpy() might have caused
    a buffer overflow.  Calc now only uses libc strcpy() when the source
    string is a constant.

    The calc STRING and STRINGHEAD now use the standard size_t (an unsigned
    type) length.  Calc mostly uses size_t in dealing with string lengths
    and object sizes when possible.

    Added ${CCWERR} make variable to allow one to force compiler warnings
    to be treated as errors.  The ${CC} make variable now uses ${CCWERR}
    however the ${LCC} (used by the Makefile test code for building hsrc
    files) does not use ${CCWERR}.  By default, ${CCWERR} is empty.
    In development Makefiles, we set CCWERR= -Werror to force us to
    address compiler warnings before the next release.

    The calc make variable, CALCPAGER, now defaults to CALCPAGER= less
    because the less utility is now very common.  Set CALCPAGER= more
    if you do not have less.

    Calc source had two styles of switch indentation.  Converted the
    style where case statements were indented with respect to the switch
    statement into the style where the case statements are at the same
    level.  When comparing with older source, one may use the -b argument
    of the diff command to ignore changes in amount of white space:

    	diff -b -r -u calc-2.11.11 calc-2.12.0

    The read, write, and help commands use the value of global string
    variable if the symbol name starts with a $.  For example:

    	global x = "lucas.cal";
	read $x;	/* same as read lucas.cal or read "lucas.cal" */

    Added dotest.cal resource.  Based on a design by Ernest Bowen
    <ebowen at une dot edu dot au>, the dotest evaluates individual
    lines from a file.  The dotest() function takes 1 to 3 arguments:

	dotest(dotest_file [,dotest_code [,dotest_maxcond]])

	dotest_file

	    Search along CALCPATH for dotest_file, which contains lines that
	    should evaluate to 1.  Comment lines and empty lines are ignored.
	    Comment lines should use ## instead of the multi like /* ... */
	    because lines are evaluated one line at a time.

	dotest_code

	    Assign the code number that is to be printed at the start of
	    each non-error line and after **** in each error line.
	    The default code number is 999.

	dotest_maxcond

	    The maximum number of error conditions that may be detected.
	    An error condition is not a sign of a problem, in some cases
	    a line deliberately forces an error condition.  A value of -1,
	    the default, implies a maximum of 2147483647.

	Global variables and functions must be declared ahead of time because
	the dotest scope of evaluation is a line at a time.  For example:

	    ; read dotest.cal
	    ; read set8700.cal
	    ; dotest("set8700.line");

    Updated the todo / wish list items.  The top priority now is to
    convert calc to GNU autoconf / configure to build the calc.

	; help todo

    Added missing help file for the stoponerror() builtin.

    Corrected and improved the help documentation for factor and lfactor.

    Fixed a problem where some error messages that should have been
    written to a file or string, went to stderr instead.  This bug was
    fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Corrected the documentation relating to the calc -c command line option.
    The -c relates to scan/parse errors only, not execution errors.

    Corrected a stack overflow problem where the math_fmt() in zio.c
    could be induced to overflow the stack.  This problem was independently
    reported by Chew Keong Tan of Secunia Research <vuln at secunia dot com>.

    Corrected a stack overflow problem where the scanerror() in token.c
    could be induced to overflow the stack by a malformed token.

    Made math_error() in math_error.c more robust against a error
    message constant that is too long.

    Made read_bindings() in hist.c more robust against very long bindings
    config lines.

    Made listsort() in listfunc.c and matsort() matfunc.c more robust
    against sorting of impossibly huge lists and matrices.

    Warnings about an undefining a builtin or undefined function, a
    constant before the comma operator, and an unterminated comment is
    now processed by scanerrors (not simply written directly to stderr).
    These warnings file and line number in which the "error" occurred
    as well as a more precise message than before.  If using -c on the
    calc command line or if stoponerror(-1), then assuming there are
    no other compile errors, only the unterminated comment will stop
    completion of the function being defined.

    The cal/regress.cal now reads most of the calc resource files.

    The issq() test had a slight performance boost.  A minor note
    was added to the help/issq file.

    Improved the documentation of the mul2, sq2, pow2, and redc2 config
    parameters in help/config.

    Added config("baseb"), a read-only configuration value to return
    the number of bits in the fundamental base in which calculations
    are performed.  This is a read-only configuration value.

    Calc now will allow syntax such as ++*p-- and  ++*----*++p----
    where p is an lvalue; successful evaluation of course require the
    successive operations to be performed to have operands of appropriate
    types; e.g. in *A, A is usually an lvalue whose current value is a
    pointer. ++ and -- act on lvalues. In the above examples there are
    implied parentheses from the beginning to immediately after p. If
    there are no pre ++ or -- operations, as in **p++.  The implied
    parentheses are from immediately before p to the end.

    Improved the error message when && is used as a prefix operator.

    Changed the help/config file to read like a builtin function help file.

    One can no longer set to 1, or to a value < 0, the config()
    parameters: "mul2", "sq2", "pow2", and "redc2".  These values
    in the past would result in improper configuration of internal
    calc algorithms.  Changed cal/test4100.cal to use the minimal
    value of 2 for "pow2", and "redc2".

    Changed the default values for the following config() parameters:

    	config("mul2") == 1780
	config("sq2") == 3388
	config("pow2") == 176

	These values were determined established on a 1.8GHz AMD 32-bit
	CPU of ~3406 BogoMIPS by the new resource file:

	    cal/alg_config.cal

   Regarding the alg_config.cal resource file:

	The best_mul2() function returns the optimal value of config("mul2").
	The best_sq2() function returns the optimal value of config("sq2").
	The best_pow2() function returns the optimal value of config("pow2").
	The other functions are just support functions.

	By design, best_mul2(), best_sq2(), and best_pow2() take a few
	minutes to run.  These functions increase the number of times a
	given computational loop is executed until a minimum amount of CPU
	time is consumed.  To watch these functions progress, one can set
	the config("user_debug") value.

	Here is a suggested way to use the alg_config.cal resource file:

	    ; read alg_config
	    ; config("user_debug",2),;
	    ; best_mul2(); best_sq2(); best_pow2();
	    ; best_mul2(); best_sq2(); best_pow2();
	    ; best_mul2(); best_sq2(); best_pow2();

	NOTE: It is perfectly normal for the optimal value returned
	to differ slightly from run to run.  Slight variations due to
	inaccuracy in CPU timings will cause the best value returned to
	differ slightly from run to run.

	See "help resource" for more information on alg_config.cal.

    Updated the "help variable" text to reflect the current calc
    use of ` (backquote), * (star), and & (ampersand).

    Removal of some restrictions on the use of the same identifier
    for more than one of parameter, local, static or global variable.

	For example, at command level, one could use:

	    for (local x = 0; x < 10; x++) print sqrt(x);

	At the beginning of a statement, "(global A)" is a way of
	indicating a reference to the variable A, whereas "global A"
	would be taken as a declaration. Parentheses are not required in
	"++global A" or "global A++" when "global" is used in this way.

	The patch extends this "specifier" (or "qualifier") feature
	to static variables, but such that "static A" refers only
	to a static variable at the current file and function scope
	levels. (If there is already a static variable A at the current
	file and function levels, a declaration statement "static A"
	would end the scope of that variable and define a new static
	variable with identifier A. A "global A" declaration is more
	drastic in that it ends the scope of any static variable A at
	the same or higher scope levels.)

	Unlike a static declaration in which an "initialization" occurs at
	most once, in the specifier case, "static A = expr" is simply an
	assignment which may be repeated any number of times.  An example
	of its use is:

	    define np() = static a = nextprime(a);

	For n not too large, the n-th call to this function will
	return the n-th prime. The variable a here will be private to
	the function.

	Because one can use "global", "local" or "static" to specify a
	type of variable, there seems little point in restricting the
	ways identifiers that can be used in more than one of these
	or as parameters. Obviously, introducing A as a local variable
	when it is being used as a parameter can lead to confusion and a
	warning is appropriate, but if it is to be used only occasionally,
	it might be convenient to be able to refer to it as "local A"
	rather than introducing another identifier. While it may be
	silly to use the same identifier for both a parameter and local
	variable, it should not be illegal.

    Added warnings for possibly questionable code in function definitions.

    Added config("redecl_warn", boolean) to control if calc issues
    warnings about variables being declared.  The config("redecl_warn")
    value is TRUE by default.

    Added config("dupvar_warn", boolean) to control if calc issues
    warnings about when variable names collide.  The config("dupvar_warn")
    value is TRUE by default.  Examples of variable name collisions
    include when:

    	* both local and static variables have the same name
    	* both local and global variables have the same name
    	* both function parameter and local variables have the same name
    	* both function parameter and global variables have the same name

    Fix of a bug which causes some static variables not to be correctly
    unscoped when their identifiers are used in a global declaration.

    Change of "undefine" from a command-level keyword to statement level and
    introduction of an "undefine static A" statement to end the scope of a
    static variable A at the current file/function levels.

    Change/restored the syntax rules for "for" and "while" loops to
    recognize an unescaped newline in top-level command-level statements.

    Updated help/avg, help/define, help/fprintf, help/gcd, help/hash,
    help/hmean, help/lcm, help/max, help/min, help/null, help/poly,
    help/printf, help/ssq, help/strcat, help/strprintf, help/sum,
    help/xor.

    Changed the definition of the function ssq() to enable list arguments
    to be processed in the same way as in sum().  For example:

    	ssq(1,2, list(3,4,list(5,6)), list(), 7, 8)

    returns the value of 1^2 + 2^2 + ... + 8^2 == 204.

    Added the calc resource sumtimes.cal, to give the runtimes for
    various ways of evaluating sums, sums of squares, etc, for large
    lists and matrices.  For example:

    	read slet at users dot sourceforge dot net>.

    Fixed a problem where some old MS environments failed some of the
    regression tests because "read -once foo.cal" was not behaving
    correctly due to how the _fullpath() was being called.  Thanks for
    this fix goes to Anatoly <notexistent-anb at yandex dot ru>.

    Documented the mis-feature about how calc parses if, for, while
    and do statements in an unexpected way.   For example:

	This works as expected:

	    if (expr) {
		...
	    }

	However this WILL NOT WORK AS EXPECTED:

	    if (expr)
	    {
		...
	    }

	because calc will parse the if being terminated by
	an empty statement followed by a

	    if (expr) ;
	    {
		...
	    }

    See also "help statement", "help unexpected", "help todo", and
    "help bugs".


The following are the changes from calc version 2.12.1 to 2.12.1.5:

    Fixed minor typos in the 'version 2.12.0 to 2.12.0.8' section below.
    Made minor formatting changes as well.

    Changed use of ${Q} in the Makefile to avoid an make "feature"
    related to OpenBSD.  Added ${RM} make variable for make tools that
    do not have builtin defined terms.

    Removed the ECHO_PROG Makefile variable.  Also removed it from
    the sysinfo() custom function.

    Improved the support for cross-compiled environments by using
    make symbols for all non-shell commands executed by Makefiles.

    Fixed a problem with the make chk awk script which failed under
    OS X 10.4.7.

    Fixed a few minor variables that were not set to default values in
    lower level Makefiles.

    Fixed a reference to a non-existent make variable in HOWTO.INSTALL.


The following are the changes from calc version 2.12.0 to 2.12.0.8:

    Fixed ellip.cal to deal with a calc syntax change that happened
    many ages ago but was never applied to this file until now.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Fixed a problem where comments using # followed by a !, newline or
    another # works.  This bug was fixed by Ernest Bowen <ebowen at une
    dot edu dot au>.

    The show builtins display for functions with long descriptions
    is now broken into multi-line descriptions.

    The str functions, such as strcpy(s1, s2), will now copy as many
    characters as possible from s2 to s1, treating '\0' like any other
    character until the end of s2 is reached. If s2 is shorter than s1,
    a '\0' is inserted.

    The strcmp(s1, s2) builtin, for strings s1, s2: strcmp(s1, s2) == 0 now
    means the same as s1 == s2.

    The str(s) builtin has been changed so that it will return only the
    string formed by the characters of 's' up to the first '\0'.

    The substr(s, start, num) builtin has been changed so that '\0' characters
    are treated like any other.

    Fixed a bug where strcpy("", "a") used to cause a segmentation fault.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Make minor change to natnumset.cal in how the tail variable is initialized.

    Fixed bugs in the strcmp, strncmp, strcpy, and strncpy help files.
    This bug was fixed by Ernest Bowen <ebowen at une dot edu dot au>.

    Added cal/screen.cal which Defines ANSI control sequences providing
    (i.e., cursor movement, changing foreground or background color,
    etc.) for VT100 terminals and terminal window emulators (i.e., xterm,
    Apple OS/X Terminal, etc.) that support them.  For example:

	; read screen
	; print green:"This is green. ":red:"This is red.":black

    Fixed a bug where too many open files returned E_FOPEN3.  Now
    a new error symbol F_MANYOPEN is used for too many open files.

    Added the builtin function fpathopen() to open a file while
    searching along a path:

    	; fd2 = fpathopen("tmp/date", "r", ".:~:~sc:/tmp:/var/tmp:/var")
	; print fd2
	"/var/tmp/date"

    By default, fpathopen() searches along CA