home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-05-09 | 61.9 KB | 2,110 lines |
- Newsgroups: comp.sources.unix
- From: dbell@pdact.pd.necisa.oz.au (David I. Bell)
- Subject: v26i027: CALC - An arbitrary precision C-like calculator, Part01/21
- Sender: unix-sources-moderator@pa.dec.com
- Approved: vixie@pa.dec.com
-
- Submitted-By: dbell@pdact.pd.necisa.oz.au (David I. Bell)
- Posting-Number: Volume 26, Issue 27
- Archive-Name: calc/part01
-
- [ don't let the size and number of features fool you -- this is a great
- calculator for those of us who can never remember the obscure and "help"-
- less syntax of bc and dc. it happens that you could use this package to
- verify the correctness of your floating-point implementation, but even
- if you're just trying to calculate disk geometries or sales tax, this is
- very probably the best and easiest-to-use tool for the job.
-
- it builds and installs and runs perfectly on my ultrix system.
-
- --vix ]
-
- Calc is an arbitrary precision calculator. It handles large integers,
- fractions, real numbers (approximated using fractions), complex numbers,
- strings, and matrices. The size of numbers and the precision of real
- calculations is limited only by the available memory and the run time.
-
- Calc can be used interactively by the user to evaluate expressions.
- It can also be programmed using a language much like C. This allows
- the user to define complicated functions which can then also be used
- interactively.
-
- There are many built-in functions (e.g., gcd, comb, sin, exp, det).
- Many of these functions are useful in number theory.
-
- In addition to the built-in types, calc can also handle new types of
- objects whose representation and operations are defined by the user
- (e.g., quadratic surds, quaternions, modular arithmetic).
-
- Calc is written in C so as to be portable. No assembly language is
- used, and machine dependencies are few. When building calc, the major
- dependency is knowing whether your machine is big or little endian.
- Calc has been successfully built on several different types of machines.
-
- The code for the arbitrary precision routines is independent of the code
- for the rest of the calculator. These routines can be called by your own
- C programs to manipulate either large integers, or large fractions.
-
- These sources are also available by anonymous ftp from ftp.uu.net in the
- directory pub/calc. Calc will also be distributed as part of 4.4BSD, and
- has been given to the GNU project.
-
- Enjoy!
-
- David I. Bell
- dbell@pdact.pd.necisa.oz.au
-
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 1 (of 21)."
- # Contents: README func.h help help/Makefile help/credit
- # help/environment help/expression help/header help/help
- # help/history help/interrupt help/intro help/list help/operator
- # help/sums help/todo help/usage help/variable label.h lib
- # lib/Makefile lib/bernoulli.cal lib/bigprime.cal lib/deg.cal
- # lib/mersenne.cal lib/nextprim.cal lib/pell.cal lib/pi.cal
- # lib/pollard.cal lib/psqrt.cal lib/solve.cal lib/sumsq.cal
- # lib/unitfrac.cal lib/varargs.cal lint.sed stdarg.h string.h
- # symbol.h version.c
- # Wrapped by dbell@elm on Tue Feb 25 15:20:52 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README'\"
- else
- echo shar: Extracting \"'README'\" \(1357 characters\)
- sed "s/^X//" >'README' <<'END_OF_FILE'
- X
- X# Copyright (c) 1992 David I. Bell
- X# Permission is granted to use, distribute, or modify this source,
- X# provided that this copyright notice remains intact.
- X#
- X# Arbitrary precision calculator.
- X
- XI am allowing this calculator to be freely distributed for personal uses.
- XLike all multi-precision programs, you should not depend absolutely on
- Xits results, since bugs in such programs can be insidious and only rarely
- Xshow up.
- X
- X-dbell-
- X
- Xp.s. By Landon Curt Noll
- X
- XTo build calc:
- X
- X 1) Look at the makefile, and adjust it to suit your needs.
- X
- X 2) build some calc documentation:
- X
- X (cd help; make full) <- after this, read the file help/full
- X
- X 3) build calc:
- X
- X make
- X
- X 4) test calc:
- X
- X After you have built calc, you can test it by running calc and
- X giving calc the following input:
- X
- X read lib/regress <- error messages should be printed
- X read lib/lucas
- X read lib/lucas_chk
- X lucas_chk(200) <- should produce no error messages
- X exit
- X
- XIf you find bugs, or better yet have bug fixes; or if you have suggested
- Xchanges, or better yet have patches, send them to both myself and DBell:
- X
- X chongo@toad.com {uunet,pyramid,sun}!hoptoad!chongo
- X dbell@pdact.pd.necisa.oz.au {uunet,pyramid}!pdact.pd.necisa.oz.au!dbell
- X
- XThe file doc/todo section points out some needs for calc. Suggestions
- Xon other enhancements, and help in doing these are welcome.
- END_OF_FILE
- if test 1357 -ne `wc -c <'README'`; then
- echo shar: \"'README'\" unpacked with wrong size!
- fi
- # end of 'README'
- fi
- if test -f 'func.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'func.h'\"
- else
- echo shar: Extracting \"'func.h'\" \(2162 characters\)
- sed "s/^X//" >'func.h' <<'END_OF_FILE'
- X/*
- X * Copyright (c) 1992 David I. Bell
- X * Permission is granted to use, distribute, or modify this source,
- X * provided that this copyright notice remains intact.
- X */
- X
- X
- X/*
- X * Structure of a function.
- X * The f_opcodes array is actually of variable size.
- X */
- Xtypedef struct func FUNC;
- Xstruct func {
- X FUNC *f_next; /* next function in list */
- X unsigned long f_opcodecount; /* size of opcode array */
- X unsigned int f_localcount; /* number of local variables */
- X unsigned int f_paramcount; /* max number of parameters */
- X char *f_name; /* function name */
- X VALUE f_savedvalue; /* saved value of last expression */
- X long f_opcodes[1]; /* array of opcodes (variable length) */
- X};
- X
- X
- X/*
- X * Amount of space needed to allocate a function of n opcodes.
- X */
- X#define funcsize(n) (sizeof(FUNC) + (n) * sizeof(long))
- X
- X
- X/*
- X * Size of a character pointer rounded up to a number of opcodes.
- X */
- X#define PTR_SIZE ((sizeof(char *) + sizeof(long) - 1) / sizeof(long))
- X
- X
- Xextern FUNC *curfunc; /* current function being compiled */
- Xextern FUNC *findfunc(); /* return function given index */
- Xextern char *namefunc(); /* return function name given index */
- Xextern BOOL evaluate(); /* evaluate a line */
- Xextern long adduserfunc();
- Xextern void beginfunc(); /* initialize a function for definition */
- Xextern int builtinopcode(); /* return the opcode for a built-in function */
- Xextern void addop(); /* add an opcode to the current function */
- Xextern void endfunc(); /* commit the just defined function for use */
- Xextern void addopindex(); /* add an opcode & index to the current func */
- Xextern void addoplabel(); /* add jump-type opcode + label to the func */
- Xextern void addopptr(); /* add an opcode + char ptr to the func */
- Xextern void showbuiltins(); /* show list of primitive builtin funcs */
- Xextern int getbuiltinfunc(); /* return the index of a built-in func */
- Xextern void builtincheck(); /* determine if the # of arguments are legal */
- Xextern void addopfunction(); /* add opcode + index + arg count to the func */
- Xextern void showfunctions(); /* show the list of user defined functs */
- Xextern void clearopt(); /* clear optimization done for next opcode */
- X
- X/* END CODE */
- END_OF_FILE
- if test 2162 -ne `wc -c <'func.h'`; then
- echo shar: \"'func.h'\" unpacked with wrong size!
- fi
- # end of 'func.h'
- fi
- if test ! -d 'help' ; then
- echo shar: Creating directory \"'help'\"
- mkdir 'help'
- fi
- if test -f 'help/Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'help/Makefile'\"
- else
- echo shar: Extracting \"'help/Makefile'\" \(1602 characters\)
- sed "s/^X//" >'help/Makefile' <<'END_OF_FILE'
- X#
- X# help - makefile for calc help files
- X#
- X# Copyright (c) 1992 David I. Bell and Landon Curt Noll
- X# Permission is granted to use, distribute, or modify this source,
- X# provided that this copyright notice remains intact.
- X#
- X# Arbitrary precision calculator.
- X#
- X# calculator by David I. Bell
- X# makefile by Landon Curt Noll
- X
- X# Normally, the upper level makefile will set these values. We provide
- X# a default here just in case you want to build from this directory.
- X#
- X# where to install things
- XHELPDIR= /usr/local/lib/calc/help
- X# how to build a directory
- XMKDIR=mkdir -p
- X#MKDIR=mkdir
- X
- X# The header file, along with these files form the full help file.
- X#
- XFULL_HELP_FILES=intro command expression define variable statement \
- X operator types obj mat list file builtin config interrupt \
- X history usage credit
- X
- X# We install these help files
- X#
- XHELP_FILES= ${FULL_HELP_FILES} full overview stdlib environment todo credit help
- X
- XSHELL= /bin/sh
- X
- Xall: ${HELP_FILES}
- X
- Xfull: header ${FULL_HELP_FILES}
- X rm -f full
- X cp header full
- X chmod +w full
- X @for i in ${FULL_HELP_FILES}; do \
- X echo '' >> full; \
- X echo '' >> full; \
- X echo "cat $$i >> full"; \
- X cat $$i >> full; \
- X done
- X chmod 0444 full
- X
- Xstdlib: ../lib/README
- X rm -f stdlib
- X cp ../lib/README stdlib
- X chmod 0444 stdlib
- X
- Xclean:
- X
- Xclobber:
- X rm -f full stdlib
- X
- Xinstall: all
- X -@if [ ! -d ${HELPDIR} ]; then \
- X echo " ${MKDIR} ${HELPDIR}"; \
- X ${MKDIR} ${HELPDIR}; \
- X fi
- X @for i in ${HELP_FILES}; do \
- X echo " rm -f ${HELPDIR}/$$i"; \
- X rm -f ${HELPDIR}/$$i; \
- X echo " chmod 0444 $$i"; \
- X chmod 0444 $$i; \
- X echo " cp $$i ${HELPDIR}"; \
- X cp $$i ${HELPDIR}; \
- X done
- END_OF_FILE
- if test 1602 -ne `wc -c <'help/Makefile'`; then
- echo shar: \"'help/Makefile'\" unpacked with wrong size!
- fi
- # end of 'help/Makefile'
- fi
- if test -f 'help/credit' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'help/credit'\"
- else
- echo shar: Extracting \"'help/credit'\" \(847 characters\)
- sed "s/^X//" >'help/credit' <<'END_OF_FILE'
- XCredits
- X
- X Written by David I. Bell.
- X
- X Thanks for suggestions and encouragement from Peter Miller,
- X Neil Justusson, and Landon Noll.
- X
- X Portions of this program are derived from an earlier set of
- X public domain arbitrarily precision routines which was posted
- X to the net around 1984. By now, there is almost no recognizable
- X code left from that original source.
- X
- X Most of this source and binary is:
- X
- X Copyright (c) 1992 David I. Bell
- X
- X A few files are a joint copyright between David I. Bell and Landon Noll.
- X
- X Permission is granted to use, distribute, or modify this source,
- X provided that this copyright notice remains intact.
- X
- X Send calc comments, suggestions, bug fixes, enhancements and
- X interesting calc scripts that you would like you see included in
- X future distributions to:
- X
- X dbell@pdact.pd.necisa.oz.au and chongo@toad.com
- X
- X Enjoy!
- END_OF_FILE
- if test 847 -ne `wc -c <'help/credit'`; then
- echo shar: \"'help/credit'\" unpacked with wrong size!
- fi
- # end of 'help/credit'
- fi
- if test -f 'help/environment' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'help/environment'\"
- else
- echo shar: Extracting \"'help/environment'\" \(1659 characters\)
- sed "s/^X//" >'help/environment' <<'END_OF_FILE'
- XEnvironment variables
- X
- X CALCPATH
- X
- X A :-separated list of directories used to search for
- X scripts filenames that do not begin with /, ./ or ~.
- X
- X If this variable does not exist, a compiled value
- X is used. Typically compiled in value is:
- X
- X .:./lib:~/lib:${LIBDIR}/calc
- X
- X where ${LIBDIR} is usually:
- X
- X /usr/local/lib/calc
- X
- X This value is used by the READ command. It is an error
- X if no such readable file is found.
- X
- X
- X CALCRC
- X
- X On startup (unless -h or -q was given on the command
- X line), calc searches for files along the :-separated
- X $CALCRC environment variable.
- X
- X If this variable does not exist, a compiled value
- X is used. Typically compiled in value is:
- X
- X ${LIBDIR}/startup:~/.calcrc
- X
- X where ${LIBDIR} is usually:
- X
- X /usr/local/lib/calc
- X
- X Missing files along the $CALCRC path are silently ignored.
- X
- X HOME
- X
- X This value is taken to be the home directory of the
- X current user. It is used when files begin with '~/'.
- X
- X If this variable does not exist, the home directory password
- X entry of the current user is used. If that information
- X is not available, '.' is used.
- X
- X PAGER
- X
- X When invoking help, this environment variable is used
- X to display a help file.
- X
- X If this variable does not exist, a compiled value
- X is used. Typically compiled in value is something
- X such as 'more', 'less', 'pg' or 'cat'.
- X
- X SHELL
- X
- X When a !-command is used, the program indicated by
- X this environment variable is used.
- X
- X If this variable does not exist, a compiled value
- X is used. Typically compiled in value is something
- X such as 'sh' is used.
- END_OF_FILE
- if test 1659 -ne `wc -c <'help/environment'`; then
- echo shar: \"'help/environment'\" unpacked with wrong size!
- fi
- # end of 'help/environment'
- fi
- if test -f 'help/expression' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'help/expression'\"
- else
- echo shar: Extracting \"'help/expression'\" \(1413 characters\)
- sed "s/^X//" >'help/expression' <<'END_OF_FILE'
- XExpression sequences
- X
- X This is a sequence of statements, of which expression statements
- X are the commonest case. Statements are separated with semicolons,
- X and the newline character generally ends the sequence. If any
- X statement is an expression by itself, or is associated with an
- X 'if' statement which is true, then two special things can happen.
- X If the sequence is executed at the top level of the calculator,
- X then the value of '.' is set to the value of the last expression.
- X Also, if an expression is a non-assignment, then the value of the
- X expression is automatically printed if its value is not NULL.
- X Some operations such as pre-increment and plus-equals are also
- X treated as assignments.
- X
- X Examples of this are the following:
- X
- X expression sets '.' to prints
- X ---------- ----------- ------
- X 3+4 7 7
- X 2*4; 8+1; fact(3) 6 8, 9, and 6
- X x=3^2 9 -
- X if (3 < 2) 5; else 6 6 6
- X x++ old x -
- X print fact(4) - 24
- X null() null() -
- X
- X Variables can be defined at the beginning of an expression sequence.
- X This is most useful for local variables, as in the following example,
- X which sums the square roots of the first few numbers:
- X
- X local s, i; s = 0; for (i = 0; i < 10; i++) s += sqrt(i); s
- X
- X If a return statement is executed in an expression sequence, then
- X the result of the expression sequence is the returned value. In
- X this case, '.' is set to the value, but nothing is printed.
- END_OF_FILE
- if test 1413 -ne `wc -c <'help/expression'`; then
- echo shar: \"'help/expression'\" unpacked with wrong size!
- fi
- # end of 'help/expression'
- fi
- if test -f 'help/header' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'help/header'\"
- else
- echo shar: Extracting \"'help/header'\" \(64 characters\)
- sed "s/^X//" >'help/header' <<'END_OF_FILE'
- X CALC - An arbitrary precision calculator.
- X by David I. Bell
- END_OF_FILE
- if test 64 -ne `wc -c <'help/header'`; then
- echo shar: \"'help/header'\" unpacked with wrong size!
- fi
- # end of 'help/header'
- fi
- if test -f 'help/help' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'help/help'\"
- else
- echo shar: Extracting \"'help/help'\" \(1210 characters\)
- sed "s/^X//" >'help/help' <<'END_OF_FILE'
- XFor more information while running calc, type help followed by one of the
- Xfollowing topics:
- X
- X topic description
- X ----- -----------
- X intro a brief introduction to calc
- X command top level commands
- X expression expression sequences
- X define how to define functions
- X variable variables and variable declarations
- X statement flow control and declaration statements
- X operator math, relational, logic and variable access operators
- X types builtin data types
- X obj user defined data types
- X mat using matrices
- X list using lists
- X file using files
- X builtin builtin functions
- X config configuration parameters
- X interrupt how interrupts are handled
- X history command history
- X usage how to invoke the calc command
- X todo needed enhancements
- X credit who wrote calc, and who helped, copyright
- X full all of the above topics
- X help this file
- X overview brief overview of calc
- X stdlib description of some lib files shipped with calc
- X environment how environment variables effect calc
- X
- XFor example:
- X
- X help usage
- X
- Xwill print the calc command usage information. One can obtain calc help
- Xwithout invoking any startup code by running calc as follows:
- X
- X calc -q help topic
- X
- Xwhere 'topic' is one of the topics listed above.
- END_OF_FILE
- if test 1210 -ne `wc -c <'help/help'`; then
- echo shar: \"'help/help'\" unpacked with wrong size!
- fi
- # end of 'help/help'
- fi
- if test -f 'help/history' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'help/history'\"
- else
- echo shar: Extracting \"'help/history'\" \(1019 characters\)
- sed "s/^X//" >'help/history' <<'END_OF_FILE'
- XCommand history
- X
- X There is a crude command history feature in the calculator.
- X If a terminal line begins with an exclamation mark or back quote
- X character (! or `), then the terminal line is handled specially.
- X
- X The command just typed can be re-executed by typing the
- X line '``' (two back quotes).
- X
- X Other previous commands can be executed again by typing '`nn'
- X (backquote <number>), where nn is the command number to be
- X ex-executed. This number is displayed in the prompt for each
- X input line, so it is easy to re-execute commands that are still
- X visible on the screen. Negative numbers can be used to re-execute
- X the n'th command back.
- X
- X The list of 20 previous commands can be displayed by typing '`h'
- X (backquote h). By typing '`hnn' (backquote h <number>), one
- X can ex-execute the last 'nn' commands.
- X
- X Up to 255 commands are saved in the history stack.
- X
- X A UNIX command can be executed by typing '!cmd', where cmd
- X is the command to execute. If cmd is not given, then a shell
- X command level is started.
- END_OF_FILE
- if test 1019 -ne `wc -c <'help/history'`; then
- echo shar: \"'help/history'\" unpacked with wrong size!
- fi
- # end of 'help/history'
- fi
- if test -f 'help/interrupt' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'help/interrupt'\"
- else
- echo shar: Extracting \"'help/interrupt'\" \(1306 characters\)
- sed "s/^X//" >'help/interrupt' <<'END_OF_FILE'
- XInterrupts
- X
- X While a calculation is in progress, you can generate the SIGINT
- X signal, and the calculator will catch it. At appropriate points
- X within a calculation, the calculator will check that the signal
- X has been given, and will abort the calculation cleanly. If the
- X calculator is in the middle of a large calculation, it might be
- X a while before the interrupt has an effect.
- X
- X You can generate the SIGINT signal multiple times if necessary,
- X and each time the calculator will abort the calculation at a more
- X risky place within the calculation. Each new interrupt prints a
- X message of the form:
- X
- X [Abort level n]
- X
- X where n ranges from 1 to 3. For n equal to 1, the calculator will
- X abort calculations at the next statement boundary. For n equal to 2,
- X the calculator will abort calculations at the next opcode boundary.
- X For n equal to 3, the calculator will abort calculations at the next
- X lowest level arithmetic operation boundary.
- X
- X If a final interrupt is given when n is 3, the calculator will
- X immediately abort the current calculation and longjmp back to the
- X top level command level. Doing this may result in corrupted data
- X structures and unpredictable future behavior, and so should only
- X be done as a last resort. You are advised to quit the calculator
- X after this has been done.
- END_OF_FILE
- if test 1306 -ne `wc -c <'help/interrupt'`; then
- echo shar: \"'help/interrupt'\" unpacked with wrong size!
- fi
- # end of 'help/interrupt'
- fi
- if test -f 'help/intro' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'help/intro'\"
- else
- echo shar: Extracting \"'help/intro'\" \(1895 characters\)
- sed "s/^X//" >'help/intro' <<'END_OF_FILE'
- XQuick introduction
- X
- X This is an interactive calculator which provides for easy large
- X numeric calculations, but which also can be easily programmed
- X for difficult or long calculations. It can accept a command line
- X argument, in which case it executes that single command and exits.
- X Otherwise, it enters interactive mode. In this mode, it accepts
- X commands one at a time, processes them, and displays the answers.
- X In the simplest case, commands are simply expressions which are
- X evaluated. For example, the following line can be input:
- X
- X 3 * (4 + 1)
- X
- X and the calculator will print 15.
- X
- X The special '.' symbol (called dot), represents the result of the
- X last command expression, if any. This is of great use when a series
- X of partial results are calculated, or when the output mode is changed
- X and the last result needs to be redisplayed. For example, the above
- X result can be doubled by typing:
- X
- X . * 2
- X
- X and the calculator will print 30.
- X
- X For more complex calculations, variables can be used to save the
- X intermediate results. For example, the result of adding 7 to the
- X previous result can be saved by typing:
- X
- X old = . + 7
- X
- X Functions can be used in expressions. There are a great number of
- X pre-defined functions. For example, the following will calculate
- X the factorial of the value of 'old':
- X
- X fact(old)
- X
- X and the calculator prints 13763753091226345046315979581580902400000000.
- X Notice that numbers can be very large. (There is a practical limit
- X of several thousand digits before calculations become too slow.)
- X
- X The calculator can calculate transcendental functions, and accept and
- X display numbers in real or exponential format. For example, typing:
- X
- X config("display", 50)
- X epsilon(1e-50)
- X sin(1)
- X
- X prints "~.84147098480789650665250232163029899962256306079837".
- X
- X The calculator also knows about complex numbers, so that typing:
- X
- X (2+3i) * (4-3i)
- X
- X prints "17+6i".
- END_OF_FILE
- if test 1895 -ne `wc -c <'help/intro'`; then
- echo shar: \"'help/intro'\" unpacked with wrong size!
- fi
- # end of 'help/intro'
- fi
- if test -f 'help/list' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'help/list'\"
- else
- echo shar: Extracting \"'help/list'\" \(1880 characters\)
- sed "s/^X//" >'help/list' <<'END_OF_FILE'
- XUsing lists
- X
- X Lists are a sequence of values which are doubly linked so that
- X elements can be removed or inserted anywhere within the list.
- X The function 'list' creates a list with possible initial elements.
- X For example,
- X
- X x = list(4, 6, 7);
- X
- X creates a list in the variable x of three elements, in the order
- X 4, 6, and 7.
- X
- X The 'push' and 'pop' functions insert or remove an element from
- X the beginning of the list. The 'append' and 'remove' functions
- X insert or remove an element from the end of the list. The 'insert'
- X and 'delete' functions insert or delete an element from the middle
- X (or ends) of a list. The functions which insert elements return
- X the null value, but the functions which remove an element return
- X the element as their value. The 'size' function returns the number
- X of elements in the list.
- X
- X Note that these functions manipulate the actual list argument,
- X instead of returning a new list. Thus in the example:
- X
- X push(x, 9);
- X
- X x becomes a list of four elements, in the order 9, 4, 6, and 7.
- X Lists can be copied by assigning them to another variable.
- X
- X An arbitrary element of a linked list can be accessed by using the
- X double-bracket operator. The beginning of the list has index 0.
- X Thus in the new list x above, the expression x[[0]] returns the
- X value of the first element of the list, which is 9. Note that this
- X indexing does not remove elements from the list.
- X
- X Since lists are doubly linked in memory, random access to arbitrary
- X elements can be slow if the list is large. However, for each list
- X a pointer is kept to the latest indexed element, thus relatively
- X sequential accesses to the elements in a list will not be slow.
- X
- X Lists can be searched for particular values by using the 'search'
- X and 'rsearch' functions. They return the element number of the
- X found value (zero based), or null if the value does not exist in
- X the list.
- END_OF_FILE
- if test 1880 -ne `wc -c <'help/list'`; then
- echo shar: \"'help/list'\" unpacked with wrong size!
- fi
- # end of 'help/list'
- fi
- if test -f 'help/operator' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'help/operator'\"
- else
- echo shar: Extracting \"'help/operator'\" \(2549 characters\)
- sed "s/^X//" >'help/operator' <<'END_OF_FILE'
- XOperators
- X
- X The operators are similar to C, but the precedence of most of
- X the operators differs. In addition, there are several additional
- X operators, and some C operators are missing. The following list
- X gives the operators arranged in order of precedence, from the
- X least tightly binding to the most tightly binding.
- X
- X
- X , Comma operator.
- X For situations in which a comma is used for another purpose
- X (function arguments, array indexing, and the print statement),
- X parenthesis must be used around the comma operator.
- X
- X a?:b:c Conditional value.
- X The test for 'a' is identical to an if test.
- X
- X = += -= *= /= %= //= &= |= <<= >>= ^= **=
- X Assignments.
- X
- X || Conditional OR.
- X Unlike C, the result is the first non-zero expression or 0,
- X instead of just 0 or 1.
- X
- X && Conditional AND.
- X Unlike C, the result is the last expression or 0,
- X instead of just 0 or 1.
- X
- X == != <= >= < >
- X Relations.
- X
- X + -
- X Binary plus and minus.
- X
- X * / // %
- X Multiply, divide. and modulo.
- X Please Note: The '/' operator is a fractional divide,
- X whereas the '//' is an integral divide. Thus think of '/'
- X as division of real numbers, and think of '//' as division
- X of integers (e.g., 8 / 3 is 8/3 whereas 8 // 3 is 2).
- X The '%' is integral or fractional modulus (e.g., 11%4 is 3,
- X and 10%pi() is ~.575222).
- X
- X | Logical OR.
- X The signs of numbers do not affect the bit value.
- X
- X & Logical AND.
- X The signs of numbers do not affect the bit value.
- X
- X ^ ** << >>
- X Powers and shifts.
- X The '^' and '**' are both exponentiation (e.g., 2^3 is 8).
- X The signs of numbers do not affect the bit values of shifts.
- X These operators associate rightward (e.g., 1<<3^2 is 512).
- X
- X + - !
- X Unary operators.
- X The '!' is the logical NOT operator. Be careful about
- X using this as the first character of a top level command,
- X since it is also used for executing UNIX commands.
- X
- X ++ --
- X Pre or post indexing.
- X These are applicable only to variables.
- X
- X [ ] [[ ]] . ( )
- X Indexing, double-bracket indexing, element references,
- X and function calls. Indexing can only be applied to matrices,
- X element references can only be applied to objects, but
- X double-bracket indexing can be applied to matrices, objects,
- X or lists.
- X
- X variables constants . ( )
- X These are variable names and constants, the special '.' symbol,
- X or a parenthesized expression. Variable names begin with a
- X letter, but then can contain letters, digits, or underscores.
- X Constants are numbers in various formats, or strings inside
- X either single or double quote marks.
- END_OF_FILE
- if test 2549 -ne `wc -c <'help/operator'`; then
- echo shar: \"'help/operator'\" unpacked with wrong size!
- fi
- # end of 'help/operator'
- fi
- if test -f 'help/sums' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'help/sums'\"
- else
- echo shar: Extracting \"'help/sums'\" \(361 characters\)
- sed "s/^X//" >'help/sums' <<'END_OF_FILE'
- X58784 4 Makefile
- X34745 25 builtin
- X43439 6 command
- X641 9 config
- X9511 2 credit
- X37950 6 define
- X3174 4 environment
- X52378 3 expression
- X46486 15 file
- X42777 3 help
- X23416 2 history
- X51967 3 interrupt
- X30991 4 intro
- X35089 4 list
- X50373 9 mat
- X43038 14 obj
- X13133 5 operator
- X12056 14 overview
- X29205 17 statement
- X0 0 sums
- X1418 5 todo
- X129 8 types
- X47095 2 usage
- X19801 5 variable
- END_OF_FILE
- if test 361 -ne `wc -c <'help/sums'`; then
- echo shar: \"'help/sums'\" unpacked with wrong size!
- fi
- # end of 'help/sums'
- fi
- if test -f 'help/todo' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'help/todo'\"
- else
- echo shar: Extracting \"'help/todo'\" \(2320 characters\)
- sed "s/^X//" >'help/todo' <<'END_OF_FILE'
- XNeeded enhancements
- X
- X Send calc comments, suggestions, bug fixes, enhancements and
- X interesting calc scripts that you would like you see included in
- X future distributions to:
- X
- X dbell@pdact.pd.necisa.oz.au and chongo@toad.com
- X
- X The following items are in the calc wish list. Programs like
- X this can be extended and improved forever. The following is a
- X list of changes which might be done someday.
- X
- X * Use faster multiply and divide algorithms for large numbers.
- X
- X * Add error handling statements, so that QUITs, errors from the
- X 'eval' function, division by zeroes, and so on can be caught.
- X This should be done using syntax similar to:
- X
- X ONERROR statement DO statement;
- X
- X Something like signal isn't versatile enough.
- X
- X * Add a debugging capability so that functions can be single stepped,
- X breakpoints inserted, variables displayed, and so on.
- X
- X * Figure out how to write all variables out to a file, including
- X deeply nested arrays, lists, and objects.
- X
- X * Make the command history useful:
- X
- X allowing editing of old commands
- X enable history to also re-fetch the results of old
- X commands, not just re-executing them
- X allow the inclusion of old commands or values of old
- X commands inside expressions.
- X
- X * Add a "ksh-like" history editor (both vi and emacs mode).
- X
- X * Implement pointers.
- X
- X * Add initializers for matrices. Perhaps allow something line:
- X
- X mat yummo[] = {2, 3, 5, 7, 13, 17, 19, 31, 61, 89, 107};
- X
- X * Eliminate the need for the define keyword by doing smarter parsing.
- X
- X * Allow results of a command (or all commands) to be re-directed to a
- X file or piped into a unix command.
- X
- X * Add some kind of #include and #define facility. Perhaps use
- X the C pre-processor itself?
- X
- X * Implement an autoload feature. Associate a calc library filename
- X with a function, object, matrix or variable. On the 1st reference
- X of such item, perform an automatic load of that file.
- X
- X * Allow one to undefine anything. Allow one to test of anything
- X is defined.
- X
- X * Support a more general input and output base mode and just dec,
- X hex or octal.
- X
- X * Allow support of POSIX bc via a translator reads bc commands,
- X converts it to calc and pipes it into calc.
- X
- X * Implement symbolic algebra, such as polynomial manipulation.
- END_OF_FILE
- if test 2320 -ne `wc -c <'help/todo'`; then
- echo shar: \"'help/todo'\" unpacked with wrong size!
- fi
- # end of 'help/todo'
- fi
- if test -f 'help/usage' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'help/usage'\"
- else
- echo shar: Extracting \"'help/usage'\" \(551 characters\)
- sed "s/^X//" >'help/usage' <<'END_OF_FILE'
- XCalc command line
- X
- X Calc has the following command line:
- X
- X calc [-h] [-q] [calc_command ...]
- X
- X -h print a help message (equivalent to the
- X help command)
- X
- X -q By default, calc executes each file specified
- X in the :-separated list found in the environment
- X variable $CALCRC. If $CALCRC does not exist,
- X an internal default is used.
- X
- X If some calc_commands arguments are given on the command line,
- X calc executes these commands and then exists. If no command
- X line arguments are given, calc prompts and reads commands
- X from standard input.
- END_OF_FILE
- if test 551 -ne `wc -c <'help/usage'`; then
- echo shar: \"'help/usage'\" unpacked with wrong size!
- fi
- # end of 'help/usage'
- fi
- if test -f 'help/variable' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'help/variable'\"
- else
- echo shar: Extracting \"'help/variable'\" \(2423 characters\)
- sed "s/^X//" >'help/variable' <<'END_OF_FILE'
- XVariable declarations
- X
- X Variables can be declared as either being global or local.
- X Global variables are visible to all functions and on the command
- X line. Local variables are visible only within a single function or
- X command sequence. When the function or command sequence returns,
- X the local variables are deleted.
- X
- X To declare one or more variables, the 'local' or 'global' keywords
- X are used, followed by the desired list of variable names, separated
- X by commas. The definition is terminated with a semicolon. Examples
- X of declarations are:
- X
- X local x, y, z;
- X global fred;
- X local foo, bar;
- X
- X Within function declarations, all variables must be defined.
- X But on the top level command line, assignments automatically define
- X global variables as needed. For example, on the top level command
- X line, the following defines the global variable x if it had not
- X already been defined:
- X
- X x = 7
- X
- X Variables have no fixed type, thus there is no need or way to
- X specify the types of variables as they are defined. Instead, the
- X types of variables change as they are assigned to or are specified
- X in special statements such as 'mat' and 'obj'. When a variable is
- X first defined using 'local' or 'global', it has the null type.
- X
- X If a procedure defines a local variable name which matches a
- X global variable name, or has a parameter name which matches a
- X global variable name, then the local variable or parameter takes
- X precedence within that procedure, and the global variable is not
- X directly accessible.
- X
- X There are no pointers in the calculator language, thus all
- X arguments to user-defined functions are normally passed by value.
- X This is true even for matrices, strings, and lists. In order
- X to circumvent this, the '&' operator is allowed before a variable
- X when it is an argument to a function. When this is done, the
- X address of the variable is passed to the function instead of its
- X value. This is true no matter what the type of the variable is.
- X This allows for fast calls of functions when the passed variable
- X is huge (such as a large array). However, the passed variable can
- X then be changed by the function if the parameter is assigned into.
- X The function being called does not need to know if the variable
- X is being passed by value or by address.
- X
- X Built-in functions and object functions always accept their
- X arguments as addresses, thus there is no need to use '&' when
- X calling built-in functions.
- END_OF_FILE
- if test 2423 -ne `wc -c <'help/variable'`; then
- echo shar: \"'help/variable'\" unpacked with wrong size!
- fi
- # end of 'help/variable'
- fi
- if test -f 'label.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'label.h'\"
- else
- echo shar: Extracting \"'label.h'\" \(534 characters\)
- sed "s/^X//" >'label.h' <<'END_OF_FILE'
- X/*
- X * Copyright (c) 1992 David I. Bell
- X * Permission is granted to use, distribute, or modify this source,
- X * provided that this copyright notice remains intact.
- X */
- X
- X
- X/*
- X * Label structures.
- X */
- Xtypedef struct {
- X long l_offset; /* offset into code of label */
- X long l_chain; /* offset into code of undefined chain */
- X char *l_name; /* name of label if any */
- X} LABEL;
- X
- Xextern void initlabels(), definelabel(), addlabel();
- Xextern void checklabels(), clearlabel(), setlabel();
- Xextern void uselabel();
- X
- X/* END CODE */
- END_OF_FILE
- if test 534 -ne `wc -c <'label.h'`; then
- echo shar: \"'label.h'\" unpacked with wrong size!
- fi
- # end of 'label.h'
- fi
- if test ! -d 'lib' ; then
- echo shar: Creating directory \"'lib'\"
- mkdir 'lib'
- fi
- if test -f 'lib/Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'lib/Makefile'\"
- else
- echo shar: Extracting \"'lib/Makefile'\" \(1215 characters\)
- sed "s/^X//" >'lib/Makefile' <<'END_OF_FILE'
- X#
- X# lib - makefile for calc library scripts
- X#
- X# Copyright (c) 1992 David I. Bell and Landon Curt Noll
- X# Permission is granted to use, distribute, or modify this source,
- X# provided that this copyright notice remains intact.
- X#
- X# Arbitrary precision calculator.
- X#
- X# calculator by David I. Bell
- X# makefile by Landon Curt Noll
- X
- X# Normally, the upper level makefile will set these values. We provide
- X# a default here just in case you want to build from this directory.
- X#
- X# where to install things
- XLIBDIR= /usr/local/lib/calc
- X# how to build a directory
- XMKDIR=mkdir -p
- X#MKDIR=mkdir
- X
- X# The calc files to install
- X#
- XCALC_FILES= README bigprime.cal deg.cal ellip.cal lucas.cal lucas_chk.cal \
- X lucas_tbl.cal mersenne.cal mod.cal nextprim.cal pell.cal pi.cal \
- X pollard.cal poly.cal psqrt.cal quat.cal regress.cal solve.cal \
- X sumsq.cal surd.cal unitfrac.cal varargs.cal
- X
- XSHELL= /bin/sh
- X
- Xall: ${CALC_FILES}
- X
- Xclean:
- X
- Xclobber:
- X
- Xinstall: all
- X -@if [ ! -d ${LIBDIR} ]; then \
- X echo " ${MKDIR} ${LIBDIR}"; \
- X ${MKDIR} ${LIBDIR}; \
- X fi
- X @for i in ${CALC_FILES}; do \
- X echo " rm -f ${LIBDIR}/$$i"; \
- X rm -f ${LIBDIR}/$$i; \
- X echo " chmod 0444 $$i"; \
- X chmod 0444 $$i; \
- X echo " cp $$i ${LIBDIR}"; \
- X cp $$i ${LIBDIR}; \
- X done
- END_OF_FILE
- if test 1215 -ne `wc -c <'lib/Makefile'`; then
- echo shar: \"'lib/Makefile'\" unpacked with wrong size!
- fi
- # end of 'lib/Makefile'
- fi
- if test -f 'lib/bernoulli.cal' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'lib/bernoulli.cal'\"
- else
- echo shar: Extracting \"'lib/bernoulli.cal'\" \(1454 characters\)
- sed "s/^X//" >'lib/bernoulli.cal' <<'END_OF_FILE'
- X/*
- X * Copyright (c) 1992 David I. Bell
- X * Calculate the Nth Bernoulli number B(n).
- X * This uses the following symbolic formula to calculate B(n):
- X *
- X * (b+1)^(n+1) - b^(n+1) = 0
- X *
- X * where b is a dummy value, and each power b^i gets replaced by B(i).
- X * For example, for n = 3:
- X * (b+1)^4 - b^4 = 0
- X * b^4 + 4*b^3 + 6*b^2 + 4*b + 1 - b^4 = 0
- X * 4*b^3 + 6*b^2 + 4*b + 1 = 0
- X * 4*B(3) + 6*B(2) + 4*B(1) + 1 = 0
- X * B(3) = -(6*B(2) + 4*B(1) + 1) / 4
- X *
- X * The combinatorial factors in the expansion of the above formula are
- X * calculated interatively, and we use the fact that B(2i+1) = 0 if i > 0.
- X * Since all previous B(n)'s are needed to calculate a particular B(n), all
- X * values obtained are saved in an array for ease in repeated calculations.
- X */
- Xglobal Bn, Bnmax;
- Xmat Bn[1001];
- XBnmax = 0;
- X
- X
- Xdefine B(n)
- X{
- X local nn, np1, i, sum, mulval, divval, combval;
- X
- X if (!isint(n) || (n < 0))
- X quit "Non-negative integer required for Bernoulli";
- X
- X if (n == 0)
- X return 1;
- X if (n == 1)
- X return -1/2;
- X if (isodd(n))
- X return 0;
- X if (n > 1000)
- X quit "Very large Bernoulli";
- X
- X if (n <= Bnmax)
- X return Bn[n];
- X
- X for (nn = Bnmax + 2; nn <= n; nn+=2) {
- X np1 = nn + 1;
- X mulval = np1;
- X divval = 1;
- X combval = 1;
- X sum = 1 - np1 / 2;
- X for (i = 2; i < np1; i+=2) {
- X combval = combval * mulval-- / divval++;
- X combval = combval * mulval-- / divval++;
- X sum += combval * Bn[i];
- X }
- X Bn[nn] = -sum / np1;
- X }
- X Bnmax = n;
- X return Bn[n];
- X}
- X
- Xprint 'B(n) defined';
- END_OF_FILE
- if test 1454 -ne `wc -c <'lib/bernoulli.cal'`; then
- echo shar: \"'lib/bernoulli.cal'\" unpacked with wrong size!
- fi
- # end of 'lib/bernoulli.cal'
- fi
- if test -f 'lib/bigprime.cal' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'lib/bigprime.cal'\"
- else
- echo shar: Extracting \"'lib/bigprime.cal'\" \(565 characters\)
- sed "s/^X//" >'lib/bigprime.cal' <<'END_OF_FILE'
- X/*
- X * Copyright (c) 1992 David I. Bell
- X * Permission is granted to use, distribute, or modify this source,
- X * provided that this copyright notice remains intact.
- X *
- X * A prime test, base a, on p*2^x+1 for even x>m.
- X */
- X
- Xdefine bigprime(a, m, p)
- X{
- X local n1, n;
- X
- X n1 = 2^m * p;
- X for (;;) {
- X m++;
- X n1 += n1;
- X n = n1 + 1;
- X if (isodd(m))
- X continue;
- X print m;
- X if (pmod(a, n1 / 2, n) != n1)
- X continue;
- X if (pmod(a, n1 / p, n) == 1)
- X continue;
- X print " " : n;
- X }
- X}
- X
- Xglobal lib_debug;
- Xif (!isnum(lib_debug) || lib_debug>0) print "bigprime(a, m, p) defined";
- END_OF_FILE
- if test 565 -ne `wc -c <'lib/bigprime.cal'`; then
- echo shar: \"'lib/bigprime.cal'\" unpacked with wrong size!
- fi
- # end of 'lib/bigprime.cal'
- fi
- if test -f 'lib/deg.cal' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'lib/deg.cal'\"
- else
- echo shar: Extracting \"'lib/deg.cal'\" \(2204 characters\)
- sed "s/^X//" >'lib/deg.cal' <<'END_OF_FILE'
- X/*
- X * Copyright (c) 1992 David I. Bell
- X * Permission is granted to use, distribute, or modify this source,
- X * provided that this copyright notice remains intact.
- X *
- X * Calculate in degrees, minutes, and seconds.
- X */
- X
- Xobj dms {deg, min, sec};
- X
- Xdefine dms(deg, min, sec)
- X{
- X local ans;
- X
- X if (isnull(sec))
- X sec = 0;
- X if (isnull(min))
- X min = 0;
- X obj dms ans;
- X ans.deg = deg;
- X ans.min = min;
- X ans.sec = sec;
- X fixdms(&ans);
- X return ans;
- X}
- X
- X
- Xdefine dms_add(a, b)
- X{
- X local ans;
- X
- X obj dms ans;
- X ans.deg = 0;
- X ans.min = 0;
- X ans.sec = 0;
- X if (istype(a, ans)) {
- X ans.deg += a.deg;
- X ans.min += a.min;
- X ans.sec += a.sec;
- X } else
- X ans.deg += a;
- X if (istype(b, ans)) {
- X ans.deg += b.deg;
- X ans.min += b.min;
- X ans.sec += b.sec;
- X } else
- X ans.deg += b;
- X fixdms(&ans);
- X return ans;
- X}
- X
- X
- Xdefine dms_neg(a)
- X{
- X local ans;
- X
- X obj dms ans;
- X ans.deg = -ans.deg;
- X ans.min = -ans.min;
- X ans.sec = -ans.sec;
- X return ans;
- X}
- X
- X
- Xdefine dms_sub(a, b)
- X{
- X return a - b;
- X}
- X
- X
- Xdefine dms_mul(a, b)
- X{
- X local ans;
- X
- X obj dms ans;
- X if (istype(a, ans) && istype(b, ans))
- X quit "Cannot multiply degrees together";
- X if (istype(a, ans)) {
- X ans.deg = a.deg * b;
- X ans.min = a.min * b;
- X ans.sec = a.sec * b;
- X } else {
- X ans.deg = b.deg * a;
- X ans.min = b.min * a;
- X ans.sec = b.sec * a;
- X }
- X fixdms(&ans);
- X return ans;
- X}
- X
- X
- Xdefine dms_print(a)
- X{
- X print a.deg : 'd' : a.min : 'm' : a.sec : 's' :;
- X}
- X
- X
- Xdefine dms_abs(a)
- X{
- X return a.deg + a.min / 60 + a.sec / 3600;
- X}
- X
- X
- Xdefine fixdms(a)
- X{
- X a.min += frac(a.deg) * 60;
- X a.deg = int(a.deg);
- X a.sec += frac(a.min) * 60;
- X a.min = int(a.min);
- X a.min += a.sec // 60;
- X a.sec %= 60;
- X a.deg += a.min // 60;
- X a.min %= 60;
- X a.deg %= 360;
- X}
- X
- Xglobal lib_debug;
- Xif (!isnum(lib_debug) || lib_debug>0) print "obj dms {deg, min, sec} defined"
- Xif (!isnum(lib_debug) || lib_debug>0) print "dms(deg, min, sec) defined"
- Xif (!isnum(lib_debug) || lib_debug>0) print "dms_add(a, b) defined"
- Xif (!isnum(lib_debug) || lib_debug>0) print "dms_neg(a) defined"
- Xif (!isnum(lib_debug) || lib_debug>0) print "dms_sub(a, b) defined"
- Xif (!isnum(lib_debug) || lib_debug>0) print "dms_mul(a, b) defined"
- Xif (!isnum(lib_debug) || lib_debug>0) print "dms_print(a) defined"
- Xif (!isnum(lib_debug) || lib_debug>0) print "dms_abs(a) defined"
- END_OF_FILE
- if test 2204 -ne `wc -c <'lib/deg.cal'`; then
- echo shar: \"'lib/deg.cal'\" unpacked with wrong size!
- fi
- # end of 'lib/deg.cal'
- fi
- if test -f 'lib/mersenne.cal' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'lib/mersenne.cal'\"
- else
- echo shar: Extracting \"'lib/mersenne.cal'\" \(843 characters\)
- sed "s/^X//" >'lib/mersenne.cal' <<'END_OF_FILE'
- X/*
- X * Copyright (c) 1992 David I. Bell
- X * Permission is granted to use, distribute, or modify this source,
- X * provided that this copyright notice remains intact.
- X *
- X * Perform a primality test of 2^p-1, for prime p>1.
- X */
- X
- Xdefine mersenne(p)
- X{
- X local u, i, p_mask;
- X
- X /* firewall */
- X if (! isint(p))
- X quit "p is not an integer";
- X
- X /* two is a special case */
- X if (p == 2)
- X return 1;
- X
- X /* if p is not prime, then 2^p-1 is not prime */
- X if (! ptest(p,10))
- X return 0;
- X
- X /* calculate 2^p-1 for later mods */
- X p_mask = 2^p - 1;
- X
- X /* lltest: u(i+1) = u(i)^2 - 2 mod 2^p-1 */
- X u = 4;
- X for (i = 2; i < p; ++i) {
- X u = u^2 - 2;
- X u = u&p_mask + u>>p;
- X if (u > p_mask)
- X u = u&p_mask + 1;
- X }
- X
- X /* 2^p-1 is prime iff u(p) = 0 mod 2^p-1 */
- X return (u == p_mask);
- X}
- X
- Xglobal lib_debug;
- Xif (!isnum(lib_debug) || lib_debug>0) print "mersenne(p) defined";
- END_OF_FILE
- if test 843 -ne `wc -c <'lib/mersenne.cal'`; then
- echo shar: \"'lib/mersenne.cal'\" unpacked with wrong size!
- fi
- # end of 'lib/mersenne.cal'
- fi
- if test -f 'lib/nextprim.cal' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'lib/nextprim.cal'\"
- else
- echo shar: Extracting \"'lib/nextprim.cal'\" \(450 characters\)
- sed "s/^X//" >'lib/nextprim.cal' <<'END_OF_FILE'
- X/*
- X * Copyright (c) 1992 David I. Bell
- X * Permission is granted to use, distribute, or modify this source,
- X * provided that this copyright notice remains intact.
- X *
- X * Function to find the next prime (probably).
- X */
- X
- Xdefine nextprime(n, tries)
- X{
- X if (isnull(tries))
- X tries = 20;
- X if (iseven(n))
- X n++;
- X while (ptest(n, tries) == 0)
- X n += 2;
- X return n;
- X}
- X
- Xglobal lib_debug;
- Xif (!isnum(lib_debug) || lib_debug>0) print "nextprime(n, tries) defined";
- END_OF_FILE
- if test 450 -ne `wc -c <'lib/nextprim.cal'`; then
- echo shar: \"'lib/nextprim.cal'\" unpacked with wrong size!
- fi
- # end of 'lib/nextprim.cal'
- fi
- if test -f 'lib/pell.cal' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'lib/pell.cal'\"
- else
- echo shar: Extracting \"'lib/pell.cal'\" \(1290 characters\)
- sed "s/^X//" >'lib/pell.cal' <<'END_OF_FILE'
- X/*
- X * Copyright (c) 1992 David I. Bell
- X * Permission is granted to use, distribute, or modify this source,
- X * provided that this copyright notice remains intact.
- X *
- X * Solve Pell's equation; Returns the solution X to: X^2 - D * Y^2 = 1.
- X * Type the solution to pells equation for a particular D.
- X */
- X
- Xdefine pell(D)
- X{
- X local X, Y;
- X
- X X = pellx(D);
- X if (isnull(X)) {
- X print "D=":D:" is square";
- X return;
- X }
- X Y = isqrt((X^2 - 1) / D);
- X print X : "^2 - " : D : "*" : Y : "^2 = " : X^2 - D*Y^2;
- X}
- X
- X
- X/*
- X * Function to solve Pell's equation
- X * Returns the solution X to:
- X * X^2 - D * Y^2 = 1
- X */
- Xdefine pellx(D)
- X{
- X local R, Rp, U, Up, V, Vp, A, T, Q1, Q2, n, ans, tmp;
- X
- X mat ans[2,2];
- X mat tmp[2,2];
- X
- X R = isqrt(D);
- X Vp = D - R^2;
- X if (Vp == 0)
- X return;
- X Rp = R + R;
- X U = Rp;
- X Up = U;
- X V = 1;
- X A = 0;
- X n = 0;
- X ans[0,0] = 1;
- X ans[1,1] = 1;
- X tmp[0,1] = 1;
- X tmp[1,0] = 1;
- X do {
- X T = V;
- X V = A * (Up - U) + Vp;
- X Vp = T;
- X A = U // V;
- X Up = U;
- X U = Rp - U % V;
- X tmp[0,0] = A;
- X ans *= tmp;
- X n++;
- X } while (A != Rp);
- X Q2 = ans[[1]];
- X Q1 = isqrt(Q2^2 * D + 1);
- X if (isodd(n)) {
- X T = Q1^2 + D * Q2^2;
- X Q2 = Q1 * Q2 * 2;
- X Q1 = T;
- X }
- X return Q1;
- X}
- X
- Xglobal lib_debug;
- Xif (!isnum(lib_debug) || lib_debug>0) print "pell(D) defined";
- Xif (!isnum(lib_debug) || lib_debug>0) print "pellx(D) defined";
- END_OF_FILE
- if test 1290 -ne `wc -c <'lib/pell.cal'`; then
- echo shar: \"'lib/pell.cal'\" unpacked with wrong size!
- fi
- # end of 'lib/pell.cal'
- fi
- if test -f 'lib/pi.cal' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'lib/pi.cal'\"
- else
- echo shar: Extracting \"'lib/pi.cal'\" \(1320 characters\)
- sed "s/^X//" >'lib/pi.cal' <<'END_OF_FILE'
- X/*
- X * Copyright (c) 1992 David I. Bell
- X * Permission is granted to use, distribute, or modify this source,
- X * provided that this copyright notice remains intact.
- X *
- X * Calculate pi within the specified epsilon using the quartic convergence
- X * iteration.
- X */
- X
- Xdefine qpi(epsilon)
- X{
- X local niter, yn, ym, tm, an, am, t, tn, sqrt2, epsilon2, count, digits;
- X local bits, bits2;
- X
- X if (isnull(epsilon))
- X epsilon = epsilon();
- X digits = digits(1/epsilon);
- X if (digits <= 8) { niter = 1; epsilon = 1e-8; }
- X else if (digits <= 40) { niter = 2; epsilon = 1e-40; }
- X else if (digits <= 170) { niter = 3; epsilon = 1e-170; }
- X else if (digits <= 693) { niter = 4; epsilon = 1e-693; }
- X else {
- X niter = 4;
- X t = 693;
- X while (t < epsilon) {
- X ++niter;
- X t *= 4;
- X }
- X }
- X epsilon2 = epsilon/(digits/10 + 1);
- X digits = digits(1/epsilon2);
- X sqrt2 = sqrt(2, epsilon2);
- X bits = abs(log2(epsilon)) + 1;
- X bits2 = abs(log2(epsilon2)) + 1;
- X yn = sqrt2 - 1;
- X an = 6 - 4 * sqrt2;
- X tn = 2;
- X for (count = 0; count < niter; count++) {
- X ym = yn;
- X am = an;
- X tn *= 4;
- X t = sqrt(sqrt(1-ym^4, epsilon2), epsilon2);
- X yn = (1-t)/(1+t);
- X an = (1+yn)^4*am-tn*yn*(1+yn+yn^2);
- X yn = bround(yn, bits2);
- X an = bround(an, bits2);
- X }
- X return (bround(1/an, bits));
- X}
- X
- Xglobal lib_debug;
- Xif (!isnum(lib_debug) || lib_debug>0) print "qpi(epsilon) defined";
- END_OF_FILE
- if test 1320 -ne `wc -c <'lib/pi.cal'`; then
- echo shar: \"'lib/pi.cal'\" unpacked with wrong size!
- fi
- # end of 'lib/pi.cal'
- fi
- if test -f 'lib/pollard.cal' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'lib/pollard.cal'\"
- else
- echo shar: Extracting \"'lib/pollard.cal'\" \(630 characters\)
- sed "s/^X//" >'lib/pollard.cal' <<'END_OF_FILE'
- X/*
- X * Copyright (c) 1992 David I. Bell
- X * Permission is granted to use, distribute, or modify this source,
- X * provided that this copyright notice remains intact.
- X *
- X * Factor using Pollard's p-1 method.
- X */
- X
- Xdefine factor(N, B, ai, af)
- X{
- X local a, k, i, d;
- X
- X if (isnull(B))
- X B = 1000;
- X if (isnull(ai))
- X ai = 2;
- X if (isnull(af))
- X af = ai + 20;
- X k = lcmfact(B);
- X d = lfactor(N, B);
- X if (d > 1)
- X return d;
- X for (a = ai; a <= af; a++) {
- X i = pmod(a, k, N);
- X d = gcd(i - 1, N);
- X if ((d > 1) && (d != N))
- X return d;
- X }
- X return 1;
- X}
- X
- Xglobal lib_debug;
- Xif (!isnum(lib_debug) || lib_debug>0) print "factor(N, B, ai, af) defined";
- END_OF_FILE
- if test 630 -ne `wc -c <'lib/pollard.cal'`; then
- echo shar: \"'lib/pollard.cal'\" unpacked with wrong size!
- fi
- # end of 'lib/pollard.cal'
- fi
- if test -f 'lib/psqrt.cal' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'lib/psqrt.cal'\"
- else
- echo shar: Extracting \"'lib/psqrt.cal'\" \(1010 characters\)
- sed "s/^X//" >'lib/psqrt.cal' <<'END_OF_FILE'
- X/*
- X * Copyright (c) 1992 David I. Bell
- X * Permission is granted to use, distribute, or modify this source,
- X * provided that this copyright notice remains intact.
- X *
- X * Calculate square roots modulo a prime.
- X *
- X * Returns null if number is not prime or if there is no square root.
- X * The smaller square root is always returned.
- X */
- X
- Xdefine psqrt(u, p)
- X{
- X local p1, q, n, y, r, v, w, t, k;
- X
- X p1 = p - 1;
- X r = lowbit(p1);
- X q = p >> r;
- X t = 1 << (r - 1);
- X for (n = 2; ; n++) {
- X if (ptest(n, 1) == 0)
- X continue;
- X y = pmod(n, q, p);
- X k = pmod(y, t, p);
- X if (k == 1)
- X continue;
- X if (k != p1)
- X return;
- X break;
- X }
- X t = pmod(u, (q - 1) / 2, p);
- X v = (t * u) % p;
- X w = (t^2 * u) % p;
- X while (w != 1) {
- X k = 0;
- X t = w;
- X do {
- X k++;
- X t = t^2 % p;
- X } while (t != 1);
- X if (k == r)
- X return;
- X t = pmod(y, 1 << (r - k - 1), p);
- X y = t^2 % p;
- X v = (v * t) % p;
- X w = (w * y) % p;
- X r = k;
- X }
- X return min(v, p - v);
- X}
- X
- X
- Xglobal lib_debug;
- Xif (!isnum(lib_debug) || lib_debug>0) print "psqrt(u, p) defined";
- END_OF_FILE
- if test 1010 -ne `wc -c <'lib/psqrt.cal'`; then
- echo shar: \"'lib/psqrt.cal'\" unpacked with wrong size!
- fi
- # end of 'lib/psqrt.cal'
- fi
- if test -f 'lib/solve.cal' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'lib/solve.cal'\"
- else
- echo shar: Extracting \"'lib/solve.cal'\" \(1192 characters\)
- sed "s/^X//" >'lib/solve.cal' <<'END_OF_FILE'
- X/*
- X * Copyright (c) 1992 David I. Bell
- X * Permission is granted to use, distribute, or modify this source,
- X * provided that this copyright notice remains intact.
- X *
- X * Solve the equation f(x) = 0 to within the desired error value for x.
- X * The function 'f' must be defined outside of this routine, and the low
- X * and high values are guesses which must produce values with opposite signs.
- X */
- X
- Xdefine solve(low, high, epsilon)
- X{
- X local flow, fhigh, fmid, mid, places;
- X
- X if (isnull(epsilon))
- X epsilon = epsilon();
- X if (epsilon <= 0)
- X quit "Non-positive epsilon value";
- X places = highbit(1 + int(1/epsilon)) + 1;
- X flow = f(low);
- X if (abs(flow) < epsilon)
- X return low;
- X fhigh = f(high);
- X if (abs(flow) < epsilon)
- X return high;
- X if (sgn(flow) == sgn(fhigh))
- X quit "Non-opposite signs";
- X while (1) {
- X mid = bround(high - fhigh * (high - low) / (fhigh - flow), places);
- X if ((mid == low) || (mid == high))
- X places++;
- X fmid = f(mid);
- X if (abs(fmid) < epsilon)
- X return mid;
- X if (sgn(fmid) == sgn(flow)) {
- X low = mid;
- X flow = fmid;
- X } else {
- X high = mid;
- X fhigh = fmid;
- X }
- X }
- X}
- X
- Xglobal lib_debug;
- Xif (!isnum(lib_debug) || lib_debug>0) print "solve(low, high, epsilon) defined";
- END_OF_FILE
- if test 1192 -ne `wc -c <'lib/solve.cal'`; then
- echo shar: \"'lib/solve.cal'\" unpacked with wrong size!
- fi
- # end of 'lib/solve.cal'
- fi
- if test -f 'lib/sumsq.cal' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'lib/sumsq.cal'\"
- else
- echo shar: Extracting \"'lib/sumsq.cal'\" \(879 characters\)
- sed "s/^X//" >'lib/sumsq.cal' <<'END_OF_FILE'
- X/*
- X * Copyright (c) 1992 David I. Bell
- X * Permission is granted to use, distribute, or modify this source,
- X * provided that this copyright notice remains intact.
- X *
- X * Determine the unique two positive integers whose squares sum to the
- X * specified prime. This is always possible for all primes of the form
- X * 4N+1, and always impossible for primes of the form 4N-1.
- X */
- X
- Xdefine ss(p)
- X{
- X local a, b, i, p4;
- X
- X if (p == 2) {
- X print "1^2 + 1^2 = 2";
- X return;
- X }
- X if ((p % 4) != 1) {
- X print p, "is not of the form 4N+1";
- X return;
- X }
- X if (!ptest(p, min(p-2, 10))) {
- X print p, "is not a prime";
- X return;
- X }
- X p4 = (p - 1) / 4;
- X i = 2;
- X do {
- X a = pmod(i++, p4, p);
- X } while ((a^2 % p) == 1);
- X b = p;
- X while (b^2 > p) {
- X i = b % a;
- X b = a;
- X a = i;
- X }
- X print a : "^2 +" , b : "^2 =" , a^2 + b^2;
- X}
- X
- Xglobal lib_debug;
- Xif (!isnum(lib_debug) || lib_debug>0) print "ss(p) defined";
- END_OF_FILE
- if test 879 -ne `wc -c <'lib/sumsq.cal'`; then
- echo shar: \"'lib/sumsq.cal'\" unpacked with wrong size!
- fi
- # end of 'lib/sumsq.cal'
- fi
- if test -f 'lib/unitfrac.cal' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'lib/unitfrac.cal'\"
- else
- echo shar: Extracting \"'lib/unitfrac.cal'\" \(849 characters\)
- sed "s/^X//" >'lib/unitfrac.cal' <<'END_OF_FILE'
- X/*
- X * Copyright (c) 1992 David I. Bell
- X * Permission is granted to use, distribute, or modify this source,
- X * provided that this copyright notice remains intact.
- X *
- X * Represent a fraction as sum of distinct unit fractions.
- X * The output is the unit fractions themselves, and in square brackets,
- X * the number of digits in the numerator and denominator of the value left
- X * to be found. Numbers larger than 3.5 become very difficult to calculate.
- X */
- X
- Xdefine unitfrac(x)
- X{
- X local d, di, n;
- X
- X if (x <= 0)
- X quit "Non-positive argument";
- X d = 2;
- X do {
- X n = int(1 / x) + 1;
- X if (n > d)
- X d = n;
- X di = 1/d;
- X print ' [': digits(num(x)): '/': digits(den(x)): ']',, di;
- X x -= di;
- X d++;
- X } while ((num(x) > 1) || (x == di) || (x == 1));
- X print ' [1/1]',, x;
- X}
- X
- X
- Xglobal lib_debug;
- Xif (!isnum(lib_debug) || lib_debug>0) print "unitfrac(x) defined";
- END_OF_FILE
- if test 849 -ne `wc -c <'lib/unitfrac.cal'`; then
- echo shar: \"'lib/unitfrac.cal'\" unpacked with wrong size!
- fi
- # end of 'lib/unitfrac.cal'
- fi
- if test -f 'lib/varargs.cal' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'lib/varargs.cal'\"
- else
- echo shar: Extracting \"'lib/varargs.cal'\" \(547 characters\)
- sed "s/^X//" >'lib/varargs.cal' <<'END_OF_FILE'
- X/*
- X * Copyright (c) 1992 David I. Bell
- X * Permission is granted to use, distribute, or modify this source,
- X * provided that this copyright notice remains intact.
- X *
- X * Example program to use 'varargs'.
- X *
- X * Program to sum the cubes of all the specified numbers.
- X */
- X
- Xdefine sc()
- X{
- X local s, i;
- X
- X s = 0;
- X for (i = 1; i <= param(0); i++) {
- X if (!isnum(param(i))) {
- X print "parameter",i,"is not a number";
- X continue;
- X }
- X s += param(i)^3;
- X }
- X return s;
- X}
- X
- Xglobal lib_debug;
- Xif (!isnum(lib_debug) || lib_debug>0) print "sc(a, b, ...) defined";
- END_OF_FILE
- if test 547 -ne `wc -c <'lib/varargs.cal'`; then
- echo shar: \"'lib/varargs.cal'\" unpacked with wrong size!
- fi
- # end of 'lib/varargs.cal'
- fi
- if test -f 'lint.sed' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'lint.sed'\"
- else
- echo shar: Extracting \"'lint.sed'\" \(1277 characters\)
- sed "s/^X//" >'lint.sed' <<'END_OF_FILE'
- X/^[a-z][a-z_]*\.c:$/d
- X/name declared but never used or defined: .* \/usr\/include\/malloc.h(/d
- X/implicitly declared to return int: _sysconf$/d
- X/name used but not defined: _sysconf in /d
- X/function returns value which is [a-z][a-z]* ignored: memcpy$/d
- X/function returns value which is [a-z][a-z]* ignored: strcpy$/d
- X/function returns value which is [a-z][a-z]* ignored: strncpy$/d
- X/function returns value which is [a-z][a-z]* ignored: strcat$/d
- X/function returns value which is [a-z][a-z]* ignored: memset$/d
- X/function returns value which is [a-z][a-z]* ignored: fclose$/d
- X/function returns value which is [a-z][a-z]* ignored: fflush$/d
- X/function returns value which is [a-z][a-z]* ignored: fprintf$/d
- X/function returns value which is [a-z][a-z]* ignored: printf$/d
- X/function returns value which is [a-z][a-z]* ignored: sprintf$/d
- X/function returns value which is [a-z][a-z]* ignored: vsprintf$/d
- X/function returns value which is [a-z][a-z]* ignored: fputc$/d
- X/function returns value which is [a-z][a-z]* ignored: fputs$/d
- X/function returns value which is [a-z][a-z]* ignored: putchar$/d
- X/function returns value which is [a-z][a-z]* ignored: ungetc$/d
- X/function returns value which is [a-z][a-z]* ignored: system$/d
- X/function returns value which is [a-z][a-z]* ignored: times$/d
- END_OF_FILE
- if test 1277 -ne `wc -c <'lint.sed'`; then
- echo shar: \"'lint.sed'\" unpacked with wrong size!
- fi
- # end of 'lint.sed'
- fi
- if test -f 'stdarg.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'stdarg.h'\"
- else
- echo shar: Extracting \"'stdarg.h'\" \(904 characters\)
- sed "s/^X//" >'stdarg.h' <<'END_OF_FILE'
- X/*
- X * Copyright (c) 1992 David I. Bell
- X * Permission is granted to use, distribute, or modify this source,
- X * provided that this copyright notice remains intact.
- X */
- X
- X#include "args.h"
- X
- X#ifndef STDARG_H
- X#define STDARG_H
- X
- X#ifdef VARARGS
- X
- X#include <varargs.h>
- X
- X#else /*VARARG*/
- X
- X#ifdef STDARG
- X
- X#if defined(__STDC__)
- X#include <stdarg.h>
- X#else
- X%;%;% BOGUS DEFINE! Must use ANSI C when STDARG is defined %;%;%
- X#endif
- X
- X#else /*STDARG*/
- X
- X/*
- X * SIMULATE_STDARG
- X *
- X * WARNING: This type of stdarg makes assumptions about the stack
- X * that may not be true on your system. You may want to
- X * define STDARG (if using ANSI C) or VARARGS.
- X */
- X
- Xtypedef char *va_list;
- X#define va_start(ap,parmn) (void)((ap) = (char*)(&(parmn) + 1))
- X#define va_end(ap) (void)((ap) = 0)
- X#define va_arg(ap, type) \
- X (((type*)((ap) = ((ap) + sizeof(type))))[-1])
- X
- X#endif /*STDARG*/
- X#endif /*VARARG*/
- X
- X#endif
- X
- X/* END CODE */
- END_OF_FILE
- if test 904 -ne `wc -c <'stdarg.h'`; then
- echo shar: \"'stdarg.h'\" unpacked with wrong size!
- fi
- # end of 'stdarg.h'
- fi
- if test -f 'string.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'string.h'\"
- else
- echo shar: Extracting \"'string.h'\" \(529 characters\)
- sed "s/^X//" >'string.h' <<'END_OF_FILE'
- X/*
- X * Copyright (c) 1992 David I. Bell
- X * Permission is granted to use, distribute, or modify this source,
- X * provided that this copyright notice remains intact.
- X */
- X
- X
- Xtypedef struct {
- X char *h_list; /* list of strings separated by nulls */
- X long h_used; /* characters used so far */
- X long h_avail; /* characters available for use */
- X long h_count; /* number of strings */
- X} STRINGHEAD;
- X
- X
- Xextern char *addstr(), *namestr(), *charstr(), *addliteral();
- Xextern long findstr(), stringindex();
- X
- Xextern void initstr();
- X
- X/* END CODE */
- END_OF_FILE
- if test 529 -ne `wc -c <'string.h'`; then
- echo shar: \"'string.h'\" unpacked with wrong size!
- fi
- # end of 'string.h'
- fi
- if test -f 'symbol.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'symbol.h'\"
- else
- echo shar: Extracting \"'symbol.h'\" \(1148 characters\)
- sed "s/^X//" >'symbol.h' <<'END_OF_FILE'
- X/*
- X * Copyright (c) 1992 David I. Bell
- X * Permission is granted to use, distribute, or modify this source,
- X * provided that this copyright notice remains intact.
- X */
- X
- X
- X/*
- X * Symbol Declarations.
- X */
- X#define SYM_UNDEFINED 0 /* undefined symbol */
- X#define SYM_PARAM 1 /* paramater symbol */
- X#define SYM_LOCAL 2 /* local symbol */
- X#define SYM_GLOBAL 3 /* global symbol */
- X
- X
- Xtypedef struct global GLOBAL;
- Xstruct global {
- X int g_len; /* length of symbol name */
- X char *g_name; /* global symbol name */
- X VALUE g_value; /* global symbol value */
- X GLOBAL *g_next; /* next symbol in hash chain */
- X};
- X
- X
- X/*
- X * Routines to search for global symbols.
- X */
- Xextern GLOBAL *addglobal(), *findglobal();
- X
- X
- X/*
- X * Routines to return names of variables.
- X */
- Xextern char *localname(), *globalname(), *paramname();
- X
- X
- X/*
- X * Other routines.
- X */
- Xextern long addlocal(), findlocal(), addparam(), findparam();
- Xextern void initlocals();
- Xextern void initglobals();
- Xextern void initfunctions();
- Xextern int writeglobals();
- Xextern int symboltype(); /* return the type of a variable name */
- Xextern void showglobals(); /* show the value of all global variables */
- X
- X/* END CODE */
- END_OF_FILE
- if test 1148 -ne `wc -c <'symbol.h'`; then
- echo shar: \"'symbol.h'\" unpacked with wrong size!
- fi
- # end of 'symbol.h'
- fi
- if test -f 'version.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'version.c'\"
- else
- echo shar: Extracting \"'version.c'\" \(531 characters\)
- sed "s/^X//" >'version.c' <<'END_OF_FILE'
- X/*
- X * Copyright (c) 1992 David I. Bell
- X * Permission is granted to use, distribute, or modify this source,
- X * provided that this copyright notice remains intact.
- X *
- X * version - determine the version of calc
- X */
- X
- X#include <stdio.h>
- X
- X#define MAJOR_VER 1 /* major version */
- X#define MINOR_VER 24 /* minor version */
- X#define PATCH_LEVEL 7 /* patch level */
- X
- Xvoid
- Xversion(stream)
- X FILE *stream; /* stream to write version on */
- X{
- X fprintf(stream, "calc version: %d.%d.%d\n",
- X MAJOR_VER, MINOR_VER, PATCH_LEVEL);
- X}
- X
- X/* END CODE */
- END_OF_FILE
- if test 531 -ne `wc -c <'version.c'`; then
- echo shar: \"'version.c'\" unpacked with wrong size!
- fi
- # end of 'version.c'
- fi
- echo shar: End of archive 1 \(of 21\).
- cp /dev/null ark1isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 21 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-