mirror of
https://github.com/lcn2/calc.git
synced 2025-08-19 01:13:27 +03:00
Compare commits
22 Commits
2.10.2t30
...
2.11.0t8.1
Author | SHA1 | Date | |
---|---|---|---|
|
5cc680fe42 | ||
|
2c72ea9339 | ||
|
0ffc341b10 | ||
|
2251281027 | ||
|
45a4b8469d | ||
|
9204d2fb8c | ||
|
35982c7cc8 | ||
|
4c0f2691e9 | ||
|
0d37ccb019 | ||
|
d7d31e9246 | ||
|
2dc364ee9f | ||
|
b54d8fc510 | ||
|
8cabbd6fb4 | ||
|
ea64a95b90 | ||
|
f60cbd24b2 | ||
|
97e9429000 | ||
|
1ce630ac19 | ||
|
4b98d5ff0e | ||
|
bad4535616 | ||
|
5307c4e16b | ||
|
b4e94b7eaa | ||
|
6e10e97592 |
84
BUGS
84
BUGS
@@ -1,8 +1,8 @@
|
||||
If you notice something wrong, strange or broken, try rereading:
|
||||
|
||||
README.FIRST
|
||||
README
|
||||
BUGS (in particular the bottom problems or mis-features section)
|
||||
HOWTO.INSTALL
|
||||
BUGS (this file)
|
||||
|
||||
If that does not help, cd to the calc source directory and try:
|
||||
|
||||
@@ -10,20 +10,21 @@ If that does not help, cd to the calc source directory and try:
|
||||
|
||||
Look at the end of the output, it should say something like:
|
||||
|
||||
9999: passed all tests /\../\
|
||||
9998: passed all tests /\../\
|
||||
9999: Ending regression tests
|
||||
|
||||
If it does not, then something is really broken!
|
||||
|
||||
If you made and modifications to calc beyond the simple Makefile
|
||||
configuration, try backing them out and see if things get better.
|
||||
|
||||
Check to see if the version of calc you are using is current. Calc
|
||||
distributions may be obtained from the official calc repository:
|
||||
To be sure that your version of calc is up to date, check out:
|
||||
|
||||
ftp://ftp.uu.net/pub/calc
|
||||
http://reality.sgi.com/chongo/tech/comp/calc/calc-download.html
|
||||
|
||||
If you are an alpha or beta tester, you may have a special pre-released
|
||||
version that is more advanced than what is in the ftp archive.
|
||||
The calc web site is located at:
|
||||
|
||||
http://reality.sgi.com/chongo/tech/comp/calc
|
||||
|
||||
=-=
|
||||
|
||||
@@ -45,6 +46,8 @@ When you send your report, please include the following information:
|
||||
|
||||
* the type of compiler you were using
|
||||
|
||||
* any compiler warnings or errors that you saw
|
||||
|
||||
* cd to the calc source directory, and type:
|
||||
|
||||
make debug > debug.out 2>&1 (sh, ksh, bash users)
|
||||
@@ -56,40 +59,49 @@ Stack traces from core dumps are useful to send as well.
|
||||
|
||||
=-=
|
||||
|
||||
The official calc repository is located in:
|
||||
|
||||
ftp://ftp.uu.net/pub/calc
|
||||
|
||||
If you don't have ftp access to that site, or if your version is more
|
||||
recent than what has been released to the ftp archive, you may, as a
|
||||
last resort, send EMail to:
|
||||
|
||||
chongo@toad.com
|
||||
|
||||
Indicate the version you have and that you would like a more up to date version.
|
||||
|
||||
=-=
|
||||
|
||||
Send any comments, suggestions and most importantly, fixes (in the form
|
||||
of a context diff patch) to:
|
||||
Send any comments, compiler warning messages, suggestions and most
|
||||
importantly, fixes (in the form of a context diff patch) to:
|
||||
|
||||
calc-tester@postofc.corp.sgi.com
|
||||
|
||||
=-=
|
||||
|
||||
Known problems or mis-features:
|
||||
Known bugs:
|
||||
|
||||
* In calc2.10.2t3, when scan() reads characters from stdin, they
|
||||
are not echoed. This also happens with fgets(files(0)) and
|
||||
fgetline(files(0)). Reports indicate that this did not happen in
|
||||
calc.2.10.1t20 but did in 2.10.2t0.
|
||||
None reported. We are sure some bugs exist. When you find them,
|
||||
please let us know! See the above for details on how to report and
|
||||
were to EMail your bug reports and hopefully patches to fix them.
|
||||
|
||||
* Many of LIBRARY, LIMITS and SEE ALSO sections of help files
|
||||
for builtins are either inconsistent or missing information.
|
||||
=-=
|
||||
|
||||
* The functions filepos2z() and z2filepos() do not work (or
|
||||
worse do not compile) when FILEPOS is 64 bits long.
|
||||
Calc Mis-features:
|
||||
|
||||
* There is some places in the source with obscure variable names
|
||||
and not much in the way of comments. We need some major cleanup
|
||||
and documentation.
|
||||
* The following shell command (written in sh,ksh,bash-like form) works:
|
||||
|
||||
calc '/*
|
||||
* comment
|
||||
*/
|
||||
print 2+3;'
|
||||
|
||||
However this (also written in sh,ksh,bash-like form) does not work:
|
||||
|
||||
echo '/*
|
||||
* comment
|
||||
*/
|
||||
print 2+3;' | calc
|
||||
|
||||
The 2nd example will result in an 'Unterminated comment' error.
|
||||
|
||||
* Calc does not support the #! exec method. For example of the
|
||||
following is placed in an executable file (assume the path to
|
||||
calc is correct) called /tmp/xyzzy:
|
||||
|
||||
#!/usr/local/bin/calc
|
||||
/*
|
||||
* comment
|
||||
*/
|
||||
print 2+3;
|
||||
|
||||
Will result in '"tmp" is undefined' and '"xyzzy" is undefined'
|
||||
error messages because calc considers $0 as an expression to
|
||||
evaluate.
|
||||
|
55
HOWTO.INSTALL
Normal file
55
HOWTO.INSTALL
Normal file
@@ -0,0 +1,55 @@
|
||||
Installing calc in 4 easy steps:
|
||||
|
||||
1) Look at the makefile, and adjust it to suit your needs.
|
||||
|
||||
Here are some Makefile hints:
|
||||
|
||||
Select a compiler set by commenting in the appropriate set
|
||||
of cc options. As shipped the Makefile assumes a gcc-like
|
||||
environment such as Linux. If a more appropriate cc set if
|
||||
found below, comment out the Linux set and comment in that
|
||||
set or edit the gcc set or the common cc set as needed.
|
||||
|
||||
You may or may not need RANLIB when building libraries.
|
||||
As shipped the Makefile assumes RANLIB is needed.
|
||||
Comment the in/out the RANLIB value if ranlib does
|
||||
not work or does not exist.
|
||||
|
||||
You may want to change the default pager used by calc.
|
||||
As shipped the Makefile assumes 'more'. On your system
|
||||
you may find 'less' to be a better pager.
|
||||
|
||||
The CALCBINDINGS is matter of personal taste. As shipped
|
||||
the Makefile assumes a default quasi-emacs-like command
|
||||
line editor. Changing CALCBINDINGS= altbind will cause ^D
|
||||
to end calc in a fashion similar to that of the bc(1) command.
|
||||
|
||||
Set TOPDIR to be the place under which help files, calc,
|
||||
include files and calc libs are to be installed. As shipped
|
||||
the Makefile assumes a TOPDIR of /usr/local/lib.
|
||||
|
||||
Set BINDIR to the place where calc is installed. As shipped
|
||||
the Makefile assumes a BINDIR /usr/local/bin.
|
||||
|
||||
Adjust other Makefile variables as needed.
|
||||
|
||||
2) build calc:
|
||||
|
||||
make all
|
||||
|
||||
==> We are interested in any compiler warnings (and errors) that
|
||||
you may find. See the BUGS file if you find any compiler
|
||||
warning or errors.
|
||||
|
||||
3) test calc:
|
||||
|
||||
make check
|
||||
|
||||
==> If you run into problems, follow the BUGS file instructions.
|
||||
|
||||
4) install calc:
|
||||
|
||||
make install
|
||||
|
||||
We suggest that you might want to read the README file and look at
|
||||
the calc help subsystem. See the README file for details.
|
29
LIBRARY
29
LIBRARY
@@ -10,13 +10,19 @@ precision arithmetic with integers, rational numbers, or complex numbers.
|
||||
There are also many numeric functions such as factorial and gcd, along
|
||||
with some transcendental functions such as sin and exp.
|
||||
|
||||
Take a look at the sample sub-directory. It contains a few simple
|
||||
examples of how to use libcalc.a that might be helpful to look at
|
||||
after you have read this file.
|
||||
|
||||
------------------
|
||||
FIRST THINGS FIRST
|
||||
------------------
|
||||
|
||||
*******************************************************************************
|
||||
* You MUST call libcalc_call_me_first() prior to using libcalc lib functions! *
|
||||
*******************************************************************************
|
||||
...............................................................................
|
||||
. .
|
||||
. You MUST call libcalc_call_me_first() prior to using libcalc lib functions! .
|
||||
. .
|
||||
...............................................................................
|
||||
|
||||
The function libcalc_call_me_first() takes no args and returns void. You
|
||||
need call libcalc_call_me_first() only once.
|
||||
@@ -98,7 +104,11 @@ For example:
|
||||
...
|
||||
|
||||
if ((error = setjmp(calc_jmp_buf)) != 0) {
|
||||
/* handle error */
|
||||
|
||||
/* reinitialize calc after a longjmp */
|
||||
reinitialize();
|
||||
|
||||
/* report the error */
|
||||
printf("Ouch: %s\n", calc_error);
|
||||
}
|
||||
calc_jmp = 1;
|
||||
@@ -434,3 +444,14 @@ for equality. The ccmp function returns TRUE if two complex numbers differ.
|
||||
There are three predefined values for complex numbers. You should clink
|
||||
them when you want to use them. They are _czero_, _cone_, and _conei_.
|
||||
These have the values 0, 1, and i.
|
||||
|
||||
----------------
|
||||
LAST THINGS LAST
|
||||
----------------
|
||||
|
||||
If you wish, when you are all doen you can call libcalc_call_me_last()
|
||||
to free a small amount of storage associated with the libcalc_call_me_first()
|
||||
call. This is not required, but is does bring things to a closure.
|
||||
|
||||
The function libcalc_call_me_last() takes no args and returns void. You
|
||||
need call libcalc_call_me_last() only once.
|
||||
|
119
README
119
README
@@ -1,68 +1,89 @@
|
||||
# Copyright (c) 1994 David I. Bell
|
||||
# Permission is granted to use, distribute, or modify this source,
|
||||
# provided that this copyright notice remains intact.
|
||||
#
|
||||
# Arbitrary precision calculator.
|
||||
Dear calc user,
|
||||
|
||||
I am allowing this calculator to be freely distributed for personal uses.
|
||||
Like all multi-precision programs, you should not depend absolutely on
|
||||
its results, since bugs in such programs can be insidious and only rarely
|
||||
show up.
|
||||
See the HOWTO.INSTALL file for information on how to build and install calc.
|
||||
|
||||
-dbell-
|
||||
To be sure that your version of calc is up to date, check out:
|
||||
|
||||
p.s. By Landon Curt Noll:
|
||||
http://reality.sgi.com/chongo/tech/comp/calc/calc-download.html
|
||||
|
||||
Building calc in 3 easy steps:
|
||||
We are interested in any/all feedback on recent versions of calc.
|
||||
In particular we would like to hear about:
|
||||
|
||||
1) Look at the makefile, and adjust it to suit your needs.
|
||||
* compiler warnings
|
||||
* compile problems
|
||||
* regression test problems (try: make check)
|
||||
* special compile flags/options that you needed
|
||||
* Makefile problems
|
||||
* help file problems
|
||||
* misc nits and typos
|
||||
|
||||
Here are some Makefile hints:
|
||||
We would like to offer a clean compile across a wide verity of platforms,
|
||||
so if you can test on several, so much the better!
|
||||
|
||||
In the past, some people have had to adjust the VARARG or
|
||||
TERMCONTROL because the Makefile cannot always guess
|
||||
correctly for certain systems. You may need to play with
|
||||
these values if you experience problems.
|
||||
|
||||
The default compiler used is 'cc'. The default compiler flag
|
||||
is '-O'. If you have gcc, or gcc v2 (or better) you should use
|
||||
that instead. Some compilers allow for optimization beyond
|
||||
just -O (gcc v2 has -O2, mips cc has -O3). You should select
|
||||
the best flag for speed optimization. Calc can be cpu intensive
|
||||
so selecting a quality compiler and good optimization level can
|
||||
really pay off.
|
||||
|
||||
2) build calc:
|
||||
|
||||
make all
|
||||
|
||||
3) test calc:
|
||||
|
||||
make check
|
||||
|
||||
==>>>If you run into problems, follow the instructions in the BUGS file<<<==
|
||||
If you run into problems, see the BUGS file.
|
||||
|
||||
=-=
|
||||
|
||||
For further reading:
|
||||
Calc is distributed with an extensive collection of help files that
|
||||
are accessible from the command line. The following assume that you
|
||||
are running calc from the distribution directory or that you have
|
||||
installed calc. In these examples, the ">" is the calc prompt, not
|
||||
something that you type in.
|
||||
|
||||
LIBRARY
|
||||
explains how programs can use libcalc.a to take advantage
|
||||
of the calc multi-precision routines.
|
||||
For list of help topics:
|
||||
|
||||
> help
|
||||
|
||||
For overview of calc overview:
|
||||
|
||||
> help intro
|
||||
> help overview
|
||||
> help command
|
||||
> help define
|
||||
> help statement
|
||||
> help variable
|
||||
|
||||
For list of builtin functions:
|
||||
|
||||
> help builtin
|
||||
|
||||
C programmers should note some unexpected differences in the calc syntax:
|
||||
|
||||
> help unexpected
|
||||
|
||||
Calc is shipped with a library of calc scripts. For a list see:
|
||||
|
||||
> help stdlib
|
||||
|
||||
=-=
|
||||
|
||||
See the file:
|
||||
|
||||
help/todo
|
||||
current wish list for calc
|
||||
help/wishlist
|
||||
|
||||
CHANGES
|
||||
recent changes to calc
|
||||
or run:
|
||||
|
||||
BUGS
|
||||
known bugs, mis-features and how to report problems
|
||||
calc help todo
|
||||
calc help wishlist
|
||||
|
||||
help/full
|
||||
full set of calc documentation
|
||||
for a wish/todo list. Code contributions are welcome.
|
||||
|
||||
=-=
|
||||
|
||||
David I. Bell dbell@auug.org.au
|
||||
chongo@toad.com <Landon Curt Noll -- chongo@toad.com> /\../\
|
||||
To join the calc-tester mailing list. Send a request to:
|
||||
|
||||
calc-tester-request@postofc.corp.sgi.com
|
||||
|
||||
Your message body (not the subject) should consist of:
|
||||
|
||||
subscribe calc-tester address
|
||||
end
|
||||
name your_full_name
|
||||
|
||||
where ``address'' is your EMail address and ``your_full_name'' is
|
||||
your full name.
|
||||
|
||||
The calc web site is located at:
|
||||
|
||||
http://reality.sgi.com/chongo/tech/comp/calc
|
||||
|
52
README.FIRST
52
README.FIRST
@@ -1,52 +0,0 @@
|
||||
Dear alpha tester,
|
||||
|
||||
Thanks for taking the time to try out this alpha version of calc! We are
|
||||
interested in any/all feedback that you may have on this version. In
|
||||
particular we would like to hear about:
|
||||
|
||||
* compile problems
|
||||
* regression test problems (try: make check)
|
||||
* compiler warnings
|
||||
* special compile flags/options that you needed
|
||||
* Makefile problems
|
||||
* help file problems
|
||||
* misc nits and typos
|
||||
|
||||
We would like to offer a clean compile across a wide verity of platforms,
|
||||
so if you can test on several, so much the better!
|
||||
|
||||
Calc distributions may be obtained from:
|
||||
|
||||
ftp://ftp.uu.net/pub/calc
|
||||
|
||||
If you don't have ftp access to that site, or if you do not find a more
|
||||
recent version (you may have a special pre-released version that is
|
||||
more advanced than what is in the ftp archive) send EMail to:
|
||||
|
||||
chongo@toad.com
|
||||
|
||||
Indicate the version you have and that you would like a more up
|
||||
to date version.
|
||||
|
||||
=-=
|
||||
|
||||
Misc items TODO before Beta release:
|
||||
|
||||
* improve the coverage in the 'SEE ALSO' help file lists
|
||||
|
||||
* where reasonable, be sure that regress.cal tests builtin functions
|
||||
|
||||
* add the Blum-Blum-Shub random() generator code
|
||||
|
||||
* add code to allow of the reading, writing and processing of binary data
|
||||
|
||||
* add shs, shs-1 and md5 hashing functions. Use align32.h.
|
||||
|
||||
* add mod h*2^n+/-1 function for integers
|
||||
|
||||
* be sure that CHANGES is up to date,
|
||||
look over the help/todo file and update as needed,
|
||||
revisit issues in the BUGS file and
|
||||
change this file :-)
|
||||
|
||||
* clean the source code and document it better
|
374
addop.c
374
addop.c
@@ -1,11 +1,12 @@
|
||||
/*
|
||||
* Copyright (c) 1995 David I. Bell
|
||||
* Copyright (c) 1997 David I. Bell
|
||||
* Permission is granted to use, distribute, or modify this source,
|
||||
* provided that this copyright notice remains intact.
|
||||
*
|
||||
* Add opcodes to a function being compiled.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "calc.h"
|
||||
#include "opcodes.h"
|
||||
#include "string.h"
|
||||
@@ -22,6 +23,7 @@
|
||||
static long maxopcodes; /* number of opcodes available */
|
||||
static long newindex; /* index of new function */
|
||||
static long oldop; /* previous opcode */
|
||||
static long oldoldop; /* opcode before previous opcode */
|
||||
static long debugline; /* line number of latest debug opcode */
|
||||
static long funccount; /* number of functions */
|
||||
static long funcavail; /* available number of functions */
|
||||
@@ -61,20 +63,25 @@ showfunctions(void)
|
||||
{
|
||||
FUNC **fpp; /* pointer into function table */
|
||||
FUNC *fp; /* current function */
|
||||
long count;
|
||||
|
||||
if (funccount == 0) {
|
||||
printf("No user functions defined.\n");
|
||||
return;
|
||||
count = 0;
|
||||
if (funccount > 0) {
|
||||
for (fpp = &functions[funccount - 1]; fpp >= functions; fpp--) {
|
||||
fp = *fpp;
|
||||
if (fp == NULL)
|
||||
continue;
|
||||
if (count++ == 0) {
|
||||
printf("Name Arguments\n---- ---------\n");
|
||||
}
|
||||
printf("%-12s %-2d\n", fp->f_name, fp->f_paramcount);
|
||||
}
|
||||
}
|
||||
printf("Name Arguments\n");
|
||||
printf("---- ---------\n");
|
||||
for (fpp = &functions[funccount - 1]; fpp >= functions; fpp--) {
|
||||
fp = *fpp;
|
||||
if (fp == NULL)
|
||||
continue;
|
||||
printf("%-12s %-2d\n", fp->f_name, fp->f_paramcount);
|
||||
if (count > 0) {
|
||||
printf("\nNumber: %ld\n", count);
|
||||
} else {
|
||||
printf("No user functions defined\n");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -112,6 +119,7 @@ beginfunc(char *name, BOOL newflag)
|
||||
initlocals();
|
||||
initlabels();
|
||||
oldop = OP_NOP;
|
||||
oldoldop = OP_NOP;
|
||||
debugline = 0;
|
||||
errorcount = 0;
|
||||
}
|
||||
@@ -127,9 +135,15 @@ endfunc(void)
|
||||
{
|
||||
register FUNC *fp; /* function just finished */
|
||||
unsigned long size; /* size of just created function */
|
||||
long index;
|
||||
|
||||
if (oldop != OP_RETURN) {
|
||||
addop(OP_UNDEF);
|
||||
addop(OP_RETURN);
|
||||
}
|
||||
checklabels();
|
||||
if (errorcount) {
|
||||
freefunc(curfunc);
|
||||
printf("\"%s\": %ld error%s\n", curfunc->f_name, errorcount,
|
||||
((errorcount == 1) ? "" : "s"));
|
||||
return;
|
||||
@@ -150,14 +164,25 @@ endfunc(void)
|
||||
size += dumpop(&fp->f_opcodes[size]);
|
||||
}
|
||||
}
|
||||
if ((inputisterminal() && conf->lib_debug & 1) ||
|
||||
(!inputisterminal() && conf->lib_debug & 2)) {
|
||||
printf("%s(", fp->f_name);
|
||||
for (index = 0; index < fp->f_paramcount; index++) {
|
||||
if (index)
|
||||
putchar(',');
|
||||
printf("%s", paramname(index));
|
||||
}
|
||||
printf(") ");
|
||||
if (functions[newindex])
|
||||
printf("re");
|
||||
printf("defined\n");
|
||||
}
|
||||
if (functions[newindex]) {
|
||||
freenumbers(functions[newindex]);
|
||||
free(functions[newindex]);
|
||||
fprintf(stderr, "**** %s() has been redefined\n", fp->f_name);
|
||||
}
|
||||
functions[newindex] = fp;
|
||||
objuncache();
|
||||
if (inputisterminal())
|
||||
printf("\"%s\" defined\n", fp->f_name);
|
||||
}
|
||||
|
||||
|
||||
@@ -195,6 +220,84 @@ adduserfunc(char *name)
|
||||
return index;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove user defined function
|
||||
*/
|
||||
void
|
||||
rmuserfunc(char *name)
|
||||
{
|
||||
long index; /* index of function */
|
||||
|
||||
index = findstr(&funcnames, name);
|
||||
if (index < 0) {
|
||||
printf("%s() has never been defined\n",
|
||||
name);
|
||||
return;
|
||||
}
|
||||
if (functions[index] == NULL)
|
||||
return;
|
||||
freenumbers(functions[index]);
|
||||
free(functions[index]);
|
||||
if ((inputisterminal() && conf->lib_debug & 1) ||
|
||||
(!inputisterminal() && conf->lib_debug & 2))
|
||||
printf("%s() undefined\n", name);
|
||||
functions[index] = NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Free memory used to store function and its constants
|
||||
*/
|
||||
void
|
||||
freefunc(FUNC *fp)
|
||||
{
|
||||
long i;
|
||||
|
||||
if (fp == NULL)
|
||||
return;
|
||||
if (conf->traceflags & TRACE_FNCODES) {
|
||||
printf("Freeing function \"%s\"\n", fp->f_name);
|
||||
dumpnames = FALSE;
|
||||
for (i = 0; i < fp->f_opcodecount; ) {
|
||||
printf("%ld: ", i);
|
||||
i += dumpop(&fp->f_opcodes[i]);
|
||||
}
|
||||
}
|
||||
freenumbers(fp);
|
||||
if (fp != functemplate)
|
||||
free(fp);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
rmalluserfunc(void)
|
||||
{
|
||||
FUNC **fpp;
|
||||
|
||||
for (fpp = functions; fpp < &functions[funccount]; fpp++) {
|
||||
if (*fpp) {
|
||||
freefunc(*fpp);
|
||||
*fpp = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* get index of defined user function with specified name, or -1 if there
|
||||
* is none or if it has been undefined
|
||||
*/
|
||||
long
|
||||
getuserfunc(char *name)
|
||||
{
|
||||
long index;
|
||||
|
||||
index = findstr(&funcnames, name);
|
||||
if (index >= 0 && functions[index] != NULL)
|
||||
return index;
|
||||
return -1L;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Clear any optimization that may be done for the next opcode.
|
||||
@@ -204,6 +307,7 @@ void
|
||||
clearopt(void)
|
||||
{
|
||||
oldop = OP_NOP;
|
||||
oldoldop = OP_NOP;
|
||||
debugline = 0;
|
||||
}
|
||||
|
||||
@@ -253,10 +357,17 @@ void
|
||||
addop(long op)
|
||||
{
|
||||
register FUNC *fp; /* current function */
|
||||
NUMBER *q;
|
||||
NUMBER *q, *q1, *q2;
|
||||
unsigned long count;
|
||||
BOOL cut;
|
||||
int diff;
|
||||
|
||||
fp = curfunc;
|
||||
if ((fp->f_opcodecount + 5) >= maxopcodes) {
|
||||
count = fp->f_opcodecount;
|
||||
cut = TRUE;
|
||||
diff = 2;
|
||||
q = NULL;
|
||||
if ((count + 5) >= maxopcodes) {
|
||||
maxopcodes += OPCODEALLOCSIZE;
|
||||
fp = (FUNC *) malloc(funcsize(maxopcodes));
|
||||
if (fp == NULL) {
|
||||
@@ -269,73 +380,174 @@ addop(long op)
|
||||
free(curfunc);
|
||||
curfunc = fp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the current opcode against the previous opcode and try to
|
||||
* slightly optimize the code depending on the various combinations.
|
||||
*/
|
||||
if (op == OP_GETVALUE) {
|
||||
switch (oldop) {
|
||||
switch (op) {
|
||||
case OP_GETVALUE:
|
||||
switch (oldop) {
|
||||
case OP_NUMBER:
|
||||
case OP_ZERO:
|
||||
case OP_ONE:
|
||||
case OP_IMAGINARY:
|
||||
case OP_GETEPSILON:
|
||||
case OP_SETEPSILON:
|
||||
case OP_STRING:
|
||||
case OP_UNDEF:
|
||||
case OP_GETCONFIG:
|
||||
case OP_SETCONFIG:
|
||||
return;
|
||||
case OP_DUPLICATE:
|
||||
diff = 1;
|
||||
oldop = OP_DUPVALUE;
|
||||
break;
|
||||
case OP_FIADDR:
|
||||
diff = 1;
|
||||
oldop = OP_FIVALUE;
|
||||
break;
|
||||
case OP_GLOBALADDR:
|
||||
diff = 1 + PTR_SIZE;
|
||||
oldop = OP_GLOBALVALUE;
|
||||
break;
|
||||
case OP_LOCALADDR:
|
||||
oldop = OP_LOCALVALUE;
|
||||
break;
|
||||
case OP_PARAMADDR:
|
||||
oldop = OP_PARAMVALUE;
|
||||
break;
|
||||
case OP_ELEMADDR:
|
||||
oldop = OP_ELEMVALUE;
|
||||
break;
|
||||
default:
|
||||
cut = FALSE;
|
||||
|
||||
case OP_NUMBER: case OP_ZERO: case OP_ONE: case OP_IMAGINARY:
|
||||
case OP_GETEPSILON: case OP_SETEPSILON: case OP_STRING:
|
||||
case OP_UNDEF: case OP_GETCONFIG: case OP_SETCONFIG:
|
||||
return;
|
||||
case OP_DUPLICATE:
|
||||
fp->f_opcodes[fp->f_opcodecount - 1] = OP_DUPVALUE;
|
||||
oldop = OP_DUPVALUE;
|
||||
return;
|
||||
case OP_FIADDR:
|
||||
fp->f_opcodes[fp->f_opcodecount - 1] = OP_FIVALUE;
|
||||
oldop = OP_FIVALUE;
|
||||
return;
|
||||
case OP_GLOBALADDR:
|
||||
fp->f_opcodes[fp->f_opcodecount - 2] = OP_GLOBALVALUE;
|
||||
oldop = OP_GLOBALVALUE;
|
||||
return;
|
||||
case OP_LOCALADDR:
|
||||
fp->f_opcodes[fp->f_opcodecount - 2] = OP_LOCALVALUE;
|
||||
oldop = OP_LOCALVALUE;
|
||||
return;
|
||||
case OP_PARAMADDR:
|
||||
fp->f_opcodes[fp->f_opcodecount - 2] = OP_PARAMVALUE;
|
||||
oldop = OP_PARAMVALUE;
|
||||
return;
|
||||
case OP_ELEMADDR:
|
||||
fp->f_opcodes[fp->f_opcodecount - 2] = OP_ELEMVALUE;
|
||||
oldop = OP_ELEMVALUE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (cut) {
|
||||
fp->f_opcodes[count - diff] = oldop;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case OP_POP:
|
||||
switch (oldop) {
|
||||
case OP_ASSIGN:
|
||||
fp->f_opcodes[count-1] = OP_ASSIGNPOP;
|
||||
oldop = OP_ASSIGNPOP;
|
||||
return;
|
||||
case OP_NUMBER:
|
||||
case OP_IMAGINARY:
|
||||
q = constvalue(fp->f_opcodes[count-1]);
|
||||
qfree(q);
|
||||
break;
|
||||
case OP_STRING:
|
||||
sfree(findstring((long)fp->f_opcodes[count-1]));
|
||||
break;
|
||||
case OP_LOCALADDR:
|
||||
case OP_PARAMADDR:
|
||||
break;
|
||||
case OP_GLOBALADDR:
|
||||
diff = 1 + PTR_SIZE;
|
||||
break;
|
||||
case OP_UNDEF:
|
||||
fp->f_opcodecount -= 1;
|
||||
oldop = OP_NOP;
|
||||
oldoldop = OP_NOP;
|
||||
return;
|
||||
default:
|
||||
cut = FALSE;
|
||||
}
|
||||
if (cut) {
|
||||
fp->f_opcodecount -= diff;
|
||||
oldop = OP_NOP;
|
||||
oldoldop = OP_NOP;
|
||||
fprintf(stderr, "%ld: unused value ignored\n",
|
||||
linenumber());
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case OP_NEGATE:
|
||||
if (oldop == OP_NUMBER) {
|
||||
q = constvalue(fp->f_opcodes[count-1]);
|
||||
fp->f_opcodes[count-1] = addqconstant(qneg(q));
|
||||
qfree(q);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ((op == OP_NEGATE) && (oldop == OP_NUMBER)) {
|
||||
q = constvalue(fp->f_opcodes[fp->f_opcodecount - 1]);
|
||||
fp->f_opcodes[fp->f_opcodecount - 1] = addqconstant(qneg(q));
|
||||
oldop = OP_NUMBER;
|
||||
return;
|
||||
}
|
||||
if ((op == OP_POWER) && (oldop == OP_NUMBER)) {
|
||||
if (qcmpi(constvalue(fp->f_opcodes[fp->f_opcodecount - 1]), 2L) == 0) {
|
||||
fp->f_opcodecount--;
|
||||
fp->f_opcodes[fp->f_opcodecount - 1] = OP_SQUARE;
|
||||
oldop = OP_SQUARE;
|
||||
return;
|
||||
if (oldop == OP_NUMBER) {
|
||||
if (oldoldop == OP_NUMBER) {
|
||||
q1 = constvalue(fp->f_opcodes[count - 3]);
|
||||
q2 = constvalue(fp->f_opcodes[count - 1]);
|
||||
switch (op) {
|
||||
case OP_DIV:
|
||||
if (qiszero(q2)) {
|
||||
cut = FALSE;
|
||||
break;
|
||||
}
|
||||
q = qqdiv(q1,q2);
|
||||
break;
|
||||
case OP_MUL:
|
||||
q = qmul(q1,q2);
|
||||
break;
|
||||
case OP_ADD:
|
||||
q = qqadd(q1,q2);
|
||||
break;
|
||||
case OP_SUB:
|
||||
q = qsub(q1,q2);
|
||||
break;
|
||||
case OP_POWER:
|
||||
if (qisfrac(q2) || qisneg(q2))
|
||||
cut = FALSE;
|
||||
else
|
||||
q = qpowi(q1,q2);
|
||||
break;
|
||||
default:
|
||||
cut = FALSE;
|
||||
}
|
||||
if (cut) {
|
||||
qfree(q1);
|
||||
qfree(q2);
|
||||
fp->f_opcodes[count - 3] = addqconstant(q);
|
||||
fp->f_opcodecount -= 2;
|
||||
oldoldop = OP_NOP;
|
||||
return;
|
||||
}
|
||||
} else if (op != OP_NUMBER) {
|
||||
q = constvalue(fp->f_opcodes[count - 1]);
|
||||
if (op == OP_POWER) {
|
||||
if (qcmpi(q, 2L) == 0) {
|
||||
fp->f_opcodecount--;
|
||||
fp->f_opcodes[count - 2] = OP_SQUARE;
|
||||
qfree(q);
|
||||
oldop = OP_SQUARE;
|
||||
return;
|
||||
}
|
||||
if (qcmpi(q, 4L) == 0) {
|
||||
fp->f_opcodes[count - 2] = OP_SQUARE;
|
||||
fp->f_opcodes[count - 1] = OP_SQUARE;
|
||||
qfree(q);
|
||||
oldop = OP_SQUARE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (qiszero(q)) {
|
||||
qfree(q);
|
||||
fp->f_opcodes[count - 2] = OP_ZERO;
|
||||
fp->f_opcodecount--;
|
||||
}
|
||||
else if (qisone(q)) {
|
||||
qfree(q);
|
||||
fp->f_opcodes[count - 2] = OP_ONE;
|
||||
fp->f_opcodecount--;
|
||||
}
|
||||
}
|
||||
if (qcmpi(constvalue(fp->f_opcodes[fp->f_opcodecount - 1]), 4L) == 0) {
|
||||
fp->f_opcodes[fp->f_opcodecount - 2] = OP_SQUARE;
|
||||
fp->f_opcodes[fp->f_opcodecount - 1] = OP_SQUARE;
|
||||
oldop = OP_SQUARE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ((op == OP_POP) && (oldop == OP_ASSIGN)) { /* optimize */
|
||||
fp->f_opcodes[fp->f_opcodecount - 1] = OP_ASSIGNPOP;
|
||||
oldop = OP_ASSIGNPOP;
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* No optimization possible, so store the opcode.
|
||||
*/
|
||||
fp->f_opcodes[fp->f_opcodecount] = op;
|
||||
fp->f_opcodecount++;
|
||||
oldoldop = oldop;
|
||||
oldop = op;
|
||||
}
|
||||
|
||||
@@ -347,24 +559,7 @@ addop(long op)
|
||||
void
|
||||
addopone(long op, long arg)
|
||||
{
|
||||
NUMBER *q;
|
||||
|
||||
switch (op) {
|
||||
case OP_NUMBER:
|
||||
q = constvalue(arg);
|
||||
if (q == NULL)
|
||||
break;
|
||||
if (qiszero(q)) {
|
||||
addop(OP_ZERO);
|
||||
return;
|
||||
}
|
||||
if (qisone(q)) {
|
||||
addop(OP_ONE);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_DEBUG:
|
||||
if (op == OP_DEBUG) {
|
||||
if ((conf->traceflags & TRACE_NODEBUG) || (arg == debugline))
|
||||
return;
|
||||
debugline = arg;
|
||||
@@ -372,7 +567,6 @@ addopone(long op, long arg)
|
||||
curfunc->f_opcodes[curfunc->f_opcodecount - 1] = arg;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
addop(op);
|
||||
curfunc->f_opcodes[curfunc->f_opcodecount] = arg;
|
||||
|
10
align32.c
10
align32.c
@@ -3,7 +3,10 @@
|
||||
*
|
||||
* This file was written by:
|
||||
*
|
||||
* Landon Curt Noll (chongo@toad.com) chongo <was here> /\../\
|
||||
* Landon Curt Noll
|
||||
* http://reality.sgi.com/chongo
|
||||
*
|
||||
* chongo <was here> /\../\
|
||||
*
|
||||
* This code has been placed in the public domain. Please do not
|
||||
* copyright this code.
|
||||
@@ -30,7 +33,7 @@
|
||||
static void buserr(void); /* catch alignment errors */
|
||||
|
||||
|
||||
MAIN
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
char byte[2*sizeof(USB32)]; /* mis-alignment buffer */
|
||||
@@ -58,7 +61,8 @@ main(void)
|
||||
'/', '/');
|
||||
|
||||
#endif
|
||||
exit(0);
|
||||
/* exit(0); */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
26
alloc.h
26
alloc.h
@@ -1,21 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 1995 David I. Bell
|
||||
* Copyright (c) 1997 David I. Bell
|
||||
* Permission is granted to use, distribute, or modify this source,
|
||||
* provided that this copyright notice remains intact.
|
||||
*/
|
||||
|
||||
|
||||
#if !defined(ALLOC_H)
|
||||
#define ALLOC_H
|
||||
#if !defined(__ALLOC_H__)
|
||||
#define __ALLOC_H__
|
||||
|
||||
|
||||
#include "have_malloc.h"
|
||||
#include "have_newstr.h"
|
||||
#include "have_string.h"
|
||||
#include "have_memmv.h"
|
||||
|
||||
#ifdef HAVE_MALLOC_H
|
||||
# include <malloc.h>
|
||||
#else
|
||||
# if defined(__STDC__) && __STDC__ != 0
|
||||
#if defined(FORCE_STDC) || (defined(__STDC__) && __STDC__ != 0) || defined(__cplusplus)
|
||||
extern void *malloc();
|
||||
extern void *realloc();
|
||||
extern void free();
|
||||
@@ -34,10 +36,10 @@
|
||||
# if defined(HAVE_NEWSTR)
|
||||
extern void *memcpy();
|
||||
extern void *memset();
|
||||
# if defined(__STDC__) && __STDC__ != 0
|
||||
#if defined(FORCE_STDC) || (defined(__STDC__) && __STDC__ != 0) || defined(__cplusplus)
|
||||
extern size_t strlen();
|
||||
# else
|
||||
extern long strlen(); /* should be size_t, but old systems don't have it */
|
||||
extern long strlen();
|
||||
# endif
|
||||
# else /* HAVE_NEWSTR */
|
||||
extern void bcopy();
|
||||
@@ -61,4 +63,14 @@ extern int strcmp();
|
||||
#define strchr(s, c) index(s, c)
|
||||
#endif /* HAVE_NEWSTR */
|
||||
|
||||
#endif /* !ALLOC_H */
|
||||
#if !defined(HAVE_MEMMOVE)
|
||||
# undef CALC_SIZE_T
|
||||
#if defined(FORCE_STDC) || (defined(__STDC__) && __STDC__ != 0) || defined(__cplusplus)
|
||||
# define CALC_SIZE_T size_t
|
||||
# else
|
||||
# define CALC_SIZE_T long
|
||||
# endif
|
||||
extern void *memmove(void *s1, const void *s2, CALC_SIZE_T n);
|
||||
#endif
|
||||
|
||||
#endif /* !__ALLOC_H__ */
|
||||
|
68
assocfunc.c
68
assocfunc.c
@@ -91,6 +91,7 @@ associndex(ASSOC *ap, BOOL create, long dim, VALUE *indices)
|
||||
ep->e_dim = dim;
|
||||
ep->e_hash = hash;
|
||||
ep->e_value.v_type = V_NULL;
|
||||
ep->e_value.v_subtype = V_NOSUBTYPE;
|
||||
for (i = 0; i < dim; i++)
|
||||
copyvalue(&indices[i], &ep->e_indices[i]);
|
||||
ep->e_next = *listhead;
|
||||
@@ -105,47 +106,62 @@ associndex(ASSOC *ap, BOOL create, long dim, VALUE *indices)
|
||||
|
||||
/*
|
||||
* Search an association for the specified value starting at the
|
||||
* specified index. Returns the element number (zero based) of the
|
||||
* found value, or -1 if the value was not found.
|
||||
* specified index. Returns 0 and stores index if value found,
|
||||
* otherwise returns 1.
|
||||
*/
|
||||
long
|
||||
assocsearch(ASSOC *ap, VALUE *vp, long index)
|
||||
int
|
||||
assocsearch(ASSOC *ap, VALUE *vp, long i, long j, ZVALUE *index)
|
||||
{
|
||||
ASSOCELEM *ep;
|
||||
|
||||
if (index < 0)
|
||||
index = 0;
|
||||
while (TRUE) {
|
||||
ep = elemindex(ap, index);
|
||||
if (ep == NULL)
|
||||
return -1;
|
||||
if (!comparevalue(&ep->e_value, vp))
|
||||
return index;
|
||||
index++;
|
||||
if (i < 0 || j > ap->a_count) {
|
||||
math_error("This should not happen in assocsearch");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
while (i < j) {
|
||||
ep = elemindex(ap, i);
|
||||
if (ep == NULL) {
|
||||
math_error("This should not happen in assocsearch");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
if (acceptvalue(&ep->e_value, vp)) {
|
||||
utoz(i, index);
|
||||
return 0;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Search an association backwards for the specified value starting at the
|
||||
* specified index. Returns the element number (zero based) of the
|
||||
* found value, or -1 if the value was not found.
|
||||
* specified index. Returns 0 and stores the index if the value is
|
||||
* found; otherwise returns 1.
|
||||
*/
|
||||
long
|
||||
assocrsearch(ASSOC *ap, VALUE *vp, long index)
|
||||
int
|
||||
assocrsearch(ASSOC *ap, VALUE *vp, long i, long j, ZVALUE *index)
|
||||
{
|
||||
ASSOCELEM *ep;
|
||||
|
||||
if (index >= ap->a_count)
|
||||
index = ap->a_count - 1;
|
||||
while (TRUE) {
|
||||
ep = elemindex(ap, index);
|
||||
if (ep == NULL)
|
||||
return -1;
|
||||
if (!comparevalue(&ep->e_value, vp))
|
||||
return index;
|
||||
index--;
|
||||
if (i < 0 || j > ap->a_count) {
|
||||
math_error("This should not happen in assocsearch");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
j--;
|
||||
while (j >= i) {
|
||||
ep = elemindex(ap, j);
|
||||
if (ep == NULL) {
|
||||
math_error("This should not happen in assocsearch");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
if (acceptvalue(&ep->e_value, vp)) {
|
||||
utoz(j, index);
|
||||
return 0;
|
||||
}
|
||||
j--;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
39
blkcpy.h
Normal file
39
blkcpy.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 1997 David I. Bell
|
||||
* Permission is granted to use, distribute, or modify this source,
|
||||
* provided that this copyright notice remains intact.
|
||||
*
|
||||
* Definitions of general values and related routines used by the calculator.
|
||||
*/
|
||||
|
||||
|
||||
#if !defined(__BLKCPY_H__)
|
||||
#define __BLKCPY_H__
|
||||
|
||||
/*
|
||||
* the main copy gateway function
|
||||
*/
|
||||
extern int copystod(VALUE *, long, long, VALUE *, long);
|
||||
|
||||
/*
|
||||
* specific copy functions
|
||||
*/
|
||||
extern int copyblk2blk(BLOCK *, long, long, BLOCK *, long, BOOL);
|
||||
extern int copyblk2file(BLOCK *, long, long, FILEID, long);
|
||||
extern int copyblk2mat(BLOCK *, long, long, MATRIX *, long);
|
||||
extern int copyblk2num(BLOCK *, long, long, NUMBER *, long, NUMBER **);
|
||||
extern int copyblk2str(BLOCK *, long, long, STRING *, long);
|
||||
extern int copyfile2blk(FILEID, long, long, BLOCK *, long, BOOL);
|
||||
extern int copylist2list(LIST *, long, long, LIST *, long);
|
||||
extern int copylist2mat(LIST *, long, long, MATRIX *, long);
|
||||
extern int copymat2blk(MATRIX *, long, long, BLOCK *, long, BOOL);
|
||||
extern int copymat2list(MATRIX *, long, long, LIST *, long);
|
||||
extern int copymat2mat(MATRIX *, long, long, MATRIX *, long);
|
||||
extern int copynum2blk(NUMBER *, long, long, BLOCK *, long, BOOL);
|
||||
extern int copyostr2blk(char *, long, long, BLOCK *, long, BOOL);
|
||||
extern int copyostr2str(char *, long, long, STRING *, long);
|
||||
extern int copystr2blk(STRING *, long, long, BLOCK *, long, BOOL);
|
||||
extern int copystr2file(STRING *, long, long, FILEID, long);
|
||||
extern int copystr2str(STRING *, long, long, STRING *, long);
|
||||
|
||||
#endif /* !__BLKCPY_H__ */
|
753
block.c
Normal file
753
block.c
Normal file
@@ -0,0 +1,753 @@
|
||||
/*
|
||||
* block - fixed, dynamic, fifo and circular memory blocks
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1997 by Landon Curt Noll. All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software and
|
||||
* its documentation for any purpose and without fee is hereby granted,
|
||||
* provided that the above copyright, this permission notice and text
|
||||
* this comment, and the disclaimer below appear in all of the following:
|
||||
*
|
||||
* supporting documentation
|
||||
* source copies
|
||||
* source works derived from this source
|
||||
* binaries derived from this source or from derived source
|
||||
*
|
||||
* LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
|
||||
* EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Comments, suggestions, bug fixes and questions about these routines
|
||||
* are welcome. Send EMail to the address given below.
|
||||
*
|
||||
* Happy bit twiddling,
|
||||
*
|
||||
* Landon Curt Noll
|
||||
* http://reality.sgi.com/chongo
|
||||
*
|
||||
* chongo <was here> /\../\
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include "value.h"
|
||||
#include "zmath.h"
|
||||
#include "config.h"
|
||||
#include "block.h"
|
||||
#include "nametype.h"
|
||||
#include "string.h"
|
||||
#include "calcerr.h"
|
||||
|
||||
#define NBLOCKCHUNK 16
|
||||
|
||||
static long nblockcount = 0;
|
||||
static long maxnblockcount = 0;
|
||||
static STRINGHEAD nblocknames;
|
||||
static NBLOCK **nblocks;
|
||||
|
||||
|
||||
/* forward declarations */
|
||||
static void blkchk(BLOCK*);
|
||||
|
||||
|
||||
/*
|
||||
* blkalloc - allocate a block
|
||||
*
|
||||
* given:
|
||||
* len - initial memory length of the block
|
||||
* type - BLK_TYPE_XXX
|
||||
* chunk - allocation chunk size
|
||||
*
|
||||
* returns:
|
||||
* pointer to a newly allocated BLOCK
|
||||
*/
|
||||
BLOCK *
|
||||
blkalloc(int len, int chunk)
|
||||
{
|
||||
BLOCK *nblk; /* new block allocated */
|
||||
|
||||
/*
|
||||
* firewall
|
||||
*/
|
||||
if (len < 0)
|
||||
len = 0;
|
||||
if (chunk <= 0)
|
||||
chunk = BLK_CHUNKSIZE;
|
||||
|
||||
/*
|
||||
* allocate BLOCK
|
||||
*/
|
||||
nblk = (BLOCK *)malloc(sizeof(BLOCK));
|
||||
if (nblk == NULL) {
|
||||
math_error("cannot allocate block");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
/*
|
||||
* initialize BLOCK
|
||||
*/
|
||||
nblk->blkchunk = chunk;
|
||||
nblk->maxsize = ((len+chunk)/chunk)*chunk;
|
||||
nblk->data = (USB8*)malloc(nblk->maxsize);
|
||||
if (nblk->data == NULL) {
|
||||
math_error("cannot allocate block data storage");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
memset(nblk->data, 0, nblk->maxsize);
|
||||
nblk->datalen = len;
|
||||
|
||||
/*
|
||||
* return BLOCK
|
||||
*/
|
||||
if (conf->calc_debug > 0) {
|
||||
blkchk(nblk);
|
||||
}
|
||||
return nblk;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* blk_free - free a block
|
||||
*
|
||||
* NOTE: THIS IS NOT THE CALC blktrunc() BUILTIN FUNCTION!! This
|
||||
* is what is called to free block storage.
|
||||
*
|
||||
* given:
|
||||
* blk - the block to free
|
||||
*/
|
||||
void
|
||||
blk_free(BLOCK *blk)
|
||||
{
|
||||
/* free if non-NULL */
|
||||
if (blk != NULL) {
|
||||
|
||||
/* free data storage */
|
||||
if (blk->data != NULL) {
|
||||
free(blk->data);
|
||||
}
|
||||
|
||||
/* free the block */
|
||||
free(blk);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* blkchk - check the sanity of a block
|
||||
*
|
||||
* These checks should never fail if calc is working correctly. During
|
||||
* debug time, we plan to call this function often. Once we are satisfied,
|
||||
* we will normally call this code only in a few places.
|
||||
*
|
||||
* This function is normally called whenever the following builtins are called:
|
||||
*
|
||||
* alloc(), realloc(), free()
|
||||
*
|
||||
* unless the "calc_debug" is set to -1. If "calc_debug" is > 0, then
|
||||
* most blk builtins will call this function.
|
||||
*
|
||||
* given:
|
||||
* blk - the BLOCK to check
|
||||
*
|
||||
* returns:
|
||||
* if all is ok, otherwise math_error() is called and this
|
||||
* function does not return
|
||||
*/
|
||||
static void
|
||||
blkchk(BLOCK *blk)
|
||||
{
|
||||
|
||||
/*
|
||||
* firewall - general sanity check
|
||||
*/
|
||||
if (conf->calc_debug == -1) {
|
||||
/* do nothing when debugging is disabled */
|
||||
return;
|
||||
}
|
||||
if (blk == NULL) {
|
||||
math_error("internal: blk ptr is NULL");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
/*
|
||||
* pointers must not be NULL
|
||||
*/
|
||||
if (blk->data == NULL) {
|
||||
math_error("internal: blk->data ptr is NULL");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
/*
|
||||
* check data lengths
|
||||
*/
|
||||
if (blk->datalen < 0) {
|
||||
math_error("internal: blk->datalen < 0");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
/*
|
||||
* check the datalen and datalen2 values
|
||||
*/
|
||||
if (blk->datalen < 0) {
|
||||
math_error("internal: blk->datalen < 0");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* blkrealloc - reallocate a block
|
||||
*
|
||||
* Reallocation of a block can change several aspects of a block.
|
||||
*
|
||||
* It can change the much data it holds or can hold.
|
||||
*
|
||||
* It can change the memory footprint (in terms of
|
||||
* how much storage is malloced for current or future use).
|
||||
*
|
||||
* It can change the chunk size used to grow malloced size
|
||||
* as the data size grows.
|
||||
*
|
||||
* Each of the len and chunksize may be kept the same.
|
||||
*
|
||||
* given:
|
||||
* blk - old BLOCK to reallocate
|
||||
* newlen - how much data the block holds
|
||||
* newchunk - allocation chunk size (<0 ==> no change, 0 == default)
|
||||
*/
|
||||
BLOCK *
|
||||
blkrealloc(BLOCK *blk, int newlen, int newchunk)
|
||||
{
|
||||
USB8 *nblk; /* realloced storage */
|
||||
int newmax; /* new maximum stoage size */
|
||||
|
||||
/*
|
||||
* firewall
|
||||
*/
|
||||
if (conf->calc_debug != -1) {
|
||||
blkchk(blk);
|
||||
}
|
||||
|
||||
/*
|
||||
* process args
|
||||
*/
|
||||
/* newlen < 0 means do not change the length */
|
||||
if (newlen < 0) {
|
||||
newlen = blk->datalen;
|
||||
}
|
||||
/* newchunk <= 0 means do not change the chunk size */
|
||||
if (newchunk < 0) {
|
||||
newchunk = blk->blkchunk;
|
||||
} else if (newchunk == 0) {
|
||||
newchunk = BLK_CHUNKSIZE;
|
||||
}
|
||||
|
||||
/*
|
||||
* reallocate storage if we have a different allocation size
|
||||
*/
|
||||
newmax = ((newlen+newchunk)/newchunk)*newchunk;
|
||||
if (newmax != blk->maxsize) {
|
||||
|
||||
/* reallocate new storage */
|
||||
nblk = (USB8*)realloc(blk->data, newmax);
|
||||
if (nblk == NULL) {
|
||||
math_error("cannot reallocate block storage");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
/* clear any new storage */
|
||||
if (newmax > blk->maxsize) {
|
||||
memset(nblk+blk->maxsize, 0, (newmax-blk->maxsize));
|
||||
}
|
||||
blk->maxsize = newmax;
|
||||
|
||||
/* restore the data pointers */
|
||||
blk->data = nblk;
|
||||
}
|
||||
|
||||
/*
|
||||
* deal the case of a newlen == 0 early and return
|
||||
*/
|
||||
if (newlen == 0) {
|
||||
|
||||
/*
|
||||
* setup the empty buffer
|
||||
*
|
||||
* We know that newtype is not circular since we force
|
||||
* newlen to be at least 1 (because circular blocks
|
||||
* always have at least one unused octet).
|
||||
*/
|
||||
if (blk->datalen < blk->maxsize) {
|
||||
memset(blk->data, 0, blk->datalen);
|
||||
} else {
|
||||
memset(blk->data, 0, blk->maxsize);
|
||||
}
|
||||
blk->datalen = 0;
|
||||
if (conf->calc_debug > 0) {
|
||||
blkchk(blk);
|
||||
}
|
||||
return blk;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the data length
|
||||
*
|
||||
* We also know that the new block is not empty since we have
|
||||
* already dealth with that case above.
|
||||
*
|
||||
* After this section of code, limit and datalen will be
|
||||
* correct in terms of the new type.
|
||||
*/
|
||||
if (newlen > blk->datalen) {
|
||||
|
||||
/* there is new storage, clear it */
|
||||
memset(blk->data + blk->datalen, 0, newlen-blk->datalen);
|
||||
/* growing storage for blocks grows the data */
|
||||
blk->datalen = newlen;
|
||||
|
||||
} else if (newlen <= blk->datalen) {
|
||||
|
||||
/* the block will be full */
|
||||
blk->datalen = newlen;
|
||||
}
|
||||
|
||||
/*
|
||||
* return realloced type
|
||||
*/
|
||||
if (conf->calc_debug > 0) {
|
||||
blkchk(blk);
|
||||
}
|
||||
return blk;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* blktrunc - truncate a BLOCK down to a minimal fixed block
|
||||
*
|
||||
* NOTE: THIS IS NOT THE INTERNAL CALC FREE FUNCTION!! This
|
||||
* is what blktrunc() builtin calls to reduce storage of a block
|
||||
* down to an absolute minimum.
|
||||
*
|
||||
* This actually forms a zero length fixed block with a chunk of 1.
|
||||
*
|
||||
* given:
|
||||
* blk - the BLOCK to shrink
|
||||
*
|
||||
* returns:
|
||||
* pointer to a newly allocated BLOCK
|
||||
*/
|
||||
void
|
||||
blktrunc(BLOCK *blk)
|
||||
{
|
||||
/*
|
||||
* firewall
|
||||
*/
|
||||
if (conf->calc_debug != -1) {
|
||||
blkchk(blk);
|
||||
}
|
||||
|
||||
/*
|
||||
* free the old storage
|
||||
*/
|
||||
free(blk->data);
|
||||
|
||||
/*
|
||||
* setup as a zero length fixed block
|
||||
*/
|
||||
blk->blkchunk = 1;
|
||||
blk->maxsize = 1;
|
||||
blk->datalen = 0;
|
||||
blk->data = (USB8*)malloc(1);
|
||||
if (blk->data == NULL) {
|
||||
math_error("cannot allocate truncated block storage");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
blk->data[0] = (USB8)0;
|
||||
if (conf->calc_debug > 0) {
|
||||
blkchk(blk);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* blk_copy - copy a block
|
||||
*
|
||||
* given:
|
||||
* blk - the block to copy
|
||||
*
|
||||
* returns:
|
||||
* pointer to copy of blk
|
||||
*/
|
||||
BLOCK *
|
||||
blk_copy(BLOCK *blk)
|
||||
{
|
||||
BLOCK *nblk; /* copy of blk */
|
||||
|
||||
/*
|
||||
* malloc new block
|
||||
*/
|
||||
nblk = (BLOCK *)malloc(sizeof(BLOCK));
|
||||
if (nblk == NULL) {
|
||||
math_error("blk_copy: cannot malloc BLOCK");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
/*
|
||||
* duplicate most of the block
|
||||
*/
|
||||
*nblk = *blk;
|
||||
|
||||
/*
|
||||
* duplicate block data
|
||||
*/
|
||||
nblk->data = (USB8 *)malloc(blk->maxsize);
|
||||
if (nblk->data == NULL) {
|
||||
math_error("blk_copy: cannot duplicate block data");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
memcpy(nblk->data, blk->data, blk->maxsize);
|
||||
return nblk;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* blk_cmp - compare blocks
|
||||
*
|
||||
* given:
|
||||
* a first BLOCK
|
||||
* b second BLOCK
|
||||
*
|
||||
* returns:
|
||||
* TRUE => BLOCKs are different
|
||||
* FALSE => BLOCKs are the same
|
||||
*/
|
||||
int
|
||||
blk_cmp(BLOCK *a, BLOCK *b)
|
||||
{
|
||||
/*
|
||||
* firewall and quick check
|
||||
*/
|
||||
if (a == b) {
|
||||
/* pointers to the same object */
|
||||
return FALSE;
|
||||
}
|
||||
if (a == NULL || b == NULL) {
|
||||
/* one pointer is NULL, so they differ */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* compare lengths
|
||||
*/
|
||||
if (a->datalen != b->datalen) {
|
||||
/* different lengths are different */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* compare the section
|
||||
*
|
||||
* We have the same lengths and types, so compare the data sections.
|
||||
*/
|
||||
if (memcmp(a->data, b->data, a->datalen) != 0) {
|
||||
/* different sections are different */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* the blocks are the same
|
||||
*/
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Print chunksize, maxsize, datalen on line line and if datalen > 0,
|
||||
* up to * 30 octets on the following line, with ... if datalen exceeds 30.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
blk_print(BLOCK *blk)
|
||||
{
|
||||
long i;
|
||||
BOOL havetail;
|
||||
USB8 *ptr;
|
||||
|
||||
/* XXX - use the config parameters for better print control */
|
||||
|
||||
printf("chunksize = %d, maxsize = %d, datalen = %d\n\t",
|
||||
(int)blk->blkchunk, (int)blk->maxsize, (int)blk->datalen);
|
||||
i = blk->datalen;
|
||||
havetail = (i > 30);
|
||||
if (havetail)
|
||||
i = 30;
|
||||
ptr = blk->data;
|
||||
while (i-- > 0)
|
||||
printf("%02x", *ptr++);
|
||||
if (havetail)
|
||||
printf("...");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Routine to print id and name of a named block and details of its
|
||||
* block component.
|
||||
*/
|
||||
void
|
||||
nblock_print(NBLOCK *nblk)
|
||||
{
|
||||
BLOCK *blk;
|
||||
|
||||
/* XXX - use the config parameters for better print control */
|
||||
|
||||
blk = nblk->blk;
|
||||
printf("block %d: %s\n\t", nblk->id, nblk->name);
|
||||
if (blk->data == NULL) {
|
||||
printf("chunksize = %d, maxsize = %d, datalen = %d\n\t",
|
||||
(int)blk->blkchunk, (int)blk->maxsize, (int)blk->datalen);
|
||||
printf("NULL");
|
||||
}
|
||||
else
|
||||
blk_print(blk);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* realloc a named block specified by its id. The new datalen and
|
||||
* chunksize are specified by len >= 0 and chunk > 0. If len < 0
|
||||
* or chunk <= 0, these values used are the current datalen and
|
||||
* chunksize, so there is no point in calling this unless len >= 0
|
||||
* and/or chunk > 0.
|
||||
* No reallocation occurs if the new maxsize is equal to the old maxsize.
|
||||
*/
|
||||
NBLOCK *
|
||||
reallocnblock(int id, int len, int chunk)
|
||||
{
|
||||
BLOCK *blk;
|
||||
int newsize;
|
||||
int oldsize;
|
||||
USB8* newdata;
|
||||
|
||||
/* Fire wall */
|
||||
if (id < 0 || id >= nblockcount) {
|
||||
math_error("Bad id in call to reallocnblock");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
blk = nblocks[id]->blk;
|
||||
if (len < 0)
|
||||
len = blk->datalen;
|
||||
if (chunk < 0)
|
||||
chunk = blk->blkchunk;
|
||||
else if (chunk == 0)
|
||||
chunk = BLK_CHUNKSIZE;
|
||||
newsize = (1 + len/chunk) * chunk;
|
||||
oldsize = blk->maxsize;
|
||||
newdata = blk->data;
|
||||
if (newdata == NULL) {
|
||||
newdata = malloc(newsize);
|
||||
if (newdata == NULL) {
|
||||
math_error("Allocation failed");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
}
|
||||
else if (newsize != oldsize) {
|
||||
newdata = realloc(blk->data, newsize);
|
||||
if (newdata == NULL) {
|
||||
math_error("Reallocation failed");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
}
|
||||
memset(newdata + len, 0, newsize - len);
|
||||
|
||||
blk->maxsize = newsize;
|
||||
blk->datalen = len;
|
||||
blk->blkchunk = chunk;
|
||||
blk->data = newdata;
|
||||
return nblocks[id];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Create and return a new namedblock with specified name, len and
|
||||
* chunksize.
|
||||
*/
|
||||
NBLOCK *
|
||||
createnblock(char *name, int len, int chunk)
|
||||
{
|
||||
NBLOCK *res;
|
||||
char *newname;
|
||||
|
||||
if (nblockcount >= maxnblockcount) {
|
||||
if (maxnblockcount <= 0) {
|
||||
maxnblockcount = NBLOCKCHUNK;
|
||||
nblocks = (NBLOCK **)malloc(NBLOCKCHUNK *
|
||||
sizeof(NBLOCK *));
|
||||
if (nblocks == NULL) {
|
||||
maxnblockcount = 0;
|
||||
math_error("unable to malloc new named blocks");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
} else {
|
||||
maxnblockcount += NBLOCKCHUNK;
|
||||
nblocks = (NBLOCK **)realloc(nblocks, maxnblockcount *
|
||||
sizeof(NBLOCK *));
|
||||
if (nblocks == NULL) {
|
||||
maxnblockcount = 0;
|
||||
math_error("cannot malloc more named blocks");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nblockcount == 0)
|
||||
initstr(&nblocknames);
|
||||
if (findstr(&nblocknames, name) >= 0) {
|
||||
math_error("Named block already exists!!!");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
newname = addstr(&nblocknames, name);
|
||||
if (newname == NULL) {
|
||||
math_error("Block name allocation failed");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
res = (NBLOCK *) malloc(sizeof(NBLOCK));
|
||||
if (res == NULL) {
|
||||
math_error("Named block allocation failed");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
nblocks[nblockcount] = res;
|
||||
res->name = newname;
|
||||
res->subtype = V_NOSUBTYPE;
|
||||
res->id = nblockcount++;
|
||||
res->blk = blkalloc(len, chunk);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* find a named block
|
||||
*/
|
||||
int
|
||||
findnblockid(char * name)
|
||||
{
|
||||
return findstr(&nblocknames, name);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* free data block for named block with specified id
|
||||
*/
|
||||
int
|
||||
removenblock(int id)
|
||||
{
|
||||
NBLOCK *nblk;
|
||||
|
||||
if (id < 0 || id >= nblockcount)
|
||||
return E_BLKFREE3;
|
||||
nblk = nblocks[id];
|
||||
if (nblk->blk->data == NULL)
|
||||
return 0;
|
||||
if (nblk->subtype & V_NOREALLOC)
|
||||
return E_BLKFREE5;
|
||||
free(nblk->blk->data);
|
||||
nblk->blk->data = NULL;
|
||||
nblk->blk->maxsize = 0;
|
||||
nblk->blk->datalen = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* count number of current unfreed named blocks
|
||||
*/
|
||||
int
|
||||
countnblocks(void)
|
||||
{
|
||||
int n;
|
||||
int id;
|
||||
|
||||
for (n = 0, id = 0; id < nblockcount; id++) {
|
||||
if (nblocks[id]->blk->data != NULL)
|
||||
n++;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* display id and name for each unfreed named block
|
||||
*/
|
||||
void
|
||||
shownblocks(void)
|
||||
{
|
||||
int id;
|
||||
|
||||
if (countnblocks() == 0) {
|
||||
printf("No unfreed named blocks\n\n");
|
||||
return;
|
||||
}
|
||||
printf(" id name\n");
|
||||
printf("---- -----\n");
|
||||
for (id = 0; id < nblockcount; id++) {
|
||||
if (nblocks[id]->blk->data != NULL)
|
||||
printf("%3d %s\n", id, nblocks[id]->name);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return pointer to nblock with specified id, NULL if never created.
|
||||
* The memory for the nblock found may have been freed.
|
||||
*/
|
||||
NBLOCK *
|
||||
findnblock(int id)
|
||||
{
|
||||
if (id < 0 || id >= nblockcount)
|
||||
return NULL;
|
||||
return nblocks[id];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Create a new block with specified newlen and new chunksize and copy
|
||||
* min(newlen, oldlen) octets to the new block. The old block is
|
||||
* not changed.
|
||||
*/
|
||||
BLOCK *
|
||||
copyrealloc(BLOCK *blk, int newlen, int newchunk)
|
||||
{
|
||||
BLOCK * newblk;
|
||||
int oldlen;
|
||||
|
||||
oldlen = blk->datalen;
|
||||
|
||||
if (newlen < 0) /* retain length */
|
||||
newlen = oldlen;
|
||||
|
||||
if (newchunk < 0) /* retain chunksize */
|
||||
newchunk = blk->blkchunk;
|
||||
else if (newchunk == 0) /* use default chunksize */
|
||||
newchunk = BLK_CHUNKSIZE;
|
||||
|
||||
|
||||
newblk = blkalloc(newlen, newchunk);
|
||||
|
||||
if (newlen < oldlen)
|
||||
oldlen = newlen;
|
||||
|
||||
if (newlen > 0)
|
||||
memcpy(newblk->data, blk->data, oldlen);
|
||||
|
||||
return newblk;
|
||||
}
|
228
block.h
Normal file
228
block.h
Normal file
@@ -0,0 +1,228 @@
|
||||
/*
|
||||
* block - fixed, dynamic, fifo and circular memory blocks
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1997 by Landon Curt Noll. All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software and
|
||||
* its documentation for any purpose and without fee is hereby granted,
|
||||
* provided that the above copyright, this permission notice and text
|
||||
* this comment, and the disclaimer below appear in all of the following:
|
||||
*
|
||||
* supporting documentation
|
||||
* source copies
|
||||
* source works derived from this source
|
||||
* binaries derived from this source or from derived source
|
||||
*
|
||||
* LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
|
||||
* EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Comments, suggestions, bug fixes and questions about these routines
|
||||
* are welcome. Send EMail to the address given below.
|
||||
*
|
||||
* Happy bit twiddling,
|
||||
*
|
||||
* Landon Curt Noll
|
||||
* http://reality.sgi.com/chongo
|
||||
*
|
||||
* chongo <was here> /\../\
|
||||
*/
|
||||
|
||||
|
||||
#if !defined(__BLOCK_H__)
|
||||
#define __BLOCK_H__
|
||||
|
||||
|
||||
/*
|
||||
* block - the basic block structure
|
||||
*
|
||||
* A block comes is one of several types. At the moment, only fixed
|
||||
* types are defined.
|
||||
*
|
||||
***
|
||||
*
|
||||
* Block functions and operations:
|
||||
*
|
||||
* x[i]
|
||||
* (i-1)th octet
|
||||
*
|
||||
* blk(len [, blkchunk])
|
||||
* unnamed block
|
||||
* len > 0
|
||||
* blkchunk defaults to BLK_CHUNKSIZE
|
||||
*
|
||||
* blk(name, [len [, blkchunk]])
|
||||
* named block
|
||||
* len > 0
|
||||
* blkchunk defaults to BLK_CHUNKSIZE
|
||||
*
|
||||
* blkfree(x)
|
||||
* Reduce storage down to 0 octetes.
|
||||
*
|
||||
* size(x)
|
||||
* The length of data stored in the block.
|
||||
*
|
||||
* sizeof(x) == blk->maxsize
|
||||
* Allocation size in memory
|
||||
*
|
||||
* isblk(x)
|
||||
* returns 0 is x is not a BLOCK, 1 if x is an
|
||||
* unnamed block, 2 if x is a named BLOCK
|
||||
*
|
||||
* blkread(x, size, count, fd [, offset])
|
||||
* blkwrite(x, size, count, fd [, offset])
|
||||
* returns number of items written
|
||||
* offset is restricted in value by block type
|
||||
*
|
||||
* blkset(x, val, length [, offset])
|
||||
* only the lower octet of val is used
|
||||
* offset is restricted in value by block type
|
||||
*
|
||||
* blkchr(x, val, length [, offset])
|
||||
* only the lower octet of val is used
|
||||
* offset is restricted in value by block type
|
||||
*
|
||||
* blkcpy(dest, src, length [, dest_offset [, src_offset]])
|
||||
* 0 <= length <= blksize(x)
|
||||
* offset's are restricted in value by block type
|
||||
* dest may not == src
|
||||
*
|
||||
* blkmove(dest, src, length [, dest_offset [, src_offset]])
|
||||
* 0 <= length <= blksize(x)
|
||||
* offset's are restricted in value by block type
|
||||
* overlapping moves are handeled correctly
|
||||
*
|
||||
* blkccpy(dest, src, stopval, length [, dest_offset [, src_offset]])
|
||||
* 0 <= length <= blksize(x)
|
||||
* offset's are restricted in value by block type
|
||||
*
|
||||
* blkcmp(dest, src, length [, dest_offset [, src_offset]])
|
||||
* 0 <= length <= blksize(x)
|
||||
* offset's are restricted in value by block type
|
||||
*
|
||||
* blkswap(x, a, b)
|
||||
* swaps groups of 'a' octets within each 'b' octets
|
||||
* b == a is a noop
|
||||
* b = a*k for some integer k >= 1
|
||||
*
|
||||
* scatter(src, dest1, dest2 [, dest3 ] ...)
|
||||
* copy sucessive octets from src into dest1, dest2, ...
|
||||
* restarting with dest1 after end of list
|
||||
* stops at end of src
|
||||
*
|
||||
* gather(dest, src1, src2 [, src3 ] ...)
|
||||
* copy first octet from src1, src2, ...
|
||||
* copy next octet from src1, src2, ...
|
||||
* ...
|
||||
* copy last octet from src1, src2, ...
|
||||
* copy 0 when there is no more data from a given source
|
||||
*
|
||||
* blkseek(x, offset, {"in","out"})
|
||||
* some seeks may not be allowed by block type
|
||||
*
|
||||
* config("blkmaxprint", count)
|
||||
* number of octets of a block to print, 0 means all
|
||||
*
|
||||
* config("blkverbose", boolean)
|
||||
* TRUE => print all lines, FALSE => skip dup lines
|
||||
*
|
||||
* config("blkbase", "base")
|
||||
* output block base = { "hex", "octal", "char", "binary", "raw" }
|
||||
* binary is base 2, raw is just octet values
|
||||
*
|
||||
* config("blkfmt", "style")
|
||||
* style of output = {
|
||||
* "line", lines in blkbase with no spaces between octets
|
||||
* "string", as one long line with no spaces between octets
|
||||
* "od_style", position, spaces between octets
|
||||
* "hd_style"} position, spaces between octets, chars on end
|
||||
*/
|
||||
struct block {
|
||||
LEN blkchunk; /* allocation chunk size */
|
||||
LEN maxsize; /* octets actually malloced for this block */
|
||||
LEN datalen; /* octets of data held this block */
|
||||
USB8 *data; /* pointer to the 1st octet of the allocated data */
|
||||
};
|
||||
typedef struct block BLOCK;
|
||||
|
||||
|
||||
struct nblock {
|
||||
char *name;
|
||||
int subtype;
|
||||
int id;
|
||||
BLOCK *blk;
|
||||
};
|
||||
typedef struct nblock NBLOCK;
|
||||
|
||||
|
||||
/*
|
||||
* block debug
|
||||
*/
|
||||
extern int blk_debug; /* 0 => debug off */
|
||||
|
||||
|
||||
/*
|
||||
* block defaults
|
||||
*/
|
||||
#define BLK_CHUNKSIZE 256 /* default allocation chunk size for blocks */
|
||||
|
||||
#define BLK_DEF_MAXPRINT 256 /* default octets to print */
|
||||
|
||||
#define BLK_BASE_HEX 0 /* output octets in a block in hex */
|
||||
#define BLK_BASE_OCT 1 /* output octets in a block in octal */
|
||||
#define BLK_BASE_CHAR 2 /* output octets in a block in characters */
|
||||
#define BLK_BASE_BINARY 3 /* output octets in a block in base 2 chars */
|
||||
#define BLK_BASE_RAW 4 /* output octets in a block in raw binary */
|
||||
|
||||
#define BLK_FMT_HD_STYLE 0 /* output in base with chars on end of line */
|
||||
#define BLK_FMT_LINE 1 /* output is lines of up to 79 chars */
|
||||
#define BLK_FMT_STRING 2 /* output is one long string */
|
||||
#define BLK_FMT_OD_STYLE 3 /* output in base with chars */
|
||||
|
||||
|
||||
/*
|
||||
* block macros
|
||||
*/
|
||||
/* length of data stored in a block */
|
||||
#define blklen(blk) ((blk)->datalen)
|
||||
|
||||
/* block footpint in memory */
|
||||
#define blksizeof(blk) ((blk)->maxsize)
|
||||
|
||||
/* block allocation chunk size */
|
||||
#define blkchunk(blk) ((blk)->blkchunk)
|
||||
|
||||
|
||||
/*
|
||||
* OCTET - what the INDEXADDR produces from a blk[offset]
|
||||
*/
|
||||
typedef USB8 OCTET;
|
||||
|
||||
|
||||
/*
|
||||
* external functions
|
||||
*/
|
||||
extern BLOCK *blkalloc(int, int);
|
||||
extern void blk_free(BLOCK*);
|
||||
extern BLOCK *blkrealloc(BLOCK*, int, int);
|
||||
extern void blktrunc(BLOCK*);
|
||||
extern BLOCK *blk_copy(BLOCK*);
|
||||
extern int blk_cmp(BLOCK*, BLOCK*);
|
||||
extern void blk_print(BLOCK*);
|
||||
extern void nblock_print(NBLOCK *);
|
||||
extern NBLOCK *createnblock(char *, int, int);
|
||||
extern NBLOCK *reallocnblock(int, int, int);
|
||||
extern int removenblock(int);
|
||||
extern int findnblockid(char *);
|
||||
extern NBLOCK *findnblock(int);
|
||||
extern BLOCK *copyrealloc(BLOCK*, int, int);
|
||||
extern int countnblocks(void);
|
||||
extern void shownblocks(void);
|
||||
|
||||
|
||||
#endif /* !__BLOCK_H__ */
|
@@ -39,6 +39,7 @@
|
||||
HALF *
|
||||
swap_b8_in_HALFs(HALF *dest, HALF *src, LEN len)
|
||||
{
|
||||
HALF *ret;
|
||||
LEN i;
|
||||
|
||||
/*
|
||||
@@ -47,6 +48,7 @@ swap_b8_in_HALFs(HALF *dest, HALF *src, LEN len)
|
||||
if (dest == NULL) {
|
||||
dest = alloc(len);
|
||||
}
|
||||
ret = dest;
|
||||
|
||||
/*
|
||||
* swap the array
|
||||
@@ -58,7 +60,7 @@ swap_b8_in_HALFs(HALF *dest, HALF *src, LEN len)
|
||||
/*
|
||||
* return the result
|
||||
*/
|
||||
return dest;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -272,6 +274,7 @@ swap_b8_in_COMPLEX(COMPLEX *dest, COMPLEX *src, BOOL all)
|
||||
HALF *
|
||||
swap_b16_in_HALFs(HALF *dest, HALF *src, LEN len)
|
||||
{
|
||||
HALF *ret;
|
||||
LEN i;
|
||||
|
||||
/*
|
||||
@@ -280,6 +283,7 @@ swap_b16_in_HALFs(HALF *dest, HALF *src, LEN len)
|
||||
if (dest == NULL) {
|
||||
dest = alloc(len);
|
||||
}
|
||||
ret = dest;
|
||||
|
||||
/*
|
||||
* swap the array
|
||||
@@ -291,7 +295,7 @@ swap_b16_in_HALFs(HALF *dest, HALF *src, LEN len)
|
||||
/*
|
||||
* return the result
|
||||
*/
|
||||
return dest;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
11
byteswap.h
11
byteswap.h
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1995 by Landon Curt Noll. All Rights Reserved.
|
||||
* Copyright (c) 1997 by Landon Curt Noll. All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software and
|
||||
* its documentation for any purpose and without fee is hereby granted,
|
||||
@@ -20,8 +20,10 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if !defined(BYTESWAP_H)
|
||||
#define BYTESWAP_H
|
||||
|
||||
#if !defined(__BYTESWAP_H__)
|
||||
#define __BYTESWAP_H__
|
||||
|
||||
|
||||
#include "longbits.h"
|
||||
|
||||
@@ -163,4 +165,5 @@
|
||||
|
||||
#endif /* LONG_BITS == 64 */
|
||||
|
||||
#endif /* !BYTESWAP_H */
|
||||
|
||||
#endif /* !__BYTESWAP_H__ */
|
||||
|
571
calc.c
571
calc.c
@@ -1,14 +1,16 @@
|
||||
/*
|
||||
* Copyright (c) 1995 David I. Bell
|
||||
* Copyright (c) 1997 David I. Bell
|
||||
* Permission is granted to use, distribute, or modify this source,
|
||||
* provided that this copyright notice remains intact.
|
||||
*
|
||||
* Arbitrary precision calculator.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <pwd.h>
|
||||
#include <sys/types.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#define CALC_C
|
||||
#include "calc.h"
|
||||
@@ -19,6 +21,10 @@
|
||||
#include "token.h"
|
||||
#include "symbol.h"
|
||||
#include "have_uid_t.h"
|
||||
#include "have_const.h"
|
||||
#include "custom.h"
|
||||
#include "math_error.h"
|
||||
#include "args.h"
|
||||
|
||||
#include "have_unistd.h"
|
||||
#if defined(HAVE_UNISTD_H)
|
||||
@@ -31,143 +37,140 @@
|
||||
#endif
|
||||
|
||||
/*
|
||||
* in case we do not have certain .h files
|
||||
* static definitions and functions
|
||||
*/
|
||||
#if !defined(HAVE_STDLIB_H) && !defined(HAVE_UNISTD_H)
|
||||
#if !defined(HAVE_UID_T) && !defined(_UID_T)
|
||||
typedef unsigned short uid_t;
|
||||
#endif
|
||||
extern char *getenv();
|
||||
extern uid_t geteuid();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Common definitions
|
||||
*/
|
||||
int abortlevel; /* current level of aborts */
|
||||
BOOL inputwait; /* TRUE if in a terminal input wait */
|
||||
jmp_buf jmpbuf; /* for errors */
|
||||
int start_done = FALSE; /* TRUE => start up processing finished */
|
||||
|
||||
extern int isatty(int tty); /* TRUE if fd is a tty */
|
||||
|
||||
static int p_flag = FALSE; /* TRUE => pipe mode */
|
||||
static int q_flag = FALSE; /* TRUE => don't execute rc files */
|
||||
static int u_flag = FALSE; /* TRUE => unbuffer stdin and stdout */
|
||||
|
||||
/*
|
||||
* global permissions
|
||||
*/
|
||||
int allow_read = TRUE; /* FALSE => may not open any files for reading */
|
||||
int allow_write = TRUE; /* FALSE => may not open any files for writing */
|
||||
int allow_exec = TRUE; /* FALSE => may not execute any commands */
|
||||
|
||||
char *calcpath; /* $CALCPATH or default */
|
||||
char *calcrc; /* $CALCRC or default */
|
||||
char *calcbindings; /* $CALCBINDINGS or default */
|
||||
char *home; /* $HOME or default */
|
||||
static char *pager; /* $PAGER or default */
|
||||
char *shell; /* $SHELL or default */
|
||||
int stdin_tty = TRUE; /* TRUE if stdin is a tty */
|
||||
int post_init = FALSE; /* TRUE setjmp for math_error is readready */
|
||||
|
||||
/*
|
||||
* some help topics are symbols, so we alias them to nice filenames
|
||||
*/
|
||||
static struct help_alias {
|
||||
char *topic;
|
||||
char *filename;
|
||||
} halias[] = {
|
||||
{"=", "assign"},
|
||||
{"%", "mod"},
|
||||
{"//", "quo"},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
NUMBER *epsilon_default; /* default allowed error for float calcs */
|
||||
|
||||
static char *usage = "usage: %s [-c] [-C] [-d] [-e] [-h] [-i] [-m mode]\n"
|
||||
"\t[-n] [-p] [-q] [-u] [-v] [[--] calc_cmd ...]\n";
|
||||
static void intint(int arg); /* interrupt routine */
|
||||
static void initenv(void); /* initialize environment vars */
|
||||
|
||||
extern void file_init(void);
|
||||
extern void zio_init(void);
|
||||
|
||||
char cmdbuf[MAXCMD+1]; /* command line expression */
|
||||
|
||||
/*
|
||||
* Top level calculator routine.
|
||||
*/
|
||||
MAIN
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
static char *str; /* current option string or expression */
|
||||
int want_defhelp = 0; /* 1=> we only want the default help */
|
||||
int cmdlen; /* length of the command string */
|
||||
extern char *optarg; /* option argument */
|
||||
extern int optind; /* option index */
|
||||
int c; /* option */
|
||||
long i;
|
||||
char *p;
|
||||
|
||||
/*
|
||||
* parse args
|
||||
*/
|
||||
argc--;
|
||||
argv++;
|
||||
while ((argc > 0) && (**argv == '-')) {
|
||||
for (str = &argv[0][1]; *str; str++) switch (*str) {
|
||||
case 'h':
|
||||
want_defhelp = 1;
|
||||
break;
|
||||
case 'm':
|
||||
if (argv[0][2]) {
|
||||
p = &argv[0][2];
|
||||
} else if (argc > 1) {
|
||||
p = argv[1];
|
||||
argc--;
|
||||
argv++;
|
||||
} else {
|
||||
fprintf(stderr, "-m requires an arg\n");
|
||||
exit(1);
|
||||
}
|
||||
if (p[1] != '\0' || *p < '0' || *p > '7') {
|
||||
fprintf(stderr, "unknown -m arg\n");
|
||||
exit(1);
|
||||
}
|
||||
allow_read = (((*p-'0') & 04) > 0);
|
||||
allow_write = (((*p-'0') & 02) > 0);
|
||||
allow_exec = (((*p-'0') & 01) > 0);
|
||||
break;
|
||||
case 'p':
|
||||
p_flag = TRUE;
|
||||
break;
|
||||
case 'q':
|
||||
q_flag = TRUE;
|
||||
break;
|
||||
case 'u':
|
||||
u_flag = TRUE;
|
||||
break;
|
||||
case 'v':
|
||||
version(stdout);
|
||||
exit(0);
|
||||
default:
|
||||
fprintf(stderr, "Unknown option\n");
|
||||
program = argv[0];
|
||||
while ((c = getopt(argc, argv, "Cehim:npquvcd")) != -1) {
|
||||
switch (c) {
|
||||
case 'C':
|
||||
#if defined(CUSTOM)
|
||||
allow_custom = TRUE;
|
||||
break;
|
||||
#else /* CUSTOM */
|
||||
/*
|
||||
* we are too early in processing to call
|
||||
* libcalc_call_me_last() - nothing to cleanup
|
||||
*/
|
||||
fprintf(stderr,
|
||||
"%s: calc was built with custom functions "
|
||||
"disabled, -C usage is disallowed\n", program);
|
||||
exit(1);
|
||||
#endif /* CUSTOM */
|
||||
case 'e':
|
||||
no_env = TRUE;
|
||||
break;
|
||||
case 'h':
|
||||
want_defhelp = 1;
|
||||
break;
|
||||
case 'i':
|
||||
i_flag = TRUE;
|
||||
break;
|
||||
case 'm':
|
||||
if (optarg[1] == '\0' || *optarg<'0' || *optarg>'7') {
|
||||
/*
|
||||
* we are too early in processing to
|
||||
* call libcalc_call_me_last()
|
||||
* nothing to cleanup
|
||||
*/
|
||||
fprintf(stderr,
|
||||
"%s: unknown -m arg\n", program);
|
||||
exit(1);
|
||||
}
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
str = cmdbuf;
|
||||
*str = '\0';
|
||||
while (--argc >= 0) {
|
||||
i = (long)strlen(*argv);
|
||||
if (str+1+i+2 >= cmdbuf+MAXCMD) {
|
||||
fprintf(stderr, "command in arg list too long\n");
|
||||
}
|
||||
allow_read = (((*optarg-'0') & 04) > 0);
|
||||
allow_write = (((*optarg-'0') & 02) > 0);
|
||||
allow_exec = (((*optarg-'0') & 01) > 0);
|
||||
break;
|
||||
case 'n':
|
||||
new_std = TRUE;
|
||||
break;
|
||||
case 'p':
|
||||
p_flag = TRUE;
|
||||
break;
|
||||
case 'q':
|
||||
q_flag = TRUE;
|
||||
break;
|
||||
case 'u':
|
||||
u_flag = TRUE;
|
||||
break;
|
||||
case 'c':
|
||||
c_flag = TRUE;
|
||||
break;
|
||||
case 'd':
|
||||
d_flag = TRUE;
|
||||
break;
|
||||
case 'v':
|
||||
/*
|
||||
* we are too early in processing to call
|
||||
* libcalc_call_me_last() - nothing to cleanup
|
||||
*/
|
||||
printf("%s (version %s)\n", CALC_TITLE, version());
|
||||
exit(0);
|
||||
default:
|
||||
/*
|
||||
* we are too early in processing to call
|
||||
* libcalc_call_me_last() - nothing to cleanup
|
||||
*/
|
||||
fprintf(stderr, usage, program);
|
||||
exit(1);
|
||||
}
|
||||
*str++ = ' ';
|
||||
strcpy(str, *argv++);
|
||||
str += i;
|
||||
str[0] = '\n';
|
||||
str[1] = '\0';
|
||||
}
|
||||
str = cmdbuf;
|
||||
havecommands = (optind < argc);
|
||||
|
||||
/*
|
||||
* look at the length of any trailing command args
|
||||
*
|
||||
* We make room for the trailing '\0\n' as well as an extra guard byte.
|
||||
*/
|
||||
for (cmdlen=0, i=optind; i < argc; ++i) {
|
||||
/* argument + space separator */
|
||||
cmdlen += strlen(argv[i]) + 1;
|
||||
}
|
||||
if (i > MAXCMD) {
|
||||
/*
|
||||
* we are too early in processing to call
|
||||
* libcalc_call_me_last() - nothing to cleanup
|
||||
*/
|
||||
fprintf(stderr,
|
||||
"%s: command in arg list is too long\n", program);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* We will form a command the remaining args separated by spaces.
|
||||
*/
|
||||
cmdbuf[0] = '\0';
|
||||
if (optind < argc) {
|
||||
strcpy(cmdbuf, argv[optind]);
|
||||
cmdlen = strlen(argv[optind]);
|
||||
for (i=optind+1; i < argc; ++i) {
|
||||
cmdbuf[cmdlen++] = ' ';
|
||||
strcpy(cmdbuf+cmdlen, argv[i]);
|
||||
cmdlen += strlen(argv[i]);
|
||||
}
|
||||
cmdbuf[cmdlen++] = '\n';
|
||||
cmdbuf[cmdlen] = '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
* unbuffered mode
|
||||
@@ -181,64 +184,36 @@ main(int argc, char **argv)
|
||||
* initialize
|
||||
*/
|
||||
libcalc_call_me_first();
|
||||
hash_init();
|
||||
file_init();
|
||||
initenv();
|
||||
resetinput();
|
||||
stdin_tty = isatty(0); /* assume stdin is on fd 0 */
|
||||
if (want_defhelp) {
|
||||
givehelp(DEFAULTCALCHELP);
|
||||
libcalc_call_me_last();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* if allowed or needed, print version and setup bindings
|
||||
*/
|
||||
if (*str == '\0') {
|
||||
/*
|
||||
* check for pipe mode and/or non-tty stdin
|
||||
*/
|
||||
if (p_flag) {
|
||||
stdin_tty = FALSE; /* stdin not a tty in pipe mode */
|
||||
conf->tab_ok = FALSE; /* config("tab",0) if pipe mode */
|
||||
} else {
|
||||
stdin_tty = isatty(0); /* assume stdin is on fd 0 */
|
||||
}
|
||||
|
||||
/*
|
||||
* empty string arg is no string
|
||||
*/
|
||||
str = NULL;
|
||||
|
||||
/*
|
||||
* if tty, setup bindings
|
||||
*/
|
||||
if (stdin_tty) {
|
||||
version(stdout);
|
||||
if (!havecommands && stdin_tty) {
|
||||
if (!d_flag) {
|
||||
printf("%s (version %s)\n", CALC_TITLE, version());
|
||||
printf("[%s]\n\n",
|
||||
"Type \"exit\" to exit, or \"help\" for help.");
|
||||
}
|
||||
if (stdin_tty) {
|
||||
switch (hist_init(calcbindings)) {
|
||||
switch (hist_init(calcbindings)) {
|
||||
case HIST_NOFILE:
|
||||
fprintf(stderr,
|
||||
"Cannot open bindings file \"%s\", %s.\n",
|
||||
calcbindings, "fancy editing disabled");
|
||||
"%s: Cannot open bindings file \"%s\", "
|
||||
"fancy editing disabled.\n",
|
||||
program, calcbindings);
|
||||
break;
|
||||
|
||||
case HIST_NOTTY:
|
||||
fprintf(stderr,
|
||||
"Cannot set terminal modes, %s.\n",
|
||||
"fancy editing disabled");
|
||||
"%s: Cannot set terminal modes, "
|
||||
"fancy editing disabled\n", program);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
/*
|
||||
* process args, not stdin
|
||||
*/
|
||||
stdin_tty = FALSE; /* stdin not a tty in arg mode */
|
||||
conf->tab_ok = FALSE; /* config("tab",0) if pipe mode */
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -249,172 +224,106 @@ main(int argc, char **argv)
|
||||
/*
|
||||
* reset/initialize the computing environment
|
||||
*/
|
||||
post_init = TRUE; /* jmpbuf is ready for math_error() */
|
||||
inittokens();
|
||||
initglobals();
|
||||
initfunctions();
|
||||
initstack();
|
||||
resetinput();
|
||||
math_cleardiversions();
|
||||
math_setfp(stdout);
|
||||
math_setmode(MODE_INITIAL);
|
||||
math_setdigits((long)DISPLAY_DEFAULT);
|
||||
conf->maxprint = MAXPRINT_DEFAULT;
|
||||
if (post_init)
|
||||
initialize();
|
||||
post_init = TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* if arg mode or non-tty mode, just do the work and be gone
|
||||
*/
|
||||
if (str || !stdin_tty) {
|
||||
if (q_flag == FALSE && allow_read) {
|
||||
runrcfiles();
|
||||
q_flag = TRUE;
|
||||
}
|
||||
if (str)
|
||||
(void) openstring(str);
|
||||
else
|
||||
(void) openterminal();
|
||||
start_done = TRUE;
|
||||
/*
|
||||
* (re)establish the interrupt handler
|
||||
*/
|
||||
(void) signal(SIGINT, intint);
|
||||
|
||||
/*
|
||||
* execute calc code based on the run state
|
||||
*/
|
||||
if (run_state == RUN_BEGIN) {
|
||||
if (!q_flag && allow_read) {
|
||||
run_state = RUN_RCFILES;
|
||||
runrcfiles();
|
||||
}
|
||||
run_state = RUN_PRE_CMD_ARGS;
|
||||
}
|
||||
|
||||
while (run_state == RUN_RCFILES) {
|
||||
fprintf(stderr, "Error in rcfiles\n");
|
||||
if ((c_flag && !stoponerror) || stoponerror < 0) {
|
||||
getcommands(FALSE);
|
||||
exit(0);
|
||||
closeinput();
|
||||
if (inputisterminal())
|
||||
run_state = RUN_PRE_CMD_ARGS;
|
||||
} else {
|
||||
if ((havecommands && !i_flag) || !stdin_tty)
|
||||
run_state = RUN_EXIT_WITH_ERROR;
|
||||
else
|
||||
run_state = RUN_PRE_CMD_ARGS;
|
||||
}
|
||||
}
|
||||
start_done = TRUE;
|
||||
|
||||
/*
|
||||
* if in arg mode, we should not get here
|
||||
*/
|
||||
if (str)
|
||||
exit(1);
|
||||
|
||||
/*
|
||||
* process commands (from stdin, not the command line)
|
||||
*/
|
||||
abortlevel = 0;
|
||||
_math_abort_ = FALSE;
|
||||
inputwait = FALSE;
|
||||
(void) signal(SIGINT, intint);
|
||||
math_cleardiversions();
|
||||
math_setfp(stdout);
|
||||
resetscopes();
|
||||
resetinput();
|
||||
if (q_flag == FALSE && allow_read) {
|
||||
q_flag = TRUE;
|
||||
runrcfiles();
|
||||
if (run_state == RUN_PRE_CMD_ARGS) {
|
||||
if (havecommands) {
|
||||
run_state = RUN_CMD_ARGS;
|
||||
(void) openstring(cmdbuf, (long) strlen(cmdbuf));
|
||||
getcommands(FALSE);
|
||||
closeinput();
|
||||
}
|
||||
run_state = RUN_PRE_TOP_LEVEL;
|
||||
}
|
||||
|
||||
while (run_state == RUN_CMD_ARGS) {
|
||||
fprintf(stderr, "Error in commands\n");
|
||||
if ((c_flag && !stoponerror) || stoponerror < 0) {
|
||||
getcommands(FALSE);
|
||||
closeinput();
|
||||
if (inputlevel() == 0) {
|
||||
getcommands(FALSE);
|
||||
run_state = RUN_PRE_TOP_LEVEL;
|
||||
}
|
||||
} else {
|
||||
closeinput();
|
||||
if (!stdin_tty || !i_flag || p_flag)
|
||||
run_state = RUN_EXIT_WITH_ERROR;
|
||||
else
|
||||
run_state = RUN_PRE_TOP_LEVEL;
|
||||
}
|
||||
}
|
||||
|
||||
if (run_state == RUN_PRE_TOP_LEVEL) {
|
||||
if (stdin_tty && ((havecommands && !i_flag) || p_flag)) {
|
||||
run_state = RUN_EXIT;
|
||||
} else {
|
||||
if (stdin_tty) {
|
||||
reinitialize();
|
||||
} else {
|
||||
resetinput();
|
||||
openterminal();
|
||||
}
|
||||
run_state = RUN_TOP_LEVEL;
|
||||
getcommands(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
while (run_state == RUN_TOP_LEVEL) {
|
||||
if ((c_flag && !stoponerror) || stoponerror < 0) {
|
||||
getcommands(TRUE);
|
||||
if (!inputisterminal())
|
||||
closeinput();
|
||||
} else {
|
||||
if (stdin_tty) {
|
||||
reinitialize();
|
||||
getcommands(TRUE);
|
||||
} else {
|
||||
run_state = RUN_EXIT_WITH_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
(void) openterminal();
|
||||
getcommands(TRUE);
|
||||
|
||||
/*
|
||||
* all done
|
||||
*/
|
||||
exit(0);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* initenv - obtain $CALCPATH, $CALCRC, $CALCBINDINGS, $HOME, $PAGER
|
||||
* and $SHELL values
|
||||
*
|
||||
* If $CALCPATH, $CALCRC, $CALCBINDINGS, $PAGER or $SHELL do not exist,
|
||||
* use the default values. If $PAGER or $SHELL is an empty string, also
|
||||
* use a default value. If $HOME does not exist, or is empty, use the home
|
||||
* directory information from the password file.
|
||||
*/
|
||||
static void
|
||||
initenv(void)
|
||||
{
|
||||
struct passwd *ent; /* our password entry */
|
||||
|
||||
/* determine the $CALCPATH value */
|
||||
calcpath = getenv(CALCPATH);
|
||||
if (calcpath == NULL)
|
||||
calcpath = DEFAULTCALCPATH;
|
||||
|
||||
/* determine the $CALCRC value */
|
||||
calcrc = getenv(CALCRC);
|
||||
if (calcrc == NULL) {
|
||||
calcrc = DEFAULTCALCRC;
|
||||
}
|
||||
|
||||
/* determine the $CALCBINDINGS value */
|
||||
calcbindings = getenv(CALCBINDINGS);
|
||||
if (calcbindings == NULL) {
|
||||
calcbindings = DEFAULTCALCBINDINGS;
|
||||
}
|
||||
|
||||
/* determine the $HOME value */
|
||||
home = getenv(HOME);
|
||||
if (home == NULL || home[0] == '\0') {
|
||||
ent = (struct passwd *)getpwuid(geteuid());
|
||||
if (ent == NULL) {
|
||||
/* just assume . is home if all else fails */
|
||||
home = ".";
|
||||
}
|
||||
home = (char *)malloc(strlen(ent->pw_dir)+1);
|
||||
strcpy(home, ent->pw_dir);
|
||||
}
|
||||
|
||||
/* determine the $PAGER value */
|
||||
pager = getenv(PAGER);
|
||||
if (pager == NULL || *pager == '\0') {
|
||||
pager = DEFAULTCALCPAGER;
|
||||
}
|
||||
|
||||
/* determine the $SHELL value */
|
||||
shell = getenv(SHELL);
|
||||
if (shell == NULL)
|
||||
shell = DEFAULTSHELL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* givehelp - display a help file
|
||||
*
|
||||
* given:
|
||||
* type the type of help to give, NULL => index
|
||||
*/
|
||||
void
|
||||
givehelp(char *type)
|
||||
{
|
||||
struct help_alias *p; /* help alias being considered */
|
||||
char *helpcmd; /* what to execute to print help */
|
||||
|
||||
/*
|
||||
* check permissions to see if we are allowed to help
|
||||
*/
|
||||
if (!allow_exec || !allow_read) {
|
||||
fprintf(stderr,
|
||||
"sorry, help is only allowed with -m mode 5 or 7\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* catch the case where we just print the index */
|
||||
if (type == NULL) {
|
||||
type = DEFAULTCALCHELP; /* the help index file */
|
||||
}
|
||||
|
||||
/* alias the type of help, if needed */
|
||||
for (p=halias; p->topic; ++p) {
|
||||
if (strcmp(type, p->topic) == 0) {
|
||||
type = p->filename;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* form the help command name */
|
||||
helpcmd = (char *)malloc(
|
||||
sizeof("if [ ! -d \"")+sizeof(HELPDIR)+1+strlen(type)+
|
||||
sizeof("\" ];then ")+
|
||||
strlen(pager)+1+1+sizeof(HELPDIR)+1+strlen(type)+1+1+
|
||||
sizeof(";else echo no such help;fi"));
|
||||
sprintf(helpcmd,
|
||||
"if [ -r \"%s/%s\" ];then %s \"%s/%s\";else echo no such help;fi",
|
||||
HELPDIR, type, pager, HELPDIR, type);
|
||||
|
||||
/* execute the help command */
|
||||
system(helpcmd);
|
||||
free(helpcmd);
|
||||
libcalc_call_me_last();
|
||||
return (run_state == RUN_EXIT_WITH_ERROR ||
|
||||
run_state == RUN_UNKNOWN) ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -438,4 +347,36 @@ intint(int arg)
|
||||
printf("\n[Abort level %d]\n", abortlevel);
|
||||
}
|
||||
|
||||
/* END CODE */
|
||||
|
||||
/*
|
||||
* Routine called on any runtime error, to complain about it (with possible
|
||||
* arguments), and then longjump back to the top level command scanner.
|
||||
*/
|
||||
void
|
||||
math_error(char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char buf[MAXERROR+1];
|
||||
|
||||
if (funcname && (*funcname != '*'))
|
||||
fprintf(stderr, "\"%s\": ", funcname);
|
||||
if (funcline && ((funcname && (*funcname != '*')) ||
|
||||
!inputisterminal()))
|
||||
fprintf(stderr, "line %ld: ", funcline);
|
||||
va_start(ap, fmt);
|
||||
vsprintf(buf, fmt, ap);
|
||||
va_end(ap);
|
||||
fprintf(stderr, "%s\n", buf);
|
||||
funcname = NULL;
|
||||
if (post_init) {
|
||||
longjmp(jmpbuf, 1);
|
||||
} else {
|
||||
fprintf(stderr, "It is too early provide a command line prompt "
|
||||
"so we must simply exit. Sorry!\n");
|
||||
/*
|
||||
* don't call libcalc_call_me_last() -- we might loop
|
||||
* and besides ... this is an unusual internal error case
|
||||
*/
|
||||
exit(3);
|
||||
}
|
||||
}
|
||||
|
104
calc.h
104
calc.h
@@ -1,17 +1,17 @@
|
||||
/*
|
||||
* Copyright (c) 1995 David I. Bell
|
||||
* Copyright (c) 1997 David I. Bell
|
||||
* Permission is granted to use, distribute, or modify this source,
|
||||
* provided that this copyright notice remains intact.
|
||||
*
|
||||
* Definitions for calculator program.
|
||||
*/
|
||||
|
||||
#ifndef CALC_H
|
||||
#define CALC_H
|
||||
|
||||
#if !defined(__CALC_H__)
|
||||
#define __CALC_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
#include "value.h"
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#define DEFAULTCALCHELP "help" /* help file that -h prints */
|
||||
#define DEFAULTSHELL "sh" /* default shell to use */
|
||||
#define CALCEXT ".cal" /* extension for files read in */
|
||||
#define PATHSIZE 1024 /* maximum length of path name */
|
||||
#define MAX_CALCRC 1024 /* maximum length of $CALCRC */
|
||||
#define HOMECHAR '~' /* char which indicates home directory */
|
||||
#define DOTCHAR '.' /* char which indicates current directory */
|
||||
#define PATHCHAR '/' /* char which separates path components */
|
||||
@@ -38,7 +38,7 @@
|
||||
#define SYMBOLSIZE 256 /* maximum symbol name size */
|
||||
#define MAXINDICES 20 /* maximum number of indices for objects */
|
||||
#define MAXLABELS 100 /* maximum number of user labels in function */
|
||||
#define MAXOBJECTS 10 /* maximum number of object types */
|
||||
#define MAXOBJECTS 128 /* maximum number of object types */
|
||||
#define MAXSTRING 1024 /* maximum size of string constant */
|
||||
#define MAXSTACK 1000 /* maximum depth of evaluation stack */
|
||||
#define MAXFILES 20 /* maximum number of opened files */
|
||||
@@ -59,6 +59,8 @@
|
||||
#define ABORT_MATH 3 /* abort on any math operation */
|
||||
#define ABORT_NOW 4 /* abort right away */
|
||||
|
||||
#define ERRMAX 20 /* default errmax value */
|
||||
|
||||
/*
|
||||
* File ids corresponding to standard in, out, error, and when not in use.
|
||||
*/
|
||||
@@ -94,21 +96,24 @@ extern int flushall(void);
|
||||
extern int idfputstr(FILEID id, char *str);
|
||||
extern int rewindid(FILEID id);
|
||||
extern void rewindall(void);
|
||||
extern long filesize(FILEID id);
|
||||
extern ZVALUE zfilesize(FILEID id);
|
||||
extern void showfiles(void);
|
||||
extern int fscanfid(FILEID id, char *fmt, int count, VALUE **vals);
|
||||
extern int scanfstr(char *str, char *fmt, int count, VALUE **vals);
|
||||
extern long ftellid(FILEID id);
|
||||
extern long fseekid(FILEID id, long offset, int whence);
|
||||
extern int ftellid(FILEID id, ZVALUE *res);
|
||||
extern int fseekid(FILEID id, ZVALUE offset, int whence);
|
||||
extern int isattyid(FILEID id);
|
||||
long fsearch(FILEID id, char *str, long pos);
|
||||
long frsearch(FILEID id, char *str, long pos);
|
||||
extern int fsearch(FILEID id, char *str, ZVALUE start, ZVALUE end, ZVALUE *res);
|
||||
extern int frsearch(FILEID id, char *str, ZVALUE first, ZVALUE last, ZVALUE *res);
|
||||
extern void showconstants(void);
|
||||
extern void freeconstant(unsigned long);
|
||||
extern void freestringconstant(long);
|
||||
extern void trimconstants(void);
|
||||
|
||||
/*
|
||||
* Input routines.
|
||||
*/
|
||||
extern FILE *f_open(char *name, char *mode);
|
||||
extern int openstring(char *str);
|
||||
extern int openstring(char *str, long num);
|
||||
extern int openterminal(void);
|
||||
extern int opensearchfile(char *name, char *pathlist, char *exten, int reopen_ok);
|
||||
extern char *nextline(void);
|
||||
@@ -117,12 +122,11 @@ extern void reread(void);
|
||||
extern void resetinput(void);
|
||||
extern void setprompt(char *);
|
||||
extern BOOL inputisterminal(void);
|
||||
extern int inputlevel(void);
|
||||
extern char *inputname(void);
|
||||
extern long linenumber(void);
|
||||
extern void runrcfiles(void);
|
||||
extern void closeinput(void);
|
||||
extern FILE *curstream(void);
|
||||
|
||||
|
||||
/*
|
||||
* Other routines.
|
||||
@@ -131,21 +135,45 @@ extern NUMBER *constvalue(unsigned long index);
|
||||
extern long addnumber(char *str);
|
||||
extern long addqconstant(NUMBER *q);
|
||||
extern void initstack(void);
|
||||
extern void version(FILE *stream);
|
||||
extern void getcommands(BOOL toplevel);
|
||||
extern void givehelp(char *type);
|
||||
extern void hash_init(void);
|
||||
extern void libcalc_call_me_first(void);
|
||||
|
||||
extern void libcalc_call_me_last(void);
|
||||
extern void showerrors(void);
|
||||
|
||||
/*
|
||||
* Global data definitions.
|
||||
* Initialization
|
||||
*/
|
||||
extern void initialize(void);
|
||||
extern void reinitialize(void);
|
||||
extern int isatty(int tty); /* TRUE if fd is a tty */
|
||||
extern char *version(void); /* return version string */
|
||||
extern int post_init; /* TRUE => setjmp for math_error is ready */
|
||||
|
||||
/*
|
||||
* global flags and definitions
|
||||
*/
|
||||
extern int abortlevel; /* current level of aborts */
|
||||
extern BOOL inputwait; /* TRUE if in a terminal input wait */
|
||||
extern VALUE *stack; /* execution stack */
|
||||
extern jmp_buf jmpbuf; /* for errors */
|
||||
extern int start_done; /* TRUE => start up processing finished */
|
||||
|
||||
extern int p_flag; /* TRUE => pipe mode */
|
||||
extern int q_flag; /* TRUE => don't execute rc files */
|
||||
extern int u_flag; /* TRUE => unbuffer stdin and stdout */
|
||||
extern int d_flag; /* TRUE => disable heading, lib_debug == 0 */
|
||||
extern int c_flag; /* TRUE => continue after error if permitted */
|
||||
extern int i_flag; /* TRUE => try to go interactive after error */
|
||||
extern int stoponerror; /* >0 => stop, <0 => continue, ==0 => use -c */
|
||||
|
||||
extern char *pager; /* $PAGER or default */
|
||||
extern int stdin_tty; /* TRUE if stdin is a tty */
|
||||
extern int havecommands; /* TRUE if have cmd args) */
|
||||
extern char *program; /* our name */
|
||||
extern char cmdbuf[]; /* command line expression */
|
||||
|
||||
extern int abortlevel; /* current level of aborts */
|
||||
extern BOOL inputwait; /* TRUE if in a terminal input wait */
|
||||
extern VALUE *stack; /* execution stack */
|
||||
extern int dumpnames; /* TRUE => dump names rather than indices */
|
||||
|
||||
extern char *calcpath; /* $CALCPATH or default */
|
||||
@@ -153,13 +181,41 @@ extern char *calcrc; /* $CALCRC or default */
|
||||
extern char *calcbindings; /* $CALCBINDINGS or default */
|
||||
extern char *home; /* $HOME or default */
|
||||
extern char *shell; /* $SHELL or default */
|
||||
extern char *program; /* our name (argv[0]) */
|
||||
|
||||
extern int no_env; /* TRUE (-e) => ignore env vars on startup */
|
||||
extern int errmax; /* if >= 0, error when errcount exceeds errmax */
|
||||
extern int new_std; /* TRUE (-n) => use newstd configuration */
|
||||
|
||||
extern int allow_read; /* FALSE => may not open any files for reading */
|
||||
extern int allow_write; /* FALSE => may not open any files for writing */
|
||||
extern int allow_exec; /* FALSE => may not execute any commands */
|
||||
|
||||
extern int post_init; /* TRUE => setjmp for math_error is ready */
|
||||
/*
|
||||
* calc startup and run state
|
||||
*/
|
||||
typedef enum {
|
||||
RUN_UNKNOWN = -1, /* unknown or unset start state */
|
||||
RUN_BEGIN = 0, /* calc execution starts */
|
||||
RUN_RCFILES = 1, /* rc files being evaluated */
|
||||
RUN_PRE_CMD_ARGS = 2, /* prepare to evaluate cmd args */
|
||||
RUN_CMD_ARGS = 3, /* cmd args being evaluated */
|
||||
RUN_PRE_TOP_LEVEL = 4, /* prepare to start top level activity */
|
||||
RUN_TOP_LEVEL = 5, /* running at top level */
|
||||
RUN_EXIT = 6, /* normal exit from calc */
|
||||
RUN_EXIT_WITH_ERROR = 7 /* exit with error */
|
||||
} run;
|
||||
extern run run_state;
|
||||
|
||||
#endif
|
||||
/*
|
||||
* calc version information
|
||||
*/
|
||||
#define CALC_TITLE "C-style arbitrary precision calculator"
|
||||
extern int calc_major_ver;
|
||||
extern int calc_minor_ver;
|
||||
extern int calc_major_patch;
|
||||
extern char *calc_minor_patch;
|
||||
extern char *version(void); /* return version string */
|
||||
|
||||
/* END CODE */
|
||||
|
||||
#endif /* !__CALC_H__ */
|
||||
|
541
calc.man
541
calc.man
@@ -1,190 +1,356 @@
|
||||
.\"
|
||||
.\" Copyright (c) 1994 David I. Bell and Landon Curt Noll
|
||||
.\" Copyright (c) 1993 David I. Bell and Landon Curt Noll
|
||||
.\" Original man page dated 15nov93
|
||||
.\" Copyright (c) 1999 David I. Bell and Landon Curt Noll
|
||||
.\" Permission is granted to use, distribute, or modify this source,
|
||||
.\" provided that this copyright notice remains intact.
|
||||
.\"
|
||||
.\" calculator by David I. Bell
|
||||
.\" man page by Landon Noll
|
||||
.TH calc 1 "^..^" "15nov93"
|
||||
.TH calc 1 "^..^" "15Oct1999"
|
||||
.SH NAME
|
||||
calc \- arbitrary precision calculator
|
||||
.SH SYNOPSIS
|
||||
\fIcalc\fP
|
||||
[\fI\-h\fP]
|
||||
[\fI\-m mode\fP]
|
||||
[\fI\-p\fP]
|
||||
[\fI\-q\fP]
|
||||
[\fI\-u\fP]
|
||||
[\fI\-v\fP]
|
||||
[\fIcalc_cmd \&.\|.\|.\fp]
|
||||
.RB [ \-c ]
|
||||
.RB [ \-C ]
|
||||
.RB [ \-d ]
|
||||
.RB [ \-e ]
|
||||
.RB [ \-h ]
|
||||
.RB [ \-i ]
|
||||
.RB [ \-m\ \&mode ]
|
||||
.br
|
||||
.in +5n
|
||||
.RB [ \-n ]
|
||||
.RB [ \-p ]
|
||||
.RB [ \-q ]
|
||||
.RB [ \-u ]
|
||||
.RB [ \-v ]
|
||||
.RB [ calc_cmd\ \&.\|.\|. ]
|
||||
.in -5n
|
||||
.SH DESCRIPTION
|
||||
\&
|
||||
.br
|
||||
CALC COMMAND LINE
|
||||
.PP
|
||||
|
||||
.TP
|
||||
\fI\-h\fP
|
||||
Print a help message.
|
||||
This option implies \fI \-q\fP.
|
||||
This is equivalent to the calc command \fIhelp help\fP.
|
||||
The help facility is disabled unless the \fImode\fP is 5 or 7.
|
||||
See \fI\-m\fP below.
|
||||
.sp
|
||||
.TP
|
||||
\fI\-m mode\fP
|
||||
This flag sets the permission mode of calc.
|
||||
It controls the ability for \fIcalc\fP to open files
|
||||
and execute programs.
|
||||
\fIMode\fP may be a number from 0 to 7.
|
||||
.sp
|
||||
The \fImode\fP value is interpreted in a way similar
|
||||
to that of the \fRchmod(1)\fP octal mode:
|
||||
.sp
|
||||
.in +0.5i
|
||||
.B \-c
|
||||
Continue reading command lines even after an execution
|
||||
error has caused the abandonment of a line.
|
||||
.sp 1
|
||||
For example:
|
||||
.sp 1
|
||||
.in +5n
|
||||
.nf
|
||||
0 do not open any file, do not execute progs
|
||||
1 do not open any file
|
||||
2 do not open files for reading, do not execute progs
|
||||
3 do not open files for reading
|
||||
4 do not open files for writing, do not execute progs
|
||||
5 do not open files for writing
|
||||
6 do not execute any program
|
||||
7 allow everything (default mode)
|
||||
calc read many_errors.cal
|
||||
.fi
|
||||
.in -0.5i
|
||||
.sp
|
||||
If one wished to run calc from a privledged user, one might
|
||||
want to use \fI\-m 0\fP in an effort to make calc more secure.
|
||||
.sp
|
||||
\fIMode\fP bits for reading and writing apply only on an open.
|
||||
.in -5n
|
||||
.sp 1
|
||||
will cause
|
||||
.B calc
|
||||
to abort on the first error, whereas:
|
||||
.sp 1
|
||||
.in +5n
|
||||
.nf
|
||||
calc -c read many_errors.cal
|
||||
.fi
|
||||
.in -5n
|
||||
.sp 1
|
||||
will
|
||||
cause
|
||||
.B calc
|
||||
to try to process each line being read
|
||||
despite the errors that it encounters.
|
||||
|
||||
.TP
|
||||
.B \-C
|
||||
Permit the execution of custom builtin functions. Without
|
||||
this flag, calling the custom() builtin function will
|
||||
simply generate an error.
|
||||
.sp 1
|
||||
Use if this flag may cause
|
||||
.B calc
|
||||
to execute functions that
|
||||
are non-standard and that are not portable. Custom builtin
|
||||
functions are disabled by default for this reason.
|
||||
|
||||
.TP
|
||||
.B \-d
|
||||
Disable the printing of the opening title. The printing
|
||||
of library debug and informational messages is also disabled
|
||||
as if \fBconfig("lib_debug", 0)\fP had been executed.
|
||||
.sp 1
|
||||
For example:
|
||||
.sp 1
|
||||
.in +5n
|
||||
calc 'read qtime; qtime(2)'
|
||||
.in -5n
|
||||
.sp 1
|
||||
will output something like:
|
||||
.sp 1
|
||||
.in +5n
|
||||
.nf
|
||||
qtime(utc_hr_offset) defined
|
||||
It's nearly ten past six.
|
||||
.fi
|
||||
.in -5n
|
||||
.sp 1
|
||||
whereas:
|
||||
.sp 1
|
||||
.in +5n
|
||||
.nf
|
||||
calc -d 'read qtime; qtime(2)'
|
||||
.fi
|
||||
.in -5n
|
||||
.sp 1
|
||||
will just say:
|
||||
.sp 1
|
||||
.in +5n
|
||||
.nf
|
||||
It's nearly ten past six.
|
||||
.fi
|
||||
.in -5n
|
||||
.sp 1
|
||||
|
||||
.TP
|
||||
.B \-e
|
||||
Ignore any environment variables on startup.
|
||||
The getenv() builtin will still return values, however.
|
||||
|
||||
.TP
|
||||
.B \-h
|
||||
Print a help message. This option implies
|
||||
.BR \-q .
|
||||
This
|
||||
is equivalent to the
|
||||
.B calc
|
||||
command help help.
|
||||
The help facility is disabled unless the mode is 5 or 7.
|
||||
See
|
||||
.BR \-m .
|
||||
|
||||
.TP
|
||||
.B \-i
|
||||
Become interactive if possible.
|
||||
Be default, if
|
||||
.I calc_cmd
|
||||
args are given,
|
||||
.B calc
|
||||
will execute them and exit.
|
||||
This flag args are given,
|
||||
.B calc
|
||||
will execute them and exit.
|
||||
This flag will cause
|
||||
.B calc
|
||||
to drop into interactive mode after the
|
||||
commands are executed.
|
||||
.sp 1
|
||||
For example:
|
||||
.sp 1
|
||||
.in +5n
|
||||
.nf
|
||||
calc 2+5
|
||||
.fi
|
||||
.in -5n
|
||||
.sp 1
|
||||
will print the value 7 and exit whereas:
|
||||
.sp 1
|
||||
.in +5n
|
||||
.nf
|
||||
calc -i 2+5
|
||||
.fi
|
||||
.in -5n
|
||||
.sp 1
|
||||
will print the value 7 and prompt the user for more
|
||||
.B calc
|
||||
commands.
|
||||
|
||||
.TP
|
||||
.BR \-m " mode"
|
||||
This flag sets the permission mode of
|
||||
.BR calc .
|
||||
It controls the ability for
|
||||
.B calc
|
||||
to open files and execute programs.
|
||||
Mode may be a number from 0 to 7.
|
||||
.sp 1
|
||||
The mode value is interpreted in a way similar to that
|
||||
of the
|
||||
.BR chmod (1)
|
||||
octal mode:
|
||||
.sp 1
|
||||
.in +5n
|
||||
.nf
|
||||
0 do not open any file, do not execute progs
|
||||
1 do not open any file
|
||||
2 do not open files for reading, do not execute progs
|
||||
3 do not open files for reading
|
||||
4 do not open files for writing, do not execute progs
|
||||
5 do not open files for writing
|
||||
6 do not execute any program
|
||||
7 allow everything (default mode)
|
||||
.fi
|
||||
.in -5n
|
||||
.sp 1
|
||||
If one wished to run
|
||||
.B calc
|
||||
from a privileged user, one might want to use
|
||||
.B \-m
|
||||
0 in an effort to make
|
||||
.B calc
|
||||
somewhat more secure.
|
||||
.sp 1
|
||||
Mode bits for reading and writing apply only on an
|
||||
open.
|
||||
Files already open are not effected.
|
||||
Thus if one wanted to use the \fI\-m 0\fP in an effort to make
|
||||
\fIcalc\fP more secure, but still wanted to read and write a specific
|
||||
file, one might want to do:
|
||||
.sp
|
||||
.in +0.5i
|
||||
Thus if one wanted to use the
|
||||
.B \-m
|
||||
0 in an effort to make
|
||||
.B calc
|
||||
somewhat more secure, but still wanted to read and write a specific
|
||||
file, one might want to do in
|
||||
.BR sh (1),
|
||||
.BR ksh (1),
|
||||
.BR bash (1)-like
|
||||
shells:
|
||||
.sp 1
|
||||
.in +5n
|
||||
.nf
|
||||
\fRcalc \-m 0 3<a.file\fP
|
||||
calc -m 0 3<a.file
|
||||
.fi
|
||||
.in -0.5i
|
||||
.sp
|
||||
Files presented to \fIcalc\fP in this way are opened in an unknown mode.
|
||||
\fICalc\fP will attempt to read or write them if directed.
|
||||
.sp
|
||||
If the \fImode\fP disables opening of files for reading, then
|
||||
the startup library scripts are disabled as of \fI\-q\fP was given.
|
||||
The reading of key bindings is also disabled when the \fImode\fP
|
||||
disables opening of files for reading.
|
||||
.in -5n
|
||||
.sp 1
|
||||
Files presented to
|
||||
.B calc
|
||||
in this way are opened in an
|
||||
unknown mode.
|
||||
.B Calc
|
||||
will attempt to read or write them if directed.
|
||||
.sp 1
|
||||
If the mode disables opening of files for reading, then
|
||||
the startup library scripts are disabled as of
|
||||
.B \-q
|
||||
was given.
|
||||
The reading of key bindings is also disabled
|
||||
when the mode disables opening of files for reading.
|
||||
|
||||
.TP
|
||||
\fI \-p\fP
|
||||
Pipe processing is enabled by use of \-p. For example:
|
||||
.sp
|
||||
.in +0.5i
|
||||
.B \-n
|
||||
Use the new configuration defaults instead of the old
|
||||
default classic defaults.
|
||||
This flag as the same effect
|
||||
as executing \fBconfig("all", "newcfg")\fP at startup time.
|
||||
|
||||
.TP
|
||||
.B \-p
|
||||
Pipe processing is enabled by use of
|
||||
.BR \-p .
|
||||
For example:
|
||||
.sp 1
|
||||
.in +5n
|
||||
.nf
|
||||
\fRecho "print 2^21701\-1, 2^23209\-1" | calc \-p | fizzbin\fP
|
||||
calc -p '2^21701-1' | fizzbin
|
||||
.fi
|
||||
.in -0.5i
|
||||
.sp
|
||||
In pipe mode, \fIcalc\fP does not prompt, does not print leading tabs
|
||||
and does not print the initial header.
|
||||
.in -5n
|
||||
.sp 1
|
||||
In pipe mode,
|
||||
.B calc
|
||||
does not prompt, does not print leading
|
||||
tabs and does not print the initial header.
|
||||
The
|
||||
.B \-p
|
||||
flag overrides
|
||||
.BR \-i .
|
||||
|
||||
.TP
|
||||
\fI \-q\fP
|
||||
Disable the use of the \fI$CALCRC\fP startup scripts.
|
||||
.B \-q
|
||||
Disable the use of the $CALCRC startup scripts.
|
||||
|
||||
.TP
|
||||
\fI \-u\fP
|
||||
.B \-u
|
||||
Disable buffering of stdin and stdout.
|
||||
|
||||
.TP
|
||||
\fI \-v\fP
|
||||
Print the version and exit.
|
||||
.B \-v
|
||||
Print the
|
||||
.B calc
|
||||
version number and exit.
|
||||
.PP
|
||||
Without \fIcalc_cmd\fPs, \fIcalc\fP operates interactively.
|
||||
If one or more \fIcalc_cmd\fPs are given on the command line,
|
||||
\fIcalc\fP will execute them and exit.
|
||||
The printing of leading tabs on output is disabled
|
||||
as if \fIconfig("tab",0)\fP had been executed.
|
||||
Without
|
||||
.IR calc_cmd ,
|
||||
.B calc
|
||||
operates interactively.
|
||||
If one or more
|
||||
.I calc_cmd
|
||||
are given on the command line,
|
||||
.B calc
|
||||
will execute them and exit.
|
||||
If
|
||||
.B \-i
|
||||
is given,
|
||||
.B calc
|
||||
will attempt to become interactive
|
||||
even of one or more
|
||||
.I calc_cmd
|
||||
are given on the command line.
|
||||
.PP
|
||||
Normally on startup, \fIcalc\fP attempts to execute a collection
|
||||
of library scripts.
|
||||
The environment variable \fI$CALCRC\fP (if non-existent then
|
||||
a compiled in value) contains a \fI:\fP separated list of
|
||||
startup library scripts.
|
||||
No error conditions are produced if these startup library scripts
|
||||
are not found.
|
||||
Normally on startup,
|
||||
.B calc
|
||||
attempts to execute a collection of
|
||||
library scripts.
|
||||
The environment variable $CALCRC (if non-existent
|
||||
then a compiled in value) contains a : separated list of startup
|
||||
library scripts.
|
||||
No error conditions are produced if these startup
|
||||
library scripts are not found.
|
||||
.PP
|
||||
If the \fImode\fP disables opening of files for reading, then
|
||||
the startup library scripts are disabled as of \fI\-q\fP was given
|
||||
and \fI$CALCRC\fP as well as the default compiled in value are ignored.
|
||||
If the mode disables opening of files for reading, then the startup
|
||||
library scripts are disabled as of
|
||||
.B \-q
|
||||
was given and $CALCRC as well
|
||||
as the default compiled in value are ignored.
|
||||
.PP
|
||||
Filenames are subject to ``~'' expansion (see below).
|
||||
The environment variable \fI$CALCPATH\fP (if non-existent then
|
||||
a compiled in value) contains a \fI:\fP separated list of search
|
||||
directories.
|
||||
If a file does not begin with \fI/\fP, \fI~\fP or \fI./\fP,
|
||||
then it is searched for under each directory listed in the \fI$CALCPATH\fP.
|
||||
It is an error if no such readable file is found.
|
||||
The
|
||||
environment variable $CALCPATH (if non-existent then a compiled in
|
||||
value) contains a : separated list of search directories.
|
||||
If a
|
||||
file does not begin with /, ~ or ./, then it is searched for under
|
||||
each directory listed in the $CALCPATH.
|
||||
It is an error if no such
|
||||
readable file is found.
|
||||
.PP
|
||||
Calc treats all open files, other than stdin, stdout and stderr
|
||||
as files available for reading and writing.
|
||||
One may present calc with an already open file in the following way:
|
||||
.sp
|
||||
.in +0.5i
|
||||
.B Calc
|
||||
treats all open files, other than stdin, stdout and
|
||||
stderr as files available for reading and writing.
|
||||
One may
|
||||
present
|
||||
.B calc
|
||||
with an already open file using
|
||||
.BR sh (1),
|
||||
.BR ksh (1),
|
||||
.BR bash (1)-like
|
||||
shells is to:
|
||||
.sp 1
|
||||
.in +5n
|
||||
calc 3<open_file 4<open_file2
|
||||
.in -5n
|
||||
.sp 1
|
||||
For more information use the following
|
||||
.B calc
|
||||
commands:
|
||||
.sp 1
|
||||
.in +5n
|
||||
.nf
|
||||
\fRcalc 3<open_file 4<open_file2\fP
|
||||
.fi
|
||||
.in -0.5i
|
||||
.PP
|
||||
For more information use the following calc commands:
|
||||
.PP
|
||||
.in 1.0i
|
||||
help usage
|
||||
.br
|
||||
help help
|
||||
.br
|
||||
help overview
|
||||
help usage
|
||||
help environment
|
||||
.in -1.0i
|
||||
.PP
|
||||
OVERVIEW
|
||||
.PP
|
||||
\fICalc\fP is arbitrary precision arithmetic system that uses
|
||||
a C-like language.
|
||||
\fICalc\fP is useful as a calculator, an algorithm prototyped
|
||||
and as a mathematical research tool.
|
||||
More importantly, \fIcalc\fP provides one with a machine
|
||||
independent means of computation.
|
||||
.PP
|
||||
\fICalc\fP comes with a rich set of builtin mathematical
|
||||
and programmatic functions.
|
||||
.PP
|
||||
\fICalc\fP is distributed with library of scripts.
|
||||
Written in the same C-like language, library scripts may be
|
||||
read in and executed during a \fIcalc\fP session.
|
||||
These library scripts are also provided because they are
|
||||
useful and to serve as examples of the \fIcalc\fP language.
|
||||
One may further extend \fIcalc\fP thru the
|
||||
use of user defined scripts.
|
||||
.PP
|
||||
Internally calc represents numeric values as fractions reduced to their
|
||||
lowest terms.
|
||||
The numerators and denominators of these factions may grow to
|
||||
arbitrarily large values.
|
||||
Numeric values read in are automatically converted into rationals.
|
||||
The user need not be aware of this internal representation.
|
||||
.PP
|
||||
For more information use the following calc commands:
|
||||
.PP
|
||||
.in 1.0i
|
||||
help intro
|
||||
.br
|
||||
help builtin
|
||||
.br
|
||||
help stdlib
|
||||
.br
|
||||
help define
|
||||
.br
|
||||
show builtins
|
||||
.br
|
||||
show functions
|
||||
.in -1.0i
|
||||
help config
|
||||
.fi
|
||||
.in -5n
|
||||
.sp 1
|
||||
.PP
|
||||
DATA TYPES
|
||||
.PP
|
||||
@@ -199,7 +365,9 @@ multiplication, division, negation, squaring, modulus,
|
||||
rounding, exponentiation, equality, comparison, printing
|
||||
and so on.
|
||||
.PP
|
||||
For more information use the following calc commands:
|
||||
For more information use the following
|
||||
.B calc
|
||||
commands:
|
||||
.PP
|
||||
.in 1.0i
|
||||
help types
|
||||
@@ -220,7 +388,9 @@ procedure.
|
||||
Values may be grouped together in a matrix, or into a
|
||||
a list that permits stack and queue style operations.
|
||||
.PP
|
||||
For more information use the following calc commands:
|
||||
For more information use the following
|
||||
.B calc
|
||||
commands:
|
||||
.PP
|
||||
.in 1.0i
|
||||
help variable
|
||||
@@ -256,7 +426,9 @@ For example:
|
||||
~chongo/lib/fft_multiply.cal
|
||||
.in -1.0i
|
||||
.PP
|
||||
For more information use the following calc command:
|
||||
For more information use the following
|
||||
.B calc
|
||||
command:
|
||||
.PP
|
||||
.in 1.0i
|
||||
help file
|
||||
@@ -275,7 +447,9 @@ These include commands such as function definition, help,
|
||||
reading in library scripts, dump files to a file, error notification,
|
||||
configuration control and status.
|
||||
.PP
|
||||
For more information use the following calc command:
|
||||
For more information use the following
|
||||
.B calc
|
||||
command:
|
||||
.PP
|
||||
.in 1.0i
|
||||
help command
|
||||
@@ -295,7 +469,8 @@ help config
|
||||
.PD 0
|
||||
.TP 20
|
||||
${LIBDIR}/*.cal
|
||||
library scripts shipped with calc
|
||||
library scripts shipped with
|
||||
.B calc
|
||||
.br
|
||||
.sp
|
||||
.TP 20
|
||||
@@ -317,35 +492,42 @@ A :-separated list of directories used to search for
|
||||
scripts filenames that do not begin with /, ./ or ~.
|
||||
.br
|
||||
.sp
|
||||
Default value: .:./lib:~/lib:${LIBDIR}
|
||||
Default value: ${CALCPATH}
|
||||
.br
|
||||
.sp
|
||||
.TP 5
|
||||
CALCRC
|
||||
On startup (unless \-h or \-q was given on the command
|
||||
line), calc searches for files along this :-separated
|
||||
line),
|
||||
.B calc
|
||||
searches for files along this :-separated
|
||||
environment variable.
|
||||
.br
|
||||
.sp
|
||||
Default value: ${LIBDIR}/startup:~/.calcrc
|
||||
Default value: ${CALCRC}
|
||||
.br
|
||||
.sp
|
||||
.TP 5
|
||||
CALCBINDINGS
|
||||
On startup (unless \fI\-h\fP or \fI\-q\fP was given on the command
|
||||
line, or \fI\-m\fP disallows opening files for reading), calc reads
|
||||
line, or \fI\-m\fP disallows opening files for reading),
|
||||
.B calc
|
||||
reads
|
||||
key bindings from the filename specified
|
||||
by this environment variable.
|
||||
.br
|
||||
.sp
|
||||
Default value: ${LIBDIR}/bindings
|
||||
Default value: ${CALCBINDINGS}
|
||||
.sp
|
||||
.SH CREDIT
|
||||
\&
|
||||
.br
|
||||
The majority of calc was written by David I. Bell.
|
||||
The majority of
|
||||
.B calc
|
||||
was written by David I. Bell.
|
||||
.sp
|
||||
Calc archives and calc-tester mailing list maintained by Landon Curt Noll.
|
||||
.B Calc
|
||||
archives and calc-tester mailing list maintained by Landon Curt Noll.
|
||||
.sp
|
||||
Thanks for suggestions and encouragement from Peter Miller,
|
||||
Neil Justusson, and Landon Noll.
|
||||
@@ -378,30 +560,27 @@ Copyright (c) 19xx Ernest Bowen and Landon Curt Noll
|
||||
Permission is granted to use, distribute, or modify this source,
|
||||
provided that this copyright notice remains intact.
|
||||
.sp
|
||||
Send calc comments, suggestions, bug fixes, enhancements
|
||||
and interesting calc scripts that you would like you see included
|
||||
Send comments, suggestions, bug fixes, enhancements
|
||||
and interesting
|
||||
.B calc
|
||||
scripts that you would like you see included
|
||||
in future distributions to:
|
||||
.sp
|
||||
.in +0.5i
|
||||
dbell@auug.org.au
|
||||
.br
|
||||
chongo@toad.com
|
||||
calc-tester@postofc.corp.sgi.com
|
||||
.in -0.5i
|
||||
.sp
|
||||
Landon Noll maintains the official calc ftp archive at:
|
||||
Landon Noll maintains the the
|
||||
.B calc
|
||||
web site is located at:
|
||||
.sp
|
||||
.in +0.5i
|
||||
ftp://ftp.uu.net/pub/calc
|
||||
http://reality.sgi.com/chongo/tech/comp/calc
|
||||
.in -0.5i
|
||||
.sp
|
||||
Alpha test versions, complete with bugs, untested code and
|
||||
experimental features may be fetched (if you are brave) under:
|
||||
.sp
|
||||
.in +0.5i
|
||||
http://reality.sgi.com/chongo/calc/
|
||||
.in -0.5i
|
||||
.sp
|
||||
One may join the calc testing group by sending a request to:
|
||||
One may join the
|
||||
.B calc
|
||||
testing group by sending a request to:
|
||||
.sp
|
||||
.in +0.5i
|
||||
calc-tester-request@postofc.corp.sgi.com
|
||||
@@ -410,14 +589,14 @@ calc-tester-request@postofc.corp.sgi.com
|
||||
Your message body (not the subject) should consist of:
|
||||
.sp
|
||||
.in +0.5i
|
||||
.nf
|
||||
subscribe calc-tester address
|
||||
.br
|
||||
end
|
||||
.br
|
||||
name your_full_name
|
||||
.fi
|
||||
.in -0.5i
|
||||
.sp
|
||||
where "address" is your EMail address and "your_full_name"
|
||||
is your full name.
|
||||
.in -0.5i
|
||||
.sp
|
||||
Enjoy!
|
||||
Share and Enjoy! :\-)
|
||||
|
123
calc_errno.c
Normal file
123
calc_errno.c
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* errno - Determine how to declare errno, sys_errlist and sys_nerr
|
||||
*
|
||||
* On most machines: errno sys_errlist and sys_nerr are declared
|
||||
* by either <stdio.h> and/or <errno.h>. But some systems declare
|
||||
* them somewhere else or do not declare them at all!
|
||||
*
|
||||
* If the system were doing a proper job in headers, this should declare them:
|
||||
*
|
||||
* #include <stdio.h>
|
||||
* #include <errno.h>
|
||||
*
|
||||
* But one some systems one must explicitly declare them as:
|
||||
*
|
||||
* extern int errno;
|
||||
* extern const char *const sys_errlist[];
|
||||
* extern int sys_nerr;
|
||||
*
|
||||
* and on some old systems they must be explicitly and incorrectly declared as:
|
||||
*
|
||||
* extern int errno;
|
||||
* extern char *sys_errlist[];
|
||||
* extern int sys_nerr;
|
||||
*
|
||||
* The purpose of this utility is try and find the right way to declare
|
||||
* them and to output the middle of a header file called calc_errno.h.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1999 by Landon Curt Noll. All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software and
|
||||
* its documentation for any purpose and without fee is hereby granted,
|
||||
* provided that the above copyright, this permission notice and text
|
||||
* this comment, and the disclaimer below appear in all of the following:
|
||||
*
|
||||
* supporting documentation
|
||||
* source copies
|
||||
* source works derived from this source
|
||||
* binaries derived from this source or from derived source
|
||||
*
|
||||
* LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
|
||||
* EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* chongo was here /\../\
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#if defined(TRY_ERRNO_NO_DECL)
|
||||
# include <errno.h>
|
||||
#endif /* TRY_ERRNO_NO_DECL */
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
#if defined(TRY_ERRNO_NO_DECL)
|
||||
printf("/*\n");
|
||||
printf(" * The following comments were produced by calc_errno\n");
|
||||
printf(" * in an effort to see if these values were correctly\n");
|
||||
printf(" * declared when calc_errno.c was compiled.\n");
|
||||
printf(" */\n\n");
|
||||
printf("/* Initially errno is %d */\n", errno);
|
||||
printf("/* There are %d entries in sys_errlist[] */\n", sys_nerr);
|
||||
printf("/* The 2nd sys_errlist entry is \"%s\" */\n\n", sys_errlist[1]);
|
||||
printf("/*\n");
|
||||
printf(" * Based on the above, calc_errno now knows\n");
|
||||
printf(" * how to declare errno and friends.\n");
|
||||
printf(" */\n\n");
|
||||
printf("#include <stdio.h>\n");
|
||||
printf("#include <errno.h>\n");
|
||||
#elif defined(TRY_ERRNO_OLD_DECL)
|
||||
extern int errno; /* last system error */
|
||||
extern char *sys_errlist[]; /* system error messages */
|
||||
extern int sys_nerr; /* number of system errors*/
|
||||
|
||||
printf("/*\n");
|
||||
printf(" * The following comments were produced by calc_errno\n");
|
||||
printf(" * in an effort to see if these values were correctly\n");
|
||||
printf(" * declared when calc_errno.c was compiled.\n");
|
||||
printf(" */\n\n");
|
||||
printf("/* Initially errno is %d */\n", errno);
|
||||
printf("/* There are %d entries in sys_errlist[] */\n", sys_nerr);
|
||||
printf("/* The 2nd sys_errlist entry is \"%s\" */\n\n", sys_errlist[1]);
|
||||
printf("/*\n");
|
||||
printf(" * Based on the above, calc_errno now knows\n");
|
||||
printf(" * how to declare errno and friends.\n");
|
||||
printf(" */\n\n");
|
||||
printf("extern int errno;\t\t/* last system error */\n");
|
||||
printf("extern char *sys_errlist[];\t"
|
||||
"/* system error messages */\n");
|
||||
printf("extern int sys_nerr;\t\t/* number of system errors*/\n");
|
||||
#else /* assume defined(TRY_ERRNO_STD_DECL) */
|
||||
extern int errno; /* last system error */
|
||||
extern const char *const sys_errlist[]; /* system error messages */
|
||||
extern int sys_nerr; /* number of system errors*/
|
||||
|
||||
printf("/*\n");
|
||||
printf(" * The following comments were produced by calc_errno\n");
|
||||
printf(" * in an effort to see if these values were correctly\n");
|
||||
printf(" * declared when calc_errno.c was compiled.\n");
|
||||
printf(" */\n\n");
|
||||
printf("/* Initially errno is %d */\n", errno);
|
||||
printf("/* There are %d entries in sys_errlist[] */\n", sys_nerr);
|
||||
printf("/* The 2nd sys_errlist entry is \"%s\" */\n\n", sys_errlist[1]);
|
||||
printf("/*\n");
|
||||
printf(" * Based on the above, calc_errno now knows\n");
|
||||
printf(" * how to declare errno and friends.\n");
|
||||
printf(" */\n\n");
|
||||
printf("extern int errno;\t\t\t/* last system error */\n");
|
||||
printf("extern const char *const sys_errlist[];\t"
|
||||
"/* system error messages */\n");
|
||||
printf("extern int sys_nerr;\t\t\t/* number of system errors*/\n");
|
||||
#endif
|
||||
|
||||
/* exit(0); */
|
||||
return 0;
|
||||
}
|
151
calcerr.tbl
151
calcerr.tbl
@@ -120,16 +120,22 @@ E_UNGETC1 Non-file argument for ungetc
|
||||
E_UNGETC2 File not open for reading for ungetc
|
||||
E_UNGETC3 Bad second argument or other error for ungetc
|
||||
E_BIGEXP Exponent too big in scanning
|
||||
E_ISATTY1 Non-file argument for isatty
|
||||
E_ISATTY2 File not open for isatty
|
||||
E_ISATTY1 E_ISATTY1 is no longer used
|
||||
E_ISATTY2 E_ISATTY2 is no longer used
|
||||
E_ACCESS1 Non-string first argument for access
|
||||
E_ACCESS2 Bad second argument for access
|
||||
E_SEARCH1 Bad first argument for search
|
||||
E_SEARCH2 Bad second argument for search
|
||||
E_SEARCH3 Bad third argument for search
|
||||
E_SEARCH4 Bad fourth argument for search
|
||||
E_SEARCH5 Cannot find fsize or fpos for search
|
||||
E_SEARCH6 File not readable for search
|
||||
E_RSEARCH1 Bad first argument for rsearch
|
||||
E_RSEARCH2 Bad second argument for rsearch
|
||||
E_RSEARCH3 Bad third argument for rsearch
|
||||
E_RSEARCH4 Bad fourth argument for rsearch
|
||||
E_RSEARCH5 Cannot find fsize or fpos for rsearch
|
||||
E_RSEARCH6 File not readable for rsearch
|
||||
E_FOPEN3 Too many open files
|
||||
E_REWIND2 Attempt to rewind a file that is not open
|
||||
E_STRERROR1 Bad argument type for strerror
|
||||
@@ -148,7 +154,7 @@ E_MATFILL1 Non-variable first argument for matfill
|
||||
E_MATFILL2 Non-matrix first argument-value for matfill
|
||||
E_MATDIM Non-matrix argument for matdim
|
||||
E_MATSUM Non-matrix argument for matsum
|
||||
E_ISIDENT Non-matrix argument for isident
|
||||
E_ISIDENT E_ISIDENT is no longer used
|
||||
E_MATTRANS1 Non-matrix argument for mattrans
|
||||
E_MATTRANS2 Non-two-dimensional matrix for mattrans
|
||||
E_DET1 Non-matrix argument for det
|
||||
@@ -191,3 +197,142 @@ E_RM2 Unable to remove a file
|
||||
E_RDPERM Operation allowed because calc mode disallows read operations
|
||||
E_WRPERM Operation allowed because calc mode disallows write operations
|
||||
E_EXPERM Operation allowed because calc mode disallows exec operations
|
||||
E_MIN Unordered arguments for min
|
||||
E_MAX Unordered arguments for max
|
||||
E_LISTMIN Unordered items for minimum of list
|
||||
E_LISTMAX Unordered items for maximum of list
|
||||
E_SIZE Size undefined for argument type
|
||||
E_NO_C_ARG Calc must be run with a -C argument to use custom function
|
||||
E_NO_CUSTOM Calc was built with custom functions disabled
|
||||
E_UNK_CUSTOM Custom function unknown, try: show custom
|
||||
E_BLK1 Non-integral length for block
|
||||
E_BLK2 Negative or too-large length for block
|
||||
E_BLK3 Non-integral chunksize for block
|
||||
E_BLK4 Negative or too-large chunksize for block
|
||||
E_BLKFREE1 Named block does not exist for blkfree
|
||||
E_BLKFREE2 Non-integral id specification for blkfree
|
||||
E_BLKFREE3 Block with specified id does not exist
|
||||
E_BLKFREE4 Block already freed
|
||||
E_BLKFREE5 No-realloc protection prevents blkfree
|
||||
E_BLOCKS1 Non-integer argument for blocks
|
||||
E_BLOCKS2 Non-allocated index number for blocks
|
||||
E_COPY1 Non-integer or negative source index for copy
|
||||
E_COPY2 Source index too large for copy
|
||||
E_COPY3 E_COPY3 is no longer used
|
||||
E_COPY4 Non-integer or negative number for copy
|
||||
E_COPY5 Number too large for copy
|
||||
E_COPY6 Non-integer or negative destination index for copy
|
||||
E_COPY7 Destination index too large for copy
|
||||
E_COPY8 Freed block source for copy
|
||||
E_COPY9 Unsuitable source type for copy
|
||||
E_COPY10 Freed block destinction for copy
|
||||
E_COPY11 Unsuitable destination type for copy
|
||||
E_COPY12 Incompatible source and destination for copy
|
||||
E_COPY13 No-copy-from source variable
|
||||
E_COPY14 No-copy-to destination variable
|
||||
E_COPY15 No-copy-from source named block
|
||||
E_COPY16 No-copy-to destination named block
|
||||
E_COPY17 No-relocation destination for copy
|
||||
E_COPYF1 File not open for copy
|
||||
E_COPYF2 fseek or fsize failure for copy
|
||||
E_COPYF3 fwrite error for copy
|
||||
E_COPYF4 fread error for copy
|
||||
E_PROTECT1 Non-variable first argument for protect
|
||||
E_PROTECT2 Non-integer second argument for protect
|
||||
E_PROTECT3 Out-of-range second argument for protect
|
||||
E_MATFILL3 No-copy-to destination for matfill
|
||||
E_MATFILL4 No-assign-from source for matfill
|
||||
E_MATTRACE1 Non-matrix argument for mattrace
|
||||
E_MATTRACE2 Non-two-dimensional argument for mattrace
|
||||
E_MATTRACE3 Non-square argument for mattrace
|
||||
E_TAN1 Bad epsilon for tan
|
||||
E_TAN2 Bad argument for tan
|
||||
E_COT1 Bad epsilon for cot
|
||||
E_COT2 Bad argument for cot
|
||||
E_SEC1 Bad epsilon for sec
|
||||
E_SEC2 Bad argument for sec
|
||||
E_CSC1 Bad epsilon for csc
|
||||
E_CSC2 Bad argument for csc
|
||||
E_SINH1 Bad epsilon for sinh
|
||||
E_SINH2 Bad argument for sinh
|
||||
E_COSH1 Bad epsilon for cosh
|
||||
E_COSH2 Bad argument for cosh
|
||||
E_TANH1 Bad epsilon for tanh
|
||||
E_TANH2 Bad argument for tanh
|
||||
E_COTH1 Bad epsilon for coth
|
||||
E_COTH2 Bad argument for coth
|
||||
E_SECH1 Bad epsilon for sech
|
||||
E_SECH2 Bad argument for sech
|
||||
E_CSCH1 Bad epsilon for csch
|
||||
E_CSCH2 Bad argument for csch
|
||||
E_ASIN1 Bad epsilon for asin
|
||||
E_ASIN2 Bad argument for asin
|
||||
E_ACOS1 Bad epsilon for acos
|
||||
E_ACOS2 Bad argument for acos
|
||||
E_ATAN1 Bad epsilon for atan
|
||||
E_ATAN2 Bad argument for atan
|
||||
E_ACOT1 Bad epsilon for acot
|
||||
E_ACOT2 Bad argument for acot
|
||||
E_ASEC1 Bad epsilon for asec
|
||||
E_ASEC2 Bad argument for asec
|
||||
E_ACSC1 Bad epsilon for acsc
|
||||
E_ACSC2 Bad argument for acsc
|
||||
E_ASINH1 Bad epsilon for asin
|
||||
E_ASINH2 Bad argument for asinh
|
||||
E_ACOSH1 Bad epsilon for acosh
|
||||
E_ACOSH2 Bad argument for acosh
|
||||
E_ATANH1 Bad epsilon for atanh
|
||||
E_ATANH2 Bad argument for atanh
|
||||
E_ACOTH1 Bad epsilon for acoth
|
||||
E_ACOTH2 Bad argument for acoth
|
||||
E_ASECH1 Bad epsilon for asech
|
||||
E_ASECH2 Bad argument for asech
|
||||
E_ACSCH1 Bad epsilon for acsch
|
||||
E_ACSCH2 Bad argument for acsch
|
||||
E_GD1 Bad epsilon for gd
|
||||
E_GD2 Bad argument for gd
|
||||
E_AGD1 Bad epsilon for agd
|
||||
E_AGD2 Bad argument for agd
|
||||
E_LOGINF Log of zero or infinity
|
||||
E_STRADD String addition failure
|
||||
E_STRMUL String multiplication failure
|
||||
E_STRNEG String reversal failure
|
||||
E_STRSUB String subtraction failure
|
||||
E_BIT1 Bad argument type for bit
|
||||
E_BIT2 Index too large for bit
|
||||
E_SETBIT1 Non-integer second argument for setbit
|
||||
E_SETBIT2 Out-of-range index for setbit
|
||||
E_SETBIT3 Non-string first argument for setbit
|
||||
E_OR Bad argument for or
|
||||
E_AND Bad argument for and
|
||||
E_STROR Allocation failure for string or
|
||||
E_STRAND Allocation failure for string and
|
||||
E_XOR Bad argument for xorvalue
|
||||
E_COMP Bad argument for comp
|
||||
E_STRDIFF Allocation failure for string diff
|
||||
E_STRCOMP Allocation failure for string comp
|
||||
E_SEG1 Bad first argument for segment
|
||||
E_SEG2 Bad second argument for segment
|
||||
E_SEG3 Bad third argument for segment
|
||||
E_STRSEG Failure for string segment
|
||||
E_HIGHBIT1 Bad argument type for highbit
|
||||
E_HIGHBIT2 Non-integer argument for highbit
|
||||
E_LOWBIT1 Bad argument type for lowbit
|
||||
E_LOWBIT2 Non-integer argument for lowbit
|
||||
E_CONTENT Bad argument type for unary hash op
|
||||
E_HASHOP Bad argument type for binary hash op
|
||||
E_HEAD1 Bad first argument for head
|
||||
E_HEAD2 Bad second argument for head
|
||||
E_STRHEAD Failure for strhead
|
||||
E_TAIL1 Bad first argument for tail
|
||||
E_TAIL2 Bad second argument for tail
|
||||
E_STRTAIL Failure for strtail
|
||||
E_STRSHIFT Failure for strshift
|
||||
E_STRCMP Non-string argument for strcmp
|
||||
E_STRNCMP Bad argument type for strncmp
|
||||
E_XOR1 Varying types of argument for xor
|
||||
E_XOR2 Bad argument type for xor
|
||||
E_STRCPY Bad argument type for strcpy
|
||||
E_STRNCPY Bad argument type for strncpy
|
||||
E_BACKSLASH Bad argument type for unary backslash
|
||||
E_SETMINUS Bad argument type for setminus
|
||||
|
@@ -29,7 +29,7 @@ NF == 0 {
|
||||
next;
|
||||
}
|
||||
|
||||
$1 ~ /^[0-9]/ {
|
||||
$1 ~ /^[0-9]+:/ {
|
||||
if (error > 0) {
|
||||
if (havebuf2) {
|
||||
print buf2;
|
||||
@@ -71,4 +71,9 @@ END {
|
||||
if (error > 0 && havebuf0) {
|
||||
print buf0;
|
||||
}
|
||||
if (error > 0) {
|
||||
exit(1);
|
||||
} else {
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
28
cmath.h
28
cmath.h
@@ -1,13 +1,15 @@
|
||||
/*
|
||||
* Copyright (c) 1993 David I. Bell
|
||||
* Copyright (c) 1997 David I. Bell
|
||||
* Permission is granted to use, distribute, or modify this source,
|
||||
* provided that this copyright notice remains intact.
|
||||
*
|
||||
* Data structure declarations for extended precision complex arithmetic.
|
||||
*/
|
||||
|
||||
#ifndef CMATH_H
|
||||
#define CMATH_H
|
||||
|
||||
#if !defined(__CMATH_H__)
|
||||
#define __CMATH_H__
|
||||
|
||||
|
||||
#include "qmath.h"
|
||||
|
||||
@@ -73,8 +75,25 @@ extern COMPLEX *cexp(COMPLEX *c, NUMBER *epsilon);
|
||||
extern COMPLEX *cln(COMPLEX *c, NUMBER *epsilon);
|
||||
extern COMPLEX *ccos(COMPLEX *c, NUMBER *epsilon);
|
||||
extern COMPLEX *csin(COMPLEX *c, NUMBER *epsilon);
|
||||
extern COMPLEX *ccosh(COMPLEX *c, NUMBER *epsilon);
|
||||
extern COMPLEX *csinh(COMPLEX *c, NUMBER *epsilon);
|
||||
extern COMPLEX *cpolar(NUMBER *q1, NUMBER *q2, NUMBER *epsilon);
|
||||
extern COMPLEX *crel(COMPLEX *c1, COMPLEX *c2);
|
||||
extern COMPLEX *casin(COMPLEX *c, NUMBER *epsilon);
|
||||
extern COMPLEX *cacos(COMPLEX *c, NUMBER *epsilon);
|
||||
extern COMPLEX *catan(COMPLEX *c, NUMBER *epsilon);
|
||||
extern COMPLEX *cacot(COMPLEX *c, NUMBER *epsilon);
|
||||
extern COMPLEX *casec(COMPLEX *c, NUMBER *epsilon);
|
||||
extern COMPLEX *cacsc(COMPLEX *c, NUMBER *epsilon);
|
||||
extern COMPLEX *casinh(COMPLEX *c, NUMBER *epsilon);
|
||||
extern COMPLEX *cacosh(COMPLEX *c, NUMBER *epsilon);
|
||||
extern COMPLEX *catanh(COMPLEX *c, NUMBER *epsilon);
|
||||
extern COMPLEX *cacoth(COMPLEX *c, NUMBER *epsilon);
|
||||
extern COMPLEX *casech(COMPLEX *c, NUMBER *epsilon);
|
||||
extern COMPLEX *cacsch(COMPLEX *c, NUMBER *epsilon);
|
||||
extern COMPLEX *cgd(COMPLEX *c, NUMBER *epsilon);
|
||||
extern COMPLEX *cagd(COMPLEX *c, NUMBER *epsilon);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
@@ -108,6 +127,5 @@ extern COMPLEX *swap_HALF_in_COMPLEX(COMPLEX *dest, COMPLEX *src, BOOL all);
|
||||
*/
|
||||
extern COMPLEX _czero_, _cone_, _conei_;
|
||||
|
||||
#endif
|
||||
|
||||
/* END CODE */
|
||||
#endif /* !__CMATH_H__ */
|
||||
|
415
comfunc.c
415
comfunc.c
@@ -125,10 +125,12 @@ csqrt(COMPLEX *c, NUMBER *epsilon, long R)
|
||||
if (cisreal(c)) {
|
||||
r = comalloc();
|
||||
if (!qisneg(c->real)) {
|
||||
qfree(r->real);
|
||||
r->real = qsqrt(c->real, epsilon, R);
|
||||
return r;
|
||||
}
|
||||
ntmp = qneg(c->real);
|
||||
qfree(r->imag);
|
||||
r->imag = qsqrt(ntmp, epsilon, R);
|
||||
qfree(ntmp);
|
||||
return r;
|
||||
@@ -160,7 +162,7 @@ csqrt(COMPLEX *c, NUMBER *epsilon, long R)
|
||||
return clink(&_czero_);
|
||||
}
|
||||
aes = qscale(c->imag, -1);
|
||||
v = qdiv(aes, u);
|
||||
v = qqdiv(aes, u);
|
||||
qfree(aes);
|
||||
r = comalloc();
|
||||
r->real = u;
|
||||
@@ -170,8 +172,8 @@ csqrt(COMPLEX *c, NUMBER *epsilon, long R)
|
||||
#endif
|
||||
imsign = c->imag->num.sign;
|
||||
es = qsquare(epsilon);
|
||||
aes = qdiv(c->real, es);
|
||||
bes = qdiv(c->imag, es);
|
||||
aes = qqdiv(c->real, es);
|
||||
bes = qqdiv(c->imag, es);
|
||||
qfree(es);
|
||||
zgcd(aes->den, bes->den, &g);
|
||||
zequo(bes->den, g, &tmp1);
|
||||
@@ -217,12 +219,14 @@ csqrt(COMPLEX *c, NUMBER *epsilon, long R)
|
||||
r = comalloc();
|
||||
qtemp = *aes;
|
||||
qtemp.num.sign = sign;
|
||||
qfree(r->real);
|
||||
r->real = qmul(&qtemp, epsilon);
|
||||
qfree(aes);
|
||||
bes = qscale(r->real, 1);
|
||||
qtemp = *bes;
|
||||
qtemp.num.sign = sign ^ imsign;
|
||||
r->imag = qdiv(c->imag, &qtemp);
|
||||
qfree(r->imag);
|
||||
r->imag = qqdiv(c->imag, &qtemp);
|
||||
qfree(bes);
|
||||
return r;
|
||||
}
|
||||
@@ -272,12 +276,14 @@ csqrt(COMPLEX *c, NUMBER *epsilon, long R)
|
||||
r = comalloc();
|
||||
qtemp = *aes;
|
||||
qtemp.num.sign = sign;
|
||||
qfree(r->real);
|
||||
r->real = qmul(&qtemp, epsilon);
|
||||
qfree(aes);
|
||||
bes = qscale(r->real, 1);
|
||||
qtemp = *bes;
|
||||
qtemp.num.sign = sign ^ imsign;
|
||||
r->imag = qdiv(c->imag, &qtemp);
|
||||
qfree(r->imag);
|
||||
r->imag = qqdiv(c->imag, &qtemp);
|
||||
qfree(bes);
|
||||
return r;
|
||||
}
|
||||
@@ -355,10 +361,10 @@ csqrt(COMPLEX *c, NUMBER *epsilon, long R)
|
||||
return clink(&_czero_);
|
||||
}
|
||||
r = comalloc();
|
||||
if (!qiszero(u))
|
||||
r->real = u;
|
||||
if (!qiszero(v))
|
||||
r->imag = v;
|
||||
qfree(r->real);
|
||||
qfree(r->imag);
|
||||
r->real = u;
|
||||
r->imag = v;
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -384,6 +390,7 @@ croot(COMPLEX *c, NUMBER *q, NUMBER *epsilon)
|
||||
return csqrt(c, epsilon, 24L);
|
||||
if (cisreal(c) && !qisneg(c->real)) {
|
||||
r = comalloc();
|
||||
qfree(r->real);
|
||||
r->real = qroot(c->real, q, epsilon);
|
||||
return r;
|
||||
}
|
||||
@@ -412,7 +419,7 @@ croot(COMPLEX *c, NUMBER *q, NUMBER *epsilon)
|
||||
epsilon2 = qbitvalue(n - m - 4);
|
||||
tmp1 = qatan2(c->imag, c->real, epsilon2);
|
||||
qfree(epsilon2);
|
||||
tmp2 = qdiv(tmp1, q);
|
||||
tmp2 = qqdiv(tmp1, q);
|
||||
qfree(tmp1);
|
||||
r = cpolar(root, tmp2, epsilon);
|
||||
qfree(root);
|
||||
@@ -437,8 +444,9 @@ cexp(COMPLEX *c, NUMBER *epsilon)
|
||||
math_error("Zero epsilon for cexp");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
r = comalloc();
|
||||
if (cisreal(c)) {
|
||||
r = comalloc();
|
||||
qfree(r->real);
|
||||
r->real = qexp(c->real, epsilon);
|
||||
return r;
|
||||
}
|
||||
@@ -458,11 +466,14 @@ cexp(COMPLEX *c, NUMBER *epsilon)
|
||||
qsincos(c->imag, k - n + 2, &sin, &cos);
|
||||
tmp2 = qmul(tmp1, cos);
|
||||
qfree(cos);
|
||||
r = comalloc();
|
||||
qfree(r->real);
|
||||
r->real = qmappr(tmp2, epsilon, 24L);
|
||||
qfree(tmp2);
|
||||
tmp2 = qmul(tmp1, sin);
|
||||
qfree(tmp1);
|
||||
qfree(sin);
|
||||
qfree(r->imag);
|
||||
r->imag = qmappr(tmp2, epsilon, 24L);
|
||||
qfree(tmp2);
|
||||
return r;
|
||||
@@ -488,6 +499,7 @@ cln(COMPLEX *c, NUMBER *epsilon)
|
||||
return clink(&_czero_);
|
||||
r = comalloc();
|
||||
if (cisreal(c) && !qisneg(c->real)) {
|
||||
qfree(r->real);
|
||||
r->real = qln(c->real, epsilon);
|
||||
return r;
|
||||
}
|
||||
@@ -500,8 +512,10 @@ cln(COMPLEX *c, NUMBER *epsilon)
|
||||
tmp1 = qln(a2b2, epsilon1);
|
||||
qfree(a2b2);
|
||||
qfree(epsilon1);
|
||||
qfree(r->real);
|
||||
r->real = qscale(tmp1, -1L);
|
||||
qfree(tmp1);
|
||||
qfree(r->imag);
|
||||
r->imag = qatan2(c->imag, c->real, epsilon);
|
||||
return r;
|
||||
}
|
||||
@@ -526,6 +540,8 @@ ccos(COMPLEX *c, NUMBER *epsilon)
|
||||
}
|
||||
n = qilog2(epsilon);
|
||||
ctmp1 = comalloc();
|
||||
qfree(ctmp1->real);
|
||||
qfree(ctmp1->imag);
|
||||
neg = qisneg(c->imag);
|
||||
ctmp1->real = neg ? qneg(c->imag) : qlink(c->imag);
|
||||
ctmp1->imag = neg ? qlink(c->real) : qneg(c->real);
|
||||
@@ -544,7 +560,9 @@ ccos(COMPLEX *c, NUMBER *epsilon)
|
||||
ctmp1 = cscale(ctmp3, -1);
|
||||
comfree(ctmp3);
|
||||
r = comalloc();
|
||||
qfree(r->real);
|
||||
r->real = qmappr(ctmp1->real, epsilon, 24L);
|
||||
qfree(r->imag);
|
||||
r->imag = qmappr(ctmp1->imag, epsilon, 24L);
|
||||
comfree(ctmp1);
|
||||
return r;
|
||||
@@ -573,6 +591,8 @@ csin(COMPLEX *c, NUMBER *epsilon)
|
||||
n = qilog2(epsilon);
|
||||
ctmp1 = comalloc();
|
||||
neg = qisneg(c->imag);
|
||||
qfree(ctmp1->real);
|
||||
qfree(ctmp1->imag);
|
||||
ctmp1->real = neg ? qneg(c->imag) : qlink(c->imag);
|
||||
ctmp1->imag = neg ? qlink(c->real) : qneg(c->real);
|
||||
epsilon1 = qbitvalue(n - 2);
|
||||
@@ -591,9 +611,11 @@ csin(COMPLEX *c, NUMBER *epsilon)
|
||||
comfree(ctmp3);
|
||||
r = comalloc();
|
||||
qtmp = neg ? qlink(ctmp1->imag) : qneg(ctmp1->imag);
|
||||
qfree(r->real);
|
||||
r->real = qmappr(qtmp, epsilon, 24L);
|
||||
qfree(qtmp);
|
||||
qtmp = neg ? qneg(ctmp1->real) : qlink(ctmp1->real);
|
||||
qfree(r->imag);
|
||||
r->imag = qmappr(qtmp, epsilon, 24L);
|
||||
qfree(qtmp);
|
||||
comfree(ctmp1);
|
||||
@@ -601,6 +623,364 @@ csin(COMPLEX *c, NUMBER *epsilon)
|
||||
}
|
||||
|
||||
|
||||
COMPLEX *
|
||||
ccosh(COMPLEX *c, NUMBER *epsilon)
|
||||
{
|
||||
COMPLEX *tmp1, *tmp2, *tmp3;
|
||||
|
||||
tmp1 = cexp(c, epsilon);
|
||||
tmp2 = cneg(c);
|
||||
tmp3 = cexp(tmp2, epsilon);
|
||||
comfree(tmp2);
|
||||
tmp2 = cadd(tmp1, tmp3);
|
||||
comfree(tmp1);
|
||||
comfree(tmp3);
|
||||
tmp1 = cscale(tmp2, -1);
|
||||
comfree(tmp2);
|
||||
return tmp1;
|
||||
}
|
||||
|
||||
|
||||
COMPLEX *
|
||||
csinh(COMPLEX *c, NUMBER *epsilon)
|
||||
{
|
||||
COMPLEX *tmp1, *tmp2, *tmp3;
|
||||
|
||||
tmp1 = cexp(c, epsilon);
|
||||
tmp2 = cneg(c);
|
||||
tmp3 = cexp(tmp2, epsilon);
|
||||
comfree(tmp2);
|
||||
tmp2 = csub(tmp1, tmp3);
|
||||
comfree(tmp1);
|
||||
comfree(tmp3);
|
||||
tmp1 = cscale(tmp2, -1);
|
||||
comfree(tmp2);
|
||||
return tmp1;
|
||||
}
|
||||
|
||||
|
||||
COMPLEX *
|
||||
casin(COMPLEX *c, NUMBER *epsilon)
|
||||
{
|
||||
COMPLEX *tmp1, *tmp2;
|
||||
|
||||
tmp1 = cmul(&_conei_, c);
|
||||
tmp2 = casinh(tmp1, epsilon);
|
||||
comfree(tmp1);
|
||||
tmp1 = cdiv(tmp2, &_conei_);
|
||||
comfree(tmp2);
|
||||
return tmp1;
|
||||
}
|
||||
|
||||
|
||||
COMPLEX *
|
||||
cacos(COMPLEX *c, NUMBER *epsilon)
|
||||
{
|
||||
COMPLEX *tmp1, *tmp2;
|
||||
|
||||
tmp1 = csquare(c);
|
||||
tmp2 = csub(&_cone_, tmp1);
|
||||
comfree(tmp1);
|
||||
tmp1 = csqrt(tmp2, epsilon, 24);
|
||||
comfree(tmp2);
|
||||
tmp2 = cmul(&_conei_, tmp1);
|
||||
comfree(tmp1);
|
||||
tmp1 = cadd(c, tmp2);
|
||||
comfree(tmp2);
|
||||
tmp2 = cln(tmp1, epsilon);
|
||||
comfree(tmp1);
|
||||
tmp1 = cdiv(tmp2, &_conei_);
|
||||
comfree(tmp2);
|
||||
return tmp1;
|
||||
}
|
||||
|
||||
|
||||
COMPLEX *
|
||||
casinh(COMPLEX *c, NUMBER *epsilon)
|
||||
{
|
||||
COMPLEX *tmp1, *tmp2, *tmp3;
|
||||
BOOL neg;
|
||||
|
||||
neg = qisneg(c->real);
|
||||
tmp1 = neg ? cneg(c) : clink(c);
|
||||
tmp2 = csquare(tmp1);
|
||||
tmp3 = cadd(&_cone_, tmp2);
|
||||
comfree(tmp2);
|
||||
tmp2 = csqrt(tmp3, epsilon, 24);
|
||||
comfree(tmp3);
|
||||
tmp3 = cadd(tmp2, tmp1);
|
||||
comfree(tmp1);
|
||||
comfree(tmp2);
|
||||
tmp1 = cln(tmp3, epsilon);
|
||||
comfree(tmp3);
|
||||
if (neg) {
|
||||
tmp2 = cneg(tmp1);
|
||||
comfree(tmp1);
|
||||
return tmp2;
|
||||
}
|
||||
return tmp1;
|
||||
}
|
||||
|
||||
|
||||
COMPLEX *
|
||||
cacosh(COMPLEX *c, NUMBER *epsilon)
|
||||
{
|
||||
COMPLEX *tmp1, *tmp2;
|
||||
|
||||
tmp1 = csquare(c);
|
||||
tmp2 = csub(tmp1, &_cone_);
|
||||
comfree(tmp1);
|
||||
tmp1 = csqrt(tmp2, epsilon, 24);
|
||||
comfree(tmp2);
|
||||
tmp2 = cadd(c, tmp1);
|
||||
comfree(tmp1);
|
||||
tmp1 = cln(tmp2, epsilon);
|
||||
comfree(tmp2);
|
||||
return tmp1;
|
||||
}
|
||||
|
||||
|
||||
COMPLEX *
|
||||
catan(COMPLEX *c, NUMBER *epsilon)
|
||||
{
|
||||
COMPLEX *tmp1, *tmp2, *tmp3;
|
||||
|
||||
if (qiszero(c->real) && qisunit(c->imag))
|
||||
return NULL;
|
||||
tmp1 = csub(&_conei_, c);
|
||||
tmp2 = cadd(&_conei_, c);
|
||||
tmp3 = cdiv(tmp1, tmp2);
|
||||
comfree(tmp1);
|
||||
comfree(tmp2);
|
||||
tmp1 = cln(tmp3, epsilon);
|
||||
comfree(tmp3);
|
||||
tmp2 = cscale(tmp1, -1);
|
||||
comfree(tmp1);
|
||||
tmp1 = cdiv(tmp2, &_conei_);
|
||||
comfree(tmp2);
|
||||
return tmp1;
|
||||
}
|
||||
|
||||
|
||||
COMPLEX *
|
||||
cacot(COMPLEX *c, NUMBER *epsilon)
|
||||
{
|
||||
COMPLEX *tmp1, *tmp2, *tmp3;
|
||||
|
||||
if (qiszero(c->real) && qisunit(c->imag))
|
||||
return NULL;
|
||||
tmp1 = cadd(c, &_conei_);
|
||||
tmp2 = csub(c, &_conei_);
|
||||
tmp3 = cdiv(tmp1, tmp2);
|
||||
comfree(tmp1);
|
||||
comfree(tmp2);
|
||||
tmp1 = cln(tmp3, epsilon);
|
||||
comfree(tmp3);
|
||||
tmp2 = cscale(tmp1, -1);
|
||||
comfree(tmp1);
|
||||
tmp1 = cdiv(tmp2, &_conei_);
|
||||
comfree(tmp2);
|
||||
return tmp1;
|
||||
}
|
||||
|
||||
COMPLEX *
|
||||
casec(COMPLEX *c, NUMBER *epsilon)
|
||||
{
|
||||
COMPLEX *tmp1, *tmp2;
|
||||
|
||||
tmp1 = cinv(c);
|
||||
tmp2 = cacos(tmp1, epsilon);
|
||||
comfree(tmp1);
|
||||
return tmp2;
|
||||
}
|
||||
|
||||
COMPLEX *
|
||||
cacsc(COMPLEX *c, NUMBER *epsilon)
|
||||
{
|
||||
COMPLEX *tmp1, *tmp2;
|
||||
|
||||
tmp1 = cinv(c);
|
||||
tmp2 = casin(tmp1, epsilon);
|
||||
comfree(tmp1);
|
||||
return tmp2;
|
||||
}
|
||||
|
||||
|
||||
COMPLEX *
|
||||
catanh(COMPLEX *c, NUMBER *epsilon)
|
||||
{
|
||||
COMPLEX *tmp1, *tmp2, *tmp3;
|
||||
|
||||
if (qiszero(c->imag) && qisunit(c->real))
|
||||
return NULL;
|
||||
tmp1 = cadd(&_cone_, c);
|
||||
tmp2 = csub(&_cone_, c);
|
||||
tmp3 = cdiv(tmp1, tmp2);
|
||||
comfree(tmp1);
|
||||
comfree(tmp2);
|
||||
tmp1 = cln(tmp3, epsilon);
|
||||
comfree(tmp3);
|
||||
tmp2 = cscale(tmp1, -1);
|
||||
comfree(tmp1);
|
||||
return tmp2;
|
||||
}
|
||||
|
||||
|
||||
COMPLEX *
|
||||
cacoth(COMPLEX *c, NUMBER *epsilon)
|
||||
{
|
||||
COMPLEX *tmp1, *tmp2, *tmp3;
|
||||
|
||||
if (qiszero(c->imag) && qisunit(c->real))
|
||||
return NULL;
|
||||
tmp1 = cadd(c, &_cone_);
|
||||
tmp2 = csub(c, &_cone_);
|
||||
tmp3 = cdiv(tmp1, tmp2);
|
||||
comfree(tmp1);
|
||||
comfree(tmp2);
|
||||
tmp1 = cln(tmp3, epsilon);
|
||||
comfree(tmp3);
|
||||
tmp2 = cscale(tmp1, -1);
|
||||
comfree(tmp1);
|
||||
return tmp2;
|
||||
}
|
||||
|
||||
COMPLEX *
|
||||
casech(COMPLEX *c, NUMBER *epsilon)
|
||||
{
|
||||
COMPLEX *tmp1, *tmp2;
|
||||
|
||||
tmp1 = cinv(c);
|
||||
tmp2 = cacosh(tmp1, epsilon);
|
||||
comfree(tmp1);
|
||||
return tmp2;
|
||||
}
|
||||
|
||||
COMPLEX *
|
||||
cacsch(COMPLEX *c, NUMBER *epsilon)
|
||||
{
|
||||
COMPLEX *tmp1, *tmp2;
|
||||
|
||||
tmp1 = cinv(c);
|
||||
tmp2 = casinh(tmp1, epsilon);
|
||||
comfree(tmp1);
|
||||
return tmp2;
|
||||
}
|
||||
|
||||
|
||||
COMPLEX *
|
||||
cgd(COMPLEX *c, NUMBER *epsilon)
|
||||
{
|
||||
COMPLEX *tmp1, *tmp2, *tmp3;
|
||||
NUMBER *q1, *q2;
|
||||
NUMBER *sin, *cos;
|
||||
NUMBER *eps;
|
||||
int n, n1;
|
||||
BOOL neg;
|
||||
|
||||
if (cisreal(c)) {
|
||||
q1 = qscale(c->real, -1);
|
||||
eps = qscale(epsilon, -1);
|
||||
q2 = qtanh(q1, eps);
|
||||
qfree(q1);
|
||||
q1 = qatan(q2, eps);
|
||||
qfree(eps);
|
||||
qfree(q2);
|
||||
tmp1 = comalloc();
|
||||
qfree(tmp1->real);
|
||||
tmp1->real = qscale(q1, 1);
|
||||
qfree(q1);
|
||||
return tmp1;
|
||||
}
|
||||
if (qiszero(c->real)) {
|
||||
n = - qilog2(epsilon);
|
||||
qsincos(c->imag, n + 8, &sin, &cos);
|
||||
if (qiszero(cos) || (n1 = -qilog2(cos)) > n) {
|
||||
qfree(sin);
|
||||
qfree(cos);
|
||||
return NULL;
|
||||
}
|
||||
neg = qisneg(sin);
|
||||
q1 = neg ? qsub(&_qone_, sin) : qqadd(&_qone_, sin);
|
||||
qfree(sin);
|
||||
if (n1 > 8) {
|
||||
qfree(q1);
|
||||
qfree(cos);
|
||||
qsincos(c->imag, n + n1, &sin, &cos);
|
||||
q1 = neg ? qsub(&_qone_, sin) : qqadd(&_qone_, sin);
|
||||
qfree(sin);
|
||||
}
|
||||
q2 = qqdiv(q1, cos);
|
||||
qfree(q1);
|
||||
q1 = qln(q2, epsilon);
|
||||
qfree(q2);
|
||||
if (neg) {
|
||||
q2 = qneg(q1);
|
||||
qfree(q1);
|
||||
q1 = q2;
|
||||
}
|
||||
tmp1 = comalloc();
|
||||
qfree(tmp1->imag);
|
||||
tmp1->imag = q1;
|
||||
if (qisneg(cos)) {
|
||||
qfree(tmp1->real);
|
||||
q1 = qpi(epsilon);
|
||||
if (qisneg(c->imag)) {
|
||||
q2 = qneg(q1);
|
||||
qfree(q1);
|
||||
q1 = q2;
|
||||
}
|
||||
tmp1->real = q1;
|
||||
}
|
||||
qfree(cos);
|
||||
return tmp1;
|
||||
}
|
||||
neg = qisneg(c->real);
|
||||
tmp1 = neg ? cneg(c) : clink(c);
|
||||
tmp2 = cexp(tmp1, epsilon);
|
||||
comfree(tmp1);
|
||||
tmp1 = cmul(&_conei_, tmp2);
|
||||
tmp3 = cadd(&_conei_, tmp2);
|
||||
comfree(tmp2);
|
||||
tmp2 = cadd(tmp1, &_cone_);
|
||||
comfree(tmp1);
|
||||
if (ciszero(tmp2) || ciszero(tmp3)) {
|
||||
comfree(tmp2);
|
||||
comfree(tmp3);
|
||||
return NULL;
|
||||
}
|
||||
tmp1 = cdiv(tmp2, tmp3);
|
||||
comfree(tmp2);
|
||||
comfree(tmp3);
|
||||
tmp2 = cln(tmp1, epsilon);
|
||||
comfree(tmp1);
|
||||
tmp1 = cdiv(tmp2, &_conei_);
|
||||
comfree(tmp2);
|
||||
if (neg) {
|
||||
tmp2 = cneg(tmp1);
|
||||
comfree(tmp1);
|
||||
return tmp2;
|
||||
}
|
||||
return tmp1;
|
||||
}
|
||||
|
||||
|
||||
COMPLEX *
|
||||
cagd(COMPLEX *c, NUMBER *epsilon)
|
||||
{
|
||||
COMPLEX *tmp1, *tmp2;
|
||||
|
||||
tmp1 = cmul(&_conei_, c);
|
||||
tmp2 = cgd(tmp1, epsilon);
|
||||
comfree(tmp1);
|
||||
if (tmp2 == NULL)
|
||||
return NULL;
|
||||
tmp1 = cdiv(tmp2, &_conei_);
|
||||
comfree(tmp2);
|
||||
return tmp1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Convert a number from polar coordinates to normal complex number form
|
||||
* within the specified accuracy. This produces the value:
|
||||
@@ -625,16 +1005,19 @@ cpolar(NUMBER *q1, NUMBER *q2, NUMBER *epsilon)
|
||||
return qlink(&_czero_);
|
||||
r = comalloc();
|
||||
if (qiszero(q2)) {
|
||||
qfree(r->real);
|
||||
r->real = qlink(q1);
|
||||
return r;
|
||||
}
|
||||
qsincos(q2, m - n + 2, &sin, &cos);
|
||||
tmp = qmul(q1, cos);
|
||||
qfree(cos);
|
||||
qfree(r->real);
|
||||
r->real = qmappr(tmp, epsilon, 24L);
|
||||
qfree(tmp);
|
||||
tmp = qmul(q1, sin);
|
||||
qfree(sin);
|
||||
qfree(r->imag);
|
||||
r->imag = qmappr(tmp, epsilon, 24L);
|
||||
qfree(tmp);
|
||||
return r;
|
||||
@@ -666,12 +1049,12 @@ cpower(COMPLEX *c1, COMPLEX *c2, NUMBER *epsilon)
|
||||
n = qilog2(epsilon);
|
||||
m1 = m2 = -1000000;
|
||||
k1 = k2 = 0;
|
||||
qtmp1 = qsquare(c1->real);
|
||||
qtmp2 = qsquare(c1->imag);
|
||||
a2b2 = qqadd(qtmp1, qtmp2);
|
||||
qfree(qtmp1);
|
||||
qfree(qtmp2);
|
||||
if (!qiszero(c2->real)) {
|
||||
qtmp1 = qsquare(c1->real);
|
||||
qtmp2 = qsquare(c1->imag);
|
||||
a2b2 = qqadd(qtmp1, qtmp2);
|
||||
qfree(qtmp1);
|
||||
qfree(qtmp2);
|
||||
m1 = qilog2(c2->real);
|
||||
epsilon1 = qbitvalue(-m1 - 1);
|
||||
qtmp1 = qln(a2b2, epsilon1);
|
||||
|
102
commath.c
102
commath.c
@@ -29,10 +29,14 @@ cadd(COMPLEX *c1, COMPLEX *c2)
|
||||
if (ciszero(c2))
|
||||
return clink(c1);
|
||||
r = comalloc();
|
||||
if (!qiszero(c1->real) || !qiszero(c2->real))
|
||||
if (!qiszero(c1->real) || !qiszero(c2->real)) {
|
||||
qfree(r->real);
|
||||
r->real = qqadd(c1->real, c2->real);
|
||||
if (!qiszero(c1->imag) || !qiszero(c2->imag))
|
||||
}
|
||||
if (!qiszero(c1->imag) || !qiszero(c2->imag)) {
|
||||
qfree(r->imag);
|
||||
r->imag = qqadd(c1->imag, c2->imag);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -50,10 +54,14 @@ csub(COMPLEX *c1, COMPLEX *c2)
|
||||
if (ciszero(c2))
|
||||
return clink(c1);
|
||||
r = comalloc();
|
||||
if (!qiszero(c1->real) || !qiszero(c2->real))
|
||||
if (!qiszero(c1->real) || !qiszero(c2->real)) {
|
||||
qfree(r->real);
|
||||
r->real = qsub(c1->real, c2->real);
|
||||
if (!qiszero(c1->imag) || !qiszero(c2->imag))
|
||||
}
|
||||
if (!qiszero(c1->imag) || !qiszero(c2->imag)) {
|
||||
qfree(r->imag);
|
||||
r->imag = qsub(c1->imag, c2->imag);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -95,7 +103,9 @@ cmul(COMPLEX *c1, COMPLEX *c2)
|
||||
q2 = qmul(c1->real, c2->real);
|
||||
q3 = qmul(c1->imag, c2->imag);
|
||||
q4 = qqadd(q2, q3);
|
||||
qfree(r->real);
|
||||
r->real = qsub(q2, q3);
|
||||
qfree(r->imag);
|
||||
r->imag = qsub(q1, q4);
|
||||
qfree(q1);
|
||||
qfree(q2);
|
||||
@@ -122,10 +132,12 @@ csquare(COMPLEX *c)
|
||||
return clink(&_cnegone_);
|
||||
r = comalloc();
|
||||
if (cisreal(c)) {
|
||||
qfree(r->real);
|
||||
r->real = qsquare(c->real);
|
||||
return r;
|
||||
}
|
||||
if (cisimag(c)) {
|
||||
qfree(r->real);
|
||||
q1 = qsquare(c->imag);
|
||||
r->real = qneg(q1);
|
||||
qfree(q1);
|
||||
@@ -133,9 +145,11 @@ csquare(COMPLEX *c)
|
||||
}
|
||||
q1 = qsquare(c->real);
|
||||
q2 = qsquare(c->imag);
|
||||
qfree(r->real);
|
||||
r->real = qsub(q1, q2);
|
||||
qfree(q1);
|
||||
qfree(q2);
|
||||
qfree(r->imag);
|
||||
q1 = qmul(c->real, c->imag);
|
||||
r->imag = qscale(q1, 1L);
|
||||
qfree(q1);
|
||||
@@ -160,26 +174,32 @@ cdiv(COMPLEX *c1, COMPLEX *c2)
|
||||
return clink(&_cone_);
|
||||
r = comalloc();
|
||||
if (cisreal(c1) && cisreal(c2)) {
|
||||
r->real = qdiv(c1->real, c2->real);
|
||||
qfree(r->real);
|
||||
r->real = qqdiv(c1->real, c2->real);
|
||||
return r;
|
||||
}
|
||||
if (cisimag(c1) && cisimag(c2)) {
|
||||
r->real = qdiv(c1->imag, c2->imag);
|
||||
qfree(r->real);
|
||||
r->real = qqdiv(c1->imag, c2->imag);
|
||||
return r;
|
||||
}
|
||||
if (cisimag(c1) && cisreal(c2)) {
|
||||
r->imag = qdiv(c1->imag, c2->real);
|
||||
qfree(r->imag);
|
||||
r->imag = qqdiv(c1->imag, c2->real);
|
||||
return r;
|
||||
}
|
||||
if (cisreal(c1) && cisimag(c2)) {
|
||||
q1 = qdiv(c1->real, c2->imag);
|
||||
qfree(r->imag);
|
||||
q1 = qqdiv(c1->real, c2->imag);
|
||||
r->imag = qneg(q1);
|
||||
qfree(q1);
|
||||
return r;
|
||||
}
|
||||
if (cisreal(c2)) {
|
||||
r->real = qdiv(c1->real, c2->real);
|
||||
r->imag = qdiv(c1->imag, c2->real);
|
||||
qfree(r->real);
|
||||
qfree(r->imag);
|
||||
r->real = qqdiv(c1->real, c2->real);
|
||||
r->imag = qqdiv(c1->imag, c2->real);
|
||||
return r;
|
||||
}
|
||||
q1 = qsquare(c2->real);
|
||||
@@ -192,14 +212,16 @@ cdiv(COMPLEX *c1, COMPLEX *c2)
|
||||
q3 = qqadd(q1, q2);
|
||||
qfree(q1);
|
||||
qfree(q2);
|
||||
r->real = qdiv(q3, den);
|
||||
qfree(r->real);
|
||||
r->real = qqdiv(q3, den);
|
||||
qfree(q3);
|
||||
q1 = qmul(c1->real, c2->imag);
|
||||
q2 = qmul(c1->imag, c2->real);
|
||||
q3 = qsub(q2, q1);
|
||||
qfree(q1);
|
||||
qfree(q2);
|
||||
r->imag = qdiv(q3, den);
|
||||
qfree(r->imag);
|
||||
r->imag = qqdiv(q3, den);
|
||||
qfree(q3);
|
||||
qfree(den);
|
||||
return r;
|
||||
@@ -221,11 +243,13 @@ cinv(COMPLEX *c)
|
||||
}
|
||||
r = comalloc();
|
||||
if (cisreal(c)) {
|
||||
qfree(r->real);
|
||||
r->real = qinv(c->real);
|
||||
return r;
|
||||
}
|
||||
if (cisimag(c)) {
|
||||
q1 = qinv(c->imag);
|
||||
qfree(r->imag);
|
||||
r->imag = qneg(q1);
|
||||
qfree(q1);
|
||||
return r;
|
||||
@@ -235,8 +259,10 @@ cinv(COMPLEX *c)
|
||||
den = qqadd(q1, q2);
|
||||
qfree(q1);
|
||||
qfree(q2);
|
||||
r->real = qdiv(c->real, den);
|
||||
q1 = qdiv(c->imag, den);
|
||||
qfree(r->real);
|
||||
r->real = qqdiv(c->real, den);
|
||||
q1 = qqdiv(c->imag, den);
|
||||
qfree(r->imag);
|
||||
r->imag = qneg(q1);
|
||||
qfree(q1);
|
||||
qfree(den);
|
||||
@@ -255,10 +281,14 @@ cneg(COMPLEX *c)
|
||||
if (ciszero(c))
|
||||
return clink(&_czero_);
|
||||
r = comalloc();
|
||||
if (!qiszero(c->real))
|
||||
if (!qiszero(c->real)) {
|
||||
qfree(r->real);
|
||||
r->real = qneg(c->real);
|
||||
if (!qiszero(c->imag))
|
||||
}
|
||||
if (!qiszero(c->imag)) {
|
||||
qfree(r->imag);
|
||||
r->imag = qneg(c->imag);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -275,7 +305,9 @@ cint(COMPLEX *c)
|
||||
if (cisint(c))
|
||||
return clink(c);
|
||||
r = comalloc();
|
||||
qfree(r->real);
|
||||
r->real = qint(c->real);
|
||||
qfree(r->imag);
|
||||
r->imag = qint(c->imag);
|
||||
return r;
|
||||
}
|
||||
@@ -293,7 +325,9 @@ cfrac(COMPLEX *c)
|
||||
if (cisint(c))
|
||||
return clink(&_czero_);
|
||||
r = comalloc();
|
||||
qfree(r->real);
|
||||
r->real = qfrac(c->real);
|
||||
qfree(r->imag);
|
||||
r->imag = qfrac(c->imag);
|
||||
return r;
|
||||
}
|
||||
@@ -311,8 +345,11 @@ cconj(COMPLEX *c)
|
||||
if (cisreal(c))
|
||||
return clink(c);
|
||||
r = comalloc();
|
||||
if (!qiszero(c->real))
|
||||
if (!qiszero(c->real)) {
|
||||
qfree(r->real);
|
||||
r->real = qlink(c->real);
|
||||
}
|
||||
qfree(r->imag);
|
||||
r->imag = qneg(c->imag);
|
||||
return r;
|
||||
}
|
||||
@@ -329,8 +366,10 @@ creal(COMPLEX *c)
|
||||
if (cisreal(c))
|
||||
return clink(c);
|
||||
r = comalloc();
|
||||
if (!qiszero(c->real))
|
||||
if (!qiszero(c->real)) {
|
||||
qfree(r->real);
|
||||
r->real = qlink(c->real);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -346,6 +385,7 @@ cimag(COMPLEX *c)
|
||||
if (cisreal(c))
|
||||
return clink(&_czero_);
|
||||
r = comalloc();
|
||||
qfree(r->real);
|
||||
r->real = qlink(c->imag);
|
||||
return r;
|
||||
}
|
||||
@@ -362,6 +402,8 @@ caddq(COMPLEX *c, NUMBER *q)
|
||||
if (qiszero(q))
|
||||
return clink(c);
|
||||
r = comalloc();
|
||||
qfree(r->real);
|
||||
qfree(r->imag);
|
||||
r->real = qqadd(c->real, q);
|
||||
r->imag = qlink(c->imag);
|
||||
return r;
|
||||
@@ -379,6 +421,8 @@ csubq(COMPLEX *c, NUMBER *q)
|
||||
if (qiszero(q))
|
||||
return clink(c);
|
||||
r = comalloc();
|
||||
qfree(r->real);
|
||||
qfree(r->imag);
|
||||
r->real = qsub(c->real, q);
|
||||
r->imag = qlink(c->imag);
|
||||
return r;
|
||||
@@ -397,6 +441,8 @@ cshift(COMPLEX *c, long n)
|
||||
if (ciszero(c) || (n == 0))
|
||||
return clink(c);
|
||||
r = comalloc();
|
||||
qfree(r->real);
|
||||
qfree(r->imag);
|
||||
r->real = qshift(c->real, n);
|
||||
r->imag = qshift(c->imag, n);
|
||||
return r;
|
||||
@@ -414,6 +460,8 @@ cscale(COMPLEX *c, long n)
|
||||
if (ciszero(c) || (n == 0))
|
||||
return clink(c);
|
||||
r = comalloc();
|
||||
qfree(r->real);
|
||||
qfree(r->imag);
|
||||
r->real = qscale(c->real, n);
|
||||
r->imag = qscale(c->imag, n);
|
||||
return r;
|
||||
@@ -435,6 +483,8 @@ cmulq(COMPLEX *c, NUMBER *q)
|
||||
if (qisnegone(q))
|
||||
return cneg(c);
|
||||
r = comalloc();
|
||||
qfree(r->real);
|
||||
qfree(r->imag);
|
||||
r->real = qmul(c->real, q);
|
||||
r->imag = qmul(c->imag, q);
|
||||
return r;
|
||||
@@ -458,8 +508,10 @@ cdivq(COMPLEX *c, NUMBER *q)
|
||||
if (qisnegone(q))
|
||||
return cneg(c);
|
||||
r = comalloc();
|
||||
r->real = qdiv(c->real, q);
|
||||
r->imag = qdiv(c->imag, q);
|
||||
qfree(r->real);
|
||||
qfree(r->imag);
|
||||
r->real = qqdiv(c->real, q);
|
||||
r->imag = qqdiv(c->imag, q);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -477,10 +529,10 @@ qqtoc(NUMBER *q1, NUMBER *q2)
|
||||
if (qiszero(q1) && qiszero(q2))
|
||||
return clink(&_czero_);
|
||||
r = comalloc();
|
||||
if (!qiszero(q1))
|
||||
r->real = qlink(q1);
|
||||
if (!qiszero(q2))
|
||||
r->imag = qlink(q2);
|
||||
qfree(r->real);
|
||||
qfree(r->imag);
|
||||
r->real = qlink(q1);
|
||||
r->imag = qlink(q2);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -512,6 +564,8 @@ crel(COMPLEX *c1, COMPLEX *c2)
|
||||
COMPLEX *c;
|
||||
|
||||
c = comalloc();
|
||||
qfree(c->real);
|
||||
qfree(c->imag);
|
||||
c->real = itoq((long) qrel(c1->real, c2->real));
|
||||
c->imag = itoq((long) qrel(c1->imag, c2->imag));
|
||||
|
||||
|
307
config.c
307
config.c
@@ -1,14 +1,19 @@
|
||||
/*
|
||||
* Copyright (c) 1995 David I. Bell
|
||||
* Copyright (c) 1997 David I. Bell
|
||||
* Permission is granted to use, distribute, or modify this source,
|
||||
* provided that this copyright notice remains intact.
|
||||
*
|
||||
* Configuration routines.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "calc.h"
|
||||
#include "token.h"
|
||||
#include "zrand.h"
|
||||
#include "block.h"
|
||||
#include "nametype.h"
|
||||
#include "config.h"
|
||||
#include "string.h"
|
||||
|
||||
|
||||
/*
|
||||
@@ -39,10 +44,17 @@ NAMETYPE configs[] = {
|
||||
{"round", CONFIG_ROUND},
|
||||
{"leadzero", CONFIG_LEADZERO},
|
||||
{"fullzero", CONFIG_FULLZERO},
|
||||
{"maxerr", CONFIG_MAXERR},
|
||||
{"maxscan", CONFIG_MAXSCAN},
|
||||
{"maxerr", CONFIG_MAXSCAN}, /* old name for maxscan */
|
||||
{"prompt", CONFIG_PROMPT},
|
||||
{"more", CONFIG_MORE},
|
||||
{"random", CONFIG_RANDOM},
|
||||
{"blkmaxprint", CONFIG_BLKMAXPRINT},
|
||||
{"blkverbose", CONFIG_BLKVERBOSE},
|
||||
{"blkbase", CONFIG_BLKBASE},
|
||||
{"blkfmt", CONFIG_BLKFMT},
|
||||
{"lib_debug", CONFIG_LIB_DEBUG},
|
||||
{"calc_debug", CONFIG_CALC_DEBUG},
|
||||
{"user_debug", CONFIG_USER_DEBUG},
|
||||
{NULL, 0}
|
||||
};
|
||||
|
||||
@@ -74,10 +86,16 @@ CONFIG oldstd = { /* backward compatible standard configuration */
|
||||
24, /* round()/bround() default rounding mode */
|
||||
FALSE, /* ok to print leading 0 before decimal pt */
|
||||
0, /* ok to print trailing 0's */
|
||||
MAXERRORCOUNT, /* max errors before abort */
|
||||
MAXSCANCOUNT, /* max scan errors before abort */
|
||||
PROMPT1, /* normal prompt */
|
||||
PROMPT2, /* prompt when inside multi-line input */
|
||||
3 /* require 1 mod 4 and to pass ptest(newn,1) */
|
||||
BLK_DEF_MAXPRINT, /* number of octets of a block to print */
|
||||
FALSE, /* skip duplicate block output lines */
|
||||
BLK_BASE_HEX, /* block octet print base */
|
||||
BLK_FMT_HD_STYLE, /* block output format */
|
||||
3, /* calc library debug level */
|
||||
0, /* internal calc debug level */
|
||||
0 /* user defined debug level */
|
||||
};
|
||||
CONFIG newstd = { /* new non-backward compatible configuration */
|
||||
MODE_INITIAL, /* current output mode */
|
||||
@@ -103,10 +121,16 @@ CONFIG newstd = { /* new non-backward compatible configuration */
|
||||
24, /* round()/bround() default rounding mode */
|
||||
TRUE, /* ok to print leading 0 before decimal pt */
|
||||
1, /* ok to print trailing 0's */
|
||||
MAXERRORCOUNT, /* max errors before abort */
|
||||
MAXSCANCOUNT, /* max scan errors before abort */
|
||||
"; ", /* normal prompt */
|
||||
";; ", /* prompt when inside multi-line input */
|
||||
3 /* require 1 mod 4 and to pass ptest(newn,1) */
|
||||
BLK_DEF_MAXPRINT, /* number of octets of a block to print */
|
||||
FALSE, /* skip duplicate block output lines */
|
||||
BLK_BASE_HEX, /* block octet print base */
|
||||
BLK_FMT_HD_STYLE, /* block output format */
|
||||
3, /* calc library debug level */
|
||||
0, /* internal calc debug level */
|
||||
0 /* user defined debug level */
|
||||
};
|
||||
CONFIG *conf = NULL; /* loaded in at startup - current configuration */
|
||||
|
||||
@@ -153,10 +177,49 @@ static NAMETYPE truth[] = {
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Possible block base output modes
|
||||
*/
|
||||
static NAMETYPE blk_base[] = {
|
||||
{"hexadecimal", BLK_BASE_HEX},
|
||||
{"hex", BLK_BASE_HEX},
|
||||
{"octal", BLK_BASE_OCT},
|
||||
{"oct", BLK_BASE_OCT},
|
||||
{"character", BLK_BASE_CHAR},
|
||||
{"char", BLK_BASE_CHAR},
|
||||
{"binary", BLK_BASE_BINARY},
|
||||
{"bin", BLK_BASE_BINARY},
|
||||
{"raw", BLK_BASE_RAW},
|
||||
{"none", BLK_BASE_RAW},
|
||||
{NULL, 0}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Possible block output formats
|
||||
*/
|
||||
static NAMETYPE blk_fmt[] = {
|
||||
{"line", BLK_FMT_LINE},
|
||||
{"lines", BLK_FMT_LINE},
|
||||
{"str", BLK_FMT_STRING},
|
||||
{"string", BLK_FMT_STRING},
|
||||
{"strings", BLK_FMT_STRING},
|
||||
{"od", BLK_FMT_OD_STYLE},
|
||||
{"odstyle", BLK_FMT_OD_STYLE},
|
||||
{"od_style", BLK_FMT_OD_STYLE},
|
||||
{"hd", BLK_FMT_HD_STYLE},
|
||||
{"hdstyle", BLK_FMT_HD_STYLE},
|
||||
{"hd_style", BLK_FMT_HD_STYLE},
|
||||
{NULL, 0}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* declate static functions
|
||||
*/
|
||||
static int modetype(char *name);
|
||||
static int blkbase(char *name);
|
||||
static int blkfmt(char *name);
|
||||
static int truthtype(char *name);
|
||||
static char *modename(int type);
|
||||
|
||||
@@ -202,6 +265,46 @@ modetype(char *name)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Given the name of a block output base, convert it to the internal format.
|
||||
* Returns -1 if the string is unknown.
|
||||
*
|
||||
* given:
|
||||
* name mode name
|
||||
*/
|
||||
static int
|
||||
blkbase(char *name)
|
||||
{
|
||||
NAMETYPE *cp; /* current config pointer */
|
||||
|
||||
for (cp = blk_base; cp->name; cp++) {
|
||||
if (strcmp(cp->name, name) == 0)
|
||||
return cp->type;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Given the name of a block output format, convert it to the internal format.
|
||||
* Returns -1 if the string is unknown.
|
||||
*
|
||||
* given:
|
||||
* name mode name
|
||||
*/
|
||||
static int
|
||||
blkfmt(char *name)
|
||||
{
|
||||
NAMETYPE *cp; /* current config pointer */
|
||||
|
||||
for (cp = blk_fmt; cp->name; cp++) {
|
||||
if (strcmp(cp->name, name) == 0)
|
||||
return cp->type;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Given the name of a truth value, convert it to a BOOL or -1.
|
||||
* Returns -1 if the string is unknown.
|
||||
@@ -257,9 +360,9 @@ setconfig(int type, VALUE *vp)
|
||||
case CONFIG_ALL:
|
||||
newconf = NULL; /* firewall */
|
||||
if (vp->v_type == V_STR) {
|
||||
if (strcmp(vp->v_str, "oldstd") == 0) {
|
||||
if (strcmp(vp->v_str->s_str, "oldstd") == 0) {
|
||||
newconf = &oldstd;
|
||||
} else if (strcmp(vp->v_str, "newstd") == 0) {
|
||||
} else if (strcmp(vp->v_str->s_str, "newstd") == 0) {
|
||||
newconf = &newstd;
|
||||
} else {
|
||||
math_error("CONFIG alias not oldstd or newstd");
|
||||
@@ -311,7 +414,7 @@ setconfig(int type, VALUE *vp)
|
||||
math_error("Non-string for mode");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
temp = modetype(vp->v_str);
|
||||
temp = modetype(vp->v_str->s_str);
|
||||
if (temp < 0) {
|
||||
math_error("Unknown mode \"%s\"", vp->v_str);
|
||||
/*NOTREACHED*/
|
||||
@@ -415,15 +518,14 @@ setconfig(int type, VALUE *vp)
|
||||
conf->redc2 = (int)temp;
|
||||
break;
|
||||
|
||||
|
||||
case CONFIG_TILDE:
|
||||
if (vp->v_type == V_NUM) {
|
||||
q = vp->v_num;
|
||||
conf->tilde_ok = !qiszero(q);
|
||||
} else if (vp->v_type == V_STR) {
|
||||
temp = truthtype(vp->v_str);
|
||||
temp = truthtype(vp->v_str->s_str);
|
||||
if (temp < 0) {
|
||||
math_error("Illegal truth value");
|
||||
math_error("Illegal truth value for tilde");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
conf->tilde_ok = (int)temp;
|
||||
@@ -435,9 +537,9 @@ setconfig(int type, VALUE *vp)
|
||||
q = vp->v_num;
|
||||
conf->tab_ok = !qiszero(q);
|
||||
} else if (vp->v_type == V_STR) {
|
||||
temp = truthtype(vp->v_str);
|
||||
temp = truthtype(vp->v_str->s_str);
|
||||
if (temp < 0) {
|
||||
math_error("Illegal truth value");
|
||||
math_error("Illegal truth value for tab");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
conf->tab_ok = (int)temp;
|
||||
@@ -575,9 +677,9 @@ setconfig(int type, VALUE *vp)
|
||||
q = vp->v_num;
|
||||
conf->leadzero = !qiszero(q);
|
||||
} else if (vp->v_type == V_STR) {
|
||||
temp = truthtype(vp->v_str);
|
||||
temp = truthtype(vp->v_str->s_str);
|
||||
if (temp < 0) { {
|
||||
math_error("Illegal truth value");
|
||||
math_error("Illegal truth value for leadzero");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
}
|
||||
@@ -590,9 +692,9 @@ setconfig(int type, VALUE *vp)
|
||||
q = vp->v_num;
|
||||
conf->fullzero = !qiszero(q);
|
||||
} else if (vp->v_type == V_STR) {
|
||||
temp = truthtype(vp->v_str);
|
||||
temp = truthtype(vp->v_str->s_str);
|
||||
if (temp < 0) { {
|
||||
math_error("Illegal truth value");
|
||||
math_error("Illegal truth value for fullzero");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
}
|
||||
@@ -600,9 +702,9 @@ setconfig(int type, VALUE *vp)
|
||||
}
|
||||
break;
|
||||
|
||||
case CONFIG_MAXERR:
|
||||
case CONFIG_MAXSCAN:
|
||||
if (vp->v_type != V_NUM) {
|
||||
math_error("Non-numeric for maxerr");
|
||||
math_error("Non-numeric for maxscancount");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
q = vp->v_num;
|
||||
@@ -610,10 +712,10 @@ setconfig(int type, VALUE *vp)
|
||||
if (qisfrac(q) || qisneg(q) || !zistiny(q->num))
|
||||
temp = -1;
|
||||
if (temp < 0) {
|
||||
math_error("Maxerr value is out of range");
|
||||
math_error("Maxscan value is out of range");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
conf->maxerrorcount = temp;
|
||||
conf->maxscancount = temp;
|
||||
break;
|
||||
|
||||
case CONFIG_PROMPT:
|
||||
@@ -621,12 +723,12 @@ setconfig(int type, VALUE *vp)
|
||||
math_error("Non-string for prompt");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
p = (char *)malloc(strlen(vp->v_str) + 1);
|
||||
p = (char *)malloc(vp->v_str->s_len + 1);
|
||||
if (p == NULL) {
|
||||
math_error("Cannot duplicate new prompt");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
strcpy(p, vp->v_str);
|
||||
strcpy(p, vp->v_str->s_str);
|
||||
free(conf->prompt1);
|
||||
conf->prompt1 = p;
|
||||
break;
|
||||
@@ -636,30 +738,114 @@ setconfig(int type, VALUE *vp)
|
||||
math_error("Non-string for more prompt");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
p = (char *)malloc(strlen(vp->v_str) + 1);
|
||||
p = (char *)malloc(vp->v_str->s_len + 1);
|
||||
if (p == NULL) {
|
||||
math_error("Cannot duplicate new more prompt");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
strcpy(p, vp->v_str);
|
||||
strcpy(p, vp->v_str->s_str);
|
||||
free(conf->prompt2);
|
||||
conf->prompt2 = p;
|
||||
break;
|
||||
|
||||
case CONFIG_RANDOM:
|
||||
case CONFIG_BLKMAXPRINT:
|
||||
if (vp->v_type != V_NUM) {
|
||||
math_error("Non-numeric for random config value");
|
||||
math_error("Non-numeric for blkmaxprint");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
q = vp->v_num;
|
||||
temp = qtoi(q);
|
||||
if (qisfrac(q) || qisneg(q) || !zistiny(q->num))
|
||||
temp = -1;
|
||||
if (temp < BLUM_CFG_MIN || temp > BLUM_CFG_MAX) {
|
||||
math_error("Random config value is out of range");
|
||||
if (temp < 0) {
|
||||
math_error("Blkmaxprint value is out of range");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
conf->random = temp;
|
||||
conf->blkmaxprint = temp;
|
||||
break;
|
||||
|
||||
case CONFIG_BLKVERBOSE:
|
||||
if (vp->v_type == V_NUM) {
|
||||
q = vp->v_num;
|
||||
conf->blkverbose = !qiszero(q);
|
||||
} else if (vp->v_type == V_STR) {
|
||||
temp = truthtype(vp->v_str->s_str);
|
||||
if (temp < 0) {
|
||||
math_error("Illegal truth value for blkverbose");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
conf->blkverbose = (int)temp;
|
||||
}
|
||||
break;
|
||||
|
||||
case CONFIG_BLKBASE:
|
||||
if (vp->v_type != V_STR) {
|
||||
math_error("Non-string for blkbase");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
temp = blkbase(vp->v_str->s_str);
|
||||
if (temp < 0) {
|
||||
math_error("Unknown mode \"%s\" for blkbase",
|
||||
vp->v_str->s_str);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
conf->blkbase = temp;
|
||||
break;
|
||||
|
||||
case CONFIG_BLKFMT:
|
||||
if (vp->v_type != V_STR) {
|
||||
math_error("Non-string for blkfmt");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
temp = blkfmt(vp->v_str->s_str);
|
||||
if (temp < 0) {
|
||||
math_error("Unknown mode \"%s\" for blkfmt",
|
||||
vp->v_str->s_str);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
conf->blkfmt = temp;
|
||||
break;
|
||||
|
||||
case CONFIG_LIB_DEBUG:
|
||||
if (vp->v_type != V_NUM) {
|
||||
math_error("Non numeric for lib_debug");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
q = vp->v_num;
|
||||
temp = qtoi(q);
|
||||
if (qisfrac(q) || !zistiny(q->num)) {
|
||||
math_error("Illegal lib_debug parameter value");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
conf->lib_debug = temp;
|
||||
break;
|
||||
|
||||
case CONFIG_CALC_DEBUG:
|
||||
if (vp->v_type != V_NUM) {
|
||||
math_error("Non numeric for calc_debug");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
q = vp->v_num;
|
||||
temp = qtoi(q);
|
||||
if (qisfrac(q) || !zistiny(q->num)) {
|
||||
math_error("Illegal calc_debug parameter value");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
conf->calc_debug = temp;
|
||||
break;
|
||||
|
||||
case CONFIG_USER_DEBUG:
|
||||
if (vp->v_type != V_NUM) {
|
||||
math_error("Non numeric for user_debug");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
q = vp->v_num;
|
||||
temp = qtoi(q);
|
||||
if (qisfrac(q) || !zistiny(q->num)) {
|
||||
math_error("Illegal user_debug parameter value");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
conf->user_debug = temp;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -676,7 +862,7 @@ setconfig(int type, VALUE *vp)
|
||||
* src copy this configuration
|
||||
*
|
||||
* returns:
|
||||
* prointer to the configuration copy
|
||||
* pointer to the configuration copy
|
||||
*/
|
||||
CONFIG *
|
||||
config_copy(CONFIG *src)
|
||||
@@ -704,7 +890,7 @@ config_copy(CONFIG *src)
|
||||
/*
|
||||
* copy over the values
|
||||
*/
|
||||
*dest = *src;
|
||||
memcpy((void *)dest, (void *)src, sizeof(CONFIG));
|
||||
|
||||
/*
|
||||
* clone the pointer values
|
||||
@@ -747,7 +933,7 @@ config_free(CONFIG *cfg)
|
||||
}
|
||||
|
||||
/*
|
||||
* free prointer values
|
||||
* free pointer values
|
||||
*/
|
||||
if (cfg->epsilon != NULL) {
|
||||
qfree(cfg->epsilon);
|
||||
@@ -812,8 +998,7 @@ config_value(CONFIG *cfg, int type, VALUE *vp)
|
||||
|
||||
case CONFIG_MODE:
|
||||
vp->v_type = V_STR;
|
||||
vp->v_subtype = V_STRLITERAL;
|
||||
vp->v_str = modename(cfg->outmode);
|
||||
vp->v_str = makenewstring(modename(cfg->outmode));
|
||||
return;
|
||||
|
||||
case CONFIG_EPSILON:
|
||||
@@ -892,24 +1077,46 @@ config_value(CONFIG *cfg, int type, VALUE *vp)
|
||||
i = cfg->fullzero;
|
||||
break;
|
||||
|
||||
case CONFIG_MAXERR:
|
||||
i = cfg->maxerrorcount;
|
||||
case CONFIG_MAXSCAN:
|
||||
i = cfg->maxscancount;
|
||||
break;
|
||||
|
||||
case CONFIG_PROMPT:
|
||||
vp->v_type = V_STR;
|
||||
vp->v_subtype = V_STRLITERAL;
|
||||
vp->v_str = cfg->prompt1;
|
||||
vp->v_str = makenewstring(cfg->prompt1);
|
||||
return;
|
||||
|
||||
case CONFIG_MORE:
|
||||
vp->v_type = V_STR;
|
||||
vp->v_subtype = V_STRLITERAL;
|
||||
vp->v_str = cfg->prompt2;
|
||||
vp->v_str = makenewstring(cfg->prompt2);
|
||||
return;
|
||||
|
||||
case CONFIG_RANDOM:
|
||||
i = cfg->random;
|
||||
case CONFIG_BLKMAXPRINT:
|
||||
i = cfg->blkmaxprint;
|
||||
break;
|
||||
|
||||
case CONFIG_BLKVERBOSE:
|
||||
i = cfg->blkverbose;
|
||||
break;
|
||||
|
||||
case CONFIG_BLKBASE:
|
||||
i = cfg->blkbase;
|
||||
break;
|
||||
|
||||
case CONFIG_BLKFMT:
|
||||
i = cfg->blkfmt;
|
||||
break;
|
||||
|
||||
case CONFIG_LIB_DEBUG:
|
||||
i = cfg->lib_debug;
|
||||
break;
|
||||
|
||||
case CONFIG_CALC_DEBUG:
|
||||
i = cfg->calc_debug;
|
||||
break;
|
||||
|
||||
case CONFIG_USER_DEBUG:
|
||||
i = cfg->user_debug;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -978,8 +1185,14 @@ config_cmp(CONFIG *cfg1, CONFIG *cfg2)
|
||||
cfg1->round != cfg2->round ||
|
||||
cfg1->leadzero != cfg2->leadzero ||
|
||||
cfg1->fullzero != cfg2->fullzero ||
|
||||
cfg1->maxerrorcount != cfg2->maxerrorcount ||
|
||||
cfg1->maxscancount != cfg2->maxscancount ||
|
||||
strcmp(cfg1->prompt1, cfg2->prompt1) != 0 ||
|
||||
strcmp(cfg1->prompt2, cfg2->prompt2) != 0 ||
|
||||
cfg1->random != cfg2->random;
|
||||
cfg1->blkmaxprint != cfg2->blkmaxprint ||
|
||||
cfg1->blkverbose != cfg2->blkverbose ||
|
||||
cfg1->blkbase != cfg2->blkbase ||
|
||||
cfg1->blkfmt != cfg2->blkfmt ||
|
||||
cfg1->lib_debug != cfg2->lib_debug ||
|
||||
cfg1->calc_debug != cfg2->calc_debug ||
|
||||
cfg1->user_debug != cfg2->user_debug;
|
||||
}
|
||||
|
58
config.h
58
config.h
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1995 by Landon Curt Noll. All Rights Reserved.
|
||||
* Copyright (c) 1997 by Landon Curt Noll. All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software and
|
||||
* its documentation for any purpose and without fee is hereby granted,
|
||||
@@ -28,17 +28,18 @@
|
||||
*
|
||||
* Happy bit twiddling,
|
||||
*
|
||||
* Landon Curt Noll
|
||||
* Landon Curt Noll
|
||||
* http://reality.sgi.com/chongo
|
||||
*
|
||||
* chongo@toad.com
|
||||
* ...!{pyramid,sun,uunet}!hoptoad!chongo
|
||||
*
|
||||
* chongo was here /\../\
|
||||
* chongo <was here> /\../\
|
||||
*/
|
||||
|
||||
#if !defined(CONFIG_H)
|
||||
#define CONFIG_H
|
||||
|
||||
#if !defined(__CONFIG_H__)
|
||||
#define __CONFIG_H__
|
||||
|
||||
|
||||
#include "nametype.h"
|
||||
#include "qmath.h"
|
||||
|
||||
|
||||
@@ -69,14 +70,20 @@
|
||||
#define CONFIG_ROUND 20
|
||||
#define CONFIG_LEADZERO 21
|
||||
#define CONFIG_FULLZERO 22
|
||||
#define CONFIG_MAXERR 23
|
||||
#define CONFIG_MAXSCAN 23
|
||||
#define CONFIG_PROMPT 24
|
||||
#define CONFIG_MORE 25
|
||||
#define CONFIG_RANDOM 26
|
||||
#define CONFIG_BLKMAXPRINT 26
|
||||
#define CONFIG_BLKVERBOSE 27
|
||||
#define CONFIG_BLKBASE 28
|
||||
#define CONFIG_BLKFMT 29
|
||||
#define CONFIG_LIB_DEBUG 30
|
||||
#define CONFIG_CALC_DEBUG 31
|
||||
#define CONFIG_USER_DEBUG 32
|
||||
|
||||
|
||||
/*
|
||||
* config defult symbols
|
||||
* config default symbols
|
||||
*/
|
||||
#define DISPLAY_DEFAULT 20 /* default digits for float display */
|
||||
#define EPSILON_DEFAULT "1e-20" /* allowed error for float calculations */
|
||||
@@ -84,11 +91,17 @@
|
||||
#define NEW_EPSILON_DEFAULT "1e-10" /* newstd EPSILON_DEFAULT */
|
||||
#define NEW_EPSILONPREC_DEFAULT 34 /* 34 ==> 2^-34 <= 1e-10 < 2^-33 */
|
||||
#define MAXPRINT_DEFAULT 16 /* default number of elements printed */
|
||||
#define MAXERRORCOUNT 20 /* default max errors before an abort */
|
||||
#define MAXSCANCOUNT 20 /* default max scan errors before an abort */
|
||||
|
||||
|
||||
/*
|
||||
* configuration object
|
||||
*
|
||||
* If you add elements to this structure, you need to also update:
|
||||
*
|
||||
* quickhash.c - config_hash()
|
||||
* hash.c - hash_value()
|
||||
* config.c - setconfig(), config_value(), config_cmp()
|
||||
*/
|
||||
struct config {
|
||||
int outmode; /* current output mode */
|
||||
@@ -113,11 +126,17 @@ struct config {
|
||||
long outround; /* output default rounding mode */
|
||||
long round; /* round()/bround() default rounding mode */
|
||||
int leadzero; /* ok to print leading 0 before decimal pt */
|
||||
int fullzero; /* ok to print trailing 0's -- XXX ??? */
|
||||
long maxerrorcount; /* max errors before abort */
|
||||
int fullzero; /* ok to print trailing 0's */
|
||||
long maxscancount; /* max scan errors before abort */
|
||||
char *prompt1; /* normal prompt */
|
||||
char *prompt2; /* prompt when inside multi-line input */
|
||||
int random; /* random mode */
|
||||
int blkmaxprint; /* octets of a block to print, 0 => all */
|
||||
int blkverbose; /* TRUE => print all lines if a block */
|
||||
int blkbase; /* block output base */
|
||||
int blkfmt; /* block output style */
|
||||
int lib_debug; /* library debug: <0 none, 0 default, >0 more */
|
||||
int calc_debug; /* internal debug: <0 none, 0 default,>0 more */
|
||||
int user_debug; /* user defined debug value: 0 default */
|
||||
};
|
||||
typedef struct config CONFIG;
|
||||
|
||||
@@ -131,13 +150,14 @@ extern CONFIG newstd; /* new non-backward compatible configuration */
|
||||
|
||||
|
||||
/*
|
||||
* configuration functions
|
||||
* configuration externals
|
||||
*/
|
||||
extern CONFIG *config_copy(CONFIG *src);
|
||||
extern void config_free(CONFIG *cfg);
|
||||
extern void config_print(CONFIG *cfg);
|
||||
extern BOOL config_cmp(CONFIG *cfg1, CONFIG *cfg2);
|
||||
extern int configtype(char *name);
|
||||
extern int configtype(char*);
|
||||
extern void config_print(CONFIG*);
|
||||
extern BOOL config_cmp(CONFIG*, CONFIG*);
|
||||
|
||||
|
||||
#endif
|
||||
#endif /* !__CONFIG_H__ */
|
||||
|
167
const.c
167
const.c
@@ -1,27 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 1993 David I. Bell
|
||||
* Copyright (c) 1997 David I. Bell
|
||||
* Permission is granted to use, distribute, or modify this source,
|
||||
* provided that this copyright notice remains intact.
|
||||
*
|
||||
* Constant number storage module.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "calc.h"
|
||||
#include "qmath.h"
|
||||
|
||||
#define CONSTALLOCSIZE 400 /* number of constants to allocate */
|
||||
|
||||
|
||||
static long constcount; /* number of constants defined */
|
||||
static long constavail; /* number of constants available */
|
||||
static NUMBER **consttable; /* table of constants */
|
||||
|
||||
|
||||
void
|
||||
initconstants(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
consttable = (NUMBER **) malloc(sizeof(NUMBER *) * CONSTALLOCSIZE);
|
||||
if (consttable == NULL) {
|
||||
math_error("Unable to allocate constant table");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
for (i = 0; i < INITCONSTCOUNT; i++)
|
||||
consttable[i] = initnumbs[i];
|
||||
consttable[INITCONSTCOUNT] = NULL; /* firewall */
|
||||
constcount = INITCONSTCOUNT;
|
||||
constavail = CONSTALLOCSIZE - INITCONSTCOUNT;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read in a constant number and add it to the table of constant numbers,
|
||||
* Read in a literal real number and add it to the table of constant numbers,
|
||||
* creating a new entry if necessary. The incoming number is a string
|
||||
* value which must have a correct format, otherwise an undefined number
|
||||
* will result. Returns the index of the number in the constant table.
|
||||
* Returns zero if the number could not be saved.
|
||||
* value which must have a correct format.
|
||||
* Returns the index of the number in the constant table.
|
||||
*
|
||||
* given:
|
||||
* str string representation of number
|
||||
@@ -32,8 +50,6 @@ addnumber(char *str)
|
||||
NUMBER *q;
|
||||
|
||||
q = str2q(str);
|
||||
if (q == NULL)
|
||||
return 0;
|
||||
return addqconstant(q);
|
||||
}
|
||||
|
||||
@@ -59,14 +75,53 @@ addqconstant(NUMBER *q)
|
||||
long denlen; /* denominator length */
|
||||
HALF numlow; /* bottom value of numerator */
|
||||
HALF denlow; /* bottom value of denominator */
|
||||
long first; /* first non-null position found */
|
||||
BOOL havefirst;
|
||||
|
||||
if (constavail <= 0) {
|
||||
if (consttable == NULL) {
|
||||
initconstants();
|
||||
} else {
|
||||
tp = (NUMBER **) realloc((char *) consttable,
|
||||
sizeof(NUMBER *) * (constcount + CONSTALLOCSIZE));
|
||||
if (tp == NULL) {
|
||||
math_error("Unable to reallocate const table");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
consttable = tp;
|
||||
constavail = CONSTALLOCSIZE;
|
||||
}
|
||||
}
|
||||
numlen = q->num.len;
|
||||
denlen = q->den.len;
|
||||
numlow = q->num.v[0];
|
||||
denlow = q->den.v[0];
|
||||
tp = &consttable[1];
|
||||
for (index = 1; index <= constcount; index++) {
|
||||
t = *tp++;
|
||||
first = 0;
|
||||
havefirst = FALSE;
|
||||
tp = consttable;
|
||||
for (index = 0; index < constcount; index++, tp++) {
|
||||
t = *tp;
|
||||
if (t->links == 0) {
|
||||
if (!havefirst) {
|
||||
havefirst = TRUE;
|
||||
first = index;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (q == t) {
|
||||
if (q->links == 1) {
|
||||
if (havefirst) {
|
||||
*tp = consttable[first];
|
||||
consttable[first] = q;
|
||||
} else {
|
||||
havefirst = TRUE;
|
||||
first = index;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
if ((numlen != t->num.len) || (numlow != t->num.v[0]))
|
||||
continue;
|
||||
if ((denlen != t->den.len) || (denlow != t->den.v[0]))
|
||||
@@ -74,40 +129,94 @@ addqconstant(NUMBER *q)
|
||||
if (q->num.sign != t->num.sign)
|
||||
continue;
|
||||
if (qcmp(q, t) == 0) {
|
||||
t->links++;
|
||||
qfree(q);
|
||||
return index;
|
||||
}
|
||||
}
|
||||
if (constavail <= 0) {
|
||||
if (consttable == NULL) {
|
||||
tp = (NUMBER **)
|
||||
malloc(sizeof(NUMBER *) * (CONSTALLOCSIZE + 1));
|
||||
*tp = NULL;
|
||||
} else
|
||||
tp = (NUMBER **) realloc((char *) consttable,
|
||||
sizeof(NUMBER *) * (constcount+CONSTALLOCSIZE + 1));
|
||||
if (tp == NULL)
|
||||
return 0;
|
||||
consttable = tp;
|
||||
constavail = CONSTALLOCSIZE;
|
||||
if (havefirst) {
|
||||
consttable[first] = q;
|
||||
return first;
|
||||
}
|
||||
constavail--;
|
||||
constcount++;
|
||||
consttable[constcount] = q;
|
||||
return constcount;
|
||||
consttable[constcount++] = q;
|
||||
return index;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return the value of a constant number given its index.
|
||||
* Returns address of the number, or NULL if the index is illegal.
|
||||
* Returns address of the number, or NULL if the index is illegal
|
||||
* or points to freed position.
|
||||
*/
|
||||
NUMBER *
|
||||
constvalue(unsigned long index)
|
||||
{
|
||||
if ((index <= 0) || (index > constcount))
|
||||
return NULL;
|
||||
if (index >= constcount) {
|
||||
math_error("Bad index value for constvalue");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
if (consttable[index]->links == 0) {
|
||||
math_error("Constvalue has been freed!!!");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
return consttable[index];
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
freeconstant(unsigned long index)
|
||||
{
|
||||
NUMBER *q;
|
||||
|
||||
if (index >= constcount) {
|
||||
math_error("Bad index value for freeconst");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
q = consttable[index];
|
||||
if (q->links == 0) {
|
||||
math_error("Attempting to free freed const location");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
qfree(q);
|
||||
if (index == constcount - 1) {
|
||||
trimconstants();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
trimconstants(void)
|
||||
{
|
||||
while (constcount > 0 &&
|
||||
(consttable[constcount-1] == NULL ||
|
||||
consttable[constcount-1]->links == 0)) {
|
||||
constcount--;
|
||||
constavail++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
showconstants(void)
|
||||
{
|
||||
long index;
|
||||
NUMBER **qp;
|
||||
long count;
|
||||
|
||||
qp = consttable;
|
||||
count = 0;
|
||||
for (index = 0; index < constcount; index++, qp++) {
|
||||
if ((*qp)->links) {
|
||||
if (!count) {
|
||||
printf("\n Index Links Value\n");
|
||||
}
|
||||
count++;
|
||||
printf("\n%8ld%8ld ", index, (*qp)->links);
|
||||
fitprint(*qp, 40);
|
||||
}
|
||||
}
|
||||
printf("\n\nNumber = %ld\n", count);
|
||||
}
|
||||
|
||||
|
||||
/* END CODE */
|
||||
|
218
custom.c
Normal file
218
custom.c
Normal file
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
* Copyright (c) 1997 by Landon Curt Noll. All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software and
|
||||
* its documentation for any purpose and without fee is hereby granted,
|
||||
* provided that the above copyright, this permission notice and text
|
||||
* this comment, and the disclaimer below appear in all of the following:
|
||||
*
|
||||
* supporting documentation
|
||||
* source copies
|
||||
* source works derived from this source
|
||||
* binaries derived from this source or from derived source
|
||||
*
|
||||
* LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
|
||||
* EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Comments, suggestions, bug fixes and questions about these routines
|
||||
* are welcome. Send EMail to the address given below.
|
||||
*
|
||||
* Happy bit twiddling,
|
||||
*
|
||||
* Landon Curt Noll
|
||||
* http://reality.sgi.com/chongo
|
||||
*
|
||||
* chongo <was here> /\../\
|
||||
*/
|
||||
|
||||
/* these include files are needed regardless of CUSTOM */
|
||||
#include "have_const.h"
|
||||
#include "value.h"
|
||||
#include "custom.h"
|
||||
|
||||
|
||||
#if defined(CUSTOM)
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "calc.h"
|
||||
|
||||
#include "have_string.h"
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
|
||||
#else /* CUSTOM */
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#endif /* CUSTOM */
|
||||
|
||||
int allow_custom = FALSE; /* TRUE => custom builtins allowed */
|
||||
|
||||
|
||||
/*
|
||||
* custom - custom callout function
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
VALUE
|
||||
custom(char *name, int count, VALUE **vals)
|
||||
{
|
||||
#if defined(CUSTOM)
|
||||
|
||||
CONST struct custom *p; /* current function */
|
||||
|
||||
/*
|
||||
* search the custom interface table for a function
|
||||
*/
|
||||
for (p = cust; p->name != NULL; ++p) {
|
||||
|
||||
/* look for the first match */
|
||||
if (strcmp(name, p->name) == 0) {
|
||||
|
||||
/* arg count check */
|
||||
if (count < p->minargs) {
|
||||
math_error("Too few arguments for custom "
|
||||
"function \"%s\"", p->name);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
if (count > p->maxargs) {
|
||||
math_error("Too many arguments for custom "
|
||||
"function \"%s\"", p->name);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
/* call the custom function */
|
||||
return p->func(name, count, vals);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* no such custom function
|
||||
*/
|
||||
return error_value(E_UNK_CUSTOM);
|
||||
|
||||
#else /* CUSTOM */
|
||||
|
||||
fprintf(stderr,
|
||||
"%sCalc was built with custom functions disabled\n",
|
||||
(conf->tab_ok ? "\t" : ""));
|
||||
return error_value(E_NO_CUSTOM);
|
||||
|
||||
#endif /* CUSTOM */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* showcustom - display the names and brief descriptins of custom functions
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
showcustom(void)
|
||||
{
|
||||
#if defined(CUSTOM)
|
||||
|
||||
CONST struct custom *p; /* current function */
|
||||
|
||||
/*
|
||||
* disable custom functions unless -C was given
|
||||
*/
|
||||
if (!allow_custom) {
|
||||
fprintf(stderr,
|
||||
"%sCalc must be run with a -C argument to "
|
||||
"show custom functions\n",
|
||||
(conf->tab_ok ? "\t" : ""));
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* print header
|
||||
*/
|
||||
printf("\nName\tArgs\tDescription\n\n");
|
||||
for (p = cust; p->name != NULL; ++p) {
|
||||
printf("%-9s ", p->name);
|
||||
if (p->maxargs == MAX_CUSTOM_ARGS)
|
||||
printf("%d+ ", p->minargs);
|
||||
else if (p->minargs == p->maxargs)
|
||||
printf("%-6d", p->minargs);
|
||||
else
|
||||
printf("%d-%-4d", p->minargs, p->maxargs);
|
||||
printf("%s\n", p->desc);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
#else /* CUSTOM */
|
||||
|
||||
fprintf(stderr,
|
||||
"%sCalc was built with custom functions disabled\n",
|
||||
(conf->tab_ok ? "\t" : ""));
|
||||
|
||||
#endif /* CUSTOM */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* customhelp - standard help interface to a custom function
|
||||
*
|
||||
* This function assumes that a help file with the same name as
|
||||
* the custom function has been installed by the custom/Makefile
|
||||
* (as listed in the CUSTOM_HELP makefile variable) under the
|
||||
* CUSTOMHELPDIR == HELPDIR/custhelp directory.
|
||||
*
|
||||
* The help command first does a search in HELPDIR and later
|
||||
* in CUSTOMHELPDIR. If a custom help file has the same name
|
||||
* as a file under HELPDIR then help will display the HELPDIR
|
||||
* file and NOT the custom file. This function will ignore
|
||||
* and HELPDIR file and work directly with the custom help file.
|
||||
*
|
||||
* given:
|
||||
* name name of the custom help file to directly access
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
customhelp(char *name)
|
||||
{
|
||||
#if defined(CUSTOM)
|
||||
|
||||
char *customname; /* a string of the form: custom/name */
|
||||
|
||||
/*
|
||||
* firewall
|
||||
*/
|
||||
if (name == NULL) {
|
||||
name = "help";
|
||||
}
|
||||
|
||||
/*
|
||||
* form the custom help name
|
||||
*/
|
||||
customname = (char *)malloc(sizeof("custhelp")+strlen(name)+1);
|
||||
if (customname == NULL) {
|
||||
math_error("bad malloc of customname");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
sprintf(customname, "custhelp/%s", name);
|
||||
|
||||
/*
|
||||
* give help directly to the custom file
|
||||
*/
|
||||
givehelp(customname);
|
||||
|
||||
/*
|
||||
* all done
|
||||
*/
|
||||
free(customname);
|
||||
|
||||
#else /* CUSTOM */
|
||||
|
||||
fprintf(stderr,
|
||||
"%sCalc was built with custom functions disabled\n",
|
||||
(conf->tab_ok ? "\t" : ""));
|
||||
|
||||
#endif /* CUSTOM */
|
||||
}
|
86
custom.h
Normal file
86
custom.h
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 1997 by Landon Curt Noll. All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software and
|
||||
* its documentation for any purpose and without fee is hereby granted,
|
||||
* provided that the above copyright, this permission notice and text
|
||||
* this comment, and the disclaimer below appear in all of the following:
|
||||
*
|
||||
* supporting documentation
|
||||
* source copies
|
||||
* source works derived from this source
|
||||
* binaries derived from this source or from derived source
|
||||
*
|
||||
* LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
|
||||
* EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Prior to calc 2.9.3t9, these routines existed as a calc library called
|
||||
* cryrand.cal. They have been rewritten in C for performance as well
|
||||
* as to make them available directly from libcalc.a.
|
||||
*
|
||||
* Comments, suggestions, bug fixes and questions about these routines
|
||||
* are welcome. Send EMail to the address given below.
|
||||
*
|
||||
* Happy bit twiddling,
|
||||
*
|
||||
* Landon Curt Noll
|
||||
* http://reality.sgi.com/chongo
|
||||
*
|
||||
* chongo <was here> /\../\
|
||||
*/
|
||||
|
||||
/*
|
||||
* Be careful what you put in this file, upper .c files include
|
||||
* this file even when CUSTOM is not defined (ALLOW_CUSTOM is empty).
|
||||
*
|
||||
* Don't include anything, let the including .c file bring in:
|
||||
*
|
||||
* have_const.h
|
||||
* value.h
|
||||
*
|
||||
* before they include this file.
|
||||
*
|
||||
* Keep this file down to a minimum. Don't put custom builtin funcion
|
||||
* stuff in this file!
|
||||
*/
|
||||
|
||||
|
||||
#if !defined(CUSTOM_H)
|
||||
#define CUSTOM_H
|
||||
|
||||
|
||||
/*
|
||||
* arg count definitons
|
||||
*/
|
||||
#define MAX_CUSTOM_ARGS 100 /* maximum number of custom arguments */
|
||||
|
||||
|
||||
/*
|
||||
* custom function interface
|
||||
*/
|
||||
struct custom {
|
||||
char *name; /* name of the custom builtin */
|
||||
char *desc; /* very brief description of custom builtin */
|
||||
short minargs; /* minimum number of arguments */
|
||||
short maxargs; /* maximum number of arguments */
|
||||
VALUE (*func)(char *name, int argc, VALUE **argv); /* custom func */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* external declarations
|
||||
*
|
||||
* These are the required interfaces. The dummy.c stubs these interfaces too.
|
||||
*/
|
||||
extern VALUE custom(char*, int, VALUE**); /* master custom interface */
|
||||
extern int allow_custom; /* TRUE => custom builtins allowed */
|
||||
extern void showcustom(void); /* print custom functions */
|
||||
extern void customhelp(char *); /* direct custom help */
|
||||
extern CONST struct custom cust[]; /* custom interface table */
|
||||
|
||||
#endif /* !CUSTOM_H */
|
51
custom/CUSTOM_CAL
Normal file
51
custom/CUSTOM_CAL
Normal file
@@ -0,0 +1,51 @@
|
||||
#
|
||||
# Copyright (c) 1997 Landon Curt Noll
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software and
|
||||
# its documentation for any purpose and without fee is hereby granted,
|
||||
# provided that the above copyright, this permission notice and text
|
||||
# this comment, and the disclaimer below appear in all of the following:
|
||||
#
|
||||
# supporting documentation
|
||||
# source copies
|
||||
# source works derived from this source
|
||||
# binaries derived from this source or from derived source
|
||||
#
|
||||
# LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
|
||||
# EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
# USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
# chongo was here /\../\ http://reality.sgi.com/chongo
|
||||
|
||||
The following custom calc library files are provided because they serve
|
||||
as examples of how use the custom interface. The custom interface
|
||||
allows for machine dependent and/or non-portable code to be added as
|
||||
builtins to the calc program. A few example custom functions and
|
||||
library files are shipped with calc to provide you with examples.
|
||||
|
||||
By default, the custom builtin returns an error. Calc have been
|
||||
built with:
|
||||
|
||||
ALLOW_CUSTOM= -DCUSTOM
|
||||
|
||||
in the top level Makefile (this is the shipped default) and calc
|
||||
must be invoked with a -C argument:
|
||||
|
||||
calc -C
|
||||
|
||||
when it is run.
|
||||
|
||||
See the ../lib/README or "help stdlib" for information about
|
||||
calc library standards and guidelines.
|
||||
|
||||
=-=
|
||||
|
||||
halflen.cal
|
||||
|
||||
halflen(num)
|
||||
|
||||
Calculate the length of a numeric value in HALF's.
|
606
custom/HOW_TO_ADD
Normal file
606
custom/HOW_TO_ADD
Normal file
@@ -0,0 +1,606 @@
|
||||
Guidelines for adding custom functions
|
||||
|
||||
Step 0: Determine if is should it be done?
|
||||
|
||||
The main focus for calc is to provide a portable platform for
|
||||
multi-precision calculations in a C-like environment. You should
|
||||
consider implementing algorithms in the calc language as a first
|
||||
choice. Sometimes an algorithm requires use of special hardware, a
|
||||
non-portable OS or pre-compiled C library. In these cases a custom
|
||||
interface may be needed.
|
||||
|
||||
The custom function interface is intended to make is easy for
|
||||
programmers to add functionality that would be otherwise
|
||||
un-suitable for general distribution. Functions that are
|
||||
non-portable (machine, hardware or OS dependent) or highly
|
||||
specialized are possible candidates for custom functions.
|
||||
|
||||
So before you go to step 1, ask yourself:
|
||||
|
||||
+ Can I implement this as a calc library script?
|
||||
|
||||
If Yes, write the script and be done with it.
|
||||
If No, continue to the next question ...
|
||||
|
||||
+ Does it require the use of non-portable features,
|
||||
OS specific support or special hardware?
|
||||
|
||||
If No, write it as a regular builtin function.
|
||||
If Yes, continue to step 1 ...
|
||||
|
||||
|
||||
Step 1: Do some background work
|
||||
|
||||
First ... read this file ALL THE WAY THROUGH before implementing
|
||||
anything in Steps 2 and beyond!
|
||||
|
||||
If you are not familiar with calc internals, we recommend that
|
||||
you look at some examples of custom functions. Check out
|
||||
the following source files:
|
||||
|
||||
../custom.c
|
||||
custom.h
|
||||
custtbl.c
|
||||
c_*.[ch]
|
||||
../help/custom
|
||||
|
||||
You would be well advised to look at a more recent calc source
|
||||
such as one available in from the calc alpha test archive.
|
||||
See the following for more details:
|
||||
|
||||
../help/archive
|
||||
|
||||
|
||||
Step 2: Name your custom function
|
||||
|
||||
We suggest that you pick a name that does not conflict with
|
||||
one of the builtin names. It makes it easier to get help
|
||||
via the help interface and avoid confusion down the road.
|
||||
|
||||
You should avoid picking a name that matches a file or
|
||||
directory name under ${HELPDIR} as well. Not all help
|
||||
files are associated with builtin function names.
|
||||
|
||||
For purposes of this file, we will use the name 'curds'
|
||||
as our example custom function name.
|
||||
|
||||
|
||||
Step 3: Document your custom function
|
||||
|
||||
No this step is NOT out of order. We recommend that you write the
|
||||
help file associated with your new custom function EARLY. By
|
||||
experience we have found that the small amount of effort made to
|
||||
write "how the custom function will be used" into a help file pays
|
||||
off in a big way when it comes to coding. Often the effort of
|
||||
writing a help file will clarify fuzzy aspects of your design.
|
||||
Besides, unless you write the help file first, it will likely never
|
||||
be written later on. :-(
|
||||
|
||||
OK ... we will stop preaching now ...
|
||||
|
||||
[[ From now on we will give filenames relative to the custom directory ]]
|
||||
|
||||
Take a look at one of the example custom help files:
|
||||
|
||||
devnull
|
||||
argv
|
||||
help
|
||||
sysinfo
|
||||
|
||||
You can save time by using one of the custom help files
|
||||
as a template. Copy one of these files to your own help file:
|
||||
|
||||
cp sysinfo curds
|
||||
|
||||
and edit it accordingly.
|
||||
|
||||
|
||||
Step 4: Write your test code
|
||||
|
||||
No this step is NOT out of order either. We recommend that you
|
||||
write a simple calc script that will call your custom function and
|
||||
check the results.
|
||||
|
||||
This script will be useful while you are debugging your code. In
|
||||
addition, if you wish to submit your code for distribution, this
|
||||
test code will be an import part of your submission. Your test
|
||||
code will also service as additional for your custom function.
|
||||
|
||||
Coops ... we said we would stop preaching, sorry about that ...
|
||||
|
||||
You can use one of the following as a template:
|
||||
|
||||
argv.cal
|
||||
halflen.cal
|
||||
|
||||
Copy one of these to your own file:
|
||||
|
||||
cp halflen.cal curds.cal
|
||||
|
||||
and exit it accordingly. In particular you will want to:
|
||||
|
||||
remove our header disclaimer (or put your own on)
|
||||
|
||||
change the name from halflen() to curds()
|
||||
|
||||
change the comment from 'halflen - determine the length ...' to
|
||||
'curds - brief description about ...'
|
||||
|
||||
change the print statement near the very bottom from:
|
||||
|
||||
print "halflen(num) defined";
|
||||
|
||||
to:
|
||||
|
||||
print "curds( ... args description here ...) defined";
|
||||
|
||||
|
||||
Step 5: Write your custom function
|
||||
|
||||
By convention, the files we ship that contain custom function
|
||||
interface code in filenames of the form:
|
||||
|
||||
c_*.c
|
||||
|
||||
We suggest that you use filenames of the form:
|
||||
|
||||
u_*.c
|
||||
|
||||
to avoid filename conflicts.
|
||||
|
||||
We recommend that you use one of the c_*.c files as a template.
|
||||
Copy an appropriate file to your file:
|
||||
|
||||
cp c_argv.c u_curds.c
|
||||
|
||||
Before you edit it, you should note that there are several important
|
||||
features of this file.
|
||||
|
||||
a) All of the code in the file is found between #if ... #endif:
|
||||
|
||||
/*
|
||||
* only comments and blank lines at the top
|
||||
*/
|
||||
|
||||
#if defined(CUSTOM)
|
||||
|
||||
... all code, #includes, #defines etc.
|
||||
|
||||
#endif /* CUSTOM */
|
||||
|
||||
This allows this code to 'go away' when the upper Makefile
|
||||
disables the custom code (because ALLOW_CUSTOM no longer
|
||||
has the -DCUSTOM define).
|
||||
|
||||
b) The function type must be:
|
||||
|
||||
/*ARGSUSED*/
|
||||
VALUE
|
||||
u_curds(char *name, int count, VALUE **vals)
|
||||
|
||||
The /*ARGSUSED*/ may be needed if you do not make use
|
||||
of all 3 function parameters.
|
||||
|
||||
The 3 args are passed in by the custom interface
|
||||
and have the following meaning:
|
||||
|
||||
name The name of the custom function that
|
||||
was called. In particular, this is the first
|
||||
string arg that was given to the custom()
|
||||
builtin. This is the equivalent of argv[0] for
|
||||
main() in C programming.
|
||||
|
||||
The same code can be used for multiple custom
|
||||
functions by processing off of this value.
|
||||
|
||||
count This is the number of additional args that
|
||||
was given to the custom() builtin. Note
|
||||
that count does NOT include the name arg.
|
||||
This is similar to argc except that count
|
||||
is one less than the main() argc interface.
|
||||
|
||||
For example, a call of:
|
||||
|
||||
custom("curds", a, b, c)
|
||||
|
||||
would cause count to be passed as 3.
|
||||
|
||||
vals This is a pointer to an array of VALUEs.
|
||||
This is the equivalent of argv+1 for
|
||||
main() in C programming. The difference
|
||||
here is that vals[0] refers to the 1st
|
||||
parameter AFTER the same.
|
||||
|
||||
For example, a call of:
|
||||
|
||||
custom("curds", a, b, c)
|
||||
|
||||
would cause vals to point to the following array:
|
||||
|
||||
vals[0] points to a
|
||||
vals[1] points to b
|
||||
vals[2] points to c
|
||||
|
||||
c) The return value is the function must be a VALUE.
|
||||
|
||||
The typical way to form a VALUE to return is by declaring
|
||||
the following local variable:
|
||||
|
||||
VALUE result; /* what we will return */
|
||||
|
||||
d) You will need to include:
|
||||
|
||||
#if defined(CUSTOM)
|
||||
|
||||
/* any #include <foobar.h> here */
|
||||
|
||||
#include "../have_const.h"
|
||||
#include "../value.h"
|
||||
#include "custom.h"
|
||||
|
||||
Typically these will be included just below any system
|
||||
includes and just below the #if defined(CUSTOM) line.
|
||||
|
||||
To better understand the VALUE type, read:
|
||||
|
||||
../value.h
|
||||
|
||||
The VALUE is a union of major value types found inside calc.
|
||||
The v_type VALUE element determines which union element is
|
||||
being used. Assume that we have:
|
||||
|
||||
VALUE *vp;
|
||||
|
||||
Then the value is determined according to v_type:
|
||||
|
||||
vp->v_type the value is which is a type defined in
|
||||
---------- ------------ ---------- ---------------
|
||||
V_NULL (none) n/a n/a
|
||||
V_INT vp->v_int long n/a
|
||||
V_NUM vp->v_num NUMBER * ../qmath.h
|
||||
V_COM vp->v_com COMPLEX * ../cmath.h
|
||||
V_ADDR vp->v_addr VALUE * ../value.h
|
||||
V_STR vp->v_str char * n/a
|
||||
V_MAT vp->v_mat MATRIX * ../value.h
|
||||
V_LIST vp->v_list LIST * ../value.h
|
||||
V_ASSOC vp->v_assoc ASSOC * ../value.h
|
||||
V_OBJ vp->v_obj OBJECT * ../value.h
|
||||
V_FILE vp->v_file FILEID ../value.h
|
||||
V_RAND vp->v_rand RAND * ../zrand.h
|
||||
V_RANDOM vp->v_random RANDOM * ../zrandom.h
|
||||
V_CONFIG vp->v_config CONFIG * ../config.h
|
||||
V_HASH vp->v_hash HASH * ../hash.h
|
||||
V_BLOCK vp->v_block BLOCK * ../block.h
|
||||
|
||||
The V_OCTET is under review and should not be used at this time.
|
||||
|
||||
There are a number of macros that may be used to determine
|
||||
information about the numerical values (ZVALUE, NUMBER and COMPLEX).
|
||||
you might also want to read the following to understand
|
||||
some of the numerical types of ZVALUE, NUMBER and COMPLEX:
|
||||
|
||||
../zmath.h
|
||||
../qmath.h
|
||||
../cmath.h
|
||||
|
||||
While we cannot go into full detail here are some cookbook
|
||||
code for manipulating VALUEs. For these examples assume
|
||||
that we will manipulate the return value:
|
||||
|
||||
VALUE result; /* what we will return */
|
||||
|
||||
To return NULL:
|
||||
|
||||
result.v_type = V_NULL;
|
||||
return result;
|
||||
|
||||
To return a long you need to convert it to a NUMBER:
|
||||
|
||||
long variable;
|
||||
|
||||
result.v_type = V_NUM;
|
||||
result.v_num = itoq(variable); /* see ../qmath.c */
|
||||
return result;
|
||||
|
||||
To return a FULL you need to convert it to a NUMBER:
|
||||
|
||||
FULL variable;
|
||||
|
||||
result.v_type = V_NUM;
|
||||
result.v_num = utoq(variable); /* see ../qmath.c */
|
||||
return result;
|
||||
|
||||
To convert a ZVALUE to a NUMBER*:
|
||||
|
||||
ZVALUE variable;
|
||||
|
||||
result.v_type = V_NUM;
|
||||
result.v_num = qalloc(); /* see ../qmath.c */
|
||||
result.v_num->num = variable;
|
||||
return result;
|
||||
|
||||
To convert a small NUMBER* into a long:
|
||||
|
||||
NUMBER *num;
|
||||
long variable;
|
||||
|
||||
variable = qtoi(num);
|
||||
|
||||
To obtain a ZVALUE from a NUMBER*, extract the numerator:
|
||||
|
||||
NUMBER *num;
|
||||
ZVALUE z_variable;
|
||||
|
||||
if (qisint(num)) {
|
||||
z_variable = num->num;
|
||||
}
|
||||
|
||||
To be sure that the value will fit, use the ZVALUE test macros:
|
||||
|
||||
ZVALUE z_num;
|
||||
long variable;
|
||||
unsigned long u_variable;
|
||||
FULL f_variable;
|
||||
short very_tiny_variable;
|
||||
|
||||
if (zgtmaxlong(z_num)) { /* see ../zmath.h */
|
||||
variable = ztolong(z_num);
|
||||
}
|
||||
if (zgtmaxulong(z_num)) {
|
||||
u_variable = ztoulong(z_num);
|
||||
}
|
||||
if (zgtmaxufull(z_num)) {
|
||||
f_variable = ztofull(z_num);
|
||||
}
|
||||
if (zistiny(z_num)) {
|
||||
very_tiny_variable = z1tol(z_num);
|
||||
}
|
||||
|
||||
|
||||
Step 6: Register the function in the custom interface table
|
||||
|
||||
To allow the custom() builtin to transfer control to your function,
|
||||
you need to add an entry into the CONST struct custom cust table
|
||||
found in custtbl.c:
|
||||
|
||||
/*
|
||||
* custom interface table
|
||||
*
|
||||
* The order of the elements in struct custom are:
|
||||
*
|
||||
* { "xyz", "brief description of the xyz custom function",
|
||||
* minimum_args, maximum_args, c_xyz },
|
||||
*
|
||||
* where:
|
||||
*
|
||||
* minimum_args an int >= 0
|
||||
* maximum_args an int >= minimum_args and <= MAX_CUSTOM_ARGS
|
||||
*
|
||||
* Use MAX_CUSTOM_ARGS for maximum_args is the maximum number of args
|
||||
* is potentially 'unlimited'.
|
||||
*
|
||||
* If the brief description cannot fit on the same line as the name
|
||||
* without wrapping on a 80 col window, the description is probably
|
||||
* too long and will not look nice in the show custom output.
|
||||
*/
|
||||
CONST struct custom cust[] = {
|
||||
|
||||
#if defined(CUSTOM)
|
||||
|
||||
|
||||
/*
|
||||
* add your own custom functions here
|
||||
*
|
||||
* We suggest that you sort the entries below by name
|
||||
* so that show custom will produce a nice sorted list.
|
||||
*/
|
||||
|
||||
{ "argv", "information about its args, returns arg count",
|
||||
0, MAX_CUSTOM_ARGS, c_argv },
|
||||
|
||||
{ "devnull", "does nothing",
|
||||
0, MAX_CUSTOM_ARGS, c_devnull },
|
||||
|
||||
{ "help", "help for custom functions",
|
||||
1, 1, c_help },
|
||||
|
||||
{ "sysinfo", "return a calc #define value",
|
||||
0, 1, c_sysinfo },
|
||||
|
||||
|
||||
#endif /* CUSTOM */
|
||||
|
||||
/*
|
||||
* This must be at the end of this table!!!
|
||||
*/
|
||||
{NULL, NULL,
|
||||
0, 0, NULL}
|
||||
};
|
||||
|
||||
The definition of struct custom may be found in custom.h.
|
||||
|
||||
It is important that your entry be placed inside the:
|
||||
|
||||
#if defined(CUSTOM) ... #endif /* CUSTOM */
|
||||
|
||||
lines so that when the custom interface is disabled by the upper
|
||||
level Makefile, one does not have unsatisfied symbols.
|
||||
|
||||
The brief description should be brief so that 'show custom' looks well
|
||||
formatted. If the brief description cannot fit on the same line as
|
||||
the name without wrapping on a 80 col window, the description is
|
||||
probably too long and will not look nice in the show custom output.
|
||||
|
||||
The minargs places a lower bound on the number of args that
|
||||
must be supplied to the interface. This does NOT count
|
||||
the name argument given to custom(). So if minargs is 2:
|
||||
|
||||
custom("curds") /* call blocked at high level interface */
|
||||
custom("curds", a) /* call blocked at high level interface */
|
||||
custom("curds", a, b) /* call passed down to "curds" interface */
|
||||
|
||||
The maxargs sets a limit on the number of args that may be passed.
|
||||
If minargs == maxargs, then the call requires a fixed number of
|
||||
argument. There is a upper limit on the number of args. If
|
||||
one wants an effectively unlimited upper bound, use MAX_CUSTOM_ARGS.
|
||||
|
||||
Note that one must have:
|
||||
|
||||
0 <= minargs <= maxargs <= MAX_CUSTOM_ARGS
|
||||
|
||||
To allow the curds function to take at least 2 args and up
|
||||
to 5 args, one would add the following entry to cust[]:
|
||||
|
||||
{ "curds", "brief description about curds interface",
|
||||
2, 5, u_curds },
|
||||
|
||||
It is recommended that the cust[] remain in alphabetical order,
|
||||
so one would place it before the "devnull" and after "argv".
|
||||
|
||||
Last, you must forward declare the u_curds near the top of the file:
|
||||
|
||||
#if defined(CUSTOM)
|
||||
|
||||
|
||||
/*
|
||||
* add your forward custom function declarations here
|
||||
*
|
||||
* Declare custom functions as follows:
|
||||
*
|
||||
* extern VALUE c_xyz(char*, int, VALUE**);
|
||||
*
|
||||
* We suggest that you sort the entries below by name.
|
||||
*/
|
||||
extern VALUE c_argv(char*, int, VALUE**);
|
||||
extern VALUE c_devnull(char*, int, VALUE**);
|
||||
extern VALUE c_help(char*, int, VALUE**);
|
||||
extern VALUE c_sysinfo(char*, int, VALUE**);
|
||||
|
||||
For u_curds we would add the line:
|
||||
|
||||
extern VALUE u_curds(char*, int, VALUE**);
|
||||
|
||||
|
||||
Step 7: Add the required information to the Makefile
|
||||
|
||||
The calc test script, curds.cal, should be added to the
|
||||
CUSTOM_CALC_FILES Makefile variable:
|
||||
|
||||
CUSTOM_CALC_FILES= argv.cal halflen.cal curds.cal
|
||||
|
||||
The help file, curds, should be added to the CUSTOM_HELP
|
||||
Makefile variable:
|
||||
|
||||
CUSTOM_HELP= argv devnull help sysinfo curds
|
||||
|
||||
If you needed to create any .h files to support u_curds.c, these
|
||||
files should be added to the CUSTOM_H_SRC Makefile variable:
|
||||
|
||||
CUSTOM_H_SRC= u_curds.h otherfile.h
|
||||
|
||||
Your u_curds.c file MUST be added to the CUSTOM_SRC Makefile variable:
|
||||
|
||||
CUSTOM_SRC= c_argv.c c_devnull.c c_help.c c_sysinfo.c u_curds.c
|
||||
|
||||
and so must the associated .o file:
|
||||
|
||||
CUSTOM_OBJ= c_argv.o c_devnull.o c_help.o c_sysinfo.o u_curds.o
|
||||
|
||||
|
||||
Step 8: Compile and link in your code
|
||||
|
||||
If your calc was not previously setup to compile custom code,
|
||||
you should set it up now. The upper level Makefile (and
|
||||
the custom Makefile) should have the following Makefile
|
||||
variable defined:
|
||||
|
||||
ALLOW_CUSTOM= -DCUSTOM
|
||||
|
||||
It is recommended that you build your code from the top level
|
||||
Makefile. It saves having to sync the other Makefile values.
|
||||
To try and build the new libcustcalc.a that contains u_curds.c:
|
||||
|
||||
(cd ..; make custom/libcustcalc.a)
|
||||
|
||||
Fix any compile and syntax errors as needed. :-)
|
||||
|
||||
Once libcustcalc.a successfully builds, compile calc:
|
||||
|
||||
cd ..
|
||||
make calc
|
||||
|
||||
And check to be sure that the regression test suite still
|
||||
works without errors:
|
||||
|
||||
make check
|
||||
|
||||
|
||||
Step 9: Add the Make dependency tools
|
||||
|
||||
You should probably add the dependency lines to the bottom of
|
||||
the Makefile. Given the required include files, you will at least
|
||||
have the following entries placed at the bottom of the Makefile:
|
||||
|
||||
u_curds.o: ../alloc.h
|
||||
u_curds.o: ../block.h
|
||||
u_curds.o: ../byteswap.h
|
||||
u_curds.o: ../calcerr.h
|
||||
u_curds.o: ../cmath.h
|
||||
u_curds.o: ../config.h
|
||||
u_curds.o: ../endian_calc.h
|
||||
u_curds.o: ../hash.h
|
||||
u_curds.o: ../have_const.h
|
||||
u_curds.o: ../have_malloc.h
|
||||
u_curds.o: ../have_newstr.h
|
||||
u_curds.o: ../have_stdlib.h
|
||||
u_curds.o: ../have_string.h
|
||||
u_curds.o: ../longbits.h
|
||||
u_curds.o: ../nametype.h
|
||||
u_curds.o: ../qmath.h
|
||||
u_curds.o: ../shs.h
|
||||
u_curds.o: ../value.h
|
||||
u_curds.o: ../zmath.h
|
||||
u_curds.o: u_curds.c
|
||||
u_curds.o: ../custom.h
|
||||
|
||||
If you have the makedepend tool from the X11 development environment
|
||||
(by Todd Brunhoff, Tektronix, Inc. and MIT Project Athena), you can
|
||||
use the following to update your dependencies:
|
||||
|
||||
# cd to the top level calc directory if you are not there already
|
||||
|
||||
rm -f Makefile.bak custom/Makefile.bak
|
||||
make depend
|
||||
|
||||
diff -c Makefile.bak Makefile # look at the changes
|
||||
diff -c custom/Makefile.bak custom/Makefile # look at the changes
|
||||
|
||||
rm -f Makefile.bak custom/Makefile.bak # cleanup
|
||||
|
||||
Step 10: Test
|
||||
|
||||
Now that you have built calc with your new custom function, test it:
|
||||
|
||||
./calc -C # run the new calc with the -C arg
|
||||
|
||||
And then try out our test suite:
|
||||
|
||||
C-style arbitrary precision calculator (version 2.10.3t5.1)
|
||||
[Type "exit" to exit, or "help" for help.]
|
||||
|
||||
> read custom/curds.cal
|
||||
curds(a, b, [c, d, e]) defined
|
||||
|
||||
> custom("curds", 2, 3, 4)
|
||||
|
||||
|
||||
Step 11: Install
|
||||
|
||||
Once you are satisfied that everything works, install the new code:
|
||||
|
||||
# cd to the top level calc directory if you are not there already
|
||||
|
||||
make install
|
||||
|
||||
Although calc does not run setuid, you may need to be root to install
|
||||
the directories into which calc installs may be write protected.
|
677
custom/Makefile
Normal file
677
custom/Makefile
Normal file
@@ -0,0 +1,677 @@
|
||||
#
|
||||
# custom - makefile for calc custom routines
|
||||
#
|
||||
# Copyright (c) 1997 Landon Curt Noll
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software and
|
||||
# its documentation for any purpose and without fee is hereby granted,
|
||||
# provided that the above copyright, this permission notice and text
|
||||
# this comment, and the disclaimer below appear in all of the following:
|
||||
#
|
||||
# supporting documentation
|
||||
# source copies
|
||||
# source works derived from this source
|
||||
# binaries derived from this source or from derived source
|
||||
#
|
||||
# LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
|
||||
# EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
# USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
# Comments, suggestions, bug fixes and questions about these routines
|
||||
# are welcome. Send EMail to the address given below.
|
||||
#
|
||||
# Happy bit twiddling,
|
||||
#
|
||||
# Landon Curt Noll
|
||||
# http://reality.sgi.com/chongo
|
||||
#
|
||||
# chongo <was here> /\../\
|
||||
|
||||
##############################################################################
|
||||
#-=-=-=-=-=-=-=-=- You may want to change some values below -=-=-=-=-=-=-=-=-#
|
||||
##############################################################################
|
||||
|
||||
# The custom calc library files to install
|
||||
#
|
||||
# Put your custom calc library files here.
|
||||
#
|
||||
CUSTOM_CALC_FILES= argv.cal halflen.cal pzasusb8.cal
|
||||
|
||||
# The custom help files to install
|
||||
#
|
||||
# Put your custom help files here.
|
||||
#
|
||||
CUSTOM_HELP= argv devnull help sysinfo pzasusb8
|
||||
|
||||
# Any .h files that are needed by programs that use libcustcalc.a
|
||||
#
|
||||
# Put any .h files that you add which might be useful to other
|
||||
# programs here.
|
||||
#
|
||||
CUSTOM_H_SRC=
|
||||
|
||||
# Any .c files that are needed to build libcustcalc.a.
|
||||
# Don't put ${REQUIRED_SRC} files in this list.
|
||||
#
|
||||
# There MUST be a .c in CUSTOM_SRC for every .o in CUSTOM_OBJ.
|
||||
#
|
||||
# Put your custom .c files here.
|
||||
#
|
||||
CUSTOM_SRC= c_argv.c c_devnull.c c_help.c c_sysinfo.c c_pzasusb8.c
|
||||
|
||||
# Any .o files that are needed by program that use libcustcalc.a.
|
||||
# Don't put ${REQUIRED_OBJ} files in this list.
|
||||
#
|
||||
# There MUST be a .c in CUSTOM_SRC for every .o in CUSTOM_OBJ.
|
||||
#
|
||||
# Put your custom .o files here.
|
||||
#
|
||||
CUSTOM_OBJ= c_argv.o c_devnull.o c_help.o c_sysinfo.o c_pzasusb8.o
|
||||
|
||||
##############################################################################
|
||||
#-=-=-=-=-=-=- Defaults in case you want to build from this dir -=-=-=-=-=-=-#
|
||||
##############################################################################
|
||||
|
||||
# Normally, the upper level makefile will set these values. We provide
|
||||
# a default here just in case you want to build from this directory.
|
||||
#
|
||||
# Makefile debug
|
||||
#
|
||||
# Q=@ do not echo internal makefile actions (quiet mode)
|
||||
# Q= echo internal makefile actions (debug / verbose mode)
|
||||
#
|
||||
#Q=
|
||||
Q=@
|
||||
|
||||
# Normally, the upper level makefile will set these values. We provide
|
||||
# a default here just in case you want to build from this directory.
|
||||
#
|
||||
# where to install things
|
||||
#
|
||||
# ${TOPDIR} is the directory under which the calc directory will be placed.
|
||||
# ${LIBDIR} is where the *.cal, *.h, *.a, bindings and help dir are installed.
|
||||
# ${HELPDIR} is where the help directory is installed.
|
||||
# ${CUSTOMLIBDIR} is where custom lib files are installed.
|
||||
# ${CUSTOMHELPDIR} is where custom help files are installed.
|
||||
#
|
||||
TOPDIR= /usr/local/lib
|
||||
#TOPDIR= /usr/lib
|
||||
#TOPDIR= /usr/libdata
|
||||
#TOPDIR= /usr/contrib/lib
|
||||
#
|
||||
LIBDIR= ${TOPDIR}/calc
|
||||
HELPDIR= ${LIBDIR}/help
|
||||
CUSTOMLIBDIR= ${LIBDIR}/custom
|
||||
CUSTOMHELPDIR= ${HELPDIR}/custhelp
|
||||
|
||||
# Normally, the upper level makefile will set these values. We provide
|
||||
# a default here just in case you want to build from this directory.
|
||||
#
|
||||
# Debug/Optimize options for ${CC}
|
||||
#
|
||||
DEBUG= -O
|
||||
#DEBUG= -O -g
|
||||
#DEBUG= -O -g3
|
||||
#DEBUG= -O1
|
||||
#DEBUG= -O1 -g
|
||||
#DEBUG= -O1 -g3
|
||||
#DEBUG= -O2
|
||||
#DEBUG= -O2 -g
|
||||
#DEBUG= -O2 -g3
|
||||
#DEBUG= -O2 -ipa
|
||||
#DEBUG= -O2 -g3 -ipa
|
||||
#DEBUG= -O3
|
||||
#DEBUG= -O3 -g
|
||||
#DEBUG= -O3 -g3
|
||||
#DEBUG= -O3 -ipa
|
||||
#DEBUG= -O3 -g3 -ipa
|
||||
#DEBUG= -g
|
||||
#DEBUG= -g3
|
||||
#DEBUG= -gx
|
||||
#DEBUG= -WM,-g
|
||||
#DEBUG=
|
||||
|
||||
# Normally, the upper level makefile will set these values. We provide
|
||||
# a default here just in case you want to build from this directory.
|
||||
#
|
||||
# On systems that have dynamic shared libs, you may want want to disable them
|
||||
# for faster calc startup.
|
||||
#
|
||||
# System type NO_SHARED recommendation
|
||||
#
|
||||
# BSD NO_SHARED=
|
||||
# SYSV NO_SHARED= -dn
|
||||
# IRIX NO_SHARED= -non_shared
|
||||
# disable NO_SHARED=
|
||||
#
|
||||
# If in doubt, use NO_SHARED=
|
||||
#
|
||||
NO_SHARED=
|
||||
#NO_SHARED= -dn
|
||||
#NO_SHARED= -non_shared
|
||||
|
||||
# Normally, the upper level makefile will set these values. We provide
|
||||
# a default here just in case you want to build from this directory.
|
||||
#
|
||||
# Some systems require one to use ranlib to add a symbol table to
|
||||
# a *.a library. Set RANLIB to the utility that performs this action.
|
||||
# Set RANLIB to : if your system does not need such a utility.
|
||||
#
|
||||
#RANLIB=ranlib
|
||||
RANLIB=:
|
||||
|
||||
# Normally, the upper level makefile will set these values. We provide
|
||||
# a default here just in case you want to build from this directory.
|
||||
#
|
||||
# Normally certain files depend on the Makefile. If the Makefile is
|
||||
# changed, then certain steps should be redone. If MAKE_FILE is
|
||||
# set to Makefile, then these files will depend on Makefile. If
|
||||
# MAKE_FILE is empty, they they wont.
|
||||
#
|
||||
# If in doubt, set MAKE_FILE to Makefile
|
||||
#
|
||||
MAKE_FILE= Makefile
|
||||
#MAKE_FILE=
|
||||
|
||||
# Normally, the upper level makefile will set these values. We provide
|
||||
# a default here just in case you want to build from this directory.
|
||||
#
|
||||
# If you do not wish to use purify, leave PURIFY commented out.
|
||||
#
|
||||
# If in doubt, leave PURIFY commented out.
|
||||
#
|
||||
#PURIFY= purify -logfile=pure.out
|
||||
#PURIFY= purify
|
||||
|
||||
# Normally, the upper level makefile will set these values. We provide
|
||||
# a default here just in case you want to build from this directory.
|
||||
#
|
||||
# By default, custom builtin functions may only be executed if calc
|
||||
# is given the -C option. This is because custom builtin functions
|
||||
# may invoke non-standard or non-portable code. One may completely
|
||||
# disable custom builtin functions by not compiling any of code
|
||||
#
|
||||
# ALLOW_CUSTOM= -DCUSTOM # allow custom only if -C is given
|
||||
# ALLOW_CUSTOM= # disable custom even if -C is given
|
||||
#
|
||||
# If in doubt, use ALLOW_CUSTOM= -DCUSTOM
|
||||
#
|
||||
ALLOW_CUSTOM= -DCUSTOM
|
||||
#ALLOW_CUSTOM=
|
||||
|
||||
###
|
||||
#
|
||||
# Normally, the upper level makefile will set these values. We provide
|
||||
# a default here just in case you want to build from this directory.
|
||||
#
|
||||
# Select your compiler type by commenting out one of the cc sets below:
|
||||
#
|
||||
# CCOPT are flags given to ${CC} for optimization
|
||||
# CCWARN are flags given to ${CC} for warning message control
|
||||
# CCMISC are misc flags given to ${CC}
|
||||
#
|
||||
# CFLAGS are all flags given to ${CC} [[often includes CCOPT, CCWARN, CCMISC]]
|
||||
# ICFLAGS are given to ${CC} for intermediate progs
|
||||
#
|
||||
# LCFLAGS are CC-style flags for ${LINT}
|
||||
# LDFLAGS are flags given to ${CC} for linking .o files
|
||||
# ILDFLAGS are flags given to ${CC} for linking .o files for intermediate progs
|
||||
#
|
||||
# CC is how the the C compiler is invoked
|
||||
#
|
||||
###
|
||||
#
|
||||
# common cc set
|
||||
#
|
||||
CCWARN=
|
||||
CCOPT= ${DEBUG} ${NO_SHARED}
|
||||
CCMISC=
|
||||
#
|
||||
CFLAGS= ${CCWARN} ${CCOPT} ${CCMISC} ${ALLOW_CUSTOM}
|
||||
ICFLAGS= ${CCWARN} ${CCMISC}
|
||||
#
|
||||
LCFLAGS=
|
||||
LDFLAGS= ${NO_SHARED} ${LD_NO_SHARED}
|
||||
ILDFLAGS=
|
||||
#
|
||||
CC= ${PURIFY} cc
|
||||
|
||||
##############################################################################
|
||||
#-=-=-=-=-=-=-=-=- Be careful if you change something below -=-=-=-=-=-=-=-=-#
|
||||
##############################################################################
|
||||
|
||||
# These .c files are required for the main custom interface and
|
||||
# for the custom support functions.
|
||||
#
|
||||
# There MUST be a .c for every .o in REQUIRED_OBJ.
|
||||
#
|
||||
REQUIRED_SRC= custtbl.c
|
||||
|
||||
# These .o files correspond to the .c files in REQUIRED_SRC
|
||||
#
|
||||
# There MUST be a .o for every .c in REQUIRED_SRC.
|
||||
#
|
||||
REQUIRED_OBJ= custtbl.o
|
||||
|
||||
# These .h files are installed under ${CUSTOMLIBDIR} by the install rule.
|
||||
#
|
||||
INSTALL_H_SRC= ${CUSTOM_H_SRC}
|
||||
|
||||
# These .c files are used to form libcustcalc.a.
|
||||
#
|
||||
CUSTCALC_SRC= ${REQUIRED_SRC} ${CUSTOM_SRC}
|
||||
|
||||
# These .o files are used to form libcustcalc.a.
|
||||
#
|
||||
CUSTCALC_OBJ= ${REQUIRED_OBJ} ${CUSTOM_OBJ}
|
||||
|
||||
# These .c files are used to build the dependency list
|
||||
#
|
||||
C_SRC= ${REQUIRED_SRC} ${CUSTOM_SRC}
|
||||
|
||||
# These .h files are used to build the dependecy list
|
||||
#
|
||||
H_SRC= ${CUSTOM_H_SRC}
|
||||
|
||||
# These files are found (but not built) in the distribution
|
||||
#
|
||||
# The CUSTOM_CAL and HOW_TO_ADD are files distributed from this
|
||||
# directory but are installed as help files from the help/Makefile.
|
||||
#
|
||||
DISTLIST= ${CUSTCALC_SRC} ${CUSTOM_CALC_FILES} ${CUSTOM_HELP} \
|
||||
${INSTALL_H_SRC} CUSTOM_CAL HOW_TO_ADD ${MAKE_FILE}
|
||||
|
||||
# complete list of targets
|
||||
#
|
||||
TARGETS= libcustcalc.a ${CUSTCALC_OBJ}
|
||||
|
||||
# required vars
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
SED= sed
|
||||
MAKEDEPEND= makedepend
|
||||
SORT= sort
|
||||
|
||||
##
|
||||
#
|
||||
# Standard rules and targets
|
||||
#
|
||||
##
|
||||
|
||||
all: ${TARGETS} ${INSTALL_H_SRC} ${CUSTOM_CALC_FILES} \
|
||||
${CUSTOM_HELP} ${MAKE_FILE} .all
|
||||
|
||||
libcustcalc.a: ${CUSTCALC_OBJ} ${MAKE_FILE} ../Makefile
|
||||
-rm -f libcustcalc.a
|
||||
ar qc libcustcalc.a ${CUSTCALC_OBJ}
|
||||
${RANLIB} libcustcalc.a
|
||||
|
||||
##
|
||||
#
|
||||
# used by the upper level Makefile
|
||||
#
|
||||
##
|
||||
|
||||
# to determine of we have done all
|
||||
#
|
||||
.all:
|
||||
rm -f .all
|
||||
touch .all
|
||||
|
||||
##
|
||||
#
|
||||
# File list generation. You can ignore this section.
|
||||
#
|
||||
#
|
||||
# We will form the names of source files as if they were in a
|
||||
# sub-directory called calc/lib.
|
||||
#
|
||||
# NOTE: Due to bogus shells found on one common system we must have
|
||||
# an non-emoty else clause for every if condition. *sigh*
|
||||
#
|
||||
##
|
||||
|
||||
distlist: ${DISTLIST}
|
||||
${Q}for i in ${DISTLIST}; do \
|
||||
echo calc/custom/$$i; \
|
||||
done
|
||||
|
||||
# The bsdi distribution has generated files as well as distributed files.
|
||||
#
|
||||
bsdilist: ${DISTLIST}
|
||||
${Q}for i in ${DISTLIST}; do \
|
||||
echo calc/custom/$$i; \
|
||||
done
|
||||
|
||||
##
|
||||
#
|
||||
# Home grown make dependency rules. Your system make not support
|
||||
# or have the needed tools. You can ignore this section.
|
||||
#
|
||||
# We will form a skelaton tree of *.c files containing only #include "foo.h"
|
||||
# lines and .h files containing the same lines surrounded by multiple include
|
||||
# prevention lines. This allows us to build a static depend list that will
|
||||
# satisfy all possible cpp symbol definition combinations.
|
||||
#
|
||||
##
|
||||
|
||||
depend:
|
||||
${Q}if [ -f Makefile.bak ]; then \
|
||||
echo "Makefile.bak exists, remove or move it out of the way"; \
|
||||
exit 1; \
|
||||
else \
|
||||
true; \
|
||||
fi
|
||||
${Q}echo forming custom/skel
|
||||
-${Q}rm -rf skel
|
||||
${Q}mkdir skel
|
||||
${Q}mkdir skel/custom
|
||||
-${Q}for i in ${C_SRC}; do \
|
||||
${SED} -n '/^#[ ]*include[ ]*"/p' \
|
||||
"$$i" > "skel/custom/$$i"; \
|
||||
done
|
||||
-${Q}for i in /dev/null ${H_SRC}; do \
|
||||
if [ "$$i" = "/dev/null" ]; then \
|
||||
continue; \
|
||||
fi; \
|
||||
tag="`echo $$i | ${SED} 's/[\.+,:]/_/g'`"; \
|
||||
echo "#ifndef $$tag" > "skel/custom/$$i"; \
|
||||
echo "#define $$tag" >> "skel/custom/$$i"; \
|
||||
${SED} -n '/^#[ ]*include[ ]*"/p' "$$i" \
|
||||
>> "skel/custom/$$i"; \
|
||||
echo '#endif /* '"$$tag"' */' >> "skel/custom/$$i"; \
|
||||
done
|
||||
${Q}(cd ..; ${MAKE} hsrc)
|
||||
${Q}for i in `cd ..; ${MAKE} h_list`; do \
|
||||
tag="`echo $$i | ${SED} 's/[\.+,:]/_/g'`"; \
|
||||
echo "#ifndef $$tag" > "skel/$$i"; \
|
||||
echo "#define $$tag" >> "skel/$$i"; \
|
||||
${SED} -n '/^#[ ]*include[ ]*"/p' "../$$i" \
|
||||
>> "skel/$$i"; \
|
||||
echo '#endif /* '"$$tag"' */' >> "skel/$$i"; \
|
||||
done
|
||||
-${Q}rm -f skel/custom/makedep.out
|
||||
${Q}echo custom/skel formed
|
||||
${Q}echo forming custom dependency list
|
||||
${Q}echo "# DO NOT DELETE THIS LINE -- make depend depends on it." > \
|
||||
skel/custom/makedep.out
|
||||
${Q}cd skel/custom; ${MAKEDEPEND} -w 1 -m -f makedep.out ${C_SRC}
|
||||
-${Q}for i in ${C_SRC}; do \
|
||||
echo "$$i" | \
|
||||
${SED} 's/^\(.*\)\.c/\1.o: \1.c/' \
|
||||
>> skel/custom/makedep.out; \
|
||||
done
|
||||
${Q}echo custom dependency list formed
|
||||
${Q}echo forming new custom/Makefile
|
||||
-${Q}rm -f Makefile.bak
|
||||
${Q}mv Makefile Makefile.bak
|
||||
${Q}${SED} -n '1,/^# DO NOT DELETE THIS LINE/p' Makefile.bak > Makefile
|
||||
${Q}echo "" >> Makefile
|
||||
${Q}${SED} -n '3,$$p' skel/custom/makedep.out | ${SORT} -u >> Makefile
|
||||
-${Q}rm -rf skel
|
||||
-${Q}if cmp -s Makefile.bak Makefile; then \
|
||||
echo 'custom Makefile was already up to date'; \
|
||||
mv -f Makefile.bak Makefile; \
|
||||
else \
|
||||
rm -f Makefile.tmp; \
|
||||
mv Makefile Makefile.tmp; \
|
||||
if [ -d RCS ]; then; \
|
||||
co -l Makefile; \
|
||||
fi ;\
|
||||
mv Makefile.tmp Makefile; \
|
||||
if [ -d RCS ]; then; \
|
||||
echo new custom Makefile formed '--' you need to check it in'; \
|
||||
fi; \
|
||||
fi
|
||||
|
||||
##
|
||||
#
|
||||
# Utility rules
|
||||
#
|
||||
##
|
||||
|
||||
clean:
|
||||
-rm -f ${CUSTCALC_OBJ}
|
||||
|
||||
clobber:
|
||||
-rm -f ${TARGETS}
|
||||
rm -f .all Makefile.tmp
|
||||
|
||||
install: all
|
||||
-${Q}if [ ! -d ${TOPDIR} ]; then \
|
||||
echo mkdir ${TOPDIR}; \
|
||||
mkdir ${TOPDIR}; \
|
||||
else \
|
||||
true; \
|
||||
fi
|
||||
-${Q}if [ ! -d ${LIBDIR} ]; then \
|
||||
echo mkdir ${LIBDIR}; \
|
||||
mkdir ${LIBDIR}; \
|
||||
else \
|
||||
true; \
|
||||
fi
|
||||
-${Q}if [ ! -d ${HELPDIR} ]; then \
|
||||
echo mkdir ${HELPDIR}; \
|
||||
mkdir ${HELPDIR}; \
|
||||
else \
|
||||
true; \
|
||||
fi
|
||||
-${Q}if [ ! -d ${CUSTOMLIBDIR} ]; then \
|
||||
echo mkdir ${CUSTOMLIBDIR}; \
|
||||
mkdir ${CUSTOMLIBDIR}; \
|
||||
else \
|
||||
true; \
|
||||
fi
|
||||
-${Q}if [ ! -d ${CUSTOMHELPDIR} ]; then \
|
||||
echo mkdir ${CUSTOMHELPDIR}; \
|
||||
mkdir ${CUSTOMHELPDIR}; \
|
||||
else \
|
||||
true; \
|
||||
fi
|
||||
${Q}for i in ${INSTALL_H_SRC} /dev/null; do \
|
||||
if [ X$$i = X/dev/null ]; then continue; fi; \
|
||||
echo rm -f ${CUSTOMLIBDIR}/$$i; \
|
||||
rm -f ${CUSTOMLIBDIR}/$$i; \
|
||||
echo cp $$i ${CUSTOMLIBDIR}; \
|
||||
cp $$i ${CUSTOMLIBDIR}; \
|
||||
echo chmod 0444 ${CUSTOMLIBDIR}/$$i; \
|
||||
chmod 0444 ${CUSTOMLIBDIR}/$$i; \
|
||||
done
|
||||
${Q}for i in ${CUSTOM_CALC_FILES}; do \
|
||||
echo rm -f ${CUSTOMLIBDIR}/$$i; \
|
||||
rm -f ${CUSTOMLIBDIR}/$$i; \
|
||||
echo cp $$i ${CUSTOMLIBDIR}; \
|
||||
cp $$i ${CUSTOMLIBDIR}; \
|
||||
echo chmod 0444 ${CUSTOMLIBDIR}/$$i; \
|
||||
chmod 0444 ${CUSTOMLIBDIR}/$$i; \
|
||||
done
|
||||
${Q}for i in ${CUSTOM_HELP}; do \
|
||||
echo rm -f ${CUSTOMHELPDIR}/$$i; \
|
||||
rm -f ${CUSTOMHELPDIR}/$$i; \
|
||||
echo cp $$i ${CUSTOMHELPDIR}; \
|
||||
cp $$i ${CUSTOMHELPDIR}; \
|
||||
echo chmod 0444 ${CUSTOMHELPDIR}/$$i; \
|
||||
chmod 0444 ${CUSTOMHELPDIR}/$$i; \
|
||||
done
|
||||
-${Q}if [ ! -z ${ALLOW_CUSTOM} ]; then \
|
||||
echo "rm -f ${CUSTOMLIBDIR}/libcustcalc.a"; \
|
||||
rm -f ${CUSTOMLIBDIR}/libcustcalc.a; \
|
||||
echo "cp libcustcalc.a ${CUSTOMLIBDIR}/libcustcalc.a"; \
|
||||
cp libcustcalc.a ${CUSTOMLIBDIR}/libcustcalc.a; \
|
||||
echo "chmod 0644 ${CUSTOMLIBDIR}/libcustcalc.a"; \
|
||||
chmod 0644 ${CUSTOMLIBDIR}/libcustcalc.a; \
|
||||
echo "${RANLIB} ${CUSTOMLIBDIR}/libcustcalc.a"; \
|
||||
${RANLIB} ${CUSTOMLIBDIR}/libcustcalc.a; \
|
||||
fi
|
||||
|
||||
##
|
||||
#
|
||||
# make depend stuff
|
||||
#
|
||||
##
|
||||
|
||||
# DO NOT DELETE THIS LINE
|
||||
|
||||
c_argv.o: ../alloc.h
|
||||
c_argv.o: ../block.h
|
||||
c_argv.o: ../byteswap.h
|
||||
c_argv.o: ../calc.h
|
||||
c_argv.o: ../calcerr.h
|
||||
c_argv.o: ../cmath.h
|
||||
c_argv.o: ../config.h
|
||||
c_argv.o: ../custom.h
|
||||
c_argv.o: ../endian_calc.h
|
||||
c_argv.o: ../hash.h
|
||||
c_argv.o: ../have_const.h
|
||||
c_argv.o: ../have_malloc.h
|
||||
c_argv.o: ../have_memmv.h
|
||||
c_argv.o: ../have_newstr.h
|
||||
c_argv.o: ../have_stdlib.h
|
||||
c_argv.o: ../have_string.h
|
||||
c_argv.o: ../longbits.h
|
||||
c_argv.o: ../md5.h
|
||||
c_argv.o: ../nametype.h
|
||||
c_argv.o: ../qmath.h
|
||||
c_argv.o: ../shs.h
|
||||
c_argv.o: ../shs1.h
|
||||
c_argv.o: ../string.h
|
||||
c_argv.o: ../value.h
|
||||
c_argv.o: ../zmath.h
|
||||
c_argv.o: c_argv.c
|
||||
c_devnull.o: ../alloc.h
|
||||
c_devnull.o: ../block.h
|
||||
c_devnull.o: ../byteswap.h
|
||||
c_devnull.o: ../calcerr.h
|
||||
c_devnull.o: ../cmath.h
|
||||
c_devnull.o: ../config.h
|
||||
c_devnull.o: ../custom.h
|
||||
c_devnull.o: ../endian_calc.h
|
||||
c_devnull.o: ../hash.h
|
||||
c_devnull.o: ../have_const.h
|
||||
c_devnull.o: ../have_malloc.h
|
||||
c_devnull.o: ../have_memmv.h
|
||||
c_devnull.o: ../have_newstr.h
|
||||
c_devnull.o: ../have_stdlib.h
|
||||
c_devnull.o: ../have_string.h
|
||||
c_devnull.o: ../longbits.h
|
||||
c_devnull.o: ../md5.h
|
||||
c_devnull.o: ../nametype.h
|
||||
c_devnull.o: ../qmath.h
|
||||
c_devnull.o: ../shs.h
|
||||
c_devnull.o: ../shs1.h
|
||||
c_devnull.o: ../string.h
|
||||
c_devnull.o: ../value.h
|
||||
c_devnull.o: ../zmath.h
|
||||
c_devnull.o: c_devnull.c
|
||||
c_help.o: ../alloc.h
|
||||
c_help.o: ../block.h
|
||||
c_help.o: ../byteswap.h
|
||||
c_help.o: ../calcerr.h
|
||||
c_help.o: ../cmath.h
|
||||
c_help.o: ../config.h
|
||||
c_help.o: ../custom.h
|
||||
c_help.o: ../endian_calc.h
|
||||
c_help.o: ../hash.h
|
||||
c_help.o: ../have_const.h
|
||||
c_help.o: ../have_malloc.h
|
||||
c_help.o: ../have_memmv.h
|
||||
c_help.o: ../have_newstr.h
|
||||
c_help.o: ../have_stdlib.h
|
||||
c_help.o: ../have_string.h
|
||||
c_help.o: ../longbits.h
|
||||
c_help.o: ../md5.h
|
||||
c_help.o: ../nametype.h
|
||||
c_help.o: ../qmath.h
|
||||
c_help.o: ../shs.h
|
||||
c_help.o: ../shs1.h
|
||||
c_help.o: ../string.h
|
||||
c_help.o: ../value.h
|
||||
c_help.o: ../zmath.h
|
||||
c_help.o: c_help.c
|
||||
c_pzasusb8.o: ../alloc.h
|
||||
c_pzasusb8.o: ../block.h
|
||||
c_pzasusb8.o: ../byteswap.h
|
||||
c_pzasusb8.o: ../calcerr.h
|
||||
c_pzasusb8.o: ../cmath.h
|
||||
c_pzasusb8.o: ../config.h
|
||||
c_pzasusb8.o: ../custom.h
|
||||
c_pzasusb8.o: ../endian_calc.h
|
||||
c_pzasusb8.o: ../hash.h
|
||||
c_pzasusb8.o: ../have_const.h
|
||||
c_pzasusb8.o: ../have_malloc.h
|
||||
c_pzasusb8.o: ../have_memmv.h
|
||||
c_pzasusb8.o: ../have_newstr.h
|
||||
c_pzasusb8.o: ../have_stdlib.h
|
||||
c_pzasusb8.o: ../have_string.h
|
||||
c_pzasusb8.o: ../longbits.h
|
||||
c_pzasusb8.o: ../md5.h
|
||||
c_pzasusb8.o: ../nametype.h
|
||||
c_pzasusb8.o: ../qmath.h
|
||||
c_pzasusb8.o: ../shs.h
|
||||
c_pzasusb8.o: ../shs1.h
|
||||
c_pzasusb8.o: ../string.h
|
||||
c_pzasusb8.o: ../value.h
|
||||
c_pzasusb8.o: ../zmath.h
|
||||
c_pzasusb8.o: c_pzasusb8.c
|
||||
c_sysinfo.o: ../alloc.h
|
||||
c_sysinfo.o: ../block.h
|
||||
c_sysinfo.o: ../byteswap.h
|
||||
c_sysinfo.o: ../calc.h
|
||||
c_sysinfo.o: ../calcerr.h
|
||||
c_sysinfo.o: ../cmath.h
|
||||
c_sysinfo.o: ../conf.h
|
||||
c_sysinfo.o: ../config.h
|
||||
c_sysinfo.o: ../custom.h
|
||||
c_sysinfo.o: ../endian_calc.h
|
||||
c_sysinfo.o: ../fposval.h
|
||||
c_sysinfo.o: ../hash.h
|
||||
c_sysinfo.o: ../have_const.h
|
||||
c_sysinfo.o: ../have_malloc.h
|
||||
c_sysinfo.o: ../have_memmv.h
|
||||
c_sysinfo.o: ../have_newstr.h
|
||||
c_sysinfo.o: ../have_stdlib.h
|
||||
c_sysinfo.o: ../have_string.h
|
||||
c_sysinfo.o: ../hist.h
|
||||
c_sysinfo.o: ../longbits.h
|
||||
c_sysinfo.o: ../longlong.h
|
||||
c_sysinfo.o: ../md5.h
|
||||
c_sysinfo.o: ../nametype.h
|
||||
c_sysinfo.o: ../prime.h
|
||||
c_sysinfo.o: ../qmath.h
|
||||
c_sysinfo.o: ../shs.h
|
||||
c_sysinfo.o: ../shs1.h
|
||||
c_sysinfo.o: ../string.h
|
||||
c_sysinfo.o: ../value.h
|
||||
c_sysinfo.o: ../zmath.h
|
||||
c_sysinfo.o: ../zrand.h
|
||||
c_sysinfo.o: ../zrandom.h
|
||||
c_sysinfo.o: c_sysinfo.c
|
||||
custtbl.o: ../alloc.h
|
||||
custtbl.o: ../block.h
|
||||
custtbl.o: ../byteswap.h
|
||||
custtbl.o: ../calcerr.h
|
||||
custtbl.o: ../cmath.h
|
||||
custtbl.o: ../config.h
|
||||
custtbl.o: ../custom.h
|
||||
custtbl.o: ../endian_calc.h
|
||||
custtbl.o: ../hash.h
|
||||
custtbl.o: ../have_const.h
|
||||
custtbl.o: ../have_malloc.h
|
||||
custtbl.o: ../have_memmv.h
|
||||
custtbl.o: ../have_newstr.h
|
||||
custtbl.o: ../have_stdlib.h
|
||||
custtbl.o: ../have_string.h
|
||||
custtbl.o: ../longbits.h
|
||||
custtbl.o: ../md5.h
|
||||
custtbl.o: ../nametype.h
|
||||
custtbl.o: ../qmath.h
|
||||
custtbl.o: ../shs.h
|
||||
custtbl.o: ../shs1.h
|
||||
custtbl.o: ../string.h
|
||||
custtbl.o: ../value.h
|
||||
custtbl.o: ../zmath.h
|
||||
custtbl.o: custtbl.c
|
41
custom/argv
Normal file
41
custom/argv
Normal file
@@ -0,0 +1,41 @@
|
||||
NAME
|
||||
argv - displays information about its args
|
||||
|
||||
SYNOPSIS
|
||||
custom("argv" [, arg ...])
|
||||
|
||||
TYPES
|
||||
arg any
|
||||
|
||||
return int
|
||||
|
||||
DESCRIPTION
|
||||
This custom function will, for each arg given print:
|
||||
|
||||
arg number
|
||||
arg type
|
||||
number of elements (size())
|
||||
memory size (sizeof())
|
||||
|
||||
The number of args passed, not counting the initial "argv" name
|
||||
arg is returned.
|
||||
|
||||
EXAMPLE
|
||||
> foo=5^713; bar=17; baz=list(2,3,4);
|
||||
> custom("argv", foo, bar, baz, 3+4.5i, pi())
|
||||
arg[0] rational_value size=1 sizeof=272
|
||||
arg[1] rational_value size=1 sizeof=68
|
||||
arg[2] list size=3 sizeof=256
|
||||
arg[3] complex_value size=1 sizeof=140
|
||||
arg[4] rational_value size=1 sizeof=84
|
||||
5
|
||||
|
||||
LIMITS
|
||||
calc must be built with ALLOW_CUSTOM= -DCUSTOM
|
||||
calc must be executed with a -C arg.
|
||||
|
||||
LIBRARY
|
||||
none
|
||||
|
||||
SEE ALSO
|
||||
custom
|
44
custom/argv.cal
Normal file
44
custom/argv.cal
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Permission to use, copy, modify, and distribute this software and
|
||||
* its documentation for any purpose and without fee is hereby granted.
|
||||
*
|
||||
* LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
|
||||
* EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* chongo was here /\../\ http://reality.sgi.com/chongo
|
||||
*/
|
||||
/*
|
||||
* argv - print information about various args
|
||||
*
|
||||
* This file is part of the custom sample calc files.
|
||||
*
|
||||
* NOTE: You must use a calc that was compiled with ALLOW_CUSTOM= -DCUSTOM
|
||||
* and run with a -C arg.
|
||||
*/
|
||||
define argv()
|
||||
{
|
||||
local i; /* arg number */
|
||||
local junk; /* throw away value */
|
||||
|
||||
/*
|
||||
* process each arg passed to us
|
||||
*/
|
||||
for (i = 1; i <= param(0); ++i) {
|
||||
/*
|
||||
* This won't really work because all the arg numbers
|
||||
* will be reported as arg[0] ... but what the heck
|
||||
* this is only a demo!
|
||||
*/
|
||||
junk = custom("argv", param(i));
|
||||
}
|
||||
return i-1;
|
||||
}
|
||||
|
||||
if (config("lib_debug") >= 0) {
|
||||
print "argv(var, ...) defined";
|
||||
}
|
160
custom/c_argv.c
Normal file
160
custom/c_argv.c
Normal file
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Permission to use, copy, modify, and distribute this software and
|
||||
* its documentation for any purpose and without fee is hereby granted.
|
||||
*
|
||||
* LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
|
||||
* EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Comments, suggestions, bug fixes and questions about these routines
|
||||
* are welcome. Send EMail to the address given below.
|
||||
*
|
||||
* Happy bit twiddling,
|
||||
*
|
||||
* Landon Curt Noll
|
||||
* http://reality.sgi.com/chongo
|
||||
*
|
||||
* chongo <was here> /\../\
|
||||
*/
|
||||
|
||||
#if defined(CUSTOM)
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../have_const.h"
|
||||
#include "../value.h"
|
||||
#include "../custom.h"
|
||||
|
||||
#include "../config.h"
|
||||
#include "../calc.h"
|
||||
|
||||
/*
|
||||
* c_argv - a custom function display info about its args
|
||||
*
|
||||
* given:
|
||||
* vals[i] and arg to display information about
|
||||
*
|
||||
* returns:
|
||||
* count
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
VALUE
|
||||
c_argv(char *name, int count, VALUE **vals)
|
||||
{
|
||||
VALUE result; /* what we will return */
|
||||
ZVALUE zfilelen; /* length of a file as a ZVALUE */
|
||||
NUMBER *filelen; /* pointer to length of a file as a NUMER */
|
||||
char *type; /* the name of the arg type */
|
||||
int i;
|
||||
|
||||
/*
|
||||
* print info on each arg
|
||||
*/
|
||||
for (i=0; i < count; ++i) {
|
||||
|
||||
/*
|
||||
* print arg number with leading tab as configured
|
||||
*/
|
||||
printf("%sarg[%d]", (conf->tab_ok ? "\t" : ""), i);
|
||||
|
||||
/*
|
||||
* print the arg type
|
||||
*/
|
||||
switch (vals[i]->v_type) {
|
||||
case V_NULL: /* null value */
|
||||
type = "null";
|
||||
break;
|
||||
case V_INT: /* normal integer */
|
||||
type = "int";
|
||||
break;
|
||||
case V_NUM: /* number */
|
||||
type = "rational_value";
|
||||
break;
|
||||
case V_COM: /* complex number */
|
||||
type = "complex_value";
|
||||
break;
|
||||
case V_ADDR: /* address of variable value */
|
||||
type = "address";
|
||||
break;
|
||||
case V_STR: /* address of string */
|
||||
type = "string";
|
||||
break;
|
||||
case V_MAT: /* address of matrix structure */
|
||||
type = "matrix";
|
||||
break;
|
||||
case V_LIST: /* address of list structure */
|
||||
type = "list";
|
||||
break;
|
||||
case V_ASSOC: /* address of association structure */
|
||||
type = "assoc";
|
||||
break;
|
||||
case V_OBJ: /* address of object structure */
|
||||
type = "ocject";
|
||||
break;
|
||||
case V_FILE: /* opened file id */
|
||||
type = "file";
|
||||
break;
|
||||
case V_RAND: /* address of additive 55 random state */
|
||||
type = "rand_state";
|
||||
break;
|
||||
case V_RANDOM: /* address of Blum random state */
|
||||
type = "random_state";
|
||||
break;
|
||||
case V_CONFIG: /* configuration state */
|
||||
type = "config_state";
|
||||
break;
|
||||
case V_HASH: /* hash state */
|
||||
type = "hash_state";
|
||||
break;
|
||||
case V_BLOCK: /* memory block */
|
||||
type = "octet_block";
|
||||
break;
|
||||
#if 0
|
||||
/* XXX - V_OCTET is subject to change */
|
||||
case V_OCTET: /* octet (unsigned char) */
|
||||
type = "octet";
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
type = "unknown";
|
||||
break;
|
||||
}
|
||||
printf("\t%-16s", type);
|
||||
|
||||
/*
|
||||
* print size and sizeof information
|
||||
*
|
||||
* We have to treat files in a special way
|
||||
* because their length can be very long.
|
||||
*/
|
||||
if (vals[i]->v_type == V_FILE) {
|
||||
/* get the file length */
|
||||
if (getsize(vals[i]->v_file, &zfilelen) == 0) {
|
||||
filelen = qalloc();
|
||||
filelen->num = zfilelen;
|
||||
qprintfd(filelen, 0L);
|
||||
qfree(filelen);
|
||||
} else {
|
||||
/* getsize error */
|
||||
printf("\tsize=unknown");
|
||||
}
|
||||
printf("\tsizeof=%ld\n", lsizeof(vals[i]));
|
||||
} else {
|
||||
printf("\tsize=%ld\tsizeof=%ld\n",
|
||||
elm_count(vals[i]), lsizeof(vals[i]));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* return count
|
||||
*/
|
||||
result.v_type = V_NUM;
|
||||
result.v_num = itoq(count);
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* CUSTOM */
|
51
custom/c_devnull.c
Normal file
51
custom/c_devnull.c
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Permission to use, copy, modify, and distribute this software and
|
||||
* its documentation for any purpose and without fee is hereby granted.
|
||||
*
|
||||
* LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
|
||||
* EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Comments, suggestions, bug fixes and questions about these routines
|
||||
* are welcome. Send EMail to the address given below.
|
||||
*
|
||||
* Happy bit twiddling,
|
||||
*
|
||||
* Landon Curt Noll
|
||||
* http://reality.sgi.com/chongo
|
||||
*
|
||||
* chongo <was here> /\../\
|
||||
*/
|
||||
|
||||
#if defined(CUSTOM)
|
||||
|
||||
|
||||
#include "../have_const.h"
|
||||
#include "../value.h"
|
||||
#include "../custom.h"
|
||||
|
||||
|
||||
/*
|
||||
* c_devnull - a custom function that does nothing
|
||||
*
|
||||
* This custom function does nothing. It is useful as a test hook
|
||||
* for looking at the general interface.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
VALUE
|
||||
c_devnull(char *name, int count, VALUE **vals)
|
||||
{
|
||||
VALUE result; /* what we will return */
|
||||
|
||||
/*
|
||||
* return NULL
|
||||
*/
|
||||
result.v_type = V_NULL;
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* CUSTOM */
|
75
custom/c_help.c
Normal file
75
custom/c_help.c
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Permission to use, copy, modify, and distribute this software and
|
||||
* its documentation for any purpose and without fee is hereby granted.
|
||||
*
|
||||
* LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
|
||||
* EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Comments, suggestions, bug fixes and questions about these routines
|
||||
* are welcome. Send EMail to the address given below.
|
||||
*
|
||||
* Happy bit twiddling,
|
||||
*
|
||||
* Landon Curt Noll
|
||||
* http://reality.sgi.com/chongo
|
||||
*
|
||||
* chongo <was here> /\../\
|
||||
*/
|
||||
|
||||
#if defined(CUSTOM)
|
||||
|
||||
|
||||
#include "../have_const.h"
|
||||
#include "../value.h"
|
||||
#include "../custom.h"
|
||||
|
||||
|
||||
/*
|
||||
* c_help - custom help function
|
||||
*
|
||||
* This function assumes that a help file with the same name as
|
||||
* the custom function has been installed by the custom/Makefile
|
||||
* (as listed in the CUSTOM_HELP makefile variable) under the
|
||||
* CUSTOMHELPDIR == HELPDIR/custhelp directory.
|
||||
*
|
||||
* The help command first does a search in HELPDIR and later
|
||||
* in CUSTOMHELPDIR. If a custom help file has the same name
|
||||
* as a file under HELPDIR then help will display the HELPDIR
|
||||
* file and NOT the custom file. This function will ignore
|
||||
* and HELPDIR file and work directly with the custom help file.
|
||||
*
|
||||
* given:
|
||||
* vals[0] name of the custom help file to directly access
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
VALUE
|
||||
c_help(char *name, int count, VALUE **vals)
|
||||
{
|
||||
VALUE result; /* what we will return */
|
||||
|
||||
/*
|
||||
* parse args
|
||||
*/
|
||||
if (vals[0]->v_type != V_STR) {
|
||||
math_error("custom help arg 1 must be a string");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
/*
|
||||
* give the help
|
||||
*/
|
||||
customhelp((char *)vals[0]->v_str);
|
||||
|
||||
/*
|
||||
* return NULL
|
||||
*/
|
||||
result.v_type = V_NULL;
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* CUSTOM */
|
70
custom/c_pzasusb8.c
Normal file
70
custom/c_pzasusb8.c
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Permission to use, copy, modify, and distribute this software and
|
||||
* its documentation for any purpose and without fee is hereby granted.
|
||||
*
|
||||
* Ernest Bowen, following Landon Curt Noll
|
||||
*/
|
||||
|
||||
#if defined(CUSTOM)
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../have_const.h"
|
||||
#include "../value.h"
|
||||
#include "../custom.h"
|
||||
#include "../zmath.h"
|
||||
|
||||
/*
|
||||
* c_pzasusb8 - print numereator of real as if its array of HALFs were
|
||||
* a string of USB8s
|
||||
*
|
||||
* given:
|
||||
* count = 1;
|
||||
* vals[0] real number;
|
||||
*
|
||||
* returns:
|
||||
* null
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
VALUE
|
||||
c_pzasusb8(char *name, int count, VALUE **vals)
|
||||
{
|
||||
VALUE result; /* what we will return */
|
||||
ZVALUE z; /* numerator of the value */
|
||||
long half_cnt; /* number of HALFs in the numerator */
|
||||
USB8 *h; /* octet pointer */
|
||||
long half_len; /* length of a half in octets */
|
||||
long i;
|
||||
long j;
|
||||
|
||||
/*
|
||||
* arg check
|
||||
*/
|
||||
result.v_type = V_NULL;
|
||||
if (vals[0]->v_type != V_NUM) {
|
||||
math_error("Non-real argument for pzasusb8");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
/*
|
||||
* look at the numerator
|
||||
*/
|
||||
z = vals[0]->v_num->num;
|
||||
half_len = sizeof(HALF);
|
||||
half_cnt = z.len;
|
||||
|
||||
/*
|
||||
* print the octets
|
||||
*/
|
||||
h = (USB8 *) z.v;
|
||||
for (i=0; i < half_cnt; ++i) {
|
||||
printf("%ld:\t", i);
|
||||
for (j=0; j < half_len; ++j) {
|
||||
printf("%02x", (int)(*h++));
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* CUSTOM */
|
364
custom/c_sysinfo.c
Normal file
364
custom/c_sysinfo.c
Normal file
@@ -0,0 +1,364 @@
|
||||
/*
|
||||
* Permission to use, copy, modify, and distribute this software and
|
||||
* its documentation for any purpose and without fee is hereby granted.
|
||||
*
|
||||
* LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
|
||||
* EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Comments, suggestions, bug fixes and questions about these routines
|
||||
* are welcome. Send EMail to the address given below.
|
||||
*
|
||||
* Happy bit twiddling,
|
||||
*
|
||||
* Landon Curt Noll
|
||||
* http://reality.sgi.com/chongo
|
||||
*
|
||||
* chongo <was here> /\../\
|
||||
*/
|
||||
|
||||
#if defined(CUSTOM)
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "../have_const.h"
|
||||
#include "../value.h"
|
||||
#include "../custom.h"
|
||||
|
||||
#include "../config.h"
|
||||
#include "../calc.h"
|
||||
#include "../longbits.h"
|
||||
#include "../longlong.h"
|
||||
#include "../block.h"
|
||||
#include "../calcerr.h"
|
||||
#include "../conf.h"
|
||||
#include "../endian_calc.h"
|
||||
#include "../fposval.h"
|
||||
#include "../hist.h"
|
||||
#include "../prime.h"
|
||||
#include "../zrand.h"
|
||||
#include "../zrandom.h"
|
||||
|
||||
|
||||
/*
|
||||
* sys_info - names and values of selected #defines
|
||||
*/
|
||||
struct infoname {
|
||||
char *name; /* name of #define converted to all UPPER_CASE */
|
||||
char *meaning; /* brief explanation of the #define */
|
||||
char *str; /* non-NULL ==> value of #define is a string */
|
||||
FULL nmbr; /* if str==NULL ==> value fo #define as a FULL */
|
||||
};
|
||||
static struct infoname sys_info[] = {
|
||||
{"A55", "slots in an additive 55 table", NULL, (FULL)A55},
|
||||
{"BASE", "base for calculations", NULL, (FULL)BASE},
|
||||
{"BASE1", "one less than base", NULL, (FULL)BASE},
|
||||
{"BASEB", "bits in the calculation base", NULL, (FULL)BASEB},
|
||||
{"BASEDIG", "number of digits in base", NULL, (FULL)BASEDIG},
|
||||
{"BIG_ENDIAN", "Most Significant Byte first symbol", NULL, (FULL)BIG_ENDIAN},
|
||||
{"BLK_CHUNKSIZE", "default allocation chunk size for blocks", NULL, (FULL)BLK_CHUNKSIZE},
|
||||
{"BLK_DEF_MAXPRINT", "default block octets to print", NULL, (FULL)BLK_DEF_MAXPRINT},
|
||||
{"BLUM_PREGEN", "non-default predefined Blum generators", NULL, (FULL)BLUM_PREGEN},
|
||||
{"BOOL_B64", "if we have 64 bit type (TRUE or FALSE)", NULL, (FULL)BOOL_B64},
|
||||
{"CALCEXT", "extension for files read in", CALCEXT, (FULL)0},
|
||||
{"CALC_BYTE_ORDER", "Byte order (LITTLE_ENDIAN or BIG_ENDIAN)", NULL, (FULL)CALC_BYTE_ORDER},
|
||||
{"CUSTOMHELPDIR", "location of the custom help directory", CUSTOMHELPDIR, (FULL)0},
|
||||
{"DEFAULTCALCBINDINGS", "default key bindings file", DEFAULTCALCBINDINGS, (FULL)0},
|
||||
{"DEFAULTCALCHELP", "help file that -h prints", DEFAULTCALCHELP, (FULL)0},
|
||||
{"DEFAULTCALCPAGER", "default pager", DEFAULTCALCPAGER, (FULL)0},
|
||||
{"DEFAULTCALCPATH", "default :-separated search path", DEFAULTCALCPATH, (FULL)0},
|
||||
{"DEFAULTCALCRC", "default :-separated startup file list", DEFAULTCALCRC, (FULL)0},
|
||||
{"DEFAULTSHELL", "default shell to use", DEFAULTSHELL, (FULL)0},
|
||||
{"DEV_BITS", "device number size in bits", NULL, (FULL)DEV_BITS},
|
||||
{"DISPLAY_DEFAULT", "default digits for float display", NULL, (FULL)DISPLAY_DEFAULT},
|
||||
{"ECHO", "where the echo command is located", ECHO, (FULL)0},
|
||||
{"EPSILONPREC_DEFAULT", "2^-EPSILON_DEFAULT <= EPSILON_DEFAULT", NULL, (FULL)EPSILONPREC_DEFAULT},
|
||||
{"EPSILON_DEFAULT", "allowed error for float calculations", EPSILON_DEFAULT, (FULL)0},
|
||||
{"ERRMAX", "default errmax value", NULL, (FULL)ERRMAX},
|
||||
{"E_USERDEF", "base of user defined errors", NULL, (FULL)E_USERDEF},
|
||||
{"E__BASE", "calc errors start above here", NULL, (FULL)E__BASE},
|
||||
{"E__COUNT", "number of calc errors", NULL, (FULL)E__COUNT},
|
||||
{"E__HIGHEST", "highest calc error", NULL, (FULL)E__HIGHEST},
|
||||
{"FALSE", "boolean false", NULL, (FULL)FALSE},
|
||||
{"FILEPOS_BITS", "file position size in bits", NULL, (FULL)FILEPOS_BITS},
|
||||
{"FULL_BITS", "bits in a FULL", NULL, (FULL)FULL_BITS},
|
||||
{"HELPDIR", "location of the help directory", HELPDIR, (FULL)0},
|
||||
{"HIST_BINDING_FILE", "Default binding file", HIST_BINDING_FILE, (FULL)0},
|
||||
{"HIST_SIZE", "Default history size", NULL, (FULL)HIST_SIZE},
|
||||
{"INIT_J", "initial 1st walking a55 table index", NULL, (FULL)INIT_J},
|
||||
{"INIT_K", "initial 2nd walking a55 table index", NULL, (FULL)INIT_K},
|
||||
{"INODE_BITS", "inode number size in bits", NULL, (FULL)INODE_BITS},
|
||||
{"LITTLE_ENDIAN", "Least Significant Byte first symbol", NULL, (FULL)LITTLE_ENDIAN},
|
||||
{"LONGLONG_BITS", "length of a long long, or 0", NULL, (FULL)LONGLONG_BITS},
|
||||
{"LONG_BITS", "bit length of a long", NULL, (FULL)LONG_BITS},
|
||||
{"MAP_POPCNT", "number of odd primes in pr_map", NULL, (FULL)MAP_POPCNT},
|
||||
{"MAX_CALCRC", "maximum allowed length of $CALCRC", NULL, (FULL)MAX_CALCRC},
|
||||
{"MAXCMD", "max length of command invocation", NULL, (FULL)MAXCMD},
|
||||
{"MAXDIM", "max number of dimensions in matrices", NULL, (FULL)MAXDIM},
|
||||
{"MAXERROR", "max length of error message string", NULL, (FULL)MAXERROR},
|
||||
{"MAXFILES", "max number of opened files", NULL, (FULL)MAXFILES},
|
||||
{"MAXFULL", "largest SFULL value", NULL, (FULL)MAXFULL},
|
||||
{"MAXHALF", "largest SHALF value", NULL, (FULL)MAXHALF},
|
||||
{"MAXINDICES", "max number of indices for objects", NULL, (FULL)MAXINDICES},
|
||||
{"MAXLABELS", "max number of user labels in function", NULL, (FULL)MAXLABELS},
|
||||
{"MAXLEN", "longest storage size allowed", NULL, (FULL)MAXLEN},
|
||||
{"MAXLONG", "largest long val", NULL, (FULL)MAXLONG},
|
||||
{"MAXOBJECTS", "max number of object types", NULL, (FULL)MAXOBJECTS},
|
||||
{"MAXPRINT_DEFAULT", "default number of elements printed", NULL, (FULL)MAXPRINT_DEFAULT},
|
||||
{"MAXREDC", "number of entries in REDC cache", NULL, (FULL)MAXREDC},
|
||||
{"MAXSCANCOUNT", "default max scan errors before an abort", NULL, (FULL)MAXSCANCOUNT},
|
||||
{"MAXSTACK", "max depth of evaluation stack", NULL, (FULL)MAXSTACK},
|
||||
{"MAXSTRING", "max size of string constant", NULL, (FULL)MAXSTRING},
|
||||
{"MAXUFULL", "largest FULL value", NULL, (FULL)MAXUFULL},
|
||||
{"MAXULONG", "largest unsigned long val", NULL, (FULL)MAXULONG},
|
||||
{"MAX_MAP_PRIME", "larest prime in pr_map", NULL, (FULL)MAX_MAP_PRIME},
|
||||
{"MAX_MAP_VAL", "larest bit in pr_map", NULL, (FULL)MAX_MAP_VAL},
|
||||
{"MAX_PFACT_VAL", "max x, for which pfact(x) is a long", NULL, (FULL)MAX_PFACT_VAL},
|
||||
{"MAX_SM_PRIME", "larest 32 bit prime", NULL, (FULL)MAX_SM_PRIME},
|
||||
{"MAX_SM_VAL", "larest 32 bit value", NULL, (FULL)MAX_SM_VAL},
|
||||
{"MUL_ALG2", "default size for alternative multiply", NULL, (FULL)MUL_ALG2},
|
||||
{"NEW_EPSILONPREC_DEFAULT", "2^-EPSILON_DEFAULT <= EPSILON_DEFAULT", NULL, (FULL)NEW_EPSILONPREC_DEFAULT},
|
||||
{"NEW_EPSILON_DEFAULT", "newstd EPSILON_DEFAULT", NEW_EPSILON_DEFAULT, (FULL)0},
|
||||
{"NXT_MAP_PRIME", "smallest odd prime not in pr_map", NULL, (FULL)NXT_MAP_PRIME},
|
||||
{"NXT_PFACT_VAL", "next prime for higher pfact values", NULL, (FULL)NXT_PFACT_VAL},
|
||||
{"OFF_T_BITS", "file offset size in bits", NULL, (FULL)OFF_T_BITS},
|
||||
{"PIX_32B", "max pix() value", NULL, (FULL)PIX_32B},
|
||||
{"POW_ALG2", "default size for using REDC for powers", NULL, (FULL)POW_ALG2},
|
||||
{"REDC_ALG2", "default size using alternative REDC alg", NULL, (FULL)REDC_ALG2},
|
||||
{"SBITS", "size of additive or shuffle entry in bits", NULL, (FULL)SBITS},
|
||||
{"SBYTES", "size of additive or shuffle entry in bytes", NULL, (FULL)SBYTES},
|
||||
{"SCNT", "length of additive 55 table in FULLs", NULL, (FULL)SCNT},
|
||||
{"SEEDXORBITS", "low bits of a55 seed devoted to xor", NULL, (FULL)SEEDXORBITS},
|
||||
{"SHALFS", "size of additive or shuffle entry in HALFs", NULL, (FULL)SHALFS},
|
||||
{"SHUFCNT", "size of shuffle table in entries", NULL, (FULL)SHUFCNT},
|
||||
{"SHUFLEN", "length of shuffle table in FULLs", NULL, (FULL)SHUFLEN},
|
||||
{"SHUFMASK", "mask for shuffle table entry selection", NULL, (FULL)SHUFMASK},
|
||||
{"SHUFPOW", "power of 2 size of the shuffle table", NULL, (FULL)SHUFPOW},
|
||||
{"SLEN", "number of FULLs in a shuffle table entry", NULL, (FULL)SLEN},
|
||||
{"SQ_ALG2", "default size for alternative squaring", NULL, (FULL)SQ_ALG2},
|
||||
{"SYMBOLSIZE", "max symbol name size", NULL, (FULL)SYMBOLSIZE},
|
||||
{"TEN_MAX", "10^(2^TEN_MAX): largest base10 conversion const", NULL, (FULL)TEN_MAX},
|
||||
{"TOPFULL", "highest bit in FULL", NULL, (FULL)TOPFULL},
|
||||
{"TOPHALF", "highest bit in a HALF", NULL, (FULL)TOPHALF},
|
||||
{"TOPLONG", "top long bit", NULL, (FULL)TOPLONG},
|
||||
{"TRUE", "boolean true", NULL, (FULL)TRUE},
|
||||
{"USUAL_ELEMENTS", "usual number of elements for objects", NULL, (FULL)USUAL_ELEMENTS},
|
||||
|
||||
/* must be last */
|
||||
{NULL, NULL, NULL, (FULL)0}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* forward declarations
|
||||
*/
|
||||
static void dump_name_meaning(void); /* custom("sysinfo", 0) */
|
||||
static void dump_name_value(void); /* custom("sysinfo", 1) */
|
||||
static void dump_mening_value(void); /* custom("sysinfo", 2) */
|
||||
|
||||
|
||||
/*
|
||||
* c_sysinfo - return a calc #define value
|
||||
*
|
||||
* given:
|
||||
* vals[0] if given, name of #define to print
|
||||
* otherwise a list of #defines are printed
|
||||
*
|
||||
* returns:
|
||||
* value of #define if given (int or string)
|
||||
* null if no #define arg was given
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
VALUE
|
||||
c_sysinfo(char *name, int count, VALUE **vals)
|
||||
{
|
||||
VALUE result; /* what we will return */
|
||||
struct infoname *p; /* current infoname */
|
||||
char *buf; /* upper case value of vals[0] */
|
||||
char *q; /* to upper case converter */
|
||||
char *r; /* to upper case converter */
|
||||
|
||||
/*
|
||||
* we will return NULL if a value was not found
|
||||
*/
|
||||
result.v_type = V_NULL;
|
||||
|
||||
/*
|
||||
* case 0: if no args, then dump the table with no values
|
||||
*/
|
||||
if (count == 0) {
|
||||
|
||||
/* dump the entire table */
|
||||
dump_name_meaning();
|
||||
|
||||
/*
|
||||
* case 1: numeric arg is given
|
||||
*/
|
||||
} else if (vals[0]->v_type == V_NUM) {
|
||||
|
||||
/* firewall - must be a tiny non-negative integer */
|
||||
if (qisneg(vals[0]->v_num) ||
|
||||
qisfrac(vals[0]->v_num) ||
|
||||
zge31b(vals[0]->v_num->num)) {
|
||||
math_error("sysinfo: arg must be string, 0, 1 or 2");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
/*
|
||||
* select action based on numeric value of arg
|
||||
*/
|
||||
switch (z1tol(vals[0]->v_num->num)) {
|
||||
case 0: /* print all infonames and meanings */
|
||||
dump_name_meaning();
|
||||
break;
|
||||
case 1: /* print all infonames and values */
|
||||
dump_name_value();
|
||||
break;
|
||||
case 2: /* print all values and meanings */
|
||||
dump_mening_value();
|
||||
break;
|
||||
default:
|
||||
math_error("sysinfo: arg must be string, 0, 1 or 2");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
/*
|
||||
* case 2: string arg is given
|
||||
*
|
||||
* The string is taken to be the infoname we want to print.
|
||||
*/
|
||||
} else if (vals[0]->v_type == V_STR) {
|
||||
|
||||
/* convert vals[0] to upper case string */
|
||||
buf = (char *)malloc(strlen((char *)vals[0]->v_str->s_str)+1);
|
||||
for (q = (char *)vals[0]->v_str->s_str, r = buf; *q; ++q, ++r)
|
||||
{
|
||||
if (isascii((int)*q) && islower((int)*q)) {
|
||||
*r = *q - 'a' + 'A';
|
||||
} else {
|
||||
*r = *q;
|
||||
}
|
||||
}
|
||||
*r = '\0';
|
||||
|
||||
/* search the table for the infoname */
|
||||
for (p = sys_info; p->name != NULL; ++p) {
|
||||
|
||||
if (strcmp(p->name, buf) == 0) {
|
||||
|
||||
/* found the infoname */
|
||||
if (p->str == NULL) {
|
||||
/* return value as integer */
|
||||
result.v_type = V_NUM;
|
||||
result.v_num = utoq( p->nmbr);
|
||||
} else {
|
||||
/* return value as string */
|
||||
result.v_type = V_STR;
|
||||
result.v_subtype = V_NOSUBTYPE;
|
||||
result.v_str = makestring(p->str);
|
||||
}
|
||||
|
||||
/* return found infotype as value */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* bad arg given
|
||||
*/
|
||||
} else {
|
||||
math_error("sysinfo: arg must be string, 0, 1 or 2");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
/*
|
||||
* return what we found or didn't find
|
||||
*/
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* dump_name_meaning - print all infonames and meanings
|
||||
*/
|
||||
static void
|
||||
dump_name_meaning(void)
|
||||
{
|
||||
struct infoname *p; /* current infoname */
|
||||
|
||||
/* dump the entire table */
|
||||
for (p = sys_info; p->name != NULL; ++p) {
|
||||
printf("%s%-23s\t%s\n",
|
||||
(conf->tab_ok ? "\t" : ""), p->name, p->meaning);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* dump_name_value - print all infonames and values
|
||||
*/
|
||||
static void
|
||||
dump_name_value(void)
|
||||
{
|
||||
struct infoname *p; /* current infoname */
|
||||
|
||||
/* dump the entire table */
|
||||
for (p = sys_info; p->name != NULL; ++p) {
|
||||
if (p->str == NULL) {
|
||||
#if LONG_BITS == FULL_BITS || FULL_BITS == 32 || !defined(HAVE_LONGLONG)
|
||||
printf("%s%-23s\t%-8lu\t(0x%lx)\n",
|
||||
(conf->tab_ok ? "\t" : ""), p->name,
|
||||
(unsigned long)p->nmbr,
|
||||
(unsigned long)p->nmbr);
|
||||
#else
|
||||
printf("%s%-23s\t%-8llu\t(0x%llx)\n",
|
||||
(conf->tab_ok ? "\t" : ""), p->name,
|
||||
(unsigned long long)p->nmbr,
|
||||
(unsigned long long)p->nmbr);
|
||||
#endif
|
||||
} else {
|
||||
printf("%s%-23s\t\"%s\"\n",
|
||||
(conf->tab_ok ? "\t" : ""), p->name, p->str);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* dump_mening_value - print all values and meanings
|
||||
*/
|
||||
static void
|
||||
dump_mening_value(void)
|
||||
{
|
||||
struct infoname *p; /* current infoname */
|
||||
|
||||
/* dump the entire table */
|
||||
for (p = sys_info; p->name != NULL; ++p) {
|
||||
if (p->str == NULL) {
|
||||
#if LONG_BITS == FULL_BITS || FULL_BITS == 32 || !defined(HAVE_LONGLONG)
|
||||
printf("%s%-36.36s\t%-8lu\t(0x%lx)\n",
|
||||
(conf->tab_ok ? "\t" : ""), p->meaning,
|
||||
(unsigned long)p->nmbr,
|
||||
(unsigned long)p->nmbr);
|
||||
#else
|
||||
printf("%s%-36.36s\t%-8llu\t(0x%llx)\n",
|
||||
(conf->tab_ok ? "\t" : ""), p->meaning,
|
||||
(unsigned long long)p->nmbr,
|
||||
(unsigned long long)p->nmbr);
|
||||
#endif
|
||||
} else {
|
||||
printf("%s%-36.36s\t\"%s\"\n",
|
||||
(conf->tab_ok ? "\t" : ""), p->meaning, p->str);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif /* CUSTOM */
|
121
custom/custtbl.c
Normal file
121
custom/custtbl.c
Normal file
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright (c) 1997 by Landon Curt Noll. All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software and
|
||||
* its documentation for any purpose and without fee is hereby granted,
|
||||
* provided that the above copyright, this permission notice and text
|
||||
* this comment, and the disclaimer below appear in all of the following:
|
||||
*
|
||||
* supporting documentation
|
||||
* source copies
|
||||
* source works derived from this source
|
||||
* binaries derived from this source or from derived source
|
||||
*
|
||||
* LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
|
||||
* EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Comments, suggestions, bug fixes and questions about these routines
|
||||
* are welcome. Send EMail to the address given below.
|
||||
*
|
||||
* Happy bit twiddling,
|
||||
*
|
||||
* Landon Curt Noll
|
||||
* http://reality.sgi.com/chongo
|
||||
*
|
||||
* chongo <was here> /\../\
|
||||
*/
|
||||
|
||||
|
||||
#include "../have_const.h"
|
||||
#include "../value.h"
|
||||
#include "../custom.h"
|
||||
|
||||
/*
|
||||
* NOTE: See the file CUSTOM for instructions on how to add
|
||||
* custom functions.
|
||||
*/
|
||||
|
||||
|
||||
#if defined(CUSTOM)
|
||||
|
||||
|
||||
/*
|
||||
* add your forward custom function declaractions here
|
||||
*
|
||||
* Declare custom functions as follows:
|
||||
*
|
||||
* extern VALUE c_xyz(char*, int, VALUE**);
|
||||
*
|
||||
* We suggest that you sort the entries below by name.
|
||||
*/
|
||||
extern VALUE c_argv(char*, int, VALUE**);
|
||||
extern VALUE c_devnull(char*, int, VALUE**);
|
||||
extern VALUE c_help(char*, int, VALUE**);
|
||||
extern VALUE c_sysinfo(char*, int, VALUE**);
|
||||
extern VALUE c_pzasusb8(char*, int, VALUE**);
|
||||
|
||||
|
||||
#endif /* CUSTOM */
|
||||
|
||||
|
||||
/*
|
||||
* custom interface table
|
||||
*
|
||||
* The order of the elements in struct custom are:
|
||||
*
|
||||
* { "xyz", "brief description of the xyz custom function",
|
||||
* minimum_args, maximum_args, c_xyz },
|
||||
*
|
||||
* where:
|
||||
*
|
||||
* minimum_args an int >= 0
|
||||
* maximum_args an int >= minimum_args and <= MAX_CUSTOM_ARGS
|
||||
*
|
||||
* Use MAX_CUSTOM_ARGS for maximum_args is the maximum number of args
|
||||
* is potentially 'unlimited'.
|
||||
*
|
||||
* If the brief description cannot fit on the same line as the name
|
||||
* without wrapping on a 80 col window, the description is probably
|
||||
* too long and will not look nice in the show custom output.
|
||||
*/
|
||||
CONST struct custom cust[] = {
|
||||
|
||||
#if defined(CUSTOM)
|
||||
|
||||
|
||||
/*
|
||||
* add your own custom functions here
|
||||
*
|
||||
* We suggest that you sort the entries below by name
|
||||
* so that show custom will produce a nice sorted list.
|
||||
*/
|
||||
|
||||
{ "argv", "information about its args, returns arg count",
|
||||
0, MAX_CUSTOM_ARGS, c_argv },
|
||||
|
||||
{ "devnull", "does nothing",
|
||||
0, MAX_CUSTOM_ARGS, c_devnull },
|
||||
|
||||
{ "help", "help for custom functions",
|
||||
1, 1, c_help },
|
||||
|
||||
{ "sysinfo", "return a calc #define value",
|
||||
0, 1, c_sysinfo },
|
||||
|
||||
{ "pzasusb8", "print ZCALUE as USB8",
|
||||
0, 1, c_pzasusb8 },
|
||||
|
||||
|
||||
#endif /* CUSTOM */
|
||||
|
||||
/*
|
||||
* This must be at the end of this table!!!
|
||||
*/
|
||||
{NULL, NULL,
|
||||
0, 0, NULL}
|
||||
};
|
27
custom/devnull
Normal file
27
custom/devnull
Normal file
@@ -0,0 +1,27 @@
|
||||
NAME
|
||||
devnull - does nothing
|
||||
|
||||
SYNOPSIS
|
||||
custom("devnull" [, arg ...])
|
||||
|
||||
TYPES
|
||||
arg any
|
||||
|
||||
return null
|
||||
|
||||
DESCRIPTION
|
||||
This custom function does nothing. It is intented for testing
|
||||
of the general custom interface.
|
||||
|
||||
EXAMPLE
|
||||
> custom("devnull", foo, bar, baz, 3+4.5i, pi())
|
||||
|
||||
LIMITS
|
||||
calc must be built with ALLOW_CUSTOM= -DCUSTOM
|
||||
calc must be executed with a -C arg.
|
||||
|
||||
LIBRARY
|
||||
none
|
||||
|
||||
SEE ALSO
|
||||
custom
|
53
custom/halflen.cal
Normal file
53
custom/halflen.cal
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Permission to use, copy, modify, and distribute this software and
|
||||
* its documentation for any purpose and without fee is hereby granted.
|
||||
*
|
||||
* LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
|
||||
* EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* chongo was here /\../\ http://reality.sgi.com/chongo
|
||||
*/
|
||||
/*
|
||||
* halflen - determine the length of numeric value in HALFs
|
||||
*
|
||||
* This file is part of the custom sample calc files.
|
||||
*
|
||||
* NOTE: You must use a calc that was compiled with ALLOW_CUSTOM= -DCUSTOM
|
||||
* and run with a -C arg.
|
||||
*/
|
||||
define halflen(num)
|
||||
{
|
||||
local baseb = custom("sysinfo","BASEB"); /* bit len of a HALF */
|
||||
|
||||
/*
|
||||
* firewall
|
||||
*/
|
||||
if (!isnum(num)) {
|
||||
return newerror("halflen only works on numeric values");
|
||||
}
|
||||
|
||||
/*
|
||||
* determine the HALF length of a numeric value
|
||||
*/
|
||||
if (num == 0) {
|
||||
/* consider 0 to be 1 HALF long */
|
||||
return 1;
|
||||
} else if (isint(num)) {
|
||||
return (highbit(num)+baseb-1)/baseb;
|
||||
} else if (isreal(num)) {
|
||||
return halflen(num(num)) + halflen(den(num));
|
||||
} else if (isnum(num)) {
|
||||
return halflen(re(num)) + halflen(im(num));
|
||||
} else {
|
||||
return newerror("halflen only works on numeric values");
|
||||
}
|
||||
}
|
||||
|
||||
if (config("lib_debug") >= 0) {
|
||||
print "halflen(num) defined";
|
||||
}
|
28
custom/help
Normal file
28
custom/help
Normal file
@@ -0,0 +1,28 @@
|
||||
NAME
|
||||
help - help for custom functions
|
||||
|
||||
SYNOPSIS
|
||||
custom("help", name)
|
||||
|
||||
TYPES
|
||||
name string
|
||||
|
||||
return null
|
||||
|
||||
DESCRIPTION
|
||||
This custom function will display the help for the builtin function
|
||||
named by the name argument.
|
||||
|
||||
EXAMPLE
|
||||
> custom("help", "custom_cal")
|
||||
... output the same as is produced by help custhelp/custom_cal ...
|
||||
|
||||
LIMITS
|
||||
calc must be built with ALLOW_CUSTOM= -DCUSTOM
|
||||
calc must be executed with a -C arg.
|
||||
|
||||
LIBRARY
|
||||
none
|
||||
|
||||
SEE ALSO
|
||||
custom
|
50
custom/pzasusb8
Normal file
50
custom/pzasusb8
Normal file
@@ -0,0 +1,50 @@
|
||||
NAME
|
||||
pzasusb8 - print a number in hex octets
|
||||
|
||||
SYNOPSIS
|
||||
custom("pzasusb8", arg)
|
||||
|
||||
TYPES
|
||||
arg real
|
||||
|
||||
return null
|
||||
|
||||
DESCRIPTION
|
||||
This custom function prints out the numerator of a real value
|
||||
in octets. Each HALF value is printed in a separate line.
|
||||
|
||||
NOTE: The output will vary depending on the size of a HALF
|
||||
and the byte order of the system. See:
|
||||
|
||||
custom("sysinfo", "BASEB")
|
||||
custom("sysinfo", "CALC_BYTE_ORDER")
|
||||
|
||||
foe details.
|
||||
|
||||
This custom function is intented for testing of the general
|
||||
custom interface.
|
||||
|
||||
EXAMPLE
|
||||
> custom("pzasusb8", 0x01020304050607080910111213141516);
|
||||
0: 13141516
|
||||
1: 09101112
|
||||
2: 05060708
|
||||
3: 01020304
|
||||
|
||||
> custom("pzasusb8", 10^25)
|
||||
0: 4a000000
|
||||
1: 16140148
|
||||
2: 00084595
|
||||
|
||||
> printf("%x\n", 10^25);
|
||||
0x84595161401484a000000
|
||||
|
||||
LIMITS
|
||||
calc must be built with ALLOW_CUSTOM= -DCUSTOM
|
||||
calc must be executed with a -C arg.
|
||||
|
||||
LIBRARY
|
||||
none
|
||||
|
||||
SEE ALSO
|
||||
custom
|
29
custom/pzasusb8.cal
Normal file
29
custom/pzasusb8.cal
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Permission to use, copy, modify, and distribute this software and
|
||||
* its documentation for any purpose and without fee is hereby granted.
|
||||
*
|
||||
* Ernest Bowen, following Landon Curt Noll
|
||||
*/
|
||||
|
||||
print "p(n) prints array in which numerator of n is stored as a";
|
||||
print "sequence of 2-hex-digits representing unsigned characters.";
|
||||
print "h(n) printx n in hex notation. This should be the same as";
|
||||
print "p(n) except for (1) its leading 0x, (2) possible trailing zeros";
|
||||
print "in p(n), and (3) the order of the hex-digit pairs.";
|
||||
print "The following example show results for n = isqrt(2e100).";
|
||||
print "";
|
||||
|
||||
define p(n) {custom("pzasusb8", n); print;}
|
||||
define h(n) = printf("%x\n", n);
|
||||
|
||||
n = isqrt(2e100);
|
||||
print "";
|
||||
p(n);
|
||||
h(n);
|
||||
print "";
|
||||
print "BASEB: ", custom("sysinfo", "BASEB");
|
||||
print "CALC_BYTE_ORDER: ", custom("sysinfo", "CALC_BYTE_ORDER");
|
||||
print "BIG_ENDIAN: ", custom("sysinfo", "BIG_ENDIAN");
|
||||
print "LITTLE_ENDIAN: ", custom("sysinfo", "LITTLE_ENDIAN");
|
||||
print "LONG_BITS: ", custom("sysinfo", "LONG_BITS");
|
||||
print "LONGLONG_BITS: ", custom("sysinfo", "LONGLONG_BITS");
|
54
custom/sysinfo
Normal file
54
custom/sysinfo
Normal file
@@ -0,0 +1,54 @@
|
||||
NAME
|
||||
sysinfo - return a calc #define value
|
||||
|
||||
SYNOPSIS
|
||||
custom("sysinfo" [, infoname]);
|
||||
|
||||
TYPES
|
||||
infoname string or int
|
||||
|
||||
return int, string or null
|
||||
|
||||
DESCRIPTION
|
||||
|
||||
This custom function will return the value certain selected #defile
|
||||
values. The infoname arg must be a string that matches the given
|
||||
#define name. For conveience, the case infoname does not matter,
|
||||
so "baseb" and "BASEB" refer to the same #define value.
|
||||
|
||||
The return value is either an integer or a string depending on
|
||||
the type of #define selected. If infoname is unknown, NULL is returned.
|
||||
|
||||
If no infoname is given then a list of infonames and meanings
|
||||
are printed. In this case, null is returned.
|
||||
|
||||
If infoname is a number, then it is interpreted as follows:
|
||||
|
||||
0 print all infonames and meanings (same as no infoname)
|
||||
1 print all infonames and values
|
||||
2 print all infoname meanings and values
|
||||
|
||||
EXAMPLE
|
||||
> custom("sysinfo", "baseb")
|
||||
32
|
||||
|
||||
> custom("sysinfo")
|
||||
... a list of infonames and meanings are printed ...
|
||||
> custom("sysinfo", 0)
|
||||
... a list of infonames and meanings are printed ...
|
||||
|
||||
> custom("sysinfo", 1)
|
||||
... a list of infonames and values are printed ...
|
||||
|
||||
> custom("sysinfo", 2)
|
||||
... a list of infoname meanings and values are printed ...
|
||||
|
||||
LIMITS
|
||||
calc must be built with ALLOW_CUSTOM= -DCUSTOM
|
||||
calc must be executed with a -C arg.
|
||||
|
||||
LIBRARY
|
||||
none
|
||||
|
||||
SEE ALSO
|
||||
custom
|
60
endian.c
60
endian.c
@@ -39,40 +39,42 @@
|
||||
char byte[8] = { (char)0x12, (char)0x36, (char)0x48, (char)0x59,
|
||||
(char)0x01, (char)0x23, (char)0x45, (char)0x67 };
|
||||
|
||||
MAIN
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
/* pointers into the byte order array */
|
||||
int *intp = (int *)byte;
|
||||
/* pointers into the byte order array */
|
||||
int *intp = (int *)byte;
|
||||
#if defined(DEBUG)
|
||||
short *shortp = (short *)byte;
|
||||
long *longp = (long *)byte;
|
||||
short *shortp = (short *)byte;
|
||||
long *longp = (long *)byte;
|
||||
|
||||
printf("byte: %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
||||
byte[0], byte[1], byte[2], byte[3],
|
||||
byte[4], byte[5], byte[6], byte[7]);
|
||||
printf("short: %04x %04x %04x %04x\n",
|
||||
shortp[0], shortp[1], shortp[2], shortp[3]);
|
||||
printf("int: %08x %08x\n",
|
||||
intp[0], intp[1]);
|
||||
printf("long: %08x %08x\n",
|
||||
longp[0], longp[1]);
|
||||
printf("byte: %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
||||
byte[0], byte[1], byte[2], byte[3],
|
||||
byte[4], byte[5], byte[6], byte[7]);
|
||||
printf("short: %04x %04x %04x %04x\n",
|
||||
shortp[0], shortp[1], shortp[2], shortp[3]);
|
||||
printf("int: %08x %08x\n",
|
||||
intp[0], intp[1]);
|
||||
printf("long: %08x %08x\n",
|
||||
longp[0], longp[1]);
|
||||
#endif
|
||||
|
||||
/* Print the standard <machine/endian.h> defines */
|
||||
printf("#define BIG_ENDIAN\t4321\n");
|
||||
printf("#define LITTLE_ENDIAN\t1234\n");
|
||||
/* Print the standard <machine/endian.h> defines */
|
||||
printf("#define BIG_ENDIAN\t4321\n");
|
||||
printf("#define LITTLE_ENDIAN\t1234\n");
|
||||
|
||||
/* Determine byte order */
|
||||
if (intp[0] == 0x12364859) {
|
||||
/* Most Significant Byte first */
|
||||
printf("#define BYTE_ORDER\tBIG_ENDIAN\n");
|
||||
} else if (intp[0] == 0x59483612) {
|
||||
/* Least Significant Byte first */
|
||||
printf("#define BYTE_ORDER\tLITTLE_ENDIAN\n");
|
||||
} else {
|
||||
fprintf(stderr, "Unknown int Byte Order, set BYTE_ORDER in Makefile\n");
|
||||
exit(1);
|
||||
}
|
||||
exit(0);
|
||||
/* Determine byte order */
|
||||
if (intp[0] == 0x12364859) {
|
||||
/* Most Significant Byte first */
|
||||
printf("#define CALC_BYTE_ORDER\tBIG_ENDIAN\n");
|
||||
} else if (intp[0] == 0x59483612) {
|
||||
/* Least Significant Byte first */
|
||||
printf("#define CALC_BYTE_ORDER\tLITTLE_ENDIAN\n");
|
||||
} else {
|
||||
fprintf(stderr,
|
||||
"Unknown int Byte Order, set CALC_BYTE_ORDER in Makefile\n");
|
||||
exit(1);
|
||||
}
|
||||
/* exit(0); */
|
||||
return 0;
|
||||
}
|
||||
|
13
file.h
13
file.h
@@ -1,11 +1,16 @@
|
||||
/*
|
||||
* Copyright (c) 1996 David I. Bell
|
||||
* Copyright (c) 1997 David I. Bell
|
||||
* Permission is granted to use, distribute, or modify this source,
|
||||
* provided that this copyright notice remains intact.
|
||||
*
|
||||
* File I/O routines callable by users.
|
||||
*/
|
||||
|
||||
|
||||
#if !defined(__FILE_H__)
|
||||
#define __FILE_H__
|
||||
|
||||
|
||||
#include "have_fpos.h"
|
||||
|
||||
|
||||
@@ -56,5 +61,11 @@ typedef struct {
|
||||
/*
|
||||
* external functions
|
||||
*/
|
||||
extern FILEIO * findid(FILEID id, int mode);
|
||||
extern int fgetposid(FILEID id, FILEPOS *ptr);
|
||||
extern int fsetposid(FILEID id, FILEPOS *ptr);
|
||||
extern int get_open_siz(FILE *fp, ZVALUE *res);
|
||||
extern char* findfname(FILEID);
|
||||
|
||||
|
||||
#endif /* !__FILE_H__ */
|
||||
|
66
fposval.c
66
fposval.c
@@ -14,8 +14,8 @@
|
||||
*
|
||||
* FILEPOS_BITS length in bits of the type FILEPOS
|
||||
* SWAP_HALF_IN_FILEPOS will copy/swap FILEPOS into an HALF array
|
||||
* STSIZE_BITS length in bits of the st_size stat element
|
||||
* SWAP_HALF_IN_STSIZE will copy/swap st_size into an HALF array
|
||||
* OFF_T_BITS length in bits of the st_size stat element
|
||||
* SWAP_HALF_IN_OFF_T will copy/swap st_size into an HALF array
|
||||
* DEV_BITS length in bits of the st_dev stat element
|
||||
* SWAP_HALF_IN_DEV will copy/swap st_dev into an HALF array
|
||||
* INODE_BITS length in bits of the st_ino stat element
|
||||
@@ -55,10 +55,12 @@
|
||||
#include <sys/stat.h>
|
||||
#include "have_fpos.h"
|
||||
#include "endian_calc.h"
|
||||
#include "have_offscl.h"
|
||||
#include "have_posscl.h"
|
||||
|
||||
char *program; /* our name */
|
||||
|
||||
MAIN
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int stsizelen; /* bit length of st_size in buf */
|
||||
@@ -78,7 +80,7 @@ main(int argc, char **argv)
|
||||
fileposlen = sizeof(FILEPOS)*8;
|
||||
printf("#undef FILEPOS_BITS\n");
|
||||
printf("#define FILEPOS_BITS %d\n", fileposlen);
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
#if CALC_BYTE_ORDER == BIG_ENDIAN
|
||||
/*
|
||||
* Big Endian
|
||||
*/
|
||||
@@ -93,49 +95,64 @@ main(int argc, char **argv)
|
||||
program, fileposlen);
|
||||
exit(1);
|
||||
}
|
||||
#else /* BYTE_ORDER == BIG_ENDIAN */
|
||||
#else /* CALC_BYTE_ORDER == BIG_ENDIAN */
|
||||
/*
|
||||
* Little Endian
|
||||
*
|
||||
*/
|
||||
#if defined(HAVE_FILEPOS_SCALAR)
|
||||
printf("#define SWAP_HALF_IN_FILEPOS(dest, src)\t\t%s\n",
|
||||
"(*(dest) = *(src))");
|
||||
#else /* HAVE_FILEPOS_SCALAR */
|
||||
/*
|
||||
* Normally a "(*(dest) = *(src))" would do, but on some
|
||||
* systems, a FILEPOS is not a scalar hince we must memcpy.
|
||||
* systems a FILEPOS is not a scalar hince we must memcpy.
|
||||
*/
|
||||
printf("#define SWAP_HALF_IN_FILEPOS(dest, src)\t%s%d%s\n",
|
||||
"memcpy((void *)(dest), (void *)(src), sizeof(",fileposlen,"))");
|
||||
#endif /* BYTE_ORDER == BIG_ENDIAN */
|
||||
#endif /* HAVE_FILEPOS_SCALAR */
|
||||
#endif /* CALC_BYTE_ORDER == BIG_ENDIAN */
|
||||
putchar('\n');
|
||||
|
||||
/*
|
||||
* print the stat file size information
|
||||
*/
|
||||
stsizelen = sizeof(buf.st_size)*8;
|
||||
printf("#undef STSIZE_BITS\n");
|
||||
printf("#define STSIZE_BITS %d\n", stsizelen);
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
printf("#undef OFF_T_BITS\n");
|
||||
printf("#define OFF_T_BITS %d\n", stsizelen);
|
||||
#if CALC_BYTE_ORDER == BIG_ENDIAN
|
||||
/*
|
||||
* Big Endian
|
||||
*/
|
||||
if (stsizelen == 64) {
|
||||
printf("#define SWAP_HALF_IN_STSIZE(dest, src)\t\t%s\n",
|
||||
printf("#define SWAP_HALF_IN_OFF_T(dest, src)\t\t%s\n",
|
||||
"SWAP_HALF_IN_B64(dest, src)");
|
||||
} else if (stsizelen == 32) {
|
||||
printf("#define SWAP_HALF_IN_STSIZE(dest, src)\t\t%s\n",
|
||||
printf("#define SWAP_HALF_IN_OFF_T(dest, src)\t\t%s\n",
|
||||
"SWAP_HALF_IN_B32(dest, src)");
|
||||
} else {
|
||||
fprintf(stderr, "%s: unexpected st_size bit size: %d\n",
|
||||
program, stsizelen);
|
||||
exit(2);
|
||||
}
|
||||
#else /* BYTE_ORDER == BIG_ENDIAN */
|
||||
#else /* CALC_BYTE_ORDER == BIG_ENDIAN */
|
||||
/*
|
||||
* Little Endian
|
||||
*
|
||||
* Normally a "(*(dest) = *(src))" would do, but on some
|
||||
* systems, a STSIZE is not a scalar hince we must memcpy.
|
||||
* systems an off_t is not a scalar hince we must memcpy.
|
||||
*/
|
||||
printf("#define SWAP_HALF_IN_STSIZE(dest, src)\t%s%d%s\n",
|
||||
#if defined(HAVE_OFF_T_SCALAR)
|
||||
printf("#define SWAP_HALF_IN_OFF_T(dest, src)\t\t%s\n",
|
||||
"(*(dest) = *(src))");
|
||||
#else /* HAVE_OFF_T_SCALAR */
|
||||
/*
|
||||
* Normally a "(*(dest) = *(src))" would do, but on some
|
||||
* systems, a off_t is not a scalar hince we must memcpy.
|
||||
*/
|
||||
printf("#define SWAP_HALF_IN_OFF_T(dest, src)\t%s%d%s\n",
|
||||
"memcpy((void *)(dest), (void *)(src), sizeof(",stsizelen,"))");
|
||||
#endif /* BYTE_ORDER == BIG_ENDIAN */
|
||||
#endif /* HAVE_OFF_T_SCALAR */
|
||||
#endif /* CALC_BYTE_ORDER == BIG_ENDIAN */
|
||||
putchar('\n');
|
||||
|
||||
/*
|
||||
@@ -144,7 +161,7 @@ main(int argc, char **argv)
|
||||
devlen = sizeof(buf.st_dev)*8;
|
||||
printf("#undef DEV_BITS\n");
|
||||
printf("#define DEV_BITS %d\n", devlen);
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
#if CALC_BYTE_ORDER == BIG_ENDIAN
|
||||
/*
|
||||
* Big Endian
|
||||
*/
|
||||
@@ -162,7 +179,7 @@ main(int argc, char **argv)
|
||||
program, devlen);
|
||||
exit(3);
|
||||
}
|
||||
#else /* BYTE_ORDER == BIG_ENDIAN */
|
||||
#else /* CALC_BYTE_ORDER == BIG_ENDIAN */
|
||||
/*
|
||||
* Little Endian
|
||||
*
|
||||
@@ -171,7 +188,7 @@ main(int argc, char **argv)
|
||||
*/
|
||||
printf("#define SWAP_HALF_IN_DEV(dest, src)\t%s%d%s\n",
|
||||
"memcpy((void *)(dest), (void *)(src), sizeof(",devlen,"))");
|
||||
#endif /* BYTE_ORDER == BIG_ENDIAN */
|
||||
#endif /* CALC_BYTE_ORDER == BIG_ENDIAN */
|
||||
putchar('\n');
|
||||
|
||||
/*
|
||||
@@ -180,7 +197,7 @@ main(int argc, char **argv)
|
||||
inodelen = sizeof(buf.st_ino)*8;
|
||||
printf("#undef INODE_BITS\n");
|
||||
printf("#define INODE_BITS %d\n", inodelen);
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
#if CALC_BYTE_ORDER == BIG_ENDIAN
|
||||
/*
|
||||
* Big Endian
|
||||
*/
|
||||
@@ -198,7 +215,7 @@ main(int argc, char **argv)
|
||||
program, inodelen);
|
||||
exit(4);
|
||||
}
|
||||
#else /* BYTE_ORDER == BIG_ENDIAN */
|
||||
#else /* CALC_BYTE_ORDER == BIG_ENDIAN */
|
||||
/*
|
||||
* Little Endian
|
||||
*
|
||||
@@ -207,6 +224,7 @@ main(int argc, char **argv)
|
||||
*/
|
||||
printf("#define SWAP_HALF_IN_INODE(dest, src)\t%s%d%s\n",
|
||||
"memcpy((void *)(dest), (void *)(src), sizeof(",inodelen,"))");
|
||||
#endif /* BYTE_ORDER == BIG_ENDIAN */
|
||||
exit(0);
|
||||
#endif /* CALC_BYTE_ORDER == BIG_ENDIAN */
|
||||
/* exit(0); */
|
||||
return 0;
|
||||
}
|
||||
|
15
func.h
15
func.h
@@ -1,12 +1,13 @@
|
||||
/*
|
||||
* Copyright (c) 1993 David I. Bell
|
||||
* Copyright (c) 1997 David I. Bell
|
||||
* Permission is granted to use, distribute, or modify this source,
|
||||
* provided that this copyright notice remains intact.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef FUNC_H
|
||||
#define FUNC_H
|
||||
#if !defined(__FUNC_H__)
|
||||
#define __FUNC_H__
|
||||
|
||||
|
||||
#include "calc.h"
|
||||
#include "label.h"
|
||||
@@ -53,6 +54,9 @@ extern FUNC *findfunc(long index);
|
||||
extern char *namefunc(long index);
|
||||
extern BOOL evaluate(BOOL nestflag);
|
||||
extern long adduserfunc(char *name);
|
||||
extern void rmuserfunc(char *name);
|
||||
extern void rmalluserfunc(void);
|
||||
extern long getuserfunc(char *name);
|
||||
extern void beginfunc(char *name, BOOL newflag);
|
||||
extern int builtinopcode(long index);
|
||||
extern char *builtinname(long index);
|
||||
@@ -74,7 +78,8 @@ extern void clearopt(void);
|
||||
extern void updateoldvalue(FUNC *fp);
|
||||
extern void calculate(FUNC *fp, int argcount);
|
||||
extern VALUE builtinfunc(long index, int argcount, VALUE *stck);
|
||||
extern void freenumbers(FUNC *);
|
||||
extern void freefunc(FUNC *);
|
||||
|
||||
#endif
|
||||
|
||||
/* END CODE */
|
||||
#endif /* !__FUNC_H__ */
|
||||
|
112
hash.h
112
hash.h
@@ -1,6 +1,5 @@
|
||||
/* XXX - this code is currently not really used, but it will be soon */
|
||||
/*
|
||||
* Copyright (c) 1995 by Landon Curt Noll. All Rights Reserved.
|
||||
* Copyright (c) 1997 by Landon Curt Noll. All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software and
|
||||
* its documentation for any purpose and without fee is hereby granted,
|
||||
@@ -21,30 +20,107 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if !defined(HASH_H)
|
||||
#define HASH_H
|
||||
|
||||
#if !defined(__HASH_H__)
|
||||
#define __HASH_H__
|
||||
|
||||
|
||||
#include "shs.h"
|
||||
#include "shs1.h"
|
||||
#include "md5.h"
|
||||
#include "zmath.h"
|
||||
|
||||
|
||||
/* MAX_CHUNKSIZE is the largest chunksize of any hash */
|
||||
#define MAX_CHUNKSIZE (SHS1_CHUNKSIZE)
|
||||
|
||||
/* max size of debugging strings in xyz_print() functions */
|
||||
#define DEBUG_SIZE 127
|
||||
|
||||
|
||||
/*
|
||||
* hashstate - state of a hash system
|
||||
*
|
||||
* Hashing some types of values requires a checkpoint (chkpt function call)
|
||||
* to be performed, which pads buffered data with 0's and performs an
|
||||
* update. The checkpoint thus causes the value to start on a new hash
|
||||
* block boundary with no buffered data.
|
||||
*
|
||||
* Some data types (strings, BLOCKs and OCTETs) do not require a
|
||||
* checkpoint as long as the previous value hashed was a string,
|
||||
* BLOCK or OCTET.
|
||||
*/
|
||||
struct hashstate {
|
||||
int type; /* hash type (see XYZ_HASH_TYPE below) */
|
||||
BOOL prevstr; /* TRUE=>previous value hashed was a string */
|
||||
union {
|
||||
SHS_INFO hh_shs; /* old Secure Hash Standard */
|
||||
} h_union;
|
||||
};
|
||||
typedef struct hashstate HASH;
|
||||
/* For ease in referencing */
|
||||
#define h_shs h_union.hh_shs
|
||||
struct hashstate {
|
||||
int hashtype; /* XYZ_HASH_TYPE debug value */
|
||||
BOOL bytes; /* TRUE => reading bytes rather than words */
|
||||
void (*update)(HASH*, USB8*, USB32); /* update arbitrary length */
|
||||
void (*chkpt)(HASH*); /* checkpoint a state */
|
||||
void (*note)(int, HASH*); /* note a special value */
|
||||
void (*type)(int, HASH*); /* note a VALUE type */
|
||||
ZVALUE (*final)(HASH*); /* complete hash state */
|
||||
int (*cmp)(HASH*,HASH*); /* compare to states, TRUE => a!=b */
|
||||
void (*print)(HASH*); /* print the value of a hash */
|
||||
int base; /* XYZ_BASE special hash value */
|
||||
int chunksize; /* XYZ_CHUNKSIZE input chunk size */
|
||||
int unionsize; /* h_union element size */
|
||||
union { /* hash dependent states */
|
||||
USB8 data[1]; /* used by hash_value to hash below */
|
||||
SHS_INFO h_shs; /* old SHS/SHA internal state */
|
||||
SHS1_INFO h_shs1; /* new SHS-1/SHA-1 internal state */
|
||||
MD5_CTX h_md5; /* MD5 internal state */
|
||||
} h_union;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
/*
|
||||
* what to xor to digest value when hashing special values
|
||||
*
|
||||
* IMPORTANT: To avoid overlap due to the HASH_XYZ macros below, the
|
||||
* XYZ_BASE values should be unique random hex values
|
||||
* that end in 00 (i.e., 0 mod 256).
|
||||
*/
|
||||
#define SHS_BASE 0x12face00 /* old SHS / SHA */
|
||||
#define SHS1_BASE 0x23cafe00 /* new SHS-1 / SHA-1 */
|
||||
#define MD5_BASE 0x34feed00 /* MD5 */
|
||||
|
||||
|
||||
/*
|
||||
* XYZ_HASH_TYPE - hash types
|
||||
*
|
||||
* we support these hash types - must start with 0
|
||||
* we support these hash types
|
||||
*/
|
||||
#define SHS_HASH_TYPE 0
|
||||
#define HASH_TYPE_MAX 0 /* must be number of XYZ_HASH_TYPE values */
|
||||
#define SHS_HASH_TYPE 1
|
||||
#define SHS1_HASH_TYPE 2
|
||||
#define MD5_HASH_TYPE 3
|
||||
|
||||
#endif /* !HASH_H */
|
||||
|
||||
/*
|
||||
* Note a special value given the base value
|
||||
*/
|
||||
#define HASH_NEG(base) (1+base) /* note a negative value */
|
||||
#define HASH_COMPLEX(base) (2+base) /* note a complex value */
|
||||
#define HASH_DIV(base) (4+base) /* note a division by a value */
|
||||
#define HASH_ZERO(base) (8+base) /* note a zero numeric value */
|
||||
#define HASH_ZVALUE(base) (16+base) /* note a ZVALUE */
|
||||
|
||||
|
||||
/*
|
||||
* external functions
|
||||
*/
|
||||
extern HASH* hash_init(int, HASH*);
|
||||
extern void hash_free(HASH*);
|
||||
extern HASH* hash_copy(HASH*);
|
||||
extern int hash_cmp(HASH*, HASH*);
|
||||
extern void hash_print(HASH*);
|
||||
extern ZVALUE hash_final(HASH*);
|
||||
extern HASH* hash_long(int, long, HASH*);
|
||||
extern HASH* hash_zvalue(int, ZVALUE, HASH*);
|
||||
extern HASH* hash_number(int, void*, HASH*);
|
||||
extern HASH* hash_complex(int, void*, HASH*);
|
||||
extern HASH* hash_str(int, char*, HASH*);
|
||||
extern HASH* hash_usb8(int, USB8*, int, HASH*);
|
||||
extern HASH* hash_value(int, void*, HASH*);
|
||||
|
||||
|
||||
#endif /* !__HASH_H__ */
|
||||
|
12
have_const.c
12
have_const.c
@@ -40,19 +40,27 @@
|
||||
* chongo was here /\../\
|
||||
*/
|
||||
|
||||
MAIN
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
#if defined(HAVE_NO_CONST)
|
||||
|
||||
printf("#undef HAVE_CONST /* no */\n");
|
||||
printf("#undef CONST\n");
|
||||
printf("#define CONST /* no */\n");
|
||||
|
||||
#else /* HAVE_NO_CONST */
|
||||
|
||||
const char * const str = "const";
|
||||
|
||||
printf("#define HAVE_CONST /* yes */\n");
|
||||
printf("#undef CONST\n");
|
||||
printf("#define CONST %s /* yes */\n", str);
|
||||
|
||||
#endif /* HAVE_NO_CONST */
|
||||
exit(0);
|
||||
|
||||
/* exit(0); */
|
||||
return 0;
|
||||
}
|
||||
|
23
have_fpos.c
23
have_fpos.c
@@ -32,22 +32,23 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
MAIN
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
#if !defined(HAVE_NO_FPOS)
|
||||
fpos_t pos; /* file position */
|
||||
fpos_t pos; /* file position */
|
||||
|
||||
/* get the current position */
|
||||
(void) fgetpos(stdin, &pos);
|
||||
/* get the current position */
|
||||
(void) fgetpos(stdin, &pos);
|
||||
|
||||
/* set the current position */
|
||||
(void) fsetpos(stdin, &pos);
|
||||
/* set the current position */
|
||||
(void) fsetpos(stdin, &pos);
|
||||
|
||||
/* print a have_fpos.h body that says we have the functions */
|
||||
printf("#undef HAVE_FPOS\n");
|
||||
printf("#define HAVE_FPOS 1 /* yes */\n\n");
|
||||
printf("typedef fpos_t FILEPOS;\n");
|
||||
/* print a have_fpos.h body that says we have the functions */
|
||||
printf("#undef HAVE_FPOS\n");
|
||||
printf("#define HAVE_FPOS 1 /* yes */\n\n");
|
||||
printf("typedef fpos_t FILEPOS;\n");
|
||||
#endif
|
||||
exit(0);
|
||||
/* exit(0); */
|
||||
return 0;
|
||||
}
|
||||
|
60
have_getpgid.c
Normal file
60
have_getpgid.c
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* have_getpgid - Determine if we getpgid()
|
||||
*
|
||||
* usage:
|
||||
* have_getpgid
|
||||
*
|
||||
* Not all systems have the getpgid() function, so this may not
|
||||
* compile on your system.
|
||||
*
|
||||
* This prog outputs several defines:
|
||||
*
|
||||
* HAVE_GETPGID
|
||||
* defined ==> use getpgid()
|
||||
* undefined ==> do not or cannot call getpgid()
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1999 by Landon Curt Noll. All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software and
|
||||
* its documentation for any purpose and without fee is hereby granted,
|
||||
* provided that the above copyright, this permission notice and text
|
||||
* this comment, and the disclaimer below appear in all of the following:
|
||||
*
|
||||
* supporting documentation
|
||||
* source copies
|
||||
* source works derived from this source
|
||||
* binaries derived from this source or from derived source
|
||||
*
|
||||
* LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
|
||||
* EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* chongo was here /\../\
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
#if defined(HAVE_NO_GETPGID)
|
||||
|
||||
printf("#undef HAVE_GETPGID /* no */\n");
|
||||
|
||||
#else /* HAVE_NO_GETPGID */
|
||||
|
||||
(void) getpgid((pid_t)0);
|
||||
|
||||
printf("#define HAVE_GETPGID /* yes */\n");
|
||||
|
||||
#endif /* HAVE_NO_GETPGID */
|
||||
|
||||
/* exit(0); */
|
||||
return 0;
|
||||
}
|
59
have_getprid.c
Normal file
59
have_getprid.c
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* have_getprid - Determine if we getprid()
|
||||
*
|
||||
* usage:
|
||||
* have_getprid
|
||||
*
|
||||
* Not all systems have the getprid() function, so this may not
|
||||
* compile on your system.
|
||||
*
|
||||
* This prog outputs several defines:
|
||||
*
|
||||
* HAVE_GETPRID
|
||||
* defined ==> use getprid()
|
||||
* undefined ==> do not or cannot call getprid()
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1999 by Landon Curt Noll. All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software and
|
||||
* its documentation for any purpose and without fee is hereby granted,
|
||||
* provided that the above copyright, this permission notice and text
|
||||
* this comment, and the disclaimer below appear in all of the following:
|
||||
*
|
||||
* supporting documentation
|
||||
* source copies
|
||||
* source works derived from this source
|
||||
* binaries derived from this source or from derived source
|
||||
*
|
||||
* LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
|
||||
* EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* chongo was here /\../\
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
#if defined(HAVE_NO_GETPRID)
|
||||
|
||||
printf("#undef HAVE_GETPRID /* no */\n");
|
||||
|
||||
#else /* HAVE_NO_GETPRID */
|
||||
|
||||
(void) getprid();
|
||||
printf("#define HAVE_GETPRID /* yes */\n");
|
||||
|
||||
#endif /* HAVE_NO_GETPRID */
|
||||
|
||||
/* exit(0); */
|
||||
return 0;
|
||||
}
|
59
have_getsid.c
Normal file
59
have_getsid.c
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* have_getsid - Determine if we getsid()
|
||||
*
|
||||
* usage:
|
||||
* have_getsid
|
||||
*
|
||||
* Not all systems have the getsid() function, so this may not
|
||||
* compile on your system.
|
||||
*
|
||||
* This prog outputs several defines:
|
||||
*
|
||||
* HAVE_GETSID
|
||||
* defined ==> use getsid()
|
||||
* undefined ==> do not call or cannot call getsid()
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1999 by Landon Curt Noll. All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software and
|
||||
* its documentation for any purpose and without fee is hereby granted,
|
||||
* provided that the above copyright, this permission notice and text
|
||||
* this comment, and the disclaimer below appear in all of the following:
|
||||
*
|
||||
* supporting documentation
|
||||
* source copies
|
||||
* source works derived from this source
|
||||
* binaries derived from this source or from derived source
|
||||
*
|
||||
* LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
|
||||
* EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* chongo was here /\../\
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
#if defined(HAVE_NO_GETSID)
|
||||
|
||||
printf("#undef HAVE_GETSID /* no */\n");
|
||||
|
||||
#else /* HAVE_NO_GETSID */
|
||||
|
||||
(void) getsid((pid_t)0);
|
||||
|
||||
printf("#define HAVE_GETSID /* yes */\n");
|
||||
|
||||
#endif /* HAVE_NO_GETSID */
|
||||
|
||||
/* exit(0); */
|
||||
return 0;
|
||||
}
|
74
have_gettime.c
Normal file
74
have_gettime.c
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* have_gettime - Determine if we clock_gettime()
|
||||
*
|
||||
* usage:
|
||||
* have_gettime
|
||||
*
|
||||
* Not all systems have the clock_gettime() function, so this may not
|
||||
* compile on your system.
|
||||
*
|
||||
* This prog outputs several defines:
|
||||
*
|
||||
* HAVE_GETTIME
|
||||
* defined ==> use clock_gettime() for either CLOCK_SGI_CYCLE
|
||||
* and/or CLOCK_REALTIME
|
||||
* undefined ==> clock_gettime() is not available for both
|
||||
* CLOCK_SGI_CYCLE and CLOCK_REALTIME
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1999 by Landon Curt Noll. All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software and
|
||||
* its documentation for any purpose and without fee is hereby granted,
|
||||
* provided that the above copyright, this permission notice and text
|
||||
* this comment, and the disclaimer below appear in all of the following:
|
||||
*
|
||||
* supporting documentation
|
||||
* source copies
|
||||
* source works derived from this source
|
||||
* binaries derived from this source or from derived source
|
||||
*
|
||||
* LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
|
||||
* EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* chongo was here /\../\
|
||||
*/
|
||||
|
||||
#include <time.h>
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
#if defined(HAVE_NO_GETTIME)
|
||||
|
||||
printf("#undef HAVE_GETTIME /* no */\n");
|
||||
|
||||
#else /* HAVE_NO_GETTIME */
|
||||
|
||||
# if defined(CLOCK_SGI_CYCLE)
|
||||
|
||||
struct timespec sgi_cycle; /* SGI hardware clock */
|
||||
(void) clock_gettime(CLOCK_SGI_CYCLE, &sgi_cycle);
|
||||
printf("#define HAVE_GETTIME /* yes - w/CLOCK_SGI_CYCLE */\n");
|
||||
|
||||
# elif defined(CLOCK_REALTIME)
|
||||
|
||||
struct timespec realtime; /* POSIX realtime clock */
|
||||
(void) clock_gettime(CLOCK_REALTIME, &realtime);
|
||||
printf("#define HAVE_GETTIME /* yes - CLOCK_REALTIME only */\n");
|
||||
|
||||
# else
|
||||
|
||||
printf("#undef HAVE_GETTIME /* no - no SGI_CYCLE and no REALTIME */\n");
|
||||
|
||||
# endif /* CLOCK_REALTIME */
|
||||
|
||||
#endif /* HAVE_NO_GETTIME */
|
||||
/* exit(0); */
|
||||
return 0;
|
||||
}
|
64
have_memmv.c
Normal file
64
have_memmv.c
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* have_memmv - Determine if we memmove()
|
||||
*
|
||||
* usage:
|
||||
* have_memmv
|
||||
*
|
||||
* Not all systems with memcpy() have memmove() functions, so this may not
|
||||
* compile on your system.
|
||||
*
|
||||
* This prog outputs several defines:
|
||||
*
|
||||
* HAVE_MEMMOVE
|
||||
* defined ==> use memmove()
|
||||
* undefined ==> use internal slow memmove() instead
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1997 by Landon Curt Noll. All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software and
|
||||
* its documentation for any purpose and without fee is hereby granted,
|
||||
* provided that the above copyright, this permission notice and text
|
||||
* this comment, and the disclaimer below appear in all of the following:
|
||||
*
|
||||
* supporting documentation
|
||||
* source copies
|
||||
* source works derived from this source
|
||||
* binaries derived from this source or from derived source
|
||||
*
|
||||
* LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
|
||||
* EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* chongo was here /\../\
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define MOVELEN 3
|
||||
|
||||
char src[] = "chongo was here";
|
||||
char dest[MOVELEN+1];
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
#if defined(HAVE_NO_MEMMOVE)
|
||||
|
||||
printf("#undef HAVE_MEMMOVE /* no */\n");
|
||||
|
||||
#else /* HAVE_NO_MEMMOVE */
|
||||
|
||||
(void) memmove(dest, src, MOVELEN);
|
||||
|
||||
printf("#define HAVE_MEMMOVE /* yes */\n");
|
||||
|
||||
#endif /* HAVE_NO_MEMMOVE */
|
||||
|
||||
/* exit(0); */
|
||||
return 0;
|
||||
}
|
@@ -39,22 +39,30 @@
|
||||
* chongo was here /\../\
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define MOVELEN 3
|
||||
|
||||
char src[] = "chongo was here";
|
||||
char dest[MOVELEN+1];
|
||||
|
||||
MAIN
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
#if defined(HAVE_NO_NEWSTR)
|
||||
|
||||
printf("#undef HAVE_NEWSTR /* no */\n");
|
||||
|
||||
#else /* HAVE_NO_NEWSTR */
|
||||
|
||||
(void) memcpy(dest, src, MOVELEN);
|
||||
(void) memset(dest, 0, MOVELEN);
|
||||
(void) strchr(src, 'e');
|
||||
|
||||
printf("#define HAVE_NEWSTR /* yes */\n");
|
||||
|
||||
#endif /* HAVE_NO_NEWSTR */
|
||||
exit(0);
|
||||
|
||||
/* exit(0); */
|
||||
return 0;
|
||||
}
|
||||
|
84
have_offscl.c
Normal file
84
have_offscl.c
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* have_offscl - determine if have a scalar off_t element
|
||||
*
|
||||
* usage:
|
||||
* have_offscl
|
||||
*
|
||||
* On some systems, off_t is a scalar value on which one can perform
|
||||
* arithmetic operations, assignments and comparisons. On some systems
|
||||
* off_t is some sort of union or struct which must be converted into
|
||||
* a ZVALUE in order to perform arithmetic operations, assignments and
|
||||
* comparisons.
|
||||
*
|
||||
*
|
||||
* This prog outputs several defines:
|
||||
*
|
||||
* HAVE_OFF_T_SCALAR
|
||||
* defined ==> ok to perform arithmetic ops, = and comparisons
|
||||
* undefined ==> convert to ZVALUE first
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1996 by Landon Curt Noll. All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software and
|
||||
* its documentation for any purpose and without fee is hereby granted,
|
||||
* provided that the above copyright, this permission notice and text
|
||||
* this comment, and the disclaimer below appear in all of the following:
|
||||
*
|
||||
* supporting documentation
|
||||
* source copies
|
||||
* source works derived from this source
|
||||
* binaries derived from this source or from derived source
|
||||
*
|
||||
* LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
|
||||
* EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* chongo was here /\../\
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
#if !defined(OFF_T_NON_SCALAR)
|
||||
off_t value; /* an off_t to perform arithmatic on */
|
||||
off_t value2; /* an off_t to perform arithmatic on */
|
||||
|
||||
/*
|
||||
* do some math opts on an off_t
|
||||
*/
|
||||
value = (off_t)getpid();
|
||||
value2 = (off_t)-1;
|
||||
if (value > (off_t)1) {
|
||||
--value;
|
||||
}
|
||||
if (value <= (off_t)getppid()) {
|
||||
--value;
|
||||
}
|
||||
if (value == value2) {
|
||||
value += value2;
|
||||
}
|
||||
value <<= 1;
|
||||
if (!value) {
|
||||
printf("/* something for the off_t to do */\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* report off_t as a scalar
|
||||
*/
|
||||
printf("#undef HAVE_OFF_T_SCALAR\n");
|
||||
printf("#define HAVE_OFF_T_SCALAR /* off_t is a simple value */\n");
|
||||
#else
|
||||
printf("#undef HAVE_OFF_T_SCALAR /* off_t is not a simple value */\n");
|
||||
#endif
|
||||
/* exit(0); */
|
||||
return 0;
|
||||
}
|
85
have_posscl.c
Normal file
85
have_posscl.c
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* have_posscl - determine if have a scalar FILEPOS element
|
||||
*
|
||||
* usage:
|
||||
* have_posscl
|
||||
*
|
||||
* On some systems, FILEPOS is a scalar value on which one can perform
|
||||
* arithmetic operations, assignments and comparisons. On some systems
|
||||
* FILEPOS is some sort of union or struct which must be converted into
|
||||
* a ZVALUE in order to perform arithmetic operations, assignments and
|
||||
* comparisons.
|
||||
*
|
||||
*
|
||||
* This prog outputs several defines:
|
||||
*
|
||||
* HAVE_FILEPOS_SCALAR
|
||||
* defined ==> ok to perform arithmetic ops, = and comparisons
|
||||
* undefined ==> convert to ZVALUE first
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1996 by Landon Curt Noll. All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software and
|
||||
* its documentation for any purpose and without fee is hereby granted,
|
||||
* provided that the above copyright, this permission notice and text
|
||||
* this comment, and the disclaimer below appear in all of the following:
|
||||
*
|
||||
* supporting documentation
|
||||
* source copies
|
||||
* source works derived from this source
|
||||
* binaries derived from this source or from derived source
|
||||
*
|
||||
* LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
|
||||
* EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* chongo was here /\../\
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include "have_fpos.h"
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
#if !defined(FILEPOS_NON_SCALAR)
|
||||
FILEPOS value; /* an FILEPOS to perform arithmatic on */
|
||||
FILEPOS value2; /* an FILEPOS to perform arithmatic on */
|
||||
|
||||
/*
|
||||
* do some math opts on an FILEPOS
|
||||
*/
|
||||
value = (FILEPOS)getpid();
|
||||
value2 = (FILEPOS)-1;
|
||||
if (value > (FILEPOS)1) {
|
||||
--value;
|
||||
}
|
||||
if (value <= (FILEPOS)getppid()) {
|
||||
--value;
|
||||
}
|
||||
if (value == value2) {
|
||||
value += value2;
|
||||
}
|
||||
value <<= 1;
|
||||
if (!value) {
|
||||
printf("/* something for the FILEPOS to do */\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* report FILEPOS as a scalar
|
||||
*/
|
||||
printf("#undef HAVE_FILEPOS_SCALAR\n");
|
||||
printf("#define HAVE_FILEPOS_SCALAR /* FILEPOS is a simple value */\n");
|
||||
#else
|
||||
printf("#undef HAVE_FILEPOS_SCALAR /* FILEPOS is not a simple value */\n");
|
||||
#endif
|
||||
/* exit(0); */
|
||||
return 0;
|
||||
}
|
118
have_stdvs.c
118
have_stdvs.c
@@ -54,86 +54,88 @@ char buf[BUFSIZ];
|
||||
|
||||
|
||||
void
|
||||
try(char *fmt, ...)
|
||||
try_this(char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
va_start(ap, fmt);
|
||||
#if !defined(DONT_HAVE_VSPRINTF)
|
||||
vsprintf(buf, fmt, ap);
|
||||
vsprintf(buf, fmt, ap);
|
||||
#else
|
||||
sprintf(buf, fmt, ap);
|
||||
sprintf(buf, fmt, ap);
|
||||
#endif
|
||||
va_end(ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
|
||||
MAIN
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
/*
|
||||
* setup
|
||||
*/
|
||||
buf[0] = '\0';
|
||||
/*
|
||||
* setup
|
||||
*/
|
||||
buf[0] = '\0';
|
||||
|
||||
/*
|
||||
* test variable args and vsprintf/sprintf
|
||||
*/
|
||||
try("@%d:%s:%d@", 1, "hi", 2);
|
||||
if (strcmp(buf, "@1:hi:2@") != 0) {
|
||||
/*
|
||||
* test variable args and vsprintf/sprintf
|
||||
*/
|
||||
try_this("@%d:%s:%d@", 1, "hi", 2);
|
||||
if (strcmp(buf, "@1:hi:2@") != 0) {
|
||||
#if !defined(DONT_HAVE_VSPRINTF)
|
||||
/* <stdarg.h> with vsprintf() didn't work */
|
||||
/* <stdarg.h> with vsprintf() didn't work */
|
||||
#else
|
||||
/* <stdarg.h> with sprintf() simulating vsprintf() didn't work */
|
||||
/* <stdarg.h> with sprintf() simulating vsprintf() didn't work */
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
try("%s %d%s%d%d %s",
|
||||
"Landon Noll 1st proved that", 2, "^", 23209, -1, "was prime");
|
||||
if (strcmp(buf, "Landon Noll 1st proved that 2^23209-1 was prime") != 0) {
|
||||
exit(1);
|
||||
}
|
||||
try_this("%s %d%s%d%d %s",
|
||||
"Landon Noll 1st proved that", 2, "^", 23209, -1, "was prime");
|
||||
if (strcmp(buf,
|
||||
"Landon Noll 1st proved that 2^23209-1 was prime") != 0) {
|
||||
#if !defined(DONT_HAVE_VSPRINTF)
|
||||
/* <stdarg.h> with vsprintf() didn't work */
|
||||
/* <stdarg.h> with vsprintf() didn't work */
|
||||
#else
|
||||
/* <stdarg.h> with sprintf() simulating vsprintf() didn't work */
|
||||
/* <stdarg.h> with sprintf() simulating vsprintf() didn't work */
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* report the result
|
||||
*/
|
||||
puts("/* what type of variable args do we have? */");
|
||||
/*
|
||||
* report the result
|
||||
*/
|
||||
puts("/* what type of variable args do we have? */");
|
||||
#if defined(DONT_HAVE_VSPRINTF)
|
||||
puts("/*");
|
||||
puts(" * SIMULATE_STDARG");
|
||||
puts(" *");
|
||||
puts(" * WARNING: This type of stdarg makes assumptions about the stack");
|
||||
puts(" * that may not be true on your system. You may want to");
|
||||
puts(" * define STDARG (if using ANSI C) or VARARGS.");
|
||||
puts(" */");
|
||||
puts("typedef char *va_list;");
|
||||
puts("#define va_start(ap,parmn) (void)((ap) = (char*)(&(parmn) + 1))");
|
||||
puts("#define va_end(ap) (void)((ap) = 0)");
|
||||
puts("#define va_arg(ap, type) \\");
|
||||
puts(" (((type*)((ap) = ((ap) + sizeof(type))))[-1])");
|
||||
puts("#define SIMULATE_STDARG /* use std_arg.h to simulate <stdarg.h> */");
|
||||
puts("/*");
|
||||
puts(" * SIMULATE_STDARG");
|
||||
puts(" *");
|
||||
puts(" * WARNING: This type of stdarg makes assumptions about the stack");
|
||||
puts(" * that may not be true on your system. You may want to");
|
||||
puts(" * define STDARG (if using ANSI C) or VARARGS.");
|
||||
puts(" */");
|
||||
puts("typedef char *va_list;");
|
||||
puts("#define va_start(ap,parmn) (void)((ap) = (char*)(&(parmn) + 1))");
|
||||
puts("#define va_end(ap) (void)((ap) = 0)");
|
||||
puts("#define va_arg(ap, type) \\");
|
||||
puts(" (((type*)((ap) = ((ap) + sizeof(type))))[-1])");
|
||||
puts("#define SIMULATE_STDARG /* use std_arg.h to simulate <stdarg.h> */");
|
||||
#else
|
||||
puts("#define STDARG /* use <stdarg.h> */");
|
||||
puts("#include <stdarg.h>");
|
||||
puts("#define STDARG /* use <stdarg.h> */");
|
||||
puts("#include <stdarg.h>");
|
||||
#endif
|
||||
puts("\n/* should we use vsprintf()? */");
|
||||
puts("\n/* should we use vsprintf()? */");
|
||||
#if !defined(DONT_HAVE_VSPRINTF)
|
||||
puts("#define HAVE_VS /* yes */");
|
||||
puts("#define HAVE_VS /* yes */");
|
||||
#else
|
||||
puts("/*");
|
||||
puts(" * Hack aleart!!!");
|
||||
puts(" *");
|
||||
puts(" * Systems that do not have vsprintf() need something. In some");
|
||||
puts(" * cases the sprintf function will deal correctly with the");
|
||||
puts(" * va_alist 3rd arg. Hope for the best!");
|
||||
puts(" */");
|
||||
puts("#define vsprintf sprintf");
|
||||
puts("#undef HAVE_VS");
|
||||
puts("/*");
|
||||
puts(" * Hack aleart!!!");
|
||||
puts(" *");
|
||||
puts(" * Systems that do not have vsprintf() need something. In some");
|
||||
puts(" * cases the sprintf function will deal correctly with the");
|
||||
puts(" * va_alist 3rd arg. Hope for the best!");
|
||||
puts(" */");
|
||||
puts("#define vsprintf sprintf");
|
||||
puts("#undef HAVE_VS");
|
||||
#endif
|
||||
exit(0);
|
||||
/* exit(0); */
|
||||
return 0;
|
||||
}
|
||||
|
12
have_uid_t.c
12
have_uid_t.c
@@ -36,6 +36,8 @@
|
||||
* chongo was here /\../\
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#if !defined(HAVE_NO_UID_T)
|
||||
#include "have_unistd.h"
|
||||
#if defined(HAVE_UNISTD_H)
|
||||
@@ -45,18 +47,24 @@
|
||||
#include <sys/types.h>
|
||||
#endif /* ! HAVE_NO_UID_T */
|
||||
|
||||
MAIN
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
#if defined(HAVE_NO_UID_T)
|
||||
|
||||
printf("#undef HAVE_UID_T /* no */\n");
|
||||
|
||||
#else /* HAVE_NO_UID_T */
|
||||
|
||||
uid_t curds;
|
||||
extern uid_t geteuid();
|
||||
|
||||
curds = geteuid();
|
||||
|
||||
printf("#define HAVE_UID_T /* yes */\n");
|
||||
|
||||
#endif /* HAVE_NO_UID_T */
|
||||
exit(0);
|
||||
|
||||
/* exit(0); */
|
||||
return 0;
|
||||
}
|
||||
|
65
have_ustat.c
Normal file
65
have_ustat.c
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* have_ustat - Determine if we ustat()
|
||||
*
|
||||
* usage:
|
||||
* have_ustat
|
||||
*
|
||||
* Not all systems have the ustat() function, so this may not
|
||||
* compile on your system.
|
||||
*
|
||||
* This prog outputs several defines:
|
||||
*
|
||||
* HAVE_USTAT
|
||||
* defined ==> use ustat()
|
||||
* undefined ==> do not call or cannot call ustat()
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1999 by Landon Curt Noll. All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software and
|
||||
* its documentation for any purpose and without fee is hereby granted,
|
||||
* provided that the above copyright, this permission notice and text
|
||||
* this comment, and the disclaimer below appear in all of the following:
|
||||
*
|
||||
* supporting documentation
|
||||
* source copies
|
||||
* source works derived from this source
|
||||
* binaries derived from this source or from derived source
|
||||
*
|
||||
* LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
|
||||
* EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* chongo was here /\../\
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <ustat.h>
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
#if defined(HAVE_NO_USTAT)
|
||||
|
||||
printf("#undef HAVE_USTAT /* no */\n");
|
||||
|
||||
#else /* HAVE_NO_USTAT */
|
||||
|
||||
struct stat stat_dot; /* stat of "." */
|
||||
struct ustat ustat_dot; /* usage stat of "." */
|
||||
|
||||
(void) stat(".", &stat_dot);
|
||||
(void) ustat(stat_dot.st_dev, &ustat_dot);
|
||||
|
||||
printf("#define HAVE_USTAT /* yes */\n");
|
||||
|
||||
#endif /* HAVE_NO_USTAT */
|
||||
|
||||
/* exit(0); */
|
||||
return 0;
|
||||
}
|
86
have_varvs.c
86
have_varvs.c
@@ -52,23 +52,25 @@ char buf[BUFSIZ];
|
||||
#include <varargs.h>
|
||||
|
||||
void
|
||||
try(char *fmt, ...)
|
||||
try_this(char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap);
|
||||
|
||||
#if !defined(DONT_HAVE_VSPRINTF)
|
||||
vsprintf(buf, fmt, ap);
|
||||
#else
|
||||
sprintf(buf, fmt, ap);
|
||||
#endif
|
||||
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void
|
||||
try(char *a, int b, char *c, int d)
|
||||
try_this(char *a, int b, char *c, int d)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -76,56 +78,58 @@ try(char *a, int b, char *c, int d)
|
||||
#endif
|
||||
|
||||
|
||||
MAIN
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
/*
|
||||
* setup
|
||||
*/
|
||||
buf[0] = '\0';
|
||||
/*
|
||||
* setup
|
||||
*/
|
||||
buf[0] = '\0';
|
||||
|
||||
/*
|
||||
* test variable args and vsprintf/sprintf
|
||||
*/
|
||||
try("@%d:%s:%d@", 1, "hi", 2);
|
||||
if (strcmp(buf, "@1:hi:2@") != 0) {
|
||||
/*
|
||||
* test variable args and vsprintf/sprintf
|
||||
*/
|
||||
try_this("@%d:%s:%d@", 1, "hi", 2);
|
||||
if (strcmp(buf, "@1:hi:2@") != 0) {
|
||||
#if !defined(DONT_HAVE_VSPRINTF)
|
||||
/* <varargs.h> with vsprintf() didn't work */
|
||||
/* <varargs.h> with vsprintf() didn't work */
|
||||
#else
|
||||
/* <varargs.h> with sprintf() simulating vsprintf() didn't work */
|
||||
/* <varargs.h> with sprintf() simulating vsprintf() didn't work */
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
try("%s %d%s%d%d %s",
|
||||
"Landon Noll 1st proved that", 2, "^", 23209, -1, "was prime");
|
||||
if (strcmp(buf, "Landon Noll 1st proved that 2^23209-1 was prime") != 0) {
|
||||
exit(1);
|
||||
}
|
||||
try_this("%s %d%s%d%d %s",
|
||||
"Landon Noll 1st proved that", 2, "^", 23209, -1, "was prime");
|
||||
if (strcmp(buf,
|
||||
"Landon Noll 1st proved that 2^23209-1 was prime") != 0) {
|
||||
#if !defined(DONT_HAVE_VSPRINTF)
|
||||
/* <stdarg.h> with vsprintf() didn't work */
|
||||
/* <stdarg.h> with vsprintf() didn't work */
|
||||
#else
|
||||
/* <stdarg.h> with sprintf() simulating vsprintf() didn't work */
|
||||
/* <stdarg.h> with sprintf() simulating vsprintf() didn't work */
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* report the result
|
||||
*/
|
||||
puts("/* what type of variable args do we have? */");
|
||||
puts("#define VARARGS /* use <varargs.h> */");
|
||||
puts("#include <varargs.h>");
|
||||
puts("\n/* should we use vsprintf()? */");
|
||||
/*
|
||||
* report the result
|
||||
*/
|
||||
puts("/* what type of variable args do we have? */");
|
||||
puts("#define VARARGS /* use <varargs.h> */");
|
||||
puts("#include <varargs.h>");
|
||||
puts("\n/* should we use vsprintf()? */");
|
||||
#if !defined(DONT_HAVE_VSPRINTF)
|
||||
puts("#define HAVE_VS /* yes */");
|
||||
puts("#define HAVE_VS /* yes */");
|
||||
#else
|
||||
puts("/*");
|
||||
puts(" * Hack aleart!!!");
|
||||
puts(" *");
|
||||
puts(" * Systems that do not have vsprintf() need something. In some");
|
||||
puts(" * cases the sprintf function will deal correctly with the");
|
||||
puts(" * va_alist 3rd arg. Hope for the best!");
|
||||
puts(" */");
|
||||
puts("#define vsprintf sprintf");
|
||||
puts("#undef HAVE_VS");
|
||||
puts("/*");
|
||||
puts(" * Hack aleart!!!");
|
||||
puts(" *");
|
||||
puts(" * Systems that do not have vsprintf() need something. In some");
|
||||
puts(" * cases the sprintf function will deal correctly with the");
|
||||
puts(" * va_alist 3rd arg. Hope for the best!");
|
||||
puts(" */");
|
||||
puts("#define vsprintf sprintf");
|
||||
puts("#undef HAVE_VS");
|
||||
#endif
|
||||
exit(0);
|
||||
/* exit(0); */
|
||||
return 0;
|
||||
}
|
||||
|
133
help.c
Normal file
133
help.c
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright (c) 1997 David I. Bell
|
||||
* Permission is granted to use, distribute, or modify this source,
|
||||
* provided that this copyright notice remains intact.
|
||||
*
|
||||
* Arbitrary precision calculator.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "calc.h"
|
||||
#include "conf.h"
|
||||
|
||||
#include "have_unistd.h"
|
||||
#if defined(HAVE_UNISTD_H)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* some help topics are symbols, so we alias them to nice filenames
|
||||
*/
|
||||
static struct help_alias {
|
||||
char *topic;
|
||||
char *filename;
|
||||
} halias[] = {
|
||||
{"=", "address"},
|
||||
{"->", "arrow"},
|
||||
{"=", "assign"},
|
||||
{"*", "dereference"},
|
||||
{".", "oldvalue"},
|
||||
{"%", "mod"},
|
||||
{"//", "quo"},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* external values
|
||||
*/
|
||||
extern char *pager; /* $PAGER or default */
|
||||
|
||||
|
||||
/*
|
||||
* givehelp - display a help file
|
||||
*
|
||||
* given:
|
||||
* type the type of help to give, NULL => index
|
||||
*/
|
||||
void
|
||||
givehelp(char *type)
|
||||
{
|
||||
struct help_alias *p; /* help alias being considered */
|
||||
char *helpcmd; /* what to execute to print help */
|
||||
char *c;
|
||||
|
||||
/*
|
||||
* check permissions to see if we are allowed to help
|
||||
*/
|
||||
if (!allow_exec || !allow_read) {
|
||||
fprintf(stderr,
|
||||
"sorry, help is only allowed with -m mode 5 or 7\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* catch the case where we just print the index */
|
||||
if (type == NULL) {
|
||||
type = DEFAULTCALCHELP; /* the help index file */
|
||||
}
|
||||
|
||||
/* alias the type of help, if needed */
|
||||
for (p=halias; p->topic; ++p) {
|
||||
if (strcmp(type, p->topic) == 0) {
|
||||
type = p->filename;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* sanity check on name
|
||||
*/
|
||||
/* look for /. or a leading . */
|
||||
if (strstr(type, "/.") != NULL || type[0] == '.') {
|
||||
fprintf(stderr, "bad help name\n");
|
||||
return;
|
||||
}
|
||||
/* look for chars that could be shell meta chars */
|
||||
for (c = type; *c; ++c) {
|
||||
switch ((int)*c) {
|
||||
case '+':
|
||||
case ',':
|
||||
case '-':
|
||||
case '.':
|
||||
case '/':
|
||||
case '_':
|
||||
break;
|
||||
default:
|
||||
if (!isascii((int)*c) || !isalnum((int)*c)) {
|
||||
fprintf(stderr, "bogus char in help name\n");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* form the help command name */
|
||||
helpcmd = (char *)malloc(
|
||||
sizeof("if [ ! -r \"")+sizeof(HELPDIR)+1+strlen(type)+
|
||||
sizeof("\" ];then ")+
|
||||
strlen(pager)+1+1+sizeof(HELPDIR)+1+strlen(type)+1+1+
|
||||
sizeof("elif [ ! -r \"")+sizeof(CUSTOMHELPDIR)+1+strlen(type)+
|
||||
sizeof("\" ];then ")+
|
||||
strlen(pager)+1+1+sizeof(CUSTOMHELPDIR)+1+strlen(type)+1+1+
|
||||
sizeof(";else ")+sizeof(ECHO)+
|
||||
sizeof("echo no such help, try: help help;fi")+1);
|
||||
sprintf(helpcmd,
|
||||
"if [ -r \"%s/%s\" ];then %s \"%s/%s\";"
|
||||
"elif [ -r \"%s/%s\" ];then %s \"%s/%s\";"
|
||||
"else %s no such help, try: help help;fi",
|
||||
HELPDIR, type, pager, HELPDIR, type,
|
||||
CUSTOMHELPDIR, type, pager, CUSTOMHELPDIR, type, ECHO);
|
||||
if (conf->calc_debug > 0) {
|
||||
printf("%s\n", helpcmd);
|
||||
sleep(3);
|
||||
}
|
||||
|
||||
/* execute the help command */
|
||||
system(helpcmd);
|
||||
free(helpcmd);
|
||||
}
|
||||
|
239
help/Makefile
239
help/Makefile
@@ -43,47 +43,96 @@ FMT= fmt
|
||||
CMP= cmp
|
||||
CAT= cat
|
||||
|
||||
# Standard help files
|
||||
# Standard and Builtin help files
|
||||
#
|
||||
# The obj.file is special and is not listed here.
|
||||
#
|
||||
STD_HELP_FILES1= intro overview help command config \
|
||||
define environment expression file history interrupt mat
|
||||
STD_HELP_FILES2= operator statement types usage variable
|
||||
STD_HELP_FILES3= todo credit
|
||||
STD_HELP_FILES= ${STD_HELP_FILES1} ${STD_HELP_FILES2} ${STD_HELP_FILES3}
|
||||
SYMBOL_HELP= assign
|
||||
STD_HELP_FILES_1= intro overview help
|
||||
STD_HELP_FILES_2= assoc
|
||||
|
||||
# These two lists are prodiced by the detaillist and missinglist rules
|
||||
# when no WARNINGS are detected.
|
||||
BLT_HELP_FILES_3= builtin
|
||||
|
||||
STD_HELP_FILES_4= command config custom define environment expression
|
||||
|
||||
BLT_HELP_FILES_5= errorcodes
|
||||
|
||||
STD_HELP_FILES_6= file history interrupt list mat
|
||||
|
||||
# beacuse obj is built special (due to confusion with it as
|
||||
# a symlink for some built environments, we treat obj specially
|
||||
# and call it obj.file
|
||||
#
|
||||
DETAIL_HELP= abs access acos acosh acot acoth acsc acsch append appr archive \
|
||||
arg asec asech asin asinh assoc atan atan2 atanh avg base bround \
|
||||
btrunc ceil cfappr cfsim char cmdbuf cmp comb conj cos cosh cot coth \
|
||||
count cp csc csch ctime delete den det digit digits dp epsilon errno \
|
||||
SPECIAL_HELP_7= obj.file
|
||||
|
||||
STD_HELP_FILES_8= operator statement
|
||||
|
||||
BLT_HELP_FILES_9= stdlib
|
||||
|
||||
STD_HELP_FILES_10= types usage unexpected variable
|
||||
|
||||
BLT_HELP_FILES_11= altbind bindings custom_cal libcalc new_custom stdlib
|
||||
|
||||
STD_HELP_FILES_12= archive
|
||||
|
||||
BLT_HELP_FILES_13= bugs changes
|
||||
|
||||
STD_HELP_FILES_14= contrib credit wishlist todo
|
||||
|
||||
# These files are used in the following order to construct full
|
||||
#
|
||||
FULL_HELP_FILES= ${STD_HELP_FILES_1} ${STD_HELP_FILES_2} \
|
||||
${BLT_HELP_FILES_3} ${STD_HELP_FILES_4} \
|
||||
${BLT_HELP_FILES_5} ${STD_HELP_FILES_6} \
|
||||
${SPECIAL_HELP_7} ${STD_HELP_FILES_8} \
|
||||
${BLT_HELP_FILES_9} ${STD_HELP_FILES_10} \
|
||||
${BLT_HELP_FILES_11} ${STD_HELP_FILES_12} \
|
||||
${BLT_HELP_FILES_13} ${STD_HELP_FILES_14}
|
||||
|
||||
# These full files are those who are not built or constrcuted
|
||||
#
|
||||
STD_HELP_FILES= ${STD_HELP_FILES_1} ${STD_HELP_FILES_2} \
|
||||
${STD_HELP_FILES_4} ${STD_HELP_FILES_6} \
|
||||
${STD_HELP_FILES_8} ${STD_HELP_FILES_10} \
|
||||
${STD_HELP_FILES_12} ${STD_HELP_FILES_14}
|
||||
|
||||
# These full files are those who are built by this Makefile
|
||||
#
|
||||
# Note that ${SPECIAL_HELP_7} is not included in this list
|
||||
# because of problems with its name.
|
||||
#
|
||||
BLT_HELP_FILES= ${BLT_HELP_FILES_3} ${BLT_HELP_FILES_5} \
|
||||
${BLT_HELP_FILES_9} \
|
||||
${BLT_HELP_FILES_11} ${BLT_HELP_FILES_13}
|
||||
|
||||
# This list is prodiced by the detaillist rule when no WARNINGS are detected.
|
||||
#
|
||||
DETAIL_HELP= abs access acos acosh acot acoth acsc acsch address agd append \
|
||||
appr arg arrow asec asech asin asinh assign atan atan2 atanh avg base \
|
||||
bit blk blkcpy blkfree blocks bround btrunc ceil cfappr cfsim char \
|
||||
cmdbuf cmp comb conj cos cosh cot coth count cp csc csch ctime delete \
|
||||
den dereference det digit digits dp epsilon errcount errmax errno \
|
||||
error eval exp fact factor fclose fcnt feof ferror fflush fgetc \
|
||||
fgetfield fgetline fgets fgetstr fib files floor fopen forall fprintf \
|
||||
fputc fputs fputstr frac frem freopen fscan fscanf fseek fsize ftell \
|
||||
gcd gcdrem getenv hash head highbit hmean hypot ilog ilog10 ilog2 im \
|
||||
insert int inverse iroot isassoc isatty isconfig iserror iseven \
|
||||
isfile ishash isident isint islist ismat ismult isnull isnum isobj \
|
||||
isodd isprime isqrt isrand israndom isreal isrel isset issimple issq \
|
||||
isstr istype jacobi join lcm lcmfact lfactor list ln lowbit ltol \
|
||||
makelist matdim matfill matmax matmin matsum mattrans max meq min \
|
||||
minv mmin mne mod modify near newerror nextcand nextprime norm null \
|
||||
num ord param perm pfact pi pix places pmod polar poly pop power \
|
||||
prevcand prevprime printf prompt ptest push putenv quo quomod rand \
|
||||
randbit randperm rcin rcmul rcout rcpow rcsq re rm remove reverse \
|
||||
rewind root round rsearch runtime scale scan scanf search sec sech \
|
||||
segment select sgn sin sinh size sizeof sort sqrt srand ssq str \
|
||||
strcat strerror strlen strpos strprintf strscan strscanf substr swap \
|
||||
system tail tan tanh time trunc xor
|
||||
fputc fputs fputstr frac free freeglobals freeredc freestatics frem \
|
||||
freopen fscan fscanf fseek fsize ftell gcd gcdrem gd getenv hash head \
|
||||
highbit hmean hnrmod hypot ilog ilog10 ilog2 im insert int inverse \
|
||||
iroot isassoc isatty isblk isconfig isdefined iserror iseven isfile \
|
||||
ishash isident isint islist ismat ismult isnull isnum isobj isobjtype \
|
||||
isodd isprime isptr isqrt isrand israndom isreal isrel issimple issq \
|
||||
isstr istype jacobi join lcm lcmfact lfactor ln lowbit ltol makelist \
|
||||
matdim matfill matmax matmin matsum mattrace mattrans max md5 memsize \
|
||||
meq min minv mmin mne mod modify name near newerror nextcand \
|
||||
nextprime norm null num oldvalue ord param perm pfact pi pix places \
|
||||
pmod polar poly pop popcnt power prevcand prevprime printf prompt \
|
||||
protect ptest push putenv quo quomod rand randbit random randombit \
|
||||
randperm rcin rcmul rcout rcpow rcsq re remove reverse rewind rm root \
|
||||
round rsearch runtime saveval scale scan scanf search sec sech seed \
|
||||
segment select sgn sha sha1 sin sinh size sizeof sort sqrt srand \
|
||||
srandom ssq str strcat strerror strlen strpos strprintf strscan \
|
||||
strscanf substr sum swap system tail tan tanh test time trunc xor
|
||||
|
||||
# Help files that are constructed from other sources
|
||||
# This list is of files that are clones of DETAIL_HELP files. They are
|
||||
# built from DETAIL_HELP files.
|
||||
#
|
||||
# The obj.file is special and is not listed here.
|
||||
#
|
||||
BUILT_HELP_FILES= bindings altbind changes libcalc stdlib bugs errorcodes
|
||||
DETAIL_CLONE= copy
|
||||
|
||||
# Singular files
|
||||
#
|
||||
@@ -94,12 +143,12 @@ SINGULAR_FILES= binding bug change errorcode type
|
||||
|
||||
# These files are found (but not built) in the distribution
|
||||
#
|
||||
DISTLIST= ${STD_HELP_FILES} ${DETAIL_HELP} ${SYMBOL_HELP} ${MAKE_FILE} \
|
||||
DISTLIST= ${STD_HELP_FILES} ${DETAIL_HELP} ${MAKE_FILE} \
|
||||
obj.file builtin.top builtin.end funclist.sed \
|
||||
errorcodes.hdr errorcodes.sed
|
||||
|
||||
all: ${STD_HELP_FILES} obj.file ${BUILT_HELP_FILES} full \
|
||||
${DETAIL_HELP} ${SINGULAR_FILES} builtin .all
|
||||
all: ${FULL_HELP_FILES} full ${DETAIL_HELP} ${DETAIL_CLONE} \
|
||||
${SINGULAR_FILES} calc .all
|
||||
|
||||
# used by the upper level Makefile to determine of we have done all
|
||||
#
|
||||
@@ -111,9 +160,9 @@ all: ${STD_HELP_FILES} obj.file ${BUILT_HELP_FILES} full \
|
||||
touch .all
|
||||
|
||||
bindings: ../lib/bindings
|
||||
rm -f bindings
|
||||
cp ../lib/bindings bindings
|
||||
chmod 0444 bindings
|
||||
rm -f $@
|
||||
cp ../lib/bindings $@
|
||||
chmod 0444 $@
|
||||
-@if [ -z "${Q}" ]; then \
|
||||
echo ''; \
|
||||
echo '=-=-= skipping the cat of help/$@ =-=-='; \
|
||||
@@ -123,9 +172,9 @@ bindings: ../lib/bindings
|
||||
fi
|
||||
|
||||
altbind: ../lib/altbind
|
||||
rm -f altbind
|
||||
cp ../lib/altbind altbind
|
||||
chmod 0444 altbind
|
||||
rm -f $@
|
||||
cp ../lib/altbind $@
|
||||
chmod 0444 $@
|
||||
-@if [ -z "${Q}" ]; then \
|
||||
echo ''; \
|
||||
echo '=-=-= skipping the cat of help/$@ =-=-='; \
|
||||
@@ -135,9 +184,9 @@ altbind: ../lib/altbind
|
||||
fi
|
||||
|
||||
stdlib: ../lib/README
|
||||
rm -f stdlib
|
||||
cp ../lib/README stdlib
|
||||
chmod 0444 stdlib
|
||||
rm -f $@
|
||||
cp ../lib/README $@
|
||||
chmod 0444 $@
|
||||
-@if [ -z "${Q}" ]; then \
|
||||
echo ''; \
|
||||
echo '=-=-= skipping the cat of help/$@ =-=-='; \
|
||||
@@ -147,9 +196,9 @@ stdlib: ../lib/README
|
||||
fi
|
||||
|
||||
changes: ../CHANGES
|
||||
rm -f changes
|
||||
cp ../CHANGES changes
|
||||
chmod 0444 changes
|
||||
rm -f $@
|
||||
cp ../CHANGES $@
|
||||
chmod 0444 $@
|
||||
-@if [ -z "${Q}" ]; then \
|
||||
echo ''; \
|
||||
echo '=-=-= skipping the cat of help/$@ =-=-='; \
|
||||
@@ -159,9 +208,9 @@ changes: ../CHANGES
|
||||
fi
|
||||
|
||||
libcalc: ../LIBRARY
|
||||
rm -f libcalc
|
||||
${SED} -e 's:$${LIBDIR}:${LIBDIR}:g' < ../LIBRARY > libcalc
|
||||
chmod 0444 libcalc
|
||||
rm -f $@
|
||||
${SED} -e 's:$${LIBDIR}:${LIBDIR}:g' < ../LIBRARY > $@
|
||||
chmod 0444 $@
|
||||
-@if [ -z "${Q}" ]; then \
|
||||
echo ''; \
|
||||
echo '=-=-= skipping the cat of help/$@ =-=-='; \
|
||||
@@ -171,9 +220,9 @@ libcalc: ../LIBRARY
|
||||
fi
|
||||
|
||||
bugs: ../BUGS
|
||||
rm -f bugs
|
||||
cp ../BUGS bugs
|
||||
chmod 0444 bugs
|
||||
rm -f $@
|
||||
cp ../BUGS $@
|
||||
chmod 0444 $@
|
||||
-@if [ -z "${Q}" ]; then \
|
||||
echo ''; \
|
||||
echo '=-=-= skipping the cat of help/$@ =-=-='; \
|
||||
@@ -183,10 +232,10 @@ bugs: ../BUGS
|
||||
fi
|
||||
|
||||
errorcodes: ../calcerr.h errorcodes.hdr errorcodes.sed
|
||||
rm -f errorcodes
|
||||
${CAT} errorcodes.hdr > errorcodes
|
||||
${SED} -n -f errorcodes.sed < ../calcerr.h >> errorcodes
|
||||
chmod 0444 errorcodes
|
||||
rm -f $@
|
||||
${CAT} errorcodes.hdr > $@
|
||||
${SED} -n -f errorcodes.sed < ../calcerr.h >> $@
|
||||
chmod 0444 $@
|
||||
-@if [ -z "${Q}" ]; then \
|
||||
echo ''; \
|
||||
echo '=-=-= skipping the cat of help/$@ =-=-='; \
|
||||
@@ -195,11 +244,58 @@ errorcodes: ../calcerr.h errorcodes.hdr errorcodes.sed
|
||||
true; \
|
||||
fi
|
||||
|
||||
full: ${STD_HELP_FILES} ${BUILT_HELP_FILES} ${MAKE_FILE}
|
||||
calc: usage
|
||||
rm -f $@
|
||||
cp usage $@
|
||||
chmod 0444 $@
|
||||
-@if [ -z "${Q}" ]; then \
|
||||
echo ''; \
|
||||
echo '=-=-= skipping the cat of help/$@ =-=-='; \
|
||||
echo ''; \
|
||||
else \
|
||||
true; \
|
||||
fi
|
||||
|
||||
custom_cal: ../custom/CUSTOM_CAL
|
||||
rm -f $@
|
||||
cp usage $@
|
||||
chmod 0444 $@
|
||||
-@if [ -z "${Q}" ]; then \
|
||||
echo ''; \
|
||||
echo '=-=-= skipping the cat of help/$@ =-=-='; \
|
||||
echo ''; \
|
||||
else \
|
||||
true; \
|
||||
fi
|
||||
|
||||
new_custom: ../custom/HOW_TO_ADD
|
||||
rm -f $@
|
||||
cp usage $@
|
||||
chmod 0444 $@
|
||||
-@if [ -z "${Q}" ]; then \
|
||||
echo ''; \
|
||||
echo '=-=-= skipping the cat of help/$@ =-=-='; \
|
||||
echo ''; \
|
||||
else \
|
||||
true; \
|
||||
fi
|
||||
|
||||
copy: blkcpy
|
||||
rm -f $@
|
||||
cp usage $@
|
||||
chmod 0444 $@
|
||||
-@if [ -z "${Q}" ]; then \
|
||||
echo ''; \
|
||||
echo '=-=-= skipping the cat of help/$@ =-=-='; \
|
||||
echo ''; \
|
||||
else \
|
||||
true; \
|
||||
fi
|
||||
|
||||
full: ${FULL_HELP_FILES} ${MAKE_FILE}
|
||||
${Q}echo "forming full"
|
||||
-${Q}rm -f full
|
||||
-${Q}for i in ${STD_HELP_FILES1} obj.file ${STD_HELP_FILES2} \
|
||||
${BUILT_HELP_FILES} ${STD_HELP_FILES3}; do \
|
||||
-${Q}rm -f $@
|
||||
-${Q}for i in ${FULL_HELP_FILES}; do \
|
||||
if [ Xintro != X"$$i" ]; then \
|
||||
echo ""; \
|
||||
else \
|
||||
@@ -215,7 +311,7 @@ full: ${STD_HELP_FILES} ${BUILT_HELP_FILES} ${MAKE_FILE}
|
||||
echo "*************"; \
|
||||
echo ""; \
|
||||
cat $$i; \
|
||||
done > full
|
||||
done > $@
|
||||
${Q}echo "full formed"
|
||||
-@if [ -z "${Q}" ]; then \
|
||||
echo ''; \
|
||||
@@ -302,8 +398,8 @@ distlist: ${DISTLIST}
|
||||
|
||||
# The bsdi distribution has generated files as well as distributed files.
|
||||
#
|
||||
bsdilist: ${DISTLIST} ${BUILT_HELP_FILES}
|
||||
${Q}for i in ${DISTLIST} ${BUILT_HELP_FILES}; do \
|
||||
bsdilist: ${DISTLIST} ${BLT_HELP_FILES}
|
||||
${Q}for i in ${DISTLIST} ${BLT_HELP_FILES}; do \
|
||||
echo calc/help/$$i; \
|
||||
done | ${SORT}
|
||||
|
||||
@@ -333,8 +429,9 @@ clean:
|
||||
rm -f obj mkbuiltin funclist.c funclist.o funclist
|
||||
|
||||
clobber:
|
||||
rm -f ${BUILT_HELP_FILES} full builtin .all
|
||||
rm -f obj mkbuiltin funclist.c funclist.o funclist ${SINGULAR_FILES}
|
||||
rm -f ${BLT_HELP_FILES} full .all calc
|
||||
rm -f obj mkbuiltin funclist.c funclist.o funclist
|
||||
rm -f ${SINGULAR_FILES} ${DETAIL_CLONE}
|
||||
|
||||
install: all
|
||||
-${Q}if [ ! -d ${TOPDIR} ]; then \
|
||||
@@ -355,8 +452,8 @@ install: all
|
||||
else \
|
||||
true; \
|
||||
fi
|
||||
${Q}for i in ${STD_HELP_FILES} ${BUILT_HELP_FILES} builtin \
|
||||
full ${DETAIL_HELP} ${SINGULAR_FILES} ${SYMBOL_HELP}; do \
|
||||
${Q}for i in ${STD_HELP_FILES} ${BLT_HELP_FILES} builtin \
|
||||
full ${DETAIL_HELP} ${SINGULAR_FILES}; do \
|
||||
echo rm -f ${HELPDIR}/$$i; \
|
||||
rm -f ${HELPDIR}/$$i; \
|
||||
echo cp $$i ${HELPDIR}; \
|
||||
@@ -367,3 +464,5 @@ install: all
|
||||
rm -f ${HELPDIR}/obj
|
||||
cp obj.file ${HELPDIR}/obj
|
||||
chmod 0444 ${HELPDIR}/obj
|
||||
# remove dead files
|
||||
-@rm -f rmblk block
|
||||
|
16
help/abs
16
help/abs
@@ -15,14 +15,18 @@ TYPES
|
||||
eps ignored if x is real, nonzero real for complex x,
|
||||
defaults to epsilon().
|
||||
|
||||
return real
|
||||
return non-negative real
|
||||
|
||||
DESCRIPTION
|
||||
If x is real, returns x if x is positive or zero, -x if x is negative.
|
||||
If x is real, returns the absolute value of x, i.e. x if x >= 0,
|
||||
-x if x < 0.
|
||||
|
||||
For complex x, returns the multiple of eps nearest or next to nearest
|
||||
to the absolute value of x. The result usually has error less in
|
||||
absolute value than abs(eps), but should not exceed 0.75 * abs(eps).
|
||||
For complex x with zero real part, returns the absolute value of im(x).
|
||||
|
||||
For other complex x, returns the multiple of eps nearest to the absolute
|
||||
value of x, or in the case of two equally near nearest values, the
|
||||
the nearest even multiple of eps. In particular, with eps = 10^-n,
|
||||
the result will be the absolute value correct to n decimal places.
|
||||
|
||||
EXAMPLE
|
||||
> print abs(3.4), abs(-3.4)
|
||||
@@ -35,7 +39,7 @@ LIMITS
|
||||
none
|
||||
|
||||
LIBRARY
|
||||
none
|
||||
NUMBER *qqabs(NUMBER *x)
|
||||
|
||||
SEE ALSO
|
||||
cmp, epsilon, hypot, norm, near, obj
|
||||
|
27
help/access
27
help/access
@@ -20,27 +20,30 @@ DESCRIPTION
|
||||
'w' or bit 1 for writing, 'x' or bit 0 for execution.
|
||||
|
||||
EXAMPLE
|
||||
The system error-numbers and messages may differ for different
|
||||
implementations
|
||||
|
||||
> !rm -f junk
|
||||
> access("junk")
|
||||
Error 10002 XXX This number will probably be changed
|
||||
System error 2
|
||||
> strerror(.)
|
||||
"No such file or directory"
|
||||
> f = fopen("junk", "w")
|
||||
> access("junk")
|
||||
> fputs(f, "Now is the time");
|
||||
> freopen(f, "r");
|
||||
> fputs(f, "Alpha")
|
||||
> fclose(f)
|
||||
> !chmod u-w junk
|
||||
> fgets(f)
|
||||
"Now is the time"
|
||||
> access("junk", "w")
|
||||
Error 10013 XXX
|
||||
> freopen(f, "w")
|
||||
Error 10013 XXX
|
||||
System error 13
|
||||
> strerror(.)
|
||||
"Permission denied"
|
||||
|
||||
LIMITS
|
||||
none - XXX - is this correct?
|
||||
There may be implementation-dependent limits inherited from the
|
||||
system call "access" used by this function.
|
||||
|
||||
LIBRARY
|
||||
none - XXX - is this correct?
|
||||
none
|
||||
|
||||
SEE ALSO
|
||||
errno, fclose, feof, ferror, fflush, fgetc, fgetline, fgets, files, fopen,
|
||||
fprintf, fputc, fputs, fseek, fsize, ftell, isfile, printf, prompt
|
||||
fopen, fclose, isfile, files
|
||||
|
@@ -21,9 +21,7 @@ EXAMPLE
|
||||
1.0472 1.0471975512 1.047197551196598 1.04719755119659774615
|
||||
|
||||
LIMITS
|
||||
unlike sin and cos, x must be real
|
||||
abs(x) <= 1
|
||||
eps > 0
|
||||
none
|
||||
|
||||
LIBRARY
|
||||
NUMBER *qacos(NUMBER *x, NUMBER *eps)
|
||||
|
11
help/acosh
11
help/acosh
@@ -11,19 +11,20 @@ TYPES
|
||||
return nonnegative real
|
||||
|
||||
DESCRIPTION
|
||||
Returns the cosh of x to a multiple of eps with error less in
|
||||
Returns the acosh of x to a multiple of eps with error less in
|
||||
absolute value than .75 * eps.
|
||||
|
||||
acosh(x) = ln(x + sqrt(x^2 - 1)) is the nonnegative real number v
|
||||
for which cosh(v) = x.
|
||||
acosh(x) is the nonnegative real number v for which cosh(v) = x.
|
||||
It is given by
|
||||
|
||||
acosh(x) = ln(x + sqrt(x^2 - 1))
|
||||
|
||||
EXAMPLE
|
||||
> print acosh(2, 1e-5), acosh(2, 1e-10), acosh(2, 1e-15), acosh(2, 1e-20)
|
||||
1.31696 1.3169578969 1.316957896924817 1.31695789692481670862
|
||||
|
||||
LIMITS
|
||||
unlike sin and cos, x must be real
|
||||
eps > 0
|
||||
none
|
||||
|
||||
LIBRARY
|
||||
NUMBER *qacosh(NUMBER *x, NUMBER *eps)
|
||||
|
@@ -21,8 +21,7 @@ EXAMPLE
|
||||
.46365 .463647609 .463647609000806 .46364760900080611621
|
||||
|
||||
LIMITS
|
||||
unlike sin and cos, x must be real
|
||||
eps > 0
|
||||
none
|
||||
|
||||
LIBRARY
|
||||
NUMBER *qacot(NUMBER *x, NUMBER *eps)
|
||||
|
@@ -14,17 +14,16 @@ DESCRIPTION
|
||||
Returns the acoth of x to a multiple of eps with error less in
|
||||
absolute value than .75 * eps.
|
||||
|
||||
acoth(x) = ln((x + 1)/(x - 1))/2 is the real number v for which
|
||||
coth(v) = x.
|
||||
acoth(x) is the real number v for which coth(v) = x.
|
||||
It is given by
|
||||
acoth(x) = ln((x + 1)/(x - 1))/2
|
||||
|
||||
EXAMPLE
|
||||
> print acoth(2, 1e-5), acoth(2, 1e-10), acoth(2, 1e-15), acoth(2, 1e-20)
|
||||
.54931 .5493061443 .549306144334055 .5493061443340548457
|
||||
|
||||
LIMITS
|
||||
unlike sin and cos, x must be real
|
||||
abs(x) > 1
|
||||
eps > 0
|
||||
none
|
||||
|
||||
LIBRARY
|
||||
NUMBER *qacoth(NUMBER *x, NUMBER *eps)
|
||||
|
@@ -21,9 +21,7 @@ EXAMPLE
|
||||
.5236 .5235987756 .523598775598299 .52359877559829887308
|
||||
|
||||
LIMITS
|
||||
unlike sin and cos, x must be real
|
||||
abs(x) >= 1
|
||||
eps > 0
|
||||
none
|
||||
|
||||
LIBRARY
|
||||
NUMBER *qacsc(NUMBER *x, NUMBER *eps)
|
||||
|
10
help/acsch
10
help/acsch
@@ -14,17 +14,17 @@ DESCRIPTION
|
||||
Returns the acsch of x to a multiple of eps with error less in
|
||||
absolute value than .75 * eps.
|
||||
|
||||
acsch(x) = ln((1 + sqrt(1 + x^2))/x) is the real number v for
|
||||
which csch(v) = x.
|
||||
acsch(x) is the real number v for which csch(v) = x. It is given by
|
||||
|
||||
acsch(x) = ln((1 + sqrt(1 + x^2))/x)
|
||||
|
||||
|
||||
EXAMPLE
|
||||
> print acsch(2, 1e-5), acsch(2, 1e-10), acsch(2, 1e-15), acsch(2, 1e-20)
|
||||
.48121 .4812118251 .481211825059603 .4812118250596034475
|
||||
|
||||
LIMITS
|
||||
unlike sin and cos, x must be real
|
||||
x != 0
|
||||
eps > 0
|
||||
none
|
||||
|
||||
LIBRARY
|
||||
NUMBER *qacsch(NUMBER *x, NUMBER *eps)
|
||||
|
161
help/address
Normal file
161
help/address
Normal file
@@ -0,0 +1,161 @@
|
||||
NAME
|
||||
& - address operator
|
||||
|
||||
SYNOPSIS
|
||||
&X
|
||||
|
||||
TYPES
|
||||
X expression specifying an octet, lvalue, string or number
|
||||
|
||||
return pointer
|
||||
|
||||
DESCRIPTION
|
||||
&X returns the address at which information for determining the current
|
||||
value of X is stored. After an assignment as in p = &X, the
|
||||
value of X is accessible by *p so long as the connection between p
|
||||
and the value is not broken by relocation of the information or by the
|
||||
value ceasing to exist. Use of an address after the connection
|
||||
is broken is unwise since the calculator may use that address for other
|
||||
purposes; the consequences of attempting to write data to, or
|
||||
otherwise accessing, such a vacated address may be catastrophic.
|
||||
|
||||
An octet is normally expressed by B[i] where B is a block and
|
||||
0 <= i < sizeof(B). &B[i] then returns the address at which this
|
||||
octet is located until the block is freed or relocated. Freeing
|
||||
of an unnamed block B occurs when a new value is assigned to B or
|
||||
when B ceases to exist; a named block B is freed by blkfree(B().
|
||||
A block is relocated when an operation like copying to B requires
|
||||
a change of sizeof(B).
|
||||
|
||||
An lvalue may be expressed by an identifier for a variable, or by
|
||||
such an identifier followed by one or more qualifiers compatible with
|
||||
the type of values associated with the variable and earlier qualifiers.
|
||||
If an identifier A specifies a global or static variable, the address
|
||||
&A is permanently associated with that variable. For a local variable
|
||||
or function parameter A, the association of the variable with &A
|
||||
is limited to each occasion when the function is called. If X specifies a
|
||||
component or element of a matrix or object, connection of
|
||||
&X with that component or element depends only on the continued existence
|
||||
of the matrix or object. For example, after
|
||||
|
||||
> mat A[3]
|
||||
|
||||
the addresses &A[0], &A[1], &A[2] locate the three elements
|
||||
of the matrix specified by A until another value is assigned to A, etc.
|
||||
Note one difference from C in that &A[0] is not the same as A.
|
||||
|
||||
An element of a list has a fixed address while the list exists and
|
||||
the element is not removed by pop(), remove(), or delete(); the index
|
||||
of the element changes if an element is pushed onto the list, or if
|
||||
earlier elements are popped or deleted.
|
||||
|
||||
Elements of an association have fixed addresses so long as the association
|
||||
exists. If A[a,b,...] has not been defined for the association A,
|
||||
&A[a,b,...] returns the constant address of a particular null value.
|
||||
|
||||
Some other special values have fixed addresses; e.g. the old value (.).
|
||||
|
||||
Some arithmetic operations are defined for addresses but these should
|
||||
be used only for octets or components of a matrix or object where the
|
||||
results refer to octets in the same block or existing components of the
|
||||
same matrix or object. For example, immediately after
|
||||
|
||||
> mat A[10]
|
||||
> p = &A[5]
|
||||
|
||||
it is permitted to use expressions like p + 4, p - 5, p++ .
|
||||
|
||||
Strings defined literally have fixed addresses, e.g., after
|
||||
|
||||
> p = &"abc"
|
||||
> A = "abc"
|
||||
|
||||
The address &*A of the value of A will be equal to p.
|
||||
|
||||
Except in cases like strcat(A, "") when *A identified with a literal
|
||||
string as above, definitions of string values using strcat() or substr()
|
||||
will copy the relevant strings to newly allocated addresses which will
|
||||
be useable only while the variables retain these defined values.
|
||||
For example,
|
||||
|
||||
> B = C = strcat("a", "bc");
|
||||
|
||||
&*B and &*C will be different. If p is defined by p = &*B, p should
|
||||
not be used after a mew value is assigned to B, or B ceases to exist,
|
||||
etc.
|
||||
|
||||
When compilation of a function encounters for the first time a particular
|
||||
literal number or the result of simple arithmetic operations (like +, -, *,
|
||||
or /) on literal numbers, that number is assigned to a particular
|
||||
address which is then used for later similar occurrences of that number
|
||||
so long as the number remains associated with at least one function or
|
||||
lvalue. For example, after
|
||||
|
||||
> x = 27;
|
||||
> y = 3 * 9;
|
||||
> define f(a) = 27 + a;
|
||||
|
||||
the three occurrences of 27 have the same address which may be displayed
|
||||
by any of &27, &*x, &*y and &f(0). If x and y are assigned
|
||||
other values and f is redefined or undefined and the 27 has not been
|
||||
stored elsewhere (e.g. as the "old value" or in another function
|
||||
definition or as an element in an association), the address assigned at
|
||||
the first occurrence of 27 will be freed and calc may later use it for
|
||||
another number.
|
||||
|
||||
When a function returns a number value, that number value is usually
|
||||
placed at a newly allocated address, even if an equal number is stored
|
||||
elsewhere. For example calls to f(a), as defined above, with the same
|
||||
non-zero value for a will be assigned to different addresses as can be
|
||||
seen from printing &*A, &*B, &*C after
|
||||
|
||||
> A = f(2); B = f(2); C = f(2);
|
||||
|
||||
(the case of f(0) is exceptional since 27 + 0 simply copies the 27
|
||||
rather than creating a new number value). Here it is clearly more
|
||||
efficient to use
|
||||
|
||||
> A = B = C = f(2);
|
||||
|
||||
which, not only performs the addition n f() only once, but stores the
|
||||
number values for A, B and C at the same address.
|
||||
|
||||
Whether a value V is a pointer and if so, its type, is indicated by the
|
||||
value returned by isptr(V): 1, 2, 3, 4 for octet-, value-, string-
|
||||
and number-pointer respectively, and 0 otherwise.
|
||||
|
||||
The output when addresses are printed consists of a description (o_ptr,
|
||||
v_ptr, s_ptr, n_ptr) followed by : and the address printed in
|
||||
%p format.
|
||||
|
||||
Iteration of & is not permitted; &&X causes a "non-variable operand"
|
||||
scan error.
|
||||
|
||||
EXAMPLE
|
||||
Addresses for particular systems may differ from those displayed here.
|
||||
|
||||
> mat A[3]
|
||||
> B = blk()
|
||||
|
||||
> print &A, &A[0], &A[1]
|
||||
v-ptr: 1400470d0 v-ptr: 140044b70 v-ptr: 140044b80
|
||||
|
||||
> print &B, &B[0], &B[1]
|
||||
v-ptr: 140047130 o-ptr: 140044d00 o-ptr: 140044d01
|
||||
|
||||
> a = A[0] = 27
|
||||
> print &*a, &*A[0]. &27
|
||||
n_ptr: 14003a850 n_ptr: 14003a850 n_ptr: 14003a850
|
||||
|
||||
> a = A[0] = "abc"
|
||||
> print &*a, &*A[0], &"abc"
|
||||
s_ptr: 14004cae0 s_ptr: 14004cae0 s_ptr: 14004cae0
|
||||
|
||||
LIMITS
|
||||
none
|
||||
|
||||
LIBRARY
|
||||
none
|
||||
|
||||
SEE ALSO
|
||||
dereference, isptr
|
57
help/agd
Normal file
57
help/agd
Normal file
@@ -0,0 +1,57 @@
|
||||
NAME
|
||||
agd - inverse gudermannian function
|
||||
|
||||
SYNOPSIS
|
||||
agd(z [,eps])
|
||||
|
||||
TYPES
|
||||
z number (real or complex)
|
||||
eps nonzero real, defaults to epsilon()
|
||||
|
||||
return number or infinite error value
|
||||
|
||||
DESCRIPTION
|
||||
Calculate the inverse gudermannian of z to a nultiple of eps with
|
||||
errors in real and imaginary parts less in absolute value than .75 * eps,
|
||||
or an error value if z is very close to one of the one of the branch
|
||||
points of agd(z)..
|
||||
|
||||
agd(z) is usually defined initially for real z with abs(z) < pi/2 by
|
||||
one of the formulae
|
||||
|
||||
agd(z) = ln(sec(z) + tan(z))
|
||||
|
||||
= 2 * atanh(tan(z/2))
|
||||
|
||||
= asinh(tan(z)),
|
||||
|
||||
or as the integral from 0 to z of (1/cos(t))dt. For complex z, the
|
||||
principal branch, approximated by gd(z, eps), has cuts along the real
|
||||
axis outside -pi/2 < z < pi/2.
|
||||
|
||||
If z = x + i * y and abs(x) < pi/2, agd(z) is given by
|
||||
|
||||
agd(z) = atanh(sin(x)/cosh(y)) + i * atan(sinh(y)/cos(x)>
|
||||
|
||||
|
||||
EXAMPLE
|
||||
> print agd(1, 1e-5), agd(1, 1e-10), agd(1, 1e-15)
|
||||
1.22619 1.2261911709 1.226191170883517
|
||||
|
||||
> print agd(2, 1e-5), agd(2, 1e-10)
|
||||
1.52345-3.14159i 1.5234524436-3.1415926536i
|
||||
|
||||
> print agd(5, 1e-5), agd(5, 1e-10), agd(5, 1e-15)
|
||||
-1.93237 -1.9323667197 -1.932366719745925
|
||||
|
||||
> print agd(1+2i, 1e-5), agd(1+2i, 1e-10)
|
||||
.22751+1.42291i .2275106584+1.4229114625i
|
||||
|
||||
LIMITS
|
||||
none
|
||||
|
||||
LIBRARY
|
||||
COMPLEX *cagd(COMPLEX *x, NUMBER *eps)
|
||||
|
||||
SEE ALSO
|
||||
gd, exp, ln, sin, sinh, etc.
|
14
help/appr
14
help/appr
@@ -22,7 +22,7 @@ DESCRIPTION
|
||||
there is no "approximation" - the result represents x exactly.
|
||||
|
||||
In the following it is assumed y is nonzero and x is not a multiple of y.
|
||||
For Real x:
|
||||
For real x:
|
||||
|
||||
appr(x,y,z) is either the nearest multiple of y greater
|
||||
than x or the nearest multiple of y less than x. Thus, if
|
||||
@@ -45,9 +45,9 @@ DESCRIPTION
|
||||
|
||||
z = 3 round away from zero, sgn(r) = -sgn(x)
|
||||
|
||||
z = 4 round down
|
||||
z = 4 round down, r > 0
|
||||
|
||||
z = 5 round up
|
||||
z = 5 round up, r < 0
|
||||
|
||||
z = 6 round towards or from zero according as y is positive or
|
||||
negative, sgn(r) = sgn(x/y)
|
||||
@@ -82,7 +82,9 @@ DESCRIPTION
|
||||
appr(x,y,z) returns the matrix or list indexed in the same way as x,
|
||||
in which each element t has been replaced by appr(t,y,z).
|
||||
|
||||
XXX - complex x needs to be documented
|
||||
Complex x:
|
||||
|
||||
Returns appr(re(x), y, z) + appr(im(x), y, z) * 1i
|
||||
|
||||
PROPERTIES
|
||||
If appr(x,y,z) != x, then abs(x - appr(x,y,z)) < abs(y).
|
||||
@@ -134,6 +136,10 @@ EXAMPLES
|
||||
> print appr(-.44,-.1,15),appr(.44,-.1,15),appr(5.7,-1,15),appr(-5.7,-1,15)
|
||||
-.4 .5 5 -6
|
||||
|
||||
> x = sqrt(7-3i, 1e-20)
|
||||
> print appr(x,1e-5,0), appr(x,1e-5,1), appr(x,1e-5,2), appr(x,1e-6,3)
|
||||
2.70331-.55488i 2.70332-.55487i 2.70331-.55487i 2.70332-.55488i
|
||||
|
||||
LIMITS
|
||||
none
|
||||
|
||||
|
@@ -7,7 +7,7 @@ Where to get the the latest versions of calc
|
||||
Alpha test versions, complete with bugs, untested code and
|
||||
experimental features may be fetched (if you are brave) under:
|
||||
|
||||
http://reality.sgi.com/chongo/calc/
|
||||
http://reality.sgi.com/chongo/tech/comp/calc/
|
||||
|
||||
One may join the calc testing group by sending a request to:
|
||||
|
||||
@@ -22,4 +22,7 @@ Where to get the the latest versions of calc
|
||||
where "address" is your EMail address and "your_full_name"
|
||||
is your full name.
|
||||
|
||||
Landon Curt Noll <chongo@toad.com> /\oo/\
|
||||
Landon Curt Noll
|
||||
http://reality.sgi.com/chongo
|
||||
|
||||
chongo <was here> /\../\
|
||||
|
2
help/arg
2
help/arg
@@ -13,7 +13,7 @@ TYPES
|
||||
DESCRIPTION
|
||||
Returns the argument of x to the nearest or next to nearest multiple of
|
||||
eps; the error will be less in absolute value than 0.75 * abs(eps),
|
||||
but usually less than 0.5 * abs(eps). By default, acc is epsilon().
|
||||
but usually less than 0.5 * abs(eps).
|
||||
|
||||
EXAMPLE
|
||||
> print arg(2), arg(2+3i, 1e-5), arg(2+3i, 1e-10), arg(2+3i, 1e-20)
|
||||
|
51
help/arrow
Normal file
51
help/arrow
Normal file
@@ -0,0 +1,51 @@
|
||||
SYMBOL and NAME
|
||||
-> - arrow operator
|
||||
|
||||
SYNOPSIS
|
||||
p -> X
|
||||
|
||||
TYPES
|
||||
p pointer to an lvalue
|
||||
X identifier
|
||||
|
||||
return lvalue
|
||||
|
||||
DESCRIPTION
|
||||
p->X returns the same as (*p).X. Thus the current value of *p is
|
||||
to be an object of a type for which X identifies one element.
|
||||
p->X then returns the lvalue corresponding to that element of of the
|
||||
value of *p.
|
||||
|
||||
The expression *p.X will cause a runtime error since this is
|
||||
interpreted as *(p.X) in which p is expected to be an object of
|
||||
an appropriate type.
|
||||
|
||||
Spaces or tabs on either side of -> are optional.
|
||||
|
||||
EXAMPLES
|
||||
> obj pair {one, two}
|
||||
> obj pair A, B
|
||||
> p = &A
|
||||
> p->one = 1; p->two = 2
|
||||
> A
|
||||
obj pair {1, 2}
|
||||
|
||||
> A->two = &B
|
||||
> p->two->one = 3; p->two->two = 4
|
||||
|
||||
> *p->ptwo
|
||||
obj pair {3, 4}
|
||||
|
||||
> B = {5,6}
|
||||
> *p->two
|
||||
obj pair {5, 6}
|
||||
|
||||
|
||||
LIMITS
|
||||
none
|
||||
|
||||
LIBRARY
|
||||
none
|
||||
|
||||
SEE ALSO
|
||||
address, dereference, isptr, dot
|
@@ -21,9 +21,7 @@ EXAMPLE
|
||||
1.0472 1.0471975512 1.047197551196598 1.04719755119659774615
|
||||
|
||||
LIMITS
|
||||
unlike sin and cos, x must be real
|
||||
abs(x) >= 1
|
||||
eps > 0
|
||||
none
|
||||
|
||||
LIBRARY
|
||||
NUMBER *qasec(NUMBER *x, NUMBER *eps)
|
||||
|
@@ -14,17 +14,16 @@ DESCRIPTION
|
||||
Returns the asech of x to a multiple of eps with error less in
|
||||
absolute value than .75 * eps.
|
||||
|
||||
asech(x) = ln((1 + sqrt(1 - x^2))/x) is the real number v for which
|
||||
sech(v) = x.
|
||||
asech(x) is the real number v for which sech(v) = x. It is given by
|
||||
|
||||
asech(x) = ln((1 + sqrt(1 - x^2))/x)
|
||||
|
||||
EXAMPLE
|
||||
> print asech(.5,1e-5), asech(.5,1e-10), asech(.5,1e-15), asech(.5,1e-20)
|
||||
1.31696 1.3169578969 1.316957896924817 1.31695789692481670862
|
||||
|
||||
LIMITS
|
||||
unlike sin and cos, x must be real
|
||||
0 < x <= 1
|
||||
eps > 0
|
||||
none
|
||||
|
||||
LIBRARY
|
||||
NUMBER *qasech(NUMBER *x, NUMBER *eps)
|
||||
|
@@ -21,9 +21,7 @@ EXAMPLE
|
||||
.5236 .5235987756 .523598775598299 .52359877559829887308
|
||||
|
||||
LIMITS
|
||||
unlike sin and cos, x must be real
|
||||
abs(x) <= 1
|
||||
eps > 0
|
||||
none
|
||||
|
||||
LIBRARY
|
||||
NUMBER *qasin(NUMBER *q, NUMBER *epsilon)
|
||||
|
@@ -14,16 +14,16 @@ DESCRIPTION
|
||||
Returns the asinh of x to a multiple of eps with error less in
|
||||
absolute value than .75 * eps.
|
||||
|
||||
asinh(x) = ln(x + sqrt(1 + x^2)) is the real number v for which
|
||||
sinh(v) = x.
|
||||
asinh(x) is the real number v for which sinh(v) = x. It is given by
|
||||
|
||||
asinh(x) = ln(x + sqrt(1 + x^2))
|
||||
|
||||
EXAMPLE
|
||||
> print asinh(2, 1e-5), asinh(2, 1e-10), asinh(2, 1e-15), asinh(2, 1e-20)
|
||||
1.44363 1.4436354752 1.44363547517881 1.44363547517881034249
|
||||
|
||||
LIMITS
|
||||
unlike sin and cos, x must be real
|
||||
eps > 0
|
||||
none
|
||||
|
||||
LIBRARY
|
||||
NUMBER *qasinh(NUMBER *x, NUMBER *eps)
|
||||
|
97
help/assign
97
help/assign
@@ -3,22 +3,111 @@ NAME
|
||||
|
||||
SYNOPSIS
|
||||
a = b
|
||||
a = {e_1, e_2, ...[ { ... } ] }
|
||||
|
||||
TYPES
|
||||
a lvalue
|
||||
b expression
|
||||
a lvalue, current value a structure in { } case
|
||||
|
||||
return lvalue
|
||||
b expression
|
||||
|
||||
e_0, e_1, ... expressions, blanks, or initializer lists
|
||||
|
||||
|
||||
return lvalue (a)
|
||||
|
||||
DESCRIPTION
|
||||
Here an lvalue is either a simple variable specified by an identifier,
|
||||
or an element of an existing structure specified by one or more
|
||||
qualifiers following an identifier.
|
||||
|
||||
An initializer list is a comma-separated list enclosed in braces as in
|
||||
|
||||
{e_0, e_1, ... }
|
||||
|
||||
where each e_i is an expression, blank or initializer list.
|
||||
|
||||
a = b evaluates b, assigns its value to a, and returns a.
|
||||
|
||||
a = {e_0, e_1, ... } where the e_i are expressions or blanks,
|
||||
requires the current value of a to be a matrix, list
|
||||
or object with at least as many elements as listed e_i. Each non-blank
|
||||
e_i is evaluated and its value is assigned to a[[i]]; elements a[[i]]
|
||||
corresponding to blank e_i are unchanged.
|
||||
|
||||
If, in a = {e_0, e_1, ...}, e_i is an initializer list, as in
|
||||
{e_i_0, e_1_1, ...}, the corresponding a[[i]] is to be a matrix, list
|
||||
or object with at least as many elements as listed e_i_j. Depending on
|
||||
whether e_i_j is an expression, blank, or initializer list, one, no, or
|
||||
possibly more than one assignment, is made to a[[i]][[j]] or, if
|
||||
relevant and possible, its elements.
|
||||
|
||||
In simple assignments, = associates from right to left so that, for
|
||||
example,
|
||||
|
||||
a = b = c
|
||||
|
||||
has the effect of a = (b = c) and results in assigning the value of c
|
||||
to both a and b. The expression (a = b) = c is acceptable, but has the
|
||||
effect of a = b; a = c; in which the first assignment is superseded by
|
||||
the second.
|
||||
|
||||
In initializations, = { ...} associates from left to right so that,
|
||||
for example,
|
||||
|
||||
a = {e_0, ... } = {v_0, ...}
|
||||
|
||||
first assigns e_0, ... to the elements of a, and then assigns v_0, ...
|
||||
to the result.
|
||||
|
||||
If there are side effects in the evaluations involved in executing a = b,
|
||||
it should be noted that the order of evaluations is: first the address
|
||||
for a, then the value of b, and finally the assignment. For example if
|
||||
A is a matrix and i = 0, then the assignment in A[i++] = A[i] is
|
||||
that of A[0] = A[1].
|
||||
|
||||
If, in execution of a = b, a is changed by the evaluation of b, the
|
||||
value of b may be stored in an unintended or inaccessible location. For
|
||||
example,
|
||||
mat A[2]= {1,2};
|
||||
A[0] = (A = 3);
|
||||
|
||||
results in the value 3 being stored not only as the new value for A
|
||||
but also at the now unnamed location earlier used for A[0].
|
||||
|
||||
|
||||
EXAMPLE
|
||||
> b = 3+1
|
||||
> a = b
|
||||
> print a, b
|
||||
4 4
|
||||
|
||||
> obj point {x,y}
|
||||
> mat A[3] = {1, list(2,3), obj point = {4,5}}
|
||||
|
||||
> A[1][[0]] = 6; A[2].x = 7
|
||||
> print A[1]
|
||||
|
||||
list (2 elements, 2 nonzero):
|
||||
[[0]] = 6
|
||||
[[1]] = 3
|
||||
|
||||
> print A[2]
|
||||
obj point {7, 5}
|
||||
|
||||
> A = {A[2], , {9,10}}
|
||||
> print A[0]
|
||||
obj point {7, 5}
|
||||
|
||||
> print A[2]
|
||||
obj point {9, 10}
|
||||
|
||||
> A = {, {2}}
|
||||
print A[1]
|
||||
|
||||
list (2 elements, 2 nonzero):
|
||||
[[0]] = 2
|
||||
[[1]] = 3
|
||||
|
||||
LIMITS
|
||||
none
|
||||
|
||||
@@ -26,4 +115,4 @@ LIBRARY
|
||||
none
|
||||
|
||||
SEE ALSO
|
||||
XXX - fill in
|
||||
swap, quomod
|
||||
|
57
help/assoc
57
help/assoc
@@ -8,38 +8,34 @@ TYPES
|
||||
return association
|
||||
|
||||
DESCRIPTION
|
||||
This functions returns an empty association array.
|
||||
This function returns an empty association array.
|
||||
|
||||
Associations are special values that act like matrices, except
|
||||
that they are more general (and slower) than normal matrices.
|
||||
Unlike matrices, associations can be indexed by arbitrary values.
|
||||
For example, if 'val' was an association, you could do the following:
|
||||
After A = assoc(), elements can be added to the association by
|
||||
assignments of the forms
|
||||
|
||||
val['hello'] = 11;
|
||||
val[4.5] = val['hello'];
|
||||
print val[9/2];
|
||||
A[a_1] = v_1
|
||||
A[a_1, a_2] = v_2
|
||||
A[a_1, a_2, a_3] = v_3
|
||||
A[a_1, a_2, a_3, a_4] = v_4
|
||||
|
||||
and 11 would be printed.
|
||||
There are no restrictions on the values of the "indices" a_i or
|
||||
the "values" v_i.
|
||||
|
||||
Associations are created by the 'assoc' function. It takes no
|
||||
arguments, and simply returns an empty association. You can then
|
||||
insert elements into the association by indexing the returned value
|
||||
as shown above.
|
||||
After the above assignments, so long as no new values have been
|
||||
assigned to A[a_i], etc., the expressions A[a_1], A[a_1, a_2], etc.
|
||||
will return the values v_1, v_2, ...
|
||||
|
||||
Associations are multi-dimensional. You can index them using one to
|
||||
four dimensions as desired, and the elements with different numbers
|
||||
of dimensions will remain separated. For example, 'val[3]' and
|
||||
'val[3,0]' can both be used in the same association and will be
|
||||
distinct elements.
|
||||
Until A[a_1], A[a_1, a_2], ... are defined as described above, these
|
||||
expressions return the null value.
|
||||
|
||||
When references are made to undefined elements of an association,
|
||||
a null value is simply returned. Therefore no bounds errors can
|
||||
occur when indexing an association. Assignments of a null value
|
||||
Thus associations act like matrices except that different elements
|
||||
may have different numbers (between 1 and 4 inclusive) of indices,
|
||||
and these indices need not be integers in specified ranges.
|
||||
|
||||
Assignments of a null value
|
||||
to an element of an association does not delete the element, but
|
||||
a later reference to that element will return the null value as if
|
||||
the element was undefined. Elements with null values are implicitly
|
||||
created on certain other operations which require an address to be
|
||||
taken, such as the += operator and using & in a function call.
|
||||
the element is undefined.
|
||||
|
||||
The elements of an association are stored in a hash table for
|
||||
quick access. The index values are hashed to select the correct
|
||||
@@ -65,9 +61,18 @@ DESCRIPTION
|
||||
and are illegal.
|
||||
|
||||
EXAMPLE
|
||||
> print assoc()
|
||||
> A = assoc(); print A
|
||||
assoc (0 elements):
|
||||
|
||||
assoc (0 elements):
|
||||
> A["zero"] = 0; A["one"] = 1; A["two"] = 2; A["three"] = 3;
|
||||
> A["smallest", "prime"] = 2;
|
||||
> print A
|
||||
assoc (5 elements);
|
||||
["two"] = 2
|
||||
["three"] = 3
|
||||
["one"] = 1
|
||||
["zero"] = 0
|
||||
["smallest","prime"] = 2
|
||||
|
||||
LIMITS
|
||||
none
|
||||
|
@@ -21,8 +21,7 @@ EXAMPLE
|
||||
1.10715 1.1071487178 1.107148717794091 1.10714871779409050302
|
||||
|
||||
LIMITS
|
||||
unlike sin and cos, x must be real
|
||||
eps > 0
|
||||
none
|
||||
|
||||
LIBRARY
|
||||
NUMBER *qatan(NUMBER *x, NUMBER *eps)
|
||||
|
21
help/atan2
21
help/atan2
@@ -2,32 +2,33 @@ NAME
|
||||
atan2 - angle to point
|
||||
|
||||
SYNOPSIS
|
||||
atan2(y, x, [,acc])
|
||||
atan2(y, x, [,eps])
|
||||
|
||||
TYPES
|
||||
y real
|
||||
x real
|
||||
acc real
|
||||
eps nonzero real, defaults to epsilon()
|
||||
|
||||
return real
|
||||
|
||||
DESCRIPTION
|
||||
Return the angle which is determined by the point (x,y). This
|
||||
function computes the arctangent of y/x in the range [-pi, pi].
|
||||
The value acc specifies the accuracy of the result. By default, acc
|
||||
is epsilon().
|
||||
If x and y are not both zero, atan2(y, x, eps) returns, as a multiple of
|
||||
eps with error less than abs(eps), the angle t such that
|
||||
-pi < t <= pi and x = r * cos(t), y = r * sin(t), where
|
||||
r > 0. Usually the error does not exceed abs(eps)/2.
|
||||
|
||||
Note that by convention, y is the first argument.
|
||||
Note that by convention, y is the first argument; if x > 0,
|
||||
atan2(y, x) = atan(y/x).
|
||||
|
||||
To conform to the 4.3BSD ANSI/IEEE 754-1985 math lib, atan2(0,0) is
|
||||
defined to return 0.
|
||||
To conform to the 4.3BSD ANSI/IEEE 754-1985 math lib, atan2(0,0)
|
||||
returns 0.
|
||||
|
||||
EXAMPLE
|
||||
> print atan2(0,0), atan2(1,sqrt(3)), atan2(17,53,1e-100)
|
||||
0 ~.52359877559829887307 ~.31038740713235146535
|
||||
|
||||
LIMITS
|
||||
acc > 0
|
||||
none
|
||||
|
||||
LIBRARY
|
||||
NUMBER *qatan2(NUMBER *y, *x, *acc)
|
||||
|
@@ -14,16 +14,16 @@ DESCRIPTION
|
||||
Returns the atanh of x to a multiple of eps with error less in
|
||||
absolute value than .75 * eps.
|
||||
|
||||
atanh(x) = ln((1 + x)/(1 - x))/2 is the real number v for whichi
|
||||
tanh(v) = x.
|
||||
atanh(x) is the real number v for which tanh(v) = x. It is given by
|
||||
|
||||
atanh(x) = ln((1 + x)/(1 - x))/2
|
||||
|
||||
EXAMPLE
|
||||
> print atanh(.5,1e-5), atanh(.5,1e-10), atanh(.5,1e-15), atanh(.5,1e-20)
|
||||
.54931 .5493061443 .549306144334055 .5493061443340548457
|
||||
|
||||
LIMITS
|
||||
unlike sin and cos, x must be real
|
||||
eps > 0
|
||||
none
|
||||
|
||||
LIBRARY
|
||||
NUMBER *qatanh(NUMBER *x, NUMBER *eps)
|
||||
|
@@ -11,7 +11,7 @@ TYPES
|
||||
|
||||
DESCRIPTION
|
||||
The base function allows one to specify how numbers should be
|
||||
printer. The base function provides a numeric shorthand to the
|
||||
printed. The base function provides a numeric shorthand to the
|
||||
config("mode") interface. With no args, base() will return the
|
||||
current mode. With 1 arg, base(val) will set the mode according to
|
||||
the arg and return the previous mode.
|
||||
|
43
help/bit
Normal file
43
help/bit
Normal file
@@ -0,0 +1,43 @@
|
||||
NAME
|
||||
bit - whether a given binary bit is set in a value
|
||||
|
||||
SYNOPSIS
|
||||
bit(x, y)
|
||||
|
||||
TYPES
|
||||
x real
|
||||
y int
|
||||
|
||||
return int
|
||||
|
||||
DESCRIPTION
|
||||
Determine if the binary bit y is set in x. If:
|
||||
|
||||
x
|
||||
int(---) mod 2 == 1
|
||||
2^y
|
||||
|
||||
return 1, otherwise return 0.
|
||||
|
||||
EXAMPLE
|
||||
> print bit(9,0), bit(9,1), bit(9,2), bit(9,3)
|
||||
1 0 0 1
|
||||
|
||||
> print bit(9,4), bit(0,0), bit(9,-1)
|
||||
0 0 0
|
||||
|
||||
> print bit(1.25, -2), bit(1.25, -1), bit(1.25, 0)
|
||||
1 0 1
|
||||
|
||||
> p = pi()
|
||||
> print bit(p, 1), bit(p, -2), bit(p, -3)
|
||||
1 0 1
|
||||
|
||||
LIMITS
|
||||
-2^31 < y < 2^31
|
||||
|
||||
LIBRARY
|
||||
BOOL qbit(NUMBER *x, long y)
|
||||
|
||||
SEE ALSO
|
||||
highbit, lowbit, digit
|
219
help/blk
Normal file
219
help/blk
Normal file
@@ -0,0 +1,219 @@
|
||||
NAME
|
||||
blk - generate or modify block values
|
||||
|
||||
SYNOPSIS
|
||||
blk([len, chunk]);
|
||||
blk(val [, len, chunk]);
|
||||
|
||||
TYPES
|
||||
len null or integer
|
||||
chunk null or integer
|
||||
val non-null string, block, or named block
|
||||
|
||||
return block or named block
|
||||
|
||||
DESCRIPTION
|
||||
With only integer arguments, blk(len, chunk) attempts to
|
||||
allocate a block of memory consisting of N octets (unsigned 8-bit
|
||||
bytes). Allocation is always done in multiples of chunk
|
||||
octets, so the actual allocation size of len rounded up
|
||||
to the next multiple of chunk.
|
||||
|
||||
The default value for len is 0. The default value for chunk is 256.
|
||||
|
||||
If the allocation is successful, blk(len, chunk) returns a value B, say,
|
||||
for which the octets in the block may be referenced by B[0], B[1],
|
||||
... , B[len-1], these all initially having zero value.
|
||||
|
||||
The octets B[i] for i >= len always have zero value. If B[i] with
|
||||
some i >= len is referenced, len is increased by 1. For example:
|
||||
|
||||
B[i] = x
|
||||
|
||||
has an effect like that of two operations on a file stream fs:
|
||||
|
||||
fseek(fs, pos);
|
||||
fputc(fs, x).
|
||||
|
||||
Similarly:
|
||||
|
||||
x = B[i]
|
||||
|
||||
is like:
|
||||
|
||||
fseek(fs, pos);
|
||||
x = fgetc(fs).
|
||||
|
||||
The value of chunk is stored as the "chunksize" for B.
|
||||
|
||||
The size(B) builtin returns the current len for the block; sizeof(B)
|
||||
returns its maxsize; memsize(B) returns maxsize + overhead for any block
|
||||
value. Also size(B) is analogous to the length of a file stream in that
|
||||
if size(B) < sizeof(B):
|
||||
|
||||
B[size(B)] = x
|
||||
|
||||
will append one octet to B and increment size(B).
|
||||
|
||||
The builtin test(B) returns 1 or 0 according as at least one octet
|
||||
is zero or all octets are zero. If B1 and B2 are blocks, they are
|
||||
considered equal (B1 == B2) if they have the same length and the
|
||||
same data, i.e. B1[i] == B2[i] for 0 <= i < len. Chunksizes
|
||||
and maxsizes are ignored.
|
||||
|
||||
The output for print B occupies two lines, the first line giving
|
||||
the chunksize, number of octets allocated (len rounded up to the
|
||||
next chunk) and len, and the second line up to 30 octets of data.
|
||||
If the datalen is zero, the second line is blank. If the datalen
|
||||
exceeds 30, this indicated by a trailing "...".
|
||||
|
||||
If a block value B created by B = blk(len, chunk) is assigned to
|
||||
another variable by C = B, a new block of the same structure as B
|
||||
is created to become the value of C, and the octets in B are copied
|
||||
to this new block. A block with possibly different length or
|
||||
chunksize is created by C = blk(B, newlen, newchunk), only the first
|
||||
min(len, newlen) octets being copied from B; later octets are
|
||||
assigned zero value. If omitted, newlen and newchunk default to
|
||||
the current datalen and chunk-size for B. The curent datalen,
|
||||
chunksize and number of allocated octets for B may be changed by:
|
||||
|
||||
B = blk(B, newlen, newchunk).
|
||||
|
||||
No data is lost if newlen is greater than or equal to the old
|
||||
size(B).
|
||||
|
||||
The memory block allocated by blk(len, chunk) is freed at or before
|
||||
termination of the statement in which this occurred, the memory
|
||||
allocated in B = blk(len, chunk) is freed when B is assigned another
|
||||
value.
|
||||
|
||||
With a string str as its first argument, blk(str [, len, chunk])
|
||||
when called for the first time creates a block with str as its
|
||||
name. Here there no restriction on the characters used in str;
|
||||
thus the string may include white space or characters normally used
|
||||
for punctuation or operators. Any subsequent call to blk(str, ...)
|
||||
with the same str will refer to the same named block.
|
||||
|
||||
A named block is assigned length and chunksize and consequent
|
||||
maximum size in the same way as unnamed blocks. A major difference
|
||||
is that in assignments, a named block is not copied. Thus, if a
|
||||
block A has been created by:
|
||||
|
||||
A = blk("foo")
|
||||
any subsequent:
|
||||
B = A
|
||||
or:
|
||||
B = blk("foo")
|
||||
|
||||
will give a second variable B referring to the same block as A.
|
||||
Either A[i] = x or B[i] = x may then be used to assign a value
|
||||
to an octet in the book. Its length or chunksize may be changed by
|
||||
instructions like:
|
||||
|
||||
blk(A, len, chunk);
|
||||
|
||||
A = blk(A, len, chunk);
|
||||
|
||||
null(blk(A, len, chunk)).
|
||||
|
||||
These have the same effect on A; when working interactively, the
|
||||
last two avoid printing of the new value for A.
|
||||
|
||||
Named blocks are assigned index numbers 0, 1, 2, ..., in the order
|
||||
of their creation. The block with index id is returned by blocks(id).
|
||||
With no argument, blocks() returns the number of current unfreed
|
||||
named blocks. A named block may be used
|
||||
|
||||
The memory allocated to a named block is freed by the blkfree()
|
||||
function with argument the named block, its name, or its id number.
|
||||
The block remains in existence but with a null data pointer,
|
||||
its length and size being reduced to zero. A new block of memory
|
||||
may be allocated to it, with possibly new length and chunksize by:
|
||||
|
||||
blk(val [, len, chunk])
|
||||
|
||||
where val is either the named block or its name.
|
||||
|
||||
The printing output for a named block is in three lines, the first
|
||||
line displaying its id number and name, the other two as for an
|
||||
unnamed block, except that "NULL" is printed if the memory has been
|
||||
freed.
|
||||
|
||||
The identifying numbers and names of the current named blocks are
|
||||
displayed by:
|
||||
show blocks
|
||||
|
||||
If A and B are named blocks, A == B will be true only if they refer
|
||||
to the same block of memory. Thus, blocks with the same data and
|
||||
datalen will be considered unequal if they have different names.
|
||||
|
||||
If A is a named block, str(A) returns the name of the block.
|
||||
|
||||
Values may be assigned to the early octets of a named or unnamed
|
||||
block by use of = { } initialization as for matrices.
|
||||
|
||||
EXAMPLE
|
||||
|
||||
> B = blk(15,10)
|
||||
|
||||
> B[7] = 0xff
|
||||
> B
|
||||
chunksize = 10, maxsize = 20, datalen = 15
|
||||
00000000000000ff00000000000000
|
||||
|
||||
> B[18] = 127
|
||||
> B
|
||||
chunksize = 10, maxsize = 20, datalen = 18
|
||||
00000000000000ff0000000000000000007f
|
||||
|
||||
> B[20] = 2
|
||||
Index out of bounds for block
|
||||
|
||||
> print size(B), sizeof(B)
|
||||
18 20
|
||||
|
||||
> B = blk(B, 100, 20)
|
||||
> B
|
||||
chunksize = 20, maxsize = 120, datalen = 100
|
||||
00000000000000ff0000000000000000007f000000000000000000000000...
|
||||
|
||||
> C = blk(B, 10} = {1,2,3}
|
||||
> C
|
||||
chunksize = 20, maxsize = 20, datalen = 10
|
||||
01020300000000ff0000
|
||||
|
||||
> A1 = blk("alpha")
|
||||
> A1
|
||||
block 0: alpha
|
||||
chunksize = 256, maxsize = 256, datalen = 0
|
||||
|
||||
> A1[7] = 0xff
|
||||
> A2 = A1
|
||||
> A2[17] = 127
|
||||
> A1
|
||||
block 0: alpha
|
||||
chunksize = 256, maxsize = 256, datalen = 18
|
||||
00000000000000ff0000000000000000007f
|
||||
|
||||
> A1 = blk(A1, 1000)
|
||||
> A1
|
||||
block 0: alpha
|
||||
chunksize = 256, maxsize = 1024, datalen = 1000
|
||||
00000000000000ff0000000000000000007f000000000000000000000000...
|
||||
|
||||
> A1 = blk(A1, , 16)
|
||||
> A1
|
||||
block 0: alpha
|
||||
chunksize = 16, maxsize = 1008, datalen = 1000
|
||||
00000000000000ff0000000000000000007f000000000000000000000000...
|
||||
|
||||
LIMITS
|
||||
0 <= len < 2^31
|
||||
|
||||
1 <= chunk < 2^31
|
||||
|
||||
LIBRARY
|
||||
XXX
|
||||
|
||||
SEE ALSO
|
||||
blocks, blkfree
|
192
help/blkcpy
Normal file
192
help/blkcpy
Normal file
@@ -0,0 +1,192 @@
|
||||
NAME
|
||||
blkcpy, copy - copy items from a structure to a structure
|
||||
|
||||
SYNOPSIS
|
||||
blkcpy(dst, src [, num [, dsi [, ssi]]]
|
||||
copy(src, dest [, [ssi [, num [, dsi]]])
|
||||
|
||||
TYPES
|
||||
src block, file, string, matrix, or list
|
||||
dest block, file, matrix or list - compatible with src
|
||||
|
||||
ssi nonnegative integer, defaults to zero
|
||||
num nonnegative integer, defaults to maximum possible
|
||||
dsi nonnegative integer, defaults to datalen for a block, filepos
|
||||
for a file, zero for other structures
|
||||
|
||||
return null if successful, error value otherwise
|
||||
|
||||
DESCRIPTION
|
||||
A call to:
|
||||
|
||||
blkcpy(dst, src, num, dsi, ssi)
|
||||
|
||||
attempts to copy 'num' consecutive items (octets or values) starting
|
||||
from the source item 'src' with index 'ssi'. By default, 'num'
|
||||
is the maximum possible and 'ssi' is 0.
|
||||
|
||||
A call to:
|
||||
|
||||
copy(src, dst, ssi, num, dsi)
|
||||
|
||||
does the same thing, but with a different arg order.
|
||||
|
||||
A copy fails if ssi or num is too large for the number of items in
|
||||
the source, if sdi is too large for the number of positions
|
||||
available in the destination, or, in cases involving a file stream,
|
||||
if the file is not open in the required mode. The source and
|
||||
destination need not be of the same type, e.g. when a block is
|
||||
copied to a matrix the octets are converted to numbers.
|
||||
|
||||
The following pairs of source-type, destination-type are permitted:
|
||||
|
||||
block to
|
||||
int
|
||||
block
|
||||
matrix
|
||||
file
|
||||
|
||||
matrix to
|
||||
block
|
||||
matrix
|
||||
list
|
||||
|
||||
string to
|
||||
block
|
||||
file
|
||||
|
||||
list to
|
||||
list
|
||||
matrix
|
||||
|
||||
file to
|
||||
block
|
||||
|
||||
int to
|
||||
block
|
||||
|
||||
In the above table, int refers to integer values. However if a
|
||||
rational value is supplied, only the numerator is copied.
|
||||
|
||||
Each copied octet or value replaces the octet or value in the
|
||||
corresponding place in the destination structure. When copying values
|
||||
to values, the new values are stored in a buffer, the old values are
|
||||
removed, and the new values copied from the buffer to the destination.
|
||||
This permits movement of data within one matrix or list, and copying
|
||||
of an element of structure to the structure.
|
||||
|
||||
Except for copying to files or blocks, the destination is already to have
|
||||
sufficient memory allocated for the copying. For example, to copy
|
||||
a matrix M of size 100 to a newly created list, one may use:
|
||||
|
||||
L = makelist(100);
|
||||
copy(M, L);
|
||||
or:
|
||||
L = makelist(100);
|
||||
blkcpy(L, M);
|
||||
|
||||
For copying from a block B (named or unnamed), the total number of octets
|
||||
available for copying is taken to the the datalen for that block,
|
||||
so that num can be at most size(B) - ssi.
|
||||
|
||||
For copying to a block B (named or unnamed), reallocation will be
|
||||
required if dsi + num > sizeof(B). (This will not be permitted if
|
||||
protect(B) has bit 4 set.)
|
||||
|
||||
For copying from a file stream fs, num can be at most size(fs) - ssi.
|
||||
|
||||
For copying from a string str, the string is taken to include the
|
||||
terminating '\0', so the total number of octets available is
|
||||
strlen(str) + 1 and num can be at most strlen(str) + 1 - ssi.
|
||||
If num <= strlen(str) - ssi, the '\0' is not copied.
|
||||
|
||||
For copying from or to a matrix M, the total number of values in
|
||||
M is size(M), so in the source case, num <= size(M) - ssi, and
|
||||
in the destination case, num <= size(M) - dsi. The indices ssi
|
||||
and dsi refer to the double-bracket method of indexing, i.e. the
|
||||
matrix is as if its elements were indexed 0, 1, ..., size(M) - 1.
|
||||
|
||||
|
||||
EXAMPLE
|
||||
> A = blk() = {1,2,3,4}
|
||||
> B = blk()
|
||||
> blkcpy(B,A)
|
||||
> B
|
||||
chunksize = 256, maxsize = 256, datalen = 4
|
||||
01020304
|
||||
>
|
||||
> blkcpy(B,A)
|
||||
> B
|
||||
chunksize = 256, maxsize = 256, datalen = 8
|
||||
0102030401020304
|
||||
> blkcpy(B, A, 2, 10)
|
||||
> B
|
||||
chunksize = 256, maxsize = 256, datalen = 12
|
||||
010203040102030400000102
|
||||
> blkcpy(B,32767)
|
||||
> B
|
||||
chunksize = 256, maxsize = 256, datalen = 16
|
||||
010203040102030400000102ff7f0000
|
||||
> mat M[2,2]
|
||||
> blkcpy(M, A)
|
||||
> M
|
||||
mat [2,2] (4 elements, 4 nonzero):
|
||||
[0,0] = 1
|
||||
[0,1] = 2
|
||||
[1,0] = 3
|
||||
[1,1] = 4
|
||||
> blkcpy(M, A, 2, 2)
|
||||
> M
|
||||
mat [2,2] (4 elements, 4 nonzero):
|
||||
[0,0] = 1
|
||||
[0,1] = 2
|
||||
[1,0] = 1
|
||||
[1,1] = 2
|
||||
|
||||
> A = blk() = {1,2,3,4}
|
||||
> B = blk()
|
||||
> copy(A,B)
|
||||
> B
|
||||
chunksize = 256, maxsize = 256, datalen = 4
|
||||
01020304
|
||||
> copy(A,B)
|
||||
> B
|
||||
chunksize = 256, maxsize = 256, datalen = 8
|
||||
0102030401020304
|
||||
> copy(A,B,1,2)
|
||||
> B
|
||||
chunksize = 256, maxsize = 256, datalen = 10
|
||||
01020304010203040203
|
||||
> mat M[2,2]
|
||||
> copy(A,M)
|
||||
> M
|
||||
mat [2,2] (4 elements, 4 nonzero):
|
||||
[0,0] = 1
|
||||
[0,1] = 2
|
||||
[1,0] = 3
|
||||
[1,1] = 4
|
||||
|
||||
> copy(A,M,2)
|
||||
> M
|
||||
mat [2,2] (4 elements, 4 nonzero):
|
||||
[0,0] = 3
|
||||
[0,1] = 4
|
||||
[1,0] = 3
|
||||
[1,1] = 4
|
||||
|
||||
> copy(A,M,0,2,2)
|
||||
> M
|
||||
mat [2,2] (4 elements, 4 nonzero):
|
||||
[0,0] = 3
|
||||
[0,1] = 4
|
||||
[1,0] = 1
|
||||
[1,1] = 2
|
||||
|
||||
LIMITS
|
||||
none
|
||||
|
||||
LIBRARY
|
||||
none
|
||||
|
||||
SEE ALSO
|
||||
blk, mat, file, list, str
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user